{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "empty-state",
  "title": "EmptyState",
  "description": "Intentional dashed-border placeholder with title, description, icon, and action slots.",
  "registryDependencies": [
    "utils",
    "https://ui.neon.com/r/neon-tokens.json"
  ],
  "files": [
    {
      "path": "src/components/empty-state/empty-state.tsx",
      "content": "\"use client\";\n\nimport type { ComponentProps, ReactNode } from \"react\";\n\nimport { cn } from \"@/lib/utils\";\n\nexport type EmptyStateProps = Omit<ComponentProps<\"div\">, \"title\"> & {\n  /** One line naming what's missing, e.g. \"No apps yet\". */\n  title: ReactNode;\n  /** Optional supporting line explaining how the space fills. */\n  description?: ReactNode;\n  /** Replace the faded Neon mark, e.g. with an icon. */\n  icon?: ReactNode;\n  /** Optional call to action, e.g. a Button. */\n  action?: ReactNode;\n  /** Vertical breathing room. */\n  size?: \"sm\" | \"md\" | \"lg\";\n  /**\n   * \"panel\" draws the dashed frame and stripe wash; \"bare\" drops both for\n   * embedding inside an already-bordered surface, e.g. a chat pane.\n   */\n  variant?: \"panel\" | \"bare\";\n};\n\n/* ─────────────────────────────────────────────────────────\n * An intentional empty state, not an absence. Three moves\n * from the Neon identity mark the space as \"waiting\":\n *\n *  texture   faint 45° hairline stripes wash the panel —\n *            the same fill MetricCard draws under trends,\n *            here reading as unclaimed ground\n *  mark      the Neon mark faded to a watermark — the\n *            brand holding the space open\n *  type      one foreground line, one muted line, action\n *            last; everything else stays quiet\n * ───────────────────────────────────────────────────────── */\nconst SIZE_PADDING: Record<NonNullable<EmptyStateProps[\"size\"]>, string> = {\n  lg: \"px-8 py-20\",\n  md: \"px-6 py-14\",\n  sm: \"px-4 py-8\",\n};\n\n/** Official Neon mark, from the published brand SVG (viewBox 0 0 31.3 31.6). */\nconst NEON_MARK_PATH =\n  \"M31.3,0v31.6l-12.2-10.6v10.6H0V0h31.3ZM3.8,27.7h11.4v-15.2l12.2,10.8V3.8H3.8s0,23.9,0,23.9Z\";\n\n/** The Neon mark, faded into the panel like a watermark. */\nconst FadedMark = () => (\n  <svg\n    aria-hidden=\"true\"\n    className=\"size-5 fill-muted-foreground/30\"\n    viewBox=\"0 0 31.3 31.6\"\n    xmlns=\"http://www.w3.org/2000/svg\"\n  >\n    <path d={NEON_MARK_PATH} />\n  </svg>\n);\n\nexport const EmptyState = ({\n  action,\n  className,\n  description,\n  icon,\n  size = \"md\",\n  title,\n  variant = \"panel\",\n  ...props\n}: EmptyStateProps) => (\n  <div\n    className={cn(\n      \"relative isolate flex flex-col items-center justify-center text-center\",\n      variant === \"panel\" && \"rounded-lg border border-border/60 border-dashed\",\n      SIZE_PADDING[size],\n      className\n    )}\n    data-slot=\"empty-state\"\n    data-variant={variant}\n    {...props}\n  >\n    {variant === \"panel\" ? (\n      <div\n        aria-hidden=\"true\"\n        className=\"-z-10 absolute inset-0 bg-[repeating-linear-gradient(-45deg,var(--border)_0_1px,transparent_1px_7px)] opacity-[0.18]\"\n      />\n    ) : null}\n    <span\n      aria-hidden=\"true\"\n      className=\"mb-3 text-muted-foreground/70 [&_svg:not([class*='size-'])]:size-5\"\n      data-slot=\"empty-state-icon\"\n    >\n      {icon ?? <FadedMark />}\n    </span>\n    <p className=\"text-balance font-medium text-foreground text-sm\">{title}</p>\n    {description ? (\n      <p className=\"mt-1.5 max-w-xs text-pretty text-muted-foreground text-xs leading-5\">\n        {description}\n      </p>\n    ) : null}\n    {action ? <div className=\"mt-5\">{action}</div> : null}\n  </div>\n);\n",
      "type": "registry:component"
    }
  ],
  "type": "registry:component"
}