Recipes · Marketing

Pricing page

Three tiers, one featured, with a compact feature list. Uses Card, Badge, and Button — no bespoke CSS.

Preview

Elevate the recommended plan with an accent badge and a subtle scale change on hover.

Starter

$0 / mo

For prototypes

  • 100 requests / mo
  • Community support
  • Public projects

Team

Popular

$29 / mo

For growing teams

  • 10k requests / mo
  • Email support
  • Private projects
  • Role-based access

Enterprise

Custom

For scale

  • Unlimited requests
  • SLA + dedicated CSM
  • SSO / SAML
  • Audit logs

Source

tsx
import { Badge, Button, Card } from "@novix-ui/react";
import { Check } from "lucide-react";
 
const TIERS = [
{ name: "Starter", price: "$0", featured: false, features: [...] },
{ name: "Team", price: "$29", featured: true, features: [...] },
{ name: "Enterprise", price: "Custom", featured: false, features: [...] },
];
 
export function Pricing() {
return (
<div className="grid gap-4 sm:grid-cols-3">
{TIERS.map((t) => (
<Card key={t.name} className={t.featured ? "p-5 ring-2 ring-accent" : "p-5"}>
<div className="flex items-center justify-between">
<p className="font-semibold">{t.name}</p>
{t.featured && <Badge variant="accent" size="sm">Popular</Badge>}
</div>
<p className="mt-3 text-2xl font-semibold">{t.price}</p>
<ul className="mt-4 space-y-1.5 text-sm text-muted-foreground">
{t.features.map((f) => (
<li key={f} className="flex gap-2">
<Check className="mt-0.5 size-4 text-accent" />{f}
</li>
))}
</ul>
<Button variant={t.featured ? "accent" : "secondary"} className="mt-5 w-full">
{t.featured ? "Start trial" : "Choose"}
</Button>
</Card>
))}
</div>
);
}

Guidelines

  • Prefer per-month pricing anchored to annual value ("billed yearly, $348").
  • Feature lists cap at 5 rows per tier. Deeper differences belong in a matrix below.
  • Enterprise CTAs go to a form, not a checkout.