{
  "_meta": {
    "purpose": "Machine-readable index of the JMS design system. Read this before UI work.",
    "generatedFrom": [
      "src/data/designSystemCatalog.js",
      "src/data/designTokens.js",
      "src/index.css"
    ],
    "regenerate": "npm run design-system:manifest (runs on build and in the pre-commit hook; the dev server serves it live)",
    "verify": "npm run design-system:check",
    "howToUse": [
      "components: what exists, what each is for, where its source file is, its use/avoid guidance, and the behaviors that bind it. Its page is routes.component with {portal} and {component} filled in.",
      "tokens.sections: every custom property in src/index.css as name: value, resolved for the admin portal. tokens.portalOverrides.user: the values the user portal changes or adds. Use var(--name) or the matching Tailwind utility, never a literal value.",
      "guidelines.principles: qualities a redesign must keep. guidelines.behaviors: interaction rules that span components; each names the components it binds, and each component lists its behaviors. Entries with standard: \"prototype\" are about the mockup being reviewable, not the product. Rendered at /ui/{portal}/guidelines.",
      "since and because on any entry record when and why a call was made. Keep them when editing the entry.",
      "To add a rule, edit the catalog: a principle, a behavior naming the components it binds, or a component guidance entry. Do not create a markdown rules file."
    ]
  },
  "project": {
    "name": "JMS Admin Prototype",
    "company": "JMS",
    "product": "Journey Management System",
    "baseDesignSystemPath": "/ui",
    "baseDesignSystemUrl": "https://jms.orchidux.com/ui"
  },
  "portals": [
    {
      "id": "admin",
      "label": "Admin",
      "description": "Agency administration portal for JMS case, journey, intake, and workflow operations."
    },
    {
      "id": "user",
      "label": "User",
      "description": "Client portal view for Intended Parent, Gestational Carrier, and Egg Donor experiences."
    }
  ],
  "routes": {
    "siteUrl": "https://jms.orchidux.com",
    "home": "/ui",
    "portal": "/ui/{portal}",
    "components": "/ui/{portal}/components",
    "component": "/ui/{portal}/components/{component}",
    "foundation": "/ui/{portal}/foundations/{topic}",
    "tokens": "/ui/{portal}/tokens",
    "guidelines": "/ui/{portal}/guidelines",
    "manifest": "/ui/manifest.json"
  },
  "components": [
    {
      "id": "alert",
      "label": "Alert",
      "description": "Alert and notification banners for info, danger, warning, and success states.",
      "portals": [
        "admin",
        "user"
      ],
      "source": "src/components/Alert.jsx",
      "behaviors": [
        "error-scope",
        "failure-copy",
        "action-sequence",
        "motion-explains",
        "not-color-alone",
        "reachable-failure"
      ]
    },
    {
      "id": "autocomplete",
      "label": "Autocomplete",
      "description": "Type-ahead search input for selecting from local option sets.",
      "portals": [
        "admin",
        "user"
      ],
      "source": "src/components/Autocomplete.jsx",
      "guidance": {
        "use": [
          "Pass label for the visible label, helperText for guidance, and hasError with the error message prop for validation."
        ],
        "avoid": [
          "placeholder as the only label."
        ]
      },
      "behaviors": [
        "forms-keep-context",
        "error-scope",
        "keyboard-focus",
        "not-color-alone"
      ]
    },
    {
      "id": "avatar",
      "label": "Avatar",
      "description": "User identity avatar with image and initials variants across supported sizes.",
      "portals": [
        "admin",
        "user"
      ],
      "source": "src/components/Avatar.jsx"
    },
    {
      "id": "badge",
      "label": "Badge",
      "description": "Compact status and metadata labels for case, workflow, and UI state.",
      "portals": [
        "admin",
        "user"
      ],
      "source": "src/components/Badge.jsx",
      "behaviors": [
        "not-color-alone"
      ]
    },
    {
      "id": "breadcrumbs",
      "label": "Breadcrumbs",
      "description": "Hierarchical navigation trail with optional home affordance.",
      "portals": [
        "admin",
        "user"
      ],
      "source": "src/components/Breadcrumbs.jsx",
      "behaviors": [
        "keyboard-focus"
      ]
    },
    {
      "id": "button",
      "label": "Button",
      "description": "Primary action component with filled, outlined, link, ghost, icon, and disabled variants.",
      "portals": [
        "admin",
        "user"
      ],
      "source": "src/components/Button.jsx",
      "guidance": {
        "use": [
          "Filled violet carries the primary action in the admin portal; filled purple carries it in the client portal."
        ],
        "avoid": [
          "Turquoise or semantic colors (success, danger, warning) as the color of an ordinary action."
        ]
      },
      "behaviors": [
        "action-sequence",
        "destructive-scope",
        "keyboard-focus",
        "reachable-failure"
      ]
    },
    {
      "id": "button-group",
      "label": "Button Group",
      "description": "Grouped action buttons for related horizontal or vertical choices.",
      "portals": [
        "admin",
        "user"
      ],
      "source": "src/components/ButtonGroup.jsx",
      "behaviors": [
        "action-sequence",
        "keyboard-focus",
        "reachable-failure"
      ]
    },
    {
      "id": "card",
      "label": "Card",
      "description": "Framed content container used for repeated items, modals, and contained tools.",
      "portals": [
        "admin",
        "user"
      ],
      "source": "src/components/Card.jsx",
      "guidance": {
        "use": [
          "Card owns its padding and internal gaps. Put content inside and let it size itself."
        ],
        "avoid": [
          "Adding p-*, py-*, or px-* classes on the Card or its direct children."
        ],
        "since": "2026-02-09",
        "because": "Padding added around Card content stacked with the component's own padding and produced bloated cards."
      },
      "behaviors": [
        "overlay-trigger-context",
        "trigger-surfaces",
        "motion-explains"
      ]
    },
    {
      "id": "checkbox",
      "label": "Checkbox",
      "description": "Binary selection control with labels, helper text, error, and disabled states.",
      "portals": [
        "admin",
        "user"
      ],
      "source": "src/components/Checkbox.jsx",
      "behaviors": [
        "selection-scope",
        "keyboard-focus"
      ]
    },
    {
      "id": "combobox",
      "label": "Combobox",
      "description": "Searchable select control for choosing one option from larger lists.",
      "portals": [
        "admin",
        "user"
      ],
      "source": "src/components/Combobox.jsx",
      "guidance": {
        "use": [
          "Pass label for the visible label, helperText for guidance, and hasError with the error message prop for validation."
        ],
        "avoid": [
          "placeholder as the only label."
        ]
      },
      "behaviors": [
        "forms-keep-context",
        "error-scope",
        "keyboard-focus",
        "not-color-alone"
      ]
    },
    {
      "id": "datepicker",
      "label": "Datepicker",
      "description": "Date selection input with calendar, helper, error, filled, and disabled states.",
      "portals": [
        "admin",
        "user"
      ],
      "source": "src/components/Datepicker.jsx",
      "guidance": {
        "use": [
          "Pass label for the visible label, helperText for guidance, and hasError with the error message prop for validation."
        ],
        "avoid": [
          "placeholder as the only label."
        ]
      },
      "behaviors": [
        "forms-keep-context",
        "error-scope",
        "keyboard-focus",
        "not-color-alone"
      ]
    },
    {
      "id": "drag-drop-upload",
      "label": "Drag Drop Upload",
      "description": "Drag-and-drop upload surface for single or multiple files with type and size constraints.",
      "portals": [
        "admin",
        "user"
      ],
      "source": "src/components/DragDropUpload.jsx"
    },
    {
      "id": "dropdown-button",
      "label": "Dropdown Button",
      "description": "Button-triggered action menu for secondary or grouped commands.",
      "portals": [
        "admin",
        "user"
      ],
      "source": "src/components/DropdownButton.jsx",
      "behaviors": [
        "action-sequence",
        "destructive-scope",
        "motion-explains",
        "keyboard-focus",
        "reachable-failure"
      ]
    },
    {
      "id": "empty-state",
      "label": "Empty State",
      "description": "Reviewable empty, no-result, and onboarding states with optional actions.",
      "portals": [
        "admin",
        "user"
      ],
      "source": "src/components/EmptyState.jsx",
      "behaviors": [
        "failure-copy"
      ]
    },
    {
      "id": "file-upload",
      "label": "File Upload",
      "description": "Single-file picker styled as a form field, with helper, error, required, disabled, and append-button states.",
      "portals": [
        "admin",
        "user"
      ],
      "source": "src/components/FileUpload.jsx",
      "guidance": {
        "use": [
          "Pass label for the visible label, helperText for guidance, and hasError with the error message prop for validation."
        ],
        "avoid": [
          "placeholder as the only label."
        ]
      },
      "behaviors": [
        "forms-keep-context",
        "error-scope",
        "keyboard-focus",
        "not-color-alone"
      ]
    },
    {
      "id": "floating-action-bar",
      "label": "Floating Action Bar",
      "description": "Contextual bulk-action surface for selected rows and Workview edit mode.",
      "portals": [
        "admin"
      ],
      "source": "src/components/FloatingActionBar.jsx",
      "guidance": {
        "use": [
          "A high-contrast dark neutral surface with violet primary actions.",
          "On mobile: summary and clear-selection controls on the first row, then a two-column action grid. Long actions span the full row; primary and destructive actions can pair side by side."
        ],
        "avoid": [
          "A light surface that blends into the table it acts on."
        ],
        "since": "2026-08-21",
        "because": "A dark surface reads as a separate command layer over dense tables."
      },
      "behaviors": [
        "action-sequence",
        "destructive-scope",
        "selection-scope",
        "selection-context",
        "keyboard-focus",
        "reachable-failure"
      ]
    },
    {
      "id": "floating-save-button",
      "label": "Floating Save Button",
      "description": "Fixed save action with admin and client color treatments, pending, and saved states.",
      "portals": [
        "admin",
        "user"
      ],
      "source": "src/components/FloatingSaveButton.jsx",
      "behaviors": [
        "action-sequence",
        "keyboard-focus",
        "reachable-failure"
      ]
    },
    {
      "id": "header-admin",
      "label": "Header Admin",
      "description": "Admin portal header with logo, navigation, resource center, notifications, and user menu.",
      "portals": [
        "admin"
      ],
      "source": "src/components/HeaderAdmin.jsx",
      "guidance": {
        "use": [
          "Admin pages compose HeaderAdmin with logo, navigation, resource center, notifications, and the user dropdown."
        ],
        "avoid": []
      }
    },
    {
      "id": "header-client",
      "label": "Header Client",
      "description": "Client portal header with language selector, avatar menu, and support actions.",
      "portals": [
        "user"
      ],
      "source": "src/components/HeaderClient.jsx",
      "guidance": {
        "use": [
          "Client pages compose ClientSidebar with HeaderClient. Controls use size=\"lg\" and filled purple primary buttons."
        ],
        "avoid": []
      }
    },
    {
      "id": "icon-button",
      "label": "Icon Button",
      "description": "Round icon-only button in filled, outlined, neutral, and ghost types for compact actions.",
      "portals": [
        "admin",
        "user"
      ],
      "source": "src/components/IconButton.jsx",
      "guidance": {
        "use": [
          "Give every icon button a name: an aria-label, or a Tooltip that names the action. The icon alone is not a label."
        ],
        "avoid": []
      },
      "behaviors": [
        "action-sequence",
        "keyboard-focus",
        "reachable-failure"
      ]
    },
    {
      "id": "input",
      "label": "Input",
      "description": "Text input with labels, helper text, icons, add-ons, filled, error, and disabled states.",
      "portals": [
        "admin",
        "user"
      ],
      "source": "src/components/Input.jsx",
      "guidance": {
        "use": [
          "Pass label for the visible label, helperText for guidance, and hasError with the error message prop for validation."
        ],
        "avoid": [
          "placeholder as the only label."
        ]
      },
      "behaviors": [
        "forms-keep-context",
        "error-scope",
        "keyboard-focus",
        "not-color-alone"
      ]
    },
    {
      "id": "modal",
      "label": "Modal",
      "description": "Dialog surface for compact tasks, confirmations, and destructive actions.",
      "portals": [
        "admin",
        "user"
      ],
      "source": "src/components/Modal.jsx",
      "behaviors": [
        "overlay-trigger-context",
        "modal-vs-drawer",
        "error-scope",
        "failure-copy",
        "destructive-scope",
        "motion-explains",
        "keyboard-focus",
        "reachable-failure"
      ]
    },
    {
      "id": "multi-select",
      "label": "Multi Select",
      "description": "Multi-value searchable selection control with helper, max-selection, and disabled states.",
      "portals": [
        "admin",
        "user"
      ],
      "source": "src/components/MultiSelect.jsx",
      "guidance": {
        "use": [
          "Pass label for the visible label, helperText for guidance, and hasError with the error message prop for validation."
        ],
        "avoid": [
          "placeholder as the only label."
        ]
      },
      "behaviors": [
        "forms-keep-context",
        "error-scope",
        "keyboard-focus",
        "not-color-alone"
      ]
    },
    {
      "id": "pagination",
      "label": "Pagination",
      "description": "Numbered table and collection pagination with disabled and ellipsis states.",
      "portals": [
        "admin",
        "user"
      ],
      "source": "src/components/Pagination.jsx",
      "behaviors": [
        "selection-scope",
        "selection-context",
        "keyboard-focus",
        "pagination-decided",
        "three-pages-of-fixtures",
        "stable-identities"
      ]
    },
    {
      "id": "phone-input",
      "label": "Phone Input",
      "description": "Phone number field with a country-code selector, sizes, states, and an optional append button.",
      "portals": [
        "admin",
        "user"
      ],
      "source": "src/components/PhoneInput.jsx",
      "guidance": {
        "use": [
          "Pass label for the visible label, helperText for guidance, and hasError with the error message prop for validation."
        ],
        "avoid": [
          "placeholder as the only label."
        ]
      },
      "behaviors": [
        "forms-keep-context",
        "error-scope",
        "keyboard-focus",
        "not-color-alone"
      ]
    },
    {
      "id": "pills",
      "label": "Pills",
      "description": "One-click switcher across sibling items viewed one at a time, with an optional attention dot.",
      "portals": [
        "admin",
        "user"
      ],
      "source": "src/components/Pills.jsx",
      "guidance": {
        "use": [
          "Switch between two or more sibling items that are viewed one at a time, each with its own field set: family members, cycles, contacts, repeatable entries.",
          "Set dot on an item that needs attention, such as one with unsaved edits."
        ],
        "avoid": [
          "A single item, or items that are not alternatives of each other; use Tabs for page sections."
        ]
      },
      "behaviors": [
        "keyboard-focus"
      ]
    },
    {
      "id": "progress-bar",
      "label": "Progress Bar",
      "description": "Linear progress indicator for completion, upload, and workflow progress.",
      "portals": [
        "admin",
        "user"
      ],
      "source": "src/components/Progress.jsx",
      "behaviors": [
        "not-color-alone"
      ]
    },
    {
      "id": "progress-circular",
      "label": "Progress Circular",
      "description": "Circular progress indicator for compact completion and status summaries.",
      "portals": [
        "admin",
        "user"
      ],
      "source": "src/components/CircularProgress.jsx",
      "behaviors": [
        "not-color-alone"
      ]
    },
    {
      "id": "radio",
      "label": "Radio",
      "description": "Single-choice option group with descriptions, helper text, error, and disabled states.",
      "portals": [
        "admin",
        "user"
      ],
      "source": "src/components/Radio.jsx",
      "behaviors": [
        "keyboard-focus"
      ]
    },
    {
      "id": "select",
      "label": "Select",
      "description": "Dropdown select with labels, icons, add-ons, filled, error, and disabled states.",
      "portals": [
        "admin",
        "user"
      ],
      "source": "src/components/Select.jsx",
      "guidance": {
        "use": [
          "Pass label for the visible label, helperText for guidance, and hasError with the error message prop for validation."
        ],
        "avoid": [
          "placeholder as the only label."
        ]
      },
      "behaviors": [
        "forms-keep-context",
        "error-scope",
        "keyboard-focus",
        "not-color-alone"
      ]
    },
    {
      "id": "sidebar-client",
      "label": "Sidebar Client",
      "description": "Client portal sidebar with Orchid navigation, case manager context, and mobile behavior.",
      "portals": [
        "user"
      ],
      "source": "src/components/ClientSidebar.jsx",
      "guidance": {
        "use": [
          "Client pages compose ClientSidebar with HeaderClient. Controls use size=\"lg\" and filled purple primary buttons."
        ],
        "avoid": []
      }
    },
    {
      "id": "switch",
      "label": "Switch",
      "description": "On/off toggle with labels, helper text, error, and disabled states.",
      "portals": [
        "admin",
        "user"
      ],
      "source": "src/components/Switch.jsx",
      "behaviors": [
        "keyboard-focus",
        "not-color-alone"
      ]
    },
    {
      "id": "table",
      "label": "Table",
      "description": "Data table with selectable rows, sorting, cells, badges, controls, and pagination patterns.",
      "portals": [
        "admin",
        "user"
      ],
      "source": "src/components/Table.jsx",
      "behaviors": [
        "overlay-trigger-context",
        "trigger-surfaces",
        "error-scope",
        "selection-scope",
        "selection-context",
        "motion-explains",
        "keyboard-focus",
        "pagination-decided",
        "three-pages-of-fixtures",
        "stable-identities"
      ]
    },
    {
      "id": "stats-card",
      "label": "Stats Card",
      "description": "Metric card for compact totals, trends, icons, and operational summaries.",
      "portals": [
        "admin",
        "user"
      ],
      "source": "src/components/StatsCard.jsx",
      "behaviors": [
        "trigger-surfaces"
      ]
    },
    {
      "id": "tabs",
      "label": "Tabs",
      "description": "Tab navigation with pill, line, icon, disabled, and multi-tab variants.",
      "portals": [
        "admin",
        "user"
      ],
      "source": "src/components/Tabs.jsx",
      "behaviors": [
        "keyboard-focus"
      ]
    },
    {
      "id": "textarea",
      "label": "Textarea",
      "description": "Multi-line text input with labels, helper text, icons, filled, error, and disabled states.",
      "portals": [
        "admin",
        "user"
      ],
      "source": "src/components/Textarea.jsx",
      "guidance": {
        "use": [
          "Pass label for the visible label, helperText for guidance, and hasError with the error message prop for validation."
        ],
        "avoid": [
          "placeholder as the only label."
        ]
      },
      "behaviors": [
        "forms-keep-context",
        "error-scope",
        "keyboard-focus",
        "not-color-alone"
      ]
    },
    {
      "id": "toast",
      "label": "Toast",
      "description": "Transient notification feedback with placement and variant examples.",
      "portals": [
        "admin",
        "user"
      ],
      "source": "src/components/Toast.jsx",
      "behaviors": [
        "error-scope",
        "failure-copy",
        "action-sequence",
        "motion-explains",
        "not-color-alone",
        "reachable-failure"
      ]
    },
    {
      "id": "tooltip",
      "label": "Tooltip",
      "description": "Hover and focus helper text for unfamiliar icons, controls, and dense UI.",
      "portals": [
        "admin",
        "user"
      ],
      "source": "src/components/Tooltip.jsx",
      "behaviors": [
        "motion-explains",
        "keyboard-focus"
      ]
    },
    {
      "id": "wysiwyg",
      "label": "Wysiwyg",
      "description": "Rich text editor surface for formatted long-form content.",
      "portals": [
        "admin",
        "user"
      ],
      "source": "src/components/Wysiwyg.jsx",
      "guidance": {
        "use": [
          "Pass label for the visible label, helperText for guidance, and hasError with the error message prop for validation."
        ],
        "avoid": [
          "placeholder as the only label."
        ]
      },
      "behaviors": [
        "forms-keep-context",
        "error-scope",
        "keyboard-focus",
        "not-color-alone"
      ]
    }
  ],
  "foundations": [
    {
      "id": "colors",
      "label": "Colors",
      "description": "Neutral, brand, and semantic color palettes for each portal."
    },
    {
      "id": "typography",
      "label": "Typography",
      "description": "Open Sans family, type sizes, line heights, weights, and letter spacing."
    },
    {
      "id": "spacing",
      "label": "Spacing",
      "description": "Spacing scale used for layout, gaps, and component composition."
    },
    {
      "id": "border-radius",
      "label": "Border Radius",
      "description": "Corner radius scale for controls, cards, overlays, and rounded surfaces."
    },
    {
      "id": "icon-sizes",
      "label": "Icon Sizes",
      "description": "Icon sizing tokens for buttons, badges, navigation, and metadata."
    },
    {
      "id": "opacity",
      "label": "Opacity",
      "description": "Opacity scale for disabled, hover, and emphasis treatments."
    },
    {
      "id": "shadows",
      "label": "Shadows",
      "description": "Elevation shadows for overlays, cards, and floating action surfaces."
    }
  ],
  "tokens": {
    "source": "src/index.css",
    "usage": "var(--<name>) or the matching Tailwind utility. sections are resolved for the admin portal; portalOverrides lists what other portals change or add.",
    "sections": [
      {
        "id": "colors",
        "label": "Colors",
        "description": "Neutral, brand, semantic, and focus colors resolved for the active portal.",
        "groups": [
          {
            "id": "neutral",
            "label": "Neutral",
            "tokens": {
              "color-neutral-0": "#FFFFFF",
              "color-neutral-5": "#EFEFF6",
              "color-neutral-10": "#DEDEE7",
              "color-neutral-20": "#D3D2DF",
              "color-neutral-40": "#BCBCD0",
              "color-neutral-60": "#9A99B6",
              "color-neutral-80": "#808495",
              "color-neutral-100": "#323245"
            }
          },
          {
            "id": "brand",
            "label": "Brand",
            "tokens": {
              "color-violet": "#7578E1",
              "color-violet-light": "#BABCF1",
              "color-violet-lightest": "#E8E9FB",
              "color-violet-darkest": "#2E3080",
              "color-violet-dark": "#585BDB",
              "color-purple": "#823D82",
              "color-purple-light": "#BC85BD",
              "color-purple-dark": "#642C63",
              "color-turquoise": "#0091AE",
              "color-turquoise-light": "#EEF7F9",
              "color-turquoise-dark": "#006F85"
            }
          },
          {
            "id": "semantic",
            "label": "Semantic",
            "tokens": {
              "color-danger": "#DC3545",
              "color-danger-light": "#FEEAEE",
              "color-danger-dark": "#C82333",
              "color-danger-darkest": "#721C24",
              "color-success": "#28A745",
              "color-success-light": "#D4EDDA",
              "color-success-dark": "#218838",
              "color-success-darkest": "#155724",
              "color-warning": "#FFC107",
              "color-warning-light": "#FFF3CD",
              "color-warning-dark": "#F2B607",
              "color-warning-darkest": "#856404",
              "color-info": "#17A2B8",
              "color-info-light": "#D1ECF1",
              "color-info-dark": "#148496",
              "color-info-darkest": "#0C5460"
            }
          },
          {
            "id": "focus",
            "label": "Focus",
            "tokens": {
              "color-focus-ring": "#80BDFF",
              "color-focus-ring-danger": "#DC354540",
              "color-focus-shadow": "#007BFF40"
            }
          }
        ]
      },
      {
        "id": "typography",
        "label": "Typography",
        "description": "Font family, size, line height, weight, and letter spacing.",
        "groups": [
          {
            "id": "font-family",
            "label": "Font Family",
            "tokens": {
              "font-family-body": "\"Open Sans\", system-ui, -apple-system, sans-serif",
              "font-family-heading": "\"Open Sans\", system-ui, -apple-system, sans-serif",
              "font-family-mono": "\"Open Sans\", \"SF Mono\", Consolas, monospace"
            }
          },
          {
            "id": "font-size",
            "label": "Font Size",
            "tokens": {
              "font-size-sm": "12px",
              "font-size-base": "14px",
              "font-size-lg": "16px",
              "font-size-xl": "20px",
              "font-size-2xl": "26px",
              "font-size-3xl": "32px",
              "font-size-4xl": "40px"
            }
          },
          {
            "id": "line-height",
            "label": "Line Height",
            "tokens": {
              "line-height-sm": "18px",
              "line-height-base": "22px",
              "line-height-lg": "24px",
              "line-height-xl": "30px",
              "line-height-2xl": "31px",
              "line-height-3xl": "38px",
              "line-height-4xl": "48px"
            }
          },
          {
            "id": "font-weight",
            "label": "Font Weight",
            "tokens": {
              "font-weight-normal": "400",
              "font-weight-medium": "500",
              "font-weight-semibold": "600",
              "font-weight-bold": "700"
            }
          },
          {
            "id": "letter-spacing",
            "label": "Letter Spacing",
            "tokens": {
              "letter-spacing-tighter": "-0.7px",
              "letter-spacing-tight": "-0.35px",
              "letter-spacing-normal": "0px",
              "letter-spacing-wide": "0.35px",
              "letter-spacing-wider": "0.7px",
              "letter-spacing-widest": "1.4px"
            }
          }
        ]
      },
      {
        "id": "spacing",
        "label": "Spacing",
        "description": "Spacing scale for layout, gaps, and component composition.",
        "groups": [
          {
            "id": "spacing",
            "label": "All Spacing Tokens",
            "tokens": {
              "spacing-3xs": "2px",
              "spacing-2xs": "4px",
              "spacing-xs": "8px",
              "spacing-sm": "12px",
              "spacing-md": "16px",
              "spacing-lg": "24px",
              "spacing-xl": "32px",
              "spacing-2xl": "48px",
              "spacing-3xl": "64px",
              "spacing-4xl": "96px"
            }
          }
        ]
      },
      {
        "id": "border-radius",
        "label": "Border Radius",
        "description": "Corner radius scale for controls, cards, overlays, and rounded surfaces.",
        "groups": [
          {
            "id": "radius",
            "label": "All Radius Tokens",
            "tokens": {
              "radius-none": "0px",
              "radius-sm": "3px",
              "radius-md": "4px",
              "radius-lg": "5px",
              "radius-full": "9999px"
            }
          }
        ]
      },
      {
        "id": "border-width",
        "label": "Border Width",
        "description": "Border widths for outlines and separators.",
        "groups": [
          {
            "id": "border-width",
            "label": "All Border Width Tokens",
            "tokens": {
              "border-width-0": "0px",
              "border-width-1": "1px",
              "border-width-2": "2px"
            }
          }
        ]
      },
      {
        "id": "sizing",
        "label": "Sizing",
        "description": "Avatar, icon, control height, and form control sizes.",
        "groups": [
          {
            "id": "avatar",
            "label": "Avatar Sizes",
            "tokens": {
              "avatar-xs": "16px",
              "avatar-sm": "24px",
              "avatar-md": "32px",
              "avatar-lg": "40px",
              "avatar-xl": "48px",
              "avatar-2xl": "64px",
              "avatar-3xl": "128px"
            }
          },
          {
            "id": "icon",
            "label": "Icon Sizes",
            "tokens": {
              "icon-xs": "12px",
              "icon-sm": "16px",
              "icon-md": "20px",
              "icon-lg": "24px",
              "icon-xl": "32px",
              "icon-2xl": "48px"
            }
          },
          {
            "id": "height",
            "label": "Control Heights",
            "tokens": {
              "height-2xs": "4px",
              "height-xs": "8px",
              "height-sm": "12px",
              "height-md": "16px",
              "height-lg": "24px",
              "height-xl": "32px",
              "height-2xl": "48px",
              "height-3xl": "64px",
              "height-4xl": "96px"
            }
          },
          {
            "id": "control",
            "label": "Form Controls",
            "tokens": {
              "checkbox-size": "20px",
              "radio-size": "20px",
              "switch-width": "35px",
              "switch-height": "22px"
            }
          }
        ]
      },
      {
        "id": "layout",
        "label": "Layout",
        "description": "Breakpoints, containers, columns, and gutters.",
        "groups": [
          {
            "id": "breakpoint",
            "label": "Breakpoints",
            "tokens": {
              "breakpoint-xs": "320px",
              "breakpoint-sm": "576px",
              "breakpoint-md": "768px",
              "breakpoint-lg": "992px",
              "breakpoint-xl": "1200px",
              "breakpoint-2xl": "1400px"
            }
          },
          {
            "id": "container",
            "label": "Containers",
            "tokens": {
              "container-sm": "540px",
              "container-md": "720px",
              "container-lg": "960px",
              "container-xl": "1140px",
              "container-2xl": "1320px"
            }
          },
          {
            "id": "grid",
            "label": "Columns and Gutters",
            "tokens": {
              "columns": "12",
              "gutter-sm": "15px",
              "gutter-default": "30px"
            }
          }
        ]
      },
      {
        "id": "opacity",
        "label": "Opacity",
        "description": "Opacity scale for disabled, hover, and emphasis treatments.",
        "groups": [
          {
            "id": "opacity",
            "label": "All Opacity Tokens",
            "tokens": {
              "opacity-0": "0",
              "opacity-10": "0.1",
              "opacity-25": "0.25",
              "opacity-50": "0.5",
              "opacity-60": "0.6",
              "opacity-75": "0.75",
              "opacity-90": "0.9",
              "opacity-100": "1"
            }
          }
        ]
      },
      {
        "id": "shadows",
        "label": "Shadows",
        "description": "Elevation shadows composed from the drop-shadow part tokens.",
        "groups": [
          {
            "id": "composed",
            "label": "Shadows",
            "tokens": {
              "shadow-sm": "0px 2px 4px 0px rgba(0, 0, 0, 0.075)",
              "shadow-md": "0px 8px 16px 0px rgba(0, 0, 0, 0.15)",
              "shadow-lg": "0px 16px 48px 0px rgba(0, 0, 0, 0.176)"
            }
          },
          {
            "id": "parts",
            "label": "Shadow Parts",
            "tokens": {
              "drop-shadow-sm-offset-x": "0px",
              "drop-shadow-sm-offset-y": "2px",
              "drop-shadow-sm-blur": "4px",
              "drop-shadow-sm-spread": "0px",
              "drop-shadow-sm-color": "rgba(0, 0, 0, 0.075)",
              "drop-shadow-md-offset-x": "0px",
              "drop-shadow-md-offset-y": "8px",
              "drop-shadow-md-blur": "16px",
              "drop-shadow-md-spread": "0px",
              "drop-shadow-md-color": "rgba(0, 0, 0, 0.15)",
              "drop-shadow-lg-offset-x": "0px",
              "drop-shadow-lg-offset-y": "16px",
              "drop-shadow-lg-blur": "48px",
              "drop-shadow-lg-spread": "0px",
              "drop-shadow-lg-color": "rgba(0, 0, 0, 0.176)"
            }
          }
        ]
      },
      {
        "id": "z-index",
        "label": "Z-Index",
        "description": "Layering for dropdowns, sticky UI, modals, popovers, and tooltips.",
        "groups": [
          {
            "id": "z-index",
            "label": "All Z-Index Tokens",
            "tokens": {
              "z-dropdown": "1000",
              "z-sticky": "1020",
              "z-fixed": "1030",
              "z-modal-backdrop": "1040",
              "z-modal": "1050",
              "z-popover": "1060",
              "z-tooltip": "1070"
            }
          }
        ]
      }
    ],
    "portalOverrides": {
      "user": {
        "color-violet": "#823C82",
        "color-violet-light": "#EED6F0",
        "color-violet-lightest": "#F6EAF7",
        "color-violet-darkest": "#4A2149",
        "color-violet-dark": "#642C63",
        "color-purple": "#823C82",
        "color-purple-light": "#EED6F0",
        "color-purple-dark": "#642C63",
        "color-turquoise": "#0091AE",
        "color-turquoise-light": "#EEF7F9",
        "color-turquoise-dark": "#006F85",
        "color-success": "#009688",
        "color-neutral-5": "#F8F8FA",
        "color-neutral-80": "#43425D",
        "body-content": "#FFFFFF",
        "primary-color": "#823C82",
        "secondary-color": "#EED6F0",
        "button-color": "#823C82",
        "button-text-color": "#FFFFFF",
        "link-color": "#0091AE",
        "nav-color": "#823C82",
        "nav-text-color": "#FFFFFF"
      }
    }
  },
  "guidelines": {
    "sections": [
      {
        "id": "principles",
        "label": "Principles",
        "description": "Qualities a redesign must keep."
      },
      {
        "id": "behaviors",
        "label": "Behaviors",
        "description": "Interaction rules that span components and can be checked."
      },
      {
        "id": "prototype-standards",
        "label": "Prototype standards",
        "description": "Rules about the mockup being reviewable, not about the product."
      },
      {
        "id": "for-agents",
        "label": "For agents",
        "description": "Where the machine-readable version lives and how to point an agent at it."
      }
    ],
    "principles": [
      {
        "id": "task-first",
        "title": "Dense, calm, task-first",
        "body": "Agency-admin surfaces are working screens. No marketing layouts, oversized hero text, or decorative panels.",
        "portals": [
          "admin"
        ]
      },
      {
        "id": "status-first",
        "title": "Status before decoration",
        "body": "Tables and profile pages lead with case status, owner, risk, next step, and recency.",
        "portals": [
          "admin"
        ]
      },
      {
        "id": "say-it-once",
        "title": "Say it once",
        "body": "Show a count or status in one place. Do not repeat it across banners, cards, badges, and helper text.",
        "portals": [
          "admin",
          "user"
        ]
      },
      {
        "id": "neutral-surfaces",
        "title": "Neutral surfaces, semantic color for state",
        "body": "Neutral surfaces dominate. Semantic colors are reserved for success, danger, warning, and info states.",
        "portals": [
          "admin",
          "user"
        ]
      },
      {
        "id": "brand-roles",
        "title": "Brand color roles",
        "body": "Violet is the main CTA and accent, purple is secondary, turquoise is tertiary and informational.",
        "portals": [
          "admin"
        ]
      },
      {
        "id": "client-portal-parity",
        "title": "Client portal follows Orchid production",
        "body": "The user portal represents the Intended Parent client portal. Its colors track the Orchid production user variables: purple primary, navigation, and buttons; light secondary purple; turquoise links; white navigation text; neutral white body content.",
        "portals": [
          "user"
        ],
        "since": "2026-08-21",
        "because": "A prototype-only palette made client-portal mockups look unlike the product they stand in for."
      },
      {
        "id": "structure-encodes-meaning",
        "title": "Structure encodes meaning",
        "body": "Dividers, numbering, labels, grouping, and cards exist to clarify a relationship. None of them decorates empty space.",
        "portals": [
          "admin",
          "user"
        ]
      },
      {
        "id": "show-dont-explain",
        "title": "Show, don't explain",
        "body": "State, placement, affordance, and concise labels do the explaining. No banners, helper paragraphs, onboarding copy, or callouts unless the consequence is high-risk or the brief requires them. If copy seems necessary, redesign the interaction first.",
        "portals": [
          "admin",
          "user"
        ]
      },
      {
        "id": "plain-verbs",
        "title": "Plain verbs, consistent names",
        "body": "Actions are written from the user's side of the screen with plain verbs, and the same action carries the same name everywhere.",
        "portals": [
          "admin",
          "user"
        ]
      },
      {
        "id": "build-from-catalog",
        "title": "Build from the catalog",
        "body": "Use a project component when one exists; extend or compose before creating a local variant. Never hardcode a value when a token or component prop exists.",
        "portals": [
          "admin",
          "user"
        ],
        "since": "2026-08-04",
        "because": "Component tables and token values copied into markdown drifted from the code; /ui and src/index.css are read directly instead."
      }
    ],
    "behaviors": [
      {
        "id": "overlay-trigger-context",
        "title": "Overlays keep their trigger in view",
        "body": "While a drawer or modal is open, the row, card, or item that opened it is marked active. When it closes, that item stays highlighted until the user moves on, and keyboard focus returns to it. The user always knows what they were looking at.",
        "components": [
          "modal",
          "table",
          "card"
        ],
        "portals": [
          "admin",
          "user"
        ]
      },
      {
        "id": "trigger-surfaces",
        "title": "Anything that opens something is a control",
        "body": "A row, card, cell, or text region that opens a modal or drawer has hover, focus, and keyboard behavior, and is a semantic interactive element whenever feasible.",
        "components": [
          "table",
          "card",
          "stats-card"
        ],
        "portals": [
          "admin",
          "user"
        ]
      },
      {
        "id": "modal-vs-drawer",
        "title": "Modal for a short form, drawer for the rest",
        "body": "A modal holds a short form with a few inputs. When a form has sections, validation context, or supporting details that would make the modal scroll, it is a drawer.",
        "components": [
          "modal"
        ],
        "portals": [
          "admin",
          "user"
        ]
      },
      {
        "id": "forms-keep-context",
        "title": "Forms keep context",
        "body": "Labels stay visible, the user's input survives a validation error, and errors appear only after the user has interacted with the field.",
        "components": [
          "input",
          "textarea",
          "select",
          "combobox",
          "autocomplete",
          "multi-select",
          "datepicker",
          "phone-input",
          "file-upload",
          "wysiwyg"
        ],
        "portals": [
          "admin",
          "user"
        ]
      },
      {
        "id": "error-scope",
        "title": "Errors land at the narrowest useful scope",
        "body": "Field errors for validation. Row or form errors for a failed action. Page-level errors only for a failed primary load. A toast only for transient, nonblocking feedback; anything persistent or actionable stays visible in context.",
        "components": [
          "input",
          "textarea",
          "select",
          "combobox",
          "autocomplete",
          "multi-select",
          "datepicker",
          "phone-input",
          "file-upload",
          "wysiwyg",
          "alert",
          "toast",
          "table",
          "modal"
        ],
        "portals": [
          "admin",
          "user"
        ]
      },
      {
        "id": "failure-copy",
        "title": "Failures say what, so what, and what next",
        "body": "A failure states what failed, the consequence, and the next useful action in plain language, with a retry, correction, or return path. Raw provider or status-code messages never appear as interface copy.",
        "components": [
          "alert",
          "toast",
          "modal",
          "empty-state"
        ],
        "portals": [
          "admin",
          "user"
        ]
      },
      {
        "id": "action-sequence",
        "title": "Actions show their whole sequence",
        "body": "A consequential action moves through ready, pending, failure, recovery or retry, and success. Input is preserved throughout, and it is always clear whether the action took effect.",
        "components": [
          "button",
          "icon-button",
          "button-group",
          "dropdown-button",
          "floating-save-button",
          "floating-action-bar",
          "alert",
          "toast"
        ],
        "portals": [
          "admin",
          "user"
        ]
      },
      {
        "id": "destructive-scope",
        "title": "Consequential actions restate their scope",
        "body": "Before a destructive or consequential action runs, the confirmation names exactly what it will affect: which records, how many, and what cannot be undone.",
        "components": [
          "modal",
          "floating-action-bar",
          "button",
          "dropdown-button"
        ],
        "portals": [
          "admin",
          "user"
        ]
      },
      {
        "id": "selection-scope",
        "title": "Selection scope is explicit",
        "body": "The header control selects the visible rows first; selecting every matching result is a separate, named action. Hidden rows are never selected silently, and a selection is never discarded silently.",
        "components": [
          "table",
          "checkbox",
          "pagination",
          "floating-action-bar"
        ],
        "portals": [
          "admin"
        ]
      },
      {
        "id": "selection-context",
        "title": "Selections survive their context, and say so",
        "body": "The selected count and its scope stay visible next to the bulk actions. Pagination, search, filter, sort, refresh, deletion, and partial failure each have a defined effect on the selection.",
        "components": [
          "table",
          "pagination",
          "floating-action-bar"
        ],
        "portals": [
          "admin"
        ]
      },
      {
        "id": "motion-explains",
        "title": "Motion explains, never decorates",
        "body": "Inserting or removing content animates the element and the resulting reflow as one move. Overlays animate in and out without shifting what is behind them. Motion is brief and nonblocking, the change reads without it, and reduced-motion gets an instant alternative.",
        "components": [
          "modal",
          "toast",
          "alert",
          "table",
          "card",
          "dropdown-button",
          "tooltip"
        ],
        "portals": [
          "admin",
          "user"
        ]
      },
      {
        "id": "keyboard-focus",
        "title": "Every control works from the keyboard",
        "body": "Every interactive element is reachable by keyboard, in a sensible order, and shows a visible focus state.",
        "components": [
          "button",
          "icon-button",
          "button-group",
          "dropdown-button",
          "floating-save-button",
          "floating-action-bar",
          "input",
          "textarea",
          "select",
          "combobox",
          "autocomplete",
          "multi-select",
          "datepicker",
          "phone-input",
          "file-upload",
          "wysiwyg",
          "checkbox",
          "radio",
          "switch",
          "tabs",
          "pagination",
          "modal",
          "table",
          "pills",
          "breadcrumbs",
          "tooltip"
        ],
        "portals": [
          "admin",
          "user"
        ]
      },
      {
        "id": "not-color-alone",
        "title": "State never relies on color alone",
        "body": "Status and errors carry text or an icon alongside color, so they read in grayscale and to color-blind users.",
        "components": [
          "badge",
          "alert",
          "toast",
          "input",
          "textarea",
          "select",
          "combobox",
          "autocomplete",
          "multi-select",
          "datepicker",
          "phone-input",
          "file-upload",
          "wysiwyg",
          "progress-bar",
          "progress-circular",
          "switch"
        ],
        "portals": [
          "admin",
          "user"
        ]
      },
      {
        "id": "pagination-decided",
        "title": "Pagination is decided, not defaulted",
        "body": "A full-page table or list expected to exceed 15 rows uses numbered pagination. Load-more, virtualized scrolling, or a capped recent list is a deliberate choice, and the handoff says why.",
        "components": [
          "table",
          "pagination"
        ],
        "portals": [
          "admin",
          "user"
        ],
        "standard": "prototype"
      },
      {
        "id": "three-pages-of-fixtures",
        "title": "Paginated collections show three pages",
        "body": "Fixture data covers page 1, page 2, and a partial last page; load-more covers the initial batch plus two more with a partial final batch. Sparse and single-page states exist as secondary fixtures, never as the only demonstration.",
        "components": [
          "table",
          "pagination"
        ],
        "portals": [
          "admin",
          "user"
        ],
        "standard": "prototype"
      },
      {
        "id": "stable-identities",
        "title": "Paging never loses an item",
        "body": "Items keep stable identities. Changing pages or appending results never duplicates, skips, reorders, or miscounts them.",
        "components": [
          "table",
          "pagination"
        ],
        "portals": [
          "admin",
          "user"
        ],
        "standard": "prototype"
      },
      {
        "id": "reachable-failure",
        "title": "Every consequential action has a reachable failure",
        "body": "At least one representative failure per consequential action, reachable on purpose through a scenario switch, a query parameter, a fixture, or a resettable success-then-failure cycle. Never random, and never production data.",
        "components": [
          "button",
          "icon-button",
          "button-group",
          "dropdown-button",
          "floating-save-button",
          "floating-action-bar",
          "alert",
          "toast",
          "modal"
        ],
        "portals": [
          "admin",
          "user"
        ],
        "standard": "prototype"
      }
    ]
  }
}
