Pricing 1
Three-tier card row with a featured middle plan. Each card lists price, blurb, feature checklist and a primary or outline CTA.
Preview
Installation
npx shadcn@latest add https://hirael.com/r/pricing-01.jsonCode
components/blocks/pricing-01.tsx
'use client';
import * as React from 'react';
import { Check } from 'lucide-react';
import { Button } from '@/registry/hirael/bases/radix/ui/button';
import { Card, CardContent, CardFooter, CardHeader } from '@/registry/hirael/bases/radix/ui/card';
import { Separator } from '@/registry/hirael/bases/radix/ui/separator';
import { cn } from '@/lib/utils';
interface Tier {
name: string;
price: string;
blurb: string;
features: readonly string[];
cta: string;
featured?: boolean;
ctaVariant: 'default' | 'outline';
}
const TIERS: readonly Tier[] = [
{
name: 'Hobby',
price: '$0',
blurb: 'For weekend projects and solo prototypes.',
features: ['Full registry access', 'Up to 3 themes', 'Community support', 'Full source access'],
cta: 'Start free',
ctaVariant: 'outline',
},
{
name: 'Pro',
price: '$18',
blurb: 'For shipping real products with real users.',
features: ['Everything in Hobby', 'Unlimited themes', 'Private registry mirror', 'Priority response'],
cta: 'Start Pro trial',
featured: true,
ctaVariant: 'default',
},
{
name: 'Team',
price: '$48',
blurb: 'For studios and product teams shipping side-by-side.',
features: ['Everything in Pro', 'Shared workspace', 'SSO & audit log', 'SLA support'],
cta: 'Contact sales',
ctaVariant: 'outline',
},
];
const Pricing01 = () => {
return (
<section className="bg-background py-20 sm:py-28">
<div className="container w-full">
<div className="mx-auto flex max-w-2xl flex-col items-center gap-5 text-center">
<span className="inline-flex items-center gap-2 font-mono text-[10px] uppercase tracking-[0.14em] text-foreground">
<span className="size-1 rounded-full bg-foreground" />
Pricing
</span>
<h2 className="font-serif text-4xl font-medium leading-[1.04] tracking-tight sm:text-5xl">
Pay for the parts you <span className="italic text-foreground">actually</span> use.
</h2>
<p className="text-base text-muted-foreground sm:text-lg">
Source code stays free. Pay only when you need private mirrors, shared themes, or team-level controls.
</p>
</div>
<div className="mt-14 grid grid-cols-1 gap-4 md:grid-cols-3">
{TIERS.map((tier) => (
<Card
key={tier.name}
style={
tier.featured
? {
backgroundImage:
'radial-gradient(120% 90% at 50% 0%, color-mix(in oklch, var(--primary) 9%, transparent), transparent 60%)',
}
: undefined
}
className={cn(
'relative gap-6 rounded-xl p-6 transition-all duration-200 hover:-translate-y-1',
tier.featured ? 'ring-1 ring-foreground/25' : 'hover:border-foreground/20',
)}
>
{tier.featured && (
<span className="absolute -top-2.5 end-6 inline-flex items-center rounded-full border border-border bg-background px-2.5 py-0.5 font-mono text-[10px] uppercase tracking-[0.12em] text-foreground">
Most popular
</span>
)}
<CardHeader className="flex flex-col gap-2 px-0">
<span className="font-mono text-[10px] uppercase tracking-[0.12em] text-muted-foreground">
{tier.name}
</span>
<div className="flex items-baseline gap-1">
<span className="text-4xl font-semibold tracking-[-0.04em]">{tier.price}</span>
<span className="font-mono text-xs text-muted-foreground">/mo</span>
</div>
<p className="text-sm text-muted-foreground">{tier.blurb}</p>
</CardHeader>
<Separator className="border-dashed" />
<CardContent className="px-0">
<ul className="flex flex-col gap-2.5">
{tier.features.map((f) => (
<li key={f} className="flex items-start gap-2.5 text-sm text-foreground">
<Check className="mt-0.5 size-4 shrink-0 text-foreground" />
{f}
</li>
))}
</ul>
</CardContent>
<CardFooter className="mt-auto px-0 pt-2">
<Button asChild variant={tier.ctaVariant} size="lg" className="w-full rounded-full">
<a href="#">{tier.cta}</a>
</Button>
</CardFooter>
</Card>
))}
</div>
</div>
</section>
);
};
export default Pricing01;
Dependencies
shadcn registry
buttoncardseparator
npm
lucide-react