{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "empty-onboarding",
  "title": "Onboarding empty",
  "description": "Styled empty: the Onboarding set. 5 decorative empty variations (StepsEmpty, ChecklistEmpty, WelcomeEmpty, TourEmpty, TipsEmpty) on the ai2 token system, driven by CSS token transitions and sized sm to xl. Part of the free styled layer.",
  "dependencies": [
    "lucide-react@^1.23.0"
  ],
  "registryDependencies": [
    "@ai2/tokens"
  ],
  "files": [
    {
      "path": "registry/ai2/styled/empty-onboarding.tsx",
      "content": "\"use client\"\n\nimport * as React from \"react\"\nimport {\n  ArrowRight,\n  Check,\n  Compass,\n  Lightbulb,\n  PartyPopper,\n  Rocket,\n} from \"lucide-react\"\n\nimport { cn } from \"@/lib/utils\"\n\n/* Onboarding empty family: 5 first-run and getting-started empty states. Numbered steps, a checkable checklist, a welcome, a product tour and a tip list. Colour comes ONLY from semantic tokens (transparency via color-mix), size = the padding plus icon and text scale. Renders without props too. Static - no motion. */\n\nexport type StyledSize = \"sm\" | \"md\" | \"lg\" | \"xl\"\n\ntype Scale = {\n  root: string\n  icon: string\n  badge: string\n  title: string\n  description: string\n}\n\nconst scales: Record<StyledSize, Scale> = {\n  sm: {\n    root: \"gap-2 p-6\",\n    icon: \"size-6\",\n    badge: \"size-12\",\n    title: \"text-sm\",\n    description: \"text-xs\",\n  },\n  md: {\n    root: \"gap-3 p-8\",\n    icon: \"size-8\",\n    badge: \"size-16\",\n    title: \"text-base\",\n    description: \"text-sm\",\n  },\n  lg: {\n    root: \"gap-3.5 p-10\",\n    icon: \"size-10\",\n    badge: \"size-20\",\n    title: \"text-lg\",\n    description: \"text-sm\",\n  },\n  xl: {\n    root: \"gap-4 p-12\",\n    icon: \"size-12\",\n    badge: \"size-24\",\n    title: \"text-xl\",\n    description: \"text-base\",\n  },\n}\n\ninterface EmptyProps {\n  className?: string\n  size?: StyledSize\n  icon?: React.ReactNode\n  title?: React.ReactNode\n  description?: React.ReactNode\n  action?: React.ReactNode\n}\n\nconst rootBase = \"flex flex-col items-center justify-center text-center\"\n\nconst iconBase = \"[&_i]:leading-none [&_svg]:size-full\"\n\nconst primaryBtn =\n  \"inline-flex h-9 items-center justify-center gap-2 rounded-md bg-primary px-4 text-sm font-medium text-primary-foreground outline-none transition-colors duration-(--motion-base) ease-(--motion-ease) hover:bg-primary/90 focus-visible:ring-[3px] focus-visible:ring-ring/50 motion-reduce:transition-none [&_i]:text-base [&_i]:leading-none [&_svg]:size-4 [&_svg]:shrink-0\"\n\nconst ghostBtn =\n  \"inline-flex h-9 items-center justify-center gap-2 rounded-md border border-border bg-transparent px-4 text-sm font-medium text-foreground outline-none transition-colors duration-(--motion-base) ease-(--motion-ease) hover:bg-[color-mix(in_oklab,var(--color-foreground)_6%,transparent)] focus-visible:ring-[3px] focus-visible:ring-ring/50 motion-reduce:transition-none [&_i]:text-base [&_i]:leading-none [&_svg]:size-4 [&_svg]:shrink-0\"\n\n/* A soft primary-toned badge: primary has no -soft token, so it is derived with color-mix. */\nconst primaryBadge =\n  \"flex items-center justify-center rounded-full border text-primary [background:color-mix(in_oklab,var(--color-primary)_12%,transparent)] [border-color:color-mix(in_oklab,var(--color-primary)_28%,transparent)]\"\n\n/* StepsEmpty: numarali baslangic adimlari + birincil aksiyon. */\nexport function StepsEmpty({\n  className,\n  size = \"md\",\n  icon,\n  title = \"Set up your workspace\",\n  description = \"Three quick steps and your workspace is ready to use.\",\n  action,\n}: EmptyProps) {\n  const s = scales[size]\n  const steps = [\"Name your workspace\", \"Invite your teammates\", \"Create your first project\"]\n  return (\n    <div data-slot=\"styled-empty\" className={cn(rootBase, s.root, className)}>\n      <span aria-hidden=\"true\" className={cn(primaryBadge, s.badge)}>\n        <span className={cn(iconBase, s.icon)}>{icon ?? <Rocket />}</span>\n      </span>\n      <p className={cn(\"font-semibold text-foreground\", s.title)}>{title}</p>\n      {description ? (\n        <p className={cn(\"max-w-prose text-muted-foreground\", s.description)}>\n          {description}\n        </p>\n      ) : null}\n      <ol className=\"mt-1 flex flex-col gap-2 text-left\">\n        {steps.map((step, i) => (\n          <li key={step} className=\"flex items-center gap-2.5 text-sm\">\n            <span className=\"flex size-6 shrink-0 items-center justify-center rounded-full border text-xs font-semibold text-primary [background:color-mix(in_oklab,var(--color-primary)_12%,transparent)] [border-color:color-mix(in_oklab,var(--color-primary)_28%,transparent)]\">\n              {i + 1}\n            </span>\n            <span className=\"text-muted-foreground\">{step}</span>\n          </li>\n        ))}\n      </ol>\n      <div className=\"mt-2\">\n        {action ?? (\n          <button type=\"button\" data-slot=\"styled-empty-action\" className={primaryBtn}>\n            Get started\n            <ArrowRight />\n          </button>\n        )}\n      </div>\n    </div>\n  )\n}\n\n/* ChecklistEmpty: tamamlanma durumu tasiyan kontrol listesi + ilerleme sayaci. */\nexport function ChecklistEmpty({\n  className,\n  size = \"md\",\n  icon,\n  title = \"Finish setting up\",\n  description = \"You are almost there. Complete the remaining items to go live.\",\n  action,\n}: EmptyProps) {\n  const s = scales[size]\n  const items: { label: string; done: boolean }[] = [\n    { label: \"Verify your email\", done: true },\n    { label: \"Connect a repository\", done: true },\n    { label: \"Deploy your first build\", done: false },\n  ]\n  const done = items.filter((i) => i.done).length\n  return (\n    <div data-slot=\"styled-empty\" className={cn(rootBase, s.root, className)}>\n      <span aria-hidden=\"true\" className={cn(primaryBadge, s.badge)}>\n        <span className={cn(iconBase, s.icon)}>{icon ?? <Check />}</span>\n      </span>\n      <p className={cn(\"font-semibold text-foreground\", s.title)}>{title}</p>\n      {description ? (\n        <p className={cn(\"max-w-prose text-muted-foreground\", s.description)}>\n          {description}\n        </p>\n      ) : null}\n      <p className=\"text-xs font-medium text-muted-foreground\">\n        {done} of {items.length} complete\n      </p>\n      <ul className=\"mt-1 flex flex-col gap-2 text-left\">\n        {items.map((item) => (\n          <li key={item.label} className=\"flex items-center gap-2.5 text-sm\">\n            <span\n              aria-hidden=\"true\"\n              className={cn(\n                \"flex size-5 shrink-0 items-center justify-center rounded-full border [&_i]:text-xs [&_i]:leading-none [&_svg]:size-3\",\n                item.done\n                  ? \"bg-success-soft text-success-soft-foreground [border-color:color-mix(in_oklab,var(--color-success)_30%,transparent)]\"\n                  : \"border-dashed border-border\"\n              )}\n            >\n              {item.done ? <Check /> : null}\n            </span>\n            <span\n              className={cn(\n                item.done ? \"text-muted-foreground line-through\" : \"text-foreground\"\n              )}\n            >\n              {item.label}\n            </span>\n          </li>\n        ))}\n      </ul>\n      {action ? <div className=\"mt-2\">{action}</div> : null}\n    </div>\n  )\n}\n\n/* WelcomeEmpty: sicak karsilama, iki aksiyon (birincil + ikincil). */\nexport function WelcomeEmpty({\n  className,\n  size = \"md\",\n  icon,\n  title = \"Welcome aboard\",\n  description = \"This is your dashboard. Create something and it will show up right here.\",\n  action,\n}: EmptyProps) {\n  const s = scales[size]\n  return (\n    <div data-slot=\"styled-empty\" className={cn(rootBase, s.root, className)}>\n      <span aria-hidden=\"true\" className={cn(primaryBadge, s.badge)}>\n        <span className={cn(iconBase, s.icon)}>{icon ?? <PartyPopper />}</span>\n      </span>\n      <p className={cn(\"font-semibold text-foreground\", s.title)}>{title}</p>\n      {description ? (\n        <p className={cn(\"max-w-prose text-muted-foreground\", s.description)}>\n          {description}\n        </p>\n      ) : null}\n      <div className=\"mt-2 flex flex-wrap items-center justify-center gap-2\">\n        {action ?? (\n          <>\n            <button type=\"button\" data-slot=\"styled-empty-action\" className={primaryBtn}>\n              Create your first item\n            </button>\n            <button type=\"button\" className={ghostBtn}>\n              Read the guide\n            </button>\n          </>\n        )}\n      </div>\n    </div>\n  )\n}\n\n/* TourEmpty: urun turu daveti, adim noktalari + tur baslatma aksiyonu. */\nexport function TourEmpty({\n  className,\n  size = \"md\",\n  icon,\n  title = \"Take the quick tour\",\n  description = \"A two minute walkthrough of the places you will use most.\",\n  action,\n}: EmptyProps) {\n  const s = scales[size]\n  const stops = [\"Navigation\", \"Editor\", \"Sharing\", \"Settings\"]\n  return (\n    <div data-slot=\"styled-empty\" className={cn(rootBase, s.root, className)}>\n      <span aria-hidden=\"true\" className={cn(primaryBadge, s.badge)}>\n        <span className={cn(iconBase, s.icon)}>{icon ?? <Compass />}</span>\n      </span>\n      <p className={cn(\"font-semibold text-foreground\", s.title)}>{title}</p>\n      {description ? (\n        <p className={cn(\"max-w-prose text-muted-foreground\", s.description)}>\n          {description}\n        </p>\n      ) : null}\n      <div className=\"mt-1 flex flex-wrap items-center justify-center gap-x-2 gap-y-1.5\">\n        {stops.map((stop, i) => (\n          <React.Fragment key={stop}>\n            {i > 0 ? (\n              <span\n                aria-hidden=\"true\"\n                className=\"text-muted-foreground [&_i]:text-xs [&_i]:leading-none [&_svg]:size-3\"\n              >\n                <ArrowRight />\n              </span>\n            ) : null}\n            <span className=\"rounded-full border border-border px-2.5 py-0.5 text-xs text-muted-foreground\">\n              {stop}\n            </span>\n          </React.Fragment>\n        ))}\n      </div>\n      <div className=\"mt-2\">\n        {action ?? (\n          <button type=\"button\" data-slot=\"styled-empty-action\" className={primaryBtn}>\n            <Compass />\n            Start the tour\n          </button>\n        )}\n      </div>\n    </div>\n  )\n}\n\n/* TipsEmpty: bos ekranda ise yarar ipuclari listesi. */\nexport function TipsEmpty({\n  className,\n  size = \"md\",\n  icon,\n  title = \"Nothing here yet\",\n  description = \"While this is empty, here are a few things worth knowing.\",\n  action,\n}: EmptyProps) {\n  const s = scales[size]\n  const tips = [\n    \"Press the plus button to add an item.\",\n    \"Drag items to reorder them at any time.\",\n    \"Everything you create is saved automatically.\",\n  ]\n  return (\n    <div data-slot=\"styled-empty\" className={cn(rootBase, s.root, className)}>\n      <span aria-hidden=\"true\" className={cn(primaryBadge, s.badge)}>\n        <span className={cn(iconBase, s.icon)}>{icon ?? <Lightbulb />}</span>\n      </span>\n      <p className={cn(\"font-semibold text-foreground\", s.title)}>{title}</p>\n      {description ? (\n        <p className={cn(\"max-w-prose text-muted-foreground\", s.description)}>\n          {description}\n        </p>\n      ) : null}\n      <ul className=\"mt-1 flex max-w-prose flex-col gap-2 text-left\">\n        {tips.map((tip) => (\n          <li key={tip} className=\"flex items-start gap-2.5 text-sm text-muted-foreground\">\n            <span\n              aria-hidden=\"true\"\n              className=\"mt-0.5 shrink-0 text-primary [&_i]:text-xs [&_i]:leading-none [&_svg]:size-4\"\n            >\n              <Lightbulb />\n            </span>\n            {tip}\n          </li>\n        ))}\n      </ul>\n      {action ? <div className=\"mt-2\">{action}</div> : null}\n    </div>\n  )\n}\n",
      "type": "registry:component",
      "target": "components/ui/empty-onboarding.tsx"
    }
  ],
  "categories": [
    "styled",
    "empty"
  ],
  "type": "registry:component"
}