{
  "$schema": "contracts/design-system-manifest.schema.json",
  "manifestVersion": "1.0.0",
  "schemaVersion": "1.0.0",
  "package": {
    "name": "@ai-created/ui",
    "version": "1.3.5",
    "description": "Shared design system for AI-Created apps",
    "sourcePath": "package.json",
    "publicApiPath": "src/index.ts",
    "entrypoints": [
      {
        "name": ".",
        "target": "./src/index.ts"
      },
      {
        "name": "./styles/tokens.css",
        "target": "./styles/tokens.css"
      },
      {
        "name": "./tailwind-preset",
        "target": "./tailwind-preset.js"
      },
      {
        "name": "./design-system.manifest.json",
        "target": "./design-system.manifest.json"
      },
      {
        "name": "./llms.txt",
        "target": "./llms.txt"
      },
      {
        "name": "./llms-full.txt",
        "target": "./llms-full.txt"
      },
      {
        "name": "./ai-created-ui.config.json",
        "target": "./ai-created-ui.config.json"
      },
      {
        "name": "./consumers.json",
        "target": "./consumers.json"
      },
      {
        "name": "./contracts/consumer-registry.schema.json",
        "target": "./contracts/consumer-registry.schema.json"
      },
      {
        "name": "./contracts/design-policy.schema.json",
        "target": "./contracts/design-policy.schema.json"
      },
      {
        "name": "./contracts/design-system-manifest.schema.json",
        "target": "./contracts/design-system-manifest.schema.json"
      },
      {
        "name": "./templates/agent/manifest.json",
        "target": "./templates/agent/manifest.json"
      },
      {
        "name": "./templates/agent/*",
        "target": "./templates/agent/*"
      }
    ]
  },
  "canonicalSourcePrecedence": [
    {
      "rank": 1,
      "scope": "runtime behavior and public API",
      "paths": [
        "src/**",
        "src/index.ts"
      ],
      "authority": "Production source is canonical for semantics, props, and behavior."
    },
    {
      "rank": 2,
      "scope": "design tokens",
      "paths": [
        "styles/tokens.css"
      ],
      "authority": "Token CSS is canonical. JSON and framework mappings are derived views."
    },
    {
      "rank": 3,
      "scope": "framework mappings",
      "paths": [
        "tailwind-preset.js"
      ],
      "authority": "The preset maps canonical semantic CSS variables into utilities."
    },
    {
      "rank": 4,
      "scope": "component and construction guidance",
      "paths": [
        "playground/src/components/design-system/componentDocs.ts",
        "playground/src/components/design-system/specs/details.ts",
        "playground/src/components/design-system/specs/construction.ts",
        "playground/src/components/design-system/specs/registry.ts"
      ],
      "authority": "The merged registry is canonical for supported design and authoring guidance."
    },
    {
      "rank": 5,
      "scope": "system guidelines",
      "paths": [
        "playground/src/components/design-system/principal-spec/registry.ts"
      ],
      "authority": "The principal guideline registry is canonical for cross-component practice."
    },
    {
      "rank": 6,
      "scope": "narrative documentation",
      "paths": [
        "AGENTS.md",
        "DESIGN-SYSTEM.md",
        "README.md",
        "CLAUDE.md"
      ],
      "authority": "Narrative documentation explains canonical sources and must not override them."
    }
  ],
  "artifacts": {
    "manifest": {
      "sourcePath": "scripts/export-design-system-manifest.mjs",
      "repositoryPath": "design-system.manifest.json",
      "publicPath": "/design-system/manifest.json",
      "schemaPath": "contracts/design-system-manifest.schema.json",
      "derived": true,
      "authority": "Consumption projection only. It never overrides canonical sources."
    },
    "tokens": {
      "sourcePath": "styles/tokens.css",
      "repositoryPath": "playground/public/design-system/tokens.json",
      "publicPath": "/design-system/tokens.json",
      "format": "DTCG-shaped JSON",
      "cssVariableCount": 154
    },
    "agentContext": {
      "sourcePath": "scripts/export-agent-context.mjs",
      "conciseRepositoryPath": "llms.txt",
      "concisePublicPath": "/llms.txt",
      "fullRepositoryPath": "llms-full.txt",
      "fullPublicPath": "/llms-full.txt",
      "derived": true
    },
    "templates": {
      "manifestPath": "templates/agent/manifest.json",
      "schemaPath": "templates/agent/manifest.schema.json",
      "packagePath": "./templates/agent/manifest.json",
      "templateCount": 6
    },
    "policy": {
      "configPath": "ai-created-ui.config.json",
      "schemaPath": "contracts/design-policy.schema.json",
      "validatorPath": "scripts/validate-design-policy.mjs"
    }
  },
  "publicApi": {
    "sourcePath": "src/index.ts",
    "exports": [
      {
        "name": "Accent",
        "localName": "Accent",
        "kind": "type",
        "modulePath": "./components/ThemeProvider",
        "sourcePath": "src/components/ThemeProvider.tsx"
      },
      {
        "name": "Badge",
        "localName": "default",
        "kind": "value",
        "modulePath": "./components/Badge",
        "sourcePath": "src/components/Badge.tsx"
      },
      {
        "name": "BadgeProps",
        "localName": "BadgeProps",
        "kind": "type",
        "modulePath": "./components/Badge",
        "sourcePath": "src/components/Badge.tsx"
      },
      {
        "name": "BadgeVariant",
        "localName": "BadgeVariant",
        "kind": "type",
        "modulePath": "./components/Badge",
        "sourcePath": "src/components/Badge.tsx"
      },
      {
        "name": "Button",
        "localName": "default",
        "kind": "value",
        "modulePath": "./components/Button",
        "sourcePath": "src/components/Button.tsx"
      },
      {
        "name": "ButtonProps",
        "localName": "ButtonProps",
        "kind": "type",
        "modulePath": "./components/Button",
        "sourcePath": "src/components/Button.tsx"
      },
      {
        "name": "ButtonSize",
        "localName": "ButtonSize",
        "kind": "type",
        "modulePath": "./components/Button",
        "sourcePath": "src/components/Button.tsx"
      },
      {
        "name": "ButtonStyleOptions",
        "localName": "ButtonStyleOptions",
        "kind": "type",
        "modulePath": "./components/Button",
        "sourcePath": "src/components/Button.tsx"
      },
      {
        "name": "ButtonVariant",
        "localName": "ButtonVariant",
        "kind": "type",
        "modulePath": "./components/Button",
        "sourcePath": "src/components/Button.tsx"
      },
      {
        "name": "Checkbox",
        "localName": "default",
        "kind": "value",
        "modulePath": "./components/Checkbox",
        "sourcePath": "src/components/Checkbox.tsx"
      },
      {
        "name": "CheckboxProps",
        "localName": "CheckboxProps",
        "kind": "type",
        "modulePath": "./components/Checkbox",
        "sourcePath": "src/components/Checkbox.tsx"
      },
      {
        "name": "ConfirmDialog",
        "localName": "default",
        "kind": "value",
        "modulePath": "./components/ConfirmDialog",
        "sourcePath": "src/components/ConfirmDialog.tsx"
      },
      {
        "name": "ConfirmDialogProps",
        "localName": "ConfirmDialogProps",
        "kind": "type",
        "modulePath": "./components/ConfirmDialog",
        "sourcePath": "src/components/ConfirmDialog.tsx"
      },
      {
        "name": "Dialog",
        "localName": "default",
        "kind": "value",
        "modulePath": "./components/Dialog",
        "sourcePath": "src/components/Dialog.tsx"
      },
      {
        "name": "DialogProps",
        "localName": "DialogProps",
        "kind": "type",
        "modulePath": "./components/Dialog",
        "sourcePath": "src/components/Dialog.tsx"
      },
      {
        "name": "DialogSize",
        "localName": "DialogSize",
        "kind": "type",
        "modulePath": "./components/Dialog",
        "sourcePath": "src/components/Dialog.tsx"
      },
      {
        "name": "Dropdown",
        "localName": "default",
        "kind": "value",
        "modulePath": "./components/Dropdown",
        "sourcePath": "src/components/Dropdown.tsx"
      },
      {
        "name": "DropdownOption",
        "localName": "DropdownOption",
        "kind": "type",
        "modulePath": "./components/Dropdown",
        "sourcePath": "src/components/Dropdown.tsx"
      },
      {
        "name": "DropdownProps",
        "localName": "DropdownProps",
        "kind": "type",
        "modulePath": "./components/Dropdown",
        "sourcePath": "src/components/Dropdown.tsx"
      },
      {
        "name": "EmptyState",
        "localName": "default",
        "kind": "value",
        "modulePath": "./components/EmptyState",
        "sourcePath": "src/components/EmptyState.tsx"
      },
      {
        "name": "EmptyStateProps",
        "localName": "EmptyStateProps",
        "kind": "type",
        "modulePath": "./components/EmptyState",
        "sourcePath": "src/components/EmptyState.tsx"
      },
      {
        "name": "ErrorReport",
        "localName": "default",
        "kind": "value",
        "modulePath": "./components/ErrorReport",
        "sourcePath": "src/components/ErrorReport.tsx"
      },
      {
        "name": "ErrorReportProps",
        "localName": "ErrorReportProps",
        "kind": "type",
        "modulePath": "./components/ErrorReport",
        "sourcePath": "src/components/ErrorReport.tsx"
      },
      {
        "name": "FieldGroup",
        "localName": "FieldGroup",
        "kind": "value",
        "modulePath": "./components/Field",
        "sourcePath": "src/components/Field.tsx"
      },
      {
        "name": "FieldGroupProps",
        "localName": "FieldGroupProps",
        "kind": "type",
        "modulePath": "./components/Field",
        "sourcePath": "src/components/Field.tsx"
      },
      {
        "name": "FieldHint",
        "localName": "FieldHint",
        "kind": "value",
        "modulePath": "./components/Field",
        "sourcePath": "src/components/Field.tsx"
      },
      {
        "name": "FieldHintProps",
        "localName": "FieldHintProps",
        "kind": "type",
        "modulePath": "./components/Field",
        "sourcePath": "src/components/Field.tsx"
      },
      {
        "name": "FieldLabel",
        "localName": "FieldLabel",
        "kind": "value",
        "modulePath": "./components/Field",
        "sourcePath": "src/components/Field.tsx"
      },
      {
        "name": "FieldLabelProps",
        "localName": "FieldLabelProps",
        "kind": "type",
        "modulePath": "./components/Field",
        "sourcePath": "src/components/Field.tsx"
      },
      {
        "name": "FieldLegend",
        "localName": "FieldLegend",
        "kind": "value",
        "modulePath": "./components/Field",
        "sourcePath": "src/components/Field.tsx"
      },
      {
        "name": "FieldLegendProps",
        "localName": "FieldLegendProps",
        "kind": "type",
        "modulePath": "./components/Field",
        "sourcePath": "src/components/Field.tsx"
      },
      {
        "name": "ModalBody",
        "localName": "ModalBody",
        "kind": "value",
        "modulePath": "./components/Modal",
        "sourcePath": "src/components/Modal.tsx"
      },
      {
        "name": "ModalBodyProps",
        "localName": "ModalBodyProps",
        "kind": "type",
        "modulePath": "./components/Modal",
        "sourcePath": "src/components/Modal.tsx"
      },
      {
        "name": "ModalFooter",
        "localName": "ModalFooter",
        "kind": "value",
        "modulePath": "./components/Modal",
        "sourcePath": "src/components/Modal.tsx"
      },
      {
        "name": "ModalFooterProps",
        "localName": "ModalFooterProps",
        "kind": "type",
        "modulePath": "./components/Modal",
        "sourcePath": "src/components/Modal.tsx"
      },
      {
        "name": "ModalHeader",
        "localName": "ModalHeader",
        "kind": "value",
        "modulePath": "./components/Modal",
        "sourcePath": "src/components/Modal.tsx"
      },
      {
        "name": "ModalHeaderProps",
        "localName": "ModalHeaderProps",
        "kind": "type",
        "modulePath": "./components/Modal",
        "sourcePath": "src/components/Modal.tsx"
      },
      {
        "name": "ModalOverlay",
        "localName": "ModalOverlay",
        "kind": "value",
        "modulePath": "./components/Modal",
        "sourcePath": "src/components/Modal.tsx"
      },
      {
        "name": "ModalOverlayProps",
        "localName": "ModalOverlayProps",
        "kind": "type",
        "modulePath": "./components/Modal",
        "sourcePath": "src/components/Modal.tsx"
      },
      {
        "name": "ModalPanel",
        "localName": "ModalPanel",
        "kind": "value",
        "modulePath": "./components/Modal",
        "sourcePath": "src/components/Modal.tsx"
      },
      {
        "name": "ModalPanelProps",
        "localName": "ModalPanelProps",
        "kind": "type",
        "modulePath": "./components/Modal",
        "sourcePath": "src/components/Modal.tsx"
      },
      {
        "name": "ModalSize",
        "localName": "ModalSize",
        "kind": "type",
        "modulePath": "./components/Modal",
        "sourcePath": "src/components/Modal.tsx"
      },
      {
        "name": "Notice",
        "localName": "default",
        "kind": "value",
        "modulePath": "./components/Notice",
        "sourcePath": "src/components/Notice.tsx"
      },
      {
        "name": "NoticeProps",
        "localName": "NoticeProps",
        "kind": "type",
        "modulePath": "./components/Notice",
        "sourcePath": "src/components/Notice.tsx"
      },
      {
        "name": "NoticeVariant",
        "localName": "NoticeVariant",
        "kind": "type",
        "modulePath": "./components/Notice",
        "sourcePath": "src/components/Notice.tsx"
      },
      {
        "name": "RadioGroup",
        "localName": "default",
        "kind": "value",
        "modulePath": "./components/RadioGroup",
        "sourcePath": "src/components/RadioGroup.tsx"
      },
      {
        "name": "RadioGroupProps",
        "localName": "RadioGroupProps",
        "kind": "type",
        "modulePath": "./components/RadioGroup",
        "sourcePath": "src/components/RadioGroup.tsx"
      },
      {
        "name": "RadioOption",
        "localName": "RadioOption",
        "kind": "type",
        "modulePath": "./components/RadioGroup",
        "sourcePath": "src/components/RadioGroup.tsx"
      },
      {
        "name": "Skeleton",
        "localName": "default",
        "kind": "value",
        "modulePath": "./components/Skeleton",
        "sourcePath": "src/components/Skeleton.tsx"
      },
      {
        "name": "SkeletonProps",
        "localName": "SkeletonProps",
        "kind": "type",
        "modulePath": "./components/Skeleton",
        "sourcePath": "src/components/Skeleton.tsx"
      },
      {
        "name": "Slider",
        "localName": "default",
        "kind": "value",
        "modulePath": "./components/Slider",
        "sourcePath": "src/components/Slider.tsx"
      },
      {
        "name": "SliderProps",
        "localName": "SliderProps",
        "kind": "type",
        "modulePath": "./components/Slider",
        "sourcePath": "src/components/Slider.tsx"
      },
      {
        "name": "Surface",
        "localName": "default",
        "kind": "value",
        "modulePath": "./components/Surface",
        "sourcePath": "src/components/Surface.tsx"
      },
      {
        "name": "SurfaceInteraction",
        "localName": "SurfaceInteraction",
        "kind": "type",
        "modulePath": "./components/Surface",
        "sourcePath": "src/components/Surface.tsx"
      },
      {
        "name": "SurfacePadding",
        "localName": "SurfacePadding",
        "kind": "type",
        "modulePath": "./components/Surface",
        "sourcePath": "src/components/Surface.tsx"
      },
      {
        "name": "SurfaceProps",
        "localName": "SurfaceProps",
        "kind": "type",
        "modulePath": "./components/Surface",
        "sourcePath": "src/components/Surface.tsx"
      },
      {
        "name": "SurfaceStyleOptions",
        "localName": "SurfaceStyleOptions",
        "kind": "type",
        "modulePath": "./components/Surface",
        "sourcePath": "src/components/Surface.tsx"
      },
      {
        "name": "SurfaceVariant",
        "localName": "SurfaceVariant",
        "kind": "type",
        "modulePath": "./components/Surface",
        "sourcePath": "src/components/Surface.tsx"
      },
      {
        "name": "Tab",
        "localName": "Tab",
        "kind": "type",
        "modulePath": "./components/Tabs",
        "sourcePath": "src/components/Tabs.tsx"
      },
      {
        "name": "Tabs",
        "localName": "default",
        "kind": "value",
        "modulePath": "./components/Tabs",
        "sourcePath": "src/components/Tabs.tsx"
      },
      {
        "name": "TabsProps",
        "localName": "TabsProps",
        "kind": "type",
        "modulePath": "./components/Tabs",
        "sourcePath": "src/components/Tabs.tsx"
      },
      {
        "name": "TextArea",
        "localName": "TextArea",
        "kind": "value",
        "modulePath": "./components/Field",
        "sourcePath": "src/components/Field.tsx"
      },
      {
        "name": "TextAreaProps",
        "localName": "TextAreaProps",
        "kind": "type",
        "modulePath": "./components/Field",
        "sourcePath": "src/components/Field.tsx"
      },
      {
        "name": "TextInput",
        "localName": "TextInput",
        "kind": "value",
        "modulePath": "./components/Field",
        "sourcePath": "src/components/Field.tsx"
      },
      {
        "name": "TextInputProps",
        "localName": "TextInputProps",
        "kind": "type",
        "modulePath": "./components/Field",
        "sourcePath": "src/components/Field.tsx"
      },
      {
        "name": "Theme",
        "localName": "Theme",
        "kind": "type",
        "modulePath": "./components/ThemeProvider",
        "sourcePath": "src/components/ThemeProvider.tsx"
      },
      {
        "name": "ThemeContextValue",
        "localName": "ThemeContextValue",
        "kind": "type",
        "modulePath": "./components/ThemeProvider",
        "sourcePath": "src/components/ThemeProvider.tsx"
      },
      {
        "name": "ThemeProvider",
        "localName": "ThemeProvider",
        "kind": "value",
        "modulePath": "./components/ThemeProvider",
        "sourcePath": "src/components/ThemeProvider.tsx"
      },
      {
        "name": "ThemeProviderProps",
        "localName": "ThemeProviderProps",
        "kind": "type",
        "modulePath": "./components/ThemeProvider",
        "sourcePath": "src/components/ThemeProvider.tsx"
      },
      {
        "name": "ThemeToggle",
        "localName": "default",
        "kind": "value",
        "modulePath": "./components/ThemeToggle",
        "sourcePath": "src/components/ThemeToggle.tsx"
      },
      {
        "name": "ThemedHeroImage",
        "localName": "default",
        "kind": "value",
        "modulePath": "./components/ThemedHeroImage",
        "sourcePath": "src/components/ThemedHeroImage.tsx"
      },
      {
        "name": "ThemedHeroImageProps",
        "localName": "ThemedHeroImageProps",
        "kind": "type",
        "modulePath": "./components/ThemedHeroImage",
        "sourcePath": "src/components/ThemedHeroImage.tsx"
      },
      {
        "name": "Toggle",
        "localName": "default",
        "kind": "value",
        "modulePath": "./components/Toggle",
        "sourcePath": "src/components/Toggle.tsx"
      },
      {
        "name": "ToggleProps",
        "localName": "ToggleProps",
        "kind": "type",
        "modulePath": "./components/Toggle",
        "sourcePath": "src/components/Toggle.tsx"
      },
      {
        "name": "Tooltip",
        "localName": "default",
        "kind": "value",
        "modulePath": "./components/Tooltip",
        "sourcePath": "src/components/Tooltip.tsx"
      },
      {
        "name": "TooltipPosition",
        "localName": "TooltipPosition",
        "kind": "type",
        "modulePath": "./components/Tooltip",
        "sourcePath": "src/components/Tooltip.tsx"
      },
      {
        "name": "TooltipProps",
        "localName": "TooltipProps",
        "kind": "type",
        "modulePath": "./components/Tooltip",
        "sourcePath": "src/components/Tooltip.tsx"
      },
      {
        "name": "accentNames",
        "localName": "accentNames",
        "kind": "value",
        "modulePath": "./components/ThemeProvider",
        "sourcePath": "src/components/ThemeProvider.tsx"
      },
      {
        "name": "borderHoverMotion",
        "localName": "borderHoverMotion",
        "kind": "value",
        "modulePath": "./lib/motion",
        "sourcePath": "src/lib/motion.ts"
      },
      {
        "name": "buttonStyles",
        "localName": "buttonStyles",
        "kind": "value",
        "modulePath": "./components/Button",
        "sourcePath": "src/components/Button.tsx"
      },
      {
        "name": "cn",
        "localName": "cn",
        "kind": "value",
        "modulePath": "./lib/utils",
        "sourcePath": "src/lib/utils.ts"
      },
      {
        "name": "fadeUpMotion",
        "localName": "fadeUpMotion",
        "kind": "value",
        "modulePath": "./lib/motion",
        "sourcePath": "src/lib/motion.ts"
      },
      {
        "name": "fieldGroupStyles",
        "localName": "fieldGroupStyles",
        "kind": "value",
        "modulePath": "./components/Field",
        "sourcePath": "src/components/Field.tsx"
      },
      {
        "name": "fieldHintStyles",
        "localName": "fieldHintStyles",
        "kind": "value",
        "modulePath": "./components/Field",
        "sourcePath": "src/components/Field.tsx"
      },
      {
        "name": "fieldLabelStyles",
        "localName": "fieldLabelStyles",
        "kind": "value",
        "modulePath": "./components/Field",
        "sourcePath": "src/components/Field.tsx"
      },
      {
        "name": "fieldLegendStyles",
        "localName": "fieldLegendStyles",
        "kind": "value",
        "modulePath": "./components/Field",
        "sourcePath": "src/components/Field.tsx"
      },
      {
        "name": "inViewFadeUpMotion",
        "localName": "inViewFadeUpMotion",
        "kind": "value",
        "modulePath": "./lib/motion",
        "sourcePath": "src/lib/motion.ts"
      },
      {
        "name": "inputStyles",
        "localName": "inputStyles",
        "kind": "value",
        "modulePath": "./components/Field",
        "sourcePath": "src/components/Field.tsx"
      },
      {
        "name": "motionDuration",
        "localName": "motionDuration",
        "kind": "value",
        "modulePath": "./lib/motion",
        "sourcePath": "src/lib/motion.ts"
      },
      {
        "name": "motionEase",
        "localName": "motionEase",
        "kind": "value",
        "modulePath": "./lib/motion",
        "sourcePath": "src/lib/motion.ts"
      },
      {
        "name": "motionOffset",
        "localName": "motionOffset",
        "kind": "value",
        "modulePath": "./lib/motion",
        "sourcePath": "src/lib/motion.ts"
      },
      {
        "name": "staggerDelay",
        "localName": "staggerDelay",
        "kind": "value",
        "modulePath": "./lib/motion",
        "sourcePath": "src/lib/motion.ts"
      },
      {
        "name": "subtleHoverMotion",
        "localName": "subtleHoverMotion",
        "kind": "value",
        "modulePath": "./lib/motion",
        "sourcePath": "src/lib/motion.ts"
      },
      {
        "name": "surfaceStyles",
        "localName": "surfaceStyles",
        "kind": "value",
        "modulePath": "./components/Surface",
        "sourcePath": "src/components/Surface.tsx"
      },
      {
        "name": "useTabPanelProps",
        "localName": "useTabPanelProps",
        "kind": "value",
        "modulePath": "./components/Tabs",
        "sourcePath": "src/components/Tabs.tsx"
      },
      {
        "name": "useTheme",
        "localName": "useTheme",
        "kind": "value",
        "modulePath": "./components/ThemeProvider",
        "sourcePath": "src/components/ThemeProvider.tsx"
      }
    ]
  },
  "components": [
    {
      "id": "button",
      "name": "Button / buttonStyles",
      "category": "Actions & feedback",
      "purpose": "Triggers an action with a consistent visual hierarchy.",
      "useWhen": [
        "Submitting or confirming an action",
        "Providing a compact inline or icon action"
      ],
      "avoidWhen": [
        "Navigation that should be a link",
        "Non-interactive status text"
      ],
      "api": [
        {
          "prop": "variant",
          "type": "ButtonVariant",
          "defaultValue": "primary",
          "description": "primary, secondary, destructive, ghost, filter, filter-active, or icon."
        },
        {
          "prop": "size",
          "type": "ButtonSize",
          "defaultValue": "md",
          "description": "inline, sm, md, lg, xl, or icon."
        },
        {
          "prop": "fullWidth",
          "type": "boolean",
          "defaultValue": "false",
          "description": "Expands the button to the available width."
        },
        {
          "prop": "type",
          "type": "button | submit | reset",
          "defaultValue": "button",
          "description": "Native button type."
        },
        {
          "prop": "className",
          "type": "string",
          "defaultValue": "undefined",
          "description": "Additional classes."
        }
      ],
      "states": [
        "default",
        "hover",
        "focus-visible",
        "disabled"
      ],
      "accessibility": [
        "Uses a native button and forwards its ref.",
        "Provide an accessible name for icon-only buttons."
      ],
      "composition": [
        "Children provide the button label or icon.",
        "buttonStyles accepts the same visual options for custom elements."
      ],
      "code": "<Button variant=\"primary\">Save changes</Button>",
      "slug": "button",
      "summary": "The primary action primitive, with explicit hierarchy, size, and semantic-button behavior.",
      "sourcePath": "src/components/Button.tsx",
      "packageExports": [
        "Button",
        "buttonStyles",
        "ButtonProps",
        "ButtonSize",
        "ButtonVariant"
      ],
      "anatomy": [
        {
          "name": "Container",
          "description": "Native action target carrying variant, size, and interaction styles.",
          "required": true,
          "semanticElement": "button"
        },
        {
          "name": "Leading content",
          "description": "Optional decorative icon placed before the label.",
          "required": false
        },
        {
          "name": "Label",
          "description": "Short verb phrase describing the result of activation.",
          "required": true
        },
        {
          "name": "Trailing content",
          "description": "Optional icon communicating direction or external behavior.",
          "required": false
        }
      ],
      "visualSpec": {
        "measurements": [
          {
            "property": "Corner radius",
            "value": "6px",
            "notes": "Uses radius-md."
          },
          {
            "property": "Content gap",
            "value": "8px"
          },
          {
            "property": "Horizontal padding",
            "value": "16 / 20 / 24 / 32px",
            "notes": "sm / md / lg / xl."
          },
          {
            "property": "Vertical padding",
            "value": "8 / 8 / 12 / 12px",
            "notes": "sm / md / lg / xl."
          },
          {
            "property": "Icon-only target",
            "value": "44 × 44px"
          }
        ],
        "rules": [
          "Keep labels on one line.",
          "Use the icon size for square icon-only controls; do not force an icon into text-button spacing.",
          "Primary and destructive use distinct semantic action tokens; specific copy still communicates the consequence."
        ],
        "responsiveBehavior": [
          "Use fullWidth only when the surrounding layout calls for a full-row action.",
          "Stack competing actions at narrow widths in the consuming layout."
        ]
      },
      "designTokens": [
        {
          "token": "--color-action-primary / --color-action-primary-hover",
          "purpose": "Primary action background and hover."
        },
        {
          "token": "--color-action-destructive / --color-action-destructive-hover",
          "purpose": "Destructive action background and hover."
        },
        {
          "token": "--color-on-action",
          "purpose": "Foreground on filled actions."
        },
        {
          "token": "--color-control-border / --color-control-border-strong",
          "purpose": "Secondary, filter, and icon control boundaries."
        },
        {
          "token": "--color-focus",
          "purpose": "Global focus-visible outline."
        },
        {
          "token": "--motion-fast",
          "purpose": "Color transition duration."
        },
        {
          "token": "--radius-md",
          "purpose": "Container radius."
        }
      ],
      "stateDefinitions": [
        {
          "name": "default",
          "trigger": "Idle and enabled.",
          "visual": "Variant-specific fill, border, and text establish action hierarchy.",
          "behavior": "Activates on click, Enter, or Space.",
          "accessibility": "Native button semantics expose name and state."
        },
        {
          "name": "hover",
          "trigger": "Pointer rests over an enabled button.",
          "visual": "Background, text, or border gains emphasis over 200ms.",
          "behavior": "No action until activation."
        },
        {
          "name": "focus-visible",
          "trigger": "Keyboard focus enters the button.",
          "visual": "2px focus-color outline with a 3px offset.",
          "behavior": "Remains the current tab stop."
        },
        {
          "name": "disabled",
          "trigger": "disabled is true.",
          "visual": "50% opacity and not-allowed cursor.",
          "behavior": "Native activation and focus are suppressed.",
          "accessibility": "Disabled state is exposed by the native element."
        }
      ],
      "keyboard": [
        {
          "key": "Enter",
          "action": "Activates the button."
        },
        {
          "key": "Space",
          "action": "Activates the button."
        },
        {
          "key": "Tab / Shift+Tab",
          "action": "Moves focus to or from an enabled button."
        }
      ],
      "accessibilitySpec": {
        "semantics": "Native <button>; buttonStyles is presentation-only when used on another element.",
        "accessibleName": "Visible text supplies the name. Icon-only buttons require aria-label.",
        "requirements": [
          "Keep type=\"button\" unless the control intentionally submits or resets a form.",
          "Do not remove the focus-visible outline.",
          "Mark decorative icons aria-hidden.",
          "A disabled action must use the disabled attribute, not only visual opacity."
        ]
      },
      "implementation": {
        "importStatement": "import { Button, buttonStyles } from '@ai-created/ui';",
        "clientComponent": true,
        "notes": [
          "Button forwards its HTMLButtonElement ref and all native button attributes.",
          "Consumer className is merged last and can override default Tailwind utilities.",
          "Use buttonStyles only when another semantic element genuinely needs the same appearance."
        ],
        "recipes": [
          {
            "name": "Submit action",
            "description": "Use a native submit type inside a form.",
            "code": "<Button type=\"submit\">Save changes</Button>"
          }
        ]
      },
      "guidance": {
        "dos": [
          "Lead labels with a specific verb such as Save, Create, or Delete.",
          "Use one clear primary action per decision area."
        ],
        "donts": [
          "Do not use a button for navigation; use a link.",
          "Do not rely on color alone to distinguish destructive meaning."
        ]
      },
      "testing": {
        "unit": [
          "Defaults to primary, md, and type button.",
          "Forwards ref, className, disabled, and native attributes."
        ],
        "interaction": [
          "Activates by pointer, Enter, and Space; disabled buttons do not activate."
        ],
        "accessibility": [
          "Has an accessible name and no axe violations in every variant."
        ],
        "visual": [
          "Snapshot every variant, size, disabled state, focus-visible state, and both themes."
        ]
      },
      "relatedComponents": [
        "confirm-dialog",
        "tooltip",
        "toggle"
      ],
      "controls": {
        "variant": {
          "type": "select",
          "label": "Variant",
          "defaultValue": "primary",
          "options": [
            "primary",
            "secondary",
            "destructive",
            "ghost",
            "filter",
            "filter-active",
            "icon"
          ]
        },
        "size": {
          "type": "select",
          "label": "Size",
          "defaultValue": "md",
          "options": [
            "inline",
            "sm",
            "md",
            "lg",
            "xl",
            "icon"
          ]
        },
        "label": {
          "type": "text",
          "label": "Label",
          "defaultValue": "Save changes"
        },
        "disabled": {
          "type": "boolean",
          "label": "Disabled",
          "defaultValue": false
        },
        "fullWidth": {
          "type": "boolean",
          "label": "Full width",
          "defaultValue": false
        }
      },
      "construction": {
        "asset": {
          "kind": "component",
          "figmaName": "Components/Actions/Button",
          "localName": "Button",
          "canvasApplicability": "Publish as a component set with variant and size axes plus boolean and swap properties."
        },
        "autoLayout": {
          "applicable": true,
          "direction": "horizontal",
          "gap": "8px",
          "padding": "8px 16px to 12px 32px by size",
          "alignment": "Center in both axes",
          "wrap": "No wrap",
          "notes": [
            "Use logical leading and trailing slots. The icon size is a square frame with centered content."
          ]
        },
        "resizing": {
          "applicable": true,
          "width": "hug",
          "height": "fixed",
          "minWidth": "36px",
          "maxWidth": "Hug content or fill parent when Full width is true",
          "minHeight": "36px",
          "maxHeight": "44px",
          "overflow": "visible",
          "notes": [
            "Text variants hug by default. Icon-only uses a fixed 36px square."
          ]
        },
        "exposedProperties": [
          {
            "name": "variant",
            "label": "Variant",
            "type": "variant",
            "required": false,
            "defaultValue": "primary",
            "options": [
              "primary",
              "secondary",
              "destructive",
              "ghost",
              "filter",
              "filter-active",
              "icon"
            ],
            "codeMapping": "variant"
          },
          {
            "name": "size",
            "label": "Size",
            "type": "variant",
            "required": false,
            "defaultValue": "md",
            "options": [
              "inline",
              "sm",
              "md",
              "lg",
              "xl",
              "icon"
            ],
            "codeMapping": "size"
          },
          {
            "name": "fullWidth",
            "label": "Full width",
            "type": "boolean",
            "required": false,
            "defaultValue": false,
            "codeMapping": "fullWidth"
          },
          {
            "name": "disabled",
            "label": "Disabled",
            "type": "boolean",
            "required": false,
            "defaultValue": false,
            "codeMapping": "disabled"
          },
          {
            "name": "label",
            "label": "Label",
            "type": "slot",
            "required": true,
            "defaultValue": "Save changes",
            "codeMapping": "children"
          },
          {
            "name": "leadingIcon",
            "label": "Leading icon",
            "type": "instance-swap",
            "required": false,
            "defaultValue": null,
            "codeMapping": "First child, decorative unless it supplies the icon-only accessible name"
          },
          {
            "name": "trailingIcon",
            "label": "Trailing icon",
            "type": "instance-swap",
            "required": false,
            "defaultValue": null,
            "codeMapping": "Last child, mark decorative"
          }
        ],
        "nestedAssets": [
          {
            "name": "Label",
            "kind": "slot",
            "required": true,
            "description": "Single-line action label.",
            "codeMapping": "children"
          },
          {
            "name": "Leading icon",
            "kind": "slot",
            "required": false,
            "description": "Optional 16px icon before the label.",
            "codeMapping": "children"
          },
          {
            "name": "Trailing icon",
            "kind": "slot",
            "required": false,
            "description": "Optional 16px icon after the label.",
            "codeMapping": "children"
          }
        ],
        "contentLimits": [
          {
            "target": "Label",
            "limit": "One line, recommended 2 to 24 characters, maximum 32",
            "overflowBehavior": "Never truncate; revise the label or allow the parent to allocate more width.",
            "rationale": "Action labels must remain immediately scannable."
          },
          {
            "target": "Icons",
            "limit": "At most one icon on either side",
            "overflowBehavior": "Remove redundant icons.",
            "rationale": "Multiple symbols compete with the action label."
          }
        ],
        "localization": {
          "translatable": [
            "Label",
            "Accessible name"
          ],
          "rtlBehavior": [
            "Leading and trailing slots follow logical reading order.",
            "Mirror directional icons; do not mirror universal symbols."
          ],
          "stressCases": [
            "Test at 200% text size.",
            "Test a label at twice the English length.",
            "Test an icon-only accessible name in every locale."
          ]
        },
        "responsive": {
          "strategy": "Intrinsic sizing with a parent-controlled full-width option.",
          "breakpoints": [
            "No internal breakpoint"
          ],
          "behavior": [
            "Keep hug width in toolbars.",
            "Use Full width inside narrow stacked action areas.",
            "The consuming layout decides when actions stack."
          ]
        },
        "limitations": {
          "figma": [
            "Figma interactive variants may demonstrate hover and press but cannot reproduce native button semantics.",
            "Do not detach instances to make one-off sizes."
          ],
          "code": [
            "Icon-only use requires an accessible name that is not represented by visual geometry.",
            "buttonStyles can style another element but does not supply button behavior."
          ],
          "notApplicable": []
        },
        "governance": {
          "status": "stable",
          "ownerRole": "Design systems action primitive owner",
          "lastReviewed": "2026-08-29",
          "canonicalSource": "src/components/Button.tsx",
          "changePolicy": [
            "A new variant or size must represent a reusable hierarchy need and include every interaction state.",
            "A breaking property, token, or behavior change requires design and engineering approval, a migration note, and a major release.",
            "The design asset, implementation, documentation, accessibility contract, and regression coverage must ship in the same change."
          ]
        }
      }
    },
    {
      "id": "badge",
      "name": "Badge",
      "category": "Actions & feedback",
      "purpose": "Displays a short status or classification label.",
      "useWhen": [
        "Showing compact metadata or status"
      ],
      "avoidWhen": [
        "Long messages",
        "Interactive controls"
      ],
      "api": [
        {
          "prop": "variant",
          "type": "BadgeVariant",
          "defaultValue": "default",
          "description": "default, muted, success, warning, error, or info."
        },
        {
          "prop": "className",
          "type": "string",
          "defaultValue": "undefined",
          "description": "Additional classes."
        },
        {
          "prop": "...props",
          "type": "HTMLAttributes<HTMLSpanElement>",
          "defaultValue": "undefined",
          "description": "Native span attributes."
        }
      ],
      "states": [
        "default",
        "muted",
        "success",
        "warning",
        "error",
        "info"
      ],
      "accessibility": [
        "Renders a span; include meaningful text."
      ],
      "composition": [
        "Place beside a title, table value, or list item."
      ],
      "code": "<Badge variant=\"success\">Ready</Badge>",
      "slug": "badge",
      "summary": "A compact, non-interactive label for status, category, or short metadata.",
      "sourcePath": "src/components/Badge.tsx",
      "packageExports": [
        "Badge",
        "BadgeProps",
        "BadgeVariant"
      ],
      "anatomy": [
        {
          "name": "Container",
          "description": "Inline pill that carries the semantic tone.",
          "required": true,
          "semanticElement": "span"
        },
        {
          "name": "Label",
          "description": "Short status or category text.",
          "required": true
        }
      ],
      "visualSpec": {
        "measurements": [
          {
            "property": "Text size",
            "value": "11px"
          },
          {
            "property": "Horizontal padding",
            "value": "8px"
          },
          {
            "property": "Vertical padding",
            "value": "2px"
          },
          {
            "property": "Radius",
            "value": "9999px"
          },
          {
            "property": "Border",
            "value": "1px"
          }
        ],
        "rules": [
          "Keep labels brief and non-wrapping.",
          "Choose a tone that matches the status meaning, not decoration."
        ]
      },
      "designTokens": [
        {
          "token": "--color-surface / --color-surface2",
          "purpose": "Neutral fills."
        },
        {
          "token": "--color-border",
          "purpose": "Neutral border."
        },
        {
          "token": "--color-success / warning / info / error",
          "purpose": "Semantic text."
        },
        {
          "token": "--color-*-surface / --color-*-border",
          "purpose": "Semantic fill and border pairs."
        }
      ],
      "stateDefinitions": [
        {
          "name": "default",
          "trigger": "Default variant.",
          "visual": "Surface2 fill with standard border and primary text.",
          "behavior": "Static metadata."
        },
        {
          "name": "muted",
          "trigger": "Muted variant.",
          "visual": "Quieter surface and secondary text.",
          "behavior": "Static metadata."
        },
        {
          "name": "success",
          "trigger": "Positive status.",
          "visual": "Success surface, border, and text.",
          "behavior": "Static metadata."
        },
        {
          "name": "warning",
          "trigger": "Cautionary status.",
          "visual": "Warning surface, border, and text.",
          "behavior": "Static metadata."
        },
        {
          "name": "error",
          "trigger": "Failure status.",
          "visual": "Error surface, border, and text.",
          "behavior": "Static metadata."
        },
        {
          "name": "info",
          "trigger": "Informational status.",
          "visual": "Info surface, border, and text.",
          "behavior": "Static metadata."
        }
      ],
      "keyboard": [],
      "accessibilitySpec": {
        "semantics": "Plain inline <span> with no implicit role.",
        "accessibleName": "Text content is read in surrounding context.",
        "requirements": [
          "Write a meaningful label rather than encoding meaning only by color.",
          "Do not add interaction to Badge; pair it with a real control when needed."
        ]
      },
      "implementation": {
        "importStatement": "import { Badge } from '@ai-created/ui';",
        "clientComponent": false,
        "notes": [
          "Forwards a span ref and accepts native span attributes.",
          "Use variant for semantic tone and className only for contextual layout."
        ]
      },
      "guidance": {
        "dos": [
          "Use one to three words.",
          "Place close to the object or value being classified."
        ],
        "donts": [
          "Do not use as a button or filter chip.",
          "Do not put sentences or essential instructions in a badge."
        ]
      },
      "testing": {
        "unit": [
          "Renders a span and maps all six variants.",
          "Forwards ref and native attributes."
        ],
        "interaction": [
          "No interaction is expected."
        ],
        "accessibility": [
          "Text remains meaningful without color."
        ],
        "visual": [
          "Capture every tone in dark and light modes."
        ]
      },
      "relatedComponents": [
        "notice",
        "surface"
      ],
      "controls": {
        "variant": {
          "type": "select",
          "label": "Tone",
          "defaultValue": "default",
          "options": [
            "default",
            "muted",
            "success",
            "warning",
            "error",
            "info"
          ]
        },
        "label": {
          "type": "text",
          "label": "Label",
          "defaultValue": "Ready"
        }
      },
      "construction": {
        "asset": {
          "kind": "component",
          "figmaName": "Components/Feedback/Badge",
          "localName": "Badge",
          "canvasApplicability": "Publish as a component set with semantic tone variants and one text property."
        },
        "autoLayout": {
          "applicable": true,
          "direction": "horizontal",
          "gap": "0px",
          "padding": "2px 8px",
          "alignment": "Center in both axes",
          "wrap": "No wrap",
          "notes": []
        },
        "resizing": {
          "applicable": true,
          "width": "hug",
          "height": "hug",
          "minWidth": "Content width",
          "maxWidth": "Recommended 160px",
          "minHeight": "18px",
          "maxHeight": "One line",
          "overflow": "visible",
          "notes": []
        },
        "exposedProperties": [
          {
            "name": "variant",
            "label": "Tone",
            "type": "variant",
            "required": false,
            "defaultValue": "default",
            "options": [
              "default",
              "muted",
              "success",
              "warning",
              "error",
              "info"
            ],
            "codeMapping": "variant"
          },
          {
            "name": "label",
            "label": "Label",
            "type": "text",
            "required": true,
            "defaultValue": "Ready",
            "codeMapping": "children"
          }
        ],
        "nestedAssets": [
          {
            "name": "Label",
            "kind": "slot",
            "required": true,
            "description": "Status or classification text.",
            "codeMapping": "children"
          }
        ],
        "contentLimits": [
          {
            "target": "Label",
            "limit": "One to three words, maximum 24 characters",
            "overflowBehavior": "Do not truncate; replace with shorter vocabulary.",
            "rationale": "A badge is compact metadata, not explanatory content."
          }
        ],
        "localization": {
          "translatable": [
            "Label"
          ],
          "rtlBehavior": [
            "Text follows the document direction; pill geometry is symmetric."
          ],
          "stressCases": [
            "Test status terminology in the longest supported locale.",
            "Verify color-independent meaning after translation."
          ]
        },
        "responsive": {
          "strategy": "Always intrinsic.",
          "breakpoints": [
            "No internal breakpoint"
          ],
          "behavior": [
            "Do not force fill width.",
            "Allow the parent row to wrap the whole badge as a unit."
          ]
        },
        "limitations": {
          "figma": [
            "Do not add interactive variants to the design asset."
          ],
          "code": [
            "Badge remains a span and must not receive click behavior."
          ],
          "notApplicable": []
        },
        "governance": {
          "status": "stable",
          "ownerRole": "Design systems feedback owner",
          "lastReviewed": "2026-08-29",
          "canonicalSource": "src/components/Badge.tsx",
          "changePolicy": [
            "Semantic tone names may change only with the shared status taxonomy.",
            "A breaking property, token, or behavior change requires design and engineering approval, a migration note, and a major release.",
            "The design asset, implementation, documentation, accessibility contract, and regression coverage must ship in the same change."
          ]
        }
      }
    },
    {
      "id": "surface",
      "name": "Surface / surfaceStyles",
      "category": "Layout & content",
      "purpose": "Provides a bordered, themed container for grouped content.",
      "useWhen": [
        "Grouping related content",
        "Creating cards or inset sections"
      ],
      "avoidWhen": [
        "A plain layout wrapper is sufficient"
      ],
      "api": [
        {
          "prop": "variant",
          "type": "SurfaceVariant",
          "defaultValue": "default",
          "description": "default, muted, accent, inset, success, warning, info, or error."
        },
        {
          "prop": "padding",
          "type": "SurfacePadding",
          "defaultValue": "none",
          "description": "none, sm, md, lg, xl, or responsive."
        },
        {
          "prop": "interaction",
          "type": "SurfaceInteraction",
          "defaultValue": "none",
          "description": "none, group, or within interaction styling."
        },
        {
          "prop": "className",
          "type": "string",
          "defaultValue": "undefined",
          "description": "Additional classes."
        }
      ],
      "states": [
        "default",
        "interactive group",
        "interactive within"
      ],
      "accessibility": [
        "A div has no implicit landmark; add a heading or landmark when needed."
      ],
      "composition": [
        "Use as the visual root of EmptyState and Notice.",
        "surfaceStyles supports custom semantic elements."
      ],
      "code": "<Surface variant=\"muted\" padding=\"md\">Content</Surface>",
      "slug": "surface",
      "summary": "A themed structural container that groups related content without imposing semantics.",
      "sourcePath": "src/components/Surface.tsx",
      "packageExports": [
        "Surface",
        "surfaceStyles",
        "SurfaceProps",
        "SurfaceVariant",
        "SurfacePadding",
        "SurfaceInteraction"
      ],
      "anatomy": [
        {
          "name": "Container",
          "description": "Bordered visual grouping root.",
          "required": true,
          "semanticElement": "div"
        },
        {
          "name": "Content slot",
          "description": "Free-form content that supplies the surface meaning.",
          "required": true
        }
      ],
      "visualSpec": {
        "measurements": [
          {
            "property": "Radius",
            "value": "6px"
          },
          {
            "property": "Border",
            "value": "1px"
          },
          {
            "property": "Padding",
            "value": "0 / 16 / 24 / 32 / 40px",
            "notes": "none / sm / md / lg / xl."
          },
          {
            "property": "Responsive padding",
            "value": "32px, then 48px at md"
          }
        ],
        "rules": [
          "Pick a surface variant for structural or semantic meaning.",
          "Interaction styling only supplies visual feedback; the consumer owns interactive semantics."
        ],
        "responsiveBehavior": [
          "Responsive padding increases at the md breakpoint.",
          "Width is controlled by the parent layout."
        ]
      },
      "designTokens": [
        {
          "token": "--color-surface / --color-surface2 / --color-bg",
          "purpose": "Structural backgrounds."
        },
        {
          "token": "--color-border / --color-border-strong",
          "purpose": "Default border and interaction emphasis."
        },
        {
          "token": "--color-accent-border",
          "purpose": "Accent border."
        },
        {
          "token": "--color-*-surface / --color-*-border",
          "purpose": "Semantic variants."
        },
        {
          "token": "--radius-md",
          "purpose": "Corner radius."
        }
      ],
      "stateDefinitions": [
        {
          "name": "default",
          "trigger": "No interaction.",
          "visual": "Stable themed fill and 1px border.",
          "behavior": "Pure layout container."
        },
        {
          "name": "interactive group",
          "trigger": "A parent group is hovered or focus-visible.",
          "visual": "Border strengthens; accent surfaces use the accent border.",
          "behavior": "Feedback follows the parent control."
        },
        {
          "name": "interactive within",
          "trigger": "The surface is hovered or contains focus.",
          "visual": "Border strengthens over 200ms.",
          "behavior": "Does not become keyboard interactive by itself."
        }
      ],
      "keyboard": [],
      "accessibilitySpec": {
        "semantics": "Default element is a non-semantic <div>. surfaceStyles can style another semantic root.",
        "accessibleName": "The surface has no name by default.",
        "requirements": [
          "Add a heading, region label, list semantics, or interactive wrapper when content needs structure.",
          "Never imply clickability through interaction styling without a keyboard-operable element."
        ]
      },
      "implementation": {
        "importStatement": "import { Surface, surfaceStyles } from '@ai-created/ui';",
        "clientComponent": false,
        "notes": [
          "Surface forwards a div ref and native HTML attributes.",
          "Use surfaceStyles to apply the same visual contract to a semantic article, section, or link."
        ]
      },
      "guidance": {
        "dos": [
          "Use consistent padding for peer surfaces.",
          "Choose inset when the content should visually recede."
        ],
        "donts": [
          "Do not nest multiple bordered surfaces without a clear hierarchy.",
          "Do not add group interaction to a non-interactive card."
        ]
      },
      "testing": {
        "unit": [
          "Maps every variant, padding, and interaction value.",
          "Consumer className overrides default utilities."
        ],
        "interaction": [
          "Group and focus-within borders respond to their documented triggers."
        ],
        "accessibility": [
          "Semantic wrappers retain their roles and names."
        ],
        "visual": [
          "Cover all variants plus interaction borders in both themes."
        ]
      },
      "relatedComponents": [
        "notice",
        "empty-state",
        "modal"
      ],
      "controls": {
        "variant": {
          "type": "select",
          "label": "Variant",
          "defaultValue": "default",
          "options": [
            "default",
            "muted",
            "accent",
            "inset",
            "success",
            "warning",
            "info",
            "error"
          ]
        },
        "padding": {
          "type": "select",
          "label": "Padding",
          "defaultValue": "none",
          "options": [
            "none",
            "sm",
            "md",
            "lg",
            "xl",
            "responsive"
          ]
        },
        "interaction": {
          "type": "select",
          "label": "Interaction",
          "defaultValue": "none",
          "options": [
            "none",
            "group",
            "within"
          ]
        }
      },
      "construction": {
        "asset": {
          "kind": "component",
          "figmaName": "Components/Layout/Surface",
          "localName": "Surface",
          "canvasApplicability": "Publish as a container component with nested content enabled."
        },
        "autoLayout": {
          "applicable": true,
          "direction": "vertical",
          "gap": "Inherited from content",
          "padding": "0, 16px, 24px, 32px, 40px, or responsive 32px/48px",
          "alignment": "Stretch children horizontally",
          "wrap": "Content controlled",
          "notes": [
            "The component supplies padding only; child spacing belongs to the content composition."
          ]
        },
        "resizing": {
          "applicable": true,
          "width": "fill",
          "height": "hug",
          "minWidth": "0px",
          "maxWidth": "Parent controlled",
          "minHeight": "0px",
          "maxHeight": "Content controlled",
          "overflow": "visible",
          "notes": [
            "Use fixed height only for an explicitly specified media or data region."
          ]
        },
        "exposedProperties": [
          {
            "name": "variant",
            "label": "Variant",
            "type": "variant",
            "required": false,
            "defaultValue": "default",
            "options": [
              "default",
              "muted",
              "accent",
              "inset",
              "success",
              "warning",
              "info",
              "error"
            ],
            "codeMapping": "variant"
          },
          {
            "name": "padding",
            "label": "Padding",
            "type": "variant",
            "required": false,
            "defaultValue": "none",
            "options": [
              "none",
              "sm",
              "md",
              "lg",
              "xl",
              "responsive"
            ],
            "codeMapping": "padding"
          },
          {
            "name": "interaction",
            "label": "Interaction",
            "type": "variant",
            "required": false,
            "defaultValue": "none",
            "options": [
              "none",
              "group",
              "within"
            ],
            "codeMapping": "interaction"
          },
          {
            "name": "content",
            "label": "Content",
            "type": "slot",
            "required": true,
            "defaultValue": null,
            "codeMapping": "children"
          }
        ],
        "nestedAssets": [
          {
            "name": "Content",
            "kind": "slot",
            "required": true,
            "description": "Consumer-owned semantic content.",
            "codeMapping": "children"
          }
        ],
        "contentLimits": [
          {
            "target": "Nested surfaces",
            "limit": "Maximum one bordered child layer in ordinary product UI",
            "overflowBehavior": "Flatten excess wrappers or remove an inner border.",
            "rationale": "Repeated framed layers obscure hierarchy."
          }
        ],
        "localization": {
          "translatable": [
            "Nested content only"
          ],
          "rtlBehavior": [
            "Container geometry is direction-neutral; nested content owns direction."
          ],
          "stressCases": [
            "Test with long nested copy and mixed-direction content."
          ]
        },
        "responsive": {
          "strategy": "Fill its parent while height follows content.",
          "breakpoints": [
            "md: responsive padding changes from 32px to 48px"
          ],
          "behavior": [
            "Responsive padding is the only built-in breakpoint behavior.",
            "Parent grids own column changes."
          ]
        },
        "limitations": {
          "figma": [
            "Interaction variants are visual demonstrations and do not make the Figma layer operable."
          ],
          "code": [
            "Surface has no semantics or interaction by itself; use a semantic wrapper when needed."
          ],
          "notApplicable": []
        },
        "governance": {
          "status": "stable",
          "ownerRole": "Design systems layout primitive owner",
          "lastReviewed": "2026-08-29",
          "canonicalSource": "src/components/Surface.tsx",
          "changePolicy": [
            "New variants must map to an approved semantic surface token pair.",
            "A breaking property, token, or behavior change requires design and engineering approval, a migration note, and a major release.",
            "The design asset, implementation, documentation, accessibility contract, and regression coverage must ship in the same change."
          ]
        }
      }
    },
    {
      "id": "notice",
      "name": "Notice",
      "category": "Actions & feedback",
      "purpose": "Communicates an informational, success, warning, or error message.",
      "useWhen": [
        "Explaining status near the relevant content"
      ],
      "avoidWhen": [
        "Transient toast notifications",
        "Multi-step forms needing field-level errors"
      ],
      "api": [
        {
          "prop": "variant",
          "type": "NoticeVariant",
          "defaultValue": "default",
          "description": "default, info, success, warning, or error."
        },
        {
          "prop": "title",
          "type": "string",
          "defaultValue": "undefined",
          "description": "Optional notice heading."
        },
        {
          "prop": "children",
          "type": "ReactNode",
          "defaultValue": "undefined",
          "description": "Message content."
        },
        {
          "prop": "role",
          "type": "string",
          "defaultValue": "status or alert",
          "description": "Override the semantic role."
        },
        {
          "prop": "aria-live",
          "type": "polite | assertive | off",
          "defaultValue": "polite or assertive",
          "description": "Override announcement behavior."
        }
      ],
      "states": [
        "default",
        "info",
        "success",
        "warning",
        "error"
      ],
      "accessibility": [
        "Defaults to status, or alert for error.",
        "Icons are decorative."
      ],
      "composition": [
        "Use ErrorReport for expandable technical details."
      ],
      "code": "<Notice variant=\"warning\" title=\"Review required\">Check the highlighted fields.</Notice>",
      "slug": "notice",
      "summary": "An inline live-region message for informational, positive, cautionary, or error feedback.",
      "sourcePath": "src/components/Notice.tsx",
      "packageExports": [
        "Notice",
        "NoticeProps",
        "NoticeVariant"
      ],
      "anatomy": [
        {
          "name": "Surface",
          "description": "Semantic-tone container and live region.",
          "required": true,
          "semanticElement": "div"
        },
        {
          "name": "Status icon",
          "description": "Decorative tone reinforcement.",
          "required": false
        },
        {
          "name": "Title",
          "description": "Optional concise message heading.",
          "required": false
        },
        {
          "name": "Body",
          "description": "Supporting explanation or recovery guidance.",
          "required": false
        }
      ],
      "visualSpec": {
        "measurements": [
          {
            "property": "Padding",
            "value": "24px"
          },
          {
            "property": "Content gap",
            "value": "16px"
          },
          {
            "property": "Icon",
            "value": "16 × 16px"
          },
          {
            "property": "Radius",
            "value": "6px"
          },
          {
            "property": "Title/body gap",
            "value": "8px"
          }
        ],
        "rules": [
          "Align icon and content to the top unless centered is intentionally used.",
          "Use semantic surface, border, text, and icon color as a coordinated set."
        ]
      },
      "designTokens": [
        {
          "token": "--color-*-surface",
          "purpose": "Tone background."
        },
        {
          "token": "--color-*-border",
          "purpose": "Tone border."
        },
        {
          "token": "--color-info / success / warning / error",
          "purpose": "Title and icon."
        },
        {
          "token": "--color-text2",
          "purpose": "Body copy."
        }
      ],
      "stateDefinitions": [
        {
          "name": "default",
          "trigger": "Neutral message.",
          "visual": "Default Surface with no status icon.",
          "behavior": "Polite status announcement."
        },
        {
          "name": "info",
          "trigger": "Informational message.",
          "visual": "Blue semantic treatment and info icon.",
          "behavior": "Polite status announcement."
        },
        {
          "name": "success",
          "trigger": "Successful outcome.",
          "visual": "Green semantic treatment and check icon.",
          "behavior": "Polite status announcement."
        },
        {
          "name": "warning",
          "trigger": "Caution or required review.",
          "visual": "Yellow semantic treatment and warning icon.",
          "behavior": "Polite status announcement."
        },
        {
          "name": "error",
          "trigger": "Failed outcome.",
          "visual": "Red semantic treatment and error icon.",
          "behavior": "Assertive alert announcement.",
          "accessibility": "Defaults to role alert and aria-live assertive."
        }
      ],
      "keyboard": [],
      "accessibilitySpec": {
        "semantics": "role=status by default; error uses role=alert. Both are overridable.",
        "accessibleName": "Title and body text form the announcement.",
        "requirements": [
          "Keep icons decorative.",
          "Avoid inserting a status region before its content is ready if it should be announced as a change.",
          "Use error only for information that merits an assertive interruption."
        ],
        "announcements": [
          "Default, info, success, and warning use polite live announcements.",
          "Error uses an assertive announcement."
        ]
      },
      "implementation": {
        "importStatement": "import { Notice } from '@ai-created/ui';",
        "clientComponent": false,
        "notes": [
          "The role and aria-live defaults are derived from variant.",
          "centered and hideIcon change presentation only.",
          "Use ErrorReport when technical details need disclosure and copying."
        ]
      },
      "guidance": {
        "dos": [
          "Explain what happened and the next useful step.",
          "Place the notice near the content it affects."
        ],
        "donts": [
          "Do not use for ephemeral toast positioning.",
          "Do not make every informational note assertive."
        ]
      },
      "testing": {
        "unit": [
          "Derives Surface variant, role, and aria-live correctly.",
          "Honors explicit role and aria-live overrides."
        ],
        "interaction": [
          "A newly rendered error is announced; centered and hidden-icon options preserve content."
        ],
        "accessibility": [
          "Icons are hidden and live-region semantics match severity."
        ],
        "visual": [
          "Capture every tone, title/body combination, centered treatment, and both themes."
        ]
      },
      "relatedComponents": [
        "error-report",
        "badge",
        "surface"
      ],
      "controls": {
        "variant": {
          "type": "select",
          "label": "Tone",
          "defaultValue": "default",
          "options": [
            "default",
            "info",
            "success",
            "warning",
            "error"
          ]
        },
        "title": {
          "type": "text",
          "label": "Title",
          "defaultValue": "Review required"
        },
        "centered": {
          "type": "boolean",
          "label": "Centered",
          "defaultValue": false
        },
        "hideIcon": {
          "type": "boolean",
          "label": "Hide icon",
          "defaultValue": false
        }
      },
      "construction": {
        "asset": {
          "kind": "component",
          "figmaName": "Components/Feedback/Notice",
          "localName": "Notice",
          "canvasApplicability": "Publish tone variants with title, message, icon visibility, and alignment properties."
        },
        "autoLayout": {
          "applicable": true,
          "direction": "horizontal",
          "gap": "16px",
          "padding": "24px",
          "alignment": "Start; optional centered composition",
          "wrap": "Content wraps",
          "notes": []
        },
        "resizing": {
          "applicable": true,
          "width": "fill",
          "height": "hug",
          "minWidth": "240px",
          "maxWidth": "Parent controlled",
          "minHeight": "Content controlled",
          "maxHeight": "Content controlled",
          "overflow": "visible",
          "notes": []
        },
        "exposedProperties": [
          {
            "name": "variant",
            "label": "Tone",
            "type": "variant",
            "required": false,
            "defaultValue": "default",
            "options": [
              "default",
              "info",
              "success",
              "warning",
              "error"
            ],
            "codeMapping": "variant"
          },
          {
            "name": "title",
            "label": "Title",
            "type": "text",
            "required": false,
            "defaultValue": null,
            "codeMapping": "title"
          },
          {
            "name": "message",
            "label": "Message",
            "type": "slot",
            "required": false,
            "defaultValue": null,
            "codeMapping": "children"
          },
          {
            "name": "centered",
            "label": "Centered",
            "type": "boolean",
            "required": false,
            "defaultValue": false,
            "codeMapping": "centered"
          },
          {
            "name": "hideIcon",
            "label": "Hide icon",
            "type": "boolean",
            "required": false,
            "defaultValue": false,
            "codeMapping": "hideIcon"
          },
          {
            "name": "icon",
            "label": "Status icon",
            "type": "instance-swap",
            "required": false,
            "defaultValue": null,
            "codeMapping": "Derived from variant; custom replacement is design-only and needs implementation review"
          }
        ],
        "nestedAssets": [
          {
            "name": "Surface",
            "kind": "primitive",
            "required": true,
            "description": "Semantic tone container.",
            "codeMapping": "<Surface> inside Notice"
          },
          {
            "name": "Status icon",
            "kind": "slot",
            "required": false,
            "description": "Decorative icon derived from tone.",
            "codeMapping": "Internal variant icon"
          },
          {
            "name": "Body",
            "kind": "slot",
            "required": false,
            "description": "Supporting content and recovery guidance.",
            "codeMapping": "children"
          }
        ],
        "contentLimits": [
          {
            "target": "Title",
            "limit": "One line, recommended maximum 48 characters",
            "overflowBehavior": "Wrap only when localization requires it.",
            "rationale": "The outcome should be understandable at a glance."
          },
          {
            "target": "Body",
            "limit": "Two short paragraphs or 240 characters",
            "overflowBehavior": "Move complex guidance into adjacent content.",
            "rationale": "Live-region announcements must remain concise."
          }
        ],
        "localization": {
          "translatable": [
            "Title",
            "Body"
          ],
          "rtlBehavior": [
            "Icon appears on the logical start side.",
            "Tone icon does not mirror."
          ],
          "stressCases": [
            "Test long recovery instructions.",
            "Verify announcement order in right-to-left mode."
          ]
        },
        "responsive": {
          "strategy": "Fill the containing content column.",
          "breakpoints": [
            "No internal breakpoint"
          ],
          "behavior": [
            "Allow copy to wrap.",
            "At very narrow widths, use centered only when the surrounding design is also centered."
          ]
        },
        "limitations": {
          "figma": [
            "Prototype presentation does not reproduce live-region announcements."
          ],
          "code": [
            "Custom role and aria-live values must remain aligned with severity."
          ],
          "notApplicable": []
        },
        "governance": {
          "status": "stable",
          "ownerRole": "Design systems feedback owner",
          "lastReviewed": "2026-08-29",
          "canonicalSource": "src/components/Notice.tsx",
          "changePolicy": [
            "Tone behavior changes require accessibility review of role and announcement priority.",
            "A breaking property, token, or behavior change requires design and engineering approval, a migration note, and a major release.",
            "The design asset, implementation, documentation, accessibility contract, and regression coverage must ship in the same change."
          ]
        }
      }
    },
    {
      "id": "skeleton",
      "name": "Skeleton",
      "category": "Actions & feedback",
      "purpose": "Reserves space while content is loading.",
      "useWhen": [
        "Loading predictable content regions"
      ],
      "avoidWhen": [
        "Unknown layouts where a spinner is clearer"
      ],
      "api": [
        {
          "prop": "className",
          "type": "string",
          "defaultValue": "undefined",
          "description": "Controls size and shape with utility classes."
        },
        {
          "prop": "...props",
          "type": "HTMLAttributes<HTMLDivElement>",
          "defaultValue": "undefined",
          "description": "Native div attributes."
        }
      ],
      "states": [
        "loading"
      ],
      "accessibility": [
        "The placeholder is hidden from assistive technology.",
        "Keep the loading context in surrounding content.",
        "Do not use as a replacement for a live loading announcement."
      ],
      "composition": [
        "Match the dimensions of the content it replaces."
      ],
      "code": "<Skeleton className=\"h-5 w-32\" />",
      "slug": "skeleton",
      "summary": "A decorative loading placeholder that reserves the final content footprint.",
      "sourcePath": "src/components/Skeleton.tsx",
      "packageExports": [
        "Skeleton",
        "SkeletonProps"
      ],
      "anatomy": [
        {
          "name": "Placeholder block",
          "description": "Consumer-sized pulse surface matching future content.",
          "required": true,
          "semanticElement": "div"
        }
      ],
      "visualSpec": {
        "measurements": [
          {
            "property": "Radius",
            "value": "6px by default"
          },
          {
            "property": "Width and height",
            "value": "Consumer-defined"
          },
          {
            "property": "Animation",
            "value": "Tailwind pulse; disabled for reduced motion"
          }
        ],
        "rules": [
          "Match the dimensions and shape of the content being loaded.",
          "Preserve stable layout between placeholder and resolved content."
        ]
      },
      "designTokens": [
        {
          "token": "--color-surface2",
          "purpose": "Placeholder fill."
        },
        {
          "token": "--radius-md",
          "purpose": "Default radius."
        }
      ],
      "stateDefinitions": [
        {
          "name": "loading",
          "trigger": "Content is pending.",
          "visual": "Surface2 block pulses unless reduced motion is requested.",
          "behavior": "Reserves layout only.",
          "accessibility": "Hidden from the accessibility tree."
        }
      ],
      "keyboard": [],
      "accessibilitySpec": {
        "semantics": "Decorative <div aria-hidden=\"true\">.",
        "accessibleName": "No accessible name; the surrounding loading region owns status.",
        "requirements": [
          "Provide a separate loading announcement when users need one.",
          "Do not put focusable content inside the skeleton.",
          "Respect reduced-motion behavior."
        ]
      },
      "implementation": {
        "importStatement": "import { Skeleton } from '@ai-created/ui';",
        "clientComponent": false,
        "notes": [
          "Set dimensions and alternate shapes with className.",
          "The placeholder is always aria-hidden and forwards div attributes."
        ]
      },
      "guidance": {
        "dos": [
          "Approximate the final content structure.",
          "Use a small group of meaningful shapes."
        ],
        "donts": [
          "Do not use arbitrary decorative skeleton grids.",
          "Do not leave skeletons visible after loading fails."
        ]
      },
      "testing": {
        "unit": [
          "Forwards className, ref, and div attributes.",
          "Always emits aria-hidden true."
        ],
        "interaction": [
          "Replaced content does not cause large layout shift."
        ],
        "accessibility": [
          "Loading status exists outside the hidden placeholder when required."
        ],
        "visual": [
          "Compare content and skeleton dimensions; verify reduced-motion rendering."
        ]
      },
      "relatedComponents": [
        "empty-state",
        "notice"
      ],
      "controls": {
        "shape": {
          "type": "select",
          "label": "Shape",
          "defaultValue": "content",
          "options": [
            "content",
            "text",
            "avatar"
          ]
        },
        "width": {
          "type": "select",
          "label": "Width",
          "defaultValue": "full",
          "options": [
            "short",
            "medium",
            "full"
          ]
        }
      },
      "construction": {
        "asset": {
          "kind": "component",
          "figmaName": "Components/Feedback/Skeleton",
          "localName": "Skeleton",
          "canvasApplicability": "Publish primitive shape presets but require authored compositions to match final content."
        },
        "autoLayout": {
          "applicable": true,
          "direction": "vertical",
          "gap": "8px for composition examples",
          "padding": "0px",
          "alignment": "Stretch or align to target content",
          "wrap": "Composition controlled",
          "notes": [
            "The exported code component is one block; multi-line examples are grouped instances."
          ]
        },
        "resizing": {
          "applicable": true,
          "width": "fill",
          "height": "fixed",
          "minWidth": "16px",
          "maxWidth": "Parent controlled",
          "minHeight": "4px",
          "maxHeight": "Target content height",
          "overflow": "clip",
          "notes": [
            "Width and height must match the content being reserved."
          ]
        },
        "exposedProperties": [
          {
            "name": "shape",
            "label": "Shape preset",
            "type": "variant",
            "required": false,
            "defaultValue": "content",
            "options": [
              "content",
              "text",
              "avatar"
            ],
            "codeMapping": "className sizing and radius utilities"
          },
          {
            "name": "width",
            "label": "Width preset",
            "type": "variant",
            "required": false,
            "defaultValue": "full",
            "options": [
              "short",
              "medium",
              "full"
            ],
            "codeMapping": "className width utility"
          }
        ],
        "nestedAssets": [
          {
            "name": "Placeholder block",
            "kind": "primitive",
            "required": true,
            "description": "One decorative loading surface.",
            "codeMapping": "<Skeleton className=\"...\" />"
          }
        ],
        "contentLimits": [
          {
            "target": "Composition",
            "limit": "Represent only the primary visible structure, usually three to seven blocks",
            "overflowBehavior": "Remove low-value decorative placeholders.",
            "rationale": "Too many shapes create noise and inaccurate expectations."
          }
        ],
        "localization": {
          "translatable": [],
          "rtlBehavior": [
            "Primitive geometry is direction-neutral; compositions follow content reading order."
          ],
          "stressCases": [
            "Verify placeholder widths are not based only on English copy.",
            "Test reduced motion."
          ]
        },
        "responsive": {
          "strategy": "Dimensions follow the final responsive content.",
          "breakpoints": [
            "Use the same breakpoints as the resolved component"
          ],
          "behavior": [
            "Update shape count and widths with the final layout.",
            "Prevent layout shift at every supported width."
          ]
        },
        "limitations": {
          "figma": [
            "Figma animation is illustrative and does not validate reduced-motion behavior."
          ],
          "code": [
            "The primitive does not announce loading; the surrounding region must do so."
          ],
          "notApplicable": []
        },
        "governance": {
          "status": "stable",
          "ownerRole": "Design systems feedback owner",
          "lastReviewed": "2026-08-29",
          "canonicalSource": "src/components/Skeleton.tsx",
          "changePolicy": [
            "New presets must correspond to repeated production content footprints.",
            "A breaking property, token, or behavior change requires design and engineering approval, a migration note, and a major release.",
            "The design asset, implementation, documentation, accessibility contract, and regression coverage must ship in the same change."
          ]
        }
      }
    },
    {
      "id": "empty-state",
      "name": "EmptyState",
      "category": "Layout & content",
      "purpose": "Explains why a collection has no content and offers a next step.",
      "useWhen": [
        "Empty lists, searches, or first-use screens"
      ],
      "avoidWhen": [
        "Loading states",
        "Error states"
      ],
      "api": [
        {
          "prop": "icon",
          "type": "LucideIcon",
          "defaultValue": "undefined",
          "description": "Optional decorative icon."
        },
        {
          "prop": "title",
          "type": "string",
          "defaultValue": "required",
          "description": "Short empty-state heading."
        },
        {
          "prop": "description",
          "type": "string",
          "defaultValue": "undefined",
          "description": "Supporting explanation."
        },
        {
          "prop": "children",
          "type": "ReactNode",
          "defaultValue": "undefined",
          "description": "Optional action content."
        },
        {
          "prop": "className",
          "type": "string",
          "defaultValue": "undefined",
          "description": "Additional classes."
        }
      ],
      "states": [
        "empty"
      ],
      "accessibility": [
        "Icon is decorative.",
        "Use a clear title and action label."
      ],
      "composition": [
        "Place actions as children, commonly a Button."
      ],
      "code": "<EmptyState title=\"No projects yet\" description=\"Create one to get started.\"><Button>Create project</Button></EmptyState>",
      "slug": "empty-state",
      "summary": "A calm, explanatory collection state with an optional next-step action.",
      "sourcePath": "src/components/EmptyState.tsx",
      "packageExports": [
        "EmptyState",
        "EmptyStateProps"
      ],
      "anatomy": [
        {
          "name": "Surface",
          "description": "Muted responsive container.",
          "required": true,
          "semanticElement": "div"
        },
        {
          "name": "Icon",
          "description": "Optional decorative context cue.",
          "required": false
        },
        {
          "name": "Title",
          "description": "Explains the empty condition.",
          "required": true
        },
        {
          "name": "Description",
          "description": "Optional reason or next-step guidance.",
          "required": false
        },
        {
          "name": "Action area",
          "description": "Optional children, usually one Button.",
          "required": false
        }
      ],
      "visualSpec": {
        "measurements": [
          {
            "property": "Padding",
            "value": "32px mobile / 48px md+"
          },
          {
            "property": "Icon",
            "value": "48 × 48px"
          },
          {
            "property": "Icon bottom margin",
            "value": "16px"
          },
          {
            "property": "Title/description gap",
            "value": "8px"
          },
          {
            "property": "Action top margin",
            "value": "24px"
          },
          {
            "property": "Copy width with icon",
            "value": "max-width 448px"
          }
        ],
        "rules": [
          "Center all content.",
          "Keep actions subordinate to the explanation.",
          "Use muted Surface styling rather than error styling."
        ]
      },
      "designTokens": [
        {
          "token": "--color-surface2",
          "purpose": "Muted Surface fill."
        },
        {
          "token": "--color-border",
          "purpose": "Container border."
        },
        {
          "token": "--color-text2",
          "purpose": "Title."
        },
        {
          "token": "--color-text3",
          "purpose": "Icon and description."
        }
      ],
      "stateDefinitions": [
        {
          "name": "empty",
          "trigger": "A successfully loaded collection has no items.",
          "visual": "Centered optional icon, copy, and action on a muted surface.",
          "behavior": "Action follows its own component behavior."
        }
      ],
      "keyboard": [
        {
          "key": "Tab",
          "action": "Moves to actions supplied as children.",
          "condition": "Only when an action is present."
        }
      ],
      "accessibilitySpec": {
        "semantics": "Non-semantic Surface container; child action preserves its own semantics.",
        "accessibleName": "The visible title names the state in reading order.",
        "requirements": [
          "Use a clear title that distinguishes empty from loading or failure.",
          "Icons are decorative.",
          "Supply a heading element through composition when the surrounding page hierarchy requires one."
        ]
      },
      "implementation": {
        "importStatement": "import { EmptyState, Button } from '@ai-created/ui';",
        "clientComponent": false,
        "notes": [
          "Accepts all div attributes and forwards the container ref through Surface.",
          "The icon prop accepts a Lucide icon component and marks it decorative."
        ]
      },
      "guidance": {
        "dos": [
          "Explain why the view is empty when it may be surprising.",
          "Offer one concrete next step when the user can resolve it."
        ],
        "donts": [
          "Do not show during loading.",
          "Do not use upbeat copy for data loss or a failure."
        ]
      },
      "testing": {
        "unit": [
          "Renders required title and optional icon, description, and children.",
          "Forwards Surface div attributes."
        ],
        "interaction": [
          "Optional action remains keyboard operable."
        ],
        "accessibility": [
          "Reading order is icon-hidden, title, description, action."
        ],
        "visual": [
          "Capture with/without icon and action at mobile and desktop padding."
        ]
      },
      "relatedComponents": [
        "skeleton",
        "notice",
        "button",
        "surface"
      ],
      "controls": {
        "title": {
          "type": "text",
          "label": "Title",
          "defaultValue": "No projects yet"
        },
        "description": {
          "type": "text",
          "label": "Description",
          "defaultValue": "Create one to get started."
        }
      },
      "construction": {
        "asset": {
          "kind": "component",
          "figmaName": "Components/Content/Empty state",
          "localName": "EmptyState",
          "canvasApplicability": "Publish icon, title, description, and action properties with nested action support."
        },
        "autoLayout": {
          "applicable": true,
          "direction": "vertical",
          "gap": "8px copy gap; 16px icon gap; 24px action gap",
          "padding": "32px mobile; 48px desktop",
          "alignment": "Center",
          "wrap": "Content wraps",
          "notes": []
        },
        "resizing": {
          "applicable": true,
          "width": "fill",
          "height": "hug",
          "minWidth": "240px",
          "maxWidth": "Parent controlled",
          "minHeight": "Content controlled",
          "maxHeight": "Content controlled",
          "overflow": "visible",
          "notes": []
        },
        "exposedProperties": [
          {
            "name": "icon",
            "label": "Icon",
            "type": "instance-swap",
            "required": false,
            "defaultValue": null,
            "codeMapping": "icon"
          },
          {
            "name": "title",
            "label": "Title",
            "type": "text",
            "required": true,
            "defaultValue": "No projects yet",
            "codeMapping": "title"
          },
          {
            "name": "description",
            "label": "Description",
            "type": "text",
            "required": false,
            "defaultValue": null,
            "codeMapping": "description"
          },
          {
            "name": "action",
            "label": "Action",
            "type": "slot",
            "required": false,
            "defaultValue": null,
            "codeMapping": "children"
          }
        ],
        "nestedAssets": [
          {
            "name": "Surface",
            "kind": "primitive",
            "required": true,
            "description": "Muted responsive container.",
            "codeMapping": "Internal Surface"
          },
          {
            "name": "Icon",
            "kind": "slot",
            "required": false,
            "description": "Decorative 48px context icon.",
            "codeMapping": "icon"
          },
          {
            "name": "Action",
            "kind": "slot",
            "required": false,
            "description": "Usually one Button.",
            "codeMapping": "children"
          }
        ],
        "contentLimits": [
          {
            "target": "Title",
            "limit": "One line preferred, maximum two lines",
            "overflowBehavior": "Wrap to two lines; then revise.",
            "rationale": "The state should remain quickly identifiable."
          },
          {
            "target": "Description",
            "limit": "Maximum three lines or about 180 characters",
            "overflowBehavior": "Move longer onboarding guidance outside the component.",
            "rationale": "The empty state is an orientation point, not a help article."
          },
          {
            "target": "Actions",
            "limit": "One primary action, optional one secondary text link",
            "overflowBehavior": "Remove lower-priority actions.",
            "rationale": "A single next step reduces decision cost."
          }
        ],
        "localization": {
          "translatable": [
            "Title",
            "Description",
            "Action labels"
          ],
          "rtlBehavior": [
            "Centered composition is direction-neutral.",
            "Directional action icons mirror."
          ],
          "stressCases": [
            "Test twice-length copy.",
            "Test without an icon.",
            "Test at 200% text size."
          ]
        },
        "responsive": {
          "strategy": "Fill the empty collection region.",
          "breakpoints": [
            "md: padding increases from 32px to 48px"
          ],
          "behavior": [
            "Copy remains centered.",
            "Parent sets vertical placement and available height."
          ]
        },
        "limitations": {
          "figma": [
            "Do not detach to fit extra actions or long instructional content."
          ],
          "code": [
            "Title is rendered as text, so the consumer must provide surrounding heading hierarchy when needed."
          ],
          "notApplicable": []
        },
        "governance": {
          "status": "stable",
          "ownerRole": "Design systems content pattern owner",
          "lastReviewed": "2026-08-29",
          "canonicalSource": "src/components/EmptyState.tsx",
          "changePolicy": [
            "Copy templates and action hierarchy changes require content design review.",
            "A breaking property, token, or behavior change requires design and engineering approval, a migration note, and a major release.",
            "The design asset, implementation, documentation, accessibility contract, and regression coverage must ship in the same change."
          ]
        }
      }
    },
    {
      "id": "error-report",
      "name": "ErrorReport",
      "category": "Actions & feedback",
      "purpose": "Presents a user-facing error with optional copyable diagnostics.",
      "useWhen": [
        "A recoverable operation failed",
        "Users may need to share debug details"
      ],
      "avoidWhen": [
        "Sensitive diagnostics should never be exposed"
      ],
      "api": [
        {
          "prop": "message",
          "type": "string",
          "defaultValue": "required",
          "description": "User-facing error message."
        },
        {
          "prop": "title",
          "type": "string",
          "defaultValue": "Something went wrong",
          "description": "Error heading."
        },
        {
          "prop": "details",
          "type": "string | null",
          "defaultValue": "undefined",
          "description": "Optional technical details."
        },
        {
          "prop": "timestamp",
          "type": "string",
          "defaultValue": "current ISO time",
          "description": "Optional diagnostic timestamp."
        }
      ],
      "states": [
        "collapsed",
        "expanded",
        "copied"
      ],
      "accessibility": [
        "Error notice is announced as an alert.",
        "Details disclosure exposes expanded state and controls."
      ],
      "composition": [
        "Place in the failed content region."
      ],
      "code": "<ErrorReport message=\"Unable to load projects.\" details={error.message} />",
      "slug": "error-report",
      "summary": "An error notice with optional expandable, copyable diagnostics for support workflows.",
      "sourcePath": "src/components/ErrorReport.tsx",
      "packageExports": [
        "ErrorReport",
        "ErrorReportProps"
      ],
      "anatomy": [
        {
          "name": "Error notice",
          "description": "Assertive error container and title.",
          "required": true
        },
        {
          "name": "Message",
          "description": "User-facing failure summary.",
          "required": true
        },
        {
          "name": "Disclosure",
          "description": "Optional Debug info toggle.",
          "required": false,
          "semanticElement": "button"
        },
        {
          "name": "Diagnostic block",
          "description": "Expanded preformatted details, timestamp, and URL.",
          "required": false,
          "semanticElement": "pre"
        },
        {
          "name": "Copy action",
          "description": "Copies the assembled diagnostics.",
          "required": false,
          "semanticElement": "button"
        }
      ],
      "visualSpec": {
        "measurements": [
          {
            "property": "Notice padding",
            "value": "24px"
          },
          {
            "property": "Internal vertical gap",
            "value": "8px"
          },
          {
            "property": "Diagnostic padding",
            "value": "12px"
          },
          {
            "property": "Disclosure icon",
            "value": "12 × 12px"
          }
        ],
        "rules": [
          "Keep the user-facing message readable without opening diagnostics.",
          "Prevent long diagnostic lines from breaking the containing layout."
        ]
      },
      "designTokens": [
        {
          "token": "--color-error / --color-error-surface / --color-error-border",
          "purpose": "Error Notice treatment."
        },
        {
          "token": "--color-surface2",
          "purpose": "Diagnostic code block."
        },
        {
          "token": "--color-text2 / --color-text3",
          "purpose": "Message and low-emphasis controls."
        }
      ],
      "stateDefinitions": [
        {
          "name": "collapsed",
          "trigger": "Details exist but disclosure is closed.",
          "visual": "Message and Debug info disclosure are visible.",
          "behavior": "Technical details are not mounted.",
          "accessibility": "aria-expanded is false and aria-controls points to the details id."
        },
        {
          "name": "expanded",
          "trigger": "Disclosure is activated.",
          "visual": "Diagnostic pre block and copy action appear.",
          "behavior": "Details include error, timestamp, and current path.",
          "accessibility": "aria-expanded is true."
        },
        {
          "name": "copied",
          "trigger": "Clipboard write resolves.",
          "visual": "Copy action becomes Copied for two seconds.",
          "behavior": "Diagnostic string is on the clipboard."
        },
        {
          "name": "copy failed",
          "trigger": "Clipboard write rejects or is unavailable.",
          "visual": "Copy action becomes Copy failed for two seconds.",
          "behavior": "The rejection is handled without an unhandled promise and the user may retry.",
          "accessibility": "The polite live status announces the failure."
        }
      ],
      "keyboard": [
        {
          "key": "Enter / Space",
          "action": "Toggles diagnostic disclosure when focused."
        },
        {
          "key": "Enter / Space",
          "action": "Copies diagnostics from the copy button."
        },
        {
          "key": "Tab",
          "action": "Moves through disclosure and copy action when present."
        }
      ],
      "accessibilitySpec": {
        "semantics": "Composes role=alert Notice plus native disclosure and copy buttons.",
        "accessibleName": "The Notice title and message identify the error; buttons have visible names.",
        "requirements": [
          "Never include credentials, tokens, personal data, or full query strings in details.",
          "Preserve aria-expanded and aria-controls on the disclosure.",
          "Copy success and failure feedback must remain visible long enough to perceive."
        ],
        "announcements": [
          "The error Notice is assertively announced.",
          "Clipboard success or failure is announced through a polite live status."
        ]
      },
      "implementation": {
        "importStatement": "import { ErrorReport } from '@ai-created/ui';",
        "clientComponent": true,
        "notes": [
          "details controls whether the disclosure and copy action exist.",
          "timestamp should be supplied for deterministic reports; otherwise it is created when debugInfo renders.",
          "The URL is limited to origin and pathname.",
          "Clipboard rejection is handled and the feedback timer is cleared on replacement and unmount."
        ]
      },
      "guidance": {
        "dos": [
          "Write the message for the user before adding technical detail.",
          "Sanitize all detail strings at the error boundary."
        ],
        "donts": [
          "Do not pass stack traces containing secrets.",
          "Do not use for field-level validation."
        ]
      },
      "testing": {
        "unit": [
          "Assembles diagnostic text with optional details and timestamp.",
          "Resets copy success or failure feedback after two seconds."
        ],
        "interaction": [
          "Disclosure toggles; clipboard resolution and rejection both produce the expected status."
        ],
        "accessibility": [
          "Alert, disclosure relationship, button names, focus order, and polite clipboard status are valid."
        ],
        "visual": [
          "Capture collapsed, expanded, copied, copy-failed, long-details, and both themes."
        ]
      },
      "relatedComponents": [
        "notice",
        "button"
      ],
      "controls": {
        "title": {
          "type": "text",
          "label": "Title",
          "defaultValue": "Something went wrong"
        },
        "message": {
          "type": "text",
          "label": "Message",
          "defaultValue": "Unable to load projects."
        },
        "details": {
          "type": "text",
          "label": "Details",
          "defaultValue": "Request timed out."
        }
      },
      "construction": {
        "asset": {
          "kind": "component",
          "figmaName": "Components/Feedback/Error report",
          "localName": "ErrorReport",
          "canvasApplicability": "Publish collapsed, expanded, and copied interactive states as component variants."
        },
        "autoLayout": {
          "applicable": true,
          "direction": "vertical",
          "gap": "8px",
          "padding": "Inherited 24px Notice padding",
          "alignment": "Stretch",
          "wrap": "Content wraps",
          "notes": []
        },
        "resizing": {
          "applicable": true,
          "width": "fill",
          "height": "hug",
          "minWidth": "280px",
          "maxWidth": "Parent controlled",
          "minHeight": "Content controlled",
          "maxHeight": "Content controlled",
          "overflow": "visible",
          "notes": []
        },
        "exposedProperties": [
          {
            "name": "title",
            "label": "Title",
            "type": "text",
            "required": false,
            "defaultValue": "Something went wrong",
            "codeMapping": "title"
          },
          {
            "name": "message",
            "label": "Message",
            "type": "text",
            "required": true,
            "defaultValue": null,
            "codeMapping": "message"
          },
          {
            "name": "details",
            "label": "Debug details",
            "type": "text",
            "required": false,
            "defaultValue": null,
            "codeMapping": "details"
          },
          {
            "name": "expanded",
            "label": "Expanded preview",
            "type": "boolean",
            "required": false,
            "defaultValue": false,
            "codeMapping": "Internal disclosure state; no public prop"
          },
          {
            "name": "copied",
            "label": "Copied preview",
            "type": "boolean",
            "required": false,
            "defaultValue": false,
            "codeMapping": "Transient internal state; no public prop"
          }
        ],
        "nestedAssets": [
          {
            "name": "Notice",
            "kind": "subcomponent",
            "required": true,
            "description": "Assertive error container.",
            "codeMapping": "<Notice variant=\"error\">"
          },
          {
            "name": "Disclosure",
            "kind": "subcomponent",
            "required": false,
            "description": "Controls diagnostic visibility.",
            "codeMapping": "Internal native button"
          },
          {
            "name": "Copy action",
            "kind": "subcomponent",
            "required": false,
            "description": "Copies sanitized diagnostics.",
            "codeMapping": "Internal Button"
          }
        ],
        "contentLimits": [
          {
            "target": "Title",
            "limit": "One line preferred",
            "overflowBehavior": "Allow localization wrap.",
            "rationale": "The failure category should remain concise."
          },
          {
            "target": "Message",
            "limit": "One or two sentences",
            "overflowBehavior": "Move troubleshooting steps below the component.",
            "rationale": "Users need a clear outcome and next step."
          },
          {
            "target": "Details",
            "limit": "Sanitized diagnostic text only, maximum practical payload 4KB",
            "overflowBehavior": "Provide a support attachment flow for larger logs.",
            "rationale": "Large or sensitive logs should not be exposed inline."
          }
        ],
        "localization": {
          "translatable": [
            "Title",
            "Message",
            "Disclosure label",
            "Copy state"
          ],
          "rtlBehavior": [
            "Disclosure chevron mirrors in right-to-left layouts.",
            "Diagnostic payload remains in its source direction."
          ],
          "stressCases": [
            "Test translated button labels.",
            "Test mixed-direction stack traces.",
            "Test an absent details value."
          ]
        },
        "responsive": {
          "strategy": "Fill the failed content region.",
          "breakpoints": [
            "No internal breakpoint"
          ],
          "behavior": [
            "Technical text wraps and remains horizontally scroll-safe.",
            "Place the component near the failed content."
          ]
        },
        "limitations": {
          "figma": [
            "Clipboard and disclosure behavior must be annotated because Figma cannot validate browser permissions."
          ],
          "code": [
            "Never pass credentials, tokens, personal data, or full URLs with sensitive query parameters to details."
          ],
          "notApplicable": []
        },
        "governance": {
          "status": "stable",
          "ownerRole": "Design systems reliability pattern owner",
          "lastReviewed": "2026-08-29",
          "canonicalSource": "src/components/ErrorReport.tsx",
          "changePolicy": [
            "Changes to diagnostic content require privacy and security review.",
            "A breaking property, token, or behavior change requires design and engineering approval, a migration note, and a major release.",
            "The design asset, implementation, documentation, accessibility contract, and regression coverage must ship in the same change."
          ]
        }
      }
    },
    {
      "id": "field",
      "name": "Field family / style helpers",
      "category": "Fields & selection",
      "purpose": "Builds consistently labelled and described form controls.",
      "useWhen": [
        "Text inputs, textareas, and grouped controls"
      ],
      "avoidWhen": [
        "Unrelated display text"
      ],
      "api": [
        {
          "prop": "FieldGroup",
          "type": "HTMLAttributes<HTMLDivElement>",
          "defaultValue": "undefined",
          "description": "Groups a label, control, and hint with one 8px sibling gap."
        },
        {
          "prop": "FieldLabel",
          "type": "LabelHTMLAttributes<HTMLLabelElement>",
          "defaultValue": "undefined",
          "description": "Native label without exterior spacing."
        },
        {
          "prop": "FieldLegend",
          "type": "HTMLAttributes<HTMLSpanElement>",
          "defaultValue": "undefined",
          "description": "Visual legend text without exterior spacing; not a semantic fieldset legend."
        },
        {
          "prop": "FieldHint",
          "type": "HTMLAttributes<HTMLParagraphElement>",
          "defaultValue": "undefined",
          "description": "Supporting or validation text without exterior spacing."
        },
        {
          "prop": "TextInput",
          "type": "InputHTMLAttributes<HTMLInputElement>",
          "defaultValue": "undefined",
          "description": "Native text input."
        },
        {
          "prop": "TextArea",
          "type": "TextareaHTMLAttributes<HTMLTextAreaElement>",
          "defaultValue": "undefined",
          "description": "Native textarea."
        }
      ],
      "states": [
        "default",
        "focus-visible",
        "disabled",
        "invalid"
      ],
      "accessibility": [
        "Connect labels with htmlFor and id.",
        "Use aria-describedby for hints and errors."
      ],
      "composition": [
        "Use FieldGroup as the single vertical-spacing owner around FieldLabel, TextInput or TextArea, and optional FieldHint.",
        "Style helpers support custom controls inside the same FieldGroup spacing contract."
      ],
      "code": "<FieldGroup>\n  <FieldLabel htmlFor=\"email\">Email</FieldLabel>\n  <TextInput id=\"email\" type=\"email\" aria-describedby=\"email-hint\" />\n  <FieldHint id=\"email-hint\">We will never share it.</FieldHint>\n</FieldGroup>",
      "slug": "field",
      "summary": "Composable labels, hints, text controls, and style helpers for consistent form fields.",
      "sourcePath": "src/components/Field.tsx",
      "packageExports": [
        "FieldGroup",
        "FieldLabel",
        "FieldLegend",
        "FieldHint",
        "TextInput",
        "TextArea",
        "fieldGroupStyles",
        "fieldLabelStyles",
        "fieldLegendStyles",
        "fieldHintStyles",
        "inputStyles"
      ],
      "anatomy": [
        {
          "name": "Field group",
          "description": "Layout wrapper for one logical field.",
          "required": true,
          "semanticElement": "div"
        },
        {
          "name": "Label",
          "description": "Visible name associated to the control.",
          "required": true,
          "semanticElement": "label"
        },
        {
          "name": "Control",
          "description": "Native input or textarea.",
          "required": true,
          "semanticElement": "input / textarea"
        },
        {
          "name": "Hint",
          "description": "Optional help or validation message associated by id.",
          "required": false,
          "semanticElement": "p"
        },
        {
          "name": "Visual legend",
          "description": "Optional uppercase group caption; not a semantic legend.",
          "required": false,
          "semanticElement": "span"
        }
      ],
      "visualSpec": {
        "measurements": [
          {
            "property": "FieldGroup sibling gap",
            "value": "8px"
          },
          {
            "property": "Label, legend, and hint exterior margin",
            "value": "0px"
          },
          {
            "property": "Input padding",
            "value": "16px horizontal / 12px vertical"
          },
          {
            "property": "Input radius",
            "value": "6px"
          },
          {
            "property": "Input border",
            "value": "1px"
          }
        ],
        "rules": [
          "FieldGroup is the single owner of vertical spacing between its label, control, and optional hint.",
          "Keep labels persistently visible; placeholders are examples, not labels.",
          "Apply validation meaning and relationships in consuming code.",
          "TextArea disables manual resizing by default."
        ]
      },
      "designTokens": [
        {
          "token": "--color-surface2",
          "purpose": "Control background."
        },
        {
          "token": "--color-control-border / --color-control-border-strong",
          "purpose": "Contrast-safe default and hover boundaries."
        },
        {
          "token": "--color-accent",
          "purpose": "Focused border."
        },
        {
          "token": "--color-text / --color-text2 / --color-text3",
          "purpose": "Value, label/help, and placeholder hierarchy."
        },
        {
          "token": "--radius-md",
          "purpose": "Control radius."
        }
      ],
      "stateDefinitions": [
        {
          "name": "default",
          "trigger": "Idle enabled field.",
          "visual": "Surface2 fill, standard border, primary value, secondary label.",
          "behavior": "Native text editing."
        },
        {
          "name": "focus-visible",
          "trigger": "Keyboard focus enters the control.",
          "visual": "Global focus outline plus accent border.",
          "behavior": "Accepts keyboard input."
        },
        {
          "name": "disabled",
          "trigger": "Native disabled is set.",
          "visual": "50% opacity and not-allowed cursor.",
          "behavior": "Editing and focus are suppressed."
        },
        {
          "name": "invalid",
          "trigger": "Consumer sets aria-invalid and error styling/content.",
          "visual": "Consumer must add a clear error treatment.",
          "behavior": "Validation message explains correction.",
          "accessibility": "aria-invalid and aria-describedby connect the error."
        }
      ],
      "keyboard": [
        {
          "key": "Tab / Shift+Tab",
          "action": "Moves focus into or out of the control."
        },
        {
          "key": "Standard text editing keys",
          "action": "Edit, select, undo, and navigate text according to the native platform."
        }
      ],
      "accessibilitySpec": {
        "semantics": "Native label, input, textarea, and paragraph primitives; FieldGroup and FieldLegend are presentation-only.",
        "accessibleName": "Associate FieldLabel with the control using htmlFor/id, or nest the control.",
        "requirements": [
          "Connect FieldHint and validation errors with aria-describedby.",
          "Set aria-invalid when validation fails.",
          "Use a real fieldset and legend for grouped choices; FieldLegend is only a styled span.",
          "Preserve native autocomplete, inputMode, type, and name attributes."
        ]
      },
      "implementation": {
        "importStatement": "import { FieldGroup, FieldLabel, FieldHint, TextInput, TextArea } from '@ai-created/ui';",
        "clientComponent": true,
        "notes": [
          "Every primitive forwards its native ref and attributes.",
          "FieldGroup owns the 8px sibling gap; FieldLabel, FieldLegend, and FieldHint add no exterior margin.",
          "Style helpers support custom controls inside the same group spacing contract without duplicating class contracts.",
          "The family does not generate ids or accessibility relationships for the consumer."
        ]
      },
      "guidance": {
        "dos": [
          "Use concise noun-phrase labels and useful format hints.",
          "Show validation next to the field and explain resolution."
        ],
        "donts": [
          "Do not use placeholder text as the only label.",
          "Do not use FieldLegend as a substitute for semantic fieldset/legend."
        ]
      },
      "testing": {
        "unit": [
          "Each primitive forwards refs and native props.",
          "Style helpers merge consumer overrides last and only FieldGroup supplies exterior sibling spacing."
        ],
        "interaction": [
          "Label click focuses the associated control and typing updates the form model."
        ],
        "accessibility": [
          "Label, description, validation, autocomplete, and disabled semantics are correct at responsive widths and 200% text zoom."
        ],
        "visual": [
          "Measure label-to-input, label-to-textarea, and control-to-hint gaps; assert equal-height Field and Dropdown labels produce equal control tops; capture wrapped labels, no-hint, invalid, disabled, responsive, and both-theme states."
        ]
      },
      "relatedComponents": [
        "checkbox",
        "radio-group",
        "slider",
        "dropdown"
      ],
      "controls": {
        "control": {
          "type": "select",
          "label": "Control",
          "defaultValue": "input",
          "options": [
            "input",
            "textarea"
          ]
        },
        "label": {
          "type": "text",
          "label": "Label",
          "defaultValue": "Email"
        },
        "hint": {
          "type": "text",
          "label": "Hint",
          "defaultValue": "We will never share it."
        },
        "disabled": {
          "type": "boolean",
          "label": "Disabled",
          "defaultValue": false
        }
      },
      "construction": {
        "asset": {
          "kind": "component",
          "figmaName": "Components/Forms/Field",
          "localName": "Field family",
          "canvasApplicability": "Publish a nested field component with input and textarea instance swaps plus state properties."
        },
        "autoLayout": {
          "applicable": true,
          "direction": "vertical",
          "gap": "8px",
          "padding": "0px",
          "alignment": "Stretch",
          "wrap": "Content wraps",
          "notes": [
            "FieldGroup owns the sibling gap; FieldLabel, FieldLegend, controls, and FieldHint do not add exterior spacing."
          ]
        },
        "resizing": {
          "applicable": true,
          "width": "fill",
          "height": "hug",
          "minWidth": "160px",
          "maxWidth": "Parent controlled",
          "minHeight": "44px plus labels and hints",
          "maxHeight": "Content controlled",
          "overflow": "visible",
          "notes": []
        },
        "exposedProperties": [
          {
            "name": "control",
            "label": "Control",
            "type": "instance-swap",
            "required": false,
            "defaultValue": "TextInput",
            "options": [
              "TextInput",
              "TextArea"
            ],
            "codeMapping": "TextInput or TextArea child"
          },
          {
            "name": "label",
            "label": "Label",
            "type": "text",
            "required": true,
            "defaultValue": "Label",
            "codeMapping": "FieldLabel children"
          },
          {
            "name": "hint",
            "label": "Hint or error",
            "type": "text",
            "required": false,
            "defaultValue": null,
            "codeMapping": "FieldHint children"
          },
          {
            "name": "disabled",
            "label": "Disabled",
            "type": "boolean",
            "required": false,
            "defaultValue": false,
            "codeMapping": "disabled on the native control"
          },
          {
            "name": "invalid",
            "label": "Invalid",
            "type": "boolean",
            "required": false,
            "defaultValue": false,
            "codeMapping": "aria-invalid on the native control plus semantic hint content"
          },
          {
            "name": "required",
            "label": "Required",
            "type": "boolean",
            "required": false,
            "defaultValue": false,
            "codeMapping": "required on the native control and a localized label indicator"
          }
        ],
        "nestedAssets": [
          {
            "name": "FieldGroup",
            "kind": "primitive",
            "required": true,
            "description": "Vertical field composition root.",
            "codeMapping": "FieldGroup"
          },
          {
            "name": "FieldLabel",
            "kind": "subcomponent",
            "required": true,
            "description": "Visible native label.",
            "codeMapping": "FieldLabel"
          },
          {
            "name": "Control",
            "kind": "slot",
            "required": true,
            "description": "TextInput, TextArea, or an equivalent labelled control.",
            "codeMapping": "TextInput, TextArea, or styled custom control"
          },
          {
            "name": "FieldHint",
            "kind": "subcomponent",
            "required": false,
            "description": "Description, requirement, or validation message.",
            "codeMapping": "FieldHint"
          }
        ],
        "contentLimits": [
          {
            "target": "Label",
            "limit": "One concise line preferred",
            "overflowBehavior": "Allow wrap, never truncate.",
            "rationale": "Every field needs an unambiguous name."
          },
          {
            "target": "Hint or error",
            "limit": "One or two short sentences",
            "overflowBehavior": "Move extended help outside the field.",
            "rationale": "Immediate guidance should be scannable."
          },
          {
            "target": "Text area",
            "limit": "Default visible size should cover the expected response, then grow or scroll",
            "overflowBehavior": "Use a counter or explicit maximum for constrained data.",
            "rationale": "Input size communicates expected content."
          }
        ],
        "localization": {
          "translatable": [
            "Label",
            "Placeholder",
            "Hint",
            "Validation message"
          ],
          "rtlBehavior": [
            "Text and control direction follow the locale or the entered data type.",
            "Required indicators stay next to the logical end of the label."
          ],
          "stressCases": [
            "Test labels at twice English length.",
            "Test mixed-direction user input.",
            "Test errors at 200% text size."
          ]
        },
        "responsive": {
          "strategy": "Fill its form column.",
          "breakpoints": [
            "No internal breakpoint"
          ],
          "behavior": [
            "Parent form controls column count.",
            "Never reduce the control below 160px unless the data format explicitly allows it."
          ]
        },
        "limitations": {
          "figma": [
            "Figma properties cannot guarantee label, hint, and control ID associations."
          ],
          "code": [
            "Consumers must connect htmlFor, id, aria-describedby, required, and aria-invalid correctly."
          ],
          "notApplicable": []
        },
        "governance": {
          "status": "stable",
          "ownerRole": "Design systems form foundations owner",
          "lastReviewed": "2026-08-29",
          "canonicalSource": "src/components/Field.tsx",
          "changePolicy": [
            "New field primitives require form accessibility and validation-pattern review.",
            "A breaking property, token, or behavior change requires design and engineering approval, a migration note, and a major release.",
            "The design asset, implementation, documentation, accessibility contract, and regression coverage must ship in the same change."
          ]
        }
      }
    },
    {
      "id": "checkbox",
      "name": "Checkbox",
      "category": "Fields & selection",
      "purpose": "Controls an independent boolean choice.",
      "useWhen": [
        "One or more independent options"
      ],
      "avoidWhen": [
        "Mutually exclusive choices"
      ],
      "api": [
        {
          "prop": "checked",
          "type": "boolean",
          "defaultValue": "required",
          "description": "Controlled checked state."
        },
        {
          "prop": "onChange",
          "type": "(checked: boolean) => void",
          "defaultValue": "required",
          "description": "Called when the value changes."
        },
        {
          "prop": "label",
          "type": "string",
          "defaultValue": "required",
          "description": "Visible accessible label."
        },
        {
          "prop": "disabled",
          "type": "boolean",
          "defaultValue": "false",
          "description": "Disables the native input."
        },
        {
          "prop": "className",
          "type": "string",
          "defaultValue": "undefined",
          "description": "Additional classes."
        }
      ],
      "states": [
        "checked",
        "unchecked",
        "disabled",
        "focus-visible"
      ],
      "accessibility": [
        "Uses a native checkbox and label.",
        "Forwards the input ref."
      ],
      "composition": [
        "Use inside a FieldGroup when additional help is needed."
      ],
      "code": "<Checkbox checked={accepted} onChange={setAccepted} label=\"I agree\" />",
      "slug": "checkbox",
      "summary": "A controlled native checkbox for one independent boolean choice.",
      "sourcePath": "src/components/Checkbox.tsx",
      "packageExports": [
        "Checkbox",
        "CheckboxProps"
      ],
      "anatomy": [
        {
          "name": "Label wrapper",
          "description": "Full clickable label and layout root.",
          "required": true,
          "semanticElement": "label"
        },
        {
          "name": "Native input",
          "description": "Visually hidden checkbox owning state and semantics.",
          "required": true,
          "semanticElement": "input[type=checkbox]"
        },
        {
          "name": "Visual box",
          "description": "16px state indicator and focus target proxy.",
          "required": true
        },
        {
          "name": "Check icon",
          "description": "Decorative selected mark.",
          "required": false
        },
        {
          "name": "Label text",
          "description": "Visible accessible name.",
          "required": true
        }
      ],
      "visualSpec": {
        "measurements": [
          {
            "property": "Indicator",
            "value": "16 × 16px"
          },
          {
            "property": "Indicator radius",
            "value": "4px"
          },
          {
            "property": "Content gap",
            "value": "10px"
          },
          {
            "property": "Check icon",
            "value": "12 × 12px, 3px stroke"
          },
          {
            "property": "Label text",
            "value": "12px"
          }
        ],
        "rules": [
          "The whole label is clickable.",
          "Keep label adjacent to the indicator.",
          "Use checkbox only for choices that can stand independently."
        ]
      },
      "designTokens": [
        {
          "token": "--color-action-primary",
          "purpose": "Checked fill and border."
        },
        {
          "token": "--color-on-action",
          "purpose": "Checked mark."
        },
        {
          "token": "--color-control-border / --color-control-border-strong",
          "purpose": "Unchecked and hover boundary."
        },
        {
          "token": "--color-focus",
          "purpose": "Peer focus-visible outline."
        },
        {
          "token": "--color-text2",
          "purpose": "Label."
        },
        {
          "token": "--motion-fast",
          "purpose": "State transition."
        }
      ],
      "stateDefinitions": [
        {
          "name": "checked",
          "trigger": "checked is true.",
          "visual": "Solid action fill with white check.",
          "behavior": "Activation requests false through onChange.",
          "accessibility": "Native checked state is exposed."
        },
        {
          "name": "unchecked",
          "trigger": "checked is false.",
          "visual": "Transparent box with strong border.",
          "behavior": "Activation requests true through onChange."
        },
        {
          "name": "disabled",
          "trigger": "disabled is true.",
          "visual": "Indicator and label use 50% opacity; cursor is not-allowed.",
          "behavior": "Native input cannot focus or change."
        },
        {
          "name": "focus-visible",
          "trigger": "Keyboard focus reaches the hidden input.",
          "visual": "Visual box receives 2px outline with 3px offset.",
          "behavior": "Space toggles the input."
        }
      ],
      "keyboard": [
        {
          "key": "Space",
          "action": "Toggles the focused checkbox."
        },
        {
          "key": "Tab / Shift+Tab",
          "action": "Moves focus to or from an enabled checkbox."
        }
      ],
      "accessibilitySpec": {
        "semantics": "Native checkbox nested in an associated label.",
        "accessibleName": "Required visible label string supplies the name.",
        "requirements": [
          "State is controlled; update checked in onChange.",
          "Do not hide or replace the visible label with color/icon only.",
          "Use disabled for unavailable choices."
        ]
      },
      "implementation": {
        "importStatement": "import { Checkbox } from '@ai-created/ui';",
        "clientComponent": false,
        "notes": [
          "A generated id connects the label and input.",
          "The component forwards the HTMLInputElement ref.",
          "onChange receives the next boolean value rather than a DOM event."
        ]
      },
      "guidance": {
        "dos": [
          "Use affirmative labels that make sense when checked.",
          "Group related checkboxes under a visible group heading."
        ],
        "donts": [
          "Do not use for mutually exclusive options.",
          "Do not require users to infer the unchecked meaning from a negative label."
        ]
      },
      "testing": {
        "unit": [
          "Reflects controlled checked and disabled props.",
          "Calls onChange once with the next value."
        ],
        "interaction": [
          "Label click and Space toggle; disabled state does not."
        ],
        "accessibility": [
          "Native checkbox has visible associated label and focus indicator."
        ],
        "visual": [
          "Capture checked/unchecked, hover, focus, disabled, long label, and both themes."
        ]
      },
      "relatedComponents": [
        "radio-group",
        "toggle",
        "field"
      ],
      "controls": {
        "checked": {
          "type": "boolean",
          "label": "Checked",
          "defaultValue": false
        },
        "disabled": {
          "type": "boolean",
          "label": "Disabled",
          "defaultValue": false
        },
        "label": {
          "type": "text",
          "label": "Label",
          "defaultValue": "I agree"
        }
      },
      "construction": {
        "asset": {
          "kind": "component",
          "figmaName": "Components/Forms/Checkbox",
          "localName": "Checkbox",
          "canvasApplicability": "Publish checked, unchecked, disabled, hover, and focus states with a text property."
        },
        "autoLayout": {
          "applicable": true,
          "direction": "horizontal",
          "gap": "10px",
          "padding": "0px",
          "alignment": "Center vertically",
          "wrap": "Label wraps",
          "notes": []
        },
        "resizing": {
          "applicable": true,
          "width": "hug",
          "height": "hug",
          "minWidth": "44px interaction area recommended",
          "maxWidth": "Parent controlled",
          "minHeight": "44px target recommended",
          "maxHeight": "Content controlled",
          "overflow": "visible",
          "notes": []
        },
        "exposedProperties": [
          {
            "name": "checked",
            "label": "Checked",
            "type": "boolean",
            "required": true,
            "defaultValue": false,
            "codeMapping": "checked"
          },
          {
            "name": "disabled",
            "label": "Disabled",
            "type": "boolean",
            "required": false,
            "defaultValue": false,
            "codeMapping": "disabled"
          },
          {
            "name": "label",
            "label": "Label",
            "type": "text",
            "required": true,
            "defaultValue": "I agree",
            "codeMapping": "label"
          }
        ],
        "nestedAssets": [
          {
            "name": "Native input",
            "kind": "primitive",
            "required": true,
            "description": "Visually hidden checkbox that owns semantics.",
            "codeMapping": "<input type=\"checkbox\">"
          },
          {
            "name": "Indicator",
            "kind": "subcomponent",
            "required": true,
            "description": "16px visual check surface.",
            "codeMapping": "Internal visual span"
          },
          {
            "name": "Label",
            "kind": "slot",
            "required": true,
            "description": "Visible choice label.",
            "codeMapping": "label"
          }
        ],
        "contentLimits": [
          {
            "target": "Label",
            "limit": "One sentence, recommended maximum two lines",
            "overflowBehavior": "Wrap naturally; do not truncate.",
            "rationale": "The consequence of the choice must remain explicit."
          }
        ],
        "localization": {
          "translatable": [
            "Label"
          ],
          "rtlBehavior": [
            "Indicator sits on the logical start side.",
            "Checkmark does not mirror."
          ],
          "stressCases": [
            "Test two-line labels.",
            "Test 200% text size and a 44px minimum target."
          ]
        },
        "responsive": {
          "strategy": "Hug content up to the parent width.",
          "breakpoints": [
            "No internal breakpoint"
          ],
          "behavior": [
            "Label wraps while indicator remains aligned to the first line.",
            "Parent controls list spacing."
          ]
        },
        "limitations": {
          "figma": [
            "Prototype checked state does not validate native input behavior."
          ],
          "code": [
            "Component is controlled; the consumer must update checked in onChange."
          ],
          "notApplicable": []
        },
        "governance": {
          "status": "stable",
          "ownerRole": "Design systems form foundations owner",
          "lastReviewed": "2026-08-29",
          "canonicalSource": "src/components/Checkbox.tsx",
          "changePolicy": [
            "State or target-size changes require input accessibility review.",
            "A breaking property, token, or behavior change requires design and engineering approval, a migration note, and a major release.",
            "The design asset, implementation, documentation, accessibility contract, and regression coverage must ship in the same change."
          ]
        }
      }
    },
    {
      "id": "radio-group",
      "name": "RadioGroup",
      "category": "Fields & selection",
      "purpose": "Selects exactly one option from a set.",
      "useWhen": [
        "Mutually exclusive choices"
      ],
      "avoidWhen": [
        "Independent toggles",
        "Large searchable option sets"
      ],
      "api": [
        {
          "prop": "options",
          "type": "RadioOption<T>[]",
          "defaultValue": "required",
          "description": "Options with value, label, and optional disabled."
        },
        {
          "prop": "value",
          "type": "T",
          "defaultValue": "required",
          "description": "Controlled selected value."
        },
        {
          "prop": "onChange",
          "type": "(value: T) => void",
          "defaultValue": "required",
          "description": "Called when selection changes."
        },
        {
          "prop": "legend",
          "type": "string",
          "defaultValue": "required",
          "description": "Fieldset legend."
        },
        {
          "prop": "name",
          "type": "string",
          "defaultValue": "generated id",
          "description": "Native radio group name."
        },
        {
          "prop": "disabled",
          "type": "boolean",
          "defaultValue": "false",
          "description": "Disables the group."
        },
        {
          "prop": "orientation",
          "type": "horizontal | vertical",
          "defaultValue": "vertical",
          "description": "Option layout."
        }
      ],
      "states": [
        "selected",
        "unselected",
        "disabled",
        "focus-visible"
      ],
      "accessibility": [
        "Uses fieldset, legend, and native radio inputs.",
        "Arrow keys follow native radio behavior."
      ],
      "composition": [
        "Use RadioOption values as stable domain keys."
      ],
      "code": "<RadioGroup options={options} value={size} onChange={setSize} legend=\"Size\" />",
      "slug": "radio-group",
      "summary": "A controlled fieldset for selecting exactly one value from a small, visible option set.",
      "sourcePath": "src/components/RadioGroup.tsx",
      "packageExports": [
        "RadioGroup",
        "RadioGroupProps",
        "RadioOption"
      ],
      "anatomy": [
        {
          "name": "Fieldset",
          "description": "Semantic group and disabled boundary.",
          "required": true,
          "semanticElement": "fieldset"
        },
        {
          "name": "Legend",
          "description": "Persistent group name.",
          "required": true,
          "semanticElement": "legend"
        },
        {
          "name": "Native radio",
          "description": "Visually hidden option input.",
          "required": true,
          "semanticElement": "input[type=radio]"
        },
        {
          "name": "Indicator",
          "description": "16px circular selection mark.",
          "required": true
        },
        {
          "name": "Option label",
          "description": "Visible name and 44px minimum row target.",
          "required": true,
          "semanticElement": "label"
        }
      ],
      "visualSpec": {
        "measurements": [
          {
            "property": "Option row minimum height",
            "value": "44px"
          },
          {
            "property": "Indicator",
            "value": "16 × 16px"
          },
          {
            "property": "Selected dot",
            "value": "9.6 × 9.6px"
          },
          {
            "property": "Indicator/label gap",
            "value": "10px"
          },
          {
            "property": "Vertical option gap",
            "value": "10px"
          },
          {
            "property": "Horizontal option gap",
            "value": "16px"
          }
        ],
        "rules": [
          "Show all choices when the set is short enough.",
          "Use vertical orientation when labels vary in length.",
          "Stable values belong in domain data; labels may change."
        ]
      },
      "designTokens": [
        {
          "token": "--color-action-primary",
          "purpose": "Selected indicator."
        },
        {
          "token": "--color-on-action",
          "purpose": "Selected inner mark."
        },
        {
          "token": "--color-control-border / --color-control-border-strong",
          "purpose": "Unselected and hover boundary."
        },
        {
          "token": "--color-focus",
          "purpose": "Peer focus outline."
        },
        {
          "token": "--color-text2",
          "purpose": "Legend and option labels."
        }
      ],
      "stateDefinitions": [
        {
          "name": "selected",
          "trigger": "Option value equals group value.",
          "visual": "Solid action circle with white inner dot.",
          "behavior": "This option is the group tab stop.",
          "accessibility": "Native checked state is exposed."
        },
        {
          "name": "unselected",
          "trigger": "Option value differs.",
          "visual": "Transparent indicator with strong border.",
          "behavior": "Activation selects this value."
        },
        {
          "name": "disabled",
          "trigger": "Group or option is disabled.",
          "visual": "50% opacity and not-allowed cursor.",
          "behavior": "Option cannot receive focus or selection."
        },
        {
          "name": "focus-visible",
          "trigger": "Keyboard focus reaches a radio.",
          "visual": "2px focus outline with 3px offset on indicator.",
          "behavior": "Native radio navigation remains active."
        }
      ],
      "keyboard": [
        {
          "key": "Arrow keys",
          "action": "Moves selection and focus among enabled native radios."
        },
        {
          "key": "Space",
          "action": "Selects the focused option."
        },
        {
          "key": "Tab",
          "action": "Enters or leaves the radio group as one stop."
        }
      ],
      "accessibilitySpec": {
        "semantics": "Native fieldset, legend, and radio inputs; an additional radiogroup wrapper carries aria-label.",
        "accessibleName": "The required legend names the group; each visible option label names its radio.",
        "requirements": [
          "Provide at least two meaningful options.",
          "Do not duplicate option values.",
          "Disabled options must remain understandable in context.",
          "Keep name stable when integrating with native form submission."
        ]
      },
      "implementation": {
        "importStatement": "import { RadioGroup, type RadioOption } from '@ai-created/ui';",
        "clientComponent": false,
        "notes": [
          "Generic string values preserve a narrow domain union.",
          "The fieldset ref is forwarded.",
          "onChange receives the chosen value directly."
        ]
      },
      "guidance": {
        "dos": [
          "Use for mutually exclusive peer choices.",
          "Order choices predictably and keep labels parallel."
        ],
        "donts": [
          "Do not use for independent booleans.",
          "Do not use for very large or searchable datasets."
        ]
      },
      "testing": {
        "unit": [
          "Renders options, generated ids/name, orientation, and disabled merging.",
          "Calls onChange with the activated value."
        ],
        "interaction": [
          "Pointer, Space, and arrow behavior select enabled options only."
        ],
        "accessibility": [
          "Fieldset/legend/input/label relationships and group name are valid."
        ],
        "visual": [
          "Capture orientations, selection, focus, group disabled, option disabled, and both themes."
        ]
      },
      "relatedComponents": [
        "checkbox",
        "dropdown",
        "field"
      ],
      "controls": {
        "value": {
          "type": "select",
          "label": "Selected",
          "defaultValue": "design",
          "options": [
            "design",
            "engineering",
            "research"
          ]
        },
        "orientation": {
          "type": "select",
          "label": "Orientation",
          "defaultValue": "vertical",
          "options": [
            "vertical",
            "horizontal"
          ]
        },
        "disabled": {
          "type": "boolean",
          "label": "Disabled",
          "defaultValue": false
        }
      },
      "construction": {
        "asset": {
          "kind": "component",
          "figmaName": "Components/Forms/Radio group",
          "localName": "RadioGroup",
          "canvasApplicability": "Publish vertical and horizontal group variants with nested option instances."
        },
        "autoLayout": {
          "applicable": true,
          "direction": "vertical",
          "gap": "12px between legend and options; 12px options vertically or 24px horizontally",
          "padding": "0px",
          "alignment": "Start",
          "wrap": "Horizontal options may wrap",
          "notes": []
        },
        "resizing": {
          "applicable": true,
          "width": "fill",
          "height": "hug",
          "minWidth": "200px",
          "maxWidth": "Parent controlled",
          "minHeight": "Content controlled",
          "maxHeight": "Content controlled",
          "overflow": "visible",
          "notes": []
        },
        "exposedProperties": [
          {
            "name": "orientation",
            "label": "Orientation",
            "type": "variant",
            "required": false,
            "defaultValue": "vertical",
            "options": [
              "vertical",
              "horizontal"
            ],
            "codeMapping": "orientation"
          },
          {
            "name": "value",
            "label": "Selected value",
            "type": "variant",
            "required": true,
            "defaultValue": null,
            "codeMapping": "value"
          },
          {
            "name": "disabled",
            "label": "Disabled",
            "type": "boolean",
            "required": false,
            "defaultValue": false,
            "codeMapping": "disabled"
          },
          {
            "name": "legend",
            "label": "Legend",
            "type": "text",
            "required": true,
            "defaultValue": "Choose one",
            "codeMapping": "legend"
          },
          {
            "name": "options",
            "label": "Options",
            "type": "slot",
            "required": true,
            "defaultValue": null,
            "codeMapping": "options"
          }
        ],
        "nestedAssets": [
          {
            "name": "Fieldset",
            "kind": "primitive",
            "required": true,
            "description": "Semantic group boundary.",
            "codeMapping": "<fieldset>"
          },
          {
            "name": "Legend",
            "kind": "subcomponent",
            "required": true,
            "description": "Group question or name.",
            "codeMapping": "<legend>"
          },
          {
            "name": "Radio option",
            "kind": "subcomponent",
            "required": true,
            "description": "Repeatable native radio, indicator, and label.",
            "codeMapping": "RadioOption data item"
          }
        ],
        "contentLimits": [
          {
            "target": "Options",
            "limit": "Recommended two to seven choices",
            "overflowBehavior": "Use Dropdown or a searchable picker for larger sets.",
            "rationale": "All choices should be comparable without excessive scanning."
          },
          {
            "target": "Option label",
            "limit": "One line preferred, maximum two lines",
            "overflowBehavior": "Wrap and align indicator with the first line.",
            "rationale": "Peer choices need parallel, concise wording."
          }
        ],
        "localization": {
          "translatable": [
            "Legend",
            "Option labels"
          ],
          "rtlBehavior": [
            "Options flow from logical start; horizontal arrow behavior follows browser radio semantics.",
            "Selection indicator does not mirror."
          ],
          "stressCases": [
            "Test the longest option in horizontal layout.",
            "Test mixed enabled and disabled options."
          ]
        },
        "responsive": {
          "strategy": "Vertical is the safe default.",
          "breakpoints": [
            "Parent-selected narrow breakpoint"
          ],
          "behavior": [
            "Change horizontal groups to vertical before labels collide.",
            "Do not change option order between widths."
          ]
        },
        "limitations": {
          "figma": [
            "Figma variants cannot reproduce native arrow-key selection."
          ],
          "code": [
            "Values are stable domain keys and must not be translated even when labels are."
          ],
          "notApplicable": []
        },
        "governance": {
          "status": "stable",
          "ownerRole": "Design systems form foundations owner",
          "lastReviewed": "2026-08-29",
          "canonicalSource": "src/components/RadioGroup.tsx",
          "changePolicy": [
            "Orientation or option behavior changes require keyboard-navigation review.",
            "A breaking property, token, or behavior change requires design and engineering approval, a migration note, and a major release.",
            "The design asset, implementation, documentation, accessibility contract, and regression coverage must ship in the same change."
          ]
        }
      }
    },
    {
      "id": "toggle",
      "name": "Toggle",
      "category": "Fields & selection",
      "purpose": "Switches a setting between on and off.",
      "useWhen": [
        "Immediate boolean settings"
      ],
      "avoidWhen": [
        "Actions that need confirmation",
        "Multiple-choice selection"
      ],
      "api": [
        {
          "prop": "checked",
          "type": "boolean",
          "defaultValue": "required",
          "description": "Controlled switch state."
        },
        {
          "prop": "onChange",
          "type": "(checked: boolean) => void",
          "defaultValue": "required",
          "description": "Called when toggled."
        },
        {
          "prop": "label",
          "type": "string",
          "defaultValue": "required",
          "description": "Visible label."
        },
        {
          "prop": "disabled",
          "type": "boolean",
          "defaultValue": "false",
          "description": "Disables the switch."
        },
        {
          "prop": "className",
          "type": "string",
          "defaultValue": "undefined",
          "description": "Additional classes."
        }
      ],
      "states": [
        "on",
        "off",
        "disabled",
        "focus-visible"
      ],
      "accessibility": [
        "Uses role switch and aria-checked.",
        "Forwards a button ref."
      ],
      "composition": [
        "Use beside settings that apply immediately."
      ],
      "code": "<Toggle checked={enabled} onChange={setEnabled} label=\"Enable notifications\" />",
      "slug": "toggle",
      "summary": "A controlled switch for an immediate on/off setting.",
      "sourcePath": "src/components/Toggle.tsx",
      "packageExports": [
        "Toggle",
        "ToggleProps"
      ],
      "anatomy": [
        {
          "name": "Switch button",
          "description": "44px-minimum interactive root.",
          "required": true,
          "semanticElement": "button[role=switch]"
        },
        {
          "name": "Track",
          "description": "40 × 24px visual state container and focus proxy.",
          "required": true
        },
        {
          "name": "Thumb",
          "description": "16px moving state marker.",
          "required": true
        },
        {
          "name": "Label",
          "description": "Visible switch name.",
          "required": true
        }
      ],
      "visualSpec": {
        "measurements": [
          {
            "property": "Target minimum height",
            "value": "44px"
          },
          {
            "property": "Track",
            "value": "40 × 24px"
          },
          {
            "property": "Thumb",
            "value": "16 × 16px"
          },
          {
            "property": "Thumb position",
            "value": "3px off / 25px on"
          },
          {
            "property": "Label gap",
            "value": "10px"
          }
        ],
        "rules": [
          "Use on for the enabled/active meaning.",
          "The setting takes effect on activation; use a checkbox or form action when changes are deferred."
        ]
      },
      "designTokens": [
        {
          "token": "--color-action-primary",
          "purpose": "On track fill and border."
        },
        {
          "token": "--color-on-action",
          "purpose": "Thumb fill."
        },
        {
          "token": "--color-surface2",
          "purpose": "Off track fill."
        },
        {
          "token": "--color-control-border / --color-control-border-strong",
          "purpose": "Off track and hover boundary."
        },
        {
          "token": "--color-focus",
          "purpose": "Track focus outline."
        },
        {
          "token": "--motion-fast",
          "purpose": "Track color and thumb movement."
        }
      ],
      "stateDefinitions": [
        {
          "name": "on",
          "trigger": "checked is true.",
          "visual": "Solid track; thumb translated right.",
          "behavior": "Activation requests false.",
          "accessibility": "aria-checked true."
        },
        {
          "name": "off",
          "trigger": "checked is false.",
          "visual": "Surface2 track; thumb at left.",
          "behavior": "Activation requests true.",
          "accessibility": "aria-checked false."
        },
        {
          "name": "disabled",
          "trigger": "disabled is true.",
          "visual": "Track and label at 50% opacity.",
          "behavior": "Native button cannot focus or activate."
        },
        {
          "name": "focus-visible",
          "trigger": "Keyboard focus reaches the switch.",
          "visual": "2px focus outline with 3px offset on track.",
          "behavior": "Space or Enter toggles."
        }
      ],
      "keyboard": [
        {
          "key": "Enter / Space",
          "action": "Toggles the switch."
        },
        {
          "key": "Tab / Shift+Tab",
          "action": "Moves focus to or from an enabled switch."
        }
      ],
      "accessibilitySpec": {
        "semantics": "Native button with role=switch and aria-checked.",
        "accessibleName": "Required visible label is included in the button name.",
        "requirements": [
          "Keep label text stable between states.",
          "State must be controlled and updated from onChange.",
          "Do not announce on/off again in the label; switch semantics already expose it."
        ]
      },
      "implementation": {
        "importStatement": "import { Toggle } from '@ai-created/ui';",
        "clientComponent": false,
        "notes": [
          "Forwards an HTMLButtonElement ref.",
          "onChange receives the next boolean immediately.",
          "The visual track and thumb are aria-hidden."
        ]
      },
      "guidance": {
        "dos": [
          "Use for settings applied immediately.",
          "Phrase labels as the feature being enabled."
        ],
        "donts": [
          "Do not use for commands such as Send or Save.",
          "Do not use if changing the value requires a separate submit step."
        ]
      },
      "testing": {
        "unit": [
          "Reflects checked and disabled state and calls onChange with the inverse.",
          "Always uses type button."
        ],
        "interaction": [
          "Pointer, Enter, and Space toggle once; disabled does not."
        ],
        "accessibility": [
          "Role, name, aria-checked, focus order, and focus indicator are valid."
        ],
        "visual": [
          "Capture on/off, hover, focus, disabled, and both themes."
        ]
      },
      "relatedComponents": [
        "checkbox",
        "theme",
        "field"
      ],
      "controls": {
        "checked": {
          "type": "boolean",
          "label": "On",
          "defaultValue": false
        },
        "disabled": {
          "type": "boolean",
          "label": "Disabled",
          "defaultValue": false
        },
        "label": {
          "type": "text",
          "label": "Label",
          "defaultValue": "Enable notifications"
        }
      },
      "construction": {
        "asset": {
          "kind": "component",
          "figmaName": "Components/Forms/Toggle",
          "localName": "Toggle",
          "canvasApplicability": "Publish on, off, disabled, hover, focus, and pressed states with a label property."
        },
        "autoLayout": {
          "applicable": true,
          "direction": "horizontal",
          "gap": "10px",
          "padding": "0px",
          "alignment": "Center vertically",
          "wrap": "Label wraps",
          "notes": []
        },
        "resizing": {
          "applicable": true,
          "width": "hug",
          "height": "hug",
          "minWidth": "44px",
          "maxWidth": "Parent controlled",
          "minHeight": "44px",
          "maxHeight": "Content controlled",
          "overflow": "visible",
          "notes": []
        },
        "exposedProperties": [
          {
            "name": "checked",
            "label": "On",
            "type": "boolean",
            "required": true,
            "defaultValue": false,
            "codeMapping": "checked"
          },
          {
            "name": "disabled",
            "label": "Disabled",
            "type": "boolean",
            "required": false,
            "defaultValue": false,
            "codeMapping": "disabled"
          },
          {
            "name": "label",
            "label": "Label",
            "type": "text",
            "required": true,
            "defaultValue": "Enable notifications",
            "codeMapping": "label"
          }
        ],
        "nestedAssets": [
          {
            "name": "Switch button",
            "kind": "primitive",
            "required": true,
            "description": "Native button with switch semantics.",
            "codeMapping": "<button role=\"switch\">"
          },
          {
            "name": "Track",
            "kind": "subcomponent",
            "required": true,
            "description": "40px by 24px state surface.",
            "codeMapping": "Internal span"
          },
          {
            "name": "Thumb",
            "kind": "subcomponent",
            "required": true,
            "description": "16px moving state indicator.",
            "codeMapping": "Internal span"
          },
          {
            "name": "Label",
            "kind": "slot",
            "required": true,
            "description": "Setting name.",
            "codeMapping": "label"
          }
        ],
        "contentLimits": [
          {
            "target": "Label",
            "limit": "Short setting phrase, maximum two lines",
            "overflowBehavior": "Wrap; never truncate.",
            "rationale": "The on and off consequence must be clear from the label and context."
          }
        ],
        "localization": {
          "translatable": [
            "Label"
          ],
          "rtlBehavior": [
            "Track remains visually consistent; label follows logical order.",
            "Do not reverse the semantic meaning of the checked state."
          ],
          "stressCases": [
            "Test a two-line label.",
            "Verify switch announcement in localized screen-reader output."
          ]
        },
        "responsive": {
          "strategy": "Intrinsic control within a parent settings row.",
          "breakpoints": [
            "No internal breakpoint"
          ],
          "behavior": [
            "Parent may place explanatory copy below.",
            "Maintain a 44px minimum target."
          ]
        },
        "limitations": {
          "figma": [
            "Prototype motion does not validate aria-checked."
          ],
          "code": [
            "The component is controlled and represents an immediate setting, not a deferred form choice."
          ],
          "notApplicable": []
        },
        "governance": {
          "status": "stable",
          "ownerRole": "Design systems form foundations owner",
          "lastReviewed": "2026-08-29",
          "canonicalSource": "src/components/Toggle.tsx",
          "changePolicy": [
            "Changes to state meaning or motion require accessibility and interaction review.",
            "A breaking property, token, or behavior change requires design and engineering approval, a migration note, and a major release.",
            "The design asset, implementation, documentation, accessibility contract, and regression coverage must ship in the same change."
          ]
        }
      }
    },
    {
      "id": "slider",
      "name": "Slider",
      "category": "Fields & selection",
      "purpose": "Selects a numeric value within a range.",
      "useWhen": [
        "Continuous or stepped numeric settings"
      ],
      "avoidWhen": [
        "Text values needing precise direct entry"
      ],
      "api": [
        {
          "prop": "value",
          "type": "number",
          "defaultValue": "required",
          "description": "Controlled numeric value."
        },
        {
          "prop": "onChange",
          "type": "(value: number) => void",
          "defaultValue": "required",
          "description": "Called with the new value."
        },
        {
          "prop": "label",
          "type": "string",
          "defaultValue": "required",
          "description": "Accessible label."
        },
        {
          "prop": "min",
          "type": "number",
          "defaultValue": "0",
          "description": "Minimum value."
        },
        {
          "prop": "max",
          "type": "number",
          "defaultValue": "100",
          "description": "Maximum value."
        },
        {
          "prop": "step",
          "type": "number",
          "defaultValue": "1",
          "description": "Increment."
        },
        {
          "prop": "showValue",
          "type": "boolean",
          "defaultValue": "true",
          "description": "Shows formatted value."
        },
        {
          "prop": "formatValue",
          "type": "(value: number) => string",
          "defaultValue": "String(value)",
          "description": "Formats the displayed value."
        }
      ],
      "states": [
        "default",
        "disabled",
        "focus-visible"
      ],
      "accessibility": [
        "Uses a labelled native range input.",
        "Forwards the input ref."
      ],
      "composition": [
        "Use formatValue for units or percentages."
      ],
      "code": "<Slider label=\"Opacity\" value={opacity} onChange={setOpacity} formatValue={(v) => `${v}%`} />",
      "slug": "slider",
      "summary": "A controlled native range input for choosing a numeric value from a bounded continuum.",
      "sourcePath": "src/components/Slider.tsx",
      "packageExports": [
        "Slider",
        "SliderProps"
      ],
      "anatomy": [
        {
          "name": "Header row",
          "description": "Persistent label and optional formatted output.",
          "required": true
        },
        {
          "name": "Label",
          "description": "Accessible range name.",
          "required": true,
          "semanticElement": "label"
        },
        {
          "name": "Value output",
          "description": "Optional formatted current value.",
          "required": false,
          "semanticElement": "output"
        },
        {
          "name": "Track",
          "description": "6px range with filled progress.",
          "required": true
        },
        {
          "name": "Thumb",
          "description": "22px draggable value handle.",
          "required": true
        }
      ],
      "visualSpec": {
        "measurements": [
          {
            "property": "Interaction row minimum height",
            "value": "44px"
          },
          {
            "property": "Track height",
            "value": "6px"
          },
          {
            "property": "Thumb",
            "value": "22 × 22px"
          },
          {
            "property": "Thumb border",
            "value": "2px"
          },
          {
            "property": "Label/track gap",
            "value": "8px"
          },
          {
            "property": "Hover thumb scale",
            "value": "1.15×"
          }
        ],
        "rules": [
          "Always expose units through formatValue when the raw number is ambiguous.",
          "Use a step appropriate to the precision users can perceive.",
          "Provide direct numeric entry instead when exact values matter."
        ]
      },
      "designTokens": [
        {
          "token": "--color-action-primary",
          "purpose": "Progress fill and thumb."
        },
        {
          "token": "--color-surface2",
          "purpose": "Unfilled track."
        },
        {
          "token": "--color-control-border",
          "purpose": "Track boundary."
        },
        {
          "token": "--color-bg",
          "purpose": "Thumb border separation."
        },
        {
          "token": "--color-focus",
          "purpose": "Range focus outline."
        }
      ],
      "stateDefinitions": [
        {
          "name": "default",
          "trigger": "Enabled range input.",
          "visual": "Action-color progress and thumb over surface track.",
          "behavior": "Pointer drag and native key commands change by step."
        },
        {
          "name": "disabled",
          "trigger": "disabled is true.",
          "visual": "50% opacity, no hover scale, not-allowed cursor.",
          "behavior": "Focus and input are suppressed."
        },
        {
          "name": "focus-visible",
          "trigger": "Keyboard focus reaches the range.",
          "visual": "2px focus outline with 3px offset.",
          "behavior": "Arrow and page keys adjust value."
        }
      ],
      "keyboard": [
        {
          "key": "Arrow Left / Down",
          "action": "Decreases by one step."
        },
        {
          "key": "Arrow Right / Up",
          "action": "Increases by one step."
        },
        {
          "key": "Home / End",
          "action": "Moves to minimum / maximum."
        },
        {
          "key": "Page Up / Page Down",
          "action": "Changes by the browser-defined larger increment."
        }
      ],
      "accessibilitySpec": {
        "semantics": "Native input[type=range] associated with a label and optional output.",
        "accessibleName": "Required label names the range.",
        "requirements": [
          "Provide useful min, max, and step values.",
          "aria-valuetext must match the visible formatted output.",
          "Do not use color alone to communicate the value; thumb position and output remain available."
        ]
      },
      "implementation": {
        "importStatement": "import { Slider } from '@ai-created/ui';",
        "clientComponent": false,
        "notes": [
          "onChange receives a number, not an event.",
          "Progress is clamped to 0-100%, including max equal to min.",
          "formatValue drives both visible output and aria-valuetext."
        ]
      },
      "guidance": {
        "dos": [
          "Use for values users understand spatially, such as volume or opacity.",
          "Show the current value when precision is useful."
        ],
        "donts": [
          "Do not use for unbounded values.",
          "Do not hide value formatting when units are unclear."
        ]
      },
      "testing": {
        "unit": [
          "Computes and clamps progress; handles max equal to min.",
          "Formats output and aria-valuetext consistently."
        ],
        "interaction": [
          "Pointer and keyboard changes call onChange with numeric values within range."
        ],
        "accessibility": [
          "Label, output htmlFor, range values, disabled state, and focus ring are valid."
        ],
        "visual": [
          "Capture min/mid/max, focus, hover, disabled, hidden output, custom units, and themes."
        ]
      },
      "relatedComponents": [
        "field",
        "dropdown"
      ],
      "controls": {
        "value": {
          "type": "number",
          "label": "Value",
          "defaultValue": 50,
          "min": 0,
          "max": 100,
          "step": 1
        },
        "showValue": {
          "type": "boolean",
          "label": "Show value",
          "defaultValue": true
        },
        "disabled": {
          "type": "boolean",
          "label": "Disabled",
          "defaultValue": false
        }
      },
      "construction": {
        "asset": {
          "kind": "component",
          "figmaName": "Components/Forms/Slider",
          "localName": "Slider",
          "canvasApplicability": "Publish value, disabled, and value-label properties with a number property for the thumb position."
        },
        "autoLayout": {
          "applicable": true,
          "direction": "vertical",
          "gap": "8px",
          "padding": "0px",
          "alignment": "Stretch",
          "wrap": "No wrap inside track",
          "notes": []
        },
        "resizing": {
          "applicable": true,
          "width": "fill",
          "height": "hug",
          "minWidth": "160px",
          "maxWidth": "Parent controlled",
          "minHeight": "44px including label and target",
          "maxHeight": "Content controlled",
          "overflow": "visible",
          "notes": []
        },
        "exposedProperties": [
          {
            "name": "value",
            "label": "Value",
            "type": "number",
            "required": true,
            "defaultValue": 50,
            "codeMapping": "value"
          },
          {
            "name": "min",
            "label": "Minimum",
            "type": "number",
            "required": false,
            "defaultValue": 0,
            "codeMapping": "min"
          },
          {
            "name": "max",
            "label": "Maximum",
            "type": "number",
            "required": false,
            "defaultValue": 100,
            "codeMapping": "max"
          },
          {
            "name": "step",
            "label": "Step",
            "type": "number",
            "required": false,
            "defaultValue": 1,
            "codeMapping": "step"
          },
          {
            "name": "showValue",
            "label": "Show value",
            "type": "boolean",
            "required": false,
            "defaultValue": true,
            "codeMapping": "showValue"
          },
          {
            "name": "disabled",
            "label": "Disabled",
            "type": "boolean",
            "required": false,
            "defaultValue": false,
            "codeMapping": "disabled"
          },
          {
            "name": "label",
            "label": "Label",
            "type": "text",
            "required": true,
            "defaultValue": "Value",
            "codeMapping": "label"
          }
        ],
        "nestedAssets": [
          {
            "name": "Label row",
            "kind": "subcomponent",
            "required": true,
            "description": "Label and optional formatted value.",
            "codeMapping": "Internal label/value elements"
          },
          {
            "name": "Range input",
            "kind": "primitive",
            "required": true,
            "description": "Native range control and focus target.",
            "codeMapping": "<input type=\"range\">"
          },
          {
            "name": "Track and thumb",
            "kind": "subcomponent",
            "required": true,
            "description": "CSS-painted current value representation.",
            "codeMapping": "Internal range styling"
          }
        ],
        "contentLimits": [
          {
            "target": "Label",
            "limit": "One concise line",
            "overflowBehavior": "Wrap only when required by localization.",
            "rationale": "The adjusted quantity should be immediately clear."
          },
          {
            "target": "Displayed value",
            "limit": "One short formatted number and unit",
            "overflowBehavior": "Use compact localized formatting.",
            "rationale": "Long prose does not belong in the value slot."
          }
        ],
        "localization": {
          "translatable": [
            "Label",
            "Formatted value and unit"
          ],
          "rtlBehavior": [
            "Document direction controls the track progression where platform conventions require it.",
            "Use locale-aware number and unit formatting."
          ],
          "stressCases": [
            "Test decimal separators.",
            "Test long units.",
            "Test minimum, maximum, and an invalid out-of-range input."
          ]
        },
        "responsive": {
          "strategy": "Track fills its form column.",
          "breakpoints": [
            "No internal breakpoint"
          ],
          "behavior": [
            "Keep at least 160px of usable track width.",
            "Pair with direct numeric entry when precision is critical."
          ]
        },
        "limitations": {
          "figma": [
            "Figma number properties demonstrate position but not keyboard increments."
          ],
          "code": [
            "min must be less than max, step must be positive, and value must remain within the range."
          ],
          "notApplicable": []
        },
        "governance": {
          "status": "stable",
          "ownerRole": "Design systems form foundations owner",
          "lastReviewed": "2026-08-29",
          "canonicalSource": "src/components/Slider.tsx",
          "changePolicy": [
            "Range, formatting, or keyboard changes require input accessibility review.",
            "A breaking property, token, or behavior change requires design and engineering approval, a migration note, and a major release.",
            "The design asset, implementation, documentation, accessibility contract, and regression coverage must ship in the same change."
          ]
        }
      }
    },
    {
      "id": "dropdown",
      "name": "Dropdown",
      "category": "Fields & selection",
      "purpose": "Selects one value from a compact list.",
      "useWhen": [
        "A listbox fits the available space"
      ],
      "avoidWhen": [
        "A few always-visible options",
        "Searchable large datasets"
      ],
      "api": [
        {
          "prop": "options",
          "type": "DropdownOption<T>[]",
          "defaultValue": "required",
          "description": "Options with value, label, and optional disabled."
        },
        {
          "prop": "value",
          "type": "T",
          "defaultValue": "required",
          "description": "Controlled selected value."
        },
        {
          "prop": "onChange",
          "type": "(value: T) => void",
          "defaultValue": "required",
          "description": "Called on selection."
        },
        {
          "prop": "label",
          "type": "string",
          "defaultValue": "required",
          "description": "Listbox label."
        },
        {
          "prop": "placeholder",
          "type": "string",
          "defaultValue": "Select an option",
          "description": "Fallback text."
        },
        {
          "prop": "disabled",
          "type": "boolean",
          "defaultValue": "false",
          "description": "Disables the listbox."
        }
      ],
      "states": [
        "closed",
        "open",
        "selected",
        "disabled"
      ],
      "accessibility": [
        "Headless UI supplies listbox keyboard and focus behavior.",
        "Forwards the trigger ref."
      ],
      "composition": [
        "Use DropdownOption disabled for unavailable values."
      ],
      "code": "<Dropdown options={options} value={sort} onChange={setSort} label=\"Sort by\" />",
      "slug": "dropdown",
      "summary": "An accessible controlled listbox for choosing one option in compact space.",
      "sourcePath": "src/components/Dropdown.tsx",
      "packageExports": [
        "Dropdown",
        "DropdownProps",
        "DropdownOption"
      ],
      "anatomy": [
        {
          "name": "Listbox root",
          "description": "Headless UI state and semantic owner.",
          "required": true
        },
        {
          "name": "Label",
          "description": "Persistent visible listbox name.",
          "required": true
        },
        {
          "name": "Trigger",
          "description": "Current selection or placeholder and disclosure icon.",
          "required": true,
          "semanticElement": "button"
        },
        {
          "name": "Options panel",
          "description": "Anchored, scrollable list of values.",
          "required": true
        },
        {
          "name": "Option",
          "description": "Selectable row with optional check marker and disabled state.",
          "required": true
        }
      ],
      "visualSpec": {
        "measurements": [
          {
            "property": "Label-to-trigger gap",
            "value": "8px"
          },
          {
            "property": "Trigger padding",
            "value": "16px left / 40px right / 12px vertical"
          },
          {
            "property": "Option padding",
            "value": "40px left / 16px right / 12px vertical"
          },
          {
            "property": "Radius",
            "value": "6px"
          },
          {
            "property": "Panel maximum height",
            "value": "240px"
          },
          {
            "property": "Panel offset",
            "value": "4px"
          },
          {
            "property": "Icons",
            "value": "16 × 16px"
          }
        ],
        "rules": [
          "Keep option labels on one line when possible; rows truncate overflow.",
          "The panel width follows the trigger.",
          "Use the placeholder only before a meaningful value is selected."
        ]
      },
      "designTokens": [
        {
          "token": "--color-surface2",
          "purpose": "Trigger and active option background."
        },
        {
          "token": "--color-surface",
          "purpose": "Options panel."
        },
        {
          "token": "--color-control-border / --color-control-border-strong",
          "purpose": "Trigger resting and hover boundaries."
        },
        {
          "token": "--color-border",
          "purpose": "Options panel border."
        },
        {
          "token": "--color-focus",
          "purpose": "Trigger focus outline."
        },
        {
          "token": "--color-accent",
          "purpose": "Selected check marker."
        },
        {
          "token": "--shadow-elevation-medium / --layer-dropdown",
          "purpose": "Options elevation and stacking."
        }
      ],
      "stateDefinitions": [
        {
          "name": "closed",
          "trigger": "Listbox is idle.",
          "visual": "Label and trigger show the current value or placeholder.",
          "behavior": "Activation opens the options panel."
        },
        {
          "name": "open",
          "trigger": "Trigger is activated.",
          "visual": "Anchored options panel appears below the trigger.",
          "behavior": "Focus and keyboard navigation move through options.",
          "accessibility": "Headless UI exposes expanded and listbox relationships."
        },
        {
          "name": "selected",
          "trigger": "Option value matches value.",
          "visual": "Primary text, medium weight, and accent check.",
          "behavior": "Choosing another option calls onChange and closes."
        },
        {
          "name": "disabled",
          "trigger": "Group or option is disabled.",
          "visual": "50% opacity and not-allowed cursor.",
          "behavior": "Disabled trigger cannot open; disabled option cannot select."
        }
      ],
      "keyboard": [
        {
          "key": "Enter / Space / Arrow Down",
          "action": "Opens the listbox and enters option navigation."
        },
        {
          "key": "Arrow Up / Arrow Down",
          "action": "Moves the active option."
        },
        {
          "key": "Enter / Space",
          "action": "Selects the active option."
        },
        {
          "key": "Escape",
          "action": "Closes without changing selection."
        },
        {
          "key": "Home / End",
          "action": "Moves to the first / last enabled option."
        },
        {
          "key": "Typeahead",
          "action": "Moves to an option matching typed characters."
        }
      ],
      "accessibilitySpec": {
        "semantics": "Headless UI Listbox with labelled button, options, and managed focus.",
        "accessibleName": "Required visible label names the listbox.",
        "requirements": [
          "Use stable unique option values.",
          "Provide a selected value that exists in options or intentionally show the placeholder.",
          "Disabled options must not be the only way to explain unavailable choices.",
          "Do not replace the listbox with a native select when rich behavior is unnecessary without considering platform benefits."
        ]
      },
      "implementation": {
        "importStatement": "import { Dropdown, type DropdownOption } from '@ai-created/ui';",
        "clientComponent": true,
        "notes": [
          "Generic string values preserve domain types.",
          "The trigger button ref is forwarded.",
          "Headless UI owns option roles, focus, and dismissal.",
          "An Enter handler normalizes trigger opening behavior."
        ]
      },
      "guidance": {
        "dos": [
          "Use for a moderate set of short, known options.",
          "Sort or group options in a predictable domain order."
        ],
        "donts": [
          "Do not use for two or three choices that should stay visible.",
          "Do not use for large datasets that require search or virtualization."
        ]
      },
      "testing": {
        "unit": [
          "Resolves selected label and placeholder and forwards trigger ref.",
          "Calls onChange with the selected enabled value."
        ],
        "interaction": [
          "Open, arrow, select, escape, outside dismissal, typeahead, and disabled flows work."
        ],
        "accessibility": [
          "Label, expanded state, active descendant/option semantics, and focus restoration are valid."
        ],
        "visual": [
          "Capture closed/open, placeholder, selected, active, disabled option/trigger, overflow, themes, and top alignment beside a Field with an equal-height label."
        ]
      },
      "relatedComponents": [
        "radio-group",
        "field"
      ],
      "controls": {
        "value": {
          "type": "select",
          "label": "Value",
          "defaultValue": "recent",
          "options": [
            "recent",
            "name",
            "status"
          ]
        },
        "disabled": {
          "type": "boolean",
          "label": "Disabled",
          "defaultValue": false
        },
        "label": {
          "type": "text",
          "label": "Label",
          "defaultValue": "Sort by"
        }
      },
      "construction": {
        "asset": {
          "kind": "component",
          "figmaName": "Components/Forms/Dropdown",
          "localName": "Dropdown",
          "canvasApplicability": "Publish closed and open variants with nested option instances and selected state."
        },
        "autoLayout": {
          "applicable": true,
          "direction": "vertical",
          "gap": "8px label gap; 4px trigger to menu",
          "padding": "0px",
          "alignment": "Stretch",
          "wrap": "Menu options do not wrap by default",
          "notes": []
        },
        "resizing": {
          "applicable": true,
          "width": "fill",
          "height": "hug",
          "minWidth": "200px",
          "maxWidth": "Parent controlled",
          "minHeight": "44px closed",
          "maxHeight": "Menu maximum 240px plus trigger",
          "overflow": "visible",
          "notes": [
            "Menu width matches the trigger and scrolls after its maximum height."
          ]
        },
        "exposedProperties": [
          {
            "name": "label",
            "label": "Label",
            "type": "text",
            "required": true,
            "defaultValue": "Select option",
            "codeMapping": "label"
          },
          {
            "name": "value",
            "label": "Selected value",
            "type": "variant",
            "required": true,
            "defaultValue": null,
            "codeMapping": "value"
          },
          {
            "name": "placeholder",
            "label": "Placeholder",
            "type": "text",
            "required": false,
            "defaultValue": "Select an option",
            "codeMapping": "placeholder"
          },
          {
            "name": "disabled",
            "label": "Disabled",
            "type": "boolean",
            "required": false,
            "defaultValue": false,
            "codeMapping": "disabled"
          },
          {
            "name": "open",
            "label": "Open preview",
            "type": "boolean",
            "required": false,
            "defaultValue": false,
            "codeMapping": "Internal Headless UI state; no public prop"
          },
          {
            "name": "options",
            "label": "Options",
            "type": "slot",
            "required": true,
            "defaultValue": null,
            "codeMapping": "options"
          }
        ],
        "nestedAssets": [
          {
            "name": "Listbox label",
            "kind": "primitive",
            "required": true,
            "description": "Accessible field label.",
            "codeMapping": "ListboxLabel"
          },
          {
            "name": "Trigger",
            "kind": "subcomponent",
            "required": true,
            "description": "Current value and chevron button.",
            "codeMapping": "ListboxButton"
          },
          {
            "name": "Options panel",
            "kind": "subcomponent",
            "required": true,
            "description": "Anchored, scrollable menu.",
            "codeMapping": "ListboxOptions"
          },
          {
            "name": "Option",
            "kind": "subcomponent",
            "required": true,
            "description": "Repeatable selected, active, or disabled row.",
            "codeMapping": "DropdownOption data item"
          }
        ],
        "contentLimits": [
          {
            "target": "Options",
            "limit": "Recommended two to fifteen options",
            "overflowBehavior": "Use search or autocomplete for larger datasets.",
            "rationale": "A long unfiltered list is inefficient."
          },
          {
            "target": "Option label",
            "limit": "One line, recommended maximum 40 characters",
            "overflowBehavior": "Truncate visually only when the full value is otherwise available.",
            "rationale": "Menu scanning depends on concise parallel labels."
          }
        ],
        "localization": {
          "translatable": [
            "Label",
            "Placeholder",
            "Option labels"
          ],
          "rtlBehavior": [
            "Text and chevron align to logical sides.",
            "Menu anchors to logical start."
          ],
          "stressCases": [
            "Test longest option.",
            "Test a translated placeholder.",
            "Test keyboard navigation in right-to-left mode."
          ]
        },
        "responsive": {
          "strategy": "Trigger fills its form column; menu matches trigger width.",
          "breakpoints": [
            "No internal breakpoint"
          ],
          "behavior": [
            "Keep the menu inside the viewport.",
            "Use a full-screen selection pattern only in a product-level mobile adaptation."
          ]
        },
        "limitations": {
          "figma": [
            "Figma open state does not validate focus movement, collision handling, or scrolling."
          ],
          "code": [
            "Options use stable untranslated values and localized labels."
          ],
          "notApplicable": []
        },
        "governance": {
          "status": "stable",
          "ownerRole": "Design systems form foundations owner",
          "lastReviewed": "2026-08-29",
          "canonicalSource": "src/components/Dropdown.tsx",
          "changePolicy": [
            "Selection behavior changes require Headless UI parity and keyboard testing.",
            "A breaking property, token, or behavior change requires design and engineering approval, a migration note, and a major release.",
            "The design asset, implementation, documentation, accessibility contract, and regression coverage must ship in the same change."
          ]
        }
      }
    },
    {
      "id": "tabs",
      "name": "Tabs / useTabPanelProps",
      "category": "Fields & selection",
      "purpose": "Switches between related views without leaving the page.",
      "useWhen": [
        "Small sets of peer content panels"
      ],
      "avoidWhen": [
        "Navigation between pages"
      ],
      "api": [
        {
          "prop": "tabs",
          "type": "Tab<T>[]",
          "defaultValue": "required",
          "description": "Keys, labels, and optional icons."
        },
        {
          "prop": "active",
          "type": "T",
          "defaultValue": "required",
          "description": "Active tab key."
        },
        {
          "prop": "onChange",
          "type": "(key: T) => void",
          "defaultValue": "required",
          "description": "Called when tab changes."
        },
        {
          "prop": "label",
          "type": "string",
          "defaultValue": "required",
          "description": "Tablist accessible label."
        },
        {
          "prop": "id",
          "type": "string",
          "defaultValue": "generated id",
          "description": "Stable group id for panels."
        }
      ],
      "states": [
        "active",
        "inactive",
        "focus-visible"
      ],
      "accessibility": [
        "Uses tablist, tab, and tabpanel relationships.",
        "Arrow, Home, and End keys move focus."
      ],
      "composition": [
        "Pass the same id to useTabPanelProps for each panel."
      ],
      "code": "const panel = useTabPanelProps(\"overview\", active, tabsId);\n<Tabs id={tabsId} tabs={tabs} active={active} onChange={setActive} label=\"Project views\" />\n<div {...panel}>Overview content</div>",
      "slug": "tabs",
      "summary": "A controlled, keyboard-navigable tablist for switching between peer panels in place.",
      "sourcePath": "src/components/Tabs.tsx",
      "packageExports": [
        "Tabs",
        "TabsProps",
        "Tab",
        "useTabPanelProps"
      ],
      "anatomy": [
        {
          "name": "Tablist",
          "description": "Named container coordinating arrow-key navigation.",
          "required": true,
          "semanticElement": "[role=tablist]"
        },
        {
          "name": "Tab",
          "description": "Roving-focus button with label and optional icon.",
          "required": true,
          "semanticElement": "button[role=tab]"
        },
        {
          "name": "Active indicator",
          "description": "2px accent line along the active tab.",
          "required": true
        },
        {
          "name": "Panel",
          "description": "Consumer-rendered view associated through useTabPanelProps.",
          "required": true,
          "semanticElement": "[role=tabpanel]"
        }
      ],
      "visualSpec": {
        "measurements": [
          {
            "property": "Tab padding",
            "value": "16px horizontal / 8px vertical"
          },
          {
            "property": "Tab gap",
            "value": "2px"
          },
          {
            "property": "Icon/label gap",
            "value": "8px"
          },
          {
            "property": "Active indicator",
            "value": "2px high"
          },
          {
            "property": "Top radius",
            "value": "6px"
          }
        ],
        "rules": [
          "Use one concise row when possible.",
          "The active state combines background, text, and indicator, not color alone.",
          "Render only peer views that share the same page context."
        ],
        "responsiveBehavior": [
          "The consumer should provide horizontal scrolling or an alternate pattern if labels overflow.",
          "Do not wrap one tablist over multiple lines."
        ]
      },
      "designTokens": [
        {
          "token": "--color-highlight",
          "purpose": "Active tab background."
        },
        {
          "token": "--color-accent",
          "purpose": "Active indicator."
        },
        {
          "token": "--color-text / --color-text2 / --color-text3",
          "purpose": "Active, hover, and inactive hierarchy."
        },
        {
          "token": "--motion-fast",
          "purpose": "Color transition."
        }
      ],
      "stateDefinitions": [
        {
          "name": "active",
          "trigger": "Tab key equals active.",
          "visual": "Highlight background, primary text, and accent indicator.",
          "behavior": "tabIndex is 0; associated panel is visible.",
          "accessibility": "aria-selected true."
        },
        {
          "name": "inactive",
          "trigger": "Tab key differs from active.",
          "visual": "Tertiary text that strengthens on hover.",
          "behavior": "tabIndex is -1; activation selects it.",
          "accessibility": "aria-selected false."
        },
        {
          "name": "focus-visible",
          "trigger": "Roving focus reaches a tab.",
          "visual": "Global button focus outline.",
          "behavior": "Arrow, Home, and End select and focus another tab."
        }
      ],
      "keyboard": [
        {
          "key": "Arrow Right / Arrow Left",
          "action": "Selects and focuses the next / previous tab with wraparound."
        },
        {
          "key": "Home / End",
          "action": "Selects and focuses the first / last tab."
        },
        {
          "key": "Enter / Space",
          "action": "Native button activation selects a focused tab."
        },
        {
          "key": "Tab",
          "action": "Moves from the active tab into the active panel or next focus target."
        }
      ],
      "accessibilitySpec": {
        "semantics": "Explicit tablist, tab, and tabpanel roles with aria-selected, aria-controls, and aria-labelledby.",
        "accessibleName": "Required label names the tablist; each tab label names its tab.",
        "requirements": [
          "Pass the same stable id to Tabs and useTabPanelProps so relationships are emitted.",
          "Render one panel for every tab key and hide inactive panels.",
          "Keep tab keys DOM-id safe and unique.",
          "Icons are decorative."
        ]
      },
      "implementation": {
        "importStatement": "import { Tabs, useTabPanelProps, type Tab } from '@ai-created/ui';",
        "clientComponent": true,
        "notes": [
          "Tabs is controlled and uses automatic activation during arrow navigation.",
          "Without a shared provided id, DOM ids are generated but cross-component aria relationships are intentionally omitted.",
          "useTabPanelProps returns role, ids, tabIndex, and hidden."
        ]
      },
      "guidance": {
        "dos": [
          "Use for two to six related peer views.",
          "Keep labels short and use a stable default tab."
        ],
        "donts": [
          "Do not use tabs for primary site navigation.",
          "Do not place unrelated tasks in the same tablist."
        ]
      },
      "testing": {
        "unit": [
          "Emits ids and panel relationships only when the stable id is shared.",
          "Handles empty tabs without errors."
        ],
        "interaction": [
          "Click, arrow wraparound, Home, End, focus movement, and panel visibility work."
        ],
        "accessibility": [
          "Roving tabIndex, selected state, tablist name, and panel relationships are valid."
        ],
        "visual": [
          "Capture each active tab, focus, optional icons, overflow pressure, and themes."
        ]
      },
      "relatedComponents": [
        "button",
        "surface"
      ],
      "controls": {
        "active": {
          "type": "select",
          "label": "Active tab",
          "defaultValue": "overview",
          "options": [
            "overview",
            "activity",
            "settings"
          ]
        }
      },
      "construction": {
        "asset": {
          "kind": "component",
          "figmaName": "Components/Navigation/Tabs",
          "localName": "Tabs",
          "canvasApplicability": "Publish a component set with active-tab variants and nested tab instances."
        },
        "autoLayout": {
          "applicable": true,
          "direction": "horizontal",
          "gap": "2px",
          "padding": "0px",
          "alignment": "End aligned on the active indicator",
          "wrap": "No wrap",
          "notes": []
        },
        "resizing": {
          "applicable": true,
          "width": "hug",
          "height": "fixed",
          "minWidth": "Content width",
          "maxWidth": "Parent or viewport width",
          "minHeight": "36px",
          "maxHeight": "36px",
          "overflow": "visible",
          "notes": []
        },
        "exposedProperties": [
          {
            "name": "active",
            "label": "Active tab",
            "type": "variant",
            "required": true,
            "defaultValue": null,
            "codeMapping": "active"
          },
          {
            "name": "label",
            "label": "Tab list label",
            "type": "text",
            "required": true,
            "defaultValue": "Views",
            "codeMapping": "label"
          },
          {
            "name": "tabs",
            "label": "Tabs",
            "type": "slot",
            "required": true,
            "defaultValue": null,
            "codeMapping": "tabs"
          },
          {
            "name": "icon",
            "label": "Tab icon",
            "type": "instance-swap",
            "required": false,
            "defaultValue": null,
            "codeMapping": "Tab.icon"
          }
        ],
        "nestedAssets": [
          {
            "name": "Tab list",
            "kind": "primitive",
            "required": true,
            "description": "Keyboard navigation container.",
            "codeMapping": "<div role=\"tablist\">"
          },
          {
            "name": "Tab",
            "kind": "subcomponent",
            "required": true,
            "description": "Repeatable label, optional icon, and indicator.",
            "codeMapping": "Tab data item"
          },
          {
            "name": "Tab panel",
            "kind": "helper",
            "required": true,
            "description": "Consumer-owned related content panel.",
            "codeMapping": "useTabPanelProps"
          }
        ],
        "contentLimits": [
          {
            "target": "Tabs",
            "limit": "Recommended two to five peer views",
            "overflowBehavior": "Use page navigation or another information architecture for larger sets.",
            "rationale": "All labels should remain visible without horizontal ambiguity."
          },
          {
            "target": "Tab label",
            "limit": "One or two words, maximum 20 characters",
            "overflowBehavior": "Do not truncate.",
            "rationale": "Short labels improve comparison and keyboard predictability."
          }
        ],
        "localization": {
          "translatable": [
            "Tab list label",
            "Tab labels"
          ],
          "rtlBehavior": [
            "Visual order follows document direction.",
            "Left and right arrow expectations must be tested for the supported browser behavior."
          ],
          "stressCases": [
            "Test all labels at twice English length.",
            "Test panel relationships after translation."
          ]
        },
        "responsive": {
          "strategy": "Intrinsic single row owned by its container.",
          "breakpoints": [
            "Parent-selected narrow breakpoint"
          ],
          "behavior": [
            "Do not wrap tab rows.",
            "Use horizontal scrolling only with an explicit overflow affordance, otherwise choose a different navigation pattern."
          ]
        },
        "limitations": {
          "figma": [
            "Prototype active variants do not validate roving focus or panel relationships."
          ],
          "code": [
            "Consumers must pass the same stable id to Tabs and useTabPanelProps."
          ],
          "notApplicable": []
        },
        "governance": {
          "status": "stable",
          "ownerRole": "Design systems navigation primitive owner",
          "lastReviewed": "2026-08-29",
          "canonicalSource": "src/components/Tabs.tsx",
          "changePolicy": [
            "Changes to tab order or activation require keyboard and information-architecture review.",
            "A breaking property, token, or behavior change requires design and engineering approval, a migration note, and a major release.",
            "The design asset, implementation, documentation, accessibility contract, and regression coverage must ship in the same change."
          ]
        }
      }
    },
    {
      "id": "dialog",
      "name": "Dialog",
      "category": "Overlays",
      "purpose": "Presents focused content above the current page.",
      "useWhen": [
        "Short focused tasks or decisions"
      ],
      "avoidWhen": [
        "Persistent page content"
      ],
      "api": [
        {
          "prop": "open",
          "type": "boolean",
          "defaultValue": "required",
          "description": "Whether the dialog is shown."
        },
        {
          "prop": "onClose",
          "type": "() => void",
          "defaultValue": "required",
          "description": "Called on dismissal."
        },
        {
          "prop": "title",
          "type": "string",
          "defaultValue": "undefined",
          "description": "Optional accessible title."
        },
        {
          "prop": "description",
          "type": "string",
          "defaultValue": "undefined",
          "description": "Optional description."
        },
        {
          "prop": "size",
          "type": "DialogSize",
          "defaultValue": "md",
          "description": "sm, md, lg, or xl."
        },
        {
          "prop": "children",
          "type": "ReactNode",
          "defaultValue": "required",
          "description": "Dialog content."
        }
      ],
      "states": [
        "closed",
        "open",
        "entering",
        "leaving"
      ],
      "accessibility": [
        "Headless UI manages focus, Escape, and restoration.",
        "Title and description are associated when provided."
      ],
      "composition": [
        "Keep the primary action and close affordance inside the dialog."
      ],
      "code": "<Dialog open={open} onClose={() => setOpen(false)} title=\"Rename project\">...</Dialog>",
      "slug": "dialog",
      "summary": "A ready-made animated modal dialog for a short focused task or decision.",
      "sourcePath": "src/components/Dialog.tsx",
      "packageExports": [
        "Dialog",
        "DialogProps",
        "DialogSize"
      ],
      "anatomy": [
        {
          "name": "Backdrop",
          "description": "Full-viewport overlay separating the dialog from page content.",
          "required": true
        },
        {
          "name": "Dialog panel",
          "description": "Centered bounded content surface.",
          "required": true
        },
        {
          "name": "Header",
          "description": "Optional title, description, and close button.",
          "required": false
        },
        {
          "name": "Close action",
          "description": "44 × 44px labelled dismiss button.",
          "required": false,
          "semanticElement": "button"
        },
        {
          "name": "Body",
          "description": "Consumer task content.",
          "required": true
        }
      ],
      "visualSpec": {
        "measurements": [
          {
            "property": "Viewport padding",
            "value": "16px"
          },
          {
            "property": "Panel max width",
            "value": "384 / 512 / 672 / 896px",
            "notes": "sm / md / lg / xl."
          },
          {
            "property": "Radius",
            "value": "6px"
          },
          {
            "property": "Header padding",
            "value": "20px horizontal mobile / 24px md; 12px vertical"
          },
          {
            "property": "Body padding",
            "value": "24px horizontal / 20px vertical"
          },
          {
            "property": "Close target",
            "value": "44 × 44px"
          },
          {
            "property": "Close glyph",
            "value": "24 × 24px"
          },
          {
            "property": "Close glyph inset",
            "value": "16px from top and logical end",
            "notes": "The target is positioned independently so it does not make a title-only header taller."
          }
        ],
        "rules": [
          "Keep the title visible and specific.",
          "Use the shared overlay header and close-control pattern.",
          "Hover strengthens the icon without drawing a border; keyboard focus retains the standard outline.",
          "Use one scroll strategy; Dialog itself does not constrain body height.",
          "Keep primary and dismissal actions inside the panel."
        ],
        "responsiveBehavior": [
          "Panel width is fluid up to its size max-width and viewport padding.",
          "Consider Modal for long or structurally rich content."
        ]
      },
      "designTokens": [
        {
          "token": "--color-overlay",
          "purpose": "Backdrop."
        },
        {
          "token": "--color-surface",
          "purpose": "Panel."
        },
        {
          "token": "--color-border",
          "purpose": "Panel and header divider."
        },
        {
          "token": "--color-text / --color-text2 / --color-text3",
          "purpose": "Title, description, and close icon."
        },
        {
          "token": "--color-focus",
          "purpose": "Close focus outline."
        }
      ],
      "stateDefinitions": [
        {
          "name": "closed",
          "trigger": "open is false.",
          "visual": "Backdrop and panel are absent after transition.",
          "behavior": "Page remains interactive."
        },
        {
          "name": "open",
          "trigger": "open is true.",
          "visual": "Backdrop and centered panel are visible.",
          "behavior": "Focus is trapped and background interaction is inert."
        },
        {
          "name": "entering",
          "trigger": "Opening transition.",
          "visual": "Backdrop fades; panel fades and scales from 95% over 200ms.",
          "behavior": "Dialog becomes the active focus scope."
        },
        {
          "name": "leaving",
          "trigger": "Closing transition.",
          "visual": "Backdrop and panel fade; panel scales to 95% over 150ms.",
          "behavior": "Focus returns after dismissal."
        }
      ],
      "keyboard": [
        {
          "key": "Escape",
          "action": "Requests close through onClose."
        },
        {
          "key": "Tab / Shift+Tab",
          "action": "Cycles focus within the open dialog."
        },
        {
          "key": "Enter / Space",
          "action": "Activates the focused dialog control."
        }
      ],
      "accessibilitySpec": {
        "semantics": "Headless UI dialog with optional DialogTitle and Description associations.",
        "accessibleName": "title supplies the accessible name when provided; otherwise body content must provide an accessible label.",
        "requirements": [
          "Prefer always providing a title.",
          "Provide at least one obvious dismissal method.",
          "Do not put another modal dialog inside Dialog.",
          "Restore focus to a meaningful trigger through the managed open state."
        ]
      },
      "implementation": {
        "importStatement": "import { Dialog } from '@ai-created/ui';",
        "clientComponent": true,
        "notes": [
          "Headless UI manages focus trap, Escape, outside dismissal, inert background, and restoration.",
          "Dialog stays in the tree while Transition controls visibility.",
          "className applies to the panel."
        ]
      },
      "guidance": {
        "dos": [
          "Use for one short task with a clear completion path.",
          "Write titles that describe the task, not generic “Dialog”."
        ],
        "donts": [
          "Do not use for persistent workspace content.",
          "Do not put large multi-step flows into the panel."
        ]
      },
      "testing": {
        "unit": [
          "Maps sizes and optional header content.",
          "Calls onClose from close button and managed dismissal."
        ],
        "interaction": [
          "Opening focus, focus trap, Escape, close button, backdrop, and restoration work."
        ],
        "accessibility": [
          "Dialog has a name/description and background is inert while open."
        ],
        "visual": [
          "Capture all sizes, header combinations, entering/open states, long content, and themes."
        ]
      },
      "relatedComponents": [
        "modal",
        "confirm-dialog",
        "button"
      ],
      "controls": {
        "open": {
          "type": "boolean",
          "label": "Open",
          "defaultValue": false
        },
        "size": {
          "type": "select",
          "label": "Size",
          "defaultValue": "md",
          "options": [
            "sm",
            "md",
            "lg",
            "xl"
          ]
        },
        "title": {
          "type": "text",
          "label": "Title",
          "defaultValue": "Rename project"
        }
      },
      "construction": {
        "asset": {
          "kind": "component",
          "figmaName": "Components/Overlays/Dialog",
          "localName": "Dialog",
          "canvasApplicability": "Publish size variants with open state, title, description, and nested body content."
        },
        "autoLayout": {
          "applicable": true,
          "direction": "vertical",
          "gap": "0px between framed regions",
          "padding": "16px viewport inset; 20px mobile / 24px desktop header inset; 12px header block padding; close target pinned 6px from the top and logical end",
          "alignment": "Stretch",
          "wrap": "Content wraps",
          "notes": []
        },
        "resizing": {
          "applicable": true,
          "width": "fill",
          "height": "hug",
          "minWidth": "280px",
          "maxWidth": "sm 384px; md 512px; lg 672px; xl 896px",
          "minHeight": "Content controlled",
          "maxHeight": "Viewport minus 32px",
          "overflow": "auto",
          "notes": []
        },
        "exposedProperties": [
          {
            "name": "open",
            "label": "Open",
            "type": "boolean",
            "required": true,
            "defaultValue": false,
            "codeMapping": "open"
          },
          {
            "name": "size",
            "label": "Size",
            "type": "variant",
            "required": false,
            "defaultValue": "md",
            "options": [
              "sm",
              "md",
              "lg",
              "xl"
            ],
            "codeMapping": "size"
          },
          {
            "name": "title",
            "label": "Title",
            "type": "text",
            "required": false,
            "defaultValue": null,
            "codeMapping": "title"
          },
          {
            "name": "description",
            "label": "Description",
            "type": "text",
            "required": false,
            "defaultValue": null,
            "codeMapping": "description"
          },
          {
            "name": "content",
            "label": "Content",
            "type": "slot",
            "required": true,
            "defaultValue": null,
            "codeMapping": "children"
          }
        ],
        "nestedAssets": [
          {
            "name": "Backdrop",
            "kind": "primitive",
            "required": true,
            "description": "Full viewport modal overlay.",
            "codeMapping": "Internal fixed overlay"
          },
          {
            "name": "Panel",
            "kind": "primitive",
            "required": true,
            "description": "Focused dialog surface.",
            "codeMapping": "Headless UI DialogPanel"
          },
          {
            "name": "Header",
            "kind": "subcomponent",
            "required": false,
            "description": "Title, description, and close action.",
            "codeMapping": "Internal header"
          },
          {
            "name": "Body",
            "kind": "slot",
            "required": true,
            "description": "Focused task content.",
            "codeMapping": "children"
          }
        ],
        "contentLimits": [
          {
            "target": "Title",
            "limit": "One line preferred, maximum two lines",
            "overflowBehavior": "Wrap; do not truncate.",
            "rationale": "Users need a concise task name."
          },
          {
            "target": "Description",
            "limit": "Maximum three lines",
            "overflowBehavior": "Move long instructions into the body.",
            "rationale": "Header copy should orient, not explain the whole task."
          },
          {
            "target": "Task scope",
            "limit": "One focused task or decision",
            "overflowBehavior": "Move complex multi-section work to a page.",
            "rationale": "Dialogs interrupt the underlying workflow."
          }
        ],
        "localization": {
          "translatable": [
            "Title",
            "Description",
            "Body",
            "Action labels"
          ],
          "rtlBehavior": [
            "Close action stays at logical end.",
            "Content follows locale direction."
          ],
          "stressCases": [
            "Test twice-length titles.",
            "Test at 200% zoom with keyboard-only dismissal."
          ]
        },
        "responsive": {
          "strategy": "Width is capped by size and inset 16px from the viewport.",
          "breakpoints": [
            "No internal breakpoint"
          ],
          "behavior": [
            "Panel shrinks to viewport width.",
            "Body must remain reachable when content exceeds viewport height."
          ]
        },
        "limitations": {
          "figma": [
            "Figma overlays cannot validate focus trapping, restoration, Escape, or scroll lock."
          ],
          "code": [
            "Always provide an accessible title through title or a correctly associated custom heading."
          ],
          "notApplicable": []
        },
        "governance": {
          "status": "stable",
          "ownerRole": "Design systems overlay primitive owner",
          "lastReviewed": "2026-08-29",
          "canonicalSource": "src/components/Dialog.tsx",
          "changePolicy": [
            "Dismissal, focus, or size changes require overlay accessibility review.",
            "A breaking property, token, or behavior change requires design and engineering approval, a migration note, and a major release.",
            "The design asset, implementation, documentation, accessibility contract, and regression coverage must ship in the same change."
          ]
        }
      }
    },
    {
      "id": "modal",
      "name": "Modal family",
      "category": "Overlays",
      "purpose": "Composes a themed modal from overlay, panel, header, body, and footer.",
      "useWhen": [
        "Reusable application modal layouts"
      ],
      "avoidWhen": [
        "Simple inline disclosure"
      ],
      "api": [
        {
          "prop": "ModalOverlay.onClose",
          "type": "() => void",
          "defaultValue": "undefined",
          "description": "Dismiss callback."
        },
        {
          "prop": "ModalOverlay.closeOnBackdrop",
          "type": "boolean",
          "defaultValue": "true",
          "description": "Whether backdrop clicks dismiss."
        },
        {
          "prop": "ModalPanel.size",
          "type": "ModalSize",
          "defaultValue": "lg",
          "description": "sm, md, lg, or xl."
        },
        {
          "prop": "ModalHeader.heading",
          "type": "ReactNode",
          "defaultValue": "required",
          "description": "Heading content."
        },
        {
          "prop": "ModalHeader.onClose",
          "type": "() => void",
          "defaultValue": "undefined",
          "description": "Optional close action."
        },
        {
          "prop": "ModalBody.scroll",
          "type": "boolean",
          "defaultValue": "true",
          "description": "Allows the body region to scroll."
        },
        {
          "prop": "children",
          "type": "ReactNode",
          "defaultValue": "required",
          "description": "Content for each region."
        }
      ],
      "states": [
        "closed",
        "open",
        "nested",
        "focus-visible"
      ],
      "accessibility": [
        "Headless UI supplies focus trap, Escape, restoration, and scroll lock.",
        "Header title and description are associated."
      ],
      "composition": [
        "Compose ModalOverlay > ModalPanel > ModalHeader, ModalBody, and ModalFooter."
      ],
      "code": "<ModalOverlay onClose={onClose}><ModalPanel><ModalHeader heading=\"Settings\" onClose={onClose} /><ModalBody>...</ModalBody><ModalFooter>...</ModalFooter></ModalPanel></ModalOverlay>",
      "slug": "modal",
      "summary": "A composable Headless UI modal shell for richer application layouts with header, body, and footer regions.",
      "sourcePath": "src/components/Modal.tsx",
      "packageExports": [
        "ModalOverlay",
        "ModalPanel",
        "ModalHeader",
        "ModalBody",
        "ModalFooter",
        "ModalSize"
      ],
      "anatomy": [
        {
          "name": "Overlay",
          "description": "Mounted dialog root, scroll container, backdrop, and focus scope.",
          "required": true
        },
        {
          "name": "Panel",
          "description": "Bounded flex-column Surface.",
          "required": true
        },
        {
          "name": "Header",
          "description": "Optional eyebrow, title, description, custom content, and close action.",
          "required": true
        },
        {
          "name": "Body",
          "description": "Primary content region with optional internal scrolling.",
          "required": true
        },
        {
          "name": "Footer",
          "description": "Optional bordered action region.",
          "required": false
        }
      ],
      "visualSpec": {
        "measurements": [
          {
            "property": "Panel max width",
            "value": "384 / 512 / 672 / 896px",
            "notes": "sm / md / lg / xl; shared with Dialog."
          },
          {
            "property": "Panel max height",
            "value": "viewport − 48px mobile / viewport − 64px md+"
          },
          {
            "property": "Overlay padding",
            "value": "16px mobile / 24px md+"
          },
          {
            "property": "Top offset mobile",
            "value": "64px"
          },
          {
            "property": "Header padding",
            "value": "20px horizontal mobile / 24px md; 12px vertical"
          },
          {
            "property": "Body/footer padding",
            "value": "20px horizontal mobile / 24px md; 16px vertical"
          },
          {
            "property": "Close target",
            "value": "44 × 44px"
          },
          {
            "property": "Close glyph",
            "value": "24 × 24px"
          },
          {
            "property": "Close glyph inset",
            "value": "16px from top and logical end",
            "notes": "Shared with Dialog; the target does not determine header height."
          }
        ],
        "rules": [
          "Compose regions only inside ModalPanel.",
          "Use the shared overlay header and close-control pattern.",
          "Hover strengthens the icon without drawing a border; keyboard focus retains the standard outline.",
          "Keep a single scrollable body between fixed header and footer.",
          "Use alertdialog role only for consequential confirmations."
        ],
        "responsiveBehavior": [
          "Aligns near the top on small screens and centers from sm upward.",
          "Body scrolls within a viewport-bounded panel."
        ]
      },
      "designTokens": [
        {
          "token": "--color-overlay",
          "purpose": "Backdrop."
        },
        {
          "token": "--color-surface / --color-border",
          "purpose": "Panel and dividers through Surface."
        },
        {
          "token": "--color-text / --color-text2",
          "purpose": "Heading and description."
        },
        {
          "token": "--radius-md",
          "purpose": "Panel radius."
        }
      ],
      "stateDefinitions": [
        {
          "name": "closed",
          "trigger": "ModalOverlay is not rendered.",
          "visual": "No modal UI.",
          "behavior": "Page owns focus and scrolling."
        },
        {
          "name": "open",
          "trigger": "ModalOverlay is mounted.",
          "visual": "Blurred overlay and panel are visible.",
          "behavior": "Headless UI traps focus, locks background interaction, and handles Escape."
        },
        {
          "name": "nested",
          "trigger": "A modal is opened from another focus scope.",
          "visual": "Higher-level modal remains visually subordinate.",
          "behavior": "Use sparingly and verify focus restoration at each level.",
          "accessibility": "Every dialog must retain a unique name."
        },
        {
          "name": "focus-visible",
          "trigger": "Keyboard focus reaches a control.",
          "visual": "The focused child component supplies its standard ring.",
          "behavior": "Tab remains within the active dialog."
        }
      ],
      "keyboard": [
        {
          "key": "Escape",
          "action": "Requests onClose when supplied."
        },
        {
          "key": "Tab / Shift+Tab",
          "action": "Cycles through focusable modal content."
        },
        {
          "key": "Enter / Space",
          "action": "Activates the focused control."
        }
      ],
      "accessibilitySpec": {
        "semantics": "Headless UI Dialog; Header uses DialogTitle and Description, and alertdialog is supported.",
        "accessibleName": "ModalHeader heading supplies the name; description supplies supporting text.",
        "requirements": [
          "Always include ModalHeader with a meaningful heading or provide an equivalent Headless UI title.",
          "Supply an onClose control unless the operation intentionally prevents dismissal.",
          "Keep footer action order and labels explicit."
        ]
      },
      "implementation": {
        "importStatement": "import { ModalOverlay, ModalPanel, ModalHeader, ModalBody, ModalFooter } from '@ai-created/ui';",
        "clientComponent": true,
        "notes": [
          "Render ModalOverlay conditionally; it is always open while mounted.",
          "onClose is optional because ConfirmDialog can suppress dismissal while loading.",
          "closeOnBackdrop affects pointer backdrop dismissal only.",
          "ModalBody scroll defaults to true."
        ]
      },
      "guidance": {
        "dos": [
          "Use for rich but bounded application tasks.",
          "Keep the primary action in the footer and close action in the header."
        ],
        "donts": [
          "Do not mount without a panel and title.",
          "Do not place essential page navigation inside a modal."
        ]
      },
      "testing": {
        "unit": [
          "Maps the shared Dialog panel sizes and every region option.",
          "Optional onClose behavior is deterministic."
        ],
        "interaction": [
          "Escape, backdrop setting, 44px close button, focus trap, body scrolling, and restoration work."
        ],
        "accessibility": [
          "Dialog naming, description, role, focus order, and inert background are valid."
        ],
        "visual": [
          "Capture sizes, mobile top alignment, desktop centering, overflow, header/footer variants, and themes."
        ]
      },
      "relatedComponents": [
        "dialog",
        "confirm-dialog",
        "surface",
        "button"
      ],
      "controls": {
        "open": {
          "type": "boolean",
          "label": "Open",
          "defaultValue": false
        },
        "size": {
          "type": "select",
          "label": "Size",
          "defaultValue": "lg",
          "options": [
            "sm",
            "md",
            "lg",
            "xl"
          ]
        },
        "closeOnBackdrop": {
          "type": "boolean",
          "label": "Backdrop closes",
          "defaultValue": true
        },
        "scroll": {
          "type": "boolean",
          "label": "Scrollable body",
          "defaultValue": true
        }
      },
      "construction": {
        "asset": {
          "kind": "component",
          "figmaName": "Components/Overlays/Modal",
          "localName": "Modal family",
          "canvasApplicability": "Publish a composable overlay component with panel, header, body, and footer slots."
        },
        "autoLayout": {
          "applicable": true,
          "direction": "vertical",
          "gap": "0px between regions",
          "padding": "16px viewport inset; region padding owned by subcomponents; close target pinned 6px from the header top and logical end",
          "alignment": "Stretch",
          "wrap": "Region content wraps",
          "notes": []
        },
        "resizing": {
          "applicable": true,
          "width": "fill",
          "height": "content-controlled",
          "minWidth": "280px",
          "maxWidth": "sm 384px; md 512px; lg 672px; xl 896px",
          "minHeight": "Content controlled",
          "maxHeight": "Viewport minus 32px",
          "overflow": "auto",
          "notes": []
        },
        "exposedProperties": [
          {
            "name": "open",
            "label": "Open",
            "type": "boolean",
            "required": false,
            "defaultValue": false,
            "codeMapping": "Conditional rendering of ModalOverlay"
          },
          {
            "name": "size",
            "label": "Size",
            "type": "variant",
            "required": false,
            "defaultValue": "lg",
            "options": [
              "sm",
              "md",
              "lg",
              "xl"
            ],
            "codeMapping": "ModalPanel.size"
          },
          {
            "name": "closeOnBackdrop",
            "label": "Backdrop closes",
            "type": "boolean",
            "required": false,
            "defaultValue": true,
            "codeMapping": "ModalOverlay.closeOnBackdrop"
          },
          {
            "name": "scroll",
            "label": "Scrollable body",
            "type": "boolean",
            "required": false,
            "defaultValue": true,
            "codeMapping": "ModalBody.scroll"
          },
          {
            "name": "heading",
            "label": "Heading",
            "type": "text",
            "required": true,
            "defaultValue": "Settings",
            "codeMapping": "ModalHeader.heading"
          },
          {
            "name": "description",
            "label": "Description",
            "type": "text",
            "required": false,
            "defaultValue": null,
            "codeMapping": "ModalHeader.description"
          },
          {
            "name": "body",
            "label": "Body",
            "type": "slot",
            "required": true,
            "defaultValue": null,
            "codeMapping": "ModalBody children"
          },
          {
            "name": "footer",
            "label": "Footer",
            "type": "slot",
            "required": false,
            "defaultValue": null,
            "codeMapping": "ModalFooter children"
          }
        ],
        "nestedAssets": [
          {
            "name": "ModalOverlay",
            "kind": "subcomponent",
            "required": true,
            "description": "Backdrop, semantics, dismissal, and focus boundary.",
            "codeMapping": "ModalOverlay"
          },
          {
            "name": "ModalPanel",
            "kind": "subcomponent",
            "required": true,
            "description": "Sized modal surface.",
            "codeMapping": "ModalPanel"
          },
          {
            "name": "ModalHeader",
            "kind": "subcomponent",
            "required": true,
            "description": "Heading, optional description, and close control.",
            "codeMapping": "ModalHeader"
          },
          {
            "name": "ModalBody",
            "kind": "subcomponent",
            "required": true,
            "description": "Primary scroll region.",
            "codeMapping": "ModalBody"
          },
          {
            "name": "ModalFooter",
            "kind": "subcomponent",
            "required": false,
            "description": "Action region.",
            "codeMapping": "ModalFooter"
          }
        ],
        "contentLimits": [
          {
            "target": "Heading",
            "limit": "One line preferred, maximum two lines",
            "overflowBehavior": "Wrap; never truncate.",
            "rationale": "The modal task should remain clear."
          },
          {
            "target": "Footer actions",
            "limit": "One primary and up to two secondary actions",
            "overflowBehavior": "Move tertiary actions into body content.",
            "rationale": "A contained decision needs a clear hierarchy."
          },
          {
            "target": "Body",
            "limit": "One focused workflow",
            "overflowBehavior": "Use a full page for broad or deeply nested tasks.",
            "rationale": "Modal interruption cost rises with complexity."
          }
        ],
        "localization": {
          "translatable": [
            "Heading",
            "Description",
            "Body",
            "Action labels"
          ],
          "rtlBehavior": [
            "Header close action and footer alignment use logical sides.",
            "Content follows locale direction."
          ],
          "stressCases": [
            "Test long action labels.",
            "Test body overflow and 200% zoom.",
            "Test nested directional form controls."
          ]
        },
        "responsive": {
          "strategy": "Panel is viewport-constrained and body may scroll.",
          "breakpoints": [
            "No internal breakpoint"
          ],
          "behavior": [
            "Maintain 16px viewport inset.",
            "On product-defined small screens, a full-height presentation may be composed outside this primitive."
          ]
        },
        "limitations": {
          "figma": [
            "Figma nesting demonstrates structure but not portal, focus, inert background, or scroll-lock behavior."
          ],
          "code": [
            "Consumers own whether the ModalOverlay is mounted; this family has no open prop itself."
          ],
          "notApplicable": []
        },
        "governance": {
          "status": "stable",
          "ownerRole": "Design systems overlay primitive owner",
          "lastReviewed": "2026-08-29",
          "canonicalSource": "src/components/Modal.tsx",
          "changePolicy": [
            "Subcomponent contracts and dismissal changes require overlay accessibility review.",
            "A breaking property, token, or behavior change requires design and engineering approval, a migration note, and a major release.",
            "The design asset, implementation, documentation, accessibility contract, and regression coverage must ship in the same change."
          ]
        }
      }
    },
    {
      "id": "confirm-dialog",
      "name": "ConfirmDialog",
      "category": "Overlays",
      "purpose": "Confirms a consequential action with explicit cancel and confirm controls.",
      "useWhen": [
        "Destructive or irreversible actions"
      ],
      "avoidWhen": [
        "Routine actions that do not need interruption"
      ],
      "api": [
        {
          "prop": "open",
          "type": "boolean",
          "defaultValue": "required",
          "description": "Whether the dialog is shown."
        },
        {
          "prop": "onConfirm",
          "type": "() => void",
          "defaultValue": "required",
          "description": "Confirm callback."
        },
        {
          "prop": "onCancel",
          "type": "() => void",
          "defaultValue": "required",
          "description": "Cancel callback."
        },
        {
          "prop": "title",
          "type": "string",
          "defaultValue": "required",
          "description": "Dialog heading."
        },
        {
          "prop": "description",
          "type": "ReactNode",
          "defaultValue": "undefined",
          "description": "Supporting explanation."
        },
        {
          "prop": "confirmLabel",
          "type": "string",
          "defaultValue": "Confirm",
          "description": "Confirm button label."
        },
        {
          "prop": "cancelLabel",
          "type": "string",
          "defaultValue": "Cancel",
          "description": "Cancel button label."
        },
        {
          "prop": "destructive",
          "type": "boolean",
          "defaultValue": "false",
          "description": "Uses destructive styling."
        },
        {
          "prop": "loading",
          "type": "boolean",
          "defaultValue": "false",
          "description": "Disables dismissal while working."
        },
        {
          "prop": "loadingLabel",
          "type": "string",
          "defaultValue": "Working…",
          "description": "Busy button label."
        }
      ],
      "states": [
        "closed",
        "open",
        "loading"
      ],
      "accessibility": [
        "Uses alertdialog semantics.",
        "Dismissal is disabled while loading."
      ],
      "composition": [
        "Use for a single consequential action with a clear description."
      ],
      "code": "<ConfirmDialog open={open} title=\"Delete project?\" description=\"This cannot be undone.\" onConfirm={remove} onCancel={cancel} destructive />",
      "slug": "confirm-dialog",
      "summary": "A constrained alert dialog for confirming one consequential or irreversible action.",
      "sourcePath": "src/components/ConfirmDialog.tsx",
      "packageExports": [
        "ConfirmDialog",
        "ConfirmDialogProps"
      ],
      "anatomy": [
        {
          "name": "Alert dialog",
          "description": "Small Modal composition with alertdialog semantics.",
          "required": true
        },
        {
          "name": "Title",
          "description": "Names the exact action under confirmation.",
          "required": true
        },
        {
          "name": "Description",
          "description": "Optional consequence and scope explanation.",
          "required": false
        },
        {
          "name": "Cancel action",
          "description": "Safe dismissal path.",
          "required": true,
          "semanticElement": "button"
        },
        {
          "name": "Confirm action",
          "description": "Executes the consequential operation.",
          "required": true,
          "semanticElement": "button"
        }
      ],
      "visualSpec": {
        "measurements": [
          {
            "property": "Panel width",
            "value": "max 384px"
          },
          {
            "property": "Footer action gap",
            "value": "12px"
          },
          {
            "property": "Header padding",
            "value": "20px horizontal mobile / 24px md; 12px vertical"
          },
          {
            "property": "Body/footer padding",
            "value": "20px horizontal mobile / 24px md; 16px vertical"
          },
          {
            "property": "Close target",
            "value": "44 × 44px"
          },
          {
            "property": "Close glyph",
            "value": "24 × 24px"
          },
          {
            "property": "Close glyph inset",
            "value": "16px from top and logical end",
            "notes": "Inherited from the shared overlay header while the dialog is dismissible."
          }
        ],
        "rules": [
          "Name the specific object and action.",
          "Place Cancel before Confirm in the footer.",
          "Use destructive styling only for destructive consequences."
        ]
      },
      "designTokens": [
        {
          "token": "--color-overlay",
          "purpose": "Modal backdrop."
        },
        {
          "token": "--color-surface / --color-border",
          "purpose": "Panel and dividers."
        },
        {
          "token": "--color-action-primary",
          "purpose": "Standard confirmation."
        },
        {
          "token": "--color-action-destructive",
          "purpose": "Destructive confirmation."
        },
        {
          "token": "--color-on-action",
          "purpose": "Filled action foreground."
        },
        {
          "token": "--color-text / --color-text2",
          "purpose": "Title and description."
        }
      ],
      "stateDefinitions": [
        {
          "name": "closed",
          "trigger": "open is false.",
          "visual": "Nothing is rendered.",
          "behavior": "No focus scope exists."
        },
        {
          "name": "open",
          "trigger": "open is true.",
          "visual": "Small alert dialog with cancel and confirm actions.",
          "behavior": "Focus is trapped; dismissal calls onCancel."
        },
        {
          "name": "loading",
          "trigger": "loading is true.",
          "visual": "Both actions are disabled and confirm label becomes loadingLabel.",
          "behavior": "Escape, backdrop, header close, cancel, and confirm activation are blocked.",
          "accessibility": "Disabled buttons expose unavailability; the label communicates work in progress."
        }
      ],
      "keyboard": [
        {
          "key": "Escape",
          "action": "Cancels and closes.",
          "condition": "Only while not loading."
        },
        {
          "key": "Tab / Shift+Tab",
          "action": "Moves between available actions within the dialog."
        },
        {
          "key": "Enter / Space",
          "action": "Activates the focused cancel or confirm button.",
          "condition": "Only while not loading."
        }
      ],
      "accessibilitySpec": {
        "semantics": "Headless UI alertdialog composed from Modal primitives.",
        "accessibleName": "Required title names the alert dialog; optional Description is associated by Headless UI.",
        "requirements": [
          "Initial focus should land on the safest useful control for the context; verify Headless UI behavior in integration.",
          "Explain irreversible consequences before the action.",
          "Do not rely on destructive color; button text must be specific.",
          "Expose completion or failure after loading ends."
        ]
      },
      "implementation": {
        "importStatement": "import { ConfirmDialog } from '@ai-created/ui';",
        "clientComponent": true,
        "notes": [
          "Returns null while closed.",
          "destructive changes the confirm visual variant; it does not alter semantics.",
          "loading suppresses every dismissal callback and action.",
          "The parent owns async state and closes on success."
        ]
      },
      "guidance": {
        "dos": [
          "Reserve confirmation for meaningful consequences.",
          "Use labels such as Delete project instead of Confirm."
        ],
        "donts": [
          "Do not interrupt routine reversible actions.",
          "Do not allow the dialog to close while its operation is unresolved."
        ]
      },
      "testing": {
        "unit": [
          "Closed returns null; defaults and destructive variant map correctly.",
          "Loading disables all dismissal paths and changes the label."
        ],
        "interaction": [
          "Cancel, confirm, Escape, backdrop, focus trap, loading, and restoration work."
        ],
        "accessibility": [
          "Alertdialog is named/described and actions have specific names and correct disabled state."
        ],
        "visual": [
          "Capture regular/destructive, description absent/present, loading, long labels, and themes."
        ]
      },
      "relatedComponents": [
        "modal",
        "dialog",
        "button"
      ],
      "controls": {
        "open": {
          "type": "boolean",
          "label": "Open",
          "defaultValue": false
        },
        "destructive": {
          "type": "boolean",
          "label": "Destructive",
          "defaultValue": true
        },
        "loading": {
          "type": "boolean",
          "label": "Loading",
          "defaultValue": false
        },
        "title": {
          "type": "text",
          "label": "Title",
          "defaultValue": "Delete project?"
        }
      },
      "construction": {
        "asset": {
          "kind": "component",
          "figmaName": "Components/Overlays/Confirm dialog",
          "localName": "ConfirmDialog",
          "canvasApplicability": "Publish standard, destructive, and loading variants with localized copy properties."
        },
        "autoLayout": {
          "applicable": true,
          "direction": "vertical",
          "gap": "0px regions; 12px between footer actions",
          "padding": "16px viewport inset; panel region padding",
          "alignment": "Stretch with actions aligned to logical end",
          "wrap": "Actions may wrap at narrow widths",
          "notes": []
        },
        "resizing": {
          "applicable": true,
          "width": "fill",
          "height": "hug",
          "minWidth": "280px",
          "maxWidth": "384px",
          "minHeight": "Content controlled",
          "maxHeight": "Viewport minus 32px",
          "overflow": "auto",
          "notes": []
        },
        "exposedProperties": [
          {
            "name": "open",
            "label": "Open",
            "type": "boolean",
            "required": true,
            "defaultValue": false,
            "codeMapping": "open"
          },
          {
            "name": "destructive",
            "label": "Destructive",
            "type": "boolean",
            "required": false,
            "defaultValue": false,
            "codeMapping": "destructive"
          },
          {
            "name": "loading",
            "label": "Loading",
            "type": "boolean",
            "required": false,
            "defaultValue": false,
            "codeMapping": "loading"
          },
          {
            "name": "title",
            "label": "Title",
            "type": "text",
            "required": true,
            "defaultValue": "Confirm action?",
            "codeMapping": "title"
          },
          {
            "name": "description",
            "label": "Description",
            "type": "slot",
            "required": false,
            "defaultValue": null,
            "codeMapping": "description"
          },
          {
            "name": "confirmLabel",
            "label": "Confirm label",
            "type": "text",
            "required": false,
            "defaultValue": "Confirm",
            "codeMapping": "confirmLabel"
          },
          {
            "name": "cancelLabel",
            "label": "Cancel label",
            "type": "text",
            "required": false,
            "defaultValue": "Cancel",
            "codeMapping": "cancelLabel"
          },
          {
            "name": "loadingLabel",
            "label": "Loading label",
            "type": "text",
            "required": false,
            "defaultValue": "Working...",
            "codeMapping": "loadingLabel"
          }
        ],
        "nestedAssets": [
          {
            "name": "Modal family",
            "kind": "subcomponent",
            "required": true,
            "description": "Alert dialog overlay, panel, header, body, and footer.",
            "codeMapping": "ModalOverlay and subcomponents"
          },
          {
            "name": "Cancel action",
            "kind": "subcomponent",
            "required": true,
            "description": "Secondary dismissal action.",
            "codeMapping": "Button"
          },
          {
            "name": "Confirm action",
            "kind": "subcomponent",
            "required": true,
            "description": "Consequential action and loading state.",
            "codeMapping": "Button"
          }
        ],
        "contentLimits": [
          {
            "target": "Title",
            "limit": "A direct question, maximum two lines",
            "overflowBehavior": "Wrap and revise if longer.",
            "rationale": "The exact decision must be obvious."
          },
          {
            "target": "Description",
            "limit": "One short paragraph describing consequence",
            "overflowBehavior": "Move detailed policy outside the dialog.",
            "rationale": "Users need enough context to decide without overload."
          },
          {
            "target": "Action labels",
            "limit": "Specific verbs, recommended maximum 24 characters",
            "overflowBehavior": "Stack actions if localization requires it.",
            "rationale": "Specific labels reduce confirmation errors."
          }
        ],
        "localization": {
          "translatable": [
            "Title",
            "Description",
            "Confirm, cancel, and loading labels"
          ],
          "rtlBehavior": [
            "Footer actions follow product locale conventions while preserving safe action hierarchy.",
            "Directional icons, if added, mirror."
          ],
          "stressCases": [
            "Test long destructive verbs.",
            "Test loading announcement and blocked dismissal.",
            "Test 200% zoom."
          ]
        },
        "responsive": {
          "strategy": "Small modal width with viewport inset.",
          "breakpoints": [
            "Parent-selected narrow breakpoint"
          ],
          "behavior": [
            "Allow footer actions to stack full width in a product composition when labels no longer fit.",
            "Do not reorder safe and destructive actions between widths."
          ]
        },
        "limitations": {
          "figma": [
            "Figma loading variants cannot validate blocked backdrop and Escape dismissal."
          ],
          "code": [
            "The consumer owns asynchronous completion and must clear loading or close the dialog."
          ],
          "notApplicable": []
        },
        "governance": {
          "status": "stable",
          "ownerRole": "Design systems safety pattern owner",
          "lastReviewed": "2026-08-29",
          "canonicalSource": "src/components/ConfirmDialog.tsx",
          "changePolicy": [
            "Destructive defaults or action ordering changes require safety, content, and accessibility review.",
            "A breaking property, token, or behavior change requires design and engineering approval, a migration note, and a major release.",
            "The design asset, implementation, documentation, accessibility contract, and regression coverage must ship in the same change."
          ]
        }
      }
    },
    {
      "id": "tooltip",
      "name": "Tooltip",
      "category": "Overlays",
      "purpose": "Provides brief supplemental information for a trigger.",
      "useWhen": [
        "Clarifying unfamiliar icons or controls"
      ],
      "avoidWhen": [
        "Essential instructions",
        "Long or interactive content"
      ],
      "api": [
        {
          "prop": "content",
          "type": "string",
          "defaultValue": "required",
          "description": "Tooltip text."
        },
        {
          "prop": "position",
          "type": "TooltipPosition",
          "defaultValue": "top",
          "description": "top, bottom, left, or right."
        },
        {
          "prop": "delay",
          "type": "number",
          "defaultValue": "300",
          "description": "Show delay in milliseconds."
        },
        {
          "prop": "children",
          "type": "ReactElement",
          "defaultValue": "required",
          "description": "Trigger element."
        },
        {
          "prop": "className",
          "type": "string",
          "defaultValue": "undefined",
          "description": "Additional tooltip classes."
        }
      ],
      "states": [
        "hidden",
        "visible",
        "focused",
        "touch-visible"
      ],
      "accessibility": [
        "Adds aria-describedby while visible.",
        "Keep essential information outside the tooltip."
      ],
      "composition": [
        "Wrap one focusable trigger."
      ],
      "code": "<Tooltip content=\"Copy link\"><Button variant=\"icon\" aria-label=\"Copy link\">...</Button></Tooltip>",
      "slug": "tooltip",
      "summary": "A brief, non-interactive description shown from pointer, focus, or touch.",
      "sourcePath": "src/components/Tooltip.tsx",
      "packageExports": [
        "Tooltip",
        "TooltipProps",
        "TooltipPosition"
      ],
      "anatomy": [
        {
          "name": "Wrapper",
          "description": "Inline trigger measurement context.",
          "required": true,
          "semanticElement": "span"
        },
        {
          "name": "Trigger",
          "description": "Exactly one cloned focusable element.",
          "required": true
        },
        {
          "name": "Tooltip bubble",
          "description": "Portalled, viewport-positioned description associated while visible.",
          "required": true,
          "semanticElement": "[role=tooltip]"
        }
      ],
      "visualSpec": {
        "measurements": [
          {
            "property": "Bubble padding",
            "value": "12px horizontal / 6px vertical"
          },
          {
            "property": "Trigger offset",
            "value": "8px"
          },
          {
            "property": "Viewport inset",
            "value": "8px minimum"
          },
          {
            "property": "Maximum width",
            "value": "240px"
          },
          {
            "property": "Radius",
            "value": "6px"
          },
          {
            "property": "Entrance",
            "value": "200ms fade"
          }
        ],
        "rules": [
          "Keep content brief, plain text, and non-interactive.",
          "Preferred placement flips when its opposite side has available space and clamps to the viewport.",
          "Do not hide essential instructions in the tooltip."
        ]
      },
      "designTokens": [
        {
          "token": "--color-surface",
          "purpose": "Bubble background."
        },
        {
          "token": "--color-border",
          "purpose": "Bubble border."
        },
        {
          "token": "--color-text2",
          "purpose": "Tooltip text."
        },
        {
          "token": "--radius-md",
          "purpose": "Bubble radius."
        },
        {
          "token": "--shadow-elevation-medium / --layer-tooltip",
          "purpose": "Portalled elevation and stacking."
        },
        {
          "token": "--motion-fast",
          "purpose": "Entrance fade."
        }
      ],
      "stateDefinitions": [
        {
          "name": "hidden",
          "trigger": "No active pointer, focus, or toggled touch.",
          "visual": "Bubble is not mounted.",
          "behavior": "Trigger retains its original aria-describedby."
        },
        {
          "name": "visible",
          "trigger": "Pointer hover remains for delay milliseconds.",
          "visual": "Bubble appears at the resolved viewport position.",
          "behavior": "Pointer may cross onto the bubble without dismissing it; leaving both hides after a short bridge delay.",
          "accessibility": "Tooltip id is appended to aria-describedby while visible."
        },
        {
          "name": "focused",
          "trigger": "Trigger receives focus for delay milliseconds.",
          "visual": "Same bubble as hover.",
          "behavior": "Blur hides it."
        },
        {
          "name": "touch-visible",
          "trigger": "Trigger receives touchstart.",
          "visual": "Bubble toggles immediately.",
          "behavior": "Another touch or outside touch hides it."
        }
      ],
      "keyboard": [
        {
          "key": "Tab / Shift+Tab",
          "action": "Focuses the child trigger; tooltip appears after delay."
        },
        {
          "key": "Escape",
          "action": "Dismisses the tooltip without moving focus."
        }
      ],
      "accessibilitySpec": {
        "semantics": "role=tooltip associated through aria-describedby only while visible.",
        "accessibleName": "content provides the supplemental description; the trigger still needs its own accessible name.",
        "requirements": [
          "Wrap exactly one focusable trigger.",
          "Preserve existing trigger event handlers and aria-describedby; the component composes them.",
          "Keep content non-interactive and supplemental.",
          "Do not use the tooltip as the accessible name of an icon button."
        ]
      },
      "implementation": {
        "importStatement": "import { Tooltip } from '@ai-created/ui';",
        "clientComponent": true,
        "notes": [
          "The child element is cloned to compose hover, focus, blur, and touch handlers.",
          "Show and hover-bridge timeouts are cleared on hide and unmount.",
          "The bubble portals to document.body, flips to the opposite side when needed, clamps to the viewport, and tracks scroll/resize.",
          "Escape and outside touch listeners exist only while visible."
        ]
      },
      "guidance": {
        "dos": [
          "Use to explain an unfamiliar icon or compact control.",
          "Keep one short sentence or phrase."
        ],
        "donts": [
          "Do not put links, buttons, or form fields inside.",
          "Do not repeat a visible label verbatim without adding value."
        ]
      },
      "testing": {
        "unit": [
          "Composes existing child handlers and aria-describedby.",
          "Clears timers and temporary listeners."
        ],
        "interaction": [
          "Hover/focus delay, pointer travel onto the bubble, Escape, leave/blur, touch toggle, outside touch, flip, clamp, scroll, and resize behave correctly."
        ],
        "accessibility": [
          "Role, id relationship, trigger name, Escape dismissal, and keyboard discoverability are valid."
        ],
        "visual": [
          "Capture all positions, viewport edges, wrapping at max width, focus/hover visibility, and themes."
        ]
      },
      "relatedComponents": [
        "button"
      ],
      "controls": {
        "position": {
          "type": "select",
          "label": "Position",
          "defaultValue": "top",
          "options": [
            "top",
            "bottom",
            "left",
            "right"
          ]
        },
        "delay": {
          "type": "number",
          "label": "Delay",
          "defaultValue": 300,
          "min": 0,
          "max": 1000,
          "step": 50,
          "unit": "ms"
        },
        "content": {
          "type": "text",
          "label": "Content",
          "defaultValue": "Copy link"
        }
      },
      "construction": {
        "asset": {
          "kind": "component",
          "figmaName": "Components/Overlays/Tooltip",
          "localName": "Tooltip",
          "canvasApplicability": "Publish position and visibility variants attached to an example trigger."
        },
        "autoLayout": {
          "applicable": true,
          "direction": "horizontal",
          "gap": "0px",
          "padding": "6px 12px",
          "alignment": "Center",
          "wrap": "Text wraps up to maximum width",
          "notes": []
        },
        "resizing": {
          "applicable": true,
          "width": "hug",
          "height": "hug",
          "minWidth": "Content width",
          "maxWidth": "240px",
          "minHeight": "Content controlled",
          "maxHeight": "Content controlled",
          "overflow": "visible",
          "notes": []
        },
        "exposedProperties": [
          {
            "name": "content",
            "label": "Content",
            "type": "text",
            "required": true,
            "defaultValue": "Helpful information",
            "codeMapping": "content"
          },
          {
            "name": "position",
            "label": "Position",
            "type": "variant",
            "required": false,
            "defaultValue": "top",
            "options": [
              "top",
              "bottom",
              "left",
              "right"
            ],
            "codeMapping": "position"
          },
          {
            "name": "delay",
            "label": "Delay",
            "type": "number",
            "required": false,
            "defaultValue": 300,
            "codeMapping": "delay"
          },
          {
            "name": "visible",
            "label": "Visible preview",
            "type": "boolean",
            "required": false,
            "defaultValue": true,
            "codeMapping": "Internal interaction state; no public prop"
          },
          {
            "name": "trigger",
            "label": "Trigger",
            "type": "instance-swap",
            "required": true,
            "defaultValue": null,
            "codeMapping": "children"
          }
        ],
        "nestedAssets": [
          {
            "name": "Trigger",
            "kind": "slot",
            "required": true,
            "description": "One focusable element that owns described-by state.",
            "codeMapping": "children"
          },
          {
            "name": "Tooltip bubble",
            "kind": "primitive",
            "required": true,
            "description": "Positioned supplemental text.",
            "codeMapping": "<span role=\"tooltip\">"
          }
        ],
        "contentLimits": [
          {
            "target": "Content",
            "limit": "One short sentence, maximum about 120 characters",
            "overflowBehavior": "Wrap up to 240px; move longer guidance into persistent UI.",
            "rationale": "Tooltips are supplemental and transient."
          },
          {
            "target": "Children",
            "limit": "Exactly one focusable trigger",
            "overflowBehavior": "Wrap compound visuals in one semantic control.",
            "rationale": "Focus and described-by must have one owner."
          }
        ],
        "localization": {
          "translatable": [
            "Content"
          ],
          "rtlBehavior": [
            "Position uses physical sides today; choose the appropriate side for the layout direction.",
            "Text follows locale direction."
          ],
          "stressCases": [
            "Test 240px maximum width.",
            "Test touch, keyboard, and pointer access with translated text."
          ]
        },
        "responsive": {
          "strategy": "Bubble hugs content, portals to the document, flips when the opposite side fits, and clamps within an 8px viewport inset.",
          "breakpoints": [
            "No internal breakpoint"
          ],
          "behavior": [
            "Preferred physical side remains consumer-selected.",
            "Do not depend on tooltip access for essential mobile instructions."
          ]
        },
        "limitations": {
          "figma": [
            "Figma hover prototypes do not cover delayed focus, pointer travel, Escape, touch toggling, outside touch, viewport collision, or aria-describedby."
          ],
          "code": [
            "Keep content supplemental, plain text, and non-interactive."
          ],
          "notApplicable": []
        },
        "governance": {
          "status": "stable",
          "ownerRole": "Design systems overlay primitive owner",
          "lastReviewed": "2026-08-29",
          "canonicalSource": "src/components/Tooltip.tsx",
          "changePolicy": [
            "Timing or trigger-event changes require input-modality and accessibility testing.",
            "A breaking property, token, or behavior change requires design and engineering approval, a migration note, and a major release.",
            "The design asset, implementation, documentation, accessibility contract, and regression coverage must ship in the same change."
          ]
        }
      }
    },
    {
      "id": "themed-hero-image",
      "name": "ThemedHeroImage",
      "category": "Theme & media",
      "purpose": "Displays a decorative hero image that adapts to the active theme.",
      "useWhen": [
        "Large decorative hero backgrounds"
      ],
      "avoidWhen": [
        "Content images that need an alt description"
      ],
      "api": [
        {
          "prop": "darkSrc",
          "type": "string",
          "defaultValue": "required",
          "description": "Dark-theme image source."
        },
        {
          "prop": "lightSrc",
          "type": "string",
          "defaultValue": "undefined",
          "description": "Optional light-theme source."
        },
        {
          "prop": "overlay",
          "type": "default | strong | soft | none",
          "defaultValue": "default",
          "description": "Overlay treatment."
        },
        {
          "prop": "priority",
          "type": "boolean",
          "defaultValue": "false",
          "description": "Next Image priority loading."
        },
        {
          "prop": "quality",
          "type": "number",
          "defaultValue": "85",
          "description": "Image quality."
        },
        {
          "prop": "sizes",
          "type": "string",
          "defaultValue": "100vw",
          "description": "Responsive image sizes."
        },
        {
          "prop": "objectPosition",
          "type": "string",
          "defaultValue": "undefined",
          "description": "Image object position."
        },
        {
          "prop": "fadeTop",
          "type": "boolean",
          "defaultValue": "false",
          "description": "Top fade."
        },
        {
          "prop": "fadeBottom",
          "type": "boolean",
          "defaultValue": "false",
          "description": "Bottom fade."
        },
        {
          "prop": "blendLight",
          "type": "boolean",
          "defaultValue": "false",
          "description": "Light-theme blend."
        }
      ],
      "states": [
        "dark theme",
        "light theme"
      ],
      "accessibility": [
        "Image is intentionally decorative with empty alt text."
      ],
      "composition": [
        "Place behind hero content in a positioned container."
      ],
      "code": "<ThemedHeroImage darkSrc=\"/hero-dark.jpg\" lightSrc=\"/hero-light.jpg\" fadeBottom />",
      "slug": "themed-hero-image",
      "summary": "A decorative, theme-aware hero background with coordinated overlays, fades, and optional light blending.",
      "sourcePath": "src/components/ThemedHeroImage.tsx",
      "packageExports": [
        "ThemedHeroImage",
        "ThemedHeroImageProps"
      ],
      "anatomy": [
        {
          "name": "Positioning root",
          "description": "Absolute full-bleed media container.",
          "required": true,
          "semanticElement": "div"
        },
        {
          "name": "Dark image",
          "description": "Required default decorative image.",
          "required": true
        },
        {
          "name": "Light image",
          "description": "Optional cross-faded light-theme image.",
          "required": false
        },
        {
          "name": "Overlay",
          "description": "Theme-aware contrast layer.",
          "required": false
        },
        {
          "name": "Top/bottom fades",
          "description": "Optional gradients blending into page background.",
          "required": false
        }
      ],
      "visualSpec": {
        "measurements": [
          {
            "property": "Bounds",
            "value": "absolute inset 0"
          },
          {
            "property": "Image fit",
            "value": "cover"
          },
          {
            "property": "Theme cross-fade",
            "value": "500ms during theme transitions"
          },
          {
            "property": "Fade depth",
            "value": "one third of container height"
          },
          {
            "property": "Default quality",
            "value": "85"
          }
        ],
        "rules": [
          "Parent must establish positioning and an explicit height.",
          "Maintain sufficient text contrast over both images.",
          "Use only for decorative imagery; content images require semantic Image usage."
        ],
        "responsiveBehavior": [
          "sizes defaults to 100vw and should be narrowed when the image is not full viewport width.",
          "objectPosition controls art-direction focus as the container crops."
        ]
      },
      "designTokens": [
        {
          "token": "--hero-overlay-default / strong / soft",
          "purpose": "Theme-specific contrast overlays."
        },
        {
          "token": "--hero-image-dark-opacity / --hero-image-light-opacity",
          "purpose": "Theme image swap."
        },
        {
          "token": "--color-bg",
          "purpose": "Top and bottom fade destination."
        },
        {
          "token": "--motion-slow",
          "purpose": "Theme cross-fade."
        }
      ],
      "stateDefinitions": [
        {
          "name": "dark theme",
          "trigger": "Root does not have light class.",
          "visual": "Dark source is opaque; optional light source is transparent; dark overlay values apply.",
          "behavior": "Image remains decorative."
        },
        {
          "name": "light theme",
          "trigger": "Root has light class.",
          "visual": "Optional light source is opaque and dark source transparent; warm overlay values apply.",
          "behavior": "blendLight can multiply the image into the light surface."
        }
      ],
      "keyboard": [],
      "accessibilitySpec": {
        "semantics": "Next Image elements use empty alt and aria-hidden; overlays are plain decorative divs.",
        "accessibleName": "No accessible name by design.",
        "requirements": [
          "Use only when the image conveys no information that is absent from nearby text.",
          "Do not put interactive content inside the component.",
          "Verify overlaid text contrast independently in both themes and crop sizes."
        ]
      },
      "implementation": {
        "importStatement": "import { ThemedHeroImage } from '@ai-created/ui';",
        "clientComponent": false,
        "notes": [
          "Requires Next.js Image configuration for external sources.",
          "priority applies only to the dark image; use it for an above-the-fold hero.",
          "If lightSrc is absent, the dark image remains fully visible in both themes.",
          "overlay none deliberately renders no overlay node."
        ]
      },
      "guidance": {
        "dos": [
          "Art-direct dark and light sources for comparable subject placement.",
          "Set accurate sizes and use priority only above the fold."
        ],
        "donts": [
          "Do not use for product screenshots or informative charts.",
          "Do not assume an overlay guarantees accessible contrast."
        ]
      },
      "testing": {
        "unit": [
          "Maps overlay, fades, blend, sizes, quality, priority, and object position.",
          "Renders one or two images as configured."
        ],
        "interaction": [
          "Theme class changes swap opacity without affecting layout."
        ],
        "accessibility": [
          "Images remain hidden from the accessibility tree and overlaid copy passes contrast."
        ],
        "visual": [
          "Capture dark/light, every overlay, fades, blend, and representative crop ratios."
        ]
      },
      "relatedComponents": [
        "theme",
        "surface"
      ],
      "controls": {
        "overlay": {
          "type": "select",
          "label": "Overlay",
          "defaultValue": "default",
          "options": [
            "default",
            "strong",
            "soft",
            "none"
          ]
        },
        "fadeTop": {
          "type": "boolean",
          "label": "Top fade",
          "defaultValue": false
        },
        "fadeBottom": {
          "type": "boolean",
          "label": "Bottom fade",
          "defaultValue": false
        },
        "blendLight": {
          "type": "boolean",
          "label": "Light blend",
          "defaultValue": false
        }
      },
      "construction": {
        "asset": {
          "kind": "component",
          "figmaName": "Components/Media/Themed hero image",
          "localName": "ThemedHeroImage",
          "canvasApplicability": "Publish a frame-filling media component with dark and light image swaps and overlay variants."
        },
        "autoLayout": {
          "applicable": true,
          "direction": "overlay",
          "gap": "0px",
          "padding": "0px",
          "alignment": "Stretch to all frame edges",
          "wrap": "Layers overlap",
          "notes": [
            "Layer order is media, theme alternative, overlay, top fade, then bottom fade."
          ]
        },
        "resizing": {
          "applicable": true,
          "width": "fill",
          "height": "fill",
          "minWidth": "Parent controlled",
          "maxWidth": "Parent controlled",
          "minHeight": "Parent controlled",
          "maxHeight": "Parent controlled",
          "overflow": "clip",
          "notes": [
            "The parent must be positioned and have an explicit or content-derived height."
          ]
        },
        "exposedProperties": [
          {
            "name": "darkSrc",
            "label": "Dark image",
            "type": "instance-swap",
            "required": true,
            "defaultValue": null,
            "codeMapping": "darkSrc"
          },
          {
            "name": "lightSrc",
            "label": "Light image",
            "type": "instance-swap",
            "required": false,
            "defaultValue": null,
            "codeMapping": "lightSrc"
          },
          {
            "name": "overlay",
            "label": "Overlay",
            "type": "variant",
            "required": false,
            "defaultValue": "default",
            "options": [
              "default",
              "strong",
              "soft",
              "none"
            ],
            "codeMapping": "overlay"
          },
          {
            "name": "fadeTop",
            "label": "Top fade",
            "type": "boolean",
            "required": false,
            "defaultValue": false,
            "codeMapping": "fadeTop"
          },
          {
            "name": "fadeBottom",
            "label": "Bottom fade",
            "type": "boolean",
            "required": false,
            "defaultValue": false,
            "codeMapping": "fadeBottom"
          },
          {
            "name": "blendLight",
            "label": "Light blend",
            "type": "boolean",
            "required": false,
            "defaultValue": false,
            "codeMapping": "blendLight"
          },
          {
            "name": "objectPosition",
            "label": "Focal point",
            "type": "text",
            "required": false,
            "defaultValue": "center",
            "codeMapping": "objectPosition"
          }
        ],
        "nestedAssets": [
          {
            "name": "Dark media",
            "kind": "slot",
            "required": true,
            "description": "Required decorative image.",
            "codeMapping": "darkSrc"
          },
          {
            "name": "Light media",
            "kind": "slot",
            "required": false,
            "description": "Optional light-theme image.",
            "codeMapping": "lightSrc"
          },
          {
            "name": "Overlay",
            "kind": "primitive",
            "required": false,
            "description": "Theme token overlay treatment.",
            "codeMapping": "Internal overlay layer"
          },
          {
            "name": "Fades",
            "kind": "primitive",
            "required": false,
            "description": "Top and bottom content-legibility fades.",
            "codeMapping": "Internal fade layers"
          }
        ],
        "contentLimits": [
          {
            "target": "Media role",
            "limit": "Decorative hero imagery only",
            "overflowBehavior": "Use a semantic image component for meaningful content.",
            "rationale": "The implementation always uses empty alt text."
          },
          {
            "target": "File weight",
            "limit": "Use the smallest source that remains sharp at rendered sizes",
            "overflowBehavior": "Create responsive optimized assets.",
            "rationale": "Hero media has high performance impact."
          }
        ],
        "localization": {
          "translatable": [],
          "rtlBehavior": [
            "Image framing must preserve important subjects for both directions.",
            "Do not place baked-in text in the source image."
          ],
          "stressCases": [
            "Review focal points with right-to-left copy placement.",
            "Test dark and light assets behind twice-length headings."
          ]
        },
        "responsive": {
          "strategy": "Absolute fill with object-cover.",
          "breakpoints": [
            "Use sizes to describe actual layout breakpoints"
          ],
          "behavior": [
            "Set a focal point that survives crop changes.",
            "Parent owns aspect ratio and minimum content height.",
            "Provide an accurate sizes value for image selection."
          ]
        },
        "limitations": {
          "figma": [
            "Figma fills do not validate Next Image loading, responsive source selection, or blend behavior."
          ],
          "code": [
            "Always decorative; do not use for content that needs alternative text."
          ],
          "notApplicable": []
        },
        "governance": {
          "status": "stable",
          "ownerRole": "Design systems media foundations owner",
          "lastReviewed": "2026-08-29",
          "canonicalSource": "src/components/ThemedHeroImage.tsx",
          "changePolicy": [
            "Overlay and blend changes require contrast review against representative hero copy.",
            "A breaking property, token, or behavior change requires design and engineering approval, a migration note, and a major release.",
            "The design asset, implementation, documentation, accessibility contract, and regression coverage must ship in the same change."
          ]
        }
      }
    },
    {
      "id": "theme",
      "name": "ThemeProvider / useTheme / ThemeToggle",
      "category": "Theme & media",
      "purpose": "Controls dark/light mode and the active accessible accent scheme.",
      "useWhen": [
        "Applications supporting theme and accent preferences"
      ],
      "avoidWhen": [
        "Components that should not own global theme state"
      ],
      "api": [
        {
          "prop": "ThemeProvider.children",
          "type": "ReactNode",
          "defaultValue": "required",
          "description": "Application subtree."
        },
        {
          "prop": "ThemeProvider.accent",
          "type": "Accent",
          "defaultValue": "undefined",
          "description": "Controlled, fixed accent; wins over storage and defaults."
        },
        {
          "prop": "ThemeProvider.defaultAccent",
          "type": "Accent",
          "defaultValue": "red",
          "description": "Uncontrolled fallback after storage and document accent."
        },
        {
          "prop": "ThemeProvider.onAccentChange",
          "type": "(accent: Accent) => void",
          "defaultValue": "undefined",
          "description": "Receives setAccent requests in either mode; controlled changes are not persisted."
        },
        {
          "prop": "useTheme().theme",
          "type": "dark | light",
          "defaultValue": "dark",
          "description": "Current theme."
        },
        {
          "prop": "useTheme().accent",
          "type": "Accent",
          "defaultValue": "red",
          "description": "Current accent scheme."
        },
        {
          "prop": "useTheme().setAccent",
          "type": "(accent: Accent) => void",
          "defaultValue": "undefined",
          "description": "Persists uncontrolled changes; controlled mode reports through the callback or is a no-op."
        },
        {
          "prop": "useTheme().toggleTheme",
          "type": "() => void",
          "defaultValue": "undefined",
          "description": "Switches and persists the theme."
        },
        {
          "prop": "ThemeToggle",
          "type": "component",
          "defaultValue": "undefined",
          "description": "Ready-made theme switch control."
        }
      ],
      "states": [
        "dark",
        "light",
        "red / green / blue / orange / yellow / purple / teal / pink / magenta"
      ],
      "accessibility": [
        "ThemeToggle exposes a labelled button.",
        "Every accent is browser contrast-tested on dark and light foundations.",
        "Respect saved theme and accent setup before rendering content.",
        "Never communicate meaning by accent color alone; status colors remain independent."
      ],
      "composition": [
        "Wrap the app once with ThemeProvider.",
        "Use useTheme for custom controls.",
        "Use semantic accent tokens; destructive and feedback colors retain their meanings."
      ],
      "code": "<ThemeProvider defaultAccent=\"blue\"><ThemeToggle /><App /></ThemeProvider>",
      "slug": "theme",
      "summary": "Application-level dark/light and accent state, persistence, reduced-motion configuration, and a ready-made switch action.",
      "sourcePath": "src/components/ThemeProvider.tsx",
      "packageExports": [
        "ThemeProvider",
        "useTheme",
        "ThemeToggle",
        "Theme",
        "Accent",
        "accentNames",
        "ThemeContextValue",
        "ThemeProviderProps"
      ],
      "anatomy": [
        {
          "name": "Theme provider",
          "description": "Context owner and document class/data-attribute synchronizer.",
          "required": true
        },
        {
          "name": "Motion configuration",
          "description": "Global reduced-motion policy set to user preference.",
          "required": true
        },
        {
          "name": "Theme toggle",
          "description": "Optional 44px icon action that reads and changes context.",
          "required": false,
          "semanticElement": "button"
        },
        {
          "name": "Root theme class",
          "description": "Document hook that activates dark/light semantic token overrides and native color-scheme.",
          "required": true,
          "semanticElement": "html.light"
        },
        {
          "name": "Root accent attribute",
          "description": "Document hook selecting the active accent scheme.",
          "required": true,
          "semanticElement": "html[data-accent]"
        }
      ],
      "visualSpec": {
        "measurements": [
          {
            "property": "ThemeToggle target",
            "value": "44 × 44px"
          },
          {
            "property": "ThemeToggle icon",
            "value": "18 × 18px"
          },
          {
            "property": "Appearance transition",
            "value": "300ms colors / 500ms hero images"
          },
          {
            "property": "Toggle tap scale",
            "value": "0.85×"
          },
          {
            "property": "Toggle hover scale",
            "value": "1.1×"
          }
        ],
        "rules": [
          "Wrap the application once.",
          "Use semantic tokens so components switch without per-component theme or accent branches.",
          "Initialize the html class and data-accent before paint in the consuming app to avoid an appearance flash."
        ]
      },
      "designTokens": [
        {
          "token": "--color-bg / surface / surface2",
          "purpose": "Theme foundations."
        },
        {
          "token": "--color-text / text2 / text3",
          "purpose": "Theme typography hierarchy."
        },
        {
          "token": "--color-accent* / --color-action-primary* / --color-focus / --color-selection",
          "purpose": "Role-tuned active accent scheme colors."
        },
        {
          "token": "--color-success / warning / info / error*",
          "purpose": "Stable feedback semantics that never follow the accent."
        },
        {
          "token": "--motion-base / --motion-slow",
          "purpose": "Theme and image transitions."
        }
      ],
      "stateDefinitions": [
        {
          "name": "dark",
          "trigger": "Default or saved dark preference.",
          "visual": "Neutral-950 background, light text, dark semantic palette; toggle shows sun.",
          "behavior": "toggleTheme stores light and adds html.light."
        },
        {
          "name": "light",
          "trigger": "Saved or pre-rendered light preference.",
          "visual": "Warm-neutral background, dark text, light semantic palette; toggle shows moon.",
          "behavior": "toggleTheme stores dark and removes html.light."
        },
        {
          "name": "accent scheme",
          "trigger": "Controlled accent prop, or uncontrolled saved accent > existing data-accent > defaultAccent > red.",
          "visual": "Accent, primary action, focus, selection, and supporting accent roles adopt the selected family.",
          "behavior": "Uncontrolled setAccent persists, updates html[data-accent], and reports through onAccentChange. Controlled accent is fixed; setAccent reports through onAccentChange without persistence, or is a no-op when no callback exists. Destructive and feedback roles remain unchanged."
        }
      ],
      "keyboard": [
        {
          "key": "Enter / Space",
          "action": "Activates ThemeToggle."
        },
        {
          "key": "Tab / Shift+Tab",
          "action": "Moves focus to or from ThemeToggle."
        }
      ],
      "accessibilitySpec": {
        "semantics": "Context provider plus native motion button; ThemeToggle has a state-dependent aria-label and title.",
        "accessibleName": "ThemeToggle announces the action it will perform, such as Switch to light mode.",
        "requirements": [
          "Run a pre-hydration appearance script or equivalent to keep theme, accent, and context state aligned at first paint.",
          "Do not encode information solely in the active theme or accent.",
          "Every accent role must retain its browser-tested contrast contract across all dark/light foundations.",
          "MotionConfig and CSS reduced-motion rules must remain enabled."
        ]
      },
      "implementation": {
        "importStatement": "import { ThemeProvider, ThemeToggle, useTheme } from '@ai-created/ui';",
        "clientComponent": true,
        "notes": [
          "ThemeProvider reads localStorage after mount and falls back to the existing html class or dark.",
          "accent is controlled and fixed; defaultAccent is the uncontrolled fallback and red is the default.",
          "onAccentChange receives setAccent requests in either mode; controlled changes are never persisted.",
          "Uncontrolled precedence is valid localStorage[accent] > existing html[data-accent] > defaultAccent > red.",
          "toggleTheme updates context, localStorage, html.light, and temporarily adds theme-transitioning.",
          "Uncontrolled setAccent updates context, localStorage[accent], html[data-accent], and calls onAccentChange when provided.",
          "The transition class is removed after the 500ms theme-media window, restarted on repeated toggles, and cleaned on unmount.",
          "The token stylesheet sets color-scheme for native controls in both modes.",
          "useTheme outside a provider receives the safe dark/red default context."
        ]
      },
      "guidance": {
        "dos": [
          "Apply the initial document class before React hydration.",
          "Use useTheme only for behavior or media that cannot be expressed through tokens."
        ],
        "donts": [
          "Do not hard-code dark-only colors inside components.",
          "Do not nest competing ThemeProviders."
        ]
      },
      "testing": {
        "unit": [
          "Resolves saved, existing-class, default themes, and uncontrolled accent precedence.",
          "Controlled accent wins over storage/document/default; callback and no-op behavior are covered.",
          "toggleTheme updates context, storage, and document class.",
          "Uncontrolled setAccent updates context, storage, and html[data-accent]."
        ],
        "interaction": [
          "ThemeToggle changes mode by pointer and keyboard and updates its label/icon."
        ],
        "accessibility": [
          "Accent choices have an accessible name and do not communicate meaning by color alone; reduced-motion preference is honored."
        ],
        "visual": [
          "Capture every foundation and public component across all nine accents and both themes, including transition and no-motion states; browser-test accent text, muted text, borders, actions, focus, selection, and action foregrounds on bg, surface, and surface2."
        ]
      },
      "relatedComponents": [
        "themed-hero-image",
        "motion-helpers",
        "button"
      ],
      "controls": {
        "theme": {
          "type": "select",
          "label": "Theme",
          "defaultValue": "dark",
          "options": [
            "dark",
            "light"
          ]
        },
        "accent": {
          "type": "select",
          "label": "Accent",
          "defaultValue": "red",
          "options": [
            "red",
            "green",
            "blue",
            "orange",
            "yellow",
            "purple",
            "teal",
            "pink",
            "magenta"
          ]
        }
      },
      "construction": {
        "asset": {
          "kind": "provider",
          "figmaName": null,
          "localName": "ThemeProvider / useTheme / ThemeToggle",
          "canvasApplicability": "ThemeProvider and useTheme have no canvas geometry. Represent dark and light through Figma variable modes; document ThemeToggle separately as the visible consumer."
        },
        "autoLayout": {
          "applicable": false,
          "direction": "none",
          "gap": "Not applicable",
          "padding": "Not applicable",
          "alignment": "Not applicable",
          "wrap": "Not applicable",
          "notes": [
            "A context provider and hook do not have a rendered layout box."
          ]
        },
        "resizing": {
          "applicable": false,
          "width": "not-applicable",
          "height": "not-applicable",
          "minWidth": "Not applicable",
          "maxWidth": "Not applicable",
          "minHeight": "Not applicable",
          "maxHeight": "Not applicable",
          "overflow": "not-applicable",
          "notes": [
            "Provider and hook dimensions are not applicable; child layout remains unchanged."
          ]
        },
        "exposedProperties": [
          {
            "name": "theme",
            "label": "Theme mode",
            "type": "variant",
            "required": false,
            "defaultValue": "dark",
            "options": [
              "dark",
              "light"
            ],
            "codeMapping": "ThemeProvider context and the dark or light Figma variable mode"
          },
          {
            "name": "accent",
            "label": "Accent scheme",
            "type": "variant",
            "required": false,
            "defaultValue": "red",
            "options": [
              "red",
              "green",
              "blue",
              "orange",
              "yellow",
              "purple",
              "teal",
              "pink",
              "magenta"
            ],
            "codeMapping": "ThemeProvider context and active data-accent selector"
          },
          {
            "name": "children",
            "label": "Application subtree",
            "type": "slot",
            "required": true,
            "defaultValue": null,
            "codeMapping": "ThemeProvider children"
          }
        ],
        "nestedAssets": [
          {
            "name": "Theme context",
            "kind": "provider",
            "required": true,
            "description": "Stores and exposes the active mode and accent scheme.",
            "codeMapping": "ThemeProvider and useTheme"
          },
          {
            "name": "Motion configuration",
            "kind": "provider",
            "required": true,
            "description": "Honors the user reduced-motion preference.",
            "codeMapping": "MotionConfig inside ThemeProvider"
          },
          {
            "name": "ThemeToggle",
            "kind": "subcomponent",
            "required": false,
            "description": "Ready-made visible mode switch.",
            "codeMapping": "ThemeToggle"
          }
        ],
        "contentLimits": [
          {
            "target": "Provider instances",
            "limit": "One provider at the application root",
            "overflowBehavior": "Remove nested ownership unless an isolated preview explicitly requires it.",
            "rationale": "Multiple competing global theme owners cause inconsistent persistence."
          }
        ],
        "localization": {
          "translatable": [
            "ThemeToggle accessible label and title"
          ],
          "rtlBehavior": [
            "Theme mode is direction-neutral.",
            "Toggle placement follows the consuming layout."
          ],
          "stressCases": [
            "Test localized mode names in the toggle.",
            "Test first render without stored preference."
          ]
        },
        "responsive": {
          "strategy": "No provider geometry; all descendants retain their own responsive contracts.",
          "breakpoints": [
            "Not applicable to provider"
          ],
          "behavior": [
            "ThemeToggle preserves its 44px square footprint wherever placed."
          ]
        },
        "limitations": {
          "figma": [
            "There is no Figma component instance for context behavior; use variable modes and a documented visible toggle.",
            "Prototype variables do not reproduce localStorage persistence, accent persistence, or pre-hydration theme resolution."
          ],
          "code": [
            "Wrap the app once and avoid component-owned global mode changes.",
            "Keep destructive and feedback colors independent from the selected accent."
          ],
          "notApplicable": [
            "Auto layout, padding, gap, resizing, and overflow do not apply to ThemeProvider or useTheme."
          ]
        },
        "governance": {
          "status": "stable",
          "ownerRole": "Design systems theming foundations owner",
          "lastReviewed": "2026-08-29",
          "canonicalSource": "src/components/ThemeProvider.tsx",
          "changePolicy": [
            "Mode, accent, persistence, root selector, or styles/tokens.css changes require token, rendering, and accessibility review across every scheme and both themes.",
            "A breaking property, token, or behavior change requires design and engineering approval, a migration note, and a major release.",
            "The design asset, implementation, documentation, accessibility contract, and regression coverage must ship in the same change."
          ]
        }
      }
    },
    {
      "id": "cn",
      "name": "cn",
      "category": "Utilities & motion",
      "purpose": "Combines conditional class strings and resolves conflicting Tailwind utilities.",
      "useWhen": [
        "A component needs conditional classes or consumer className merging"
      ],
      "avoidWhen": [
        "A static className needs no composition"
      ],
      "api": [
        {
          "prop": "...inputs",
          "type": "Array<string | false | null | undefined>",
          "defaultValue": "required",
          "description": "Class fragments in precedence order."
        }
      ],
      "states": [
        "not applicable"
      ],
      "accessibility": [
        "Class merging must not remove focus, disabled, or semantic state styles."
      ],
      "composition": [
        "Pass the consumer className last when it should override defaults."
      ],
      "code": "const classes = cn(\"rounded-md border\", active && \"border-accent\", className);",
      "slug": "cn",
      "summary": "The class-composition utility that filters conditional fragments and resolves conflicting Tailwind utilities.",
      "sourcePath": "src/lib/utils.ts",
      "packageExports": [
        "cn"
      ],
      "anatomy": [
        {
          "name": "Input fragments",
          "description": "Ordered strings or falsy conditional values.",
          "required": true
        },
        {
          "name": "Falsy filter",
          "description": "Removes false, null, and undefined inputs.",
          "required": true
        },
        {
          "name": "Tailwind merge",
          "description": "Resolves utility conflicts by precedence.",
          "required": true
        },
        {
          "name": "Class string",
          "description": "Serializable final className.",
          "required": true
        }
      ],
      "visualSpec": {
        "measurements": [
          {
            "property": "Output",
            "value": "One whitespace-delimited class string"
          }
        ],
        "rules": [
          "Put default classes first and the consumer className last when overrides are allowed.",
          "Do not use arbitrary class conflicts as a substitute for explicit variants.",
          "Focus and semantic-state utilities are part of the component contract."
        ]
      },
      "designTokens": [
        {
          "token": "Consumer-defined semantic tokens",
          "purpose": "cn preserves token-backed Tailwind utilities while resolving conflicts."
        }
      ],
      "stateDefinitions": [
        {
          "name": "not applicable",
          "trigger": "Called during class composition.",
          "visual": "No visual output by itself.",
          "behavior": "Returns the Tailwind-merged string."
        }
      ],
      "keyboard": [],
      "accessibilitySpec": {
        "semantics": "No DOM semantics; output affects the consuming element only.",
        "accessibleName": "Not applicable.",
        "requirements": [
          "Do not merge away required focus-visible, disabled, hidden, or contrast styles.",
          "The consuming component remains responsible for semantics."
        ]
      },
      "implementation": {
        "importStatement": "import { cn } from '@ai-created/ui';",
        "clientComponent": false,
        "notes": [
          "Accepts only string, false, null, and undefined fragments.",
          "Falsy values are filtered before tailwind-merge runs.",
          "Later conflicting utilities take precedence according to tailwind-merge."
        ]
      },
      "guidance": {
        "dos": [
          "Use for conditional variants and intentional consumer overrides.",
          "Keep class ordering predictable."
        ],
        "donts": [
          "Do not pass untrusted class strings.",
          "Do not hide component variant logic in long ad-hoc condition chains."
        ]
      },
      "testing": {
        "unit": [
          "Filters falsy values and preserves non-conflicting order.",
          "Resolves representative Tailwind conflicts in favor of later utilities."
        ],
        "interaction": [
          "Not applicable."
        ],
        "accessibility": [
          "Verify merged output retains focus and disabled utilities."
        ],
        "visual": [
          "Not applicable; visual coverage belongs to consumers."
        ]
      },
      "relatedComponents": [
        "button",
        "surface"
      ],
      "controls": {
        "base": {
          "type": "text",
          "label": "Base classes",
          "defaultValue": "rounded-md px-4 py-3"
        },
        "conditional": {
          "type": "text",
          "label": "Conditional classes",
          "defaultValue": "bg-surface2 text-text"
        },
        "enabled": {
          "type": "boolean",
          "label": "Include conditional",
          "defaultValue": true
        }
      },
      "construction": {
        "asset": {
          "kind": "utility",
          "figmaName": null,
          "localName": "cn",
          "canvasApplicability": "This class-merging function has no Figma or canvas representation."
        },
        "autoLayout": {
          "applicable": false,
          "direction": "none",
          "gap": "Not applicable",
          "padding": "Not applicable",
          "alignment": "Not applicable",
          "wrap": "Not applicable",
          "notes": [
            "A pure string utility emits no element and owns no auto-layout mechanics."
          ]
        },
        "resizing": {
          "applicable": false,
          "width": "not-applicable",
          "height": "not-applicable",
          "minWidth": "Not applicable",
          "maxWidth": "Not applicable",
          "minHeight": "Not applicable",
          "maxHeight": "Not applicable",
          "overflow": "not-applicable",
          "notes": [
            "A pure string utility has no width, height, constraints, or overflow."
          ]
        },
        "exposedProperties": [
          {
            "name": "inputs",
            "label": "Class inputs",
            "type": "slot",
            "required": true,
            "defaultValue": null,
            "codeMapping": "Function arguments in precedence order"
          },
          {
            "name": "conditional",
            "label": "Include conditional input",
            "type": "boolean",
            "required": false,
            "defaultValue": true,
            "codeMapping": "Boolean expression passed as an input"
          }
        ],
        "nestedAssets": [
          {
            "name": "tailwind-merge",
            "kind": "helper",
            "required": true,
            "description": "Resolves conflicting Tailwind utility classes.",
            "codeMapping": "Internal twMerge dependency"
          }
        ],
        "contentLimits": [
          {
            "target": "Inputs",
            "limit": "Class strings plus false, null, or undefined",
            "overflowBehavior": "Split complex style decisions into named variant functions.",
            "rationale": "The utility is for class composition, not component architecture."
          }
        ],
        "localization": {
          "translatable": [],
          "rtlBehavior": [
            "Not applicable; class merging has no reading direction of its own."
          ],
          "stressCases": [
            "Verify logical-direction utilities when building localized components."
          ]
        },
        "responsive": {
          "strategy": "Not applicable; emitted classes inherit Tailwind responsive behavior.",
          "breakpoints": [
            "Not applicable to utility"
          ],
          "behavior": [
            "Responsive behavior is entirely determined by the input class strings."
          ]
        },
        "limitations": {
          "figma": [
            "No Figma asset should be created for this utility."
          ],
          "code": [
            "Passing consumer className last is a policy choice; verify that it cannot remove required state or accessibility styles."
          ],
          "notApplicable": [
            "Canvas geometry, auto layout, component properties, instance swaps, and prototype interactions are not applicable."
          ]
        },
        "governance": {
          "status": "stable",
          "ownerRole": "Design systems engineering foundations owner",
          "lastReviewed": "2026-08-29",
          "canonicalSource": "src/lib/utils.ts",
          "changePolicy": [
            "Input types or merge-engine changes require a repository-wide class precedence audit.",
            "A breaking property, token, or behavior change requires design and engineering approval, a migration note, and a major release.",
            "The design asset, implementation, documentation, accessibility contract, and regression coverage must ship in the same change."
          ]
        }
      }
    },
    {
      "id": "motion-helpers",
      "name": "Motion helpers",
      "category": "Utilities & motion",
      "purpose": "Keeps Framer Motion timing, offsets, easing, reveals, and hover behavior consistent.",
      "useWhen": [
        "Shared entrance, in-view reveal, stagger, or subtle hover behavior is needed"
      ],
      "avoidWhen": [
        "Motion does not clarify hierarchy or state"
      ],
      "api": [
        {
          "prop": "motionDuration",
          "type": "readonly timing object",
          "defaultValue": "shared values",
          "description": "Instant, fast, base, reveal, section, and ambient durations."
        },
        {
          "prop": "motionOffset",
          "type": "readonly offset object",
          "defaultValue": "shared values",
          "description": "Small, medium, large, and hover distances."
        },
        {
          "prop": "motionEase",
          "type": "readonly easing object",
          "defaultValue": "shared values",
          "description": "Standard, in-out, and out easing."
        },
        {
          "prop": "staggerDelay",
          "type": "(index, step?, base?) => number",
          "defaultValue": "step 0.1, base 0",
          "description": "Calculates a list-item delay."
        },
        {
          "prop": "fadeUpMotion",
          "type": "(delay?, y?, duration?) => MotionProps",
          "defaultValue": "shared reveal values",
          "description": "Returns mount animation props."
        },
        {
          "prop": "inViewFadeUpMotion",
          "type": "(delay?, y?, duration?) => MotionProps",
          "defaultValue": "shared reveal values",
          "description": "Returns one-time viewport reveal props."
        },
        {
          "prop": "subtleHoverMotion",
          "type": "(distance?) => MotionProps",
          "defaultValue": "2px",
          "description": "Returns subtle hover lift props."
        },
        {
          "prop": "borderHoverMotion",
          "type": "(distance?, borderColor?) => MotionProps",
          "defaultValue": "4px, border-strong",
          "description": "Returns lift plus border emphasis."
        }
      ],
      "states": [
        "entry",
        "in view",
        "hover",
        "reduced motion"
      ],
      "accessibility": [
        "ThemeProvider configures Framer Motion to honor the user reduced-motion preference.",
        "Never rely on motion alone to communicate meaning."
      ],
      "composition": [
        "Spread helper results onto a Framer Motion element."
      ],
      "code": "<motion.article {...inViewFadeUpMotion(staggerDelay(index))}>...</motion.article>",
      "slug": "motion-helpers",
      "summary": "Shared timing, easing, offsets, reveal recipes, and subtle hover behavior for Framer Motion.",
      "sourcePath": "src/lib/motion.ts",
      "packageExports": [
        "motionDuration",
        "motionOffset",
        "motionEase",
        "staggerDelay",
        "fadeUpMotion",
        "inViewFadeUpMotion",
        "subtleHoverMotion",
        "borderHoverMotion"
      ],
      "anatomy": [
        {
          "name": "Duration scale",
          "description": "Six named timings from instant to ambient.",
          "required": true
        },
        {
          "name": "Offset scale",
          "description": "Reveal and hover travel distances.",
          "required": true
        },
        {
          "name": "Easing scale",
          "description": "Standard cubic bezier and named Framer easings.",
          "required": true
        },
        {
          "name": "Reveal helpers",
          "description": "Serializable Framer Motion prop objects for mount and in-view entrance.",
          "required": true
        },
        {
          "name": "Hover helpers",
          "description": "Serializable lift and border-emphasis prop objects.",
          "required": true
        }
      ],
      "visualSpec": {
        "measurements": [
          {
            "property": "Durations",
            "value": "150 / 200 / 300 / 500 / 600 / 1500ms"
          },
          {
            "property": "Reveal offsets",
            "value": "16 / 20 / 30px"
          },
          {
            "property": "Hover offsets",
            "value": "2 / 4px"
          },
          {
            "property": "Default stagger",
            "value": "100ms per item"
          }
        ],
        "rules": [
          "Use motion to clarify hierarchy or state, not to decorate every element.",
          "Prefer shared values over one-off durations and distances.",
          "In-view reveals run once by default.",
          "Do not rely on motion alone to communicate meaning."
        ]
      },
      "designTokens": [
        {
          "token": "--motion-fast",
          "purpose": "CSS equivalent of 200ms interactions."
        },
        {
          "token": "--motion-base",
          "purpose": "CSS equivalent of 300ms transitions."
        },
        {
          "token": "--motion-slow",
          "purpose": "CSS equivalent of 500ms reveals/cross-fades."
        },
        {
          "token": "--color-border-strong",
          "purpose": "Default borderHoverMotion emphasis."
        }
      ],
      "stateDefinitions": [
        {
          "name": "entry",
          "trigger": "fadeUpMotion props mount.",
          "visual": "Opacity moves 0→1 while y moves to 0.",
          "behavior": "Runs immediately with optional delay."
        },
        {
          "name": "in view",
          "trigger": "inViewFadeUpMotion enters viewport.",
          "visual": "Same fade-up treatment.",
          "behavior": "Runs once when observed."
        },
        {
          "name": "hover",
          "trigger": "Pointer hover on a motion element.",
          "visual": "Element lifts 2px or 4px; border helper also strengthens border.",
          "behavior": "Returns over the shared fast duration."
        },
        {
          "name": "reduced motion",
          "trigger": "User requests reduced motion under ThemeProvider MotionConfig.",
          "visual": "Framer Motion reduces transform motion according to user preference; global CSS collapses animation durations.",
          "behavior": "Meaning and interaction remain available without animation."
        }
      ],
      "keyboard": [],
      "accessibilitySpec": {
        "semantics": "Helpers return presentation props only and do not alter DOM semantics.",
        "accessibleName": "Not applicable.",
        "requirements": [
          "Render motion elements with the correct semantic element and focus behavior.",
          "Use within ThemeProvider so MotionConfig honors the user preference.",
          "Never delay essential content or input availability behind animation.",
          "Avoid hover-only information."
        ]
      },
      "implementation": {
        "importStatement": "import { fadeUpMotion, inViewFadeUpMotion, staggerDelay } from '@ai-created/ui';",
        "clientComponent": false,
        "notes": [
          "Helpers return plain serializable-compatible Framer Motion prop objects.",
          "staggerDelay is deterministic and supports custom step/base.",
          "borderHoverMotion accepts a CSS color string and defaults to the strong-border token.",
          "Consumers provide the motion.* element and semantic tag."
        ]
      },
      "guidance": {
        "dos": [
          "Use subtle consistent motion for hierarchy changes.",
          "Test the result with reduced motion enabled."
        ],
        "donts": [
          "Do not stagger large lists so late content feels blocked.",
          "Do not apply hover lift to controls where movement harms targeting."
        ]
      },
      "testing": {
        "unit": [
          "Constants stay immutable and helpers return exact expected prop shapes.",
          "staggerDelay handles zero, custom base, and custom step."
        ],
        "interaction": [
          "In-view fires once and hover returns to rest.",
          "Reduced-motion configuration suppresses nonessential movement."
        ],
        "accessibility": [
          "No content or state is conveyed only through movement."
        ],
        "visual": [
          "Record representative entry, stagger, hover, and reduced-motion states."
        ]
      },
      "relatedComponents": [
        "theme",
        "themed-hero-image",
        "surface"
      ],
      "controls": {
        "delay": {
          "type": "number",
          "label": "Delay",
          "defaultValue": 0,
          "min": 0,
          "max": 2,
          "step": 0.1,
          "unit": "s"
        },
        "offset": {
          "type": "number",
          "label": "Offset",
          "defaultValue": 20,
          "min": 0,
          "max": 60,
          "step": 1,
          "unit": "px"
        },
        "duration": {
          "type": "number",
          "label": "Duration",
          "defaultValue": 0.5,
          "min": 0,
          "max": 2,
          "step": 0.05,
          "unit": "s"
        }
      },
      "construction": {
        "asset": {
          "kind": "helper",
          "figmaName": null,
          "localName": "Motion helpers",
          "canvasApplicability": "Functions and timing constants have no reusable Figma component geometry. Document approved motion tokens and prototype examples instead."
        },
        "autoLayout": {
          "applicable": false,
          "direction": "none",
          "gap": "Not applicable",
          "padding": "Not applicable",
          "alignment": "Not applicable",
          "wrap": "Not applicable",
          "notes": [
            "Motion helper functions return Framer Motion props and emit no layout container."
          ]
        },
        "resizing": {
          "applicable": false,
          "width": "not-applicable",
          "height": "not-applicable",
          "minWidth": "Not applicable",
          "maxWidth": "Not applicable",
          "minHeight": "Not applicable",
          "maxHeight": "Not applicable",
          "overflow": "not-applicable",
          "notes": [
            "Motion helper functions own transforms and timing, not geometry constraints."
          ]
        },
        "exposedProperties": [
          {
            "name": "delay",
            "label": "Delay",
            "type": "number",
            "required": false,
            "defaultValue": 0,
            "codeMapping": "fadeUpMotion or inViewFadeUpMotion delay argument"
          },
          {
            "name": "offset",
            "label": "Vertical offset",
            "type": "number",
            "required": false,
            "defaultValue": 20,
            "codeMapping": "y argument or motionOffset token"
          },
          {
            "name": "duration",
            "label": "Duration",
            "type": "number",
            "required": false,
            "defaultValue": 0.5,
            "codeMapping": "duration argument or motionDuration token"
          },
          {
            "name": "distance",
            "label": "Hover distance",
            "type": "number",
            "required": false,
            "defaultValue": 2,
            "codeMapping": "subtleHoverMotion or borderHoverMotion distance argument"
          }
        ],
        "nestedAssets": [
          {
            "name": "motionDuration",
            "kind": "helper",
            "required": true,
            "description": "Approved timing constants.",
            "codeMapping": "motionDuration"
          },
          {
            "name": "motionOffset",
            "kind": "helper",
            "required": true,
            "description": "Approved translation distances.",
            "codeMapping": "motionOffset"
          },
          {
            "name": "motionEase",
            "kind": "helper",
            "required": true,
            "description": "Approved easing curves.",
            "codeMapping": "motionEase"
          },
          {
            "name": "Motion element",
            "kind": "slot",
            "required": true,
            "description": "Consumer-owned Framer Motion element receiving helper output.",
            "codeMapping": "Spread returned props onto motion.*"
          }
        ],
        "contentLimits": [
          {
            "target": "Concurrent effects",
            "limit": "One primary entrance or hover effect per element",
            "overflowBehavior": "Remove competing transforms and ambient loops.",
            "rationale": "Motion should clarify hierarchy without becoming decoration."
          },
          {
            "target": "Staggered collections",
            "limit": "Keep total sequence short enough that the last item is not delayed from use",
            "overflowBehavior": "Reduce step or animate groups rather than every row.",
            "rationale": "Content must remain promptly available."
          }
        ],
        "localization": {
          "translatable": [],
          "rtlBehavior": [
            "Transforms must not encode reading direction unless a product-specific helper explicitly does so."
          ],
          "stressCases": [
            "Test reduced motion.",
            "Test layout in both directions to ensure transforms do not imply the wrong flow."
          ]
        },
        "responsive": {
          "strategy": "No intrinsic geometry; the receiving element owns responsive behavior.",
          "breakpoints": [
            "Not applicable to helper"
          ],
          "behavior": [
            "Reduce or remove spatial motion where small screens make displacement distracting.",
            "Do not delay interactivity while animation completes."
          ]
        },
        "limitations": {
          "figma": [
            "Figma prototype easing and timing are reference approximations, not the canonical implementation.",
            "Do not create a detached component for each animation helper."
          ],
          "code": [
            "ThemeProvider is required for the shared reduced-motion policy.",
            "Helper output may be overridden by later Framer Motion props."
          ],
          "notApplicable": [
            "Auto layout, component resizing, text limits, and instance swapping are not owned by motion helpers."
          ]
        },
        "governance": {
          "status": "stable",
          "ownerRole": "Design systems motion foundations owner",
          "lastReviewed": "2026-08-29",
          "canonicalSource": "src/lib/motion.ts",
          "changePolicy": [
            "Token or helper changes require reduced-motion review and regression checks on every consumer category.",
            "A breaking property, token, or behavior change requires design and engineering approval, a migration note, and a major release.",
            "The design asset, implementation, documentation, accessibility contract, and regression coverage must ship in the same change."
          ]
        }
      }
    }
  ],
  "guidelines": [
    {
      "slug": "foundations",
      "index": "01",
      "title": "Foundations",
      "shortTitle": "Foundations",
      "summary": "The visual, spatial, typographic, motion, media, and accessible accent-scheme decisions that every AI-Created interface inherits.",
      "status": "canonical",
      "owner": "Design Systems",
      "lastReviewed": "August 2026",
      "reviewCycle": "Quarterly and before any token release",
      "sourceOfTruth": "styles/tokens.css and tailwind-preset.js",
      "outcomes": [
        "A product can switch themes and accent schemes without local color overrides.",
        "Design decisions map to named semantic tokens before component styling.",
        "Layouts remain readable from 320px through the 1400px container maximum."
      ],
      "sections": [
        {
          "id": "token-architecture",
          "title": "Token architecture",
          "summary": "Use a three-level naming model so raw values can change without altering product intent.",
          "blocks": [
            {
              "type": "table",
              "title": "Decision hierarchy",
              "columns": [
                "Level",
                "Example",
                "Who uses it",
                "Rule"
              ],
              "rows": [
                [
                  "Reference",
                  "--ref-red-500",
                  "System maintainers",
                  "Stores a raw value. Never use directly in product UI."
                ],
                [
                  "Semantic",
                  "--color-action-primary",
                  "Designers and engineers",
                  "Names intent and owns light and dark mode behavior."
                ],
                [
                  "Component",
                  "Button / Primary / Background",
                  "Component authors",
                  "Maps a component decision to a semantic token."
                ]
              ]
            },
            {
              "type": "rules",
              "title": "Token rules",
              "items": [
                {
                  "title": "Name the purpose",
                  "description": "A token should explain why the value exists, not what its current hex value resembles."
                },
                {
                  "title": "Change every scheme together",
                  "description": "Every accent role is tuned and reviewed across all nine schemes and light/dark mode, including focus and selection; feedback semantics remain stable."
                },
                {
                  "title": "Avoid product aliases",
                  "description": "Do not create a new token for one screen. Promote a value only after a repeated semantic need is demonstrated."
                },
                {
                  "title": "Keep compatibility aliases secondary",
                  "description": "Existing red aliases remain supported public contracts. New work can prefer accent and action names when intent is unambiguous."
                }
              ]
            }
          ]
        },
        {
          "id": "color",
          "title": "Color and contrast",
          "summary": "Accent schemes, committed actions, destructive actions, neutral surfaces, and semantic feedback each have an explicit role.",
          "blocks": [
            {
              "type": "tokens",
              "title": "Core semantic palette",
              "description": "Samples resolve live through the current theme.",
              "items": [
                {
                  "name": "Background",
                  "value": "Canvas",
                  "purpose": "Page background and highest-level negative space.",
                  "cssVariable": "--color-bg"
                },
                {
                  "name": "Surface",
                  "value": "Primary surface",
                  "purpose": "Cards, panels, fields, and floating regions.",
                  "cssVariable": "--color-surface"
                },
                {
                  "name": "Surface 2",
                  "value": "Nested surface",
                  "purpose": "Controls, inset regions, and subtle grouping.",
                  "cssVariable": "--color-surface2"
                },
                {
                  "name": "Text",
                  "value": "Primary content",
                  "purpose": "Headings, labels, and critical information.",
                  "cssVariable": "--color-text"
                },
                {
                  "name": "Accent",
                  "value": "Identity",
                  "purpose": "Links, emphasis, and non-destructive branded actions.",
                  "cssVariable": "--color-accent"
                },
                {
                  "name": "Action primary",
                  "value": "Committed action",
                  "purpose": "High-emphasis action fill.",
                  "cssVariable": "--color-action-primary"
                },
                {
                  "name": "Action destructive",
                  "value": "Consequential action",
                  "purpose": "Destructive action fill, distinct from ordinary commitment.",
                  "cssVariable": "--color-action-destructive"
                },
                {
                  "name": "Control border",
                  "value": "Interactive boundary",
                  "purpose": "Contrast-safe boundaries for inputs and outlined controls.",
                  "cssVariable": "--color-control-border"
                },
                {
                  "name": "Success",
                  "value": "Positive state",
                  "purpose": "Completed or healthy outcomes only.",
                  "cssVariable": "--color-success"
                },
                {
                  "name": "Warning",
                  "value": "Attention state",
                  "purpose": "Recoverable risk or pending attention.",
                  "cssVariable": "--color-warning"
                },
                {
                  "name": "Info",
                  "value": "Neutral state",
                  "purpose": "Contextual or process information.",
                  "cssVariable": "--color-info"
                },
                {
                  "name": "Error",
                  "value": "Failure state",
                  "purpose": "Invalid input, failed operations, and destructive risk.",
                  "cssVariable": "--color-error"
                }
              ]
            },
            {
              "type": "checklist",
              "title": "Color acceptance",
              "groups": [
                {
                  "title": "Required",
                  "items": [
                    "Body text meets 4.5:1 contrast.",
                    "Large text and icons conveying meaning meet 3:1 contrast.",
                    "Focus indicators meet 3:1 against adjacent colors.",
                    "Meaning never relies on color alone."
                  ]
                },
                {
                  "title": "Avoid",
                  "items": [
                    "Raw reference colors in product code.",
                    "Accent decoration competing with primary actions.",
                    "Tinted text on tinted surfaces without contrast validation.",
                    "Theme-specific assets without a paired alternative.",
                    "Letting accent schemes change destructive or feedback meanings."
                  ]
                }
              ]
            }
          ]
        },
        {
          "id": "type-layout",
          "title": "Typography, spacing, and grid",
          "summary": "Instrument Serif creates editorial moments. Space Grotesk carries every functional reading task.",
          "blocks": [
            {
              "type": "table",
              "title": "Type roles",
              "columns": [
                "Role",
                "Family",
                "Typical size",
                "Use"
              ],
              "rows": [
                [
                  "Display / Hero",
                  "Instrument Serif",
                  "60 to 96px",
                  "One primary narrative statement per page."
                ],
                [
                  "Display / Section",
                  "Instrument Serif",
                  "40 to 60px",
                  "Major chapter introductions."
                ],
                [
                  "Heading",
                  "Space Grotesk 500",
                  "20 to 32px",
                  "Functional page and card hierarchy."
                ],
                [
                  "Body",
                  "Space Grotesk 400",
                  "14 to 20px",
                  "Instructions, descriptions, and long-form content."
                ],
                [
                  "Metadata",
                  "System mono",
                  "10 to 12px",
                  "Tokens, statuses, keyboard keys, and code-adjacent labels."
                ]
              ]
            },
            {
              "type": "table",
              "title": "Responsive layout contract",
              "columns": [
                "Range",
                "Gutter",
                "Columns",
                "Behavior"
              ],
              "rows": [
                [
                  "320 to 767px",
                  "6vw",
                  "4",
                  "Stack content, preserve source order, use full-width controls when needed."
                ],
                [
                  "768 to 1023px",
                  "2vw",
                  "8",
                  "Introduce split regions only when each column remains readable."
                ],
                [
                  "1024 to 1399px",
                  "2vw",
                  "12",
                  "Enable persistent secondary navigation and dense matrices."
                ],
                [
                  "1400px and above",
                  "2vw",
                  "12",
                  "Cap primary content at 1400px and grow outer whitespace."
                ]
              ]
            },
            {
              "type": "rules",
              "title": "Composition rules",
              "items": [
                {
                  "title": "Use a 4px base unit",
                  "description": "Tokenized radii and intentional optical adjustments may differ, but layout spacing should resolve to the base unit."
                },
                {
                  "title": "Prefer gap over margins",
                  "description": "Parent layout owns relationships between siblings. Components own only their internal spacing."
                },
                {
                  "title": "Keep reading measures controlled",
                  "description": "Body copy should usually remain between 45 and 75 characters per line."
                },
                {
                  "title": "Preserve hierarchy when stacking",
                  "description": "Responsive changes may alter layout, never the semantic or focus order."
                }
              ]
            }
          ]
        },
        {
          "id": "shape-motion-media",
          "title": "Shape, elevation, motion, icons, and media",
          "summary": "Secondary visual systems remain restrained so content and interaction state stay primary.",
          "blocks": [
            {
              "type": "table",
              "title": "System inventory",
              "columns": [
                "Area",
                "Contract",
                "Current support"
              ],
              "rows": [
                [
                  "Radius",
                  "4px small, 6px default, 10px large, full for pills",
                  "Canonical tokens"
                ],
                [
                  "Elevation",
                  "Border first; shadow only when depth changes interaction meaning",
                  "Local Tailwind effects, not yet canonical tokens"
                ],
                [
                  "Motion",
                  "200ms feedback, 300ms transitions, 500ms entrances",
                  "Canonical duration tokens and shared helpers"
                ],
                [
                  "Icons",
                  "Lucide, 16px inline, 20px controls, 32px empty states",
                  "Code dependency; no separate icon package"
                ],
                [
                  "Imagery",
                  "Theme-paired, art-directed, useful at crop extremes",
                  "ThemedHeroImage plus product-owned assets"
                ],
                [
                  "Data visualization",
                  "Text, shape, and pattern reinforce color",
                  "Guidance only; no chart primitive yet"
                ]
              ]
            },
            {
              "type": "checklist",
              "title": "Media and motion acceptance",
              "groups": [
                {
                  "title": "Motion",
                  "items": [
                    "Animate opacity and transforms when possible.",
                    "Respect prefers-reduced-motion.",
                    "Keep focus and reading order stable during transitions.",
                    "Use motion to explain state or hierarchy, never as idle decoration."
                  ]
                },
                {
                  "title": "Media",
                  "items": [
                    "Provide useful alt text or mark decorative media as empty alt.",
                    "Test both theme sources and missing-image fallbacks.",
                    "Preserve the subject at mobile and wide crops.",
                    "Include captions or transcripts for time-based media."
                  ]
                }
              ]
            }
          ]
        }
      ],
      "sourcePath": "playground/src/components/design-system/principal-spec/registry.ts"
    },
    {
      "slug": "construction",
      "index": "02",
      "title": "Component construction",
      "shortTitle": "Construction",
      "summary": "Figma-equivalent component anatomy, sizing, properties, slots, overrides, and design-to-code parity rules.",
      "status": "operational",
      "owner": "Design Systems and Frontend Platform",
      "lastReviewed": "August 2026",
      "reviewCycle": "With every component API change",
      "sourceOfTruth": "playground component specs and src/components",
      "outcomes": [
        "A designer can create a supported instance without detaching it.",
        "Each design property maps to a public prop, slot, or documented composition.",
        "Resize, localization, and exceptional-state behavior is decided before release."
      ],
      "sections": [
        {
          "id": "asset-model",
          "title": "Asset model and naming",
          "summary": "One component set represents one public concept. Names encode hierarchy, not visual styling.",
          "blocks": [
            {
              "type": "table",
              "title": "Layer naming model",
              "columns": [
                "Layer",
                "Pattern",
                "Example",
                "Rule"
              ],
              "rows": [
                [
                  "Library asset",
                  "Component / Name",
                  "Component / Button",
                  "Matches the public export name."
                ],
                [
                  "Variant property",
                  "Sentence case",
                  "Variant = Primary",
                  "Maps to a finite prop union."
                ],
                [
                  "Boolean property",
                  "Show + noun",
                  "Show icon = True",
                  "Controls optional visibility, not layout hacks."
                ],
                [
                  "Text property",
                  "Content role",
                  "Label = Save",
                  "Exposes only content intended for instance editing."
                ],
                [
                  "Nested layer",
                  "Semantic role",
                  "Leading icon",
                  "Names responsibility rather than shape or position."
                ]
              ]
            },
            {
              "type": "rules",
              "title": "Construction principles",
              "items": [
                {
                  "title": "Mirror the public API",
                  "description": "Variant and boolean properties use the same concepts and defaults as code."
                },
                {
                  "title": "Prefer nested components",
                  "description": "Icons, field messages, and surfaces remain replaceable nested assets where supported."
                },
                {
                  "title": "Protect structural layers",
                  "description": "Consumers may edit content and approved swaps, but should not need to unlock layout layers."
                },
                {
                  "title": "Document intentional gaps",
                  "description": "Utility and provider exports are marked as code-only instead of receiving fictional canvas assets."
                }
              ]
            }
          ]
        },
        {
          "id": "layout-sizing",
          "title": "Auto layout and resizing",
          "summary": "Each axis has an explicit contract: hug, fill, fixed, or content-controlled.",
          "blocks": [
            {
              "type": "table",
              "title": "Sizing decisions",
              "columns": [
                "Mode",
                "Use when",
                "Avoid when",
                "Code equivalent"
              ],
              "rows": [
                [
                  "Hug",
                  "Content defines the useful dimension.",
                  "Peer alignment requires equal widths.",
                  "inline-flex, w-fit, intrinsic sizing"
                ],
                [
                  "Fill",
                  "The parent owns available space.",
                  "The control should remain content-sized.",
                  "w-full, flex-1, min-w-0"
                ],
                [
                  "Fixed",
                  "The dimension is a tokenized target.",
                  "Localized text or user content is present.",
                  "size-* or explicit component token"
                ],
                [
                  "Content-controlled",
                  "Media or a consumer slot owns proportion.",
                  "The component can define a safe default.",
                  "aspect-ratio, min/max constraints"
                ]
              ]
            },
            {
              "type": "checklist",
              "title": "Resize stress test",
              "groups": [
                {
                  "title": "Canvas",
                  "items": [
                    "Test minimum supported width.",
                    "Test fill-container behavior.",
                    "Test 200 percent text scaling.",
                    "Test a three-line translated label.",
                    "Test optional slots removed and replaced."
                  ]
                },
                {
                  "title": "Code",
                  "items": [
                    "Verify flex children use min-width: 0 where truncation is intended.",
                    "Verify hit targets do not shrink below 44 by 44px on touch.",
                    "Verify overflow is documented as wrap, clip, scroll, or expand.",
                    "Verify DOM and focus order match the visual layout."
                  ]
                }
              ]
            }
          ]
        },
        {
          "id": "properties-slots",
          "title": "Properties, slots, and overrides",
          "summary": "Editable surfaces are intentional and finite. They should produce supported code, not arbitrary new component states.",
          "blocks": [
            {
              "type": "rules",
              "title": "Property strategy",
              "items": [
                {
                  "title": "Variants represent meaningful choice",
                  "description": "Use a variant only when appearance and behavior form a named, supported option.",
                  "requirements": [
                    "No boolean explosion",
                    "No duplicated state variants",
                    "No theme property on components"
                  ]
                },
                {
                  "title": "State is demonstrated, not configured",
                  "description": "Hover, focus, pressed, loading, invalid, and disabled are prototype or specimen states unless the API directly owns them."
                },
                {
                  "title": "Slots describe composition boundaries",
                  "description": "A slot declares acceptable content, size, alignment, and fallback behavior."
                },
                {
                  "title": "Instance swaps stay type-safe",
                  "description": "Limit swaps to assets that satisfy the same semantic and dimensional contract."
                }
              ]
            },
            {
              "type": "table",
              "title": "Override policy",
              "columns": [
                "Change",
                "Allowed",
                "Condition"
              ],
              "rows": [
                [
                  "Text content",
                  "Yes",
                  "Within documented content limits and accessible naming rules."
                ],
                [
                  "Nested icon swap",
                  "Yes",
                  "Same icon size and semantic role."
                ],
                [
                  "Semantic color token",
                  "By variant only",
                  "No local fills or raw values."
                ],
                [
                  "Internal spacing",
                  "No",
                  "Request a supported size or composition instead."
                ],
                [
                  "Layer deletion",
                  "Boolean property only",
                  "Do not delete locked structural layers."
                ],
                [
                  "Detach instance",
                  "Exception only",
                  "Requires a documented system gap and follow-up issue."
                ]
              ]
            }
          ]
        },
        {
          "id": "parity",
          "title": "Design-to-code parity",
          "summary": "Parity means equivalent decisions, defaults, states, and behavior. Pixel similarity alone is insufficient.",
          "blocks": [
            {
              "type": "process",
              "title": "Parity review",
              "steps": [
                {
                  "title": "Inventory",
                  "owner": "Designer",
                  "output": "Anatomy, variants, content bounds, resize rules",
                  "gate": "All supported decisions are represented."
                },
                {
                  "title": "Map",
                  "owner": "Engineer",
                  "output": "Property-to-prop and slot-to-composition mapping",
                  "gate": "No design property requires an undocumented override."
                },
                {
                  "title": "Stress",
                  "owner": "Design and QA",
                  "output": "Theme, locale, zoom, keyboard, state evidence",
                  "gate": "Both implementations pass the same acceptance cases."
                },
                {
                  "title": "Publish",
                  "owner": "Design Systems",
                  "output": "Versioned design asset, package release, migration note",
                  "gate": "Sources publish together or the change remains unreleased."
                }
              ]
            },
            {
              "type": "checklist",
              "title": "Definition of parity",
              "groups": [
                {
                  "title": "Design",
                  "items": [
                    "Names and defaults match code.",
                    "All public variants and states are demonstrated.",
                    "Auto layout reproduces responsive intent.",
                    "Tokens are semantic aliases, not copied values."
                  ]
                },
                {
                  "title": "Code",
                  "items": [
                    "Public props match documented properties.",
                    "Native semantics and keyboard behavior are preserved.",
                    "Visual regression covers both themes.",
                    "Release notes identify additions, changes, and deprecations."
                  ]
                }
              ]
            }
          ]
        }
      ],
      "sourcePath": "playground/src/components/design-system/principal-spec/registry.ts"
    },
    {
      "slug": "patterns",
      "index": "03",
      "title": "Product patterns",
      "shortTitle": "Patterns",
      "summary": "Reusable interaction and page-level decisions for common product flows, including their loading, empty, error, and permission states.",
      "status": "operational",
      "owner": "Product Design",
      "lastReviewed": "August 2026",
      "reviewCycle": "Quarterly and after major product launches",
      "sourceOfTruth": "DESIGN-SYSTEM.md and live pattern specimens",
      "outcomes": [
        "Common workflows behave consistently across products.",
        "Teams design the complete state model before the happy path ships.",
        "Patterns compose public primitives without creating hidden component APIs."
      ],
      "sections": [
        {
          "id": "state-model",
          "title": "Complete state model",
          "summary": "Every data-backed surface declares what the user sees before, during, and after work.",
          "blocks": [
            {
              "type": "table",
              "title": "Required product states",
              "columns": [
                "State",
                "Communicate",
                "Primary action",
                "Preferred primitive"
              ],
              "rows": [
                [
                  "Initial",
                  "Purpose and first useful action",
                  "Start or create",
                  "EmptyState"
                ],
                [
                  "Loading",
                  "Structure and progress without layout shift",
                  "Usually none",
                  "Skeleton or inline pending state"
                ],
                [
                  "Success",
                  "Result and next step",
                  "Continue or inspect",
                  "Notice or refreshed content"
                ],
                [
                  "Empty result",
                  "Why no match exists",
                  "Clear filters or change query",
                  "EmptyState"
                ],
                [
                  "Recoverable error",
                  "What failed and how to retry",
                  "Retry",
                  "Notice or inline field message"
                ],
                [
                  "Diagnostic error",
                  "Summary plus inspectable details",
                  "Copy report or retry",
                  "ErrorReport"
                ],
                [
                  "Offline",
                  "Connection dependency and preserved work",
                  "Retry when online",
                  "Notice with local state"
                ],
                [
                  "Permission denied",
                  "Missing access and request path",
                  "Request access",
                  "EmptyState or dedicated page"
                ]
              ]
            }
          ]
        },
        {
          "id": "forms-actions",
          "title": "Forms and committed actions",
          "summary": "Validation stays close to the field while submission status remains clear at the form level.",
          "blocks": [
            {
              "type": "rules",
              "title": "Form behavior",
              "items": [
                {
                  "title": "Validate at a useful moment",
                  "description": "Validate on blur or submit. Avoid interrupting the user before a value can be complete."
                },
                {
                  "title": "Keep errors persistent",
                  "description": "Field errors remain visible until the condition is resolved and are associated through description semantics."
                },
                {
                  "title": "Preserve input on failure",
                  "description": "A failed submission must not erase work. Focus the first actionable error when useful."
                },
                {
                  "title": "Make submission singular",
                  "description": "Disable or guard repeated submissions and communicate pending state in the action label."
                }
              ]
            },
            {
              "type": "table",
              "title": "Destructive action ladder",
              "columns": [
                "Risk",
                "Pattern",
                "Confirmation"
              ],
              "rows": [
                [
                  "Low and reversible",
                  "Immediate action plus undo",
                  "No blocking dialog"
                ],
                [
                  "Material but recoverable",
                  "ConfirmDialog with consequence",
                  "Explicit action label"
                ],
                [
                  "Permanent or high impact",
                  "ConfirmDialog plus typed or secondary verification",
                  "Name the object and outcome"
                ]
              ]
            }
          ]
        },
        {
          "id": "navigation-discovery",
          "title": "Navigation, search, and data discovery",
          "summary": "Location, scope, query, filters, and result count remain observable and shareable.",
          "blocks": [
            {
              "type": "checklist",
              "title": "Discovery contract",
              "groups": [
                {
                  "title": "Navigation",
                  "items": [
                    "One page has one primary landmark and heading.",
                    "Current location is visually and programmatically identifiable.",
                    "Back behavior returns to a meaningful prior context.",
                    "Deep links restore the same useful state."
                  ]
                },
                {
                  "title": "Search and filters",
                  "items": [
                    "Search results appear next to the query, not only as a count.",
                    "Filters expose active values and a clear-all action.",
                    "No-results states explain how to recover.",
                    "Query and filters use URL state when sharing matters."
                  ]
                },
                {
                  "title": "Pagination and tables",
                  "items": [
                    "Announce result range and total.",
                    "Preserve sort and selection across pagination deliberately.",
                    "Keep row actions keyboard reachable.",
                    "Offer a narrow-screen alternative to horizontal data loss."
                  ]
                }
              ]
            }
          ]
        },
        {
          "id": "page-archetypes",
          "title": "Page archetypes",
          "summary": "Stable page skeletons reduce navigation and density decisions while leaving room for product content.",
          "blocks": [
            {
              "type": "table",
              "title": "Archetype inventory",
              "columns": [
                "Archetype",
                "Required regions",
                "Responsive priority"
              ],
              "rows": [
                [
                  "Directory",
                  "Title, search/filter, result summary, list, empty/error states",
                  "Keep search and first results above the fold."
                ],
                [
                  "Detail",
                  "Breadcrumb/back, identity, status, primary actions, grouped details",
                  "Keep identity before actions and secondary metadata."
                ],
                [
                  "Editor",
                  "Title/status, workspace, controls, validation, save state",
                  "Preserve the work area and collapse secondary controls."
                ],
                [
                  "Settings",
                  "Local navigation, grouped fields, save feedback",
                  "Stack navigation before fields without losing location."
                ],
                [
                  "Dashboard",
                  "Time/scope controls, summary, trends, exceptions",
                  "Prioritize exceptions and readable comparisons."
                ],
                [
                  "Onboarding",
                  "Progress, one decision, help, safe exit",
                  "One column and one primary action."
                ]
              ]
            }
          ]
        }
      ],
      "sourcePath": "playground/src/components/design-system/principal-spec/registry.ts"
    },
    {
      "slug": "content",
      "index": "04",
      "title": "Content design",
      "shortTitle": "Content",
      "summary": "Voice, interface language, formatting, localization, and accessible naming rules for product content.",
      "status": "operational",
      "owner": "Product Design and Content",
      "lastReviewed": "August 2026",
      "reviewCycle": "Twice yearly and with locale expansion",
      "sourceOfTruth": "DESIGN-SYSTEM.md content guidelines",
      "outcomes": [
        "People understand the next action without interpreting system jargon.",
        "Errors explain the problem, consequence, and recovery.",
        "Layouts survive translation, bidirectional text, and user-generated content."
      ],
      "sections": [
        {
          "id": "voice",
          "title": "Voice and tone",
          "summary": "The voice is direct, calm, specific, and human. Tone adjusts to consequence without changing personality.",
          "blocks": [
            {
              "type": "table",
              "title": "Voice dimensions",
              "columns": [
                "Prefer",
                "Avoid",
                "Example"
              ],
              "rows": [
                [
                  "Specific",
                  "Vague",
                  "“Export failed because the file is read-only.”"
                ],
                [
                  "Direct",
                  "Ceremonial",
                  "“Save changes” instead of “Proceed with saving.”"
                ],
                [
                  "Calm",
                  "Alarmist",
                  "“Connection lost. Your draft is saved locally.”"
                ],
                [
                  "Human",
                  "Cute or robotic",
                  "“We could not verify that address.”"
                ]
              ]
            },
            {
              "type": "rules",
              "title": "Tone by moment",
              "items": [
                {
                  "title": "Routine",
                  "description": "Be compact. Labels and actions should feel almost invisible."
                },
                {
                  "title": "Learning",
                  "description": "Explain the concept and next step without front-loading every exception."
                },
                {
                  "title": "Blocked",
                  "description": "State what happened, whether work is safe, and the most useful recovery."
                },
                {
                  "title": "High risk",
                  "description": "Slow the interaction down. Name the affected object, consequence, and permanence."
                }
              ]
            }
          ]
        },
        {
          "id": "interface-copy",
          "title": "Interface copy",
          "summary": "Labels describe objects. Actions begin with verbs. Supporting text earns its space.",
          "blocks": [
            {
              "type": "table",
              "title": "Copy patterns",
              "columns": [
                "Element",
                "Pattern",
                "Example"
              ],
              "rows": [
                [
                  "Button",
                  "Verb + object when context is not obvious",
                  "Create project"
                ],
                [
                  "Field label",
                  "Stable noun phrase",
                  "Billing address"
                ],
                [
                  "Helper text",
                  "Format, consequence, or reason",
                  "Used only for account recovery."
                ],
                [
                  "Validation",
                  "Problem + correction",
                  "Enter an email address in name@example.com format."
                ],
                [
                  "Dialog title",
                  "Decision or consequence",
                  "Delete “Quarterly plan”?"
                ],
                [
                  "Empty state",
                  "Situation + value + next action",
                  "No saved views yet. Save this filter to reuse it."
                ],
                [
                  "Success",
                  "Completed result",
                  "Project created"
                ]
              ]
            },
            {
              "type": "checklist",
              "title": "Copy acceptance",
              "groups": [
                {
                  "title": "Every string",
                  "items": [
                    "Uses sentence case.",
                    "Avoids unnecessary punctuation.",
                    "Does not repeat adjacent headings or labels.",
                    "Makes sense when read by a screen reader out of visual context."
                  ]
                },
                {
                  "title": "Errors",
                  "items": [
                    "Names the failed object or action.",
                    "Avoids blame.",
                    "Preserves useful technical detail behind disclosure.",
                    "Offers a recovery when one exists."
                  ]
                }
              ]
            }
          ]
        },
        {
          "id": "formatting",
          "title": "Numbers, dates, names, and truncation",
          "summary": "Locale-aware formatting is part of the content contract, not post-production cleanup.",
          "blocks": [
            {
              "type": "table",
              "title": "Formatting rules",
              "columns": [
                "Content",
                "Display rule",
                "Implementation"
              ],
              "rows": [
                [
                  "Dates",
                  "Use unambiguous localized forms. Include year when context can cross years.",
                  "Intl.DateTimeFormat"
                ],
                [
                  "Times",
                  "Use the user locale and show the time zone when participants differ.",
                  "Intl.DateTimeFormat with timeZoneName"
                ],
                [
                  "Numbers",
                  "Respect grouping and decimal conventions. Keep raw precision only where meaningful.",
                  "Intl.NumberFormat"
                ],
                [
                  "Currency",
                  "Always bind amount to ISO currency. Never infer from symbol alone.",
                  "Intl.NumberFormat with currency"
                ],
                [
                  "Names",
                  "Store and display as entered. Do not require first/last assumptions.",
                  "One full-name field unless domain needs parts"
                ],
                [
                  "File size",
                  "Use consistent decimal or binary units within a product.",
                  "Shared formatter"
                ],
                [
                  "Truncation",
                  "Preserve distinguishing start and end where useful. Reveal the full value.",
                  "CSS ellipsis plus accessible full text"
                ]
              ]
            }
          ]
        },
        {
          "id": "localization",
          "title": "Localization and bidirectionality",
          "summary": "Components expand, mirror, and reflow without asking translators to fit English-shaped boxes.",
          "blocks": [
            {
              "type": "checklist",
              "title": "Localization stress cases",
              "groups": [
                {
                  "title": "Translation",
                  "items": [
                    "Test 30 to 50 percent text expansion.",
                    "Do not concatenate sentence fragments.",
                    "Keep variables contextually named for translators.",
                    "Use plural rules rather than count-based string branches."
                  ]
                },
                {
                  "title": "RTL",
                  "items": [
                    "Use logical start and end properties.",
                    "Mirror directional icons, not universal symbols.",
                    "Keep numbers, code, and media direction intentional.",
                    "Verify focus and reading order independently of visual mirroring."
                  ]
                },
                {
                  "title": "User content",
                  "items": [
                    "Support mixed scripts and bidirectional isolation.",
                    "Define wrapping for long unbroken strings.",
                    "Do not communicate status through capitalization.",
                    "Keep accessible names in the user language."
                  ]
                }
              ]
            }
          ]
        }
      ],
      "sourcePath": "playground/src/components/design-system/principal-spec/registry.ts"
    },
    {
      "slug": "accessibility",
      "index": "05",
      "title": "Accessibility standards",
      "shortTitle": "Accessibility",
      "summary": "The release contract for inclusive semantics, input, perception, reflow, motion, and assistive technology behavior.",
      "status": "canonical",
      "owner": "Design Systems and Engineering",
      "lastReviewed": "August 2026",
      "reviewCycle": "Every release and quarterly manual audit",
      "sourceOfTruth": "WCAG 2.2 AA target and component accessibility specs",
      "outcomes": [
        "Core workflows operate with keyboard and screen reader alone.",
        "Content remains usable at 200 percent zoom and 320 CSS pixels.",
        "Component releases include automated and manual accessibility evidence."
      ],
      "sections": [
        {
          "id": "standard",
          "title": "Conformance target",
          "summary": "WCAG 2.2 Level AA is the minimum. Native semantics and platform conventions are the starting point.",
          "blocks": [
            {
              "type": "table",
              "title": "Acceptance matrix",
              "columns": [
                "Area",
                "Minimum",
                "Evidence"
              ],
              "rows": [
                [
                  "Contrast",
                  "4.5:1 text, 3:1 large text and meaningful UI graphics",
                  "Theme-paired contrast audit"
                ],
                [
                  "Keyboard",
                  "All actions reachable, operable, and escapable",
                  "Interaction tests plus manual pass"
                ],
                [
                  "Focus",
                  "Visible, ordered, not obscured, restored after overlays",
                  "Both themes at desktop and mobile viewport"
                ],
                [
                  "Touch",
                  "44 by 44 CSS pixel target where practical",
                  "Rendered target inspection"
                ],
                [
                  "Zoom and reflow",
                  "200 percent zoom and 320 CSS pixel width without lost content",
                  "Manual browser matrix"
                ],
                [
                  "Motion",
                  "Reduced-motion alternative and no unsafe flashing",
                  "Media query and behavior review"
                ],
                [
                  "Names and roles",
                  "Programmatic name, role, value, state",
                  "Accessibility tree and screen reader"
                ]
              ]
            }
          ]
        },
        {
          "id": "interaction",
          "title": "Keyboard, focus, and announcements",
          "summary": "Keyboard behavior follows the native element or established ARIA pattern, never a visual imitation.",
          "blocks": [
            {
              "type": "rules",
              "title": "Interaction requirements",
              "items": [
                {
                  "title": "Use native controls first",
                  "description": "Buttons, links, inputs, selects, and dialogs provide behavior that custom roles must otherwise reproduce."
                },
                {
                  "title": "Do not trap focus outside a modal",
                  "description": "Only active modal dialogs contain focus. Escape closes when cancellation is supported."
                },
                {
                  "title": "Return focus intentionally",
                  "description": "Closing transient UI restores focus to the trigger or the next logical workflow target."
                },
                {
                  "title": "Announce outcomes, not activity noise",
                  "description": "Use live regions for asynchronous results that are not otherwise focused. Avoid repeated progress chatter."
                }
              ]
            },
            {
              "type": "table",
              "title": "Common keyboard contracts",
              "columns": [
                "Pattern",
                "Keys"
              ],
              "rows": [
                [
                  "Button and toggle",
                  "Enter and Space activate"
                ],
                [
                  "Tabs",
                  "Arrow keys move; Home and End jump; focus and selection policy is documented"
                ],
                [
                  "Menu",
                  "Arrow keys move; Enter selects; Escape closes and restores focus"
                ],
                [
                  "Dialog",
                  "Tab cycles inside; Escape cancels when allowed"
                ],
                [
                  "Slider",
                  "Arrow keys step; Page keys make larger changes; Home and End set bounds"
                ],
                [
                  "Radio group",
                  "Arrow keys move and select within the group"
                ]
              ]
            }
          ]
        },
        {
          "id": "perception-reflow",
          "title": "Perception, reflow, and user preferences",
          "summary": "Information survives theme, forced colors, text spacing, zoom, and reduced motion.",
          "blocks": [
            {
              "type": "checklist",
              "title": "Resilience checks",
              "groups": [
                {
                  "title": "Visual",
                  "items": [
                    "Light and dark themes retain hierarchy.",
                    "Forced-colors mode preserves controls and focus.",
                    "Status includes text or shape in addition to color.",
                    "Browser text-spacing overrides do not clip content."
                  ]
                },
                {
                  "title": "Responsive",
                  "items": [
                    "No two-dimensional scrolling for ordinary content at 320 CSS pixels.",
                    "Sticky regions do not obscure focus.",
                    "Landscape mobile retains primary actions.",
                    "Tables provide a deliberate narrow-screen strategy."
                  ]
                },
                {
                  "title": "Preferences",
                  "items": [
                    "Reduced motion removes nonessential movement.",
                    "Autoplay is absent or user-controlled.",
                    "Animation does not block interaction.",
                    "Theme choice persists without flash."
                  ]
                }
              ]
            }
          ]
        },
        {
          "id": "testing",
          "title": "Accessibility test responsibilities",
          "summary": "Automation catches regressions. Manual evaluation confirms that the workflow is actually understandable.",
          "blocks": [
            {
              "type": "process",
              "title": "Release evidence",
              "steps": [
                {
                  "title": "Author",
                  "owner": "Component author",
                  "output": "Semantic markup, keyboard tests, labels, state announcements",
                  "gate": "No known serious automated violations."
                },
                {
                  "title": "Review",
                  "owner": "Design Systems",
                  "output": "Focus, contrast, zoom, reflow, reduced-motion evidence",
                  "gate": "Both themes and exceptional states pass."
                },
                {
                  "title": "Assistive technology",
                  "owner": "QA or trained reviewer",
                  "output": "VoiceOver/Safari plus NVDA/Firefox or equivalent workflow notes",
                  "gate": "Name, role, state, reading order, and recovery are usable."
                },
                {
                  "title": "Monitor",
                  "owner": "Product team",
                  "output": "Reported issue triage and regression coverage",
                  "gate": "Critical issues block release; fixes add lasting tests."
                }
              ]
            }
          ]
        }
      ],
      "sourcePath": "playground/src/components/design-system/principal-spec/registry.ts"
    },
    {
      "slug": "governance",
      "index": "06",
      "title": "Governance and contribution",
      "shortTitle": "Governance",
      "summary": "Ownership, maturity, contribution, release, adoption, exception, and deprecation rules for keeping the system trustworthy.",
      "status": "canonical",
      "owner": "Design Systems",
      "lastReviewed": "August 2026",
      "reviewCycle": "Monthly operating review",
      "sourceOfTruth": "Repository, package releases, and this portal",
      "outcomes": [
        "Teams know what is safe to adopt and who decides changes.",
        "Design and code publish as one reviewed release.",
        "Every consumer release moves through a visible, recoverable adoption lifecycle.",
        "Exceptions and deprecations include an owner and an exit path."
      ],
      "sections": [
        {
          "id": "maturity",
          "title": "Maturity and ownership",
          "summary": "Every shared asset has a status, accountable owner, review date, and canonical implementation.",
          "blocks": [
            {
              "type": "table",
              "title": "Maturity model",
              "columns": [
                "Status",
                "Use",
                "Promise"
              ],
              "rows": [
                [
                  "Draft",
                  "Evaluation only",
                  "Shape and API may change without migration."
                ],
                [
                  "Beta",
                  "Opt-in product use",
                  "Known gaps are documented; breaking changes include direct outreach."
                ],
                [
                  "Stable",
                  "Default for production",
                  "Semantic versioning, migration guidance, and regression coverage."
                ],
                [
                  "Deprecated",
                  "Existing use while migrating",
                  "Replacement, deadline, and removal version are published."
                ],
                [
                  "Retired",
                  "Do not use",
                  "Removed from active libraries and retained only in history."
                ]
              ]
            },
            {
              "type": "table",
              "title": "Decision rights",
              "columns": [
                "Role",
                "Accountability"
              ],
              "rows": [
                [
                  "Design Systems",
                  "System coherence, asset model, tokens, docs, final acceptance"
                ],
                [
                  "Frontend Platform",
                  "Public API, semantics, performance, package quality"
                ],
                [
                  "Product designer",
                  "Use case evidence, workflow fit, content and responsive validation"
                ],
                [
                  "Product engineer",
                  "Integration evidence, edge cases, adoption and migration feedback"
                ],
                [
                  "Accessibility reviewer",
                  "Manual behavior and conformance risk"
                ]
              ]
            }
          ]
        },
        {
          "id": "contribution",
          "title": "Contribution workflow",
          "summary": "New system surface area begins with repeated product need, not a polished component proposal.",
          "blocks": [
            {
              "type": "process",
              "title": "From need to release",
              "steps": [
                {
                  "title": "Frame",
                  "owner": "Contributor",
                  "output": "Problem, affected workflows, evidence from at least two contexts",
                  "gate": "A shared need exists and composition cannot solve it cleanly."
                },
                {
                  "title": "Explore",
                  "owner": "Design and engineering",
                  "output": "API, anatomy, states, tokens, accessibility, content and responsive model",
                  "gate": "The smallest coherent contract is selected."
                },
                {
                  "title": "Build",
                  "owner": "Contributor",
                  "output": "Code, design asset, docs, tests, examples and migration notes",
                  "gate": "Parity and quality checklist passes."
                },
                {
                  "title": "Review",
                  "owner": "System owners",
                  "output": "Design, API, accessibility and visual approval",
                  "gate": "No unresolved release blocker remains."
                },
                {
                  "title": "Adopt",
                  "owner": "Product team",
                  "output": "Pilot evidence and follow-up issues",
                  "gate": "Beta graduates after real workflow validation."
                }
              ]
            },
            {
              "type": "checklist",
              "title": "Proposal evidence",
              "groups": [
                {
                  "title": "Problem",
                  "items": [
                    "Two or more concrete product contexts.",
                    "Why existing primitives and patterns are insufficient.",
                    "User and accessibility consequences.",
                    "Expected adoption and maintenance owner."
                  ]
                },
                {
                  "title": "Solution",
                  "items": [
                    "Public API and design properties.",
                    "Complete state, content, responsive, locale, and theme model.",
                    "Token impact and visual rationale.",
                    "Testing, rollout, and migration plan."
                  ]
                }
              ]
            }
          ]
        },
        {
          "id": "change-management",
          "title": "Release and change management",
          "summary": "Documentation, package behavior, design assets, and migration guidance move together.",
          "blocks": [
            {
              "type": "table",
              "title": "Change classes",
              "columns": [
                "Class",
                "Examples",
                "Requirement"
              ],
              "rows": [
                [
                  "Patch",
                  "Bug fix, docs clarification, accessibility correction without API impact",
                  "Regression test and changelog entry"
                ],
                [
                  "Minor",
                  "New component, prop, token, recipe, or compatible visual capability",
                  "Docs, examples, design asset, adoption note"
                ],
                [
                  "Major",
                  "Removed or renamed API, changed default, token meaning change",
                  "Deprecation window, codemod or migration, owner outreach"
                ],
                [
                  "Emergency",
                  "Security or critical accessibility fix",
                  "Expedited review plus follow-up documentation and audit"
                ]
              ]
            },
            {
              "type": "rules",
              "title": "Deprecation contract",
              "items": [
                {
                  "title": "Name the replacement",
                  "description": "A deprecation without a supported next step is not actionable."
                },
                {
                  "title": "Provide a deadline",
                  "description": "Publish the earliest removal version and a review date."
                },
                {
                  "title": "Measure remaining use",
                  "description": "Track package references or product inventory before removal."
                },
                {
                  "title": "Keep the old path stable",
                  "description": "Do not silently change deprecated behavior during the migration window."
                }
              ]
            }
          ]
        },
        {
          "id": "consumer-adoption",
          "title": "Consumer adoption lifecycle",
          "summary": "Consumers opt into update discovery, validate releases in their own environment, approve them manually, and deploy on their own schedule.",
          "blocks": [
            {
              "type": "process",
              "title": "Release to production",
              "steps": [
                {
                  "title": "Publish",
                  "owner": "Design Systems",
                  "output": "Immutable vX.Y.Z tag, GitHub Release, and reviewed notes",
                  "gate": "Release workflow passes without moving an existing tag."
                },
                {
                  "title": "Propose",
                  "owner": "Consumer updater",
                  "output": "An optional package.json and package-lock.json pull request",
                  "gate": "Both files resolve the same immutable release tag."
                },
                {
                  "title": "Validate",
                  "owner": "Consumer CI",
                  "output": "Consumer-owned typecheck, lint, tests, policy checks, accessibility checks, and production build",
                  "gate": "Applicable compatibility checks pass; a provider preview does not substitute for them."
                },
                {
                  "title": "Approve",
                  "owner": "Product owner",
                  "output": "Release-note and product-impact review",
                  "gate": "A human merges; automerge stays disabled."
                },
                {
                  "title": "Deploy and verify",
                  "owner": "Consumer owner",
                  "output": "Normal deployment plus an affected-workflow smoke test",
                  "gate": "The deployed consumer behaves as reviewed."
                },
                {
                  "title": "Monitor",
                  "owner": "Consumer owner",
                  "output": "Optional scheduled freshness signal",
                  "gate": "Monitoring reports staleness without changing the application."
                }
              ]
            },
            {
              "type": "table",
              "title": "Choose an adoption path",
              "columns": [
                "Path",
                "Consumer choice",
                "Expected result"
              ],
              "rows": [
                [
                  "Renovate",
                  "Add the focused @ai-created/ui package rule to the consumer repository.",
                  "Eligible immutable tags produce reviewable pull requests."
                ],
                [
                  "Scheduled Renovate",
                  "Add a consumer-chosen schedule to that package rule.",
                  "Pull requests open during the preferred maintenance window."
                ],
                [
                  "Manual",
                  "Update the tagged dependency and regenerate the lockfile together.",
                  "The same review and compatibility contract applies without a bot."
                ],
                [
                  "No update",
                  "Keep the currently installed immutable tag.",
                  "The existing application remains unchanged."
                ]
              ]
            },
            {
              "type": "rules",
              "title": "Operational boundaries",
              "items": [
                {
                  "title": "No registration required",
                  "description": "The design-system repository does not need to know which applications consume it. Teams may maintain their own inventory when useful."
                },
                {
                  "title": "Compatibility is consumer-owned",
                  "description": "Each application defines the commands and environments that prove the release works with its stack."
                },
                {
                  "title": "Provider checks are separate",
                  "description": "Deployment previews help review the product but do not replace consumer-owned compatibility checks."
                },
                {
                  "title": "Completion includes production",
                  "description": "A green pull request is not the endpoint. Merge manually, confirm deployment, and verify the affected product workflow."
                },
                {
                  "title": "Monitoring reports rather than mutates",
                  "description": "The optional currency check exposes a stale tag. It does not open, merge, deploy, or verify an update."
                },
                {
                  "title": "Recover by fixing forward",
                  "description": "When compatibility or production verification fails, repair the consumer or publish a new patch. Never move a published tag or weaken a required check."
                }
              ]
            }
          ]
        },
        {
          "id": "health",
          "title": "System health and exceptions",
          "summary": "A mature library measures use, quality, and drift rather than equating inventory size with success.",
          "blocks": [
            {
              "type": "table",
              "title": "Health signals",
              "columns": [
                "Signal",
                "Question"
              ],
              "rows": [
                [
                  "Adoption",
                  "What share of eligible product surfaces uses the supported primitive or pattern?"
                ],
                [
                  "Coverage",
                  "Which recurring product needs still require local implementations?"
                ],
                [
                  "Quality",
                  "What accessibility, visual, reliability, and performance regressions recur?"
                ],
                [
                  "Parity",
                  "Which design or code assets expose unmatched decisions?"
                ],
                [
                  "Velocity",
                  "How long do proposals, reviews, migrations, and critical fixes take?"
                ],
                [
                  "Trust",
                  "Can product teams predict behavior, ownership, and upgrade cost?"
                ]
              ]
            },
            {
              "type": "rules",
              "title": "Exception policy",
              "items": [
                {
                  "title": "Record the need",
                  "description": "State the unmet requirement, affected surface, and why composition fails."
                },
                {
                  "title": "Limit the blast radius",
                  "description": "Keep the exception product-local and avoid naming it like a shared primitive."
                },
                {
                  "title": "Assign an owner and review date",
                  "description": "Every exception expires, graduates, or is explicitly renewed."
                },
                {
                  "title": "Feed the system",
                  "description": "Repeated exceptions become contribution evidence, not permanent forks."
                }
              ]
            }
          ]
        }
      ],
      "sourcePath": "playground/src/components/design-system/principal-spec/registry.ts"
    },
    {
      "slug": "assets",
      "index": "07",
      "title": "Assets and distribution",
      "shortTitle": "Assets",
      "summary": "Reusable tokens, package exports, presets, icon policy, media requirements, and the source-of-truth map for every consumer.",
      "status": "evolving",
      "owner": "Design Systems and Frontend Platform",
      "lastReviewed": "August 2026",
      "reviewCycle": "Every package and token release",
      "sourceOfTruth": "Repository package exports and generated token artifact",
      "outcomes": [
        "Consumers can install or download the system without copying values by hand.",
        "Every asset type names its canonical source and update path.",
        "Generated exports fail validation when they drift from source CSS."
      ],
      "sections": [
        {
          "id": "downloads",
          "title": "Reusable downloads",
          "summary": "The downloadable token artifact is generated from canonical CSS. Code consumers use package exports directly.",
          "blocks": [
            {
              "type": "resources",
              "title": "Asset directory",
              "items": [
                {
                  "title": "Design tokens JSON",
                  "description": "Generated DTCG-shaped token data with reference, semantic, layout, radius, motion, and light/dark mode values.",
                  "href": "/design-system/tokens.json",
                  "action": "Download JSON"
                },
                {
                  "title": "Design-system manifest",
                  "description": "Versioned machine-readable contract for every public export, component, guideline, source, token dependency, and blocking validation command.",
                  "href": "/design-system/manifest.json",
                  "action": "Download JSON"
                },
                {
                  "title": "AI agent quick context",
                  "description": "Concise operating rules and links for tools that discover llms.txt.",
                  "href": "/llms.txt",
                  "action": "Open text"
                },
                {
                  "title": "AI agent full context",
                  "description": "Complete readable component, accessibility, implementation, guideline, template, and validation reference.",
                  "href": "/llms-full.txt",
                  "action": "Open text"
                },
                {
                  "title": "Token CSS",
                  "description": "Canonical CSS custom properties for product runtimes.",
                  "href": "https://github.com/TheMarco/ai-created-ui/blob/main/styles/tokens.css",
                  "action": "View source",
                  "external": true
                },
                {
                  "title": "Tailwind preset",
                  "description": "Theme mappings, typography families, radii, semantic colors, and motion utilities.",
                  "href": "https://github.com/TheMarco/ai-created-ui/blob/main/tailwind-preset.js",
                  "action": "View source",
                  "external": true
                },
                {
                  "title": "Approved page templates",
                  "description": "Six complete production archetypes with loading, empty, error, permission, and completion states.",
                  "href": "https://github.com/TheMarco/ai-created-ui/tree/main/templates/agent",
                  "action": "View source",
                  "external": true
                },
                {
                  "title": "Agent integration guide",
                  "description": "Query commands, consumer setup, exception policy, CI gates, and MCP adapter guidance.",
                  "href": "https://github.com/TheMarco/ai-created-ui/blob/main/docs/agent-integration.md",
                  "action": "Read guide",
                  "external": true
                },
                {
                  "title": "Component package",
                  "description": "Public React components, utilities, providers, and motion helpers.",
                  "href": "https://github.com/TheMarco/ai-created-ui",
                  "action": "Open repository",
                  "external": true
                }
              ]
            },
            {
              "type": "code",
              "title": "Consumer setup",
              "description": "Import tokens once, extend the preset, then import public components from the package root.",
              "language": "tsx",
              "code": "// app/globals.css\n@import '@ai-created/ui/styles/tokens.css';\n\n// tailwind.config.js\nmodule.exports = {\n  presets: [require('@ai-created/ui/tailwind-preset')],\n  content: ['./src/**/*.{ts,tsx}'],\n};\n\n// product UI\nimport { Button, Surface } from '@ai-created/ui';"
            }
          ]
        },
        {
          "id": "agent-contract",
          "title": "AI agent contract",
          "summary": "Agents use the same versioned inputs and blocking gates as human contributors, without inferring undocumented design decisions.",
          "blocks": [
            {
              "type": "rules",
              "title": "Agent operating model",
              "items": [
                {
                  "title": "Query canonical context",
                  "description": "Read the manifest or query CLI before implementation. Never reconstruct props, variants, or tokens from model memory."
                },
                {
                  "title": "Start from an approved archetype",
                  "description": "Use the directory, detail, form, settings, dashboard, or onboarding template when its product shape matches."
                },
                {
                  "title": "Reject silent drift",
                  "description": "Raw colors, reference tokens, internal imports, arbitrary system values, and local primitive copies fail the policy gate."
                },
                {
                  "title": "Make exceptions accountable",
                  "description": "A necessary departure names one rule, narrow files, a concrete reason, an owner, and a future review date."
                }
              ]
            },
            {
              "type": "code",
              "title": "Agent query and validation",
              "description": "Commands return JSON and validate the same contract that ships with the selected package version.",
              "language": "bash",
              "code": "npm run agent:query -- component button\nnpm run agent:query -- guideline accessibility\nnpm run agent:query -- template dashboard\nnpm run agent:check"
            },
            {
              "type": "resources",
              "title": "Agent entry points",
              "description": "Start at the overview when introducing the model to a team. Stay in this chapter for the canonical rules.",
              "items": [
                {
                  "title": "Agents overview",
                  "description": "Product-level explanation of how agents query the contract, what validation rejects, and how exceptions reach human review.",
                  "href": "/agents",
                  "action": "Open page"
                },
                {
                  "title": "AI agent integration guide",
                  "description": "Consumer setup, required gates, repository enforcement, and adapter guidance.",
                  "href": "https://github.com/TheMarco/ai-created-ui/blob/main/docs/agent-integration.md",
                  "action": "Read guide",
                  "external": true
                }
              ]
            }
          ]
        },
        {
          "id": "source-map",
          "title": "Source-of-truth map",
          "summary": "Each asset has one canonical authoring location and an explicit distribution path.",
          "blocks": [
            {
              "type": "table",
              "title": "Asset ownership",
              "columns": [
                "Asset",
                "Canonical source",
                "Distribution",
                "Change gate"
              ],
              "rows": [
                [
                  "Reference and semantic tokens",
                  "styles/tokens.css",
                  "CSS package export and generated JSON",
                  "Theme and contrast review"
                ],
                [
                  "Tailwind mappings",
                  "tailwind-preset.js",
                  "Preset package export",
                  "Matches canonical CSS names"
                ],
                [
                  "React components",
                  "src/components",
                  "Package root exports",
                  "API, a11y, unit, interaction and visual review"
                ],
                [
                  "Component specifications",
                  "playground/specs",
                  "This portal",
                  "Registry completeness and parity tests"
                ],
                [
                  "Icons",
                  "Lucide dependency",
                  "lucide-react",
                  "Use standard glyph before custom asset"
                ],
                [
                  "Product imagery",
                  "Owning product repository",
                  "Product deployment",
                  "Theme, crop, rights and accessibility review"
                ],
                [
                  "Visual baselines",
                  "e2e/__screenshots__",
                  "Repository test artifact",
                  "Intentional reviewed update"
                ],
                [
                  "Agent manifest and context",
                  "Runtime, tokens, registries, templates, and AGENTS.md",
                  "Package files and portal downloads",
                  "Generated parity and freshness checks"
                ]
              ]
            }
          ]
        },
        {
          "id": "library-model",
          "title": "Design library model",
          "summary": "A future design-tool library should mirror this portal without becoming a competing source of truth.",
          "blocks": [
            {
              "type": "table",
              "title": "Recommended library pages",
              "columns": [
                "Page",
                "Contents"
              ],
              "rows": [
                [
                  "00 Cover and release",
                  "Version, status, owner, release notes, migration alerts"
                ],
                [
                  "01 Foundations",
                  "Variables, text styles, layout, radius, motion, icon and media rules"
                ],
                [
                  "02 Components",
                  "Published component sets matching public exports"
                ],
                [
                  "03 Patterns",
                  "Approved compositions and complete state flows"
                ],
                [
                  "04 Accessibility",
                  "Annotations, focus order, keyboard and announcement notes"
                ],
                [
                  "05 QA",
                  "Theme, locale, resize, density and exceptional-state comparison frames"
                ],
                [
                  "99 Deprecated",
                  "Migration-only assets with removal version"
                ]
              ]
            },
            {
              "type": "rules",
              "title": "Publishing policy",
              "items": [
                {
                  "title": "Version the release",
                  "description": "Publish design assets with the corresponding package version and changelog."
                },
                {
                  "title": "Expose semantic variables",
                  "description": "Consumers select intent. Reference values remain hidden from product authoring."
                },
                {
                  "title": "Keep code-only exports honest",
                  "description": "Providers and utilities receive documentation, not artificial canvas components."
                },
                {
                  "title": "Audit detached instances",
                  "description": "Detachment signals either missing capability or unsupported product drift."
                }
              ]
            }
          ]
        },
        {
          "id": "asset-quality",
          "title": "Asset quality gates",
          "summary": "Reusable assets are complete only when their licensing, modes, states, naming, and fallback behavior are documented.",
          "blocks": [
            {
              "type": "checklist",
              "title": "Release checklist by asset type",
              "groups": [
                {
                  "title": "Tokens",
                  "items": [
                    "Generated artifact matches CSS.",
                    "Aliases resolve without cycles.",
                    "Light and dark modes are complete.",
                    "Names and types remain stable or include migration."
                  ]
                },
                {
                  "title": "Icons",
                  "items": [
                    "Optical size matches 16, 20, or 32px role.",
                    "Accessible name comes from the control or nearby text.",
                    "Directionality is documented.",
                    "Custom icons include source and license."
                  ]
                },
                {
                  "title": "Media",
                  "items": [
                    "Usage rights and source are recorded.",
                    "Light/dark variants and crops are paired.",
                    "Fallback and alt behavior is defined.",
                    "Files meet product performance budgets."
                  ]
                }
              ]
            }
          ]
        }
      ],
      "sourcePath": "playground/src/components/design-system/principal-spec/registry.ts"
    }
  ],
  "validation": {
    "policy": "Every command is blocking. A change is publishable only when all commands pass.",
    "commands": [
      {
        "id": "typecheck",
        "command": "npm run typecheck",
        "purpose": "Validate package and portal TypeScript.",
        "blocking": true
      },
      {
        "id": "lint",
        "command": "npm run lint",
        "purpose": "Validate source, scripts, tests, and portal conventions.",
        "blocking": true
      },
      {
        "id": "test",
        "command": "npm run test",
        "purpose": "Run component and contract tests.",
        "blocking": true
      },
      {
        "id": "tokens",
        "command": "npm run tokens:check",
        "purpose": "Reject stale generated design tokens.",
        "blocking": true
      },
      {
        "id": "manifest",
        "command": "node scripts/export-design-system-manifest.mjs --check",
        "purpose": "Reject a stale or incomplete agent manifest.",
        "blocking": true
      },
      {
        "id": "tailwind",
        "command": "npm run tailwind:check",
        "purpose": "Reject framework mappings that drift from canonical tokens.",
        "blocking": true
      },
      {
        "id": "api",
        "command": "npm run api:check",
        "purpose": "Reject documented props, controls, or imports that drift from the public TypeScript API.",
        "blocking": true
      },
      {
        "id": "policy",
        "command": "npm run policy:check",
        "purpose": "Reject prohibited styling, imports, tokens, and primitive copies.",
        "blocking": true
      },
      {
        "id": "templates",
        "command": "npm run templates:check",
        "purpose": "Compile and verify every approved page template and public export fixture.",
        "blocking": true
      },
      {
        "id": "documentation",
        "command": "npm run docs:check",
        "purpose": "Reject stale public counts, routes, workflows, or propagation guidance.",
        "blocking": true
      },
      {
        "id": "agent-context",
        "command": "npm run agent-context:check",
        "purpose": "Reject stale concise or full agent context artifacts.",
        "blocking": true
      },
      {
        "id": "agent",
        "command": "npm run agent:check",
        "purpose": "Run the complete machine-readable anti-drift contract.",
        "blocking": true
      },
      {
        "id": "portal",
        "command": "npm run build:playground",
        "purpose": "Build the specification portal.",
        "blocking": true
      },
      {
        "id": "package",
        "command": "npm run package:check",
        "purpose": "Verify the distributable package contract.",
        "blocking": true
      },
      {
        "id": "full",
        "command": "npm run validate",
        "purpose": "Run the repository validation gate.",
        "blocking": true
      }
    ]
  }
}
