{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "status-badge",
  "title": "StatusBadge",
  "description": "Dot-and-label status vocabulary for apps and branches, with a billing PlanBadge companion.",
  "registryDependencies": [
    "utils",
    "https://ui.neon.com/r/neon-tokens.json"
  ],
  "files": [
    {
      "path": "src/components/status-badge/status-badge.tsx",
      "content": "\"use client\";\n\nimport type { ComponentProps } from \"react\";\n\nimport { cn } from \"@/lib/utils\";\n\nexport type AppStatus = \"ready\" | \"provisioning\" | \"error\" | \"stopped\";\n\nexport type AppPlan = \"free\" | \"paid\";\n\nexport type StatusBadgeProps = Omit<ComponentProps<\"span\">, \"children\"> & {\n  /** Lifecycle state of the app or branch. */\n  status: AppStatus;\n  /** Override the default status text. */\n  label?: string;\n};\n\nexport type PlanBadgeProps = Omit<ComponentProps<\"span\">, \"children\"> & {\n  /** Billing plan of the tenant. */\n  plan: AppPlan;\n  /** Override the default plan text. */\n  label?: string;\n};\n\n/* ─────────────────────────────────────────────────────────\n * The shared status vocabulary: a square dot and a quiet\n * mono word, both flush with the token-radius system (sharp by default).\n * Color lives only in the dot — ready is primary, error is\n * destructive, stopped is muted. Provisioning breathes: a\n * slow 2.6s inhale/exhale with a soft glow, never a blink;\n * it holds steady under reduced motion. Text stays muted so\n * a wall of badges reads calmly on the dashboard.\n * ───────────────────────────────────────────────────────── */\nconst STATUS_LABEL: Record<AppStatus, string> = {\n  error: \"error\",\n  provisioning: \"provisioning\",\n  ready: \"ready\",\n  stopped: \"stopped\",\n};\n\nconst STATUS_DOT: Record<AppStatus, string> = {\n  error: \"bg-destructive\",\n  provisioning: \"neon-status-breathe bg-current text-primary\",\n  ready: \"bg-primary\",\n  stopped: \"bg-muted-foreground/50\",\n};\n\nexport const StatusBadge = ({\n  className,\n  label,\n  status,\n  ...props\n}: StatusBadgeProps) => (\n  <span\n    className={cn(\n      \"inline-flex items-center gap-1.5 rounded-sm border border-border/60 bg-card px-2 py-0.5 font-mono text-muted-foreground text-xs\",\n      className\n    )}\n    data-slot=\"status-badge\"\n    data-status={status}\n    {...props}\n  >\n    <span\n      aria-hidden=\"true\"\n      className={cn(\"size-1.5 shrink-0\", STATUS_DOT[status])}\n    />\n    {label ?? STATUS_LABEL[status]}\n  </span>\n);\n\n/** Billing-plan companion: same footprint, no dot, paid gets ink. */\nexport const PlanBadge = ({\n  className,\n  label,\n  plan,\n  ...props\n}: PlanBadgeProps) => (\n  <span\n    className={cn(\n      \"inline-flex items-center rounded-sm border border-border/60 px-2 py-0.5 font-mono text-xs\",\n      plan === \"paid\"\n        ? \"border-primary/40 text-primary\"\n        : \"bg-card text-muted-foreground\",\n      className\n    )}\n    data-plan={plan}\n    data-slot=\"plan-badge\"\n    {...props}\n  >\n    {label ?? plan}\n  </span>\n);\n",
      "type": "registry:component"
    }
  ],
  "type": "registry:component"
}