{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "onboarding-2",
  "title": "Three-Card Setup Steps",
  "description": "Onboarding laid out as three numbered step cards for importing data, inviting teammates, and customizing the workspace, each toggling to complete.",
  "dependencies": [
    "@base-ui/react"
  ],
  "registryDependencies": [
    "button",
    "card",
    "progress"
  ],
  "files": [
    {
      "path": "registry/blocks/onboarding/2/onboarding-block.tsx",
      "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { Button } from \"@/components/ui/button\"\nimport {\n  Card,\n  CardDescription,\n  CardFooter,\n  CardHeader,\n  CardTitle,\n} from \"@/components/ui/card\"\nimport { Progress } from \"@/components/ui/progress\"\nimport { cn } from \"@/lib/utils\"\nimport { IconPlaceholder } from \"@/components/icons/icon-placeholder\"\n\n/** Props a call site may pass through to an icon. */\ntype IconProps = { className?: string; size?: number | string }\n\nconst SETUP_CARDS = [\n  {\n    id: \"import\",\n    icon: (p: IconProps) => (\n      <IconPlaceholder\n        lucide=\"UploadCloud\"\n        tabler=\"IconCloudUpload\"\n        hugeicons=\"CloudUploadIcon\"\n        phosphor=\"CloudArrowUp\"\n        remixicon=\"RiUploadCloud2Line\"\n        {...p}\n      />\n    ),\n    step: \"Step 1\",\n    title: \"Import your data\",\n    description:\n      \"Connect a data source or upload a CSV to bring your existing records into Acme instantly.\",\n  },\n  {\n    id: \"invite\",\n    icon: (p: IconProps) => (\n      <IconPlaceholder\n        lucide=\"Users\"\n        tabler=\"IconUsersGroup\"\n        hugeicons=\"UserGroupIcon\"\n        phosphor=\"UsersThree\"\n        remixicon=\"RiTeamLine\"\n        {...p}\n      />\n    ),\n    step: \"Step 2\",\n    title: \"Invite teammates\",\n    description:\n      \"Add colleagues by email and assign roles (admin, editor, or viewer) to collaborate right away.\",\n  },\n  {\n    id: \"customize\",\n    icon: (p: IconProps) => (\n      <IconPlaceholder\n        lucide=\"Palette\"\n        tabler=\"IconPalette\"\n        hugeicons=\"PaintBoardIcon\"\n        phosphor=\"Palette\"\n        remixicon=\"RiPaletteLine\"\n        {...p}\n      />\n    ),\n    step: \"Step 3\",\n    title: \"Customize your workspace\",\n    description:\n      \"Set your brand colors, default language, and notification preferences to match your workflow.\",\n  },\n]\n\nexport default function OnboardingBlock() {\n  const [done, setDone] = React.useState<Record<string, boolean>>({})\n\n  const completed = SETUP_CARDS.filter((c) => done[c.id]).length\n  const total = SETUP_CARDS.length\n  const pct = Math.round((completed / total) * 100)\n\n  function toggleDone(id: string) {\n    setDone((prev) => ({ ...prev, [id]: !prev[id] }))\n  }\n\n  return (\n    <section className=\"flex w-full items-center justify-center bg-background px-6 py-12 text-foreground\">\n      <div className=\"flex w-full max-w-4xl flex-col gap-6\">\n        <div className=\"flex flex-col gap-4\">\n          <div className=\"flex flex-col gap-1\">\n            <h1 className=\"font-heading text-lg font-semibold tracking-tight\">\n              Get started with Acme\n            </h1>\n            <p className=\"text-sm text-muted-foreground\">\n              Complete these three steps to finish setting up your account.\n            </p>\n          </div>\n          <div className=\"flex flex-col gap-2\">\n            <div className=\"flex items-center justify-between text-xs\">\n              <span className=\"font-medium text-foreground\">\n                Setup progress\n              </span>\n              <span className=\"text-muted-foreground tabular-nums\">\n                <span className=\"font-medium text-foreground\">{completed}</span>{\" \"}\n                of {total} complete\n              </span>\n            </div>\n            <Progress\n              value={pct}\n              aria-label={`${completed} of ${total} steps complete`}\n            />\n          </div>\n        </div>\n\n        <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-3\">\n          {SETUP_CARDS.map((card) => {\n            const Icon = card.icon\n            const isDone = !!done[card.id]\n            return (\n              <Card\n                key={card.id}\n                className={cn(\n                  \"flex flex-col gap-4 transition-colors\",\n                  isDone && \"border-primary/40 bg-primary/5\"\n                )}\n              >\n                <CardHeader>\n                  <div\n                    className={cn(\n                      \"flex size-9 items-center justify-center rounded-md transition-colors\",\n                      isDone\n                        ? \"bg-primary text-primary-foreground\"\n                        : \"bg-muted text-muted-foreground\"\n                    )}\n                  >\n                    {isDone ? (\n                      <IconPlaceholder\n                        lucide=\"Check\"\n                        tabler=\"IconCheck\"\n                        hugeicons=\"Tick02Icon\"\n                        phosphor=\"Check\"\n                        remixicon=\"RiCheckLine\"\n                        className=\"size-4\"\n                        aria-hidden=\"true\"\n                      />\n                    ) : (\n                      <Icon className=\"size-4\" aria-hidden=\"true\" />\n                    )}\n                  </div>\n                  <span className=\"mt-3 text-[10px] font-medium tracking-widest text-muted-foreground uppercase\">\n                    {card.step}\n                  </span>\n                  <CardTitle className=\"text-sm font-semibold\">\n                    {card.title}\n                  </CardTitle>\n                  <CardDescription>{card.description}</CardDescription>\n                </CardHeader>\n\n                <CardFooter className=\"mt-auto\">\n                  {isDone ? (\n                    <Button\n                      size=\"sm\"\n                      variant=\"secondary\"\n                      className=\"w-full\"\n                      onClick={() => toggleDone(card.id)}\n                    >\n                      <IconPlaceholder\n                        lucide=\"Check\"\n                        tabler=\"IconCheck\"\n                        hugeicons=\"Tick02Icon\"\n                        phosphor=\"Check\"\n                        remixicon=\"RiCheckLine\"\n                        data-icon=\"inline-start\"\n                        aria-hidden=\"true\"\n                      />\n                      Completed\n                    </Button>\n                  ) : (\n                    <Button\n                      size=\"sm\"\n                      variant=\"outline\"\n                      className=\"w-full\"\n                      onClick={() => toggleDone(card.id)}\n                    >\n                      Start\n                      <IconPlaceholder\n                        lucide=\"ArrowRight\"\n                        tabler=\"IconArrowRight\"\n                        hugeicons=\"ArrowRightIcon\"\n                        phosphor=\"ArrowRight\"\n                        remixicon=\"RiArrowRightLine\"\n                        data-icon=\"inline-end\"\n                        aria-hidden=\"true\"\n                      />\n                    </Button>\n                  )}\n                </CardFooter>\n              </Card>\n            )\n          })}\n        </div>\n      </div>\n    </section>\n  )\n}\n",
      "type": "registry:component",
      "target": "components/blocks/onboarding-2.tsx"
    }
  ],
  "meta": {
    "height": "472px",
    "tier": "free"
  },
  "categories": [
    "onboarding"
  ],
  "type": "registry:block"
}