# Pricing 6

> Accordion expand per tier with price in trigger and features inside — grid-reveal stagger on open panels.

A shadcn/ui block from the [@nusaiba](https://nusaiba.dev) registry, listed on [shadcn.exchange](https://shadcn.exchange/r/nusaiba/pricing-6).

- Page, with a live preview: https://shadcn.exchange/r/nusaiba/pricing-6
- Screenshot: https://abzjhwgwpdpz7ua5.public.blob.vercel-storage.com/shots/nusaiba/pricing-6-light-d4a06e36825941d2.png
- Registry item: https://nusaiba.dev/r/base-nova/pricing-6.json
- Categories: pricing
- Listed: 2026-10-13, source last changed 2026-10-13

## Install

```bash
npx shadcn@latest add https://nusaiba.dev/r/base-nova/pricing-6.json
```

Run it in a project that has shadcn/ui set up. It adds the files below and installs what they depend on.

## Dependencies

- npm packages: `motion`
- Registry items: `@nusaiba/foundation`, `accordion`, `button`

## Files

### `registry/blocks/pricing/6/pricing-section.tsx`

```tsx
"use client";

import { useState } from "react";
import { CheckIcon } from "lucide-react";
import { motion, useReducedMotion } from "motion/react";
import {
	Accordion,
	AccordionContent,
	AccordionItem,
	AccordionTrigger,
} from "@/components/ui/accordion";
import { Button } from "@/components/ui/button";
import { defaultSpring, motionStagger, motionViewport } from "@/lib/motion-tokens";
import { cn } from "@/lib/utils";
import { SectionShell, ContentRail } from "@/components/layout-contract";

const tiers = [
	{
		id: "starter",
		name: "Starter",
		price: "$0",
		period: "forever",
		summary: "Free registry blocks and CLI install path.",
		features: ["All free blocks", "Shadcn CLI install", "Copy prompt", "Live preview"],
	},
	{
		id: "pro",
		name: "Pro",
		price: "$147",
		period: "once",
		summary: "Pro catalog, token, and commercial license.",
		features: [
			"Every Pro block",
			"Private registry token",
			"Commercial license",
			"Motion pattern docs",
		],
		popular: true,
	},
	{
		id: "enterprise",
		name: "Enterprise",
		price: "Custom",
		period: "annual",
		summary: "Team workspace, SSO, and dedicated support.",
		features: ["Everything in Pro", "Team seats", "Role-based access", "Priority support"],
	},
];

export function PricingAccordionSection() {
	const reduceMotion = useReducedMotion();
	const [open, setOpen] = useState<string[]>(["pro"]);

	return (
		<SectionShell spacingMode="section" className="bg-background">
			<ContentRail maxWidth="max-w-3xl" className="space-y-8 md:space-y-10">
				<div className="max-w-xl space-y-2">
					<p className="font-medium text-primary text-xs uppercase tracking-[0.22em]">
						Expand
					</p>
					<h2 className="text-balance font-medium text-2xl tracking-tight md:text-4xl">
						One tier at a time
					</h2>
					<p className="text-pretty text-muted-foreground text-sm md:text-base">
						Open a plan to see features — accordion clarity without a full comparison
						table.
					</p>
				</div>

				<motion.div
					className="overflow-hidden border border-border bg-background shadow-[0_1px_2px_rgba(0,0,0,0.04)] dark:shadow-[0_1px_2px_rgba(0,0,0,0.2)]"
					initial={reduceMotion ? false : { opacity: 0, y: 12, filter: "blur(4px)" }}
					transition={defaultSpring}
					viewport={motionViewport}
					whileInView={reduceMotion ? undefined : { opacity: 1, y: 0, filter: "blur(0px)" }}
				>
					<Accordion
						className="divide-y divide-border"
						onValueChange={setOpen}
						value={open}
					>
						{tiers.map((tier, index) => (
							<motion.div
								initial={reduceMotion ? false : { opacity: 0, y: 8 }}
								key={tier.id}
								transition={{
									...defaultSpring,
									delay: index * motionStagger.item,
								}}
								viewport={motionViewport}
								whileInView={reduceMotion ? undefined : { opacity: 1, y: 0 }}
							>
								<AccordionItem className="border-0 px-4 md:px-6" value={tier.id}>
									<AccordionTrigger
										className={cn(
											"py-5 hover:no-underline md:py-6",
											"after:absolute after:top-1/2 after:left-1/2 after:size-10 after:-translate-1/2",
										)}
									>
										<div className="flex flex-1 flex-wrap items-center justify-between gap-3 pr-4 text-left">
											<div className="space-y-0.5">
												<div className="flex items-center gap-2">
													<span className="font-medium">{tier.name}</span>
													{tier.popular ? (
														<span className="font-medium text-[10px] text-primary uppercase tracking-[0.18em]">
															Popular
														</span>
													) : null}
												</div>
												<p className="text-pretty text-muted-foreground text-sm">
													{tier.summary}
												</p>
											</div>
											<div className="text-right">
												<p className="font-medium text-xl tabular-nums tracking-tight md:text-2xl">
													{tier.price}
												</p>
												<p className="text-muted-foreground text-xs">{tier.period}</p>
											</div>
										</div>
									</AccordionTrigger>
									<AccordionContent className="pb-5 md:pb-6">
										<ul className="mb-5 space-y-2.5">
											{tier.features.map((feature) => (
												<li className="flex items-start gap-2 text-sm" key={feature}>
													<CheckIcon className="mt-0.5 size-4 shrink-0 text-primary" />
													{feature}
												</li>
											))}
										</ul>
										<Button
											className="active:scale-[0.96]"
											variant={tier.popular ? "default" : "outline"}
										>
											{tier.price === "Custom" ? "Contact sales" : "Get started"}
										</Button>
									</AccordionContent>
								</AccordionItem>
							</motion.div>
						))}
					</Accordion>
				</motion.div>
			</ContentRail>
		</SectionShell>
	);
}
```
