{
  "schema": "helixui.components/v2",
  "generator": "helixui",
  "buildId": "444df7f",
  "generatedAt": "2026-06-18T04:22:55.247Z",
  "source": "https://helixui.ai",
  "count": 90,
  "contentHash": "sha256:6f763413951b26b2a842515950bbbfd4fd54e4619b94e7f5af918e65372c0063",
  "categories": [
    "chat",
    "data",
    "feedback",
    "form",
    "layout",
    "media",
    "navigation",
    "overlay",
    "primitive",
    "shell",
    "surface"
  ],
  "designMd": {
    "canonicalSpec": "https://github.com/google-labs-code/design.md",
    "canonicalVersion": "alpha",
    "systemStatement": "/DESIGN.md",
    "flavorSpec": "/DESIGN_MD_FORMAT.md",
    "flavorVersion": 1,
    "canonicalSections": [
      "Overview",
      "Colors",
      "Typography",
      "Layout",
      "Elevation & Depth",
      "Shapes",
      "Components",
      "Do's and Don'ts"
    ],
    "canonicalTokenBlocks": [
      "colors",
      "typography",
      "rounded",
      "spacing",
      "components"
    ],
    "canonicalComponentProps": [
      "backgroundColor",
      "textColor",
      "typography",
      "rounded",
      "padding",
      "size",
      "height",
      "width"
    ],
    "extensions": {
      "helixui": {
        "dnaGenes": {
          "accent": [
            "blue",
            "violet",
            "cyan",
            "green",
            "lime",
            "orange",
            "pink",
            "crimson",
            "gold"
          ],
          "chroma": [
            "muted",
            "standard",
            "vibrant"
          ],
          "lightness": [
            "light",
            "dark",
            "auto"
          ],
          "radius": [
            "sharp",
            "subtle",
            "standard",
            "rounded",
            "extreme"
          ],
          "density": [
            "compact",
            "comfortable",
            "spacious"
          ],
          "typography": [
            "sans",
            "grotesk",
            "rounded",
            "serif",
            "mono"
          ],
          "surface": [
            "flat",
            "elevated",
            "glassy"
          ],
          "motion": [
            "subtle",
            "standard",
            "lively"
          ]
        },
        "presets": {
          "wildtype": {
            "accent": "blue",
            "chroma": "standard",
            "lightness": "auto",
            "radius": "standard",
            "density": "comfortable",
            "typography": "sans",
            "surface": "elevated",
            "motion": "standard",
            "mood": "The default helixui appearance — calm, blue, comfortable."
          },
          "studio": {
            "accent": "cyan",
            "chroma": "muted",
            "lightness": "auto",
            "radius": "subtle",
            "density": "compact",
            "typography": "grotesk",
            "surface": "flat",
            "motion": "standard",
            "mood": "Compact, sharp, mono-feel for a code-heavy interface."
          },
          "botanic": {
            "accent": "green",
            "chroma": "standard",
            "lightness": "auto",
            "radius": "rounded",
            "density": "spacious",
            "typography": "rounded",
            "surface": "elevated",
            "motion": "standard",
            "mood": "Soft, warm, organic — for content-first surfaces."
          },
          "solstice": {
            "accent": "orange",
            "chroma": "vibrant",
            "lightness": "auto",
            "radius": "rounded",
            "density": "comfortable",
            "typography": "sans",
            "surface": "elevated",
            "motion": "standard",
            "mood": "Warm, vibrant accent for marketing or playful apps."
          },
          "noir": {
            "accent": "crimson",
            "chroma": "muted",
            "lightness": "dark",
            "radius": "sharp",
            "density": "compact",
            "typography": "grotesk",
            "surface": "flat",
            "motion": "standard",
            "mood": "Dark, sharp, crimson — for tools you live in."
          }
        },
        "expression": {
          "accent": "colors.brand-* (OKLCH ramp from accent.hue × chroma.multiplier)",
          "density": "spacing.* (× density.spacing on the 13-step base)",
          "radius": "rounded.{sm,md,lg,xl} (× radius.factor on the 4-step base)",
          "typography": "typography.*.fontFamily + fontSize (family stack + scale multiplier)",
          "surface": "shadow tokens (sm/md/lg) — body-section concern",
          "motion": "duration tokens (fast/normal/slow) — body-section concern"
        },
        "designSystemKinds": [
          "design-system",
          "app",
          "site",
          "docs",
          "extension",
          "mobile"
        ],
        "mediums": [
          "web",
          "mobile-web",
          "mobile-native",
          "desktop",
          "tv"
        ],
        "themes": [
          "light",
          "dark",
          "auto"
        ]
      }
    }
  },
  "components": [
    {
      "name": "ActionSheet",
      "slug": "action-sheet",
      "package": "@helixui/core",
      "import": "import { ActionSheet, type ActionSheetAction } from '@helixui/core'",
      "description": "An iOS-style modal sheet that slides up from the bottom edge with a list of actions. Different from Sheet — Sheet is a side drawer, ActionSheet is a vertical action menu.",
      "category": "overlay",
      "tags": [
        "mobile",
        "modal",
        "menu",
        "bottom-sheet",
        "actions",
        "ios"
      ],
      "status": "stable",
      "since": "0.5.0",
      "layout": {
        "display": "portal",
        "width": "fill",
        "height": "content",
        "intrinsicSize": "pinned to bottom edge, max-h ~80vh, scrolls inside",
        "stackable": false,
        "fullBleed": true
      },
      "anatomy": "[overlay (dimmed)]\n  ┌── action sheet panel (slides up from bottom) ──┐\n  │  Title (optional)                              │\n  │ ─────────────────────────────────────────────  │  n  │  • Action 1                                    │\n  │  • Action 2                                    │\n  │  • Destructive action  (red)                   │\n  │ ─────────────────────────────────────────────  │\n  │  Cancel                                        │\n  └────────────────────────────────────────────────┘\n",
      "visual": "A bottom-anchored panel with rounded top corners (radius.lg) that slides up from the bottom edge over a dimmed overlay. Each action is a full-width row separated by hairlines; destructive rows render in danger tone. A trailing Cancel row is separated by a small gap. Mounts with a translateY animation that respects prefers-reduced-motion.\n",
      "props": [
        {
          "name": "title",
          "type": "ReactNode",
          "default": "",
          "description": "Top centered title."
        },
        {
          "name": "description",
          "type": "ReactNode",
          "default": "",
          "description": "Sub-title under the title."
        },
        {
          "name": "actions",
          "type": "ActionSheetAction[]",
          "default": "",
          "description": "Required. List of actions; each has `id`, `label`, optional `description`, `icon`, `destructive`, `disabled`, and `onAction(close)`."
        },
        {
          "name": "cancelLabel",
          "type": "ReactNode",
          "default": "Cancel",
          "description": "Label for the bottom cancel button. Set null to hide."
        },
        {
          "name": "isOpen",
          "type": "boolean",
          "default": "",
          "description": "Controlled open state."
        },
        {
          "name": "defaultOpen",
          "type": "boolean",
          "default": false,
          "description": "Uncontrolled initial open."
        },
        {
          "name": "onOpenChange",
          "type": "(open: boolean) => void",
          "default": "",
          "description": "Open change handler."
        }
      ],
      "slots": [],
      "tokens": [
        "color.bg.surface.default",
        "color.bg.action.neutral.default",
        "color.text.primary",
        "color.text.secondary",
        "color.text.muted",
        "color.text.action.brand",
        "color.text.action.danger",
        "color.border.default",
        "color.border.focus",
        "radius.lg",
        "space.1",
        "space.2",
        "space.3",
        "space.4",
        "font.family.sans",
        "font.size.xs",
        "font.size.sm",
        "font.size.md",
        "font.weight.medium",
        "font.weight.semibold"
      ],
      "a11y": {
        "role": "dialog",
        "keyboard": [
          {
            "key": "Escape",
            "action": "Close."
          }
        ],
        "notes": [
          "Built on react-aria-components Modal — focus trap, restoration, dismiss on overlay click, all handled.",
          "The cancel button is a button (not an action item) so it visually separates from the list — matches iOS pattern."
        ]
      },
      "composes_with": [
        {
          "component": "Sheet",
          "relation": "alternative",
          "note": "Use Sheet for general side drawers; ActionSheet is the iOS-style action menu only."
        },
        {
          "component": "Menu",
          "relation": "alternative",
          "note": "On desktop prefer Menu anchored to a trigger."
        },
        {
          "component": "Button",
          "relation": "trigger",
          "note": "Common opener."
        },
        {
          "component": "Dialog",
          "relation": "sibling"
        },
        {
          "component": "FAB",
          "relation": "sibling"
        }
      ],
      "related": [
        "Sheet",
        "Dialog",
        "FAB"
      ],
      "when_to_use": [],
      "pitfalls": [],
      "prompt_examples": [
        {
          "intent": "mobile destructive choice",
          "prompt": "show a delete / cancel sheet on tap",
          "snippet": "<ActionSheet\n  isOpen={open}\n  onOpenChange={setOpen}\n  actions={[\n    { label: 'Delete', tone: 'danger', onPress: handleDelete },\n    { label: 'Cancel', tone: 'neutral' },\n  ]}\n/>\n"
        },
        {
          "intent": "photo source picker",
          "prompt": "Take photo / Choose from library / Cancel sheet",
          "snippet": "<ActionSheet\n  title=\"Add photo\"\n  isOpen={open}\n  onOpenChange={setOpen}\n  actions={[\n    { label: 'Take Photo', onPress: takePhoto },\n    { label: 'Choose from Library', onPress: pick },\n    { label: 'Cancel' },\n  ]}\n/>\n"
        }
      ]
    },
    {
      "name": "AppShell",
      "slug": "app-shell",
      "package": "@helixui/core",
      "import": "import { AppShell } from '@helixui/core'",
      "description": "A responsive application layout — sticky header, persistent sidebar on desktop, sidebar hidden on mobile (caller composes a Sheet drawer).",
      "category": "shell",
      "tags": [
        "layout",
        "shell",
        "header",
        "sidebar",
        "responsive",
        "top-level"
      ],
      "status": "stable",
      "since": "0.2.0",
      "layout": {
        "display": "grid",
        "width": "fill",
        "height": "fill",
        "intrinsicSize": "fills viewport, sidebar 240px (configurable), header sticky top",
        "stackable": false,
        "fullBleed": true
      },
      "anatomy": "┌─ header (sticky top) ────────────────────────────────┐\n│ logo  …  search  …  avatar                           │\n├──────────┬───────────────────────────────────────────┤\n│ sidebar  │ <main>                                    │\n│ (≥768px) │   PageHeader                              │\n│          │   <page content>                          │\n│          │                                           │\n│          │                                           │\n└──────────┴───────────────────────────────────────────┘\n ↑ sidebar collapses below collapseBreakpoint;\n ↑ caller must render hamburger + Sheet for mobile.\n",
      "visual": "A desktop-first chrome: a sticky top header (border-bottom by border.default), a fixed-width sidebar on the\nleft, and a scrolling main column. Below `collapseBreakpoint` the sidebar disappears and main becomes\nfull-bleed; the caller is responsible for wiring a hamburger + Sheet drawer to expose it again.\n",
      "props": [
        {
          "name": "sidebar",
          "type": "ReactNode",
          "default": "",
          "description": "Left rail content. Shown on desktop, hidden below the breakpoint."
        },
        {
          "name": "header",
          "type": "ReactNode",
          "default": "",
          "description": "Sticky top bar."
        },
        {
          "name": "sidebarWidth",
          "type": "number | string",
          "default": 240,
          "description": "Sidebar width. Number → px."
        },
        {
          "name": "collapseBreakpoint",
          "type": "number",
          "default": 768,
          "description": "Min viewport (px) for sidebar to be visible."
        }
      ],
      "slots": [
        "children — main content area"
      ],
      "tokens": [
        "color.bg.surface.default",
        "color.text.primary",
        "color.border.default"
      ],
      "a11y": {
        "notes": [
          "Sidebar uses `<aside>`; main uses `<main>`. Wrap nav inside the sidebar in `<nav aria-label>` (helixui Sidebar component does this).",
          "On mobile the sidebar is `display:none`. To expose it, render a hamburger in `header` that opens a `Sheet side=\"start\"` with the same sidebar content."
        ]
      },
      "composes_with": [
        {
          "component": "Sidebar",
          "relation": "slot",
          "note": "Fills the `sidebar` prop."
        },
        {
          "component": "PageHeader",
          "relation": "child",
          "note": "Common first child of `children` to title each route."
        },
        {
          "component": "Sheet",
          "relation": "sibling",
          "note": "Pair with Sheet (side='start') for the mobile sidebar drawer."
        },
        {
          "component": "SafeArea",
          "relation": "parent",
          "note": "Wrap AppShell in SafeArea on mobile builds."
        }
      ],
      "related": [
        "Sidebar",
        "PageHeader"
      ],
      "when_to_use": [],
      "pitfalls": [],
      "prompt_examples": [
        {
          "intent": "scaffold a logged-in app layout",
          "prompt": "give me an app layout with a top bar and side nav",
          "snippet": "<AppShell\n  header={<TopBar />}\n  sidebar={<Sidebar><Sidebar.Group><Sidebar.Item href=\"/\" active>Home</Sidebar.Item></Sidebar.Group></Sidebar>}\n>\n  <PageHeader title=\"Home\" />\n  {/* page */}\n</AppShell>\n"
        },
        {
          "intent": "responsive — show the sidebar in a drawer on mobile",
          "prompt": "make the sidebar slide in on mobile",
          "snippet": "const [open, setOpen] = useState(false);\n<>\n  <AppShell\n    header={<TopBar onMenu={() => setOpen(true)} />}\n    sidebar={<Sidebar>…</Sidebar>}\n  >\n    {content}\n  </AppShell>\n  <Sheet side=\"start\" isOpen={open} onOpenChange={setOpen}>\n    <Sidebar>…</Sidebar>\n  </Sheet>\n</>\n"
        },
        {
          "intent": "narrow icon-only sidebar",
          "prompt": "use a 64px icon-only sidebar",
          "snippet": "<AppShell sidebarWidth={64} sidebar={<IconRail />}>\n  ...\n</AppShell>\n"
        }
      ]
    },
    {
      "name": "AttachmentTile",
      "slug": "attachment-tile",
      "package": "@helixui/core",
      "import": "import { AttachmentTile } from '@helixui/core'",
      "description": "A compact tile for a file attachment — thumbnail or icon + name + size + optional remove or upload progress.",
      "category": "media",
      "tags": [
        "file",
        "attachment",
        "upload",
        "preview",
        "tile"
      ],
      "status": "stable",
      "since": "0.3.0",
      "layout": {
        "display": "flex",
        "width": "fill",
        "height": "content",
        "intrinsicSize": "~56px tall, hugs available width",
        "stackable": true,
        "fullBleed": false
      },
      "anatomy": "┌──────────────────────────────────────────┐\n│  [thumb/icon]  filename.ext           [×] │\n│                12 KB · uploading 60%      │\n└──────────────────────────────────────────┘\n",
      "visual": "A horizontal tile with a square thumbnail or file-type icon on the left, name + meta in the middle (font.size.sm), and an optional remove button on the right. While uploading, a thin progress bar overlays the bottom edge.\n",
      "props": [
        {
          "name": "name",
          "type": "ReactNode",
          "default": "",
          "description": "File name."
        },
        {
          "name": "size",
          "type": "ReactNode",
          "default": "",
          "description": "Pre-formatted size ('1.4 MB')."
        },
        {
          "name": "thumbnail",
          "type": "string",
          "default": "",
          "description": "Image URL — when set, replaces the file glyph with a thumbnail."
        },
        {
          "name": "icon",
          "type": "ReactNode",
          "default": "",
          "description": "Custom icon node (overrides default file glyph)."
        },
        {
          "name": "progress",
          "type": "number",
          "default": "",
          "description": "0–100. While set, shows a progress fill instead of remove."
        },
        {
          "name": "onRemove",
          "type": "() => void",
          "default": "",
          "description": "Show a close button that triggers this callback. Hidden during upload."
        },
        {
          "name": "compact",
          "type": "boolean",
          "default": false,
          "description": "Hide the size line and shrink padding (for inline use in messages)."
        }
      ],
      "slots": [],
      "tokens": [
        "color.bg.surface.default",
        "color.bg.action.neutral.default",
        "color.bg.action.brand.default",
        "color.border.default",
        "color.border.focus",
        "color.text.primary",
        "color.text.secondary",
        "color.text.muted",
        "radius.md",
        "radius.sm",
        "radius.full",
        "space.2",
        "font.family.sans",
        "font.size.xs",
        "font.size.sm",
        "font.weight.medium"
      ],
      "a11y": {
        "notes": [
          "Remove button has `aria-label=\"Remove attachment\"`.",
          "Progress is shown visually only — pair with a `aria-live` status if the user must hear it."
        ]
      },
      "composes_with": [
        {
          "component": "ChatComposer",
          "relation": "child",
          "note": "Common in the chat composer attachment row."
        },
        {
          "component": "List",
          "relation": "child",
          "note": "Each List row may render as an AttachmentTile."
        },
        {
          "component": "ChatMessage",
          "relation": "sibling"
        }
      ],
      "related": [
        "ChatComposer",
        "ChatMessage"
      ],
      "when_to_use": [],
      "pitfalls": [],
      "prompt_examples": [
        {
          "intent": "show an uploaded file",
          "prompt": "render a docx attachment with a remove X",
          "snippet": "<AttachmentTile name=\"report.docx\" size=\"48 KB\" onRemove={handleRemove} />\n"
        },
        {
          "intent": "in-progress upload",
          "prompt": "show upload progress on an image",
          "snippet": "<AttachmentTile name=\"photo.jpg\" size=\"2.4 MB\" progress={0.6} />\n"
        }
      ]
    },
    {
      "name": "Avatar",
      "slug": "avatar",
      "package": "@helixui/core",
      "import": "import { Avatar } from '@helixui/core'",
      "description": "A user or entity image with text fallback when the image is missing or fails to load.",
      "category": "media",
      "tags": [
        "user",
        "identity",
        "image",
        "fallback",
        "circle"
      ],
      "status": "stable",
      "since": "0.1.0",
      "layout": {
        "display": "inline-block",
        "width": "content",
        "height": "content",
        "intrinsicSize": "24/32/40/48/64px square (xs/sm/md/lg/xl)",
        "stackable": true,
        "fullBleed": false
      },
      "anatomy": "●  ← circular image; if missing → initials on tinted bg\n",
      "visual": "A circular image with rounded fallback when the image fails to load. Fallback shows uppercase initials on a deterministic tinted background derived from the name. Optional ring (border) or PresenceDot can sit on top.\n",
      "props": [
        {
          "name": "src",
          "type": "string",
          "default": "",
          "description": "Image URL."
        },
        {
          "name": "alt",
          "type": "string",
          "default": "",
          "description": "Accessible label. Used as `aria-label`. If empty, `fallback` is used."
        },
        {
          "name": "fallback",
          "type": "string",
          "default": "",
          "description": "Text to display when no image is available — typically initials."
        },
        {
          "name": "size",
          "type": "'xs' | 'sm' | 'md' | 'lg' | 'xl'",
          "default": "md",
          "description": "Avatar size."
        },
        {
          "name": "shape",
          "type": "'circle' | 'square'",
          "default": "circle",
          "description": "Avatar shape."
        }
      ],
      "slots": [],
      "tokens": [
        "color.bg.action.neutral.default",
        "color.text.secondary",
        "font.family.sans",
        "font.weight.semibold",
        "font.size.xs",
        "font.size.sm",
        "font.size.md",
        "font.size.xl",
        "radius.full",
        "radius.md"
      ],
      "a11y": {
        "notes": [
          "Always pass `alt` when the avatar identifies a real person or entity. Use empty `alt=\"\"` only when the avatar is purely decorative and accompanied by visible text.",
          "Initials in `fallback` should be 1–2 characters."
        ]
      },
      "composes_with": [
        {
          "component": "AvatarGroup",
          "relation": "child",
          "note": "Used inside AvatarGroup for stacked rows."
        },
        {
          "component": "PresenceDot",
          "relation": "sibling",
          "note": "Render PresenceDot anchored to the avatar."
        },
        {
          "component": "ChatMessage",
          "relation": "child",
          "note": "Common as the leading slot of a ChatMessage."
        }
      ],
      "related": [],
      "when_to_use": [],
      "pitfalls": [],
      "prompt_examples": [
        {
          "intent": "user avatar with initials fallback",
          "prompt": "avatar for \"Sara Tang\"",
          "snippet": "<Avatar src={user.imageUrl} fallback=\"ST\" alt=\"Sara Tang\" />\n"
        },
        {
          "intent": "large avatar in a profile header",
          "prompt": "64px avatar in a profile card",
          "snippet": "<Avatar size=\"xl\" src={user.imageUrl} fallback=\"ST\" />\n"
        }
      ]
    },
    {
      "name": "AvatarGroup",
      "slug": "avatar-group",
      "package": "@helixui/core",
      "import": "import { AvatarGroup } from '@helixui/core'",
      "description": "A row of overlapping avatars with an optional overflow chip — `+N` for hidden members.",
      "category": "media",
      "tags": [
        "users",
        "collaborators",
        "stacked",
        "overflow"
      ],
      "status": "stable",
      "since": "0.2.0",
      "layout": {
        "display": "inline-flex",
        "width": "content",
        "height": "content",
        "intrinsicSize": "hugs N avatars with negative inline gap",
        "stackable": true,
        "fullBleed": false
      },
      "anatomy": "( ●●●●  +12 )  ← overlapping avatars + overflow chip\n",
      "visual": "A row of avatars with negative left margin so each avatar overlaps the previous by ~30%. Each has a thin border that matches the surface so the overlap reads as separation. A `+N` overflow chip is the last child when there are more than `max` avatars.\n",
      "props": [
        {
          "name": "max",
          "type": "number",
          "default": "",
          "description": "Cap visible avatars; rest go into the +N chip."
        },
        {
          "name": "size",
          "type": "'xs' | 'sm' | 'md' | 'lg' | 'xl'",
          "default": "md",
          "description": "Avatar size; applied to all children."
        },
        {
          "name": "total",
          "type": "number",
          "default": "",
          "description": "Override total count when `children` is only the visible subset."
        }
      ],
      "slots": [
        "children — Avatar elements"
      ],
      "tokens": [
        "color.bg.surface.default",
        "color.bg.action.neutral.default",
        "color.text.secondary",
        "radius.full",
        "font.family.sans",
        "font.weight.semibold",
        "font.size.xs",
        "font.size.sm",
        "font.size.md",
        "font.size.xl"
      ],
      "a11y": {
        "notes": [
          "The overflow chip has `aria-label=\"N more\"`.",
          "Pass meaningful `alt` to each Avatar for screen-reader output."
        ]
      },
      "composes_with": [
        {
          "component": "Avatar",
          "relation": "child",
          "note": "Each child is an Avatar."
        },
        {
          "component": "List",
          "relation": "child",
          "note": "Often rendered as the trailing slot of a list row."
        }
      ],
      "related": [
        "Avatar"
      ],
      "when_to_use": [],
      "pitfalls": [],
      "prompt_examples": [
        {
          "intent": "show a small collaborator pile",
          "prompt": "show the first 4 avatars and +N chip for the rest",
          "snippet": "<AvatarGroup max={4}>\n  {users.map(u => <Avatar key={u.id} fallback={u.initials} src={u.image} />)}\n</AvatarGroup>\n"
        }
      ]
    },
    {
      "name": "Badge",
      "slug": "badge",
      "package": "@helixui/core",
      "import": "import { Badge } from '@helixui/core'",
      "description": "A small inline label for status, counts, or categories.",
      "category": "feedback",
      "tags": [
        "label",
        "count",
        "status",
        "pill",
        "chip"
      ],
      "status": "stable",
      "since": "0.1.0",
      "layout": {
        "display": "inline-block",
        "width": "content",
        "height": "content",
        "intrinsicSize": "~16-22px tall, hugs text",
        "stackable": true,
        "fullBleed": false
      },
      "anatomy": "( New )   ( 3 )   ( beta )   ← small pill of text\n",
      "visual": "A small pill (radius.full) with a tone-tinted background and matching foreground text. Compact font (font.size.xs) with semibold weight. Solid / soft / outline variants control emphasis. Often used inline next to a heading or appended to a list item.\n",
      "props": [
        {
          "name": "tone",
          "type": "'neutral' | 'brand' | 'danger' | 'success' | 'warning'",
          "default": "neutral",
          "description": "Color intent."
        },
        {
          "name": "variant",
          "type": "'soft' | 'solid' | 'outline'",
          "default": "soft",
          "description": "Visual treatment."
        },
        {
          "name": "size",
          "type": "'sm' | 'md' | 'lg'",
          "default": "md",
          "description": "Badge size. `sm` for compact inline chips, `md` for section eyebrows / statuses, `lg` for prominent hero / featured-card headers (uppercase by default)."
        }
      ],
      "slots": [],
      "tokens": [
        "color.bg.action.brand.subtle",
        "color.bg.action.brand.default",
        "color.bg.action.danger.subtle",
        "color.bg.action.danger.default",
        "color.bg.action.success.subtle",
        "color.bg.action.success.default",
        "color.bg.action.warning.subtle",
        "color.bg.action.warning.default",
        "color.bg.action.neutral.default",
        "color.bg.surface.inverse",
        "color.text.action.brand",
        "color.text.action.danger",
        "color.text.action.success",
        "color.text.action.warning",
        "color.text.primary",
        "color.text.inverse",
        "color.text.on.brand",
        "color.text.on.danger",
        "color.text.on.success",
        "color.text.on.warning",
        "radius.full",
        "space.1",
        "space.2",
        "space.3"
      ],
      "a11y": {
        "notes": [
          "Color alone is not enough — pair the tone with a clear text label.",
          "For dynamic counts, place the badge near content it relates to via `aria-describedby`."
        ]
      },
      "composes_with": [
        {
          "component": "Sidebar",
          "relation": "child",
          "note": "Often appears as `Sidebar.Item.trailing`."
        },
        {
          "component": "List",
          "relation": "child",
          "note": "Common in trailing slot of a List row."
        },
        {
          "component": "Tabs",
          "relation": "child",
          "note": "Counts next to tab labels."
        }
      ],
      "related": [],
      "when_to_use": [],
      "pitfalls": [],
      "prompt_examples": [
        {
          "intent": "tag a feature as new",
          "prompt": "a green New badge",
          "snippet": "<Badge tone=\"success\">New</Badge>\n"
        },
        {
          "intent": "unread count",
          "prompt": "show \"12\" as a count badge",
          "snippet": "<Badge tone=\"brand\" variant=\"solid\">12</Badge>\n"
        }
      ]
    },
    {
      "name": "Banner",
      "slug": "banner",
      "package": "@helixui/core",
      "import": "import { Banner } from '@helixui/core'",
      "description": "A persistent page-level alert. Stronger than Callout, less interruptive than Toast or Dialog.",
      "category": "feedback",
      "tags": [
        "alert",
        "page-level",
        "persistent",
        "announcement"
      ],
      "status": "stable",
      "since": "0.2.0",
      "layout": {
        "display": "block",
        "width": "fill",
        "height": "content",
        "intrinsicSize": "full-bleed at the top of a page or section",
        "stackable": false,
        "fullBleed": true
      },
      "anatomy": "┌─[icon]── Title — short description ───────── [Action] [×] ─┐\n└────────────────────────────────────────────────────────────────┘\n",
      "visual": "A full-bleed colored band at the top of a page or section. Tinted background per tone (info/success/warning/danger), a leading icon, message text, optional action button, and a dismiss × on the right.\n",
      "props": [
        {
          "name": "tone",
          "type": "'info' | 'success' | 'warning' | 'danger' | 'neutral'",
          "default": "info",
          "description": "Color intent."
        },
        {
          "name": "title",
          "type": "ReactNode",
          "default": "",
          "description": "Bold headline."
        },
        {
          "name": "description",
          "type": "ReactNode",
          "default": "",
          "description": "Body text."
        },
        {
          "name": "icon",
          "type": "ReactNode",
          "default": "",
          "description": "Leading icon."
        },
        {
          "name": "actions",
          "type": "ReactNode",
          "default": "",
          "description": "Right-aligned actions."
        },
        {
          "name": "dismissible",
          "type": "boolean",
          "default": false,
          "description": "Show a close button."
        },
        {
          "name": "open",
          "type": "boolean",
          "default": "",
          "description": "Controlled visibility. When omitted, the close button manages internal state."
        },
        {
          "name": "onOpenChange",
          "type": "(open: boolean) => void",
          "default": "",
          "description": "Visibility change handler."
        }
      ],
      "slots": [
        "children — additional content below description"
      ],
      "tokens": [
        "color.bg.action.brand.subtle",
        "color.bg.action.brand.default",
        "color.bg.action.success.subtle",
        "color.bg.action.success.default",
        "color.bg.action.warning.subtle",
        "color.bg.action.warning.default",
        "color.bg.action.danger.subtle",
        "color.bg.action.danger.default",
        "color.bg.surface.subtle",
        "color.text.action.brand",
        "color.text.action.success",
        "color.text.action.warning",
        "color.text.action.danger",
        "color.text.primary",
        "color.border.default",
        "radius.md",
        "radius.sm",
        "space.2",
        "space.3",
        "space.4",
        "font.family.sans",
        "font.size.sm",
        "font.weight.semibold",
        "font.lineHeight.normal"
      ],
      "a11y": {
        "role": "status",
        "notes": [
          "For non-interruptive page state. For critical errors that block the user, prefer Dialog.",
          "Close button has `aria-label=\"Dismiss\"`."
        ]
      },
      "composes_with": [
        {
          "component": "PageHeader",
          "relation": "sibling",
          "note": "Renders above PageHeader at the top of a page."
        },
        {
          "component": "Callout",
          "relation": "alternative",
          "note": "Use Callout inline within content; Banner is page-level."
        },
        {
          "component": "Toast",
          "relation": "alternative",
          "note": "Toast for transient; Banner for persistent."
        },
        {
          "component": "Dialog",
          "relation": "sibling"
        }
      ],
      "related": [
        "Callout",
        "Toast",
        "Dialog"
      ],
      "when_to_use": [],
      "pitfalls": [],
      "prompt_examples": [
        {
          "intent": "announce a maintenance window",
          "prompt": "page-wide maintenance notice",
          "snippet": "<Banner tone=\"warning\" title=\"Maintenance window\" description=\"We'll be down 9–10pm UTC tonight.\" onDismiss={hide} />\n"
        },
        {
          "intent": "success after a long action",
          "prompt": "banner saying changes published",
          "snippet": "<Banner tone=\"success\" title=\"Changes published.\" />\n"
        }
      ]
    },
    {
      "name": "BottomNav",
      "slug": "bottom-nav",
      "package": "@helixui/core",
      "import": "import { BottomNav } from '@helixui/core'",
      "description": "A fixed bottom tab bar — primary navigation pattern on mobile. Items can be links or buttons; supports an active state, optional icon, and a number/dot badge.",
      "category": "navigation",
      "tags": [
        "mobile",
        "tabs",
        "fixed-bottom",
        "tab-bar",
        "primary-nav"
      ],
      "status": "stable",
      "since": "0.5.0",
      "layout": {
        "display": "fixed",
        "width": "fill",
        "height": "content",
        "intrinsicSize": "pinned to bottom edge, ~56-64px tall",
        "stackable": false,
        "fullBleed": true
      },
      "anatomy": "┌────────────────────────────────────────────────┐  ← page content scrolls\n│                                                │\n├────────────────────────────────────────────────┤\n│   ⌂ Home    ⊙ Search    ◎ Profile              │  ← BottomNav (fixed)\n└────────────────────────────────────────────────┘\n",
      "visual": "A fixed bottom bar with 3–5 evenly spaced items, each an icon over a tiny label. Active item uses brand foreground; inactive use muted text. Optional Badge/dot floats at top-right of the icon. On notch devices, padding reads `env(safe-area-inset-bottom)`.\n",
      "props": [
        {
          "name": "label",
          "type": "string",
          "default": "Primary",
          "description": "`aria-label` on the wrapping `<nav>`."
        }
      ],
      "slots": [
        "BottomNav.Item — anchor (when `href`) or button. Props: `icon`, `active` (sets `aria-current=\"page\"`), `badge` (number → count, true → dot)."
      ],
      "tokens": [
        "color.bg.surface.default",
        "color.bg.action.danger.default",
        "color.text.secondary",
        "color.text.action.brand",
        "color.text.on.danger",
        "color.border.default",
        "color.border.focus",
        "radius.full",
        "font.family.sans",
        "font.size.xs",
        "font.weight.medium",
        "font.weight.semibold"
      ],
      "a11y": {
        "notes": [
          "Wrapped in `<nav aria-label>`. Active item is rendered with `aria-current=\"page\"`.",
          "Includes `padding-bottom: env(safe-area-inset-bottom)` so it sits above the iOS home indicator when used as a fixed bar."
        ]
      },
      "composes_with": [
        {
          "component": "SafeArea",
          "relation": "parent",
          "note": "Wrap in SafeArea on mobile builds for inset."
        },
        {
          "component": "Sidebar",
          "relation": "alternative",
          "note": "Sidebar is desktop primary nav; BottomNav is mobile."
        },
        {
          "component": "Tabs",
          "relation": "alternative",
          "note": "Tabs for in-page section switching; BottomNav for app-level nav."
        },
        {
          "component": "FAB",
          "relation": "sibling"
        },
        {
          "component": "AppShell",
          "relation": "sibling"
        }
      ],
      "related": [
        "SafeArea",
        "FAB",
        "AppShell"
      ],
      "when_to_use": [],
      "pitfalls": [],
      "prompt_examples": [
        {
          "intent": "mobile primary nav",
          "prompt": "three-tab bottom bar Home, Search, Profile",
          "snippet": "<BottomNav>\n  <BottomNav.Item href=\"/\" icon={<HomeIcon />} active>Home</BottomNav.Item>\n  <BottomNav.Item href=\"/search\" icon={<SearchIcon />}>Search</BottomNav.Item>\n  <BottomNav.Item href=\"/me\" icon={<UserIcon />}>Profile</BottomNav.Item>\n</BottomNav>\n"
        },
        {
          "intent": "tab with unread dot",
          "prompt": "show a dot badge on Inbox",
          "snippet": "<BottomNav.Item href=\"/inbox\" icon={<InboxIcon />} badge=\"dot\">Inbox</BottomNav.Item>\n"
        }
      ]
    },
    {
      "name": "Box",
      "slug": "box",
      "package": "@helixui/core",
      "import": "import { Box } from '@helixui/core'",
      "description": "A neutral container with padding and margin shorthands wired to space tokens.",
      "category": "layout",
      "tags": [
        "primitive",
        "container",
        "spacing",
        "utility"
      ],
      "status": "stable",
      "since": "0.1.0",
      "layout": {
        "display": "block",
        "width": "auto",
        "height": "auto",
        "intrinsicSize": "content size; tunable padding/margin via props",
        "stackable": true,
        "fullBleed": false
      },
      "anatomy": "[ <children> ]  ← unstyled container with padding/margin shorthands\n",
      "visual": "A presentational `<div>` with token-aware padding (`p`, `px`, `py`, …) and margin shorthands. No background, border, or radius by default — strictly a layout primitive.\n",
      "props": [
        {
          "name": "p",
          "type": "number | string",
          "default": "",
          "description": "Padding on all sides. Numeric input → `space.N` token; string passes through as raw CSS."
        },
        {
          "name": "px",
          "type": "number | string",
          "default": "",
          "description": "Inline (left+right) padding."
        },
        {
          "name": "py",
          "type": "number | string",
          "default": "",
          "description": "Block (top+bottom) padding."
        },
        {
          "name": "m",
          "type": "number | string",
          "default": "",
          "description": "Margin on all sides."
        },
        {
          "name": "mx",
          "type": "number | string",
          "default": "",
          "description": "Inline margin."
        },
        {
          "name": "my",
          "type": "number | string",
          "default": "",
          "description": "Block margin."
        },
        {
          "name": "...rest",
          "type": "HTMLAttributes<HTMLDivElement>",
          "default": "",
          "description": "Native div attributes."
        }
      ],
      "slots": [],
      "tokens": [
        "space.0",
        "space.1",
        "space.2",
        "space.3",
        "space.4",
        "space.5",
        "space.6",
        "space.8",
        "space.10",
        "space.12",
        "space.16",
        "space.20",
        "space.24"
      ],
      "a11y": {
        "notes": [
          "Box is presentational. Use a semantic element where possible (`<section>`, `<article>`, etc.)."
        ]
      },
      "composes_with": [
        {
          "component": "Stack",
          "relation": "alternative",
          "note": "Use Stack when you want a flex column/row of children."
        },
        {
          "component": "Flex",
          "relation": "alternative",
          "note": "Use Flex for explicit flexbox layout."
        },
        {
          "component": "Grid",
          "relation": "alternative",
          "note": "Use Grid for 2-D layout."
        }
      ],
      "related": [
        "Flex",
        "Grid",
        "Stack"
      ],
      "when_to_use": [],
      "pitfalls": [],
      "prompt_examples": [
        {
          "intent": "pad a section",
          "prompt": "add 24px of padding around this group",
          "snippet": "<Box p={6}>{children}</Box>\n"
        },
        {
          "intent": "horizontal rule of margin",
          "prompt": "add top margin",
          "snippet": "<Box mt={4}>{children}</Box>\n"
        }
      ]
    },
    {
      "name": "Breadcrumb",
      "slug": "breadcrumb",
      "package": "@helixui/core",
      "import": "import { Breadcrumbs, Breadcrumb } from '@helixui/core'",
      "description": "A trail of pages above the current page. The last item is treated as the current page.",
      "category": "navigation",
      "tags": [
        "trail",
        "hierarchy",
        "path"
      ],
      "status": "stable",
      "since": "0.1.0",
      "layout": {
        "display": "inline-flex",
        "width": "fill",
        "height": "content",
        "intrinsicSize": "one line, wraps on overflow",
        "stackable": false,
        "fullBleed": false
      },
      "anatomy": "Home › Workspace › Projects › Current page\n",
      "visual": "A horizontal row of small links separated by a chevron-like glyph. The last item is rendered as plain text (current page) and gets `aria-current=page`. Truncates with ellipsis when constrained.\n",
      "props": [
        {
          "name": "href",
          "type": "string",
          "default": "",
          "description": "Link target. The last Breadcrumb in the list should omit `href` and renders as `aria-current=\"page\"`."
        }
      ],
      "slots": [
        "Breadcrumbs children — Breadcrumb items",
        "Breadcrumb children — page label"
      ],
      "tokens": [
        "color.text.primary",
        "color.text.secondary",
        "color.text.muted",
        "color.border.focus",
        "radius.sm",
        "space.1",
        "space.2",
        "font.family.sans",
        "font.size.sm",
        "font.weight.medium"
      ],
      "a11y": {
        "notes": [
          "Built on `react-aria-components` Breadcrumbs — emits a `<nav aria-label=\"Breadcrumbs\">` wrapper automatically.",
          "The last item should omit `href`; helixui renders it as the current page with `aria-current=\"page\"`."
        ]
      },
      "composes_with": [
        {
          "component": "PageHeader",
          "relation": "slot",
          "note": "Common in PageHeader.breadcrumb slot."
        }
      ],
      "related": [],
      "when_to_use": [],
      "pitfalls": [],
      "prompt_examples": [
        {
          "intent": "show parent path on a settings page",
          "prompt": "breadcrumb Home / Settings / Billing",
          "snippet": "<Breadcrumbs>\n  <Breadcrumb href=\"/\">Home</Breadcrumb>\n  <Breadcrumb href=\"/settings\">Settings</Breadcrumb>\n  <Breadcrumb>Billing</Breadcrumb>\n</Breadcrumbs>\n"
        }
      ]
    },
    {
      "name": "Button",
      "slug": "button",
      "package": "@helixui/core",
      "import": "import { Button } from '@helixui/core'",
      "description": "Triggers an action when clicked.",
      "category": "form",
      "tags": [
        "clickable",
        "action",
        "primary",
        "destructive",
        "submit",
        "cta"
      ],
      "status": "stable",
      "since": "0.1.0",
      "layout": {
        "display": "inline-block",
        "width": "content",
        "height": "content",
        "intrinsicSize": "~28px (sm) / 36px (md) / 44px (lg) tall, hugs label width",
        "stackable": true,
        "fullBleed": false
      },
      "anatomy": "┌────────────────────────────────┐\n│  [icon?]  Label  [icon?]       │   ← children = label, optional leading/trailing icon\n└────────────────────────────────┘\n ↑ background per (variant, tone)\n ↑ border per (variant, tone)\n ↑ rounded by radius.md\n",
      "visual": "A pill-shaped, slightly rounded rectangle (radius.md). `solid` fills with the tone color and uses on-tone text;\n`soft` is a tinted fill of the tone with the tone's text color; `outline` is transparent with a 1px tone border;\n`ghost` is fully transparent until hover. Hover and active states deepen the tone by one step. The focus ring\nis a 2px offset outline on `:focus-visible` only. Disabled buttons are 50% opacity and lose pointer events.\n",
      "props": [
        {
          "name": "variant",
          "type": "'solid' | 'soft' | 'ghost' | 'outline'",
          "default": "solid",
          "description": "Visual style. `solid` is the highest-emphasis option; `ghost` the lowest."
        },
        {
          "name": "tone",
          "type": "'brand' | 'neutral' | 'danger'",
          "default": "brand",
          "description": "Color intent. `brand` for primary actions, `neutral` for secondary, `danger` for destructive."
        },
        {
          "name": "size",
          "type": "'sm' | 'md' | 'lg'",
          "default": "md",
          "description": "Button size. Use `sm` in compact UIs (toolbars), `lg` for prominent calls to action."
        },
        {
          "name": "disabled",
          "type": "boolean",
          "default": false,
          "description": "Disables interaction. Removes the element from the tab order."
        },
        {
          "name": "type",
          "type": "'button' | 'submit' | 'reset'",
          "default": "button",
          "description": "Native HTML button type. Defaults to `button` so the component does not accidentally submit forms."
        },
        {
          "name": "...rest",
          "type": "ButtonHTMLAttributes<HTMLButtonElement>",
          "default": "",
          "description": "All standard button attributes are forwarded to the underlying `<button>`."
        }
      ],
      "slots": [],
      "tokens": [
        "color.bg.action.brand.default",
        "color.bg.action.brand.hover",
        "color.bg.action.brand.active",
        "color.bg.action.brand.subtle",
        "color.bg.action.neutral.default",
        "color.bg.action.neutral.hover",
        "color.bg.action.neutral.active",
        "color.bg.action.danger.default",
        "color.bg.action.danger.hover",
        "color.bg.action.danger.active",
        "color.bg.action.danger.subtle",
        "color.bg.surface.default",
        "color.text.on.brand",
        "color.text.on.danger",
        "color.text.primary",
        "color.text.action.brand",
        "color.text.action.danger",
        "color.border.default",
        "color.border.strong",
        "color.border.focus",
        "color.border.danger",
        "radius.md",
        "space.2",
        "space.3",
        "space.4",
        "space.5",
        "font.size.sm",
        "font.size.md",
        "font.size.lg",
        "font.family.sans",
        "font.weight.semibold",
        "font.lineHeight.tight"
      ],
      "a11y": {
        "role": "button",
        "keyboard": [
          {
            "key": "Space",
            "action": "Activates the button."
          },
          {
            "key": "Enter",
            "action": "Activates the button."
          }
        ],
        "notes": [
          "Always provide an accessible name via children or `aria-label`. Icon-only buttons must use `aria-label`.",
          "Prefer `aria-disabled=\"true\"` over `disabled` when the action is conditionally unavailable but should remain focusable so users can discover it.",
          "The focus ring is rendered with `outline` and only on `:focus-visible`, so mouse users do not see it."
        ]
      },
      "composes_with": [
        {
          "component": "IconButton",
          "relation": "alternative",
          "note": "Use IconButton when there is no text label."
        },
        {
          "component": "Form",
          "relation": "parent",
          "note": "`type=\"submit\"` submits the surrounding Form."
        },
        {
          "component": "DialogTrigger",
          "relation": "child",
          "note": "Common opener for dialogs."
        },
        {
          "component": "Stack",
          "relation": "parent",
          "note": "Group multiple buttons in a Stack with `direction=\"row\"`."
        },
        {
          "component": "Tooltip",
          "relation": "wraps",
          "note": "Wrap with Tooltip when the action needs explanation."
        }
      ],
      "related": [
        "IconButton"
      ],
      "when_to_use": [],
      "pitfalls": [],
      "prompt_examples": [
        {
          "intent": "primary call-to-action",
          "prompt": "add a Save button",
          "snippet": "<Button>Save</Button>\n"
        },
        {
          "intent": "destructive action",
          "prompt": "make a Delete button",
          "snippet": "<Button tone=\"danger\">Delete</Button>\n"
        },
        {
          "intent": "secondary action next to a primary",
          "prompt": "Cancel + Save buttons in a row",
          "snippet": "<Stack direction=\"row\" gap={2} justify=\"end\">\n  <Button variant=\"ghost\" tone=\"neutral\">Cancel</Button>\n  <Button>Save</Button>\n</Stack>\n"
        },
        {
          "intent": "icon-only action in a toolbar",
          "prompt": "small ghost button with just a search icon",
          "snippet": "<Button variant=\"ghost\" size=\"sm\" aria-label=\"Search\">\n  <SearchIcon />\n</Button>\n"
        },
        {
          "intent": "form submission",
          "prompt": "submit button at the bottom of a form",
          "snippet": "<Button type=\"submit\" size=\"lg\">Create account</Button>\n"
        }
      ]
    },
    {
      "name": "Calendar",
      "slug": "calendar",
      "package": "@helixui/core",
      "import": "import { Calendar, RangeCalendar } from '@helixui/core'",
      "description": "A month-view date picker. Internationalized via @internationalized/date — supports any calendar system, not just Gregorian.",
      "category": "form",
      "tags": [
        "date",
        "picker",
        "month-view",
        "i18n"
      ],
      "status": "stable",
      "since": "0.1.0",
      "layout": {
        "display": "block",
        "width": "content",
        "height": "content",
        "intrinsicSize": "~280×320px (month grid)",
        "stackable": false,
        "fullBleed": false
      },
      "anatomy": "[<] May 2026 [>]\nSu Mo Tu We Th Fr Sa\n             1  2  3\n 4  5  6  7  8  9 10\n11 12 13 14 15 16 17  ← selected highlighted\n18 19 20 21 22 23 24\n25 26 27 28 29 30 31\n",
      "visual": "A 7-column grid with a previous/next month header. Day cells are square; today shows a ring; selected day fills with brand color; hover tints with action.brand.subtle. Range mode highlights the span between two anchors.\n",
      "props": [
        {
          "name": "value",
          "type": "DateValue",
          "default": "",
          "description": "Controlled selected date."
        },
        {
          "name": "defaultValue",
          "type": "DateValue",
          "default": "",
          "description": "Uncontrolled initial selection."
        },
        {
          "name": "minValue",
          "type": "DateValue",
          "default": "",
          "description": "Earliest selectable date."
        },
        {
          "name": "maxValue",
          "type": "DateValue",
          "default": "",
          "description": "Latest selectable date."
        },
        {
          "name": "isDisabled",
          "type": "boolean",
          "default": false,
          "description": "Disable the entire calendar."
        },
        {
          "name": "isReadOnly",
          "type": "boolean",
          "default": false,
          "description": "Block selection but keep navigation."
        },
        {
          "name": "onChange",
          "type": "(date: DateValue) => void",
          "default": "",
          "description": "Selection change handler."
        }
      ],
      "slots": [],
      "tokens": [
        "color.bg.surface.default",
        "color.bg.action.neutral.default",
        "color.bg.action.brand.default",
        "color.bg.action.brand.subtle",
        "color.border.default",
        "color.border.focus",
        "color.text.primary",
        "color.text.secondary",
        "color.text.muted",
        "color.text.action.brand",
        "color.text.on.brand",
        "radius.md",
        "radius.sm",
        "space.1",
        "space.2",
        "space.3",
        "font.family.sans",
        "font.size.xs",
        "font.size.sm",
        "font.size.md",
        "font.weight.medium",
        "font.weight.semibold"
      ],
      "a11y": {
        "role": "application",
        "keyboard": [
          {
            "key": "ArrowKeys",
            "action": "Move focus by day."
          },
          {
            "key": "PageUp",
            "action": "Previous month."
          },
          {
            "key": "PageDown",
            "action": "Next month."
          },
          {
            "key": "Home",
            "action": "Start of week."
          },
          {
            "key": "End",
            "action": "End of week."
          },
          {
            "key": "Enter",
            "action": "Select date."
          }
        ],
        "notes": [
          "Built on react-aria-components Calendar — full a11y, RTL, calendar systems, internationalization.",
          "Use `@internationalized/date` to construct DateValue objects (`parseDate`, `today`, etc.)."
        ]
      },
      "composes_with": [
        {
          "component": "Popover",
          "relation": "parent",
          "note": "Often rendered inside a Popover triggered by a TextInput."
        },
        {
          "component": "TextInput",
          "relation": "sibling",
          "note": "Common pairing — input shows formatted date, calendar picks it."
        }
      ],
      "related": [],
      "when_to_use": [],
      "pitfalls": [],
      "prompt_examples": [
        {
          "intent": "simple date picker",
          "prompt": "pick a single date",
          "snippet": "<Calendar value={date} onChange={setDate} />\n"
        },
        {
          "intent": "date range",
          "prompt": "pick a start and end date",
          "snippet": "<RangeCalendar value={range} onChange={setRange} />\n"
        }
      ]
    },
    {
      "name": "Callout",
      "slug": "callout",
      "package": "@helixui/core",
      "import": "import { Callout } from '@helixui/core'",
      "description": "An inline message banner — info, success, warning, danger, or neutral.",
      "category": "feedback",
      "tags": [
        "inline-alert",
        "note",
        "tip",
        "in-content"
      ],
      "status": "stable",
      "since": "0.1.0",
      "layout": {
        "display": "block",
        "width": "fill",
        "height": "content",
        "intrinsicSize": "inline within a content column",
        "stackable": true,
        "fullBleed": false
      },
      "anatomy": "┌─[i]── Heading ─────────────────────────────┐\n│   Body copy explaining the situation.       │\n└────────────────────────────────────────────┘\n",
      "visual": "A rounded surface (radius.md) with a tone-tinted background, leading icon, optional title, and body. Subtler than Banner — designed to live inside content, not float at page top.\n",
      "props": [
        {
          "name": "tone",
          "type": "'info' | 'success' | 'warning' | 'danger' | 'neutral'",
          "default": "info",
          "description": "Color intent."
        },
        {
          "name": "title",
          "type": "ReactNode",
          "default": "",
          "description": "Bold headline above the body."
        },
        {
          "name": "icon",
          "type": "ReactNode",
          "default": "",
          "description": "Optional leading icon. Provided by the caller; helixui has no icon set."
        }
      ],
      "slots": [
        "children — the body content"
      ],
      "tokens": [
        "color.bg.action.brand.subtle",
        "color.bg.action.success.subtle",
        "color.bg.action.warning.subtle",
        "color.bg.action.danger.subtle",
        "color.bg.surface.subtle",
        "color.text.action.brand",
        "color.text.action.success",
        "color.text.action.warning",
        "color.text.action.danger",
        "color.text.primary",
        "color.border.default",
        "radius.md",
        "space.1",
        "space.3",
        "space.4",
        "font.size.sm",
        "font.weight.semibold",
        "font.lineHeight.normal"
      ],
      "a11y": {
        "role": "status",
        "notes": [
          "For non-critical updates the default `role=\"status\"` is appropriate. For critical errors that must interrupt the user, use a Toast or Dialog instead.",
          "Do not use color alone to convey meaning; the leading icon and title text should make the tone unambiguous."
        ]
      },
      "composes_with": [
        {
          "component": "Banner",
          "relation": "alternative",
          "note": "Banner for page-level; Callout for in-content."
        },
        {
          "component": "Stack",
          "relation": "parent",
          "note": "Often inside a Stack of body content."
        },
        {
          "component": "Toast",
          "relation": "sibling"
        }
      ],
      "related": [
        "Toast"
      ],
      "when_to_use": [],
      "pitfalls": [],
      "prompt_examples": [
        {
          "intent": "in-content tip",
          "prompt": "a blue info callout about API limits",
          "snippet": "<Callout tone=\"info\" title=\"Heads up\">Rate limit is 100 req/min.</Callout>\n"
        },
        {
          "intent": "inline error",
          "prompt": "red error callout in a settings page",
          "snippet": "<Callout tone=\"danger\">Couldn't save changes — please retry.</Callout>\n"
        }
      ]
    },
    {
      "name": "Card",
      "slug": "card",
      "package": "@helixui/core",
      "import": "import { Card } from '@helixui/core'",
      "description": "A surface container with three elevation styles.",
      "category": "surface",
      "tags": [
        "container",
        "surface",
        "elevation",
        "group",
        "panel"
      ],
      "status": "stable",
      "since": "0.1.0",
      "layout": {
        "display": "block",
        "width": "fill",
        "height": "content",
        "intrinsicSize": "fills available width, hugs content height, ~20px internal padding",
        "stackable": true,
        "fullBleed": false
      },
      "anatomy": "┌──────────────────────────────────┐\n│                                  │\n│   <children>                     │   ← arbitrary content; helixui recommends Stack inside\n│                                  │\n└──────────────────────────────────┘\n ↑ surface bg + border (outlined) | shadow.md (elevated) | flat (no border, subtle bg)\n ↑ rounded by radius.lg, padded by space.5\n",
      "visual": "A rounded rectangle with generous internal padding (space.5) and large radius (radius.lg). `outlined` shows a\n1px subtle border on the default surface, `elevated` removes the border and uses a soft shadow (shadow.md),\n`flat` is borderless with a slightly recessed background tint. With `interactive`, hover lifts the shadow\nhalf a step and focus shows a 2px focus-ring border.\n",
      "props": [
        {
          "name": "variant",
          "type": "'flat' | 'outlined' | 'elevated'",
          "default": "outlined",
          "description": "Visual treatment."
        },
        {
          "name": "interactive",
          "type": "boolean",
          "default": false,
          "description": "Adds hover/focus affordance — set on cards that act as links or buttons."
        }
      ],
      "slots": [],
      "tokens": [
        "color.bg.surface.default",
        "color.bg.surface.subtle",
        "color.border.default",
        "color.border.strong",
        "color.border.focus",
        "radius.lg",
        "space.5",
        "shadow.md"
      ],
      "a11y": {
        "notes": [
          "When `interactive`, also render an interactive element (`<a>` or `<button>`) inside or on top, with appropriate role.",
          "The card itself is presentational — do not put `onClick` on it without a role."
        ]
      },
      "composes_with": [
        {
          "component": "Stack",
          "relation": "child",
          "note": "Use Stack inside Card to control vertical rhythm of contents."
        },
        {
          "component": "Heading",
          "relation": "child",
          "note": "Common first child as a card title."
        },
        {
          "component": "Text",
          "relation": "child",
          "note": "Body content of a card."
        },
        {
          "component": "Button",
          "relation": "child",
          "note": "Action(s) at the bottom of the card."
        },
        {
          "component": "Sheet",
          "relation": "alternative",
          "note": "Use Sheet for content that should overlay the page."
        }
      ],
      "related": [],
      "when_to_use": [],
      "pitfalls": [],
      "prompt_examples": [
        {
          "intent": "group related content into a panel",
          "prompt": "wrap this in a card",
          "snippet": "<Card>\n  <Stack gap={3}>\n    <Heading size=\"md\">Title</Heading>\n    <Text>Description goes here.</Text>\n  </Stack>\n</Card>\n"
        },
        {
          "intent": "make a clickable card linking elsewhere",
          "prompt": "card that links to /settings",
          "snippet": "<Card interactive asChild>\n  <a href=\"/settings\">\n    <Stack gap={2}>\n      <Heading size=\"sm\">Settings</Heading>\n      <Text size=\"sm\" tone=\"muted\">Manage your account.</Text>\n    </Stack>\n  </a>\n</Card>\n"
        },
        {
          "intent": "raised hero card on a list page",
          "prompt": "elevated card with a CTA",
          "snippet": "<Card variant=\"elevated\">\n  <Stack gap={4}>\n    <Heading size=\"lg\">Upgrade to Pro</Heading>\n    <Text>Unlock advanced analytics.</Text>\n    <Button>Upgrade</Button>\n  </Stack>\n</Card>\n"
        }
      ]
    },
    {
      "name": "Carousel",
      "slug": "carousel",
      "package": "@helixui/core",
      "import": "import { Carousel } from '@helixui/core'",
      "description": "A horizontal scroll-snap row of items. Native scroll on mobile (swipe); hidden arrows on hover for desktop; optional dots showing pagination.",
      "category": "media",
      "tags": [
        "slides",
        "swipe",
        "horizontal",
        "gallery"
      ],
      "status": "stable",
      "since": "0.5.0",
      "layout": {
        "display": "flex",
        "width": "fill",
        "height": "content",
        "intrinsicSize": "one slide per snap point, height of tallest slide",
        "stackable": false,
        "fullBleed": false
      },
      "anatomy": "[<]  [ slide ][ slide ][ slide ][ slide ]  [>]\n              ● ○ ○ ○   ← pagination dots\n",
      "visual": "A horizontally scrolling row that scroll-snaps each slide into view. Hidden arrow buttons appear on hover (desktop) at the edges; mobile uses native swipe. Optional dots at the bottom indicate position.\n",
      "props": [
        {
          "name": "arrows",
          "type": "boolean",
          "default": true,
          "description": "Show prev/next arrows on hover (hidden on touch)."
        },
        {
          "name": "dots",
          "type": "boolean",
          "default": false,
          "description": "Show pagination dots below the track."
        },
        {
          "name": "snap",
          "type": "'start' | 'center'",
          "default": "start",
          "description": "Scroll-snap alignment of items."
        },
        {
          "name": "gap",
          "type": "number | string",
          "default": "",
          "description": "Gap between items (px when number)."
        },
        {
          "name": "label",
          "type": "string",
          "default": "Carousel",
          "description": "`aria-label` on the wrapping region."
        }
      ],
      "slots": [
        "Carousel.Item — wraps each slide. Width is up to you (e.g. `flex: 0 0 80%`)."
      ],
      "tokens": [
        "color.bg.surface.default",
        "color.bg.action.neutral.active",
        "color.bg.action.brand.default",
        "color.border.default",
        "color.border.focus",
        "color.text.primary",
        "radius.full",
        "space.1",
        "space.2",
        "space.3",
        "font.family.sans",
        "shadow.md"
      ],
      "a11y": {
        "notes": [
          "Wrapper is `role=\"region\"` with `aria-roledescription=\"carousel\"`.",
          "Dots are `role=\"tablist\" / role=\"tab\"` with `aria-selected`.",
          "On touch devices, scrollbars are hidden; swipe is the only nav. Arrows are mouse-only."
        ]
      },
      "composes_with": [
        {
          "component": "Card",
          "relation": "child",
          "note": "Each slide is often a Card."
        }
      ],
      "related": [],
      "when_to_use": [],
      "pitfalls": [],
      "prompt_examples": [
        {
          "intent": "image gallery",
          "prompt": "a swipeable photo carousel with dots",
          "snippet": "<Carousel showDots>\n  {photos.map(p => <img key={p.id} src={p.url} alt=\"\" />)}\n</Carousel>\n"
        }
      ]
    },
    {
      "name": "Chart",
      "slug": "chart",
      "package": "@helixui/core",
      "import": "import { Chart } from '@helixui/core'",
      "description": "Unified chart surface backed by either Chart.js or Recharts. Both engines accept the same `<ChartData>` shape (labels + datasets); the adapter translates to engine-native formats internally. Both engines lazy-load and are declared as optional peer dependencies — install only what you use.",
      "category": "data",
      "tags": [
        "data-viz",
        "graph",
        "plot",
        "analytics"
      ],
      "status": "stable",
      "since": "0.7.0",
      "layout": {
        "display": "block",
        "width": "fill",
        "height": "fixed:320px",
        "intrinsicSize": "fills available width, default 320px tall",
        "stackable": true,
        "fullBleed": false
      },
      "anatomy": "┌──────────────────────────────┐\n│  Title                        │\n│  ▁▂▃▅▆▇█▇▆▅▃▂▁  legend       │\n│  └──────────────axis────────  │\n│  Caption                      │\n└──────────────────────────────┘\n",
      "visual": "A surface with optional title, legend, and caption. The plot area uses brand / success / warning / danger token colors for series. Tooltips appear on hover/touch; axis labels use muted text. Animations respect prefers-reduced-motion.\n",
      "props": [
        {
          "name": "type",
          "type": "'line' | 'area' | 'bar' | 'stackedBar' | 'horizontalBar' | 'pie' | 'doughnut' | 'radar' | 'scatter'",
          "default": "—",
          "description": "Chart type. Same set across both engines."
        },
        {
          "name": "data",
          "type": "ChartData",
          "default": "—",
          "description": "Unified `{ labels, datasets }` shape. Adapters translate it."
        },
        {
          "name": "engine",
          "type": "'chartjs' | 'recharts'",
          "default": "chartjs",
          "description": "Which engine to use. Chart.js draws to canvas; Recharts to SVG."
        },
        {
          "name": "theme",
          "type": "'light' | 'dark' | 'auto'",
          "default": "auto",
          "description": "`auto` follows `document.documentElement.dataset.theme`."
        },
        {
          "name": "legend",
          "type": "boolean",
          "default": true,
          "description": "Show / hide the legend."
        },
        {
          "name": "grid",
          "type": "boolean",
          "default": true,
          "description": "Show / hide axis grid lines."
        },
        {
          "name": "tooltip",
          "type": "boolean",
          "default": true,
          "description": "Show / hide tooltips on hover/touch."
        },
        {
          "name": "animate",
          "type": "boolean",
          "default": "auto",
          "description": "Animate on mount and on data change. Defaults follow `prefers-reduced-motion`."
        },
        {
          "name": "hideAxes",
          "type": "boolean",
          "default": false,
          "description": "Useful for compact widgets — drops both x and y tick labels."
        },
        {
          "name": "smooth",
          "type": "boolean",
          "default": true,
          "description": "Smoothed curves for line/area."
        },
        {
          "name": "compactNumbers",
          "type": "boolean",
          "default": true,
          "description": "Pretty-format the y-axis as `1.2K` / `3.4M`."
        },
        {
          "name": "cutout",
          "type": "number",
          "default": 0.6,
          "description": "Doughnut cutout (0–1). Ignored for non-doughnut types."
        },
        {
          "name": "height",
          "type": "number | string",
          "default": 320,
          "description": "Numbers are treated as px."
        },
        {
          "name": "title",
          "type": "ReactNode",
          "default": "—",
          "description": "Optional title rendered above the chart."
        },
        {
          "name": "caption",
          "type": "ReactNode",
          "default": "—",
          "description": "Optional caption rendered below the chart."
        },
        {
          "name": "chartjsOptions",
          "type": "Record<string, unknown>",
          "default": "{}",
          "description": "Spread last into Chart.js options. Escape hatch."
        },
        {
          "name": "rechartsOptions",
          "type": "Record<string, unknown>",
          "default": "{}",
          "description": "Reserved for the recharts adapter."
        },
        {
          "name": "onMount",
          "type": "(info: { engine, instance }) => void",
          "default": "—",
          "description": "Fires once mounted. Receives the underlying engine instance."
        }
      ],
      "slots": [],
      "tokens": [
        "color.bg.surface.default",
        "color.bg.surface.subtle",
        "color.bg.action.brand.default",
        "color.bg.action.success.default",
        "color.bg.action.warning.default",
        "color.bg.action.danger.default",
        "color.bg.action.danger.subtle",
        "color.border.default",
        "color.text.primary",
        "color.text.muted",
        "color.text.action.danger",
        "radius.md",
        "font.family.sans",
        "motion.duration.fast",
        "motion.easing.standard"
      ],
      "a11y": {
        "notes": [
          "Canvas-based engines (Chart.js) get a `role='img'` on the canvas with the chart title as `aria-label`.",
          "Tooltips honor pointer + touch.",
          "Animations turn off when `prefers-reduced-motion: reduce` unless `animate` is explicitly set."
        ]
      },
      "composes_with": [
        {
          "component": "Card",
          "relation": "parent",
          "note": "Often wrapped in a Card on dashboards."
        },
        {
          "component": "StatCard",
          "relation": "sibling",
          "note": "KPI tiles next to a chart."
        },
        {
          "component": "Sparkline",
          "relation": "alternative",
          "note": "Use Sparkline for tiny inline trends."
        }
      ],
      "related": [
        "Sparkline",
        "StatCard"
      ],
      "when_to_use": [],
      "pitfalls": [],
      "prompt_examples": [
        {
          "intent": "monthly revenue line chart",
          "prompt": "show a line chart of revenue",
          "snippet": "<Chart type=\"line\" data={{ labels, datasets: [{ label: 'Revenue', data }] }} />\n"
        },
        {
          "intent": "bar chart with engine override",
          "prompt": "use recharts for a bar chart",
          "snippet": "<Chart engine=\"recharts\" type=\"bar\" data={data} />\n"
        }
      ]
    },
    {
      "name": "ChatComposer",
      "slug": "chat-composer",
      "package": "@helixui/core",
      "import": "import { ChatComposer } from '@helixui/core'",
      "description": "A multi-line message composer with auto-resize, Enter-to-send (Shift+Enter for newline), and slots for attachments and toolbar buttons.",
      "category": "chat",
      "tags": [
        "input",
        "message",
        "send",
        "ai",
        "multiline"
      ],
      "status": "stable",
      "since": "0.3.0",
      "layout": {
        "display": "block",
        "width": "fill",
        "height": "content",
        "intrinsicSize": "min ~48px, grows up to maxHeight on multi-line",
        "stackable": false,
        "fullBleed": false
      },
      "anatomy": "┌────────────────────────────────────────┐\n│ [📎] | Type a message...           [↑] │\n│       (auto-resize, Enter sends)       │\n└────────────────────────────────────────┘\n",
      "visual": "A rounded surface (radius.lg) holding a multi-line textarea, optional attachment button on the left, and a brand-colored send button on the right. Auto-grows up to a max height, then scrolls inside. Enter sends; Shift+Enter inserts a newline.\n",
      "props": [
        {
          "name": "value",
          "type": "string",
          "default": "",
          "description": "Controlled message text."
        },
        {
          "name": "defaultValue",
          "type": "string",
          "default": "",
          "description": "Uncontrolled initial text."
        },
        {
          "name": "onChange",
          "type": "(v: string) => void",
          "default": "",
          "description": "Called on every keystroke."
        },
        {
          "name": "onSend",
          "type": "(v: string) => void",
          "default": "",
          "description": "Called when the user presses Enter or clicks send. Receives the trimmed message."
        },
        {
          "name": "placeholder",
          "type": "string",
          "default": "Send a message…",
          "description": "Placeholder."
        },
        {
          "name": "isDisabled",
          "type": "boolean",
          "default": false,
          "description": "Disable the entire composer."
        },
        {
          "name": "isSending",
          "type": "boolean",
          "default": false,
          "description": "While true, the send button is disabled (use during request)."
        },
        {
          "name": "attachments",
          "type": "ReactNode",
          "default": "",
          "description": "Slot above the input — attachment chips, mentions."
        },
        {
          "name": "beforeInput",
          "type": "ReactNode",
          "default": "",
          "description": "Slot to the left of the input (formatting toolbar, attach button)."
        },
        {
          "name": "afterInput",
          "type": "ReactNode",
          "default": "",
          "description": "Slot to the right of the input, before the send button."
        },
        {
          "name": "sendIcon",
          "type": "ReactNode",
          "default": "",
          "description": "Override the default paper-plane icon."
        },
        {
          "name": "sendLabel",
          "type": "string",
          "default": "Send",
          "description": "`aria-label` on the send button."
        },
        {
          "name": "minRows",
          "type": "number",
          "default": 1,
          "description": "Auto-resize floor."
        },
        {
          "name": "maxRows",
          "type": "number",
          "default": 8,
          "description": "Auto-resize ceiling; scrolls beyond."
        }
      ],
      "slots": [],
      "tokens": [
        "color.bg.surface.default",
        "color.bg.surface.muted",
        "color.bg.action.brand.default",
        "color.bg.action.brand.hover",
        "color.bg.action.neutral.default",
        "color.text.primary",
        "color.text.on.brand",
        "color.text.muted",
        "color.border.default",
        "color.border.focus",
        "radius.lg",
        "radius.full",
        "space.1",
        "space.2",
        "space.3",
        "font.family.sans",
        "font.size.md"
      ],
      "a11y": {
        "keyboard": [
          {
            "key": "Enter",
            "action": "Send the message."
          },
          {
            "key": "Shift+Enter",
            "action": "Insert newline."
          }
        ],
        "notes": [
          "The send button is disabled when the message is empty or whitespace.",
          "IME composition is respected — `Enter` does not send while composing (Korean/Japanese/Chinese input)."
        ]
      },
      "composes_with": [
        {
          "component": "AttachmentTile",
          "relation": "child",
          "note": "Renders attached files inside the composer."
        },
        {
          "component": "PromptSuggestions",
          "relation": "sibling",
          "note": "Suggestions appear above the composer."
        },
        {
          "component": "ChatList",
          "relation": "sibling",
          "note": "Sits below the chat list scroll area."
        },
        {
          "component": "ChatMessage",
          "relation": "sibling"
        },
        {
          "component": "IconButton",
          "relation": "sibling"
        }
      ],
      "related": [
        "ChatList",
        "ChatMessage",
        "AttachmentTile",
        "IconButton"
      ],
      "when_to_use": [],
      "pitfalls": [],
      "prompt_examples": [
        {
          "intent": "AI chat input",
          "prompt": "composer that sends on Enter",
          "snippet": "<ChatComposer onSend={handleSend} placeholder=\"Ask anything…\" />\n"
        },
        {
          "intent": "with attachments",
          "prompt": "composer with paperclip",
          "snippet": "<ChatComposer onSend={handleSend} onAttach={handleAttach} />\n"
        }
      ]
    },
    {
      "name": "ChatHeader",
      "slug": "chat-header",
      "package": "@helixui/core",
      "import": "import { ChatHeader } from '@helixui/core'",
      "description": "The top bar of a single conversation — avatar, title, subtitle, right-aligned actions.",
      "category": "chat",
      "tags": [
        "conversation",
        "top-bar",
        "identity"
      ],
      "status": "stable",
      "since": "0.3.0",
      "layout": {
        "display": "flex",
        "width": "fill",
        "height": "content",
        "intrinsicSize": "~56px tall, full width",
        "stackable": false,
        "fullBleed": true
      },
      "anatomy": "┌──── ●  Sara Tang   typing…   ──── [⋮][📞] ┐\n",
      "visual": "A horizontal bar with a leading Avatar, a title with optional subtitle (online status, typing), and right-aligned action icons. Border-bottom by border.default separates it from the message list.\n",
      "props": [
        {
          "name": "avatar",
          "type": "ReactNode",
          "default": "",
          "description": "Avatar rendered on the left. May contain a PresenceDot."
        },
        {
          "name": "title",
          "type": "ReactNode",
          "default": "",
          "description": "Conversation title — channel name, person, AI assistant."
        },
        {
          "name": "subtitle",
          "type": "ReactNode",
          "default": "",
          "description": "Member count, presence text, model name."
        },
        {
          "name": "actions",
          "type": "ReactNode",
          "default": "",
          "description": "Right-aligned IconButtons / Buttons — call, search, more."
        }
      ],
      "slots": [],
      "tokens": [
        "color.bg.surface.default",
        "color.border.default",
        "color.text.primary",
        "color.text.muted",
        "space.1",
        "space.3",
        "space.4",
        "font.family.sans",
        "font.size.xs",
        "font.size.md",
        "font.weight.semibold"
      ],
      "a11y": {
        "notes": [
          "Renders as `<header>`. The title is plain content — wrap in a heading tag if appropriate (`<Text as=\"h2\">`)."
        ]
      },
      "composes_with": [
        {
          "component": "Avatar",
          "relation": "child",
          "note": "Leading slot."
        },
        {
          "component": "IconButton",
          "relation": "child",
          "note": "Right-aligned actions."
        },
        {
          "component": "ChatList",
          "relation": "sibling",
          "note": "Sits above the chat list."
        },
        {
          "component": "ChatComposer",
          "relation": "sibling"
        }
      ],
      "related": [
        "ChatList",
        "ChatComposer"
      ],
      "when_to_use": [],
      "pitfalls": [],
      "prompt_examples": [
        {
          "intent": "one-on-one chat header",
          "prompt": "header with avatar, name, online dot",
          "snippet": "<ChatHeader avatar={<Avatar fallback=\"ST\" />} title=\"Sara\" subtitle=\"online\" />\n"
        }
      ]
    },
    {
      "name": "ChatList",
      "slug": "chat-list",
      "package": "@helixui/core",
      "import": "import { ChatList } from '@helixui/core'",
      "description": "A scrolling container for ChatMessages with sticky-to-bottom auto-scroll. When the user has scrolled up to read history, new messages do NOT yank them back.",
      "category": "chat",
      "tags": [
        "messages",
        "scroll",
        "sticky-bottom",
        "feed"
      ],
      "status": "stable",
      "since": "0.3.0",
      "layout": {
        "display": "flex",
        "width": "fill",
        "height": "fill",
        "intrinsicSize": "fills available height, scrolls",
        "stackable": false,
        "fullBleed": false
      },
      "anatomy": "┌────────────────────────┐\n│ [old messages above]   │ ↑ scrolls\n│ ChatMessage            │\n│ ChatMessage            │\n│ ChatMessage  ← new     │ ← stays pinned to bottom unless user scrolled up\n└────────────────────────┘\n",
      "visual": "A vertically scrolling column that auto-pins to the bottom when new messages arrive — but only if the user is already near the bottom. If they scrolled up to read history, new messages do not yank them back.\n",
      "props": [
        {
          "name": "autoScroll",
          "type": "boolean",
          "default": true,
          "description": "Auto-scroll on children change (only if user is near the bottom)."
        },
        {
          "name": "label",
          "type": "string",
          "default": "Conversation",
          "description": "`aria-label` for the log container."
        }
      ],
      "slots": [
        "children — ChatMessage components"
      ],
      "tokens": [
        "space.4",
        "font.family.sans"
      ],
      "a11y": {
        "role": "log",
        "notes": [
          "Container is `role=\"log\"` with `aria-live=\"polite\"`. New messages are announced once.",
          "The sticky-to-bottom behaviour preserves the user's reading position when they scroll up."
        ]
      },
      "composes_with": [
        {
          "component": "ChatMessage",
          "relation": "child",
          "note": "Each child is a ChatMessage."
        },
        {
          "component": "ChatHeader",
          "relation": "sibling",
          "note": "Sits below ChatHeader."
        },
        {
          "component": "ChatComposer",
          "relation": "sibling",
          "note": "Sits above ChatComposer."
        },
        {
          "component": "TypingIndicator",
          "relation": "sibling"
        }
      ],
      "related": [
        "ChatMessage",
        "ChatComposer",
        "TypingIndicator"
      ],
      "when_to_use": [],
      "pitfalls": [],
      "prompt_examples": [
        {
          "intent": "render an AI conversation",
          "prompt": "list of chat messages with sticky-bottom",
          "snippet": "<ChatList>\n  {messages.map(m => <ChatMessage key={m.id} role={m.role}>{m.content}</ChatMessage>)}\n</ChatList>\n"
        }
      ]
    },
    {
      "name": "ChatMessage",
      "slug": "chat-message",
      "package": "@helixui/core",
      "import": "import { ChatMessage } from '@helixui/core'",
      "description": "A single message in a chat — user / assistant / system role, bubble or inline (Slack-style) variant, optional avatar / name / time / footer.",
      "category": "chat",
      "tags": [
        "bubble",
        "message",
        "role",
        "user",
        "assistant"
      ],
      "status": "stable",
      "since": "0.3.0",
      "layout": {
        "display": "block",
        "width": "fill",
        "height": "content",
        "intrinsicSize": "left or right aligned by role, max ~720px wide",
        "stackable": true,
        "fullBleed": false
      },
      "anatomy": "[avatar]  Name · time\n          ┌──────────────────────┐\n          │  message body…       │\n          └──────────────────────┘\n          [optional footer]\n",
      "visual": "A row containing an avatar, a name + timestamp meta line, and a content bubble. User messages typically right-align with brand-tinted bubble; assistant left-aligns with neutral surface. The `inline` variant strips the bubble for Slack-style flat feeds.\n",
      "props": [
        {
          "name": "role",
          "type": "'user' | 'assistant' | 'system'",
          "default": "assistant",
          "description": "Speaker. `user` aligns right (in bubble variant); `system` centers and dims."
        },
        {
          "name": "variant",
          "type": "'bubble' | 'inline'",
          "default": "bubble",
          "description": "`bubble` for messenger UIs; `inline` for thread-style chat."
        },
        {
          "name": "avatar",
          "type": "ReactNode",
          "default": "",
          "description": "Avatar element rendered to the left (or right, for user)."
        },
        {
          "name": "name",
          "type": "ReactNode",
          "default": "",
          "description": "Display name. Position depends on variant."
        },
        {
          "name": "time",
          "type": "ReactNode",
          "default": "",
          "description": "Timestamp or relative time ('2m ago')."
        },
        {
          "name": "pending",
          "type": "boolean",
          "default": false,
          "description": "Mute the bubble while a message is being sent or streamed."
        },
        {
          "name": "footer",
          "type": "ReactNode",
          "default": "",
          "description": "Slot below the bubble — reactions, ToolCall, CitationList."
        }
      ],
      "slots": [
        "children — message content (text, MarkdownMessage, CodeBlock, etc.)"
      ],
      "tokens": [
        "color.bg.action.brand.default",
        "color.bg.action.neutral.default",
        "color.text.primary",
        "color.text.muted",
        "color.text.on.brand",
        "radius.lg",
        "radius.sm",
        "space.1",
        "space.2",
        "space.3",
        "space.4",
        "font.family.sans",
        "font.size.xs",
        "font.size.sm",
        "font.weight.semibold"
      ],
      "a11y": {
        "notes": [
          "The bubble itself is a styled `<div>`. Provide a sensible reading order; screen readers announce children + meta.",
          "For lists of messages, wrap in `<ChatList>` which is a `role=\"log\"` container."
        ]
      },
      "composes_with": [
        {
          "component": "ChatList",
          "relation": "parent",
          "note": "Always inside a ChatList."
        },
        {
          "component": "Avatar",
          "relation": "child",
          "note": "Leading avatar."
        },
        {
          "component": "ToolCall",
          "relation": "child",
          "note": "Tool calls render inside an assistant message."
        },
        {
          "component": "ThinkingBlock",
          "relation": "child",
          "note": "Reasoning summary inside an assistant message."
        },
        {
          "component": "ChatComposer",
          "relation": "sibling"
        },
        {
          "component": "TypingIndicator",
          "relation": "sibling"
        },
        {
          "component": "ChatHeader",
          "relation": "sibling"
        }
      ],
      "related": [
        "ChatList",
        "ChatComposer",
        "TypingIndicator",
        "ChatHeader"
      ],
      "when_to_use": [],
      "pitfalls": [],
      "prompt_examples": [
        {
          "intent": "user prompt",
          "prompt": "a user message saying hello",
          "snippet": "<ChatMessage role=\"user\">Hello!</ChatMessage>\n"
        },
        {
          "intent": "streaming assistant reply",
          "prompt": "show an assistant reply with a streaming caret",
          "snippet": "<ChatMessage role=\"assistant\">\n  {streamedText}<StreamingIndicator />\n</ChatMessage>\n"
        }
      ]
    },
    {
      "name": "Checkbox",
      "slug": "checkbox",
      "package": "@helixui/core",
      "import": "import { Checkbox } from '@helixui/core'",
      "description": "A binary checkbox with indeterminate state.",
      "category": "form",
      "tags": [
        "boolean",
        "toggle",
        "multi-select",
        "form"
      ],
      "status": "stable",
      "since": "0.1.0",
      "layout": {
        "display": "inline-flex",
        "width": "content",
        "height": "content",
        "intrinsicSize": "~20px box + label gap",
        "stackable": true,
        "fullBleed": false
      },
      "anatomy": "[ ☐ ]  Label       ← unchecked\n[ ☑ ]  Label       ← checked\n[ ▣ ]  Label       ← indeterminate\n",
      "visual": "A small rounded square (radius.sm) that fills with brand color when checked, with a white check glyph. Indeterminate state shows a horizontal bar. Label sits to the right with space.2 gap.\n",
      "props": [
        {
          "name": "isSelected",
          "type": "boolean",
          "default": false,
          "description": "Controlled checked state."
        },
        {
          "name": "defaultSelected",
          "type": "boolean",
          "default": false,
          "description": "Uncontrolled initial state."
        },
        {
          "name": "isIndeterminate",
          "type": "boolean",
          "default": false,
          "description": "Shows a dash glyph indicating mixed state."
        },
        {
          "name": "isRequired",
          "type": "boolean",
          "default": false,
          "description": "Marks required for validation."
        },
        {
          "name": "isInvalid",
          "type": "boolean",
          "default": false,
          "description": "Forces invalid state."
        },
        {
          "name": "isDisabled",
          "type": "boolean",
          "default": false,
          "description": "Disables interaction."
        },
        {
          "name": "onChange",
          "type": "(isSelected: boolean) => void",
          "default": "",
          "description": "Change handler."
        },
        {
          "name": "...rest",
          "type": "CheckboxProps from react-aria-components",
          "default": "",
          "description": "All forwarded."
        }
      ],
      "slots": [
        "children — visible label text"
      ],
      "tokens": [
        "color.bg.surface.default",
        "color.bg.action.brand.default",
        "color.text.primary",
        "color.text.on.brand",
        "color.border.strong",
        "color.border.focus",
        "color.border.danger",
        "radius.sm",
        "space.2",
        "font.family.sans",
        "font.size.sm"
      ],
      "a11y": {
        "role": "checkbox",
        "keyboard": [
          {
            "key": "Space",
            "action": "Toggles the checkbox."
          }
        ],
        "notes": [
          "Built on react-aria-components Checkbox — full keyboard, screen-reader, and indeterminate handling.",
          "For groups of related options, use CheckboxGroup (follow react-aria-components)."
        ]
      },
      "composes_with": [
        {
          "component": "Field",
          "relation": "parent",
          "note": "Use Field if you need separate label/description structure."
        },
        {
          "component": "Form",
          "relation": "parent",
          "note": "Submitted as part of a Form."
        },
        {
          "component": "Switch",
          "relation": "sibling"
        },
        {
          "component": "RadioGroup",
          "relation": "sibling"
        }
      ],
      "related": [
        "Switch",
        "RadioGroup"
      ],
      "when_to_use": [],
      "pitfalls": [],
      "prompt_examples": [
        {
          "intent": "agree-to-terms",
          "prompt": "checkbox to accept terms",
          "snippet": "<Checkbox isSelected={ok} onChange={setOk}>I agree to the terms</Checkbox>\n"
        },
        {
          "intent": "select all in a table",
          "prompt": "header checkbox with indeterminate when partially selected",
          "snippet": "<Checkbox isIndeterminate={partial} isSelected={all} onChange={toggleAll}>Select all</Checkbox>\n"
        }
      ]
    },
    {
      "name": "CodeBlock",
      "slug": "code-block",
      "package": "@helixui/core",
      "import": "import { CodeBlock } from '@helixui/core'",
      "description": "A fenced code display with language label and copy button. Built-in tokenizer for ts / js / py / json / bash; bring your own highlighter for others.",
      "category": "data",
      "tags": [
        "code",
        "mono",
        "snippet",
        "copy"
      ],
      "status": "stable",
      "since": "0.3.0",
      "layout": {
        "display": "block",
        "width": "fill",
        "height": "content",
        "intrinsicSize": "fills width, scrolls horizontally on overflow",
        "stackable": true,
        "fullBleed": false
      },
      "anatomy": "┌─ tsx ─────────────────────────── [📋] ┐\n│  const x = 1;                         │\n│  console.log(x);                       │\n└────────────────────────────────────────┘\n",
      "visual": "A surface with a small language label in the top-left, a copy button in the top-right, and monospace content (font.family.mono) on a subtle surface (surface.subtle). Tokenized highlighting for ts/js/py/json/bash; falls back to plain text otherwise.\n",
      "props": [
        {
          "name": "code",
          "type": "string",
          "default": "",
          "description": "Source text. Required."
        },
        {
          "name": "language",
          "type": "string",
          "default": "ts",
          "description": "Language tag for highlighter and label."
        },
        {
          "name": "filename",
          "type": "string",
          "default": "",
          "description": "Optional filename — replaces the language label."
        },
        {
          "name": "noCopy",
          "type": "boolean",
          "default": false,
          "description": "Hide the copy button."
        },
        {
          "name": "highlight",
          "type": "(code, language?) => string",
          "default": "",
          "description": "Override the built-in highlighter. Returns HTML string."
        }
      ],
      "slots": [],
      "tokens": [
        "color.bg.surface.inverse",
        "color.text.inverse",
        "color.border.default",
        "radius.md",
        "radius.sm",
        "space.2",
        "space.3",
        "space.4",
        "font.family.sans",
        "font.family.mono",
        "font.size.xs",
        "font.size.sm",
        "font.weight.medium"
      ],
      "a11y": {
        "notes": [
          "Copy button announces 'Copied' via its `aria-label` after a successful copy.",
          "Built-in highlighter is regex-based (small) — for richer highlighting pass `highlight` (e.g. wrap Prism / Shiki)."
        ]
      },
      "composes_with": [
        {
          "component": "CodeEditor",
          "relation": "alternative",
          "note": "CodeBlock is read-only display; CodeEditor is editable."
        },
        {
          "component": "Card",
          "relation": "parent",
          "note": "Often inside a Card or doc body."
        },
        {
          "component": "ChatMessage",
          "relation": "sibling"
        }
      ],
      "related": [
        "ChatMessage"
      ],
      "when_to_use": [],
      "pitfalls": [],
      "prompt_examples": [
        {
          "intent": "show a tsx snippet",
          "prompt": "render a code block with copy button",
          "snippet": "<CodeBlock language=\"tsx\">{`const x = 1;`}</CodeBlock>\n"
        }
      ]
    },
    {
      "name": "CodeEditor",
      "slug": "code-editor",
      "package": "@helixui/core",
      "import": "import { CodeEditor } from '@helixui/core'",
      "description": "An editable code surface backed by either CodeMirror 6 or Monaco. Pick the engine via a single prop. Both engines lazy-load and are declared as optional peer dependencies — install only what you use.",
      "category": "form",
      "tags": [
        "code",
        "editor",
        "editable",
        "codemirror",
        "monaco"
      ],
      "status": "stable",
      "since": "0.6.0",
      "layout": {
        "display": "block",
        "width": "fill",
        "height": "fixed:320px",
        "intrinsicSize": "fills width, default 320px tall, scrolls inside",
        "stackable": false,
        "fullBleed": false
      },
      "anatomy": "┌─ tsx ──────────────────────────────────┐\n│  1  const x = 1;          ← line nums   │\n│  2  console.log(x);                     │\n│  3  |                                   │\n└─────────────────────────────────────────┘\n",
      "visual": "A full-featured code editor surface with line numbers, syntax highlighting, and (when enabled) folding and minimap. Engine-agnostic — both CodeMirror 6 and Monaco are supported and lazy-loaded.\n",
      "props": [
        {
          "name": "value",
          "type": "string",
          "default": "''",
          "description": "Current document text."
        },
        {
          "name": "onChange",
          "type": "(value: string) => void",
          "default": "—",
          "description": "Fires on every edit with the new text."
        },
        {
          "name": "engine",
          "type": "'codemirror' | 'monaco'",
          "default": "codemirror",
          "description": "Which engine to mount. CodeMirror is lighter; Monaco offers full IDE feel."
        },
        {
          "name": "language",
          "type": "'typescript' | 'javascript' | 'json' | 'python' | 'html' | 'css' | 'markdown' | 'plaintext'",
          "default": "plaintext",
          "description": "Language for syntax highlighting and language services."
        },
        {
          "name": "theme",
          "type": "'light' | 'dark' | 'auto'",
          "default": "auto",
          "description": "`auto` follows `document.documentElement.dataset.theme` and updates live."
        },
        {
          "name": "readOnly",
          "type": "boolean",
          "default": false,
          "description": "Disable editing."
        },
        {
          "name": "lineNumbers",
          "type": "boolean",
          "default": "auto",
          "description": "On by default on desktop, off on mobile."
        },
        {
          "name": "wordWrap",
          "type": "boolean",
          "default": "auto",
          "description": "Off by default on desktop, on on mobile."
        },
        {
          "name": "tabSize",
          "type": "number",
          "default": 2,
          "description": "Tab width in spaces."
        },
        {
          "name": "fontSize",
          "type": "number",
          "default": "14 / 13",
          "description": "14 desktop, 13 mobile by default."
        },
        {
          "name": "height",
          "type": "number | string",
          "default": 360,
          "description": "Numbers are treated as px. Strings pass through (`'50vh'`, `'100%'`)."
        },
        {
          "name": "autoFocus",
          "type": "boolean",
          "default": false,
          "description": "Focus the editor when it mounts."
        },
        {
          "name": "codemirrorExtensions",
          "type": "unknown[]",
          "default": "[]",
          "description": "Extra CodeMirror 6 extensions appended after defaults."
        },
        {
          "name": "monacoOptions",
          "type": "Record<string, unknown>",
          "default": "{}",
          "description": "Partial Monaco IStandaloneEditorConstructionOptions, spread last."
        },
        {
          "name": "onMount",
          "type": "(info: { engine, instance }) => void",
          "default": "—",
          "description": "Fires once mounted. Receives the underlying editor instance."
        }
      ],
      "slots": [],
      "tokens": [
        "color.bg.surface.default",
        "color.bg.surface.subtle",
        "color.border.default",
        "color.border.focus",
        "color.text.muted",
        "color.text.primary",
        "color.text.action.danger",
        "color.bg.action.danger.subtle",
        "radius.md",
        "font.family.mono",
        "motion.duration.fast",
        "motion.easing.standard"
      ],
      "a11y": {
        "notes": [
          "Both engines provide their own keyboard accessibility (cursor movement, selection, find).",
          "Container shows a `:focus-within` ring matching helixui's other inputs.",
          "Respects `prefers-reduced-motion` via the global motion stylesheet — no per-engine guard required."
        ]
      },
      "composes_with": [
        {
          "component": "CodeBlock",
          "relation": "alternative",
          "note": "Use CodeBlock for static display."
        },
        {
          "component": "Form",
          "relation": "parent",
          "note": "Can act as a controlled form input."
        }
      ],
      "related": [
        "CodeBlock"
      ],
      "when_to_use": [],
      "pitfalls": [],
      "prompt_examples": [
        {
          "intent": "editable JSON config",
          "prompt": "editable code area for JSON",
          "snippet": "<CodeEditor language=\"json\" value={value} onChange={setValue} />\n"
        }
      ]
    },
    {
      "name": "Collapsible",
      "slug": "collapsible",
      "package": "@helixui/core",
      "import": "import { Collapsible } from '@helixui/core'",
      "description": "A toggleable disclosure panel — show or hide a chunk of content behind a header.",
      "category": "surface",
      "tags": [
        "disclosure",
        "expand",
        "accordion",
        "show-hide"
      ],
      "status": "stable",
      "since": "0.1.0",
      "layout": {
        "display": "block",
        "width": "fill",
        "height": "content",
        "intrinsicSize": "header always visible, body animates open/closed",
        "stackable": true,
        "fullBleed": false
      },
      "anatomy": "[▶ Title]                 ← collapsed\n[▼ Title]\n   <children>                ← expanded\n",
      "visual": "A header row with a rotating chevron and a body that animates its height when toggled. Header uses font.weight.semibold and a hover surface; body uses default text.\n",
      "props": [
        {
          "name": "title",
          "type": "ReactNode",
          "default": "",
          "description": "Header label. Required."
        },
        {
          "name": "isExpanded",
          "type": "boolean",
          "default": "",
          "description": "Controlled expanded state."
        },
        {
          "name": "defaultExpanded",
          "type": "boolean",
          "default": false,
          "description": "Uncontrolled initial."
        },
        {
          "name": "onExpandedChange",
          "type": "(expanded: boolean) => void",
          "default": "",
          "description": "Change handler."
        },
        {
          "name": "isDisabled",
          "type": "boolean",
          "default": false,
          "description": "Disables toggling."
        }
      ],
      "slots": [
        "children — panel content"
      ],
      "tokens": [
        "color.bg.surface.default",
        "color.bg.action.neutral.default",
        "color.text.primary",
        "color.text.secondary",
        "color.border.default",
        "color.border.focus",
        "radius.md",
        "space.3",
        "space.4",
        "font.family.sans",
        "font.size.md",
        "font.size.sm",
        "font.weight.medium"
      ],
      "a11y": {
        "notes": [
          "Built on react-aria-components `Disclosure` — full ARIA expanded/controls and keyboard handled.",
          "For multiple coordinated collapsibles, use `DisclosureGroup` directly from `react-aria-components`."
        ]
      },
      "composes_with": [
        {
          "component": "Stack",
          "relation": "parent",
          "note": "Group multiple Collapsibles in a Stack for an accordion."
        },
        {
          "component": "NavigationMenu",
          "relation": "sibling"
        },
        {
          "component": "Tabs",
          "relation": "sibling"
        }
      ],
      "related": [
        "NavigationMenu",
        "Tabs"
      ],
      "when_to_use": [],
      "pitfalls": [],
      "prompt_examples": [
        {
          "intent": "FAQ entry",
          "prompt": "expandable FAQ question",
          "snippet": "<Collapsible title=\"What is helixui?\">\n  helixui is an AI-friendly design system.\n</Collapsible>\n"
        }
      ]
    },
    {
      "name": "CollapsingHeader",
      "slug": "collapsing-header",
      "package": "@helixui/core",
      "import": "import { CollapsingHeader } from '@helixui/core'",
      "description": "An iOS-style header that fades from a large hero title at the top to a compact title with actions when the page is scrolled.",
      "category": "shell",
      "tags": [
        "mobile",
        "ios",
        "scroll",
        "header",
        "large-title"
      ],
      "status": "beta",
      "since": "0.5.0",
      "layout": {
        "display": "block",
        "width": "fill",
        "height": "content",
        "intrinsicSize": "expanded ~120px, collapses to ~52px on scroll",
        "stackable": false,
        "fullBleed": true
      },
      "anatomy": "(collapsed top)  Title                    [actions]\n(expanded top)\n  Hero Title\n  ─────────────────────────\n  page content scrolls under it\n",
      "visual": "An iOS-style header that starts as a large hero title at rest and fades into a compact sticky title with right-aligned actions as the page scrolls down.\n",
      "props": [
        {
          "name": "title",
          "type": "ReactNode",
          "default": "",
          "description": "Headline shown when the header is at full height."
        },
        {
          "name": "collapsedTitle",
          "type": "ReactNode",
          "default": "",
          "description": "Compact title shown when collapsed. Defaults to `title`."
        },
        {
          "name": "description",
          "type": "ReactNode",
          "default": "",
          "description": "Lead paragraph below the title."
        },
        {
          "name": "actions",
          "type": "ReactNode",
          "default": "",
          "description": "Right-aligned actions (visible in both states)."
        },
        {
          "name": "minHeight",
          "type": "number",
          "default": 56,
          "description": "Collapsed height (px)."
        },
        {
          "name": "maxHeight",
          "type": "number",
          "default": 140,
          "description": "Expanded height (px)."
        },
        {
          "name": "scrollContainer",
          "type": "HTMLElement | null",
          "default": "",
          "description": "Element whose scroll drives the collapse. Defaults to `window`."
        }
      ],
      "slots": [],
      "tokens": [
        "color.bg.surface.default",
        "color.text.primary",
        "color.text.secondary",
        "color.border.default",
        "space.1",
        "space.3",
        "space.4",
        "font.family.sans",
        "font.size.sm",
        "font.size.md",
        "font.size.3xl",
        "font.weight.semibold",
        "font.weight.bold",
        "shadow.sm"
      ],
      "a11y": {
        "notes": [
          "The header includes `padding-top: env(safe-area-inset-top)` so it clears the iOS notch.",
          "The compact title cross-fades; both are rendered for screen readers."
        ]
      },
      "composes_with": [
        {
          "component": "PageHeader",
          "relation": "alternative",
          "note": "PageHeader is static; CollapsingHeader animates with scroll."
        }
      ],
      "related": [
        "PageHeader"
      ],
      "when_to_use": [],
      "pitfalls": [],
      "prompt_examples": [
        {
          "intent": "mobile profile page",
          "prompt": "large title that shrinks on scroll",
          "snippet": "<CollapsingHeader title=\"Profile\" actions={<IconButton aria-label=\"Edit\"><EditIcon /></IconButton>} />\n"
        }
      ]
    },
    {
      "name": "ColorPicker",
      "slug": "color-picker",
      "package": "@helixui/core",
      "import": "import { ColorPicker, ColorPickerInline } from '@helixui/core'",
      "description": "An HSB color picker — saturation/brightness area, hue slider, and hex input. Available inline or in a popover.",
      "category": "form",
      "tags": [
        "color",
        "hsb",
        "picker"
      ],
      "status": "beta",
      "since": "0.1.0",
      "layout": {
        "display": "block",
        "width": "content",
        "height": "content",
        "intrinsicSize": "~240×240 area + sliders",
        "stackable": false,
        "fullBleed": false
      },
      "anatomy": "┌──────────────────┐\n│ saturation/value │\n│   gradient area  │\n│       (●)        │  ← drag handle\n└──────────────────┘\n┌─────── hue slider ──────┐ #3b82f6  [hex]\n",
      "visual": "A 2-D saturation × value gradient with a draggable thumb, a horizontal hue slider beneath, and a hex input. ColorPickerInline embeds it; ColorPicker (default) puts it inside a Popover.\n",
      "props": [
        {
          "name": "label",
          "type": "ReactNode",
          "default": "",
          "description": "Visible label."
        },
        {
          "name": "value",
          "type": "Color",
          "default": "",
          "description": "Controlled color (use `parseColor()` from react-aria-components)."
        },
        {
          "name": "defaultValue",
          "type": "Color",
          "default": "#3b82f6",
          "description": "Uncontrolled initial color."
        },
        {
          "name": "onChange",
          "type": "(color: Color) => void",
          "default": "",
          "description": "Color change handler."
        }
      ],
      "slots": [],
      "tokens": [
        "color.bg.surface.default",
        "color.border.default",
        "color.border.focus",
        "color.text.primary",
        "radius.md",
        "radius.sm",
        "radius.full",
        "space.2",
        "space.3",
        "font.family.sans",
        "font.family.mono",
        "font.size.sm",
        "font.weight.medium",
        "shadow.md"
      ],
      "a11y": {
        "notes": [
          "Built on react-aria-components ColorPicker — keyboard arrows move the saturation/brightness thumb and hue thumb in 1% steps; Shift+arrow moves in 10% steps.",
          "The hex input accepts any valid CSS color and normalizes it.",
          "The popover variant uses DialogTrigger for focus management when open."
        ]
      },
      "composes_with": [
        {
          "component": "Popover",
          "relation": "parent",
          "note": "Default rendering is inside a Popover."
        }
      ],
      "related": [
        "Popover"
      ],
      "when_to_use": [],
      "pitfalls": [],
      "prompt_examples": [
        {
          "intent": "theme color picker",
          "prompt": "pick a hex color",
          "snippet": "<ColorPicker value={color} onChange={setColor} />\n"
        }
      ]
    },
    {
      "name": "CommandPalette",
      "slug": "command-palette",
      "package": "@helixui/core",
      "import": "import { CommandPalette, type Command } from '@helixui/core'",
      "description": "A Cmd+K command palette — searchable list of actions in a modal, with keyboard navigation and grouping.",
      "category": "overlay",
      "tags": [
        "cmd-k",
        "search",
        "actions",
        "modal",
        "productivity"
      ],
      "status": "beta",
      "since": "0.2.0",
      "layout": {
        "display": "portal",
        "width": "fixed:560px",
        "height": "content",
        "intrinsicSize": "centered modal, max-h ~60vh",
        "stackable": false,
        "fullBleed": false
      },
      "anatomy": "┌─ overlay ────────────────────────────────┐\n│  ┌── modal ───────────────────────────┐  │\n│  │  > search                          │  │\n│  │  ─────────────                     │  │\n│  │  Section                           │  │\n│  │   • action 1   ⌘K                  │  │\n│  │   • action 2                       │  │\n│  │  Section                           │  │\n│  │   • action 3                       │  │\n│  └────────────────────────────────────┘  │\n└──────────────────────────────────────────┘\n",
      "visual": "A centered modal with a top search input and a scrollable list of grouped commands beneath. Arrow keys navigate, Enter activates, ⌘K opens. Each item shows an optional icon, label, and shortcut hint.\n",
      "props": [
        {
          "name": "commands",
          "type": "Command[]",
          "default": "",
          "description": "Required. Each command has `id`, `label`, optional `group`, `hint`, `keywords`, `icon`, and an `onAction(close)` handler."
        },
        {
          "name": "isOpen",
          "type": "boolean",
          "default": "",
          "description": "Controlled visibility."
        },
        {
          "name": "defaultOpen",
          "type": "boolean",
          "default": false,
          "description": "Uncontrolled initial visibility."
        },
        {
          "name": "onOpenChange",
          "type": "(open: boolean) => void",
          "default": "",
          "description": "Visibility change handler."
        },
        {
          "name": "shortcut",
          "type": "string",
          "default": "Mod+k",
          "description": "Global keyboard shortcut to open. `Mod` = Cmd on Mac, Ctrl elsewhere."
        },
        {
          "name": "placeholder",
          "type": "string",
          "default": "Type a command…",
          "description": "Search input placeholder."
        },
        {
          "name": "emptyMessage",
          "type": "ReactNode",
          "default": "No matches.",
          "description": "Shown when no commands match the query."
        }
      ],
      "slots": [],
      "tokens": [
        "color.bg.surface.default",
        "color.bg.action.neutral.default",
        "color.bg.action.brand.subtle",
        "color.border.default",
        "color.text.primary",
        "color.text.secondary",
        "color.text.muted",
        "color.text.action.brand",
        "radius.lg",
        "radius.md",
        "radius.sm",
        "space.2",
        "space.3",
        "space.4",
        "space.6",
        "font.family.sans",
        "font.family.mono",
        "font.size.xs",
        "font.size.sm",
        "font.size.md",
        "font.weight.semibold",
        "shadow.lg"
      ],
      "a11y": {
        "keyboard": [
          {
            "key": "Mod+k",
            "action": "Open palette globally."
          },
          {
            "key": "ArrowDown",
            "action": "Next command."
          },
          {
            "key": "ArrowUp",
            "action": "Previous command."
          },
          {
            "key": "Enter",
            "action": "Run highlighted command."
          },
          {
            "key": "Escape",
            "action": "Close palette."
          }
        ],
        "notes": [
          "The input is `role=\"combobox\"`; the list is `role=\"listbox\"`; items are `role=\"option\"`. The active item is announced via `aria-activedescendant`."
        ]
      },
      "composes_with": [
        {
          "component": "Menu",
          "relation": "alternative",
          "note": "Menu is anchored to a trigger; CommandPalette is global."
        },
        {
          "component": "Dialog",
          "relation": "alternative",
          "note": "Dialog is for tasks; CommandPalette is for actions."
        },
        {
          "component": "Popover",
          "relation": "sibling"
        }
      ],
      "related": [
        "Menu",
        "Dialog",
        "Popover"
      ],
      "when_to_use": [],
      "pitfalls": [],
      "prompt_examples": [
        {
          "intent": "global cmd-k",
          "prompt": "cmd+k command palette with two sections",
          "snippet": "<CommandPalette\n  isOpen={open}\n  onOpenChange={setOpen}\n  commands={[\n    { group: 'File', items: [{ id: 'new', label: 'New file', onPress: createFile }] },\n    { group: 'Help', items: [{ id: 'docs', label: 'Open docs', onPress: openDocs }] },\n  ]}\n/>\n"
        }
      ]
    },
    {
      "name": "CurrencyInput",
      "slug": "currency-input",
      "package": "@helixui/core",
      "import": "import { CurrencyInput } from '@helixui/core'",
      "description": "Locale-aware currency input. Formats on blur, parses on the fly. Uses Intl.NumberFormat for symbols, separators, and precision.",
      "category": "form",
      "tags": [
        "currency",
        "money",
        "money-input",
        "locale",
        "intl",
        "payment",
        "pricing"
      ],
      "status": "stable",
      "since": "0.1.0",
      "layout": null,
      "anatomy": null,
      "visual": null,
      "props": [
        {
          "name": "value",
          "type": "number | null",
          "default": "undefined",
          "description": "Controlled numeric value."
        },
        {
          "name": "defaultValue",
          "type": "number | null",
          "default": "undefined",
          "description": "Uncontrolled initial value."
        },
        {
          "name": "onValueChange",
          "type": "(value: number | null) => void",
          "default": "undefined",
          "description": "Fires with the parsed numeric value or null when the field is empty."
        },
        {
          "name": "currency",
          "type": "string",
          "default": "USD",
          "description": "ISO 4217 currency code. Drives the symbol and the default precision."
        },
        {
          "name": "locale",
          "type": "string",
          "default": "navigator.language",
          "description": "Override the user's locale. Affects symbol position and decimal separator."
        },
        {
          "name": "showSymbol",
          "type": "boolean",
          "default": true,
          "description": "Render the currency symbol inside the input."
        },
        {
          "name": "precision",
          "type": "number",
          "default": "undefined",
          "description": "Override the number of decimal places. Defaults to what the currency expects."
        },
        {
          "name": "positiveOnly",
          "type": "boolean",
          "default": true,
          "description": "Reject negative values."
        },
        {
          "name": "size",
          "type": "'sm' | 'md' | 'lg'",
          "default": "md",
          "description": "Input size."
        },
        {
          "name": "tone",
          "type": "'brand' | 'neutral' | 'danger'",
          "default": "brand",
          "description": "Tone for focus ring."
        }
      ],
      "slots": [],
      "tokens": [
        "color.bg.input",
        "color.bg.surface.default",
        "color.bg.action.brand.subtle",
        "color.border.subtle",
        "color.border.action.brand",
        "color.border.danger",
        "color.text.primary",
        "color.text.muted",
        "radius.md",
        "spacing.1",
        "spacing.2",
        "spacing.3",
        "spacing.4",
        "font.size.xs",
        "font.size.sm",
        "font.size.md",
        "font.size.lg"
      ],
      "a11y": {
        "role": "textbox",
        "keyboard": [
          {
            "key": "0-9",
            "action": "Enter digits."
          },
          {
            "key": ".",
            "action": "Decimal separator (or `,` depending on locale)."
          }
        ],
        "notes": [
          "Uses `inputmode='decimal'` so mobile keyboards show the numeric layout.",
          "On blur the value reformats with thousands separators.",
          "Without an explicit `aria-label`, defaults to e.g. \"USD amount\"."
        ]
      },
      "composes_with": [],
      "related": [
        "text-input",
        "number-field"
      ],
      "when_to_use": [],
      "pitfalls": [],
      "prompt_examples": []
    },
    {
      "name": "DataTable",
      "slug": "data-table",
      "package": "@helixui/core",
      "import": "import { DataTable, type ColumnDef } from '@helixui/core'",
      "description": "A full-featured table primitive — sortable, filterable, selectable, paginated. Works for read-only display and for selection-driven workflows. Zero external dependencies.",
      "category": "data",
      "tags": [
        "table",
        "datagrid",
        "list",
        "sort",
        "filter",
        "pagination",
        "selection",
        "admin"
      ],
      "status": "stable",
      "since": "0.1.0",
      "layout": null,
      "anatomy": null,
      "visual": null,
      "props": [
        {
          "name": "data",
          "type": "readonly T[]",
          "default": "required",
          "description": "The rows to display. Order is preserved unless sorting is active."
        },
        {
          "name": "columns",
          "type": "readonly ColumnDef<T>[]",
          "default": "required",
          "description": "Column definitions. Each column has an id, header, accessor, and optional sort/filter/cell renderer."
        },
        {
          "name": "getRowId",
          "type": "(row: T, index: number) => string",
          "default": "defaultGetRowId",
          "description": "Stable row identifier. Defaults to `row.id` if present, otherwise the row index."
        },
        {
          "name": "pageSize",
          "type": "number",
          "default": "undefined",
          "description": "Enables client-side pagination. Renders all rows if absent."
        },
        {
          "name": "selectable",
          "type": "boolean",
          "default": false,
          "description": "Show the row-selection checkbox column."
        },
        {
          "name": "onSelectionChange",
          "type": "(ids: Set<string>) => void",
          "default": "undefined",
          "description": "Fires whenever the selection changes."
        },
        {
          "name": "defaultSelection",
          "type": "Iterable<string>",
          "default": "undefined",
          "description": "Initial selection (uncontrolled)."
        },
        {
          "name": "selection",
          "type": "Set<string>",
          "default": "undefined",
          "description": "Controlled selection. Pair with `onSelectionChange`."
        },
        {
          "name": "defaultSort",
          "type": "{ id: string; direction: 'asc' | 'desc' }",
          "default": "undefined",
          "description": "Initial sort (uncontrolled)."
        },
        {
          "name": "sort",
          "type": "{ id: string; direction: 'asc' | 'desc' } | null",
          "default": "undefined",
          "description": "Controlled sort. Pair with `onSortChange`. Use for server-side sorting."
        },
        {
          "name": "onSortChange",
          "type": "(sort: { id: string; direction: 'asc' | 'desc' } | null) => void",
          "default": "undefined",
          "description": "Fires when the user changes the active sort."
        },
        {
          "name": "emptyState",
          "type": "ReactNode",
          "default": "undefined",
          "description": "Rendered when no rows match. Defaults to a friendly \"No results\" message."
        },
        {
          "name": "loading",
          "type": "boolean",
          "default": false,
          "description": "When true, replaces the body with `loadingState`."
        },
        {
          "name": "loadingState",
          "type": "ReactNode",
          "default": "undefined",
          "description": "Rendered while `loading` is true. Defaults to a \"Loading…\" line."
        },
        {
          "name": "striped",
          "type": "boolean",
          "default": true,
          "description": "Alternate row backgrounds."
        },
        {
          "name": "bordered",
          "type": "boolean",
          "default": true,
          "description": "Borders between rows."
        },
        {
          "name": "density",
          "type": "'compact' | 'comfortable'",
          "default": "undefined",
          "description": "Overrides the density gene for this table. Useful for admin views."
        }
      ],
      "slots": [],
      "tokens": [
        "color.bg.surface.default",
        "color.bg.surface.subtle",
        "color.bg.action.brand.subtle",
        "color.bg.action.brand.default",
        "color.border.subtle",
        "color.border.action.brand",
        "color.text.primary",
        "color.text.secondary",
        "color.text.muted",
        "color.text.action.brand",
        "radius.sm",
        "radius.md",
        "spacing.1",
        "spacing.2",
        "spacing.3",
        "spacing.4",
        "spacing.8",
        "font.size.xs",
        "font.size.sm",
        "font.weight.semibold"
      ],
      "a11y": {
        "role": "table",
        "keyboard": [
          {
            "key": "Tab",
            "action": "Focus moves between sortable headers / filter inputs / checkboxes."
          },
          {
            "key": "Space",
            "action": "On a focused sort header — toggles asc → desc → off."
          },
          {
            "key": "ArrowKeys",
            "action": "Native browser scrolling inside the table region."
          }
        ],
        "notes": [
          "Sortable headers announce `aria-sort` (ascending / descending / none).",
          "Each row's checkbox has a contextual `aria-label`.",
          "The scrollable container is a focusable region with a visible focus ring.",
          "Caption announces the total row count and active sort."
        ]
      },
      "composes_with": [],
      "related": [
        "table"
      ],
      "when_to_use": [],
      "pitfalls": [],
      "prompt_examples": []
    },
    {
      "name": "DateField",
      "slug": "date-field",
      "package": "@helixui/core",
      "import": "import { DateField } from '@helixui/core'",
      "description": "Segmented date input — month / day / year (or whatever the user's locale prefers). Built on react-aria-components.",
      "category": "form",
      "tags": [
        "date",
        "input",
        "segmented",
        "picker",
        "calendar"
      ],
      "status": "stable",
      "since": "0.1.0",
      "layout": null,
      "anatomy": null,
      "visual": null,
      "props": [
        {
          "name": "label",
          "type": "string",
          "default": "undefined",
          "description": "Field label rendered above the segmented input."
        },
        {
          "name": "description",
          "type": "string",
          "default": "undefined",
          "description": "Helper text rendered below the field."
        },
        {
          "name": "errorMessage",
          "type": "string",
          "default": "undefined",
          "description": "Validation message shown when the field is invalid."
        },
        {
          "name": "tone",
          "type": "'brand' | 'neutral' | 'danger'",
          "default": "brand",
          "description": "Tone for the focus ring and error styling."
        },
        {
          "name": "size",
          "type": "'sm' | 'md' | 'lg'",
          "default": "md",
          "description": "Touch target size, matching every other helixui input."
        },
        {
          "name": "value",
          "type": "DateValue | null",
          "default": "undefined",
          "description": "Controlled value."
        },
        {
          "name": "defaultValue",
          "type": "DateValue",
          "default": "undefined",
          "description": "Uncontrolled initial value."
        },
        {
          "name": "onChange",
          "type": "(value: DateValue | null) => void",
          "default": "undefined",
          "description": "Fires whenever the user completes a segment edit."
        },
        {
          "name": "minValue",
          "type": "DateValue",
          "default": "undefined",
          "description": "Earliest selectable date."
        },
        {
          "name": "maxValue",
          "type": "DateValue",
          "default": "undefined",
          "description": "Latest selectable date."
        },
        {
          "name": "isDisabled",
          "type": "boolean",
          "default": false,
          "description": "Renders the field disabled and removes it from tab order."
        },
        {
          "name": "isReadOnly",
          "type": "boolean",
          "default": false,
          "description": "Renders the field non-editable but still focusable."
        }
      ],
      "slots": [],
      "tokens": [
        "color.bg.input",
        "color.bg.surface.default",
        "color.border.subtle",
        "color.border.action.brand",
        "color.border.danger",
        "color.text.primary",
        "color.text.secondary",
        "color.text.muted",
        "color.text.action.brand",
        "color.text.danger",
        "radius.sm",
        "radius.md",
        "spacing.1",
        "spacing.2",
        "spacing.3",
        "spacing.4",
        "font.size.sm",
        "font.size.md",
        "font.size.lg",
        "font.size.xs"
      ],
      "a11y": {
        "role": "group",
        "keyboard": [
          {
            "key": "Tab",
            "action": "Focus the next segment."
          },
          {
            "key": "ArrowUp",
            "action": "Increment the focused segment."
          },
          {
            "key": "ArrowDown",
            "action": "Decrement the focused segment."
          },
          {
            "key": "0-9",
            "action": "Overwrite the focused segment."
          }
        ],
        "notes": [
          "Each segment is independently focusable.",
          "Disabled and read-only states respect ARIA conventions.",
          "`errorMessage` is announced via `aria-describedby`."
        ]
      },
      "composes_with": [],
      "related": [],
      "when_to_use": [],
      "pitfalls": [],
      "prompt_examples": []
    },
    {
      "name": "DatePicker",
      "slug": "date-picker",
      "package": "@helixui/core",
      "import": "import { DatePicker } from '@helixui/core'",
      "description": "Segmented date input plus a popover calendar. Pick a date by typing, arrow keys, or clicking the grid.",
      "category": "form",
      "tags": [
        "date",
        "picker",
        "popover",
        "calendar",
        "input"
      ],
      "status": "stable",
      "since": "0.1.0",
      "layout": null,
      "anatomy": null,
      "visual": null,
      "props": [
        {
          "name": "label",
          "type": "string",
          "default": "undefined",
          "description": "Field label rendered above the trigger."
        },
        {
          "name": "description",
          "type": "string",
          "default": "undefined",
          "description": "Helper text rendered below the trigger."
        },
        {
          "name": "errorMessage",
          "type": "string",
          "default": "undefined",
          "description": "Validation error rendered when the field is invalid."
        },
        {
          "name": "tone",
          "type": "'brand' | 'neutral' | 'danger'",
          "default": "brand",
          "description": "Tone for the focus ring and the selected day in the calendar."
        },
        {
          "name": "size",
          "type": "'sm' | 'md' | 'lg'",
          "default": "md",
          "description": "Touch target size matching every other helixui input."
        },
        {
          "name": "value",
          "type": "DateValue | null",
          "default": "undefined",
          "description": "Controlled selected date."
        },
        {
          "name": "defaultValue",
          "type": "DateValue",
          "default": "undefined",
          "description": "Uncontrolled initial selected date."
        },
        {
          "name": "onChange",
          "type": "(value: DateValue | null) => void",
          "default": "undefined",
          "description": "Fires when the user picks a date in the grid or commits a segment edit."
        },
        {
          "name": "minValue",
          "type": "DateValue",
          "default": "undefined",
          "description": "Earliest selectable date."
        },
        {
          "name": "maxValue",
          "type": "DateValue",
          "default": "undefined",
          "description": "Latest selectable date."
        },
        {
          "name": "isDateUnavailable",
          "type": "(date: DateValue) => boolean",
          "default": "undefined",
          "description": "Mark specific dates as unselectable (blackout dates)."
        },
        {
          "name": "isDisabled",
          "type": "boolean",
          "default": false,
          "description": "Disable the entire picker."
        },
        {
          "name": "isReadOnly",
          "type": "boolean",
          "default": false,
          "description": "Show the field as non-editable while still focusable."
        }
      ],
      "slots": [],
      "tokens": [
        "color.bg.input",
        "color.bg.surface.default",
        "color.bg.surface.subtle",
        "color.bg.action.brand.default",
        "color.bg.action.brand.subtle",
        "color.border.subtle",
        "color.border.action.brand",
        "color.border.danger",
        "color.text.primary",
        "color.text.secondary",
        "color.text.muted",
        "color.text.action.brand",
        "color.text.action.brand.on",
        "color.text.danger",
        "radius.sm",
        "radius.md",
        "radius.lg",
        "shadow.lg",
        "spacing.1",
        "spacing.2",
        "spacing.3",
        "spacing.4",
        "font.size.xs",
        "font.size.sm",
        "font.size.md",
        "font.size.lg",
        "font.weight.regular",
        "font.weight.medium",
        "font.weight.semibold"
      ],
      "a11y": {
        "role": "combobox",
        "keyboard": [
          {
            "key": "Tab",
            "action": "Focus the next segment or the trigger."
          },
          {
            "key": "ArrowUp",
            "action": "Increment focused segment."
          },
          {
            "key": "ArrowDown",
            "action": "Decrement focused segment."
          },
          {
            "key": "Enter",
            "action": "Open the popover from the trigger; select a focused day in the grid."
          },
          {
            "key": "Escape",
            "action": "Close the popover."
          },
          {
            "key": "ArrowKeys",
            "action": "Inside the grid — move by day; PageUp/PageDown by month."
          }
        ],
        "notes": [
          "Each input segment is independently focusable.",
          "The trigger is a labeled `<button>` that opens a dialog with the calendar.",
          "The dialog traps focus while open and restores focus to the trigger on close.",
          "Days announce their selection state and unavailable state.",
          "`errorMessage` is exposed via `aria-describedby`."
        ]
      },
      "composes_with": [],
      "related": [],
      "when_to_use": [],
      "pitfalls": [],
      "prompt_examples": []
    },
    {
      "name": "DateRangePicker",
      "slug": "date-range-picker",
      "package": "@helixui/core",
      "import": "import { DateRangePicker } from '@helixui/core'",
      "description": "Two segmented date inputs (start + end) plus a popover range calendar.",
      "category": "form",
      "tags": [
        "date",
        "range",
        "picker",
        "calendar",
        "popover",
        "departure",
        "return"
      ],
      "status": "stable",
      "since": "0.1.0",
      "layout": null,
      "anatomy": null,
      "visual": null,
      "props": [
        {
          "name": "label",
          "type": "string",
          "default": "undefined",
          "description": "Field label rendered above the trigger row."
        },
        {
          "name": "description",
          "type": "string",
          "default": "undefined",
          "description": "Helper text rendered below the trigger row."
        },
        {
          "name": "errorMessage",
          "type": "string",
          "default": "undefined",
          "description": "Validation error rendered when the field is invalid."
        },
        {
          "name": "tone",
          "type": "'brand' | 'neutral' | 'danger'",
          "default": "brand",
          "description": "Tone for the focus ring and selected days."
        },
        {
          "name": "size",
          "type": "'sm' | 'md' | 'lg'",
          "default": "md",
          "description": "Touch target size, matching every other helixui input."
        },
        {
          "name": "value",
          "type": "RangeValue<DateValue> | null",
          "default": "undefined",
          "description": "Controlled selected range."
        },
        {
          "name": "defaultValue",
          "type": "RangeValue<DateValue>",
          "default": "undefined",
          "description": "Uncontrolled initial range."
        },
        {
          "name": "onChange",
          "type": "(value: RangeValue<DateValue> | null) => void",
          "default": "undefined",
          "description": "Fires when the user picks a complete range."
        },
        {
          "name": "minValue",
          "type": "DateValue",
          "default": "undefined",
          "description": "Earliest selectable date."
        },
        {
          "name": "maxValue",
          "type": "DateValue",
          "default": "undefined",
          "description": "Latest selectable date."
        },
        {
          "name": "isDateUnavailable",
          "type": "(date: DateValue) => boolean",
          "default": "undefined",
          "description": "Mark specific dates as unselectable (blackout dates)."
        },
        {
          "name": "isDisabled",
          "type": "boolean",
          "default": false,
          "description": "Disable the entire picker."
        },
        {
          "name": "isReadOnly",
          "type": "boolean",
          "default": false,
          "description": "Show as non-editable."
        }
      ],
      "slots": [],
      "tokens": [
        "color.bg.surface.default",
        "color.bg.action.brand.default",
        "color.bg.action.brand.subtle",
        "color.border.subtle",
        "color.border.action.brand",
        "color.text.primary",
        "color.text.muted",
        "color.text.action.brand",
        "color.text.action.brand.on",
        "radius.md",
        "spacing.1"
      ],
      "a11y": {
        "role": "combobox",
        "keyboard": [
          {
            "key": "Tab",
            "action": "Move between start / end segments and the trigger."
          },
          {
            "key": "ArrowUp",
            "action": "Increment focused segment."
          },
          {
            "key": "ArrowDown",
            "action": "Decrement focused segment."
          },
          {
            "key": "Enter",
            "action": "Open the popover; on the grid, anchor or commit the range."
          },
          {
            "key": "ArrowKeys",
            "action": "Inside the grid — move by day; PageUp/PageDown by month."
          }
        ],
        "notes": [
          "Each segment is independently focusable.",
          "The trigger is a labeled button; opens a dialog with a range-aware calendar.",
          "Days inside the active range announce as `aria-selected`."
        ]
      },
      "composes_with": [],
      "related": [
        "date-picker",
        "calendar"
      ],
      "when_to_use": [],
      "pitfalls": [],
      "prompt_examples": []
    },
    {
      "name": "DateTimePicker",
      "slug": "date-time-picker",
      "package": "@helixui/core",
      "import": "import { DateTimePicker } from '@helixui/core'",
      "description": "Date + time picker — segmented date input, time field, and a popover calendar. For meeting times, appointment slots, scheduled posts.",
      "category": "form",
      "tags": [
        "date",
        "time",
        "picker",
        "calendar",
        "schedule",
        "appointment"
      ],
      "status": "stable",
      "since": "0.1.0",
      "layout": null,
      "anatomy": null,
      "visual": null,
      "props": [
        {
          "name": "label",
          "type": "string",
          "default": "undefined",
          "description": "Field label rendered above the row."
        },
        {
          "name": "description",
          "type": "string",
          "default": "undefined",
          "description": "Helper text rendered below the row."
        },
        {
          "name": "errorMessage",
          "type": "string",
          "default": "undefined",
          "description": "Validation message shown when invalid."
        },
        {
          "name": "tone",
          "type": "'brand' | 'neutral' | 'danger'",
          "default": "brand",
          "description": "Tone for focus ring + selected day."
        },
        {
          "name": "size",
          "type": "'sm' | 'md' | 'lg'",
          "default": "md",
          "description": "Touch target size."
        },
        {
          "name": "value",
          "type": "DateValue | null",
          "default": "undefined",
          "description": "Controlled date."
        },
        {
          "name": "onChange",
          "type": "(value: DateValue | null) => void",
          "default": "undefined",
          "description": "Fires when the date changes."
        },
        {
          "name": "time",
          "type": "TimeValue",
          "default": "undefined",
          "description": "Controlled time portion."
        },
        {
          "name": "onTimeChange",
          "type": "(value: TimeValue | null) => void",
          "default": "undefined",
          "description": "Fires when the time changes."
        },
        {
          "name": "defaultTime",
          "type": "TimeValue",
          "default": "undefined",
          "description": "Uncontrolled initial time."
        },
        {
          "name": "timeStep",
          "type": "number",
          "default": 5,
          "description": "Granularity of the minute field, in minutes."
        }
      ],
      "slots": [],
      "tokens": [
        "color.bg.surface.default",
        "color.bg.action.brand.default",
        "color.border.subtle",
        "color.border.action.brand",
        "color.text.primary",
        "color.text.muted",
        "color.text.action.brand",
        "radius.sm",
        "radius.md",
        "radius.lg",
        "spacing.1",
        "spacing.2",
        "spacing.3"
      ],
      "a11y": {
        "role": "combobox",
        "keyboard": [
          {
            "key": "Tab",
            "action": "Move between date segments, time segments, and the trigger."
          },
          {
            "key": "ArrowUp",
            "action": "Increment focused segment."
          },
          {
            "key": "ArrowDown",
            "action": "Decrement focused segment."
          },
          {
            "key": "Enter",
            "action": "Open the popover from the trigger; select a focused day in the grid."
          }
        ],
        "notes": [
          "Date and time fields are independently focusable.",
          "Time field defaults to 24-hour; pass `hourCycle={12}` via wrapping for am/pm.",
          "The popover calendar only affects the date; the time persists across day changes."
        ]
      },
      "composes_with": [],
      "related": [
        "date-picker",
        "date-range-picker",
        "calendar"
      ],
      "when_to_use": [],
      "pitfalls": [],
      "prompt_examples": []
    },
    {
      "name": "Dialog",
      "slug": "dialog",
      "package": "@helixui/core",
      "import": "import { Dialog, DialogTrigger } from '@helixui/core'",
      "description": "A modal that traps focus and dims the page behind it. Use for tasks that require completion before continuing.",
      "category": "overlay",
      "tags": [
        "modal",
        "blocking",
        "confirm",
        "focus-trap",
        "dismissable"
      ],
      "status": "stable",
      "since": "0.1.0",
      "layout": {
        "display": "portal",
        "width": "fixed:380/540/720px (sm/md/lg)",
        "height": "content",
        "intrinsicSize": "centered, max-w by size, max-h ~80vh, scrolls inside",
        "stackable": false,
        "fullBleed": false
      },
      "anatomy": "┌─ overlay (full screen, dimmed) ────────────────────────┐\n│                                                        │\n│      ┌── dialog panel ─────────────────────────┐      │\n│      │  Title (h2 slot)                         │      │\n│      │  Description                              │      │\n│      │                                           │      │\n│      │  <children — usually a Stack form>        │      │\n│      │                                           │      │\n│      │  [ Cancel ]  [ Confirm ]   ← actions row  │      │\n│      └──────────────────────────────────────────┘      │\n│                                                        │\n└────────────────────────────────────────────────────────┘\n ↑ trapped focus, dismiss on overlay-click + Escape (when isDismissable)\n",
      "visual": "A centered surface (radius.xl) on a dimmed overlay. The panel uses surface.default with a strong shadow (shadow.lg)\nand ample padding (space.6). Title is large semibold (font.size.xl + font.weight.semibold), description in muted\nsecondary text below. Mounts with a subtle scale-and-fade (respects prefers-reduced-motion). Body scrolls\ninternally when it overflows; header and footer remain pinned only if you compose them with Stack.\n",
      "props": [
        {
          "name": "title",
          "type": "ReactNode",
          "default": "",
          "description": "Dialog title — rendered as `<h2 slot=\"title\">` for screen readers."
        },
        {
          "name": "description",
          "type": "ReactNode",
          "default": "",
          "description": "Lead paragraph below the title."
        },
        {
          "name": "size",
          "type": "'sm' | 'md' | 'lg'",
          "default": "md",
          "description": "Max width — 380 / 540 / 720 px."
        },
        {
          "name": "isDismissable",
          "type": "boolean",
          "default": true,
          "description": "Allow close via overlay click and Escape."
        },
        {
          "name": "isOpen",
          "type": "boolean",
          "default": "",
          "description": "Controlled open state."
        },
        {
          "name": "defaultOpen",
          "type": "boolean",
          "default": false,
          "description": "Uncontrolled initial open."
        },
        {
          "name": "onOpenChange",
          "type": "(open: boolean) => void",
          "default": "",
          "description": "Open change handler."
        }
      ],
      "slots": [
        "DialogTrigger child — the button that opens the dialog",
        "Dialog children — content; render-prop receives `{ close }` to close imperatively"
      ],
      "tokens": [
        "color.bg.surface.default",
        "color.text.primary",
        "color.text.secondary",
        "radius.xl",
        "space.4",
        "space.6",
        "space.12",
        "font.family.sans",
        "font.size.sm",
        "font.size.xl",
        "font.weight.semibold",
        "font.lineHeight.tight",
        "shadow.lg"
      ],
      "a11y": {
        "role": "dialog",
        "keyboard": [
          {
            "key": "Tab",
            "action": "Cycles through focusable content. Focus is trapped."
          },
          {
            "key": "Escape",
            "action": "Closes the dialog when `isDismissable`."
          }
        ],
        "notes": [
          "Always provide `title` (or set `aria-label` on the Dialog) so screen readers announce the dialog's purpose.",
          "Animations respect `prefers-reduced-motion`."
        ]
      },
      "composes_with": [
        {
          "component": "DialogTrigger",
          "relation": "parent",
          "note": "Required wrapper that provides the open trigger element."
        },
        {
          "component": "Button",
          "relation": "trigger",
          "note": "Most common trigger inside DialogTrigger."
        },
        {
          "component": "Stack",
          "relation": "child",
          "note": "Recommended layout for the dialog body and its actions row."
        },
        {
          "component": "Form",
          "relation": "child",
          "note": "Forms inside dialogs submit and then close via the render-prop `close()`."
        },
        {
          "component": "Sheet",
          "relation": "alternative",
          "note": "On small screens prefer Sheet (side='bottom') for the same task."
        },
        {
          "component": "Popover",
          "relation": "alternative",
          "note": "Use Popover for non-blocking, anchored interactions."
        }
      ],
      "related": [
        "Sheet",
        "Popover"
      ],
      "when_to_use": [],
      "pitfalls": [],
      "prompt_examples": [
        {
          "intent": "destructive confirmation",
          "prompt": "delete account confirmation modal",
          "snippet": "<DialogTrigger>\n  <Button tone=\"danger\">Delete account</Button>\n  <Dialog title=\"Delete account?\" description=\"This cannot be undone.\">\n    {({ close }) => (\n      <Stack direction=\"row\" justify=\"end\" gap={2}>\n        <Button variant=\"ghost\" onPress={close}>Cancel</Button>\n        <Button tone=\"danger\" onPress={close}>Delete</Button>\n      </Stack>\n    )}\n  </Dialog>\n</DialogTrigger>\n"
        },
        {
          "intent": "small form in a modal",
          "prompt": "modal to rename a project",
          "snippet": "<DialogTrigger>\n  <Button variant=\"soft\">Rename</Button>\n  <Dialog title=\"Rename project\" size=\"sm\">\n    {({ close }) => (\n      <Stack gap={3}>\n        <TextInput label=\"Name\" />\n        <Stack direction=\"row\" justify=\"end\" gap={2}>\n          <Button variant=\"ghost\" onPress={close}>Cancel</Button>\n          <Button onPress={close}>Save</Button>\n        </Stack>\n      </Stack>\n    )}\n  </Dialog>\n</DialogTrigger>\n"
        },
        {
          "intent": "non-dismissable required choice",
          "prompt": "accept terms blocking modal that cannot be dismissed",
          "snippet": "<Dialog isOpen title=\"Accept the terms\" isDismissable={false}>\n  {({ close }) => (\n    <Stack gap={4}>\n      <Text>You must accept the terms to continue.</Text>\n      <Button onPress={close}>I agree</Button>\n    </Stack>\n  )}\n</Dialog>\n"
        },
        {
          "intent": "controlled open/close",
          "prompt": "dialog whose open state lives in my component",
          "snippet": "const [open, setOpen] = useState(false);\n<Dialog isOpen={open} onOpenChange={setOpen} title=\"Edit\">\n  ...\n</Dialog>\n"
        }
      ]
    },
    {
      "name": "HelixUIDNAProvider",
      "slug": "dna-provider",
      "package": "@helixui/core",
      "import": "import { HelixUIDNAProvider } from '@helixui/core'",
      "description": "Applies a `DNA` (helixui theme genome) to a wrapping div. Every component inside re-renders under the genome's accent / chroma / radius / density / typography / surface / motion / lightness genes via cascading CSS variables — no JS rerender beyond a style mutation.",
      "category": "shell",
      "tags": [
        "theme",
        "dna",
        "genome",
        "provider"
      ],
      "status": "stable",
      "since": "0.4.0",
      "layout": {
        "display": "block",
        "width": "auto",
        "height": "auto",
        "intrinsicSize": "unstyled wrapper; pure CSS variable scope",
        "stackable": true,
        "fullBleed": false
      },
      "anatomy": "<HelixUIDNAProvider dna={...}>\n  ⟨all components inside inherit the genome⟩\n</HelixUIDNAProvider>\n",
      "visual": "A presentational wrapper that applies CSS variables for accent / chroma / radius / density / typography / surface / motion / lightness genes. Children re-render visually without React rerender — the gene change is just a style mutation.\n",
      "props": [
        {
          "name": "dna",
          "type": "DNA",
          "default": "",
          "description": "Required. A DNA value from `@helixui/dna` — `wildtype()`, a preset, a mutation, or a bred child."
        },
        {
          "name": "inline",
          "type": "boolean",
          "default": false,
          "description": "Render the wrapper as `inline-block` (for compact previews)."
        },
        {
          "name": "...rest",
          "type": "HTMLAttributes<HTMLDivElement>",
          "default": "",
          "description": "Native div attributes."
        }
      ],
      "slots": [
        "children — the subtree that should render under this DNA"
      ],
      "tokens": [
        "color.bg.surface.default",
        "color.text.primary",
        "font.family.sans"
      ],
      "a11y": {
        "notes": [
          "The wrapping div sets `data-theme` only when the DNA's `lightness` gene is fixed (`light` / `dark`). With `auto` the inherited theme is used.",
          "DNA changes animate the surface color via a CSS `transition` (220ms); respects `prefers-reduced-motion`."
        ]
      },
      "composes_with": [
        {
          "component": "ThemeProvider",
          "relation": "parent",
          "note": "ThemeProvider sets light/dark; DNAProvider tunes the genome on top."
        }
      ],
      "related": [
        "ThemeProvider"
      ],
      "when_to_use": [],
      "pitfalls": [],
      "prompt_examples": [
        {
          "intent": "apply a custom theme genome",
          "prompt": "wrap the app in a DNA with rounder radius",
          "snippet": "<HelixUIDNAProvider dna={{ radius: 'round', density: 'cozy' }}>\n  <App />\n</HelixUIDNAProvider>\n"
        }
      ]
    },
    {
      "name": "EmptyState",
      "slug": "empty-state",
      "package": "@helixui/core",
      "import": "import { EmptyState } from '@helixui/core'",
      "description": "A centered placeholder for \"no data yet\" — icon, title, description, and an action.",
      "category": "feedback",
      "tags": [
        "placeholder",
        "no-data",
        "cta"
      ],
      "status": "stable",
      "since": "0.2.0",
      "layout": {
        "display": "block",
        "width": "fill",
        "height": "content",
        "intrinsicSize": "centered, ~280px tall",
        "stackable": false,
        "fullBleed": false
      },
      "anatomy": "        [icon]\n      Title\n   short description\n     [ Action ]\n",
      "visual": "A centered column with a large muted icon, a heading, a description, and an optional primary action button. Used inside an empty Card, empty list, or empty page.\n",
      "props": [
        {
          "name": "icon",
          "type": "ReactNode",
          "default": "",
          "description": "Optional leading icon."
        },
        {
          "name": "title",
          "type": "ReactNode",
          "default": "",
          "description": "Headline."
        },
        {
          "name": "description",
          "type": "ReactNode",
          "default": "",
          "description": "Supporting text."
        },
        {
          "name": "actions",
          "type": "ReactNode",
          "default": "",
          "description": "Buttons or links to recover from the empty state."
        },
        {
          "name": "size",
          "type": "'sm' | 'md'",
          "default": "md",
          "description": "Compact or full size."
        }
      ],
      "slots": [],
      "tokens": [
        "color.bg.action.neutral.default",
        "color.text.primary",
        "color.text.secondary",
        "color.text.muted",
        "radius.full",
        "space.2",
        "space.3",
        "space.6",
        "space.12",
        "font.family.sans",
        "font.size.sm",
        "font.size.md",
        "font.size.lg",
        "font.weight.semibold"
      ],
      "a11y": {
        "role": "status",
        "notes": [
          "The container uses `role=\"status\"` so screen readers announce the empty state when it appears.",
          "Always include `actions` if there's a path to recover (create the first item, retry, …)."
        ]
      },
      "composes_with": [
        {
          "component": "Card",
          "relation": "parent",
          "note": "Often inside a Card to show \"no data yet\"."
        },
        {
          "component": "Button",
          "relation": "child",
          "note": "Primary CTA below the description."
        },
        {
          "component": "Banner",
          "relation": "sibling"
        }
      ],
      "related": [
        "Banner"
      ],
      "when_to_use": [],
      "pitfalls": [],
      "prompt_examples": [
        {
          "intent": "empty inbox",
          "prompt": "no messages placeholder with a Compose button",
          "snippet": "<EmptyState\n  icon={<InboxIcon />}\n  title=\"No messages\"\n  description=\"When someone writes you, it appears here.\"\n  action={<Button>Compose</Button>}\n/>\n"
        }
      ]
    },
    {
      "name": "FAB",
      "slug": "fab",
      "package": "@helixui/core",
      "import": "import { FAB } from '@helixui/core'",
      "description": "Floating action button — circular by default, or pill (`extended`) with an icon + label. Fixed-positioned at the bottom-right by default; place yourself with `positioned={false}`.",
      "category": "overlay",
      "tags": [
        "mobile",
        "floating",
        "primary-action",
        "circular"
      ],
      "status": "stable",
      "since": "0.5.0",
      "layout": {
        "display": "fixed",
        "width": "content",
        "height": "content",
        "intrinsicSize": "~56px circle (default), or pill in extended",
        "stackable": false,
        "fullBleed": false
      },
      "anatomy": "…page content…\n                     ╭─╮\n                     │+│   ← circular FAB\n                     ╰─╯\n",
      "visual": "A circular brand-colored button with a centered icon, fixed to the bottom-right with safe-area padding. The `extended` variant becomes a pill with icon + label. Uses shadow.lg for lift.\n",
      "props": [
        {
          "name": "aria-label",
          "type": "string",
          "default": "",
          "description": "Required accessible name when icon-only (no extended label)."
        },
        {
          "name": "tone",
          "type": "'brand' | 'neutral' | 'danger'",
          "default": "brand",
          "description": "Color intent."
        },
        {
          "name": "size",
          "type": "'sm' | 'md' | 'lg'",
          "default": "md",
          "description": "Diameter / pill height — 40 / 56 / 64 px."
        },
        {
          "name": "extended",
          "type": "boolean",
          "default": false,
          "description": "Render as a pill with icon + label child."
        },
        {
          "name": "positioned",
          "type": "boolean",
          "default": true,
          "description": "Fixed-position at bottom-right with safe-area inset; set false to place manually."
        },
        {
          "name": "icon",
          "type": "ReactNode",
          "default": "",
          "description": "Icon content."
        }
      ],
      "slots": [
        "children — used as label only when `extended`"
      ],
      "tokens": [
        "color.bg.action.brand.default",
        "color.bg.action.brand.hover",
        "color.bg.action.danger.default",
        "color.bg.action.danger.hover",
        "color.bg.action.neutral.default",
        "color.bg.surface.default",
        "color.text.on.brand",
        "color.text.on.danger",
        "color.text.primary",
        "color.border.default",
        "color.border.focus",
        "radius.full",
        "space.2",
        "space.4",
        "space.5",
        "font.family.sans",
        "font.size.sm",
        "font.size.md",
        "font.weight.semibold",
        "shadow.lg"
      ],
      "a11y": {
        "role": "button",
        "notes": [
          "Always provide `aria-label` for the icon-only variant — the screen reader has no visible text.",
          "Default placement adds `bottom: var(--helixui-space-4) + env(safe-area-inset-bottom)` so the FAB clears the iOS home indicator and any BottomNav."
        ]
      },
      "composes_with": [
        {
          "component": "SafeArea",
          "relation": "parent",
          "note": "Wrap on mobile builds for inset."
        },
        {
          "component": "IconButton",
          "relation": "alternative",
          "note": "IconButton stays inline; FAB floats."
        },
        {
          "component": "BottomNav",
          "relation": "sibling"
        },
        {
          "component": "ActionSheet",
          "relation": "sibling"
        }
      ],
      "related": [
        "BottomNav",
        "ActionSheet",
        "IconButton"
      ],
      "when_to_use": [],
      "pitfalls": [],
      "prompt_examples": [
        {
          "intent": "compose new email",
          "prompt": "a floating + button in the bottom-right",
          "snippet": "<FAB icon={<PlusIcon />} aria-label=\"Compose\" onPress={compose} />\n"
        },
        {
          "intent": "extended FAB with label",
          "prompt": "pill-shaped FAB saying \"New post\"",
          "snippet": "<FAB extended icon={<PlusIcon />}>New post</FAB>\n"
        }
      ]
    },
    {
      "name": "Field",
      "slug": "field",
      "package": "@helixui/core",
      "import": "import { Field } from '@helixui/core'",
      "description": "A vertical layout for label + control + description + error message. Use with non-RAC controls; RAC inputs (TextInput, Checkbox, etc.) already accept `label`/`description`/`errorMessage` props.",
      "category": "form",
      "tags": [
        "label",
        "description",
        "error",
        "wrapper"
      ],
      "status": "stable",
      "since": "0.1.0",
      "layout": {
        "display": "block",
        "width": "fill",
        "height": "content",
        "intrinsicSize": "vertical stack, hugs control height",
        "stackable": true,
        "fullBleed": false
      },
      "anatomy": "Label                                            (required)\n[control]\nHelp text describing the field\nError message\n",
      "visual": "A vertical stack: a label (font.weight.semibold), the wrapped control, an optional muted description, and an error message in danger tone when present.\n",
      "props": [
        {
          "name": "...rest",
          "type": "HTMLAttributes<HTMLDivElement>",
          "default": "",
          "description": "Native div attributes."
        }
      ],
      "slots": [
        "children — Field.Label, the control, Field.Description, Field.Error in any order"
      ],
      "tokens": [
        "color.text.primary",
        "color.text.secondary",
        "color.text.action.danger",
        "font.family.sans",
        "font.size.sm",
        "font.weight.medium",
        "space.2"
      ],
      "a11y": {
        "notes": [
          "Field is presentational. Wire `htmlFor`/`id` between Label and the control yourself.",
          "Field.Error has `role=\"alert\"` so screen readers announce changes."
        ]
      },
      "composes_with": [
        {
          "component": "TextInput",
          "relation": "wraps",
          "note": "Wrap any non-RAC control with Field for label/description/error."
        },
        {
          "component": "Form",
          "relation": "parent",
          "note": "Inside a Form."
        },
        {
          "component": "Textarea",
          "relation": "sibling"
        },
        {
          "component": "Checkbox",
          "relation": "sibling"
        },
        {
          "component": "Switch",
          "relation": "sibling"
        },
        {
          "component": "RadioGroup",
          "relation": "sibling"
        }
      ],
      "related": [
        "TextInput",
        "Textarea",
        "Checkbox",
        "Switch",
        "RadioGroup"
      ],
      "when_to_use": [],
      "pitfalls": [],
      "prompt_examples": [
        {
          "intent": "wrap a custom control",
          "prompt": "add label/help to a custom select",
          "snippet": "<Field label=\"Country\" description=\"Used for tax purposes\">\n  <CustomSelect />\n</Field>\n"
        }
      ]
    },
    {
      "name": "FileUpload",
      "slug": "file-upload",
      "package": "@helixui/core",
      "import": "import { FileUpload } from '@helixui/core'",
      "description": "Drag-and-drop file upload with progress, errors, and accept/size filtering. Pair with your own upload pipeline.",
      "category": "form",
      "tags": [
        "file",
        "upload",
        "dropzone",
        "attachment",
        "drag-drop",
        "input"
      ],
      "status": "stable",
      "since": "0.1.0",
      "layout": null,
      "anatomy": null,
      "visual": null,
      "props": [
        {
          "name": "label",
          "type": "string",
          "default": "undefined",
          "description": "Field label rendered above the dropzone."
        },
        {
          "name": "description",
          "type": "ReactNode",
          "default": "undefined",
          "description": "Helper text rendered below the dropzone."
        },
        {
          "name": "hint",
          "type": "ReactNode",
          "default": "undefined",
          "description": "Visible inside the dropzone — defaults to a \"Click to upload or drag and drop\" cue."
        },
        {
          "name": "accept",
          "type": "string",
          "default": "undefined",
          "description": "MIME / extension filter; e.g. \"image/*\" or \".pdf,.docx\"."
        },
        {
          "name": "maxSize",
          "type": "number",
          "default": "undefined",
          "description": "Max file size in bytes. Files larger are reported via `onReject`."
        },
        {
          "name": "multiple",
          "type": "boolean",
          "default": false,
          "description": "Allow selecting more than one file."
        },
        {
          "name": "onFiles",
          "type": "(files: File[]) => void",
          "default": "undefined",
          "description": "Fires when files pass the accept + size filters."
        },
        {
          "name": "onReject",
          "type": "(rejections: { file: File; reason: 'size' | 'type' }[]) => void",
          "default": "undefined",
          "description": "Fires for files that fail filtering."
        },
        {
          "name": "progress",
          "type": "Record<string, number>",
          "default": "undefined",
          "description": "Map of file.name → 0-100 percent. helixui renders a progress bar per file."
        },
        {
          "name": "errors",
          "type": "Record<string, string>",
          "default": "undefined",
          "description": "Optional per-file error messages, keyed by file.name."
        },
        {
          "name": "tone",
          "type": "'brand' | 'neutral'",
          "default": "brand",
          "description": "Tone for the active drop ring."
        },
        {
          "name": "disabled",
          "type": "boolean",
          "default": false,
          "description": "Disable interaction."
        }
      ],
      "slots": [],
      "tokens": [
        "color.bg.surface.default",
        "color.bg.surface.subtle",
        "color.bg.action.brand.subtle",
        "color.bg.action.brand.default",
        "color.border.subtle",
        "color.border.action.brand",
        "color.text.primary",
        "color.text.secondary",
        "color.text.muted",
        "color.text.action.brand",
        "color.text.danger",
        "radius.sm",
        "radius.md",
        "radius.lg",
        "spacing.1",
        "spacing.2",
        "spacing.3",
        "spacing.5",
        "font.size.xs",
        "font.size.sm",
        "font.weight.medium",
        "font.weight.semibold"
      ],
      "a11y": {
        "role": "button",
        "keyboard": [
          {
            "key": "Tab",
            "action": "Focus the dropzone."
          },
          {
            "key": "Enter",
            "action": "Open the native file picker."
          },
          {
            "key": "Space",
            "action": "Open the native file picker."
          }
        ],
        "notes": [
          "The dropzone is a labeled button (`role=\"button\"`) for screen readers.",
          "Drag-and-drop is a supplementary affordance; keyboard + native picker is the primary path.",
          "Each progress bar exposes ARIA progress state with min/max/value.",
          "Disabled state removes the dropzone from the tab order."
        ]
      },
      "composes_with": [],
      "related": [
        "attachment-tile"
      ],
      "when_to_use": [],
      "pitfalls": [],
      "prompt_examples": []
    },
    {
      "name": "Flex",
      "slug": "flex",
      "package": "@helixui/core",
      "import": "import { Flex } from '@helixui/core'",
      "description": "A flexbox container with direction, alignment, and gap as first-class props.",
      "category": "layout",
      "tags": [
        "primitive",
        "flexbox",
        "row",
        "column",
        "gap"
      ],
      "status": "stable",
      "since": "0.1.0",
      "layout": {
        "display": "flex",
        "width": "auto",
        "height": "auto",
        "intrinsicSize": "flex container; sized by flow + children",
        "stackable": true,
        "fullBleed": false
      },
      "anatomy": "[ child ][ child ][ child ]   ← horizontal\n  child\n  child\n  child                          ← vertical (direction=\"column\")\n",
      "visual": "A flex container with `direction`, `align`, `justify`, `gap`, and `wrap` exposed as props that map to design tokens.\n",
      "props": [
        {
          "name": "direction",
          "type": "'row' | 'row-reverse' | 'column' | 'column-reverse'",
          "default": "row",
          "description": "Flex direction."
        },
        {
          "name": "align",
          "type": "'start' | 'center' | 'end' | 'stretch' | 'baseline'",
          "default": "stretch",
          "description": "Cross-axis alignment."
        },
        {
          "name": "justify",
          "type": "'start' | 'center' | 'end' | 'between' | 'around' | 'evenly'",
          "default": "start",
          "description": "Main-axis alignment."
        },
        {
          "name": "gap",
          "type": "number | string",
          "default": "",
          "description": "Gap between children. Numeric → `space.N` token."
        },
        {
          "name": "wrap",
          "type": "boolean",
          "default": false,
          "description": "Allow wrapping."
        },
        {
          "name": "inline",
          "type": "boolean",
          "default": false,
          "description": "Use `inline-flex` instead of `flex`."
        }
      ],
      "slots": [],
      "tokens": [
        "space.1",
        "space.2",
        "space.3",
        "space.4",
        "space.5",
        "space.6",
        "space.8"
      ],
      "a11y": {
        "notes": [
          "Flex is presentational. Use Stack for vertically/horizontally arranged content lists."
        ]
      },
      "composes_with": [
        {
          "component": "Stack",
          "relation": "alternative",
          "note": "Stack is opinionated for vertical/horizontal stacking."
        },
        {
          "component": "Grid",
          "relation": "alternative",
          "note": "Use Grid for 2-D layout."
        },
        {
          "component": "Box",
          "relation": "sibling"
        }
      ],
      "related": [
        "Stack",
        "Grid",
        "Box"
      ],
      "when_to_use": [],
      "pitfalls": [],
      "prompt_examples": [
        {
          "intent": "horizontal row of items",
          "prompt": "flex row with gap",
          "snippet": "<Flex direction=\"row\" gap={3} align=\"center\">{children}</Flex>\n"
        }
      ]
    },
    {
      "name": "FloatingBar",
      "slug": "floating-bar",
      "package": "@helixui/core",
      "import": "import { FloatingBar } from '@helixui/core'",
      "description": "A pinned action bar that floats over content — typically used for bulk actions on selected items.",
      "category": "overlay",
      "tags": [
        "floating",
        "bulk-actions",
        "selection",
        "toolbar"
      ],
      "status": "stable",
      "since": "0.1.0",
      "layout": {
        "display": "fixed",
        "width": "content",
        "height": "content",
        "intrinsicSize": "centered horizontally, near bottom of viewport",
        "stackable": false,
        "fullBleed": false
      },
      "anatomy": "┌── floating bar ──┐\n│ 3 selected   ✕  Delete  Move ▾ │\n└─────────────────┘\n",
      "visual": "A pill-shaped surface with strong shadow (shadow.lg) that floats over the page content. Shows a leading status (e.g. \"3 selected\"), a divider, then trailing actions.\n",
      "props": [
        {
          "name": "placement",
          "type": "'bottom' | 'top'",
          "default": "bottom",
          "description": "Edge to anchor to."
        },
        {
          "name": "visible",
          "type": "boolean",
          "default": true,
          "description": "Show/hide with animation. Use to reveal on selection."
        }
      ],
      "slots": [
        "children — a single pill-shaped wrapper that contains the actions"
      ],
      "tokens": [
        "color.bg.surface.default",
        "color.border.default",
        "color.text.primary",
        "radius.full",
        "space.2",
        "space.3",
        "space.4",
        "font.family.sans",
        "font.size.sm",
        "shadow.lg"
      ],
      "a11y": {
        "role": "toolbar",
        "notes": [
          "Provide an `aria-label` on the bar describing the available actions (\"Bulk actions on N items\").",
          "The bar is `aria-hidden` when not `visible`, removing it from the tab order."
        ]
      },
      "composes_with": [
        {
          "component": "Table",
          "relation": "sibling",
          "note": "Common over a Table during multi-select."
        },
        {
          "component": "List",
          "relation": "sibling",
          "note": "Or over a List with selectable rows."
        },
        {
          "component": "Button",
          "relation": "sibling"
        },
        {
          "component": "IconButton",
          "relation": "sibling"
        }
      ],
      "related": [
        "Button",
        "IconButton"
      ],
      "when_to_use": [],
      "pitfalls": [],
      "prompt_examples": [
        {
          "intent": "bulk row actions",
          "prompt": "floating bar showing 3 selected with Delete and Move",
          "snippet": "<FloatingBar visible={count > 0} status={`${count} selected`}>\n  <Button onPress={remove}>Delete</Button>\n  <Button onPress={move}>Move</Button>\n</FloatingBar>\n"
        }
      ]
    },
    {
      "name": "Form",
      "slug": "form",
      "package": "@helixui/core",
      "import": "import { Form } from '@helixui/core'",
      "description": "A `<form>` wrapper from react-aria-components that surfaces validation errors per-field via the `validationErrors` prop.",
      "category": "form",
      "tags": [
        "form",
        "validation",
        "submit",
        "rac"
      ],
      "status": "stable",
      "since": "0.1.0",
      "layout": {
        "display": "block",
        "width": "fill",
        "height": "content",
        "intrinsicSize": "native form element; layout by children",
        "stackable": true,
        "fullBleed": false
      },
      "anatomy": "<Form>\n  Field…\n  Field…\n  [ Cancel ] [ Submit ]\n</Form>\n",
      "visual": "A `<form>` wrapper with no inherent visuals. Provides a `validationErrors` prop that surfaces server validation against fields by name.\n",
      "props": [
        {
          "name": "validationErrors",
          "type": "Record<string, string | string[]>",
          "default": "",
          "description": "Server-side validation errors keyed by field name. Forwarded to each FieldError."
        },
        {
          "name": "onSubmit",
          "type": "(e: FormEvent) => void",
          "default": "",
          "description": "Submit handler. Native form behavior unless `e.preventDefault()`."
        },
        {
          "name": "...rest",
          "type": "FormHTMLAttributes<HTMLFormElement>",
          "default": "",
          "description": "All native form attributes."
        }
      ],
      "slots": [],
      "tokens": [
        "space.5"
      ],
      "a11y": {
        "notes": [
          "Use `<Form>` instead of `<form>` to get react-aria's coordinated validation handling.",
          "Server errors via `validationErrors` are surfaced to the corresponding fields automatically."
        ]
      },
      "composes_with": [
        {
          "component": "Field",
          "relation": "child",
          "note": "Each control is wrapped in a Field."
        },
        {
          "component": "TextInput",
          "relation": "child",
          "note": "RAC inputs accept label/description directly."
        },
        {
          "component": "Button",
          "relation": "child",
          "note": "Submit button at the end."
        },
        {
          "component": "Textarea",
          "relation": "sibling"
        },
        {
          "component": "Checkbox",
          "relation": "sibling"
        },
        {
          "component": "RadioGroup",
          "relation": "sibling"
        }
      ],
      "related": [
        "TextInput",
        "Textarea",
        "Checkbox",
        "RadioGroup",
        "Field"
      ],
      "when_to_use": [],
      "pitfalls": [],
      "prompt_examples": [
        {
          "intent": "login form",
          "prompt": "email + password + submit",
          "snippet": "<Form onSubmit={handleSubmit}>\n  <TextInput name=\"email\" label=\"Email\" />\n  <TextInput name=\"password\" label=\"Password\" type=\"password\" />\n  <Button type=\"submit\">Sign in</Button>\n</Form>\n"
        }
      ]
    },
    {
      "name": "Grid",
      "slug": "grid",
      "package": "@helixui/core",
      "import": "import { Grid } from '@helixui/core'",
      "description": "A CSS grid container. Pass a number for equal columns, or any raw track string.",
      "category": "layout",
      "tags": [
        "primitive",
        "grid",
        "columns",
        "rows"
      ],
      "status": "stable",
      "since": "0.1.0",
      "layout": {
        "display": "grid",
        "width": "auto",
        "height": "auto",
        "intrinsicSize": "CSS grid container, tunable tracks",
        "stackable": true,
        "fullBleed": false
      },
      "anatomy": "[ . ][ . ][ . ]\n[ . ][ . ][ . ]   ← columns/rows tunable\n",
      "visual": "A CSS grid container. Pass a number for equal columns, or any raw `grid-template-columns` track string. Token-aware gaps.\n",
      "props": [
        {
          "name": "columns",
          "type": "number | string",
          "default": "",
          "description": "Equal columns when number; raw `grid-template-columns` when string."
        },
        {
          "name": "rows",
          "type": "number | string",
          "default": "",
          "description": "Same shape, applied to rows."
        },
        {
          "name": "gap",
          "type": "number | string",
          "default": "",
          "description": "Cell gap. Numeric → `space.N` token."
        },
        {
          "name": "rowGap",
          "type": "number | string",
          "default": "",
          "description": "Row gap override."
        },
        {
          "name": "columnGap",
          "type": "number | string",
          "default": "",
          "description": "Column gap override."
        },
        {
          "name": "inline",
          "type": "boolean",
          "default": false,
          "description": "Use `inline-grid`."
        }
      ],
      "slots": [],
      "tokens": [
        "space.2",
        "space.4",
        "space.6"
      ],
      "a11y": {
        "notes": [
          "Presentational. Use semantic elements as children."
        ]
      },
      "composes_with": [
        {
          "component": "Flex",
          "relation": "alternative",
          "note": "Use Flex for 1-D layout."
        },
        {
          "component": "Stack",
          "relation": "alternative",
          "note": "Use Stack for vertical/horizontal stacking with consistent gap."
        },
        {
          "component": "Box",
          "relation": "sibling"
        }
      ],
      "related": [
        "Flex",
        "Stack",
        "Box"
      ],
      "when_to_use": [],
      "pitfalls": [],
      "prompt_examples": [
        {
          "intent": "three-column responsive grid",
          "prompt": "3 column grid with 24px gap",
          "snippet": "<Grid columns={3} gap={6}>{cards}</Grid>\n"
        },
        {
          "intent": "auto-fit gallery",
          "prompt": "auto-fitting tiles min 240px",
          "snippet": "<Grid columns=\"repeat(auto-fit, minmax(240px, 1fr))\" gap={6}>{items}</Grid>\n"
        }
      ]
    },
    {
      "name": "IconButton",
      "slug": "icon-button",
      "package": "@helixui/core",
      "import": "import { IconButton } from '@helixui/core'",
      "description": "A square button containing only an icon. Requires an accessible label.",
      "category": "form",
      "tags": [
        "clickable",
        "icon-only",
        "compact",
        "action"
      ],
      "status": "stable",
      "since": "0.1.0",
      "layout": {
        "display": "inline-block",
        "width": "content",
        "height": "content",
        "intrinsicSize": "~28/36/44px square (sm/md/lg)",
        "stackable": true,
        "fullBleed": false
      },
      "anatomy": "[ ⊙ ]   ← square button, icon only\n",
      "visual": "A square button (radius.md) sized for an icon child. Same variants and tones as Button. Requires `aria-label`.\n",
      "props": [
        {
          "name": "aria-label",
          "type": "string",
          "default": "",
          "description": "Required. Names the action — screen readers have no visible text to read."
        },
        {
          "name": "variant",
          "type": "'solid' | 'soft' | 'ghost' | 'outline'",
          "default": "ghost",
          "description": "Visual style."
        },
        {
          "name": "tone",
          "type": "'brand' | 'neutral' | 'danger'",
          "default": "neutral",
          "description": "Color intent."
        },
        {
          "name": "size",
          "type": "'sm' | 'md' | 'lg'",
          "default": "md",
          "description": "Square size — 32 / 40 / 48 px."
        }
      ],
      "slots": [
        "children — the icon node"
      ],
      "tokens": [
        "color.bg.action.brand.default",
        "color.bg.action.brand.hover",
        "color.bg.action.brand.subtle",
        "color.bg.action.neutral.default",
        "color.bg.action.neutral.hover",
        "color.bg.action.danger.default",
        "color.bg.action.danger.hover",
        "color.bg.action.danger.subtle",
        "color.bg.surface.default",
        "color.text.primary",
        "color.text.on.brand",
        "color.text.on.danger",
        "color.text.action.brand",
        "color.text.action.danger",
        "color.border.default",
        "color.border.strong",
        "color.border.focus",
        "radius.md"
      ],
      "a11y": {
        "role": "button",
        "notes": [
          "`aria-label` is required. TypeScript enforces it.",
          "For destructive icon-only actions, include a Tooltip describing what the action does."
        ]
      },
      "composes_with": [
        {
          "component": "Tooltip",
          "relation": "wraps",
          "note": "Wrap with Tooltip to expose what the icon means."
        },
        {
          "component": "Button",
          "relation": "alternative",
          "note": "Use Button when there is a text label."
        },
        {
          "component": "ChatHeader",
          "relation": "child",
          "note": "Common in right-aligned actions."
        }
      ],
      "related": [
        "Button",
        "Tooltip"
      ],
      "when_to_use": [],
      "pitfalls": [],
      "prompt_examples": [
        {
          "intent": "menu trigger icon",
          "prompt": "three-dot icon button with tooltip",
          "snippet": "<TooltipTrigger><IconButton aria-label=\"More\"><MoreIcon /></IconButton><Tooltip>More</Tooltip></TooltipTrigger>\n"
        }
      ]
    },
    {
      "name": "InputGroup",
      "slug": "input-group",
      "package": "@helixui/core",
      "import": "import { InputGroup } from '@helixui/core'",
      "description": "A horizontal layout for multiple controls. With `attached`, children share a single rounded border.",
      "category": "form",
      "tags": [
        "composite",
        "attached",
        "input-row"
      ],
      "status": "stable",
      "since": "0.1.0",
      "layout": {
        "display": "inline-flex",
        "width": "fill",
        "height": "content",
        "intrinsicSize": "fills width, hugs content height",
        "stackable": false,
        "fullBleed": false
      },
      "anatomy": "[ prefix ][ input              ][ suffix ]\n └────── attached border (single radius) ───────┘\n",
      "visual": "A horizontal row of controls. With `attached`, children share a single rounded outer border and inner borders collapse, producing the classic \"URL prefix + input + button\" look.\n",
      "props": [
        {
          "name": "attached",
          "type": "boolean",
          "default": false,
          "description": "Joins children with shared border (segmented look)."
        },
        {
          "name": "...rest",
          "type": "HTMLAttributes<HTMLDivElement>",
          "default": "",
          "description": "Native div attributes."
        }
      ],
      "slots": [
        "children — controls (TextInput, Button, IconButton, Select, etc.)"
      ],
      "tokens": [
        "space.2",
        "radius.md"
      ],
      "a11y": {
        "role": "group",
        "notes": [
          "Container is `role=\\\"group\\\"`; provide a `aria-label` describing the group's purpose."
        ]
      },
      "composes_with": [
        {
          "component": "TextInput",
          "relation": "child",
          "note": "Most common middle child."
        },
        {
          "component": "Button",
          "relation": "child",
          "note": "Trailing action."
        },
        {
          "component": "Select",
          "relation": "child",
          "note": "Leading or trailing."
        }
      ],
      "related": [
        "TextInput"
      ],
      "when_to_use": [],
      "pitfalls": [],
      "prompt_examples": [
        {
          "intent": "URL field with copy button",
          "prompt": "attached input + button row",
          "snippet": "<InputGroup attached>\n  <TextInput value={url} readOnly />\n  <Button onPress={copy}>Copy</Button>\n</InputGroup>\n"
        }
      ]
    },
    {
      "name": "List",
      "slug": "list",
      "package": "@helixui/core",
      "import": "import { List } from '@helixui/core'",
      "description": "A denser data list — feed, inbox, settings rows. Each item has media / primary / secondary / trailing slots.",
      "category": "data",
      "tags": [
        "rows",
        "feed",
        "inbox",
        "settings"
      ],
      "status": "stable",
      "since": "0.2.0",
      "layout": {
        "display": "block",
        "width": "fill",
        "height": "content",
        "intrinsicSize": "fills width, rows hug content",
        "stackable": true,
        "fullBleed": false
      },
      "anatomy": "[ media ]  Primary text                    [ trailing ]\n           Secondary muted text\n──────────────────────────────────────────────────────────\n[ media ]  Primary…                              [ trailing ]\n           Secondary…\n",
      "visual": "A vertical list of rows, each with media (avatar/icon), primary + secondary text, and trailing content. Hairline dividers between rows. Hover surface (action.neutral.default at low alpha) on interactive rows.\n",
      "props": [
        {
          "name": "divided",
          "type": "boolean",
          "default": false,
          "description": "Render a 1px border between items."
        },
        {
          "name": "interactive",
          "type": "boolean",
          "default": false,
          "description": "Add hover/focus affordance — for clickable lists."
        }
      ],
      "slots": [
        "List.Item — media, primary, secondary, trailing slots; optional href to render as `<a>`"
      ],
      "tokens": [
        "color.bg.action.neutral.default",
        "color.text.primary",
        "color.text.secondary",
        "color.border.default",
        "color.border.focus",
        "radius.md",
        "space.2",
        "space.3",
        "space.4",
        "font.family.sans",
        "font.size.sm",
        "font.weight.medium"
      ],
      "a11y": {
        "notes": [
          "Renders `<ul><li>`. Items become `<a>` when `href` is provided, otherwise plain rows.",
          "For selectable lists with keyboard nav, prefer `Table` with selection or react-aria-components `GridList`."
        ]
      },
      "composes_with": [
        {
          "component": "Avatar",
          "relation": "child",
          "note": "Common media slot."
        },
        {
          "component": "Badge",
          "relation": "child",
          "note": "Common trailing slot."
        },
        {
          "component": "Card",
          "relation": "parent",
          "note": "Often wrapped in a Card."
        },
        {
          "component": "EmptyState",
          "relation": "alternative",
          "note": "When list is empty, render EmptyState."
        },
        {
          "component": "Table",
          "relation": "sibling"
        }
      ],
      "related": [
        "Table"
      ],
      "when_to_use": [],
      "pitfalls": [],
      "prompt_examples": [
        {
          "intent": "inbox list",
          "prompt": "list of conversations with avatar, name, last message, unread count",
          "snippet": "<List>\n  {threads.map(t => (\n    <List.Item key={t.id}\n      media={<Avatar fallback={t.initials} />}\n      primary={t.name}\n      secondary={t.preview}\n      trailing={<Badge>{t.unread}</Badge>}\n    />\n  ))}\n</List>\n"
        }
      ]
    },
    {
      "name": "Menu",
      "slug": "menu",
      "package": "@helixui/core",
      "import": "import { Menu, MenuItem, MenuTrigger, MenuSeparator, SubmenuTrigger } from '@helixui/core'",
      "description": "A floating list of commands attached to a trigger.",
      "category": "overlay",
      "tags": [
        "floating",
        "menu",
        "dropdown",
        "actions"
      ],
      "status": "stable",
      "since": "0.1.0",
      "layout": {
        "display": "portal",
        "width": "content",
        "height": "content",
        "intrinsicSize": "anchored to trigger, max-h with scroll",
        "stackable": false,
        "fullBleed": false
      },
      "anatomy": "[ trigger ▾ ]\n   ┌────────────────┐\n   │ • Edit         │\n   │ • Duplicate    │\n   │ ─────────────  │\n   │ • Delete  ⌘⌫   │\n   └────────────────┘\n",
      "visual": "A floating panel anchored to its trigger. Items are rows with optional leading icon, label, and trailing kbd shortcut. Separators are 1px hairlines. Submenu items show a trailing chevron.\n",
      "props": [
        {
          "name": "placement",
          "type": "'top' | 'bottom' | 'start' | 'end'",
          "default": "bottom",
          "description": "Anchor placement."
        },
        {
          "name": "selectionMode",
          "type": "'none' | 'single' | 'multiple'",
          "default": "none",
          "description": "Selection model. `none` for command menus."
        },
        {
          "name": "...rest",
          "type": "MenuProps from react-aria-components",
          "default": "",
          "description": "All forwarded."
        }
      ],
      "slots": [
        "MenuTrigger children — the trigger button + Menu",
        "Menu children — MenuItem, MenuSeparator, SubmenuTrigger"
      ],
      "tokens": [
        "color.bg.surface.default",
        "color.bg.action.neutral.default",
        "color.bg.action.neutral.hover",
        "color.bg.action.danger.subtle",
        "color.border.default",
        "color.text.primary",
        "color.text.muted",
        "color.text.action.danger",
        "radius.md",
        "space.1",
        "space.2",
        "space.3",
        "space.4",
        "font.family.sans",
        "font.size.sm",
        "font.size.xs",
        "shadow.md"
      ],
      "a11y": {
        "role": "menu",
        "keyboard": [
          {
            "key": "ArrowDown",
            "action": "Move down."
          },
          {
            "key": "ArrowUp",
            "action": "Move up."
          },
          {
            "key": "ArrowRight",
            "action": "Open submenu."
          },
          {
            "key": "ArrowLeft",
            "action": "Close submenu."
          },
          {
            "key": "Enter",
            "action": "Activate item."
          },
          {
            "key": "Escape",
            "action": "Close menu."
          }
        ],
        "notes": [
          "For destructive items, set `destructive` — color shifts to danger and the focused background lightens to danger.subtle."
        ]
      },
      "composes_with": [
        {
          "component": "Button",
          "relation": "trigger",
          "note": "Common opener (MenuTrigger)."
        },
        {
          "component": "IconButton",
          "relation": "trigger",
          "note": "Common opener for icon-only triggers."
        },
        {
          "component": "CommandPalette",
          "relation": "alternative",
          "note": "CommandPalette is global ⌘K; Menu is anchored."
        },
        {
          "component": "Popover",
          "relation": "sibling"
        },
        {
          "component": "Dialog",
          "relation": "sibling"
        }
      ],
      "related": [
        "Popover",
        "Dialog"
      ],
      "when_to_use": [],
      "pitfalls": [],
      "prompt_examples": [
        {
          "intent": "context menu",
          "prompt": "three-dot menu with Edit, Duplicate, Delete",
          "snippet": "<MenuTrigger>\n  <IconButton aria-label=\"More\"><MoreIcon /></IconButton>\n  <Menu>\n    <MenuItem onAction={edit}>Edit</MenuItem>\n    <MenuItem onAction={dup}>Duplicate</MenuItem>\n    <MenuSeparator />\n    <MenuItem onAction={remove}>Delete</MenuItem>\n  </Menu>\n</MenuTrigger>\n"
        }
      ]
    },
    {
      "name": "MultiSelect",
      "slug": "multi-select",
      "package": "@helixui/core",
      "import": "import { MultiSelect, MultiSelectOption } from '@helixui/core'",
      "description": "A combobox that accepts multiple values, displayed as removable tags inline.",
      "category": "form",
      "tags": [
        "combobox",
        "tags",
        "chips",
        "multi"
      ],
      "status": "beta",
      "since": "0.1.0",
      "layout": {
        "display": "block",
        "width": "fill",
        "height": "content",
        "intrinsicSize": "fills width, hugs height + chip rows",
        "stackable": false,
        "fullBleed": false
      },
      "anatomy": "[ chip × ][ chip × ][ chip × ]  type… ▾\n                                  └─ popover listbox ─┐\n                                     • option 1       │\n                                     • option 2       │\n                                     ▼ load more\n",
      "visual": "A combobox-style input with selected values rendered as inline removable tags. Typing filters the popover listbox below; selecting an option adds another chip.\n",
      "props": [
        {
          "name": "label",
          "type": "ReactNode",
          "default": "",
          "description": "Visible label."
        },
        {
          "name": "description",
          "type": "ReactNode",
          "default": "",
          "description": "Helper text."
        },
        {
          "name": "errorMessage",
          "type": "string | (v: ValidationResult) => string",
          "default": "",
          "description": "Error text."
        },
        {
          "name": "placeholder",
          "type": "string",
          "default": "Add…",
          "description": "Combobox input placeholder."
        },
        {
          "name": "selectedKeys",
          "type": "Selection",
          "default": "",
          "description": "Controlled selected ids."
        },
        {
          "name": "defaultSelectedKeys",
          "type": "Iterable<string | number>",
          "default": "",
          "description": "Uncontrolled initial selection."
        },
        {
          "name": "onSelectionChange",
          "type": "(keys: Selection) => void",
          "default": "",
          "description": "Selection change handler."
        }
      ],
      "slots": [
        "children — MultiSelectOption components"
      ],
      "tokens": [
        "color.bg.surface.default",
        "color.bg.action.neutral.default",
        "color.bg.action.brand.subtle",
        "color.bg.action.brand.default",
        "color.text.primary",
        "color.text.secondary",
        "color.text.muted",
        "color.text.action.brand",
        "color.text.on.brand",
        "color.text.action.danger",
        "color.border.default",
        "color.border.focus",
        "radius.md",
        "radius.sm",
        "radius.full",
        "space.1",
        "space.2",
        "space.3",
        "font.family.sans",
        "font.size.sm",
        "font.size.xs",
        "font.weight.medium",
        "shadow.md"
      ],
      "a11y": {
        "notes": [
          "Composes react-aria-components ComboBox + TagGroup. ComboBox handles input typing & list selection; TagGroup handles selected-tag removal with Backspace and Delete.",
          "Provide `aria-label` on the container if no `label` is shown."
        ]
      },
      "composes_with": [
        {
          "component": "Select",
          "relation": "alternative",
          "note": "Use Select for single-value."
        }
      ],
      "related": [
        "Select"
      ],
      "when_to_use": [],
      "pitfalls": [],
      "prompt_examples": [
        {
          "intent": "pick multiple tags",
          "prompt": "multi-select for tags",
          "snippet": "<MultiSelect value={tags} onChange={setTags}>\n  <MultiSelectOption value=\"design\">Design</MultiSelectOption>\n  <MultiSelectOption value=\"ai\">AI</MultiSelectOption>\n</MultiSelect>\n"
        }
      ]
    },
    {
      "name": "NavigationMenu",
      "slug": "navigation-menu",
      "package": "@helixui/core",
      "import": "import { NavigationMenu } from '@helixui/core'",
      "description": "A vertical navigation list with collapsible sections. Use for app sidebars and side navs.",
      "category": "navigation",
      "tags": [
        "nav",
        "collapsible",
        "side",
        "sections"
      ],
      "status": "stable",
      "since": "0.1.0",
      "layout": {
        "display": "block",
        "width": "fill",
        "height": "content",
        "intrinsicSize": "vertical list with collapsible sections",
        "stackable": true,
        "fullBleed": false
      },
      "anatomy": "▾ Section\n   • Item\n   • Item\n▸ Section (collapsed)\n▾ Section\n   • Item\n",
      "visual": "A vertical list with sections that can collapse. Section headers show a chevron and bold label; items are pill-shaped with active state.\n",
      "props": [
        {
          "name": "label",
          "type": "string",
          "default": "Main",
          "description": "Accessible name on the wrapping `<nav>`."
        },
        {
          "name": "...rest",
          "type": "HTMLAttributes<HTMLElement>",
          "default": "",
          "description": "Native nav attributes."
        }
      ],
      "slots": [
        "NavigationMenu.Group — DisclosureGroup; allows multiple sections to be open at once",
        "NavigationMenu.Section — Disclosure; pass `title` and children",
        "NavigationMenu.Item — `<a>` with `active` flag → renders `aria-current=\"page\"`"
      ],
      "tokens": [
        "color.bg.action.neutral.default",
        "color.bg.action.brand.subtle",
        "color.text.primary",
        "color.text.secondary",
        "color.text.action.brand",
        "color.border.focus",
        "radius.md",
        "space.1",
        "space.2",
        "space.3",
        "font.family.sans",
        "font.size.sm",
        "font.weight.medium"
      ],
      "a11y": {
        "notes": [
          "Sections use react-aria's Disclosure — keyboard, ARIA expanded/controls, focus all handled.",
          "Mark the active link with `active` prop; helixui sets `aria-current=\"page\"`."
        ]
      },
      "composes_with": [
        {
          "component": "Sidebar",
          "relation": "alternative",
          "note": "Sidebar is the structured rail with header/footer; NavigationMenu is the bare collapsible list."
        },
        {
          "component": "Breadcrumb",
          "relation": "sibling"
        },
        {
          "component": "Tabs",
          "relation": "sibling"
        }
      ],
      "related": [
        "Breadcrumb",
        "Tabs"
      ],
      "when_to_use": [],
      "pitfalls": [],
      "prompt_examples": [
        {
          "intent": "docs side nav",
          "prompt": "collapsible side nav with two sections",
          "snippet": "<NavigationMenu>\n  <NavigationMenu.Section title=\"Getting started\">\n    <NavigationMenu.Item href=\"/install\">Install</NavigationMenu.Item>\n  </NavigationMenu.Section>\n  <NavigationMenu.Section title=\"Components\">\n    <NavigationMenu.Item href=\"/components/button\">Button</NavigationMenu.Item>\n  </NavigationMenu.Section>\n</NavigationMenu>\n"
        }
      ]
    },
    {
      "name": "NumberField",
      "slug": "number-field",
      "package": "@helixui/core",
      "import": "import { NumberField } from '@helixui/core'",
      "description": "A numeric input with locale-aware parsing, optional +/- steppers, min/max/step, and validation.",
      "category": "form",
      "tags": [
        "number",
        "input",
        "stepper",
        "numeric"
      ],
      "status": "stable",
      "since": "0.2.0",
      "layout": {
        "display": "block",
        "width": "fill",
        "height": "content",
        "intrinsicSize": "fills width, hugs height",
        "stackable": true,
        "fullBleed": false
      },
      "anatomy": "Label\n[          1,234 ][−][+]\nDescription / error\n",
      "visual": "A text input formatted as a number with optional +/- steppers on the right. Locale-aware parsing (commas vs dots) and validation against `min`/`max`/`step`.\n",
      "props": [
        {
          "name": "label",
          "type": "ReactNode",
          "default": "",
          "description": "Visible label."
        },
        {
          "name": "description",
          "type": "ReactNode",
          "default": "",
          "description": "Helper text."
        },
        {
          "name": "errorMessage",
          "type": "string | (v: ValidationResult) => string",
          "default": "",
          "description": "Error text."
        },
        {
          "name": "size",
          "type": "'sm' | 'md' | 'lg'",
          "default": "md",
          "description": "Control height."
        },
        {
          "name": "steppers",
          "type": "boolean",
          "default": true,
          "description": "Show +/- buttons inside the group."
        },
        {
          "name": "minValue",
          "type": "number",
          "default": "",
          "description": "Minimum allowed value."
        },
        {
          "name": "maxValue",
          "type": "number",
          "default": "",
          "description": "Maximum allowed value."
        },
        {
          "name": "step",
          "type": "number",
          "default": 1,
          "description": "Step amount per +/- click."
        },
        {
          "name": "formatOptions",
          "type": "Intl.NumberFormatOptions",
          "default": "",
          "description": "Locale formatting (currency, percent, units)."
        }
      ],
      "slots": [],
      "tokens": [
        "color.bg.surface.default",
        "color.bg.surface.muted",
        "color.bg.action.neutral.default",
        "color.border.default",
        "color.border.focus",
        "color.border.danger",
        "color.text.primary",
        "color.text.secondary",
        "color.text.action.danger",
        "radius.md",
        "space.2",
        "space.3",
        "font.family.sans",
        "font.size.sm",
        "font.size.md",
        "font.size.lg",
        "font.weight.medium"
      ],
      "a11y": {
        "notes": [
          "Built on react-aria-components NumberField — locale-aware parsing/formatting and ARIA spinbutton semantics.",
          "Pass `formatOptions` (Intl.NumberFormatOptions) for currency, percent, or unit-formatted inputs."
        ]
      },
      "composes_with": [
        {
          "component": "Field",
          "relation": "wraps",
          "note": "NumberField has built-in label/description/error like other RAC inputs."
        },
        {
          "component": "Form",
          "relation": "parent",
          "note": "Submitted as part of a Form."
        },
        {
          "component": "TextInput",
          "relation": "sibling"
        },
        {
          "component": "Slider",
          "relation": "sibling"
        }
      ],
      "related": [
        "TextInput",
        "Slider"
      ],
      "when_to_use": [],
      "pitfalls": [],
      "prompt_examples": [
        {
          "intent": "quantity input",
          "prompt": "number input with min 0 max 99",
          "snippet": "<NumberField label=\"Qty\" minValue={0} maxValue={99} value={qty} onChange={setQty} />\n"
        }
      ]
    },
    {
      "name": "NumericKeypad",
      "slug": "numeric-keypad",
      "package": "@helixui/core",
      "import": "import { NumericKeypad } from '@helixui/core'",
      "description": "An iOS/Android-style 3×4 numeric keypad with optional letter sub-labels (ABC, DEF, …). Use for PIN entry, banking apps, or custom input flows where the system keyboard is unwanted.",
      "category": "form",
      "tags": [
        "mobile",
        "keypad",
        "pin",
        "numeric"
      ],
      "status": "stable",
      "since": "0.5.0",
      "layout": {
        "display": "grid",
        "width": "fill",
        "height": "content",
        "intrinsicSize": "3×4 grid; tile size scales with width",
        "stackable": false,
        "fullBleed": false
      },
      "anatomy": "1   2   3\n4   5   6\n7   8   9\n        0   ⌫\n",
      "visual": "A 3×4 grid of large round buttons (44px+) with optional letter sub-labels (ABC, DEF, …) for phone-style entry. Backspace key in the bottom-right.\n",
      "props": [
        {
          "name": "onDigit",
          "type": "(digit: string) => void",
          "default": "",
          "description": "Called for each digit press 0–9."
        },
        {
          "name": "onBackspace",
          "type": "() => void",
          "default": "",
          "description": "Called when backspace is tapped (when no `submitLabel`)."
        },
        {
          "name": "onSubmit",
          "type": "() => void",
          "default": "",
          "description": "Called when the submit key is tapped (when `submitLabel` is set)."
        },
        {
          "name": "bottomLeft",
          "type": "ReactNode",
          "default": "",
          "description": "Custom node for the bottom-left cell (default empty)."
        },
        {
          "name": "bottomRight",
          "type": "ReactNode",
          "default": "",
          "description": "Custom node for the bottom-right cell (default backspace)."
        },
        {
          "name": "submitLabel",
          "type": "ReactNode",
          "default": "",
          "description": "When set, renders a brand-colored submit button at bottom-right and triggers `onSubmit` instead of backspace."
        },
        {
          "name": "size",
          "type": "'md' | 'lg'",
          "default": "md",
          "description": "Key height — 56 / 72 px."
        }
      ],
      "slots": [],
      "tokens": [
        "color.bg.action.neutral.default",
        "color.bg.action.neutral.hover",
        "color.bg.action.neutral.active",
        "color.bg.action.brand.default",
        "color.bg.action.brand.hover",
        "color.text.primary",
        "color.text.on.brand",
        "color.text.muted",
        "color.border.focus",
        "radius.full",
        "space.2",
        "space.3",
        "font.family.sans",
        "font.size.2xl",
        "font.weight.medium",
        "font.weight.semibold"
      ],
      "a11y": {
        "notes": [
          "Each key is a `<button>` with an `aria-label` (\"Digit 1\"). The wrapper is `role=\"group\"`.",
          "For currency inputs, set `bottomLeft` to a decimal `.` button."
        ]
      },
      "composes_with": [
        {
          "component": "PinInput",
          "relation": "sibling",
          "note": "Often paired with PinInput for mobile PIN entry."
        }
      ],
      "related": [
        "PinInput"
      ],
      "when_to_use": [],
      "pitfalls": [],
      "prompt_examples": [
        {
          "intent": "mobile PIN entry",
          "prompt": "on-screen numeric keypad",
          "snippet": "<NumericKeypad onPress={handleKey} />\n"
        }
      ]
    },
    {
      "name": "PageHeader",
      "slug": "page-header",
      "package": "@helixui/core",
      "import": "import { PageHeader } from '@helixui/core'",
      "description": "The top of a page — title, description, breadcrumb, and a right-aligned actions slot.",
      "category": "shell",
      "tags": [
        "title",
        "breadcrumb",
        "actions",
        "page-top"
      ],
      "status": "stable",
      "since": "0.2.0",
      "layout": {
        "display": "block",
        "width": "fill",
        "height": "content",
        "intrinsicSize": "fills width, hugs content",
        "stackable": false,
        "fullBleed": false
      },
      "anatomy": "Breadcrumb › path\nTitle                                    [ Action ] [ ⋮ ]\nDescription\n",
      "visual": "A header block at the top of a page: optional breadcrumb above, large heading + description on the left, right-aligned actions.\n",
      "props": [
        {
          "name": "breadcrumb",
          "type": "ReactNode",
          "default": "",
          "description": "Optional row above the title — typically `<Breadcrumbs>`."
        },
        {
          "name": "title",
          "type": "ReactNode",
          "default": "",
          "description": "Page heading. Rendered as `<h1>`."
        },
        {
          "name": "description",
          "type": "ReactNode",
          "default": "",
          "description": "Lead paragraph below the title."
        },
        {
          "name": "actions",
          "type": "ReactNode",
          "default": "",
          "description": "Right-aligned action group — primary buttons, IconButtons."
        },
        {
          "name": "bordered",
          "type": "boolean",
          "default": false,
          "description": "Adds a bottom border + spacing to separate from page content."
        }
      ],
      "slots": [],
      "tokens": [
        "color.text.primary",
        "color.text.secondary",
        "color.border.default",
        "font.family.sans",
        "font.size.md",
        "font.size.sm",
        "font.size.2xl",
        "font.weight.semibold",
        "font.lineHeight.tight",
        "space.1",
        "space.2",
        "space.3",
        "space.4",
        "space.6"
      ],
      "a11y": {
        "notes": [
          "Renders `<h1>` so there's exactly one per page. Use a different heading inside `actions` if needed."
        ]
      },
      "composes_with": [
        {
          "component": "AppShell",
          "relation": "child",
          "note": "Common first child of the AppShell main area."
        },
        {
          "component": "Breadcrumb",
          "relation": "slot",
          "note": "Goes in the breadcrumb slot."
        },
        {
          "component": "Button",
          "relation": "child",
          "note": "Right-aligned actions."
        }
      ],
      "related": [
        "Breadcrumb",
        "AppShell"
      ],
      "when_to_use": [],
      "pitfalls": [],
      "prompt_examples": [
        {
          "intent": "page title with action",
          "prompt": "page header for Users with a New user button",
          "snippet": "<PageHeader\n  title=\"Users\"\n  description=\"Manage who can access this workspace.\"\n  actions={<Button>New user</Button>}\n/>\n"
        }
      ]
    },
    {
      "name": "Pagination",
      "slug": "pagination",
      "package": "@helixui/core",
      "import": "import { Pagination } from '@helixui/core'",
      "description": "Page-by-page navigation with previous/next buttons, page numbers, and ellipses.",
      "category": "navigation",
      "tags": [
        "pages",
        "paging",
        "numbers"
      ],
      "status": "stable",
      "since": "0.1.0",
      "layout": {
        "display": "inline-flex",
        "width": "content",
        "height": "content",
        "intrinsicSize": "centered, hugs page count",
        "stackable": false,
        "fullBleed": false
      },
      "anatomy": "[ ‹ ]  1  2  …  7  8 [9] 10 …  20  [ › ]\n",
      "visual": "A horizontal row of small page-number buttons with previous/next arrows on the ends and ellipses for elided ranges. Current page filled with brand tone.\n",
      "props": [
        {
          "name": "page",
          "type": "number",
          "default": "",
          "description": "Current 1-indexed page. Required."
        },
        {
          "name": "total",
          "type": "number",
          "default": "",
          "description": "Total number of pages. Required."
        },
        {
          "name": "onChange",
          "type": "(page: number) => void",
          "default": "",
          "description": "Page change handler."
        },
        {
          "name": "siblings",
          "type": "number",
          "default": 1,
          "description": "Pages shown on each side of the current page."
        },
        {
          "name": "boundaries",
          "type": "number",
          "default": 1,
          "description": "Pages shown at the start and end."
        },
        {
          "name": "label",
          "type": "string",
          "default": "Pagination",
          "description": "Accessible label on the `<nav>`."
        }
      ],
      "slots": [],
      "tokens": [
        "color.bg.action.neutral.default",
        "color.bg.action.brand.default",
        "color.text.primary",
        "color.text.secondary",
        "color.text.muted",
        "color.text.on.brand",
        "color.border.focus",
        "radius.md",
        "space.2",
        "font.family.sans",
        "font.size.sm",
        "font.weight.semibold"
      ],
      "a11y": {
        "notes": [
          "Wrapped in `<nav aria-label>`, current page marked with `aria-current=\"page\"`.",
          "Previous/Next buttons have explicit `aria-label`."
        ]
      },
      "composes_with": [
        {
          "component": "Table",
          "relation": "sibling",
          "note": "Common below a Table."
        },
        {
          "component": "List",
          "relation": "sibling",
          "note": "Or below a List."
        }
      ],
      "related": [],
      "when_to_use": [],
      "pitfalls": [],
      "prompt_examples": [
        {
          "intent": "paginate a table",
          "prompt": "pagination for 20 pages, current page 9",
          "snippet": "<Pagination total={20} page={page} onPageChange={setPage} />\n"
        }
      ]
    },
    {
      "name": "PinInput",
      "slug": "pin-input",
      "package": "@helixui/core",
      "import": "import { PinInput } from '@helixui/core'",
      "description": "A row of single-character cells for PIN / OTP entry. Auto-advances on type, supports paste-to-fill, backspace-to-previous, arrow navigation, and SMS one-time-code autofill.",
      "category": "form",
      "tags": [
        "otp",
        "pin",
        "verification",
        "sms"
      ],
      "status": "stable",
      "since": "0.5.0",
      "layout": {
        "display": "inline-flex",
        "width": "content",
        "height": "content",
        "intrinsicSize": "~44-56px tall, hugs N cells",
        "stackable": false,
        "fullBleed": false
      },
      "anatomy": "[ _ ][ _ ][ _ ][ _ ][ _ ][ _ ]   ← 6-digit code\n",
      "visual": "A row of single-character cells with auto-advance, paste-to-fill, backspace-to-previous, and SMS one-time-code autofill on iOS/Android.\n",
      "props": [
        {
          "name": "length",
          "type": "number",
          "default": 6,
          "description": "Number of cells."
        },
        {
          "name": "value",
          "type": "string",
          "default": "",
          "description": "Controlled value."
        },
        {
          "name": "defaultValue",
          "type": "string",
          "default": "",
          "description": "Uncontrolled initial."
        },
        {
          "name": "onChange",
          "type": "(value: string) => void",
          "default": "",
          "description": "Change handler."
        },
        {
          "name": "onComplete",
          "type": "(value: string) => void",
          "default": "",
          "description": "Called once when the last cell is filled."
        },
        {
          "name": "pattern",
          "type": "'digits' | 'alphanumeric'",
          "default": "digits",
          "description": "Allowed character set."
        },
        {
          "name": "mask",
          "type": "boolean",
          "default": false,
          "description": "Mask the value (for PINs)."
        },
        {
          "name": "isInvalid",
          "type": "boolean",
          "default": false,
          "description": "Invalid styling."
        },
        {
          "name": "isDisabled",
          "type": "boolean",
          "default": false,
          "description": "Disable all cells."
        },
        {
          "name": "label",
          "type": "ReactNode",
          "default": "",
          "description": "Label above the cells."
        },
        {
          "name": "description",
          "type": "ReactNode",
          "default": "",
          "description": "Helper text."
        },
        {
          "name": "errorMessage",
          "type": "ReactNode",
          "default": "",
          "description": "Error text. Implies `isInvalid`."
        },
        {
          "name": "size",
          "type": "'sm' | 'md' | 'lg'",
          "default": "md",
          "description": "Cell size."
        },
        {
          "name": "autoFocus",
          "type": "boolean",
          "default": false,
          "description": "Focus the first cell on mount."
        }
      ],
      "slots": [],
      "tokens": [
        "color.bg.surface.default",
        "color.bg.surface.muted",
        "color.bg.action.brand.default",
        "color.border.default",
        "color.border.focus",
        "color.border.danger",
        "color.text.primary",
        "color.text.secondary",
        "color.text.action.danger",
        "radius.md",
        "space.2",
        "font.family.sans",
        "font.size.sm",
        "font.size.md",
        "font.size.xl",
        "font.size.2xl",
        "font.weight.medium",
        "font.weight.semibold"
      ],
      "a11y": {
        "notes": [
          "First cell has `autocomplete=\"one-time-code\"` so iOS / Android can offer SMS code autofill.",
          "`inputMode=\"numeric\"` on digit-only mode brings up the numeric keypad on mobile.",
          "Error message has `role=\"alert\"`."
        ]
      },
      "composes_with": [
        {
          "component": "NumericKeypad",
          "relation": "sibling",
          "note": "Pair on mobile when system keyboard is undesired."
        },
        {
          "component": "Field",
          "relation": "wraps",
          "note": "Wrap with Field for label/error."
        },
        {
          "component": "TextInput",
          "relation": "sibling"
        },
        {
          "component": "Stepper",
          "relation": "sibling"
        }
      ],
      "related": [
        "TextInput",
        "NumericKeypad",
        "Stepper"
      ],
      "when_to_use": [],
      "pitfalls": [],
      "prompt_examples": [
        {
          "intent": "verify SMS code",
          "prompt": "6-digit OTP input",
          "snippet": "<PinInput length={6} value={code} onChange={setCode} />\n"
        }
      ]
    },
    {
      "name": "Popover",
      "slug": "popover",
      "package": "@helixui/core",
      "import": "import { Popover, PopoverTrigger, PopoverContent } from '@helixui/core'",
      "description": "A floating panel anchored to a trigger. Use for ephemeral content that doesn't justify a Dialog.",
      "category": "overlay",
      "tags": [
        "floating",
        "anchored",
        "transient"
      ],
      "status": "stable",
      "since": "0.1.0",
      "layout": {
        "display": "portal",
        "width": "content",
        "height": "content",
        "intrinsicSize": "anchored to trigger; placement auto",
        "stackable": false,
        "fullBleed": false
      },
      "anatomy": "[ trigger ]\n   ╭───────────╮\n   │  content  │  ← anchored\n   ╰───▽───────╯\n",
      "visual": "A floating panel with shadow.lg and arrow caret, anchored to a trigger. Closes on click-outside, Escape, or programmatically.\n",
      "props": [
        {
          "name": "placement",
          "type": "'top' | 'bottom' | 'start' | 'end' | …",
          "default": "bottom",
          "description": "Anchor placement. See react-aria docs for full enum."
        },
        {
          "name": "offset",
          "type": "number",
          "default": 8,
          "description": "Distance from trigger in pixels."
        },
        {
          "name": "isOpen",
          "type": "boolean",
          "default": "",
          "description": "Controlled open state."
        },
        {
          "name": "defaultOpen",
          "type": "boolean",
          "default": false,
          "description": "Uncontrolled initial open."
        },
        {
          "name": "onOpenChange",
          "type": "(open: boolean) => void",
          "default": "",
          "description": "Open change handler."
        }
      ],
      "slots": [
        "PopoverTrigger child — the anchor element",
        "PopoverContent child — the floating content (renders in a portal)"
      ],
      "tokens": [
        "color.bg.surface.default",
        "color.border.default",
        "color.text.primary",
        "radius.md",
        "space.4",
        "font.family.sans",
        "font.size.sm",
        "shadow.md"
      ],
      "a11y": {
        "notes": [
          "Composed of `<DialogTrigger>` + `<Popover>` + `<Dialog>` from react-aria-components — focus trapping, restoration, dismiss-on-outside, escape, all built in.",
          "Animation respects `prefers-reduced-motion`."
        ]
      },
      "composes_with": [
        {
          "component": "Button",
          "relation": "trigger",
          "note": "Common opener."
        },
        {
          "component": "IconButton",
          "relation": "trigger",
          "note": "Common opener for icon-only."
        },
        {
          "component": "Dialog",
          "relation": "alternative",
          "note": "Use Dialog for modal/blocking interactions."
        },
        {
          "component": "Tooltip",
          "relation": "alternative",
          "note": "Tooltip for short labels; Popover for richer content."
        },
        {
          "component": "Menu",
          "relation": "sibling"
        }
      ],
      "related": [
        "Dialog",
        "Tooltip",
        "Menu"
      ],
      "when_to_use": [],
      "pitfalls": [],
      "prompt_examples": [
        {
          "intent": "rich tooltip with actions",
          "prompt": "popover anchored to a Help button",
          "snippet": "<PopoverTrigger>\n  <Button variant=\"ghost\">Help</Button>\n  <Popover><PopoverContent>Need help? <a href=\"/docs\">Read the docs.</a></PopoverContent></Popover>\n</PopoverTrigger>\n"
        }
      ]
    },
    {
      "name": "PresenceDot",
      "slug": "presence-dot",
      "package": "@helixui/core",
      "import": "import { PresenceDot } from '@helixui/core'",
      "description": "A small status dot — online / away / busy / offline. Use standalone or attached to an Avatar.",
      "category": "feedback",
      "tags": [
        "status",
        "online",
        "dot",
        "presence"
      ],
      "status": "stable",
      "since": "0.3.0",
      "layout": {
        "display": "inline-block",
        "width": "content",
        "height": "content",
        "intrinsicSize": "~8-10px circle",
        "stackable": true,
        "fullBleed": false
      },
      "anatomy": "●  ← solid color dot\n",
      "visual": "A small solid circle in a status color: success (online), warning (away), danger (busy), neutral (offline). Often anchored to the bottom-right of an Avatar.\n",
      "props": [
        {
          "name": "status",
          "type": "'online' | 'away' | 'busy' | 'offline'",
          "default": "online",
          "description": "Status; drives the color."
        },
        {
          "name": "size",
          "type": "'sm' | 'md' | 'lg'",
          "default": "md",
          "description": "Dot size."
        },
        {
          "name": "attached",
          "type": "boolean",
          "default": false,
          "description": "When true, position absolutely in the bottom-right of the parent (parent must be `position: relative`)."
        },
        {
          "name": "label",
          "type": "string",
          "default": "",
          "description": "Override the default `aria-label` ('Online', 'Away', etc.)."
        }
      ],
      "slots": [],
      "tokens": [
        "color.bg.surface.default",
        "color.bg.action.success.default",
        "color.bg.action.warning.default",
        "color.bg.action.danger.default",
        "color.text.muted"
      ],
      "a11y": {
        "role": "status",
        "notes": [
          "The dot has `role=\"status\"` and an `aria-label` for screen readers.",
          "The white border isolates the dot from the avatar; uses `color.bg.surface.default`, so it adapts to dark mode."
        ]
      },
      "composes_with": [
        {
          "component": "Avatar",
          "relation": "sibling",
          "note": "Anchored to an Avatar."
        },
        {
          "component": "AvatarGroup",
          "relation": "sibling"
        }
      ],
      "related": [
        "Avatar",
        "AvatarGroup"
      ],
      "when_to_use": [],
      "pitfalls": [],
      "prompt_examples": [
        {
          "intent": "show online status",
          "prompt": "green presence dot on an avatar",
          "snippet": "<Box position=\"relative\">\n  <Avatar fallback=\"ST\" />\n  <PresenceDot status=\"online\" />\n</Box>\n"
        }
      ]
    },
    {
      "name": "PriceTag",
      "slug": "price-tag",
      "package": "@helixui/core",
      "import": "import { PriceTag } from '@helixui/core'",
      "description": "A formatted currency price label with optional strike-through original price and sale-percentage chip.",
      "category": null,
      "tags": [],
      "status": "stable",
      "since": "0.7.0",
      "layout": null,
      "anatomy": null,
      "visual": "Inline row of: current price (semibold, primary text) → strike-through original (muted) → small `-N%` chip (danger soft).\n",
      "props": [
        {
          "name": "value",
          "type": "number",
          "default": null,
          "description": "Current price (the number actually being charged)."
        },
        {
          "name": "original",
          "type": "number",
          "default": null,
          "description": "Original price. When higher than `value`, renders as a strike-through pre-discount price."
        },
        {
          "name": "currency",
          "type": "string",
          "default": "'USD'",
          "description": "ISO 4217 currency code."
        },
        {
          "name": "locale",
          "type": "string",
          "default": null,
          "description": "BCP-47 locale used by `Intl.NumberFormat`. Defaults to runtime."
        },
        {
          "name": "size",
          "type": "'sm' | 'md' | 'lg' | 'xl'",
          "default": "md",
          "description": "Visual size. `xl` is bolded and slightly tighter for hero pricing."
        },
        {
          "name": "showSale",
          "type": "boolean",
          "default": true,
          "description": "Whether to render the `-N%` sale chip when `original` is supplied."
        },
        {
          "name": "fractionDigits",
          "type": "number",
          "default": null,
          "description": "Override min/max fraction digits. By default uses the currency's locale convention."
        }
      ],
      "slots": [],
      "tokens": [
        "color.text.primary",
        "color.text.muted",
        "color.text.action.danger",
        "color.bg.action.danger.subtle",
        "font.size.sm",
        "font.size.md",
        "font.size.lg",
        "font.size.2xl",
        "font.weight.semibold",
        "font.weight.bold",
        "radius.sm",
        "space.2"
      ],
      "a11y": {
        "notes": [
          "Sale chip exposes `aria-label='N% off'`.",
          "Original price exposes `aria-label='Original price …'` so screen readers get the discount context.",
          "Numbers use `tabular-nums` so price columns align."
        ]
      },
      "composes_with": [
        {
          "component": "Card",
          "relation": "contained-by",
          "note": "Common in product cards."
        },
        {
          "component": "Sheet",
          "relation": "contained-by",
          "note": "Cart drawers / line items."
        },
        {
          "component": "Table",
          "relation": "contained-by",
          "note": "Pricing tables."
        }
      ],
      "related": [],
      "when_to_use": [],
      "pitfalls": [],
      "prompt_examples": [
        {
          "intent": "Plain price",
          "prompt": "show $48",
          "snippet": "<PriceTag value={48} />\n"
        },
        {
          "intent": "Sale price",
          "prompt": "show $36 down from $48",
          "snippet": "<PriceTag value={36} original={48} />\n"
        },
        {
          "intent": "Korean Won",
          "prompt": "₩48,000 in Korean locale",
          "snippet": "<PriceTag value={48000} currency=\"KRW\" locale=\"ko-KR\" />\n"
        },
        {
          "intent": "Hero pricing",
          "prompt": "big bold price for the pricing page",
          "snippet": "<PriceTag value={29} size=\"xl\" />\n"
        }
      ]
    },
    {
      "name": "ProgressBar",
      "slug": "progress-bar",
      "package": "@helixui/core",
      "import": "import { ProgressBar } from '@helixui/core'",
      "description": "Linear progress indicator. Determinate when given a `value`; indeterminate (looping shimmer) when `value` is omitted.",
      "category": "feedback",
      "tags": [
        "progress",
        "loading",
        "determinate",
        "indeterminate"
      ],
      "status": "stable",
      "since": "0.2.0",
      "layout": {
        "display": "block",
        "width": "fill",
        "height": "content",
        "intrinsicSize": "~6-8px tall, fills width",
        "stackable": true,
        "fullBleed": false
      },
      "anatomy": "[████████████░░░░░░░░░░]  62%   ← determinate\n[shimmer ░░░░░░░░░░░░░░░]       ← indeterminate (looping)\n",
      "visual": "A thin horizontal bar with a brand-tinted track. Determinate fills the track to `value`; indeterminate animates a moving highlight across.\n",
      "props": [
        {
          "name": "value",
          "type": "number",
          "default": "",
          "description": "Current value. Omit for indeterminate."
        },
        {
          "name": "max",
          "type": "number",
          "default": 100,
          "description": "Max value."
        },
        {
          "name": "tone",
          "type": "'brand' | 'success' | 'warning' | 'danger' | 'neutral'",
          "default": "brand",
          "description": "Fill color."
        },
        {
          "name": "size",
          "type": "'sm' | 'md' | 'lg'",
          "default": "md",
          "description": "Track height — 4 / 8 / 12 px."
        },
        {
          "name": "label",
          "type": "ReactNode",
          "default": "",
          "description": "Inline label above the bar."
        },
        {
          "name": "showValue",
          "type": "boolean",
          "default": false,
          "description": "Render the percentage on the right of the label row."
        }
      ],
      "slots": [],
      "tokens": [
        "color.bg.action.neutral.default",
        "color.bg.action.brand.default",
        "color.bg.action.success.default",
        "color.bg.action.warning.default",
        "color.bg.action.danger.default",
        "color.text.primary",
        "color.text.secondary",
        "radius.full",
        "space.2",
        "font.family.sans",
        "font.size.sm",
        "font.weight.medium"
      ],
      "a11y": {
        "role": "progressbar",
        "notes": [
          "When `value` is provided the element receives `aria-valuenow/min/max`. Omit `value` for indeterminate (no `aria-valuenow`).",
          "Animation respects `prefers-reduced-motion`."
        ]
      },
      "composes_with": [
        {
          "component": "Spinner",
          "relation": "alternative",
          "note": "Spinner for tiny inline loading; ProgressBar for measured/long."
        },
        {
          "component": "Skeleton",
          "relation": "alternative",
          "note": "Skeleton when the layout itself should look loading."
        }
      ],
      "related": [
        "Spinner"
      ],
      "when_to_use": [],
      "pitfalls": [],
      "prompt_examples": [
        {
          "intent": "upload progress",
          "prompt": "progress bar at 62%",
          "snippet": "<ProgressBar value={0.62} />\n"
        },
        {
          "intent": "unknown duration",
          "prompt": "looping indeterminate bar",
          "snippet": "<ProgressBar />\n"
        }
      ]
    },
    {
      "name": "PromptSuggestions",
      "slug": "prompt-suggestions",
      "package": "@helixui/core",
      "import": "import { PromptSuggestions, type PromptSuggestion } from '@helixui/core'",
      "description": "A row (chips) or grid (cards) of suggested prompts. Used at the start of an empty AI conversation or as follow-up suggestions after a response.",
      "category": "chat",
      "tags": [
        "ai",
        "starters",
        "follow-ups",
        "chips"
      ],
      "status": "stable",
      "since": "0.3.0",
      "layout": {
        "display": "flex",
        "width": "fill",
        "height": "content",
        "intrinsicSize": "wraps; chip row or card grid",
        "stackable": false,
        "fullBleed": false
      },
      "anatomy": "( Suggestion 1 ) ( Suggestion 2 ) ( Suggestion 3 )       ← chips\n┌─────────────────┐ ┌─────────────────┐\n│  Title          │ │  Title          │   ← cards\n│  description    │ │  description    │\n└─────────────────┘ └─────────────────┘\n",
      "visual": "Either a wrapping row of pill-shaped chips (compact) or a 2-column card grid (richer). Tapping a suggestion fires `onSelect` with the prompt text.\n",
      "props": [
        {
          "name": "suggestions",
          "type": "PromptSuggestion[]",
          "default": "",
          "description": "Required. Each has `id`, `label`, optional `hint`, `icon`."
        },
        {
          "name": "onSelect",
          "type": "(s) => void",
          "default": "",
          "description": "Called when the user picks a suggestion."
        },
        {
          "name": "layout",
          "type": "'chips' | 'cards'",
          "default": "chips",
          "description": "Compact wrap-around chips or larger grid cards."
        },
        {
          "name": "label",
          "type": "string",
          "default": "Suggested prompts",
          "description": "`aria-label` on the wrapping group."
        }
      ],
      "slots": [],
      "tokens": [
        "color.bg.surface.default",
        "color.bg.action.neutral.default",
        "color.border.default",
        "color.border.strong",
        "color.border.focus",
        "color.text.primary",
        "color.text.muted",
        "color.text.action.brand",
        "radius.md",
        "space.2",
        "space.3",
        "space.4",
        "font.family.sans",
        "font.size.sm",
        "font.size.xs",
        "font.weight.medium"
      ],
      "a11y": {
        "notes": [
          "The wrapper is `role=\"group\"` with an `aria-label`.",
          "Each suggestion is a `<button>` so it's focusable and activatable with Enter / Space."
        ]
      },
      "composes_with": [
        {
          "component": "ChatComposer",
          "relation": "sibling",
          "note": "Sits above the composer in an empty state."
        },
        {
          "component": "EmptyState",
          "relation": "alternative",
          "note": "Use EmptyState for non-AI empty states."
        }
      ],
      "related": [
        "ChatComposer"
      ],
      "when_to_use": [],
      "pitfalls": [],
      "prompt_examples": [
        {
          "intent": "AI conversation starters",
          "prompt": "three suggested prompts as chips",
          "snippet": "<PromptSuggestions\n  variant=\"chips\"\n  suggestions={[{ id: '1', text: 'Summarize this' }, { id: '2', text: 'Translate to Korean' }]}\n  onSelect={s => send(s.text)}\n/>\n"
        }
      ]
    },
    {
      "name": "PullToRefresh",
      "slug": "pull-to-refresh",
      "package": "@helixui/core",
      "import": "import { PullToRefresh } from '@helixui/core'",
      "description": "A scroll container that detects a downward pull at the top of its content and runs an async refresh callback when released past a threshold.",
      "category": "shell",
      "tags": [
        "mobile",
        "gesture",
        "refresh",
        "scroll"
      ],
      "status": "beta",
      "since": "0.5.0",
      "layout": {
        "display": "block",
        "width": "fill",
        "height": "fill",
        "intrinsicSize": "fills available; intercepts top-edge pull",
        "stackable": false,
        "fullBleed": false
      },
      "anatomy": "↓ Pull down to refresh ↓\n────────────────────────\n[ scrollable content ]\n",
      "visual": "A scroll container that exposes a small spinner when the user drags down past the top. Past a threshold, releasing fires the async refresh and the spinner spins until the promise resolves.\n",
      "props": [
        {
          "name": "onRefresh",
          "type": "() => void | Promise<void>",
          "default": "",
          "description": "Required. Called when the user releases past `threshold`. While the returned promise is pending, the spinner stays visible and disabled."
        },
        {
          "name": "threshold",
          "type": "number",
          "default": 64,
          "description": "Pixel distance past which release triggers refresh."
        },
        {
          "name": "maxPull",
          "type": "number",
          "default": 120,
          "description": "Soft cap on pull distance (rubber-band beyond this)."
        }
      ],
      "slots": [
        "children — the scrollable content"
      ],
      "tokens": [
        "color.bg.surface.default",
        "color.text.action.brand",
        "radius.full",
        "font.family.sans",
        "shadow.md"
      ],
      "a11y": {
        "notes": [
          "Pull-to-refresh is a touch gesture; it should never be the only way to refresh. Pair with a visible Refresh button or a CommandPalette entry.",
          "The component listens to pointer events so it works with mouse drag for desktop testing, but the gesture is mobile-first."
        ]
      },
      "composes_with": [
        {
          "component": "List",
          "relation": "child",
          "note": "Common: PullToRefresh wraps a List."
        },
        {
          "component": "ChatList",
          "relation": "alternative",
          "note": "ChatList has its own scroll behavior."
        },
        {
          "component": "SwipeableListItem",
          "relation": "sibling"
        }
      ],
      "related": [
        "List",
        "SwipeableListItem"
      ],
      "when_to_use": [],
      "pitfalls": [],
      "prompt_examples": [
        {
          "intent": "mobile feed pull-to-refresh",
          "prompt": "pull to refresh wrapping a feed list",
          "snippet": "<PullToRefresh onRefresh={loadFeed}>\n  <List>{rows}</List>\n</PullToRefresh>\n"
        }
      ]
    },
    {
      "name": "RadioCard",
      "slug": "radio-card",
      "package": "@helixui/core",
      "import": "import { RadioCard } from '@helixui/core'",
      "description": "A radio option styled as a card. Use inside a RadioGroup when each option needs more space (icon, title, description).",
      "category": "form",
      "tags": [
        "radio",
        "card",
        "option",
        "selectable"
      ],
      "status": "stable",
      "since": "0.1.0",
      "layout": {
        "display": "block",
        "width": "fill",
        "height": "content",
        "intrinsicSize": "card-sized; rows grow with content",
        "stackable": true,
        "fullBleed": false
      },
      "anatomy": "┌─ ◉ Title ──────────┐\n│   description       │\n│   [icon]            │\n└─────────────────────┘\n",
      "visual": "A Card-shaped radio option. Selected state highlights with a brand border + tinted background; the radio dot is in the top-left or top-right per variant.\n",
      "props": [
        {
          "name": "value",
          "type": "string",
          "default": "",
          "description": "Required. The value submitted when this option is selected."
        },
        {
          "name": "title",
          "type": "ReactNode",
          "default": "",
          "description": "Headline of the card."
        },
        {
          "name": "description",
          "type": "ReactNode",
          "default": "",
          "description": "Supporting text below the title."
        },
        {
          "name": "icon",
          "type": "ReactNode",
          "default": "",
          "description": "Optional leading icon."
        },
        {
          "name": "isDisabled",
          "type": "boolean",
          "default": false,
          "description": "Disables this option."
        }
      ],
      "slots": [
        "children — additional content"
      ],
      "tokens": [
        "color.bg.surface.default",
        "color.bg.action.brand.subtle",
        "color.bg.action.brand.default",
        "color.border.default",
        "color.border.strong",
        "color.border.focus",
        "color.text.primary",
        "color.text.secondary",
        "color.text.action.brand",
        "radius.md",
        "space.1",
        "space.3",
        "space.4",
        "font.family.sans",
        "font.size.md",
        "font.size.sm",
        "font.weight.semibold"
      ],
      "a11y": {
        "role": "radio",
        "keyboard": [
          {
            "key": "ArrowDown",
            "action": "Move to next option in group."
          },
          {
            "key": "ArrowUp",
            "action": "Move to previous option in group."
          },
          {
            "key": "Space",
            "action": "Selects the focused card."
          }
        ]
      },
      "composes_with": [
        {
          "component": "RadioGroup",
          "relation": "parent",
          "note": "Use inside a RadioGroup."
        }
      ],
      "related": [
        "RadioGroup"
      ],
      "when_to_use": [],
      "pitfalls": [],
      "prompt_examples": [
        {
          "intent": "plan picker",
          "prompt": "three plan radio cards",
          "snippet": "<RadioGroup value={plan} onChange={setPlan}>\n  <RadioCard value=\"free\" title=\"Free\" description=\"$0/mo\" />\n  <RadioCard value=\"pro\" title=\"Pro\" description=\"$12/mo\" />\n  <RadioCard value=\"team\" title=\"Team\" description=\"$24/mo\" />\n</RadioGroup>\n"
        }
      ]
    },
    {
      "name": "RadioGroup",
      "slug": "radio-group",
      "package": "@helixui/core",
      "import": "import { RadioGroup, Radio } from '@helixui/core'",
      "description": "A list of mutually exclusive options. Use Radio components as children.",
      "category": "form",
      "tags": [
        "radio",
        "choice",
        "exclusive"
      ],
      "status": "stable",
      "since": "0.1.0",
      "layout": {
        "display": "block",
        "width": "fill",
        "height": "content",
        "intrinsicSize": "vertical stack of options",
        "stackable": true,
        "fullBleed": false
      },
      "anatomy": "( ◉ ) Option A\n( ◯ ) Option B\n( ◯ ) Option C\n",
      "visual": "A vertical or horizontal group of radio buttons. Selected radio fills with brand color; label sits to the right.\n",
      "props": [
        {
          "name": "label",
          "type": "ReactNode",
          "default": "",
          "description": "Group label."
        },
        {
          "name": "description",
          "type": "ReactNode",
          "default": "",
          "description": "Helper text."
        },
        {
          "name": "errorMessage",
          "type": "string | (v: ValidationResult) => string",
          "default": "",
          "description": "Error text."
        },
        {
          "name": "orientation",
          "type": "'vertical' | 'horizontal'",
          "default": "vertical",
          "description": "Layout."
        },
        {
          "name": "value",
          "type": "string",
          "default": "",
          "description": "Controlled selected value."
        },
        {
          "name": "defaultValue",
          "type": "string",
          "default": "",
          "description": "Uncontrolled initial value."
        },
        {
          "name": "isRequired",
          "type": "boolean",
          "default": false,
          "description": "Required for validation."
        },
        {
          "name": "isDisabled",
          "type": "boolean",
          "default": false,
          "description": "Disables all radios."
        },
        {
          "name": "onChange",
          "type": "(value: string) => void",
          "default": "",
          "description": "Change handler."
        }
      ],
      "slots": [
        "children — Radio components"
      ],
      "tokens": [
        "color.bg.surface.default",
        "color.bg.action.brand.default",
        "color.border.strong",
        "color.border.focus",
        "color.text.primary",
        "color.text.secondary",
        "color.text.action.danger",
        "space.2",
        "space.4",
        "font.family.sans",
        "font.size.sm",
        "font.weight.medium"
      ],
      "a11y": {
        "role": "radiogroup",
        "keyboard": [
          {
            "key": "ArrowDown",
            "action": "Move to next radio."
          },
          {
            "key": "ArrowUp",
            "action": "Move to previous radio."
          },
          {
            "key": "Space",
            "action": "Selects focused radio."
          }
        ]
      },
      "composes_with": [
        {
          "component": "Radio",
          "relation": "child",
          "note": "Default radio child."
        },
        {
          "component": "RadioCard",
          "relation": "child",
          "note": "Card-shaped option."
        },
        {
          "component": "Field",
          "relation": "wraps",
          "note": "RadioGroup has built-in label/description."
        },
        {
          "component": "Checkbox",
          "relation": "sibling"
        }
      ],
      "related": [
        "RadioCard",
        "Checkbox"
      ],
      "when_to_use": [],
      "pitfalls": [],
      "prompt_examples": [
        {
          "intent": "simple choice",
          "prompt": "choose A / B / C",
          "snippet": "<RadioGroup label=\"Choose one\" value={v} onChange={setV}>\n  <Radio value=\"a\">A</Radio>\n  <Radio value=\"b\">B</Radio>\n  <Radio value=\"c\">C</Radio>\n</RadioGroup>\n"
        }
      ]
    },
    {
      "name": "Rating",
      "slug": "rating",
      "package": "@helixui/core",
      "import": "import { Rating } from '@helixui/core'",
      "description": "A star rating control. Interactive by default — click or tap to set; supports half-star precision and a read-only display mode.",
      "category": "form",
      "tags": [
        "stars",
        "rating",
        "review"
      ],
      "status": "stable",
      "since": "0.5.0",
      "layout": {
        "display": "inline-flex",
        "width": "content",
        "height": "content",
        "intrinsicSize": "hugs N stars",
        "stackable": true,
        "fullBleed": false
      },
      "anatomy": "★ ★ ★ ★ ☆   4 of 5\n",
      "visual": "A row of star glyphs filled to the current value. Half-star precision when enabled. Read-only mode disables interaction and lowers contrast.\n",
      "props": [
        {
          "name": "value",
          "type": "number",
          "default": "",
          "description": "Controlled value 0..max."
        },
        {
          "name": "defaultValue",
          "type": "number",
          "default": 0,
          "description": "Uncontrolled initial."
        },
        {
          "name": "max",
          "type": "number",
          "default": 5,
          "description": "Total stars."
        },
        {
          "name": "step",
          "type": "0.5 | 1",
          "default": 1,
          "description": "Increments. `0.5` enables half-star precision."
        },
        {
          "name": "onChange",
          "type": "(v) => void",
          "default": "",
          "description": "Change handler."
        },
        {
          "name": "readOnly",
          "type": "boolean",
          "default": false,
          "description": "Display mode — no hover, no click."
        },
        {
          "name": "size",
          "type": "'sm' | 'md' | 'lg'",
          "default": "md",
          "description": "Star size."
        },
        {
          "name": "label",
          "type": "string",
          "default": "Rating",
          "description": "`aria-label`."
        },
        {
          "name": "allowClear",
          "type": "boolean",
          "default": false,
          "description": "Clicking the current value clears back to 0."
        }
      ],
      "slots": [],
      "tokens": [
        "color.bg.action.warning.default",
        "color.border.focus"
      ],
      "a11y": {
        "role": "slider",
        "notes": [
          "When interactive: `role=\"slider\"`, `aria-valuenow/min/max` reflect the value. When `readOnly`: `role=\"img\"`.",
          "Each tap target is a `<button>` so it's keyboard-accessible."
        ]
      },
      "composes_with": [
        {
          "component": "Form",
          "relation": "parent",
          "note": "Inside a form when collecting reviews."
        },
        {
          "component": "Slider",
          "relation": "sibling"
        }
      ],
      "related": [
        "Slider"
      ],
      "when_to_use": [],
      "pitfalls": [],
      "prompt_examples": [
        {
          "intent": "leave a review",
          "prompt": "5-star rating with half precision",
          "snippet": "<Rating value={value} onChange={setValue} allowHalf />\n"
        },
        {
          "intent": "show product score",
          "prompt": "read-only rating of 4.5",
          "snippet": "<Rating value={4.5} readOnly />\n"
        }
      ]
    },
    {
      "name": "RichTextEditor",
      "slug": "rich-text-editor",
      "package": "@helixui/core",
      "import": "import { RichTextEditor } from '@helixui/core'",
      "description": "WYSIWYG editor backed by TipTap (built on ProseMirror). Lazy-loads the engine and every extension; declared as optional peer dependencies. Ships a default toolbar but exposes an imperative handle for fully custom UI.",
      "category": "form",
      "tags": [
        "wysiwyg",
        "editor",
        "tiptap",
        "prosemirror"
      ],
      "status": "stable",
      "since": "0.7.0",
      "layout": {
        "display": "block",
        "width": "fill",
        "height": "fill",
        "intrinsicSize": "fills available; toolbar pinned top",
        "stackable": false,
        "fullBleed": false
      },
      "anatomy": "┌── toolbar (B I U • ¶ ) ──┐\n├──────────────────────────┤\n│  editable content area   │\n│  …                       │\n└──────────────────────────┘\n",
      "visual": "A WYSIWYG editor with a default toolbar (bold, italic, lists, links, code) and a content area. Lazy-loads TipTap and selected extensions. Imperative handle exposes ProseMirror APIs.\n",
      "props": [
        {
          "name": "value",
          "type": "string",
          "default": "''",
          "description": "HTML string for the current document."
        },
        {
          "name": "onChange",
          "type": "(html: string) => void",
          "default": "—",
          "description": "Fires on every edit with the new HTML."
        },
        {
          "name": "onChangeText",
          "type": "(text: string) => void",
          "default": "—",
          "description": "Plain-text snapshot, fired alongside onChange."
        },
        {
          "name": "onChangeJSON",
          "type": "(json: unknown) => void",
          "default": "—",
          "description": "TipTap JSON snapshot, fired alongside onChange."
        },
        {
          "name": "onSelectionChange",
          "type": "(state: RichTextSelectionState) => void",
          "default": "—",
          "description": "Fires whenever the selection or active formats change."
        },
        {
          "name": "extensions",
          "type": "RichTextExtension[] | 'all'",
          "default": "starter",
          "description": "Built-in extensions to enable. Defaults to a starter preset; pass 'all' to enable everything."
        },
        {
          "name": "theme",
          "type": "'light' | 'dark' | 'auto'",
          "default": "auto",
          "description": "`auto` follows `document.documentElement.dataset.theme`."
        },
        {
          "name": "readOnly",
          "type": "boolean",
          "default": false,
          "description": "Disable editing."
        },
        {
          "name": "autoFocus",
          "type": "boolean",
          "default": false,
          "description": "Focus the editor when it mounts."
        },
        {
          "name": "placeholder",
          "type": "string",
          "default": "Write something…",
          "description": "Empty-state hint. Requires the `placeholder` extension (on by default)."
        },
        {
          "name": "toolbar",
          "type": "boolean",
          "default": true,
          "description": "Show the built-in toolbar."
        },
        {
          "name": "renderToolbar",
          "type": "(handle, state) => ReactNode",
          "default": "—",
          "description": "Render a custom toolbar instead of the default. Receives the imperative handle and current selection state."
        },
        {
          "name": "height",
          "type": "number | string",
          "default": 360,
          "description": "Editing surface height. Numbers are treated as px."
        },
        {
          "name": "editorRef",
          "type": "Ref<RichTextEditorHandle>",
          "default": "—",
          "description": "Imperative handle for advanced control."
        },
        {
          "name": "tiptapExtensions",
          "type": "unknown[]",
          "default": "[]",
          "description": "Extra TipTap extensions appended after the built-in ones."
        },
        {
          "name": "onMount",
          "type": "(handle: RichTextEditorHandle) => void",
          "default": "—",
          "description": "Fires once mounted, with the imperative handle."
        }
      ],
      "slots": [],
      "tokens": [
        "color.bg.surface.default",
        "color.bg.surface.subtle",
        "color.bg.surface.inverse",
        "color.border.default",
        "color.border.focus",
        "color.text.primary",
        "color.text.muted",
        "color.text.action.brand",
        "color.text.action.danger",
        "color.bg.action.brand.default",
        "color.bg.action.danger.subtle",
        "radius.md",
        "radius.sm",
        "font.family.sans",
        "font.family.mono",
        "motion.duration.fast",
        "motion.easing.standard"
      ],
      "a11y": {
        "notes": [
          "TipTap exposes a `role='textbox' aria-multiline='true'` surface.",
          "Toolbar buttons set `aria-pressed` for active states.",
          "Container shows a `:focus-within` ring matching helixui's other inputs.",
          "Respects `prefers-reduced-motion` via the global motion stylesheet."
        ]
      },
      "composes_with": [
        {
          "component": "CodeEditor",
          "relation": "alternative",
          "note": "CodeEditor for code; RichTextEditor for prose."
        },
        {
          "component": "Form",
          "relation": "parent",
          "note": "Treat as a controlled form input."
        },
        {
          "component": "TextInput",
          "relation": "sibling"
        },
        {
          "component": "Textarea",
          "relation": "sibling"
        }
      ],
      "related": [
        "TextInput",
        "Textarea",
        "CodeEditor"
      ],
      "when_to_use": [],
      "pitfalls": [],
      "prompt_examples": [
        {
          "intent": "blog post editor",
          "prompt": "WYSIWYG editor for a post body",
          "snippet": "<RichTextEditor value={body} onChange={setBody} placeholder=\"Write…\" />\n"
        }
      ]
    },
    {
      "name": "SafeArea",
      "slug": "safe-area",
      "package": "@helixui/core",
      "import": "import { SafeArea } from '@helixui/core'",
      "description": "A wrapper that reserves space for the device's safe-area insets — notch, status bar, home indicator. Reads `env(safe-area-inset-*)` and applies the value as padding (default) or margin to the chosen edges.",
      "category": "shell",
      "tags": [
        "mobile",
        "inset",
        "notch",
        "home-indicator"
      ],
      "status": "stable",
      "since": "0.5.0",
      "layout": {
        "display": "block",
        "width": "fill",
        "height": "fill",
        "intrinsicSize": "fills viewport; pads chosen edges by env(safe-area-inset-*)",
        "stackable": false,
        "fullBleed": true
      },
      "anatomy": "╔═════════════════════════════╗  ← top inset (notch / status bar)\n║  <children>                ║\n║                            ║\n╚═════════════════════════════╝  ← bottom inset (home indicator)\n",
      "visual": "A presentational wrapper that reads `env(safe-area-inset-top|right|bottom|left)` and applies them as padding (default) or margin to the chosen edges.\n",
      "props": [
        {
          "name": "edges",
          "type": "SafeAreaEdge[] | 'all'",
          "default": "all",
          "description": "Which edges to reserve. `'top' | 'right' | 'bottom' | 'left'` or `'all'`."
        },
        {
          "name": "apply",
          "type": "'padding' | 'margin'",
          "default": "padding",
          "description": "How to apply the inset."
        }
      ],
      "slots": [],
      "tokens": [],
      "a11y": {
        "notes": [
          "SafeArea is presentational. It does not change focus order or alter content semantics."
        ]
      },
      "composes_with": [
        {
          "component": "AppShell",
          "relation": "parent",
          "note": "Wrap AppShell on mobile builds."
        },
        {
          "component": "BottomNav",
          "relation": "parent",
          "note": "Often wraps the BottomNav region."
        },
        {
          "component": "FAB",
          "relation": "sibling"
        }
      ],
      "related": [
        "BottomNav",
        "FAB"
      ],
      "when_to_use": [],
      "pitfalls": [],
      "prompt_examples": [
        {
          "intent": "pad below the notch",
          "prompt": "safe area top + bottom",
          "snippet": "<SafeArea edges={['top','bottom']}>\n  <App />\n</SafeArea>\n"
        }
      ]
    },
    {
      "name": "SegmentedControl",
      "slug": "segmented-control",
      "package": "@helixui/core",
      "import": "import { SegmentedControl, Segment } from '@helixui/core'",
      "description": "A grouped row of toggle buttons for picking between a small number of mutually exclusive views.",
      "category": "form",
      "tags": [
        "toggle-group",
        "tabs",
        "choice"
      ],
      "status": "stable",
      "since": "0.1.0",
      "layout": {
        "display": "inline-flex",
        "width": "content",
        "height": "content",
        "intrinsicSize": "pill row, ~28-36px tall",
        "stackable": false,
        "fullBleed": false
      },
      "anatomy": "[ Day ][ Week ][ Month ]   ← exclusive choice (one filled)\n",
      "visual": "A pill-shaped row of equal-width segments with a sliding active background. Active segment uses elevated surface; inactive use subtle background.\n",
      "props": [
        {
          "name": "size",
          "type": "'sm' | 'md'",
          "default": "md",
          "description": "Control height."
        },
        {
          "name": "selectionMode",
          "type": "'single' | 'multiple'",
          "default": "single",
          "description": "Selection model."
        },
        {
          "name": "disallowEmptySelection",
          "type": "boolean",
          "default": true,
          "description": "Prevent unselecting the last item in single mode."
        },
        {
          "name": "selectedKeys",
          "type": "Set<string>",
          "default": "",
          "description": "Controlled selection."
        },
        {
          "name": "defaultSelectedKeys",
          "type": "Iterable<string>",
          "default": "",
          "description": "Uncontrolled initial selection."
        },
        {
          "name": "onSelectionChange",
          "type": "(keys: Set<string>) => void",
          "default": "",
          "description": "Selection change handler."
        }
      ],
      "slots": [
        "children — Segment components"
      ],
      "tokens": [
        "color.bg.action.neutral.default",
        "color.bg.surface.default",
        "color.text.primary",
        "color.text.secondary",
        "color.border.focus",
        "radius.md",
        "space.3",
        "font.family.sans",
        "font.size.xs",
        "font.size.sm",
        "font.weight.medium",
        "shadow.sm"
      ],
      "a11y": {
        "role": "radiogroup",
        "keyboard": [
          {
            "key": "ArrowLeft",
            "action": "Move focus left."
          },
          {
            "key": "ArrowRight",
            "action": "Move focus right."
          },
          {
            "key": "Space",
            "action": "Selects focused segment."
          }
        ],
        "notes": [
          "For 5+ options, prefer Tabs or a Select."
        ]
      },
      "composes_with": [
        {
          "component": "Tabs",
          "relation": "alternative",
          "note": "Tabs for in-page section switching; SegmentedControl for compact view modes."
        }
      ],
      "related": [
        "Tabs"
      ],
      "when_to_use": [],
      "pitfalls": [],
      "prompt_examples": [
        {
          "intent": "view mode picker",
          "prompt": "segmented control Day / Week / Month",
          "snippet": "<SegmentedControl value={mode} onChange={setMode}>\n  <Segment value=\"day\">Day</Segment>\n  <Segment value=\"week\">Week</Segment>\n  <Segment value=\"month\">Month</Segment>\n</SegmentedControl>\n"
        }
      ]
    },
    {
      "name": "Select",
      "slug": "select",
      "package": "@helixui/core",
      "import": "import { Select, Option } from '@helixui/core'",
      "description": "A single-value picker rendered as a popover listbox.",
      "category": "form",
      "tags": [
        "picker",
        "dropdown",
        "single-value"
      ],
      "status": "stable",
      "since": "0.1.0",
      "layout": {
        "display": "block",
        "width": "fill",
        "height": "content",
        "intrinsicSize": "fills width, hugs height",
        "stackable": false,
        "fullBleed": false
      },
      "anatomy": "[ Selected value         ▾ ]\n   ╭──── popover ───╮\n   │ • Option A     │\n   │ • Option B  ✓  │\n   │ • Option C     │\n   ╰────────────────╯\n",
      "visual": "A trigger button styled like a TextInput with a trailing chevron. On open, a popover listbox appears anchored to the trigger; selected option is checkmarked.\n",
      "props": [
        {
          "name": "label",
          "type": "ReactNode",
          "default": "",
          "description": "Visible label."
        },
        {
          "name": "description",
          "type": "ReactNode",
          "default": "",
          "description": "Helper text."
        },
        {
          "name": "errorMessage",
          "type": "string | (v: ValidationResult) => string",
          "default": "",
          "description": "Error text."
        },
        {
          "name": "placeholder",
          "type": "string",
          "default": "Select…",
          "description": "Shown when nothing is selected."
        },
        {
          "name": "size",
          "type": "'sm' | 'md' | 'lg'",
          "default": "md",
          "description": "Trigger height."
        },
        {
          "name": "selectedKey",
          "type": "Key | null",
          "default": "",
          "description": "Controlled selected option."
        },
        {
          "name": "defaultSelectedKey",
          "type": "Key",
          "default": "",
          "description": "Uncontrolled initial."
        },
        {
          "name": "onSelectionChange",
          "type": "(key: Key) => void",
          "default": "",
          "description": "Selection change handler."
        }
      ],
      "slots": [
        "children — Option components"
      ],
      "tokens": [
        "color.bg.surface.default",
        "color.bg.action.neutral.default",
        "color.bg.action.brand.subtle",
        "color.border.default",
        "color.border.focus",
        "color.text.primary",
        "color.text.secondary",
        "color.text.muted",
        "color.text.action.brand",
        "color.text.action.danger",
        "radius.md",
        "space.1",
        "space.2",
        "space.3",
        "font.family.sans",
        "font.size.sm",
        "font.size.md",
        "font.size.lg",
        "font.weight.medium",
        "shadow.md"
      ],
      "a11y": {
        "role": "combobox",
        "keyboard": [
          {
            "key": "ArrowDown",
            "action": "Open / move down."
          },
          {
            "key": "Enter",
            "action": "Select highlighted option."
          },
          {
            "key": "Escape",
            "action": "Close."
          }
        ]
      },
      "composes_with": [
        {
          "component": "Field",
          "relation": "wraps",
          "note": "Built-in label/description/error."
        },
        {
          "component": "Form",
          "relation": "parent",
          "note": "Submitted as part of a Form."
        },
        {
          "component": "MultiSelect",
          "relation": "alternative",
          "note": "MultiSelect for multiple values."
        }
      ],
      "related": [
        "MultiSelect"
      ],
      "when_to_use": [],
      "pitfalls": [],
      "prompt_examples": [
        {
          "intent": "country picker",
          "prompt": "select with three options",
          "snippet": "<Select label=\"Country\" value={country} onChange={setCountry}>\n  <Option value=\"us\">United States</Option>\n  <Option value=\"kr\">Korea</Option>\n  <Option value=\"jp\">Japan</Option>\n</Select>\n"
        }
      ]
    },
    {
      "name": "Sheet",
      "slug": "sheet",
      "package": "@helixui/core",
      "import": "import { Sheet, SheetTrigger } from '@helixui/core'",
      "description": "A modal panel that slides in from a screen edge. Use for navigation, filters, or longer task flows on mobile.",
      "category": "overlay",
      "tags": [
        "drawer",
        "side-panel",
        "mobile",
        "modal"
      ],
      "status": "stable",
      "since": "0.1.0",
      "layout": {
        "display": "portal",
        "width": "content",
        "height": "fill",
        "intrinsicSize": "fills 1 dimension; size by `side`",
        "stackable": false,
        "fullBleed": true
      },
      "anatomy": "┌─ overlay ────────────────────┐\n│ ┌─ Sheet (side=start) ──┐    │\n│ │  content              │    │  ← slides in from left/right/top/bottom\n│ │                       │    │\n│ └───────────────────────┘    │\n└──────────────────────────────┘\n",
      "visual": "A panel that slides in from the chosen edge over a dimmed overlay. Common sides are start (drawer), end (right inspector), bottom (mobile filters).\n",
      "props": [
        {
          "name": "side",
          "type": "'start' | 'end' | 'top' | 'bottom'",
          "default": "end",
          "description": "Edge the sheet enters from."
        },
        {
          "name": "title",
          "type": "ReactNode",
          "default": "",
          "description": "Sheet title."
        },
        {
          "name": "description",
          "type": "ReactNode",
          "default": "",
          "description": "Lead paragraph."
        },
        {
          "name": "isDismissable",
          "type": "boolean",
          "default": true,
          "description": "Close via overlay click and Escape."
        },
        {
          "name": "isOpen",
          "type": "boolean",
          "default": "",
          "description": "Controlled open state."
        },
        {
          "name": "defaultOpen",
          "type": "boolean",
          "default": false,
          "description": "Uncontrolled initial open."
        },
        {
          "name": "onOpenChange",
          "type": "(open: boolean) => void",
          "default": "",
          "description": "Open change handler."
        }
      ],
      "slots": [
        "SheetTrigger child — the trigger button",
        "Sheet children — render-prop receives `{ close }`"
      ],
      "tokens": [
        "color.bg.surface.default",
        "color.text.primary",
        "color.text.secondary",
        "radius.xl",
        "space.4",
        "space.6",
        "font.family.sans",
        "font.size.sm",
        "font.size.xl",
        "font.weight.semibold",
        "shadow.lg"
      ],
      "a11y": {
        "role": "dialog",
        "notes": [
          "Same focus trapping and dismiss semantics as Dialog. The visual difference is the slide-in animation from a screen edge.",
          "On `bottom` and `top` sides, the sheet has rounded corners only on the entering edge."
        ]
      },
      "composes_with": [
        {
          "component": "Sidebar",
          "relation": "child",
          "note": "Used as the mobile drawer body."
        },
        {
          "component": "Dialog",
          "relation": "alternative",
          "note": "Dialog for centered tasks; Sheet for edge-anchored."
        },
        {
          "component": "ActionSheet",
          "relation": "alternative",
          "note": "ActionSheet is the iOS-style action menu."
        },
        {
          "component": "Popover",
          "relation": "sibling"
        }
      ],
      "related": [
        "Dialog",
        "Popover"
      ],
      "when_to_use": [],
      "pitfalls": [],
      "prompt_examples": [
        {
          "intent": "mobile sidebar drawer",
          "prompt": "left drawer with the main nav",
          "snippet": "<Sheet side=\"start\" isOpen={open} onOpenChange={setOpen}>\n  <Sidebar>...</Sidebar>\n</Sheet>\n"
        },
        {
          "intent": "filter panel",
          "prompt": "right side filter sheet",
          "snippet": "<SheetTrigger>\n  <Button>Filter</Button>\n  <Sheet side=\"end\">…</Sheet>\n</SheetTrigger>\n"
        }
      ]
    },
    {
      "name": "Sidebar",
      "slug": "sidebar",
      "package": "@helixui/core",
      "import": "import { Sidebar } from '@helixui/core'",
      "description": "A vertical navigation rail with grouped items. Designed for AppShell's sidebar slot, also usable inside a Sheet on mobile.",
      "category": "navigation",
      "tags": [
        "nav",
        "vertical",
        "rail",
        "sections",
        "grouped",
        "persistent"
      ],
      "status": "stable",
      "since": "0.2.0",
      "layout": {
        "display": "flex",
        "width": "fixed:240px (default), tunable via parent",
        "height": "fill",
        "intrinsicSize": "full-height vertical column, footer pinned",
        "stackable": false,
        "fullBleed": false
      },
      "anatomy": "┌─────────────────────────┐\n│ Sidebar.Header          │   ← brand / search\n├─────────────────────────┤\n│ Sidebar.Group \"title\"   │\n│   • Sidebar.Item active │   ← active uses aria-current=page\n│   • Sidebar.Item        │\n│   • Sidebar.Item   [3]  │   ← trailing content (badge, count)\n│                         │\n│ Sidebar.Group \"title\"   │\n│   • Sidebar.Item        │\n├─────────────────────────┤\n│ Sidebar.Footer          │   ← pinned to bottom\n└─────────────────────────┘\n ↑ wrapped in <nav aria-label>\n",
      "visual": "A muted vertical column. Items are pill-shaped (radius.md) with subtle hover (action.neutral.default at low alpha)\nand a tinted brand background (action.brand.subtle) when active. Group titles are tiny uppercase labels\n(font.size.xs + font.weight.semibold) with low contrast. Icons sit at space.2 from the label. The footer is\nseparated by border.default and contains compact identity (Avatar + name).\n",
      "props": [
        {
          "name": "label",
          "type": "string",
          "default": "Primary",
          "description": "`aria-label` on the wrapping `<nav>`."
        }
      ],
      "slots": [
        "Sidebar.Header — brand / search at the top",
        "Sidebar.Group — group of items with optional `title`",
        "Sidebar.Item — anchor (when `href`) or button. `active` adds `aria-current=page`. Optional `icon` and `trailing`.",
        "Sidebar.Footer — pinned bottom slot"
      ],
      "tokens": [
        "color.bg.action.neutral.default",
        "color.bg.action.brand.subtle",
        "color.text.primary",
        "color.text.secondary",
        "color.text.muted",
        "color.text.action.brand",
        "color.border.default",
        "color.border.focus",
        "radius.md",
        "space.1",
        "space.2",
        "space.3",
        "font.family.sans",
        "font.size.sm",
        "font.size.xs",
        "font.weight.semibold",
        "font.weight.medium"
      ],
      "a11y": {
        "notes": [
          "Wraps in `<nav aria-label>`. Active item is rendered with `aria-current=\"page\"`.",
          "Items can be `<a>` or `<button>` depending on whether `href` is provided."
        ]
      },
      "composes_with": [
        {
          "component": "AppShell",
          "relation": "slot",
          "note": "Fills the `sidebar` slot of AppShell on desktop."
        },
        {
          "component": "Sheet",
          "relation": "parent",
          "note": "Render the same Sidebar inside Sheet (side='start') for the mobile drawer."
        },
        {
          "component": "NavigationMenu",
          "relation": "alternative",
          "note": "Use NavigationMenu for a horizontal top-bar nav."
        },
        {
          "component": "BottomNav",
          "relation": "alternative",
          "note": "Mobile-only horizontal nav at the bottom of the viewport."
        },
        {
          "component": "Avatar",
          "relation": "child",
          "note": "Common in Sidebar.Header and Sidebar.Footer."
        }
      ],
      "related": [
        "AppShell",
        "NavigationMenu",
        "Sheet"
      ],
      "when_to_use": [],
      "pitfalls": [],
      "prompt_examples": [
        {
          "intent": "basic side navigation",
          "prompt": "sidebar with Dashboard, Users, Billing",
          "snippet": "<Sidebar label=\"Workspace nav\">\n  <Sidebar.Group>\n    <Sidebar.Item href=\"/\" active>Dashboard</Sidebar.Item>\n    <Sidebar.Item href=\"/users\">Users</Sidebar.Item>\n    <Sidebar.Item href=\"/billing\">Billing</Sidebar.Item>\n  </Sidebar.Group>\n</Sidebar>\n"
        },
        {
          "intent": "grouped navigation with counts",
          "prompt": "sidebar with two sections, show unread count next to Inbox",
          "snippet": "<Sidebar label=\"Mail\">\n  <Sidebar.Group title=\"Mail\">\n    <Sidebar.Item href=\"/inbox\" trailing=\"12\" active>Inbox</Sidebar.Item>\n    <Sidebar.Item href=\"/sent\">Sent</Sidebar.Item>\n  </Sidebar.Group>\n  <Sidebar.Group title=\"Workspace\">\n    <Sidebar.Item href=\"/team\">Team</Sidebar.Item>\n  </Sidebar.Group>\n</Sidebar>\n"
        },
        {
          "intent": "sidebar with brand + user identity",
          "prompt": "side nav with logo at the top and current user at the bottom",
          "snippet": "<Sidebar>\n  <Sidebar.Header>\n    <Avatar fallback=\"HX\" /> <Text weight=\"semibold\">helixui</Text>\n  </Sidebar.Header>\n  <Sidebar.Group>\n    <Sidebar.Item href=\"/\" active>Home</Sidebar.Item>\n  </Sidebar.Group>\n  <Sidebar.Footer>\n    <Avatar fallback=\"ST\" size=\"sm\" /> <Text size=\"sm\">Jordan Lee</Text>\n  </Sidebar.Footer>\n</Sidebar>\n"
        },
        {
          "intent": "mobile drawer reuse",
          "prompt": "use the same sidebar inside a sheet on mobile",
          "snippet": "<Sheet side=\"start\" isOpen={open} onOpenChange={setOpen}>\n  <Sidebar>...</Sidebar>\n</Sheet>\n"
        }
      ]
    },
    {
      "name": "Skeleton",
      "slug": "skeleton",
      "package": "@helixui/core",
      "import": "import { Skeleton } from '@helixui/core'",
      "description": "A shimmering placeholder for content that's still loading.",
      "category": "feedback",
      "tags": [
        "loading",
        "placeholder",
        "shimmer"
      ],
      "status": "stable",
      "since": "0.1.0",
      "layout": {
        "display": "block",
        "width": "fill",
        "height": "content",
        "intrinsicSize": "sized by props (width/height)",
        "stackable": true,
        "fullBleed": false
      },
      "anatomy": "▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒\n▒▒▒▒▒▒▒▒▒▒\n▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒    ← shimmer animation\n",
      "visual": "A flat block (radius.md) with a moving shimmer gradient. Common shapes: rectangular line, circle (avatar), and full row block. Animation respects prefers-reduced-motion.\n",
      "props": [
        {
          "name": "shape",
          "type": "'rect' | 'circle' | 'text'",
          "default": "rect",
          "description": "Skeleton shape."
        },
        {
          "name": "width",
          "type": "number | string",
          "default": "",
          "description": "Override CSS width."
        },
        {
          "name": "height",
          "type": "number | string",
          "default": "",
          "description": "Override CSS height."
        }
      ],
      "slots": [],
      "tokens": [
        "color.bg.action.neutral.default",
        "color.bg.action.neutral.hover",
        "radius.md",
        "radius.sm",
        "radius.full"
      ],
      "a11y": {
        "notes": [
          "Skeleton is `aria-hidden`. It must be paired with a `aria-live` region elsewhere if the loading state is meaningful (e.g. \"Loading messages…\").",
          "Animation respects `prefers-reduced-motion`."
        ]
      },
      "composes_with": [
        {
          "component": "List",
          "relation": "child",
          "note": "Used as placeholder rows while loading."
        },
        {
          "component": "Card",
          "relation": "child",
          "note": "Inside Cards as placeholder content."
        },
        {
          "component": "Spinner",
          "relation": "sibling"
        }
      ],
      "related": [
        "Spinner"
      ],
      "when_to_use": [],
      "pitfalls": [],
      "prompt_examples": [
        {
          "intent": "list loading state",
          "prompt": "5 skeleton rows while loading",
          "snippet": "{Array.from({ length: 5 }).map((_, i) => (\n  <Skeleton key={i} height={48} />\n))}\n"
        }
      ]
    },
    {
      "name": "Slider",
      "slug": "slider",
      "package": "@helixui/core",
      "import": "import { Slider } from '@helixui/core'",
      "description": "A horizontal slider for a single value or a range. Pass an array `value`/`defaultValue` to get a range slider with two thumbs.",
      "category": "form",
      "tags": [
        "range",
        "value",
        "horizontal"
      ],
      "status": "stable",
      "since": "0.2.0",
      "layout": {
        "display": "block",
        "width": "fill",
        "height": "content",
        "intrinsicSize": "fills width, ~32px tall",
        "stackable": true,
        "fullBleed": false
      },
      "anatomy": "─────────●─────────────────  single thumb\n─────●═══════════●─────────  range (two thumbs)\n",
      "visual": "A horizontal track with a brand-filled portion under the thumb(s). Single thumb for one value; two thumbs for a range. Optional ticks and labels.\n",
      "props": [
        {
          "name": "label",
          "type": "ReactNode",
          "default": "",
          "description": "Visible label."
        },
        {
          "name": "showValue",
          "type": "boolean",
          "default": true,
          "description": "Render the formatted current value to the right of the label."
        },
        {
          "name": "value",
          "type": "number | number[]",
          "default": "",
          "description": "Controlled value(s)."
        },
        {
          "name": "defaultValue",
          "type": "number | number[]",
          "default": "",
          "description": "Uncontrolled initial value(s)."
        },
        {
          "name": "minValue",
          "type": "number",
          "default": 0,
          "description": "Min."
        },
        {
          "name": "maxValue",
          "type": "number",
          "default": 100,
          "description": "Max."
        },
        {
          "name": "step",
          "type": "number",
          "default": 1,
          "description": "Step."
        },
        {
          "name": "formatOptions",
          "type": "Intl.NumberFormatOptions",
          "default": "",
          "description": "Format the rendered output (percent, currency, units)."
        },
        {
          "name": "onChange",
          "type": "(value) => void",
          "default": "",
          "description": "Change handler."
        }
      ],
      "slots": [],
      "tokens": [
        "color.bg.surface.default",
        "color.bg.action.neutral.default",
        "color.bg.action.brand.default",
        "color.text.primary",
        "color.text.secondary",
        "color.text.muted",
        "color.border.focus",
        "radius.full",
        "space.2",
        "font.family.sans",
        "font.size.sm",
        "font.weight.medium",
        "shadow.sm"
      ],
      "a11y": {
        "keyboard": [
          {
            "key": "ArrowKeys",
            "action": "Step value."
          },
          {
            "key": "PageUp",
            "action": "Big step up."
          },
          {
            "key": "PageDown",
            "action": "Big step down."
          },
          {
            "key": "Home",
            "action": "Min."
          },
          {
            "key": "End",
            "action": "Max."
          }
        ]
      },
      "composes_with": [
        {
          "component": "Form",
          "relation": "parent",
          "note": "Submitted as part of a Form."
        },
        {
          "component": "Field",
          "relation": "wraps",
          "note": "Has built-in label/description."
        },
        {
          "component": "NumberField",
          "relation": "sibling"
        }
      ],
      "related": [
        "NumberField"
      ],
      "when_to_use": [],
      "pitfalls": [],
      "prompt_examples": [
        {
          "intent": "volume control",
          "prompt": "slider 0 to 100",
          "snippet": "<Slider label=\"Volume\" value={vol} onChange={setVol} minValue={0} maxValue={100} />\n"
        },
        {
          "intent": "price range",
          "prompt": "range slider for min/max price",
          "snippet": "<Slider label=\"Price\" value={range} onChange={setRange} minValue={0} maxValue={500} />\n"
        }
      ]
    },
    {
      "name": "Sparkline",
      "slug": "sparkline",
      "package": "@helixui/core",
      "import": "import { Sparkline } from '@helixui/core'",
      "description": "Tiny inline trend visualization rendered as pure SVG. No peer dependencies. Pairs with `<StatCard>` for KPI tiles, with `<List>` cells for per-row trends, or with `<Chart>` for full-size views.",
      "category": "data",
      "tags": [
        "mini-chart",
        "inline",
        "svg",
        "trend"
      ],
      "status": "stable",
      "since": "0.7.0",
      "layout": {
        "display": "inline-block",
        "width": "content",
        "height": "content",
        "intrinsicSize": "~80×24px (tunable)",
        "stackable": true,
        "fullBleed": false
      },
      "anatomy": "▁▂▃▅▆▇█▇▆▅▃▂▁    ← inline tiny chart\n",
      "visual": "A pure-SVG mini line/area chart with no axes or labels. Renders quickly inline next to a number. Tone (success/danger) tints the line per direction.\n",
      "props": [
        {
          "name": "data",
          "type": "number[]",
          "default": "—",
          "description": "Series of y-values. Indexes are the x positions."
        },
        {
          "name": "variant",
          "type": "'line' | 'area' | 'bar'",
          "default": "line",
          "description": "Render mode."
        },
        {
          "name": "tone",
          "type": "'brand' | 'success' | 'warning' | 'danger' | 'neutral' | 'auto' | string",
          "default": "auto",
          "description": "Color. `'auto'` picks success for upward, danger for downward, neutral for flat. Any CSS color is accepted."
        },
        {
          "name": "strokeWidth",
          "type": "number",
          "default": 1.5,
          "description": "Stroke width for line / area."
        },
        {
          "name": "width",
          "type": "number",
          "default": 96,
          "description": "Render width in px."
        },
        {
          "name": "height",
          "type": "number",
          "default": 28,
          "description": "Render height in px."
        },
        {
          "name": "showLast",
          "type": "boolean",
          "default": "true",
          "description": "Dot at the last point. Defaults true for line/area, false for bar."
        },
        {
          "name": "min",
          "type": "number",
          "default": "auto",
          "description": "Force min y. Defaults auto-fit with 10% pad."
        },
        {
          "name": "max",
          "type": "number",
          "default": "auto",
          "description": "Force max y. Defaults auto-fit with 10% pad."
        },
        {
          "name": "smooth",
          "type": "boolean",
          "default": true,
          "description": "Catmull-Rom smoothed curve for line/area."
        },
        {
          "name": "ariaLabel",
          "type": "string",
          "default": "—",
          "description": "When set, the SVG gains `role='img'` and is announced."
        }
      ],
      "slots": [],
      "tokens": [
        "color.bg.action.brand.default",
        "color.bg.action.success.default",
        "color.bg.action.warning.default",
        "color.bg.action.danger.default",
        "color.text.muted",
        "radius.sm"
      ],
      "a11y": {
        "notes": [
          "Decorative by default — pass `ariaLabel` to surface a description.",
          "Renders deterministically without animation; safe under `prefers-reduced-motion`."
        ]
      },
      "composes_with": [
        {
          "component": "StatCard",
          "relation": "child",
          "note": "Shown as the trend visualization in a StatCard."
        },
        {
          "component": "List",
          "relation": "child",
          "note": "Per-row trend in a list."
        },
        {
          "component": "Chart",
          "relation": "alternative",
          "note": "Use Chart for full-size data viz."
        }
      ],
      "related": [
        "Chart",
        "StatCard"
      ],
      "when_to_use": [],
      "pitfalls": [],
      "prompt_examples": [
        {
          "intent": "KPI trend line",
          "prompt": "tiny green sparkline for revenue",
          "snippet": "<Sparkline data={[1, 2, 3, 5, 4, 6, 8]} tone=\"success\" />\n"
        }
      ]
    },
    {
      "name": "Spinner",
      "slug": "spinner",
      "package": "@helixui/core",
      "import": "import { Spinner } from '@helixui/core'",
      "description": "An indeterminate loading indicator.",
      "category": "feedback",
      "tags": [
        "loading",
        "spinner",
        "indicator"
      ],
      "status": "stable",
      "since": "0.1.0",
      "layout": {
        "display": "inline-block",
        "width": "content",
        "height": "content",
        "intrinsicSize": "16/20/24/32px (sm/md/lg/xl)",
        "stackable": true,
        "fullBleed": false
      },
      "anatomy": "◐   ← rotating ring\n",
      "visual": "A circular progress ring with a rotating gap. Color follows currentColor. Animation respects prefers-reduced-motion.\n",
      "props": [
        {
          "name": "size",
          "type": "'sm' | 'md' | 'lg'",
          "default": "md",
          "description": "Visual size."
        },
        {
          "name": "tone",
          "type": "'current' | 'brand' | 'neutral'",
          "default": "current",
          "description": "Color. `current` inherits from CSS `color`."
        },
        {
          "name": "label",
          "type": "string",
          "default": "Loading",
          "description": "Accessible name announced by screen readers."
        }
      ],
      "slots": [],
      "tokens": [
        "color.text.action.brand",
        "color.text.muted"
      ],
      "a11y": {
        "role": "status",
        "notes": [
          "For determinate progress, use a different component (helixui does not yet ship one — use the native `<progress>` for now).",
          "Animation duration extends under `prefers-reduced-motion` rather than stopping outright; a frozen spinner suggests \"stuck\"."
        ]
      },
      "composes_with": [
        {
          "component": "Button",
          "relation": "child",
          "note": "Inside a Button when the action is in flight."
        },
        {
          "component": "ProgressBar",
          "relation": "alternative",
          "note": "ProgressBar when there is a known value or this takes long."
        },
        {
          "component": "Skeleton",
          "relation": "sibling"
        }
      ],
      "related": [
        "Skeleton"
      ],
      "when_to_use": [],
      "pitfalls": [],
      "prompt_examples": [
        {
          "intent": "loading indicator",
          "prompt": "small inline spinner",
          "snippet": "<Spinner size=\"sm\" />\n"
        }
      ]
    },
    {
      "name": "Stack",
      "slug": "stack",
      "package": "@helixui/core",
      "import": "import { Stack } from '@helixui/core'",
      "description": "Arrange children in a column (default) or row, with token-aware gap.",
      "category": "layout",
      "tags": [
        "primitive",
        "flex",
        "gap",
        "rhythm"
      ],
      "status": "stable",
      "since": "0.1.0",
      "layout": {
        "display": "flex",
        "width": "auto",
        "height": "auto",
        "intrinsicSize": "flex container; sized by children",
        "stackable": true,
        "fullBleed": false
      },
      "anatomy": "child\n  ↕ gap\nchild\n  ↕ gap\nchild\n",
      "visual": "An opinionated flex container. Default direction is column; pass `direction=\"row\"` for horizontal. Token-aware `gap` controls spacing between children.\n",
      "props": [
        {
          "name": "direction",
          "type": "'row' | 'column'",
          "default": "column",
          "description": "Stack direction. Replaces vapor-ui's HStack/VStack."
        },
        {
          "name": "align",
          "type": "'start' | 'center' | 'end' | 'stretch' | 'baseline'",
          "default": "stretch",
          "description": "Cross-axis alignment."
        },
        {
          "name": "justify",
          "type": "'start' | 'center' | 'end' | 'between' | 'around' | 'evenly'",
          "default": "start",
          "description": "Main-axis alignment."
        },
        {
          "name": "gap",
          "type": "number | string",
          "default": 4,
          "description": "Gap between children. Numeric → `space.N` token."
        },
        {
          "name": "wrap",
          "type": "boolean",
          "default": false,
          "description": "Allow wrapping."
        }
      ],
      "slots": [],
      "tokens": [
        "space.1",
        "space.2",
        "space.3",
        "space.4",
        "space.5",
        "space.6"
      ],
      "a11y": {
        "notes": [
          "Presentational. Use a semantic element via children."
        ]
      },
      "composes_with": [
        {
          "component": "Flex",
          "relation": "alternative",
          "note": "Flex when you need explicit align/justify control."
        },
        {
          "component": "Grid",
          "relation": "alternative",
          "note": "Grid for 2-D layout."
        },
        {
          "component": "Box",
          "relation": "sibling"
        }
      ],
      "related": [
        "Flex",
        "Grid",
        "Box"
      ],
      "when_to_use": [],
      "pitfalls": [],
      "prompt_examples": [
        {
          "intent": "vertical layout",
          "prompt": "vertical stack with 16px gap",
          "snippet": "<Stack gap={4}>{children}</Stack>\n"
        },
        {
          "intent": "right-aligned button row",
          "prompt": "horizontal stack with right alignment",
          "snippet": "<Stack direction=\"row\" justify=\"end\" gap={2}>{buttons}</Stack>\n"
        }
      ]
    },
    {
      "name": "StatCard",
      "slug": "stat-card",
      "package": "@helixui/core",
      "import": "import { StatCard } from '@helixui/core'",
      "description": "A KPI display — label, big value, a delta vs previous period, and an optional description line.",
      "category": "data",
      "tags": [
        "kpi",
        "metric",
        "tile",
        "dashboard"
      ],
      "status": "stable",
      "since": "0.2.0",
      "layout": {
        "display": "block",
        "width": "fill",
        "height": "content",
        "intrinsicSize": "fills available width, ~120-160px tall",
        "stackable": true,
        "fullBleed": false
      },
      "anatomy": "┌──────────────────────┐\n│  Label               │\n│  $12,840             │   ← big value\n│  ▲ +12.4%            │   ← delta\n│  vs last month       │   ← description\n│  ▁▂▃▅▆▇█             │   ← optional Sparkline\n└──────────────────────┘\n",
      "visual": "A Card-shaped KPI tile with a small label, a large numeric value (font.size.2xl+), a delta with directional arrow tinted by tone, and optional supporting description and Sparkline.\n",
      "props": [
        {
          "name": "label",
          "type": "ReactNode",
          "default": "",
          "description": "Metric name."
        },
        {
          "name": "value",
          "type": "ReactNode",
          "default": "",
          "description": "Big number — typically a string. Tabular-numerals are applied."
        },
        {
          "name": "description",
          "type": "ReactNode",
          "default": "",
          "description": "Small caption below the value."
        },
        {
          "name": "delta",
          "type": "string",
          "default": "",
          "description": "Signed delta string e.g. `+12.4%` or `-2`. Sign is parsed for color."
        },
        {
          "name": "trend",
          "type": "'up' | 'down' | 'flat'",
          "default": "",
          "description": "Override inferred trend."
        },
        {
          "name": "invertedTrend",
          "type": "boolean",
          "default": false,
          "description": "Lower is better (e.g. error rate). Flips up→bad, down→good."
        }
      ],
      "slots": [],
      "tokens": [
        "color.bg.surface.default",
        "color.border.default",
        "color.text.primary",
        "color.text.secondary",
        "color.text.muted",
        "color.text.action.success",
        "color.text.action.danger",
        "radius.lg",
        "space.1",
        "space.2",
        "space.4",
        "space.5",
        "font.family.sans",
        "font.size.xs",
        "font.size.sm",
        "font.size.3xl",
        "font.weight.medium",
        "font.weight.semibold",
        "font.weight.bold"
      ],
      "a11y": {
        "notes": [
          "Label/value/description are plain text. Pair multiple StatCards in a Grid for a KPI row.",
          "When using as a link or button, wrap or render the appropriate role inside."
        ]
      },
      "composes_with": [
        {
          "component": "Sparkline",
          "relation": "child",
          "note": "Trend visualization at the bottom."
        },
        {
          "component": "Card",
          "relation": "alternative",
          "note": "StatCard is opinionated; Card is generic."
        },
        {
          "component": "Grid",
          "relation": "parent",
          "note": "Common in a dashboard Grid."
        }
      ],
      "related": [
        "Card"
      ],
      "when_to_use": [],
      "pitfalls": [],
      "prompt_examples": [
        {
          "intent": "dashboard KPI",
          "prompt": "revenue KPI with +12.4% delta",
          "snippet": "<StatCard\n  label=\"Revenue\"\n  value=\"$12,840\"\n  delta={{ value: '+12.4%', tone: 'success' }}\n  description=\"vs last month\"\n/>\n"
        }
      ]
    },
    {
      "name": "Stepper",
      "slug": "stepper",
      "package": "@helixui/core",
      "import": "import { Stepper, type StepperStep } from '@helixui/core'",
      "description": "A horizontal or vertical sequence of steps with done / current / pending / failed status. Use for onboarding flows, multi-step forms, or check-out funnels.",
      "category": "navigation",
      "tags": [
        "steps",
        "wizard",
        "progress",
        "multi-step"
      ],
      "status": "stable",
      "since": "0.5.0",
      "layout": {
        "display": "flex",
        "width": "fill",
        "height": "content",
        "intrinsicSize": "horizontal or vertical, fills container",
        "stackable": false,
        "fullBleed": false
      },
      "anatomy": "(✓ done) ── (● current) ── (○ pending) ── (! failed)\n",
      "visual": "A row (or column) of circular step indicators connected by lines. Done shows a check on a brand fill; current is a brand ring; pending is muted; failed uses danger tone.\n",
      "props": [
        {
          "name": "steps",
          "type": "StepperStep[]",
          "default": "",
          "description": "Required. Each has `id`, `label`, optional `description` and explicit `status`."
        },
        {
          "name": "current",
          "type": "number",
          "default": "",
          "description": "Index of the current step. Auto-fills `status`: done before, current at, pending after."
        },
        {
          "name": "orientation",
          "type": "'horizontal' | 'vertical'",
          "default": "horizontal",
          "description": "Layout."
        }
      ],
      "slots": [],
      "tokens": [
        "color.bg.surface.default",
        "color.bg.action.brand.default",
        "color.bg.action.brand.subtle",
        "color.bg.action.danger.default",
        "color.border.default",
        "color.border.strong",
        "color.text.primary",
        "color.text.secondary",
        "color.text.muted",
        "color.text.on.brand",
        "color.text.on.danger",
        "space.1",
        "space.2",
        "space.3",
        "font.family.sans",
        "font.size.xs",
        "font.size.sm",
        "font.weight.medium",
        "font.weight.semibold"
      ],
      "a11y": {
        "notes": [
          "Renders as `<ol>`. The current step has `aria-current=\"step\"`.",
          "For onboarding, pair with focus management — focus the heading of the active step on mount."
        ]
      },
      "composes_with": [
        {
          "component": "Form",
          "relation": "sibling",
          "note": "Often above a multi-step Form."
        },
        {
          "component": "PinInput",
          "relation": "sibling"
        },
        {
          "component": "NumericKeypad",
          "relation": "sibling"
        }
      ],
      "related": [
        "PinInput",
        "NumericKeypad"
      ],
      "when_to_use": [],
      "pitfalls": [],
      "prompt_examples": [
        {
          "intent": "onboarding progress",
          "prompt": "3-step stepper, on step 2",
          "snippet": "<Stepper current={1} steps={[\n  { id: 'account', label: 'Account' },\n  { id: 'profile', label: 'Profile' },\n  { id: 'done', label: 'Finish' },\n]} />\n"
        }
      ]
    },
    {
      "name": "StreamingIndicator",
      "slug": "streaming-indicator",
      "package": "@helixui/core",
      "import": "import { StreamingIndicator } from '@helixui/core'",
      "description": "An inline marker placed at the end of streaming LLM text — blinking caret, pulsing block, or three dots.",
      "category": "chat",
      "tags": [
        "ai",
        "streaming",
        "caret",
        "inline"
      ],
      "status": "stable",
      "since": "0.3.0",
      "layout": {
        "display": "inline-block",
        "width": "content",
        "height": "content",
        "intrinsicSize": "~10px wide caret / ~16px dots",
        "stackable": false,
        "fullBleed": false
      },
      "anatomy": "…some streamed text▍   ← blinking caret at the end\n",
      "visual": "A small inline marker placed at the end of streaming text. Variants: blinking caret, pulsing block, or three dots.\n",
      "props": [
        {
          "name": "variant",
          "type": "'caret' | 'block' | 'dots'",
          "default": "block",
          "description": "Visual style."
        }
      ],
      "slots": [],
      "tokens": [
        "color.text.action.brand"
      ],
      "a11y": {
        "role": "status",
        "notes": [
          "The element has `aria-label=\\\"Streaming\\\"`. Animation respects `prefers-reduced-motion`."
        ]
      },
      "composes_with": [
        {
          "component": "ChatMessage",
          "relation": "child",
          "note": "Lives inside an in-flight assistant message."
        },
        {
          "component": "TypingIndicator",
          "relation": "alternative",
          "note": "TypingIndicator is shown while another participant types."
        },
        {
          "component": "ThinkingBlock",
          "relation": "sibling"
        }
      ],
      "related": [
        "ChatMessage",
        "ThinkingBlock"
      ],
      "when_to_use": [],
      "pitfalls": [],
      "prompt_examples": [
        {
          "intent": "show LLM streaming",
          "prompt": "caret at the end of streamed text",
          "snippet": "<>{text}<StreamingIndicator /></>\n"
        }
      ]
    },
    {
      "name": "SwipeableListItem",
      "slug": "swipeable-list-item",
      "package": "@helixui/core",
      "import": "import { SwipeableListItem, type SwipeAction } from '@helixui/core'",
      "description": "A list row that reveals leading or trailing actions when the user swipes left or right. Pass the row content as `children`; pass actions for either edge.",
      "category": "data",
      "tags": [
        "mobile",
        "gesture",
        "swipe",
        "row-actions"
      ],
      "status": "beta",
      "since": "0.5.0",
      "layout": {
        "display": "block",
        "width": "fill",
        "height": "content",
        "intrinsicSize": "fills width; row hugs content height",
        "stackable": true,
        "fullBleed": false
      },
      "anatomy": "← (Archive) ─── [ row content ] ─── (Delete) →\n",
      "visual": "A list row with hidden leading/trailing actions revealed by horizontal swipe. Snaps open or closed; release past threshold triggers the action.\n",
      "props": [
        {
          "name": "leadingActions",
          "type": "SwipeAction[]",
          "default": "[]",
          "description": "Actions revealed by left-to-right swipe."
        },
        {
          "name": "trailingActions",
          "type": "SwipeAction[]",
          "default": "[]",
          "description": "Actions revealed by right-to-left swipe."
        },
        {
          "name": "commitThreshold",
          "type": "number",
          "default": 120,
          "description": "Pixel distance past which release commits the first action on that side."
        },
        {
          "name": "actionWidth",
          "type": "number",
          "default": 80,
          "description": "Width (px) of one action button."
        }
      ],
      "slots": [
        "children — the list row content"
      ],
      "tokens": [
        "color.bg.surface.default",
        "color.bg.action.neutral.default",
        "color.bg.action.brand.default",
        "color.bg.action.danger.default",
        "color.bg.action.success.default",
        "color.bg.action.warning.default",
        "color.text.primary",
        "color.text.on.brand",
        "color.text.on.danger",
        "color.text.on.success",
        "color.text.on.warning",
        "font.family.sans",
        "font.size.xs",
        "font.weight.medium"
      ],
      "a11y": {
        "notes": [
          "Pointer-event-driven (works with mouse and touch). On keyboard-only flows, the swipe affordance is hidden — pair with a Menu / context affordance for keyboard parity.",
          "Snaps open to the first action when released past `actionWidth/2`; commits the first action when released past `commitThreshold`.",
          "For destructive actions, set `tone=\"danger\"` AND require explicit confirmation (an extra prompt) — accidental swipes happen."
        ]
      },
      "composes_with": [
        {
          "component": "List",
          "relation": "parent",
          "note": "Used as List items on mobile."
        },
        {
          "component": "ActionSheet",
          "relation": "sibling"
        },
        {
          "component": "Menu",
          "relation": "sibling"
        }
      ],
      "related": [
        "List",
        "ActionSheet",
        "Menu"
      ],
      "when_to_use": [],
      "pitfalls": [],
      "prompt_examples": [
        {
          "intent": "swipe to archive or delete",
          "prompt": "left action archive, right action delete",
          "snippet": "<SwipeableListItem\n  trailingActions={[{ id: 'del', label: 'Delete', tone: 'danger', onPress: del }]}\n  leadingActions={[{ id: 'arc', label: 'Archive', onPress: archive }]}\n>\n  Row content\n</SwipeableListItem>\n"
        }
      ]
    },
    {
      "name": "Switch",
      "slug": "switch",
      "package": "@helixui/core",
      "import": "import { Switch } from '@helixui/core'",
      "description": "A two-state toggle. Use when a setting takes effect immediately; use Checkbox in forms.",
      "category": "form",
      "tags": [
        "toggle",
        "on-off",
        "setting"
      ],
      "status": "stable",
      "since": "0.1.0",
      "layout": {
        "display": "inline-flex",
        "width": "content",
        "height": "content",
        "intrinsicSize": "~32×20 toggle + label",
        "stackable": true,
        "fullBleed": false
      },
      "anatomy": "(○──)   off\n(──●)   on (filled brand)\n",
      "visual": "A pill-shaped track with a sliding circular knob. Off uses neutral track; on uses brand-filled track. Animates the knob with a soft transition.\n",
      "props": [
        {
          "name": "isSelected",
          "type": "boolean",
          "default": false,
          "description": "Controlled state."
        },
        {
          "name": "defaultSelected",
          "type": "boolean",
          "default": false,
          "description": "Uncontrolled initial state."
        },
        {
          "name": "isDisabled",
          "type": "boolean",
          "default": false,
          "description": "Disables interaction."
        },
        {
          "name": "onChange",
          "type": "(isSelected: boolean) => void",
          "default": "",
          "description": "Change handler."
        },
        {
          "name": "...rest",
          "type": "SwitchProps from react-aria-components",
          "default": "",
          "description": "All forwarded."
        }
      ],
      "slots": [
        "children — visible label text"
      ],
      "tokens": [
        "color.bg.action.neutral.active",
        "color.bg.action.brand.default",
        "color.text.primary",
        "color.border.focus",
        "color.white",
        "radius.full",
        "space.2",
        "shadow.sm",
        "font.family.sans",
        "font.size.sm"
      ],
      "a11y": {
        "role": "switch",
        "keyboard": [
          {
            "key": "Space",
            "action": "Toggles the switch."
          },
          {
            "key": "Enter",
            "action": "Toggles the switch."
          }
        ],
        "notes": [
          "Use Switch for instant changes (mute audio, dark mode). Use Checkbox for opt-ins inside forms."
        ]
      },
      "composes_with": [
        {
          "component": "Field",
          "relation": "wraps",
          "note": "Wrap if you need separate label/description structure."
        },
        {
          "component": "Checkbox",
          "relation": "alternative",
          "note": "Checkbox for forms; Switch for instant settings."
        }
      ],
      "related": [
        "Checkbox"
      ],
      "when_to_use": [],
      "pitfalls": [],
      "prompt_examples": [
        {
          "intent": "instant setting toggle",
          "prompt": "switch for \"Enable notifications\"",
          "snippet": "<Switch isSelected={on} onChange={setOn}>Enable notifications</Switch>\n"
        }
      ]
    },
    {
      "name": "Table",
      "slug": "table",
      "package": "@helixui/core",
      "import": "import { Table, TableHeader, TableBody, Row, Column, Cell } from '@helixui/core'",
      "description": "An interactive data table with selection, sorting, keyboard navigation, and a screen-reader-friendly grid.",
      "category": "data",
      "tags": [
        "grid",
        "rows",
        "columns",
        "sortable",
        "selectable"
      ],
      "status": "stable",
      "since": "0.1.0",
      "layout": {
        "display": "block",
        "width": "fill",
        "height": "content",
        "intrinsicSize": "fills width, scrolls horizontally on overflow",
        "stackable": false,
        "fullBleed": false
      },
      "anatomy": "┌─ Header  Header  Header ─┐\n├──────────────────────────┤\n│  cell    cell    cell    │\n│  cell    cell    cell    │\n│  cell    cell    cell    │\n└──────────────────────────┘\n",
      "visual": "A row × column grid with a sticky header, hairline row dividers, and zebra hover. Sortable columns show a chevron when active. Selectable rows show a leading checkbox column.\n",
      "props": [
        {
          "name": "selectionMode",
          "type": "'none' | 'single' | 'multiple'",
          "default": "none",
          "description": "Row selection mode."
        },
        {
          "name": "selectionBehavior",
          "type": "'replace' | 'toggle'",
          "default": "replace",
          "description": "How rows are selected."
        },
        {
          "name": "sortDescriptor",
          "type": "SortDescriptor",
          "default": "",
          "description": "Controlled sort state."
        },
        {
          "name": "onSortChange",
          "type": "(d: SortDescriptor) => void",
          "default": "",
          "description": "Sort change handler."
        }
      ],
      "slots": [
        "Table children — TableHeader + TableBody",
        "Column children — header label",
        "Cell children — cell content"
      ],
      "tokens": [
        "color.bg.surface.subtle",
        "color.bg.action.brand.subtle",
        "color.border.default",
        "color.border.focus",
        "color.text.primary",
        "color.text.secondary",
        "space.3",
        "space.4",
        "font.family.sans",
        "font.size.sm",
        "font.size.xs",
        "font.weight.semibold"
      ],
      "a11y": {
        "role": "grid",
        "keyboard": [
          {
            "key": "ArrowKeys",
            "action": "Move focus between cells."
          },
          {
            "key": "Space",
            "action": "Toggle row selection."
          },
          {
            "key": "Cmd/Ctrl+A",
            "action": "Select all (when `selectionMode=multiple`)."
          }
        ]
      },
      "composes_with": [
        {
          "component": "FloatingBar",
          "relation": "sibling",
          "note": "Use over a Table when rows are selected."
        },
        {
          "component": "Pagination",
          "relation": "sibling",
          "note": "Below the Table."
        },
        {
          "component": "EmptyState",
          "relation": "alternative",
          "note": "When no rows."
        }
      ],
      "related": [
        "Pagination"
      ],
      "when_to_use": [],
      "pitfalls": [],
      "prompt_examples": [
        {
          "intent": "sortable user table",
          "prompt": "three-column table with sort and selection",
          "snippet": "<Table selectionMode=\"multiple\" onSortChange={setSort}>\n  <TableHeader>\n    <Column id=\"name\" allowsSorting>Name</Column>\n    <Column id=\"email\">Email</Column>\n    <Column id=\"role\">Role</Column>\n  </TableHeader>\n  <TableBody>\n    {rows.map(r => (\n      <Row key={r.id}><Cell>{r.name}</Cell><Cell>{r.email}</Cell><Cell>{r.role}</Cell></Row>\n    ))}\n  </TableBody>\n</Table>\n"
        }
      ]
    },
    {
      "name": "Tabs",
      "slug": "tabs",
      "package": "@helixui/core",
      "import": "import { Tabs, TabList, Tab, TabPanel } from '@helixui/core'",
      "description": "Switch between related views without navigating away.",
      "category": "navigation",
      "tags": [
        "sections",
        "switch",
        "in-page"
      ],
      "status": "stable",
      "since": "0.1.0",
      "layout": {
        "display": "block",
        "width": "fill",
        "height": "content",
        "intrinsicSize": "tab strip + panel; panel sized by content",
        "stackable": false,
        "fullBleed": false
      },
      "anatomy": "[ Tab ][ Tab ][ Tab* ]\n──────────────────────\n  panel content\n",
      "visual": "A horizontal tab strip with an underline indicator under the active tab, followed by the active panel below. Hover/focus tabs lighten with surface tint.\n",
      "props": [
        {
          "name": "variant",
          "type": "'underline' | 'pill'",
          "default": "underline",
          "description": "Visual style. `pill` reads as a SegmentedControl with panels."
        },
        {
          "name": "orientation",
          "type": "'horizontal' | 'vertical'",
          "default": "horizontal",
          "description": "Layout."
        },
        {
          "name": "selectedKey",
          "type": "Key",
          "default": "",
          "description": "Controlled selection."
        },
        {
          "name": "defaultSelectedKey",
          "type": "Key",
          "default": "",
          "description": "Uncontrolled initial."
        },
        {
          "name": "onSelectionChange",
          "type": "(key: Key) => void",
          "default": "",
          "description": "Change handler."
        }
      ],
      "slots": [
        "Tabs children — TabList + TabPanels",
        "TabList children — Tab components",
        "Tab children — label",
        "TabPanel children — panel content; one per Tab id"
      ],
      "tokens": [
        "color.bg.surface.default",
        "color.bg.action.neutral.default",
        "color.bg.action.brand.default",
        "color.text.primary",
        "color.text.secondary",
        "color.text.action.brand",
        "color.border.default",
        "color.border.focus",
        "radius.md",
        "space.1",
        "space.2",
        "space.3",
        "space.4",
        "font.family.sans",
        "font.size.sm",
        "font.weight.medium",
        "shadow.sm"
      ],
      "a11y": {
        "role": "tablist",
        "keyboard": [
          {
            "key": "ArrowLeft",
            "action": "Previous tab (horizontal)."
          },
          {
            "key": "ArrowRight",
            "action": "Next tab (horizontal)."
          },
          {
            "key": "Home",
            "action": "First tab."
          },
          {
            "key": "End",
            "action": "Last tab."
          }
        ]
      },
      "composes_with": [
        {
          "component": "SegmentedControl",
          "relation": "alternative",
          "note": "SegmentedControl for compact view-mode pickers."
        },
        {
          "component": "Tab",
          "relation": "child",
          "note": "Each tab."
        },
        {
          "component": "TabPanel",
          "relation": "child",
          "note": "Each panel."
        }
      ],
      "related": [
        "SegmentedControl"
      ],
      "when_to_use": [],
      "pitfalls": [],
      "prompt_examples": [
        {
          "intent": "in-page sections",
          "prompt": "three-tab interface for Overview/Activity/Settings",
          "snippet": "<Tabs>\n  <TabList>\n    <Tab id=\"o\">Overview</Tab>\n    <Tab id=\"a\">Activity</Tab>\n    <Tab id=\"s\">Settings</Tab>\n  </TabList>\n  <TabPanel id=\"o\">…</TabPanel>\n  <TabPanel id=\"a\">…</TabPanel>\n  <TabPanel id=\"s\">…</TabPanel>\n</Tabs>\n"
        }
      ]
    },
    {
      "name": "Text",
      "slug": "text",
      "package": "@helixui/core",
      "import": "import { Text } from '@helixui/core'",
      "description": "Typography primitive — render any element with token-driven size, weight, tone, alignment.",
      "category": "primitive",
      "tags": [
        "typography",
        "text",
        "inline"
      ],
      "status": "stable",
      "since": "0.1.0",
      "layout": {
        "display": "inline",
        "width": "auto",
        "height": "auto",
        "intrinsicSize": "as configured by element",
        "stackable": true,
        "fullBleed": false
      },
      "anatomy": "Inline or block text with token sizes/weights/tones\n",
      "visual": "Renders as any element (default `<span>`). Props expose font.size, font.weight, color tone, alignment.\n",
      "props": [
        {
          "name": "as",
          "type": "ElementType",
          "default": "span",
          "description": "Element to render."
        },
        {
          "name": "size",
          "type": "'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' | '3xl' | '4xl'",
          "default": "md",
          "description": "Maps to `font.size.*` tokens."
        },
        {
          "name": "weight",
          "type": "'regular' | 'medium' | 'semibold' | 'bold'",
          "default": "",
          "description": "Maps to `font.weight.*` tokens."
        },
        {
          "name": "tone",
          "type": "'primary' | 'secondary' | 'muted' | 'inverse' | 'brand' | 'danger' | 'success' | 'warning'",
          "default": "primary",
          "description": "Color tone."
        },
        {
          "name": "align",
          "type": "'start' | 'center' | 'end'",
          "default": "",
          "description": "Text alignment."
        },
        {
          "name": "truncate",
          "type": "boolean",
          "default": false,
          "description": "Single-line truncation with ellipsis."
        }
      ],
      "slots": [],
      "tokens": [
        "font.size.xs",
        "font.size.sm",
        "font.size.md",
        "font.size.lg",
        "font.size.xl",
        "font.size.2xl",
        "font.size.3xl",
        "font.size.4xl",
        "font.weight.regular",
        "font.weight.medium",
        "font.weight.semibold",
        "font.weight.bold",
        "color.text.primary",
        "color.text.secondary",
        "color.text.muted",
        "color.text.action.brand",
        "color.text.action.danger",
        "color.text.action.success",
        "color.text.action.warning"
      ],
      "a11y": {
        "notes": [
          "Use `as` to render the correct semantic element. `<Text as=\"h1\" size=\"3xl\">` for page titles.",
          "Do not rely on size alone for hierarchy — use the right heading element."
        ]
      },
      "composes_with": [
        {
          "component": "Stack",
          "relation": "parent",
          "note": "Often inside a Stack."
        },
        {
          "component": "Card",
          "relation": "parent",
          "note": "Body content of a Card."
        }
      ],
      "related": [],
      "when_to_use": [],
      "pitfalls": [],
      "prompt_examples": [
        {
          "intent": "muted helper text",
          "prompt": "small muted helper line",
          "snippet": "<Text size=\"sm\" tone=\"muted\">Helper text</Text>\n"
        }
      ]
    },
    {
      "name": "TextInput",
      "slug": "text-input",
      "package": "@helixui/core",
      "import": "import { TextInput } from '@helixui/core'",
      "description": "A single-line text input with built-in label, description, error, and prefix/suffix slots.",
      "category": "form",
      "tags": [
        "input",
        "text",
        "single-line"
      ],
      "status": "stable",
      "since": "0.1.0",
      "layout": {
        "display": "block",
        "width": "fill",
        "height": "content",
        "intrinsicSize": "fills width, ~36-44px tall",
        "stackable": true,
        "fullBleed": false
      },
      "anatomy": "Label\n[ prefix | text input | suffix ]\nHelp / error\n",
      "visual": "A single-line input with built-in label, description, error, and prefix/suffix slots for icons or units.\n",
      "props": [
        {
          "name": "label",
          "type": "ReactNode",
          "default": "",
          "description": "Visible label rendered above the input."
        },
        {
          "name": "description",
          "type": "ReactNode",
          "default": "",
          "description": "Helper text below the input."
        },
        {
          "name": "errorMessage",
          "type": "string | (v: ValidationResult) => string",
          "default": "",
          "description": "Error message below the input. Can be a function for built-in `validate` results."
        },
        {
          "name": "placeholder",
          "type": "string",
          "default": "",
          "description": "Placeholder text."
        },
        {
          "name": "size",
          "type": "'sm' | 'md' | 'lg'",
          "default": "md",
          "description": "Control height."
        },
        {
          "name": "prefix",
          "type": "ReactNode",
          "default": "",
          "description": "Inline content before the input — icon or static label."
        },
        {
          "name": "suffix",
          "type": "ReactNode",
          "default": "",
          "description": "Inline content after the input."
        },
        {
          "name": "isRequired",
          "type": "boolean",
          "default": false,
          "description": "Marks the field required for validation."
        },
        {
          "name": "isInvalid",
          "type": "boolean",
          "default": false,
          "description": "Forces the invalid state."
        },
        {
          "name": "isDisabled",
          "type": "boolean",
          "default": false,
          "description": "Disables the input."
        },
        {
          "name": "...rest",
          "type": "TextFieldProps from react-aria-components",
          "default": "",
          "description": "Forwarded — value/defaultValue/onChange/onBlur/etc."
        }
      ],
      "slots": [],
      "tokens": [
        "color.bg.surface.default",
        "color.bg.surface.muted",
        "color.border.default",
        "color.border.focus",
        "color.border.danger",
        "color.text.primary",
        "color.text.secondary",
        "color.text.muted",
        "color.text.action.danger",
        "radius.md",
        "space.2",
        "space.3",
        "font.family.sans",
        "font.size.sm",
        "font.size.md",
        "font.size.lg",
        "font.weight.medium"
      ],
      "a11y": {
        "notes": [
          "Built on react-aria-components TextField — keyboard, screen-reader, and validation are handled.",
          "Pass `label` instead of relying on `placeholder` for accessibility."
        ]
      },
      "composes_with": [
        {
          "component": "Form",
          "relation": "parent",
          "note": "Inside Form."
        },
        {
          "component": "InputGroup",
          "relation": "parent",
          "note": "Compose with Buttons via InputGroup."
        },
        {
          "component": "NumberField",
          "relation": "alternative",
          "note": "NumberField for numbers."
        },
        {
          "component": "Textarea",
          "relation": "alternative",
          "note": "Textarea for multi-line."
        },
        {
          "component": "Field",
          "relation": "sibling"
        }
      ],
      "related": [
        "Textarea",
        "InputGroup",
        "Field"
      ],
      "when_to_use": [],
      "pitfalls": [],
      "prompt_examples": [
        {
          "intent": "simple text field",
          "prompt": "email input with placeholder",
          "snippet": "<TextInput label=\"Email\" placeholder=\"you@example.com\" value={email} onChange={setEmail} />\n"
        },
        {
          "intent": "with leading icon",
          "prompt": "search input with magnifying glass prefix",
          "snippet": "<TextInput label=\"Search\" prefix={<SearchIcon />} value={q} onChange={setQ} />\n"
        }
      ]
    },
    {
      "name": "Textarea",
      "slug": "textarea",
      "package": "@helixui/core",
      "import": "import { Textarea } from '@helixui/core'",
      "description": "A multi-line text input with optional label, description, and error.",
      "category": "form",
      "tags": [
        "multi-line",
        "input",
        "text"
      ],
      "status": "stable",
      "since": "0.1.0",
      "layout": {
        "display": "block",
        "width": "fill",
        "height": "content",
        "intrinsicSize": "fills width, default 4 rows",
        "stackable": true,
        "fullBleed": false
      },
      "anatomy": "Label\n┌──────────────────────────┐\n│                          │\n│  multi-line input        │\n│                          │\n└──────────────────────────┘\nHelp / error\n",
      "visual": "A multi-line text input wrapped with built-in label, description, and error message. Resizable vertically by default.\n",
      "props": [
        {
          "name": "label",
          "type": "ReactNode",
          "default": "",
          "description": "Visible label."
        },
        {
          "name": "description",
          "type": "ReactNode",
          "default": "",
          "description": "Helper text."
        },
        {
          "name": "errorMessage",
          "type": "string | (v: ValidationResult) => string",
          "default": "",
          "description": "Error message."
        },
        {
          "name": "placeholder",
          "type": "string",
          "default": "",
          "description": "Placeholder."
        },
        {
          "name": "rows",
          "type": "number",
          "default": 4,
          "description": "Initial visible rows."
        },
        {
          "name": "resize",
          "type": "'none' | 'vertical' | 'horizontal' | 'both'",
          "default": "vertical",
          "description": "User resize affordance."
        },
        {
          "name": "...rest",
          "type": "TextFieldProps",
          "default": "",
          "description": "Forwarded to react-aria's TextField."
        }
      ],
      "slots": [],
      "tokens": [
        "color.bg.surface.default",
        "color.bg.surface.muted",
        "color.border.default",
        "color.border.focus",
        "color.border.danger",
        "color.text.primary",
        "color.text.secondary",
        "color.text.muted",
        "color.text.action.danger",
        "radius.md",
        "space.2",
        "space.3",
        "font.family.sans",
        "font.size.sm",
        "font.size.md",
        "font.weight.medium",
        "font.lineHeight.normal"
      ],
      "a11y": {
        "notes": [
          "Built on react-aria-components TextField."
        ]
      },
      "composes_with": [
        {
          "component": "Form",
          "relation": "parent",
          "note": "Inside Form."
        },
        {
          "component": "TextInput",
          "relation": "alternative",
          "note": "TextInput for single-line."
        },
        {
          "component": "RichTextEditor",
          "relation": "alternative",
          "note": "RichTextEditor for formatted content."
        },
        {
          "component": "Field",
          "relation": "sibling"
        }
      ],
      "related": [
        "TextInput",
        "Field"
      ],
      "when_to_use": [],
      "pitfalls": [],
      "prompt_examples": [
        {
          "intent": "comment box",
          "prompt": "multi-line comment input",
          "snippet": "<Textarea label=\"Comment\" rows={4} value={c} onChange={setC} />\n"
        }
      ]
    },
    {
      "name": "ThemeProvider",
      "slug": "theme-provider",
      "package": "@helixui/core",
      "import": "import { ThemeProvider, useTheme } from '@helixui/core'",
      "description": "Sets the current theme. HelixUI tokens are scoped to `[data-theme=\\\"light\\\"|\\\"dark\\\"]`; ThemeProvider applies that attribute and exposes a `useTheme` hook.",
      "category": "shell",
      "tags": [
        "theme",
        "light",
        "dark",
        "provider"
      ],
      "status": "stable",
      "since": "0.1.0",
      "layout": {
        "display": "block",
        "width": "auto",
        "height": "auto",
        "intrinsicSize": "unstyled wrapper; sets data-theme on root",
        "stackable": true,
        "fullBleed": false
      },
      "anatomy": "<ThemeProvider theme=\"dark\">\n  ⟨all components inherit data-theme=dark⟩\n</ThemeProvider>\n",
      "visual": "A presentational wrapper that toggles `data-theme=\"light\"` or `data-theme=\"dark\"` on a wrapping element. All helixui tokens are scoped to that attribute.\n",
      "props": [
        {
          "name": "theme",
          "type": "'light' | 'dark'",
          "default": "",
          "description": "Controlled theme."
        },
        {
          "name": "defaultTheme",
          "type": "'light' | 'dark'",
          "default": "light",
          "description": "Initial theme when uncontrolled."
        },
        {
          "name": "rootElement",
          "type": "'document' | 'wrapper'",
          "default": "document",
          "description": "Where to apply `data-theme`. `document` writes to `<html>`. `wrapper` renders a div."
        },
        {
          "name": "onChange",
          "type": "(theme: Theme) => void",
          "default": "",
          "description": "Theme change handler."
        }
      ],
      "slots": [
        "children — your app"
      ],
      "tokens": [
        "color.text.primary",
        "color.bg.surface.default"
      ],
      "a11y": {
        "notes": [
          "Theme switch should respect `prefers-color-scheme` on first load — wire that into your `defaultTheme`.",
          "Avoid mounting two ThemeProviders with different themes; tokens cascade by attribute."
        ]
      },
      "composes_with": [
        {
          "component": "HelixUIDNAProvider",
          "relation": "child",
          "note": "DNA tunes the genome inside a chosen theme."
        }
      ],
      "related": [],
      "when_to_use": [],
      "pitfalls": [],
      "prompt_examples": [
        {
          "intent": "toggle dark mode",
          "prompt": "wrap the app for theme switching",
          "snippet": "<ThemeProvider theme={theme}>\n  <App />\n</ThemeProvider>\n"
        }
      ]
    },
    {
      "name": "ThinkingBlock",
      "slug": "thinking-block",
      "package": "@helixui/core",
      "import": "import { ThinkingBlock } from '@helixui/core'",
      "description": "A collapsed reasoning / chain-of-thought block. Use to present an LLM's intermediate thought process in a non-distracting way.",
      "category": "chat",
      "tags": [
        "ai",
        "reasoning",
        "chain-of-thought",
        "collapsible"
      ],
      "status": "stable",
      "since": "0.3.0",
      "layout": {
        "display": "block",
        "width": "fill",
        "height": "content",
        "intrinsicSize": "fills width, hugs content",
        "stackable": true,
        "fullBleed": false
      },
      "anatomy": "[ ▶ Thinking…           ]   ← collapsed\n[ ▼ Thinking…           ]\n     reasoning paragraph 1\n     reasoning paragraph 2\n",
      "visual": "A muted card with a small \"Thinking…\" header and a collapsible body. Used to show LLM internal reasoning without making it the main attraction.\n",
      "props": [
        {
          "name": "label",
          "type": "ReactNode",
          "default": "",
          "description": "Override the header label. Default depends on `thinking`/`duration`."
        },
        {
          "name": "thinking",
          "type": "boolean",
          "default": false,
          "description": "While true, shows a pulsing dot and the brand-colored rule."
        },
        {
          "name": "duration",
          "type": "ReactNode",
          "default": "",
          "description": "Append a duration to the default 'Thought' label (e.g. '4s')."
        },
        {
          "name": "defaultOpen",
          "type": "boolean",
          "default": false,
          "description": "Initially expanded."
        },
        {
          "name": "open",
          "type": "boolean",
          "default": "",
          "description": "Controlled state."
        },
        {
          "name": "onOpenChange",
          "type": "(open) => void",
          "default": "",
          "description": "Change handler."
        }
      ],
      "slots": [
        "children — the reasoning text (whitespace preserved)"
      ],
      "tokens": [
        "color.bg.action.brand.default",
        "color.border.default",
        "color.border.focus",
        "color.text.secondary",
        "color.text.muted",
        "radius.sm",
        "space.1",
        "space.2",
        "space.3",
        "font.family.sans",
        "font.size.sm"
      ],
      "a11y": {
        "notes": [
          "Header button has `aria-expanded`. While `thinking` the pulsing dot animates; respect `prefers-reduced-motion` if you bring custom motion."
        ]
      },
      "composes_with": [
        {
          "component": "ChatMessage",
          "relation": "child",
          "note": "Inside an assistant message."
        },
        {
          "component": "ToolCall",
          "relation": "sibling",
          "note": "Often appears next to ToolCall blocks."
        }
      ],
      "related": [
        "ToolCall",
        "ChatMessage"
      ],
      "when_to_use": [],
      "pitfalls": [],
      "prompt_examples": [
        {
          "intent": "expose chain-of-thought",
          "prompt": "collapsible reasoning block in a chat",
          "snippet": "<ThinkingBlock summary=\"Planning the response\">\n  Step 1: identify the question.\n  Step 2: gather facts…\n</ThinkingBlock>\n"
        }
      ]
    },
    {
      "name": "Toast",
      "slug": "toast",
      "package": "@helixui/core",
      "import": "import { ToastProvider, toast } from '@helixui/core'",
      "description": "Transient messages that announce a background result. Mount `<ToastProvider />` once; call `toast.success(...)` from anywhere.",
      "category": "feedback",
      "tags": [
        "transient",
        "notification",
        "pop-up"
      ],
      "status": "beta",
      "since": "0.1.0",
      "layout": {
        "display": "fixed",
        "width": "content",
        "height": "content",
        "intrinsicSize": "corner-anchored, ~360px wide",
        "stackable": true,
        "fullBleed": false
      },
      "anatomy": "┌─────────────────────────┐\n│ ✓ Saved.                │   ← stacks bottom-right\n└─────────────────────────┘\n",
      "visual": "A small surface in a viewport corner, tinted by tone (success/info/warning/danger), auto-dismissing after a timeout. Stacks vertically when multiple are visible.\n",
      "props": [
        {
          "name": "title",
          "type": "string",
          "default": "",
          "description": "Primary message. Required."
        },
        {
          "name": "description",
          "type": "string",
          "default": "",
          "description": "Optional second line."
        },
        {
          "name": "tone",
          "type": "'neutral' | 'info' | 'success' | 'warning' | 'danger'",
          "default": "neutral",
          "description": "Color intent. Drives the left border color."
        }
      ],
      "slots": [],
      "tokens": [
        "color.bg.surface.default",
        "color.bg.action.neutral.default",
        "color.bg.action.brand.default",
        "color.bg.action.success.default",
        "color.bg.action.warning.default",
        "color.bg.action.danger.default",
        "color.border.default",
        "color.border.focus",
        "color.text.primary",
        "color.text.secondary",
        "radius.md",
        "radius.sm",
        "space.2",
        "space.3",
        "space.4",
        "font.family.sans",
        "font.size.sm",
        "font.weight.semibold",
        "shadow.md"
      ],
      "a11y": {
        "role": "status",
        "notes": [
          "Built on react-aria-components' UNSTABLE_Toast queue (the only API path while toast is stabilising). Do not stack multiple `<ToastProvider/>` instances.",
          "Tones use color borders + accessible icons (caller-supplied) — never rely on color alone.",
          "Toasts pause on focus and pointer hover. Hovered or focused toasts will not auto-dismiss."
        ]
      },
      "composes_with": [
        {
          "component": "Banner",
          "relation": "alternative",
          "note": "Banner for persistent; Toast for transient."
        },
        {
          "component": "Callout",
          "relation": "sibling"
        }
      ],
      "related": [
        "Callout"
      ],
      "when_to_use": [],
      "pitfalls": [],
      "prompt_examples": [
        {
          "intent": "save confirmation",
          "prompt": "show a green toast saying Saved",
          "snippet": "toast.success('Saved.')\n"
        },
        {
          "intent": "error",
          "prompt": "red error toast",
          "snippet": "toast.error('Could not save.')\n"
        }
      ]
    },
    {
      "name": "ToolCall",
      "slug": "tool-call",
      "package": "@helixui/core",
      "import": "import { ToolCall } from '@helixui/core'",
      "description": "A collapsible card representing a single tool / function call from an LLM — name, status, optional summary line, and expandable input / output sections.",
      "category": "chat",
      "tags": [
        "ai",
        "function-call",
        "collapsible",
        "tool"
      ],
      "status": "stable",
      "since": "0.3.0",
      "layout": {
        "display": "block",
        "width": "fill",
        "height": "content",
        "intrinsicSize": "fills width, hugs content",
        "stackable": true,
        "fullBleed": false
      },
      "anatomy": "[ ▶ get_weather   running ]\n[ ▼ get_weather   ok       ]\n     input:  { city: \"Seoul\" }\n     output: { temp: 17 }\n",
      "visual": "A collapsible card showing a tool name, status pill (running / ok / error), an optional one-line summary, and expandable input/output sections rendered as code.\n",
      "props": [
        {
          "name": "name",
          "type": "ReactNode",
          "default": "",
          "description": "Tool name (e.g. `web_search`). Required."
        },
        {
          "name": "status",
          "type": "'running' | 'done' | 'failed'",
          "default": "done",
          "description": "Current state. `running` shows a pulsing dot."
        },
        {
          "name": "summary",
          "type": "ReactNode",
          "default": "",
          "description": "One-line argument summary, shown next to the name when collapsed (e.g. the JSON args, single-line)."
        },
        {
          "name": "defaultOpen",
          "type": "boolean",
          "default": false,
          "description": "Initially expanded."
        },
        {
          "name": "open",
          "type": "boolean",
          "default": "",
          "description": "Controlled open."
        },
        {
          "name": "onOpenChange",
          "type": "(open) => void",
          "default": "",
          "description": "Open change handler."
        },
        {
          "name": "input",
          "type": "ReactNode",
          "default": "",
          "description": "Slot for input args — typically `<CodeBlock language=\"json\" />`."
        },
        {
          "name": "output",
          "type": "ReactNode",
          "default": "",
          "description": "Slot for the result — text, table, or another CodeBlock."
        }
      ],
      "slots": [
        "children — extra body content rendered after `output`"
      ],
      "tokens": [
        "color.bg.surface.default",
        "color.bg.surface.subtle",
        "color.bg.action.brand.subtle",
        "color.bg.action.success.subtle",
        "color.bg.action.danger.subtle",
        "color.border.default",
        "color.border.focus",
        "color.text.primary",
        "color.text.secondary",
        "color.text.muted",
        "color.text.action.brand",
        "color.text.action.success",
        "color.text.action.danger",
        "radius.md",
        "radius.full",
        "space.2",
        "space.3",
        "font.family.sans",
        "font.family.mono",
        "font.size.xs",
        "font.size.sm",
        "font.weight.medium",
        "font.weight.semibold"
      ],
      "a11y": {
        "notes": [
          "The header button has `aria-expanded` reflecting the disclosure state.",
          "Use inside a ChatMessage's `footer` slot to attach tool calls to a specific assistant turn."
        ]
      },
      "composes_with": [
        {
          "component": "ChatMessage",
          "relation": "child",
          "note": "Inside an assistant message."
        },
        {
          "component": "CodeBlock",
          "relation": "child",
          "note": "Input/output rendered as CodeBlocks."
        },
        {
          "component": "ThinkingBlock",
          "relation": "sibling",
          "note": "Often interleaved with reasoning."
        }
      ],
      "related": [
        "ChatMessage",
        "CodeBlock",
        "ThinkingBlock"
      ],
      "when_to_use": [],
      "pitfalls": [],
      "prompt_examples": [
        {
          "intent": "render a tool invocation",
          "prompt": "show a get_weather tool call result",
          "snippet": "<ToolCall\n  name=\"get_weather\"\n  status=\"ok\"\n  input={{ city: 'Seoul' }}\n  output={{ temp: 17, condition: 'cloudy' }}\n/>\n"
        }
      ]
    },
    {
      "name": "Tooltip",
      "slug": "tooltip",
      "package": "@helixui/core",
      "import": "import { Tooltip, TooltipTrigger } from '@helixui/core'",
      "description": "A short, on-hover/on-focus label for a control. Use for icon-only buttons or to expand abbreviations.",
      "category": "overlay",
      "tags": [
        "hint",
        "label",
        "on-hover",
        "on-focus"
      ],
      "status": "stable",
      "since": "0.1.0",
      "layout": {
        "display": "portal",
        "width": "content",
        "height": "content",
        "intrinsicSize": "small floating label",
        "stackable": false,
        "fullBleed": false
      },
      "anatomy": "[ trigger ]\n   ╭───────────╮\n   │ small text │\n   ╰─▽─────────╯\n",
      "visual": "A small dark surface with light text and an arrow caret pointing at the trigger. Appears on hover and focus, hides on blur or after a delay.\n",
      "props": [
        {
          "name": "placement",
          "type": "'top' | 'bottom' | 'start' | 'end'",
          "default": "top",
          "description": "Anchor placement."
        },
        {
          "name": "delay",
          "type": "number",
          "default": 300,
          "description": "Open delay in ms."
        },
        {
          "name": "closeDelay",
          "type": "number",
          "default": 100,
          "description": "Close delay in ms."
        }
      ],
      "slots": [
        "TooltipTrigger child — the focusable element being described",
        "Tooltip child — the floating label"
      ],
      "tokens": [
        "color.bg.surface.inverse",
        "color.text.inverse",
        "radius.sm",
        "space.2",
        "font.family.sans",
        "font.size.xs",
        "font.weight.medium"
      ],
      "a11y": {
        "notes": [
          "Tooltips appear only on hover/focus and never replace a label. Use `aria-label` for naming.",
          "Tooltip content must be plain text. For richer content use a Popover with `role=\"dialog\"`."
        ]
      },
      "composes_with": [
        {
          "component": "IconButton",
          "relation": "wraps",
          "note": "Most common — explain what the icon means."
        },
        {
          "component": "Popover",
          "relation": "alternative",
          "note": "Use Popover for richer interactive content."
        }
      ],
      "related": [
        "Popover",
        "IconButton"
      ],
      "when_to_use": [],
      "pitfalls": [],
      "prompt_examples": [
        {
          "intent": "explain an icon button",
          "prompt": "tooltip on a settings icon button",
          "snippet": "<TooltipTrigger>\n  <IconButton aria-label=\"Settings\"><GearIcon /></IconButton>\n  <Tooltip>Open settings</Tooltip>\n</TooltipTrigger>\n"
        }
      ]
    },
    {
      "name": "TypingIndicator",
      "slug": "typing-indicator",
      "package": "@helixui/core",
      "import": "import { TypingIndicator } from '@helixui/core'",
      "description": "Three bouncing dots inside a pill — shown while a participant is composing a message.",
      "category": "chat",
      "tags": [
        "typing",
        "dots",
        "pill"
      ],
      "status": "stable",
      "since": "0.3.0",
      "layout": {
        "display": "inline-block",
        "width": "content",
        "height": "content",
        "intrinsicSize": "~36×20px pill",
        "stackable": false,
        "fullBleed": false
      },
      "anatomy": "( ● ● ● )   ← bouncing dots\n",
      "visual": "A small pill containing three dots that bounce in sequence. Indicates the other participant is composing a message.\n",
      "props": [
        {
          "name": "name",
          "type": "ReactNode",
          "default": "",
          "description": "Optional speaker name rendered to the left of the dots ('Alice')."
        }
      ],
      "slots": [],
      "tokens": [
        "color.bg.action.neutral.default",
        "color.text.secondary",
        "color.text.muted",
        "radius.full",
        "space.2",
        "space.3",
        "font.family.sans",
        "font.size.sm"
      ],
      "a11y": {
        "role": "status",
        "notes": [
          "Container is `role=\"status\"` with `aria-live=\"polite\"` and an `aria-label` like \"Alice is typing\".",
          "Animation respects `prefers-reduced-motion`."
        ]
      },
      "composes_with": [
        {
          "component": "ChatMessage",
          "relation": "alternative",
          "note": "Render in place of a ChatMessage when the participant is typing."
        },
        {
          "component": "StreamingIndicator",
          "relation": "alternative",
          "note": "StreamingIndicator is for the streaming token, not \"is typing\"."
        },
        {
          "component": "ChatList",
          "relation": "sibling"
        }
      ],
      "related": [
        "ChatMessage",
        "ChatList"
      ],
      "when_to_use": [],
      "pitfalls": [],
      "prompt_examples": [
        {
          "intent": "show \"is typing\"",
          "prompt": "three-dot typing indicator",
          "snippet": "<TypingIndicator />\n"
        }
      ]
    }
  ]
}