{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "comparison-1",
  "title": "Two-Plan Table With Billing Toggle",
  "description": "Plan comparison table pitting Starter against Pro across grouped feature rows, with a monthly and annual toggle that changes the price and cell values.",
  "dependencies": [
    "@base-ui/react"
  ],
  "registryDependencies": [
    "badge",
    "button",
    "table"
  ],
  "files": [
    {
      "path": "registry/blocks/comparison/1/comparison-block.tsx",
      "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { Badge } from \"@/components/ui/badge\"\nimport { Button } from \"@/components/ui/button\"\nimport {\n  Table,\n  TableBody,\n  TableCell,\n  TableHead,\n  TableHeader,\n  TableRow,\n} from \"@/components/ui/table\"\nimport { cn } from \"@/lib/utils\"\nimport { IconPlaceholder } from \"@/components/icons/icon-placeholder\"\n\ntype Billing = \"monthly\" | \"annual\"\n\ntype Cell = boolean | string | { monthly: string; annual: string }\n\nconst resolveCell = (value: Cell, billing: Billing): boolean | string =>\n  typeof value === \"object\" ? value[billing] : value\n\nconst FEATURES: {\n  category: string\n  rows: { label: string; starter: Cell; pro: Cell }[]\n}[] = [\n  {\n    category: \"Core\",\n    rows: [\n      { label: \"Projects\", starter: \"Up to 3\", pro: \"Unlimited\" },\n      {\n        label: \"Storage\",\n        starter: \"1 GB\",\n        pro: { monthly: \"100 GB\", annual: \"200 GB\" },\n      },\n      { label: \"API access\", starter: true, pro: true },\n      { label: \"Custom domains\", starter: false, pro: true },\n    ],\n  },\n  {\n    category: \"Collaboration\",\n    rows: [\n      { label: \"Team members\", starter: \"1\", pro: \"Unlimited\" },\n      { label: \"Role-based permissions\", starter: false, pro: true },\n      { label: \"Shared workspaces\", starter: false, pro: true },\n      { label: \"Activity log\", starter: false, pro: true },\n    ],\n  },\n  {\n    category: \"Security & Compliance\",\n    rows: [\n      { label: \"Two-factor authentication\", starter: true, pro: true },\n      { label: \"SSO / SAML\", starter: false, pro: true },\n      { label: \"Audit logs\", starter: false, pro: true },\n      { label: \"Data residency controls\", starter: false, pro: true },\n    ],\n  },\n  {\n    category: \"Support\",\n    rows: [\n      { label: \"Community forum\", starter: true, pro: true },\n      { label: \"Email support\", starter: false, pro: true },\n      {\n        label: \"Priority response SLA\",\n        starter: false,\n        pro: { monthly: \"< 4 h\", annual: \"< 2 h\" },\n      },\n      { label: \"Dedicated account manager\", starter: false, pro: true },\n    ],\n  },\n]\n\nfunction FeatureValue({\n  value,\n  highlight,\n}: {\n  value: boolean | string\n  highlight?: boolean\n}) {\n  if (typeof value === \"string\") {\n    return (\n      <span\n        className={cn(\n          \"text-sm font-medium\",\n          highlight ? \"text-foreground\" : \"text-muted-foreground\"\n        )}\n      >\n        {value}\n      </span>\n    )\n  }\n  if (value) {\n    return (\n      <IconPlaceholder\n        lucide=\"Check\"\n        tabler=\"IconCheck\"\n        hugeicons=\"Tick02Icon\"\n        phosphor=\"Check\"\n        remixicon=\"RiCheckLine\"\n        className={cn(\n          \"mx-auto size-4\",\n          highlight ? \"text-primary\" : \"text-muted-foreground\"\n        )}\n        aria-label=\"Included\"\n      />\n    )\n  }\n  return (\n    <IconPlaceholder\n      lucide=\"X\"\n      tabler=\"IconX\"\n      hugeicons=\"Cancel01Icon\"\n      phosphor=\"X\"\n      remixicon=\"RiCloseLine\"\n      className=\"mx-auto size-4 text-muted-foreground/40\"\n      aria-label=\"Not included\"\n    />\n  )\n}\n\nexport default function ComparisonBlock() {\n  const [billing, setBilling] = React.useState<Billing>(\"monthly\")\n  const proPrice = billing === \"annual\" ? 23 : 29\n\n  return (\n    <section className=\"flex w-full items-center justify-center bg-background px-4 py-16 text-foreground sm:px-6\">\n      <div className=\"mx-auto w-full max-w-3xl\">\n        <div className=\"mx-auto max-w-xl text-center\">\n          <span className=\"text-sm font-medium tracking-widest text-muted-foreground uppercase\">\n            Plans\n          </span>\n          <h2 className=\"mt-3 font-heading text-3xl font-bold tracking-tight sm:text-4xl\">\n            Compare plans\n          </h2>\n          <p className=\"mt-3 text-muted-foreground\">\n            Every feature, side by side, so you can pick the right plan with\n            confidence.\n          </p>\n        </div>\n\n        <div className=\"mt-8 flex justify-center\">\n          <div\n            role=\"group\"\n            aria-label=\"Billing period\"\n            className=\"inline-flex items-center gap-1 rounded-lg border border-border bg-muted/50 p-1\"\n          >\n            <button\n              type=\"button\"\n              onClick={() => setBilling(\"monthly\")}\n              aria-pressed={billing === \"monthly\"}\n              className={cn(\n                \"rounded-md px-4 py-1.5 text-sm font-medium transition-colors\",\n                billing === \"monthly\"\n                  ? \"bg-background text-foreground shadow-sm\"\n                  : \"text-muted-foreground hover:text-foreground\"\n              )}\n            >\n              Monthly\n            </button>\n            <button\n              type=\"button\"\n              onClick={() => setBilling(\"annual\")}\n              aria-pressed={billing === \"annual\"}\n              className={cn(\n                \"flex items-center gap-2 rounded-md px-4 py-1.5 text-sm font-medium transition-colors\",\n                billing === \"annual\"\n                  ? \"bg-background text-foreground shadow-sm\"\n                  : \"text-muted-foreground hover:text-foreground\"\n              )}\n            >\n              Annual\n              <Badge className=\"px-1.5 text-[10px] font-semibold\">-20%</Badge>\n            </button>\n          </div>\n        </div>\n\n        <div className=\"relative mt-10 rounded-lg border border-border bg-card\">\n          <Badge className=\"absolute bottom-full left-[87.5%] z-20 mb-2 -translate-x-1/2 px-2 text-[10px] font-semibold\">\n            Popular\n          </Badge>\n          <Table>\n            <TableHeader>\n              <TableRow className=\"hover:bg-transparent\">\n                <TableHead className=\"w-1/2 py-4 text-sm font-semibold text-foreground\">\n                  Feature\n                </TableHead>\n                <TableHead className=\"w-1/4 py-4 text-center text-sm font-semibold text-foreground\">\n                  <div className=\"flex flex-col items-center gap-0.5\">\n                    <span>Starter</span>\n                    <span className=\"text-xs font-normal text-muted-foreground\">\n                      Free\n                    </span>\n                  </div>\n                </TableHead>\n                <TableHead className=\"w-1/4 rounded-tr-lg bg-primary/10 py-4 text-center text-sm font-semibold text-foreground\">\n                  <div className=\"flex flex-col items-center gap-0.5\">\n                    <span>Pro</span>\n                    <span className=\"text-xs font-normal text-muted-foreground\">\n                      ${proPrice} / Month\n                    </span>\n                  </div>\n                </TableHead>\n              </TableRow>\n            </TableHeader>\n\n            <TableBody>\n              {FEATURES.map(({ category, rows }) => (\n                <React.Fragment key={category}>\n                  <TableRow className=\"bg-muted/50 hover:bg-muted/50\">\n                    <TableCell\n                      colSpan={3}\n                      className=\"py-2 text-xs font-semibold tracking-wider text-muted-foreground uppercase\"\n                    >\n                      {category}\n                    </TableCell>\n                  </TableRow>\n\n                  {rows.map((row) => (\n                    <TableRow key={row.label}>\n                      <TableCell className=\"text-sm text-foreground\">\n                        {row.label}\n                      </TableCell>\n                      <TableCell className=\"text-center\">\n                        <FeatureValue\n                          value={resolveCell(row.starter, billing)}\n                        />\n                      </TableCell>\n                      <TableCell className=\"bg-primary/5 text-center\">\n                        <FeatureValue\n                          value={resolveCell(row.pro, billing)}\n                          highlight\n                        />\n                      </TableCell>\n                    </TableRow>\n                  ))}\n                </React.Fragment>\n              ))}\n\n              <TableRow className=\"hover:bg-transparent\">\n                <TableCell />\n                <TableCell className=\"py-5 text-center\">\n                  <Button\n                    nativeButton={false}\n                    variant=\"outline\"\n                    size=\"sm\"\n                    className=\"w-full max-w-[120px]\"\n                    render={<a href=\"#\" />}\n                  >\n                    Get Started\n                  </Button>\n                </TableCell>\n                <TableCell className=\"rounded-br-lg bg-primary/5 py-5 text-center\">\n                  <Button\n                    nativeButton={false}\n                    size=\"sm\"\n                    className=\"w-full max-w-[120px]\"\n                    render={<a href=\"#\" />}\n                  >\n                    Start Free Trial\n                  </Button>\n                </TableCell>\n              </TableRow>\n            </TableBody>\n          </Table>\n        </div>\n      </div>\n    </section>\n  )\n}\n",
      "type": "registry:component",
      "target": "components/blocks/comparison-1.tsx"
    }
  ],
  "meta": {
    "height": "1227px",
    "tier": "free"
  },
  "docs": "Requires a `base-*` style in components.json (the `shadcn init` default). Legacy `new-york`/`radix-*` styles install Radix primitives, which reject the `render` prop this block uses.",
  "categories": [
    "comparison"
  ],
  "type": "registry:block"
}