@hirobius/design-system 0.18.0 → 0.19.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (85) hide show
  1. package/CONSUMING.md +150 -0
  2. package/DESIGN.md +220 -0
  3. package/README.md +14 -2
  4. package/dist/chunks/{activity-feed-C8_e-Btq.js → activity-feed-DIMeUJpW.js} +4907 -2912
  5. package/dist/chunks/{form-DnGRy27o.js → form-BvNNnJ0t.js} +2 -2
  6. package/dist/form.js +5 -5
  7. package/dist/hirobius-ui.js +1986 -2529
  8. package/dist/icons.js +53 -0
  9. package/dist/manifest.js +15 -14
  10. package/dist/patterns.js +292 -101
  11. package/dist/static.css +3 -3
  12. package/dist/styles.css +1 -1
  13. package/dist/tokens.css +1 -1
  14. package/dist/types/src/app/components/alert-dialog.d.ts +9 -1
  15. package/dist/types/src/app/components/alert.d.ts +4 -0
  16. package/dist/types/src/app/components/avatar.d.ts +4 -0
  17. package/dist/types/src/app/components/badge.d.ts +4 -0
  18. package/dist/types/src/app/components/box.d.ts +5 -0
  19. package/dist/types/src/app/components/breadcrumb.d.ts +4 -0
  20. package/dist/types/src/app/components/button-group.d.ts +4 -0
  21. package/dist/types/src/app/components/button.d.ts +3 -0
  22. package/dist/types/src/app/components/card.d.ts +9 -0
  23. package/dist/types/src/app/components/checkbox.d.ts +4 -0
  24. package/dist/types/src/app/components/combobox.d.ts +10 -0
  25. package/dist/types/src/app/components/command-palette.d.ts +3 -1
  26. package/dist/types/src/app/components/container.d.ts +5 -0
  27. package/dist/types/src/app/components/context-menu.d.ts +25 -2
  28. package/dist/types/src/app/components/data-table-section.d.ts +45 -0
  29. package/dist/types/src/app/components/destructive-section.d.ts +32 -0
  30. package/dist/types/src/app/components/dialog.d.ts +20 -2
  31. package/dist/types/src/app/components/disclosure.d.ts +3 -0
  32. package/dist/types/src/app/components/divider.d.ts +4 -0
  33. package/dist/types/src/app/components/empty-state.d.ts +4 -0
  34. package/dist/types/src/app/components/field.d.ts +4 -0
  35. package/dist/types/src/app/components/form-actions.d.ts +26 -0
  36. package/dist/types/src/app/components/grid.d.ts +4 -0
  37. package/dist/types/src/app/components/hds-tooltip.d.ts +14 -2
  38. package/dist/types/src/app/components/hover-card.d.ts +16 -1
  39. package/dist/types/src/app/components/icon.d.ts +4 -0
  40. package/dist/types/src/app/components/inline-link.d.ts +4 -0
  41. package/dist/types/src/app/components/input.d.ts +5 -0
  42. package/dist/types/src/app/components/kbd.d.ts +3 -0
  43. package/dist/types/src/app/components/menu.d.ts +26 -2
  44. package/dist/types/src/app/components/metric-tiles.d.ts +40 -0
  45. package/dist/types/src/app/components/page-header.d.ts +34 -0
  46. package/dist/types/src/app/components/pagination.d.ts +3 -0
  47. package/dist/types/src/app/components/popover.d.ts +14 -2
  48. package/dist/types/src/app/components/progress.d.ts +4 -0
  49. package/dist/types/src/app/components/radio.d.ts +5 -0
  50. package/dist/types/src/app/components/select.d.ts +16 -0
  51. package/dist/types/src/app/components/skeleton.d.ts +4 -0
  52. package/dist/types/src/app/components/slider.d.ts +3 -0
  53. package/dist/types/src/app/components/spinner.d.ts +4 -0
  54. package/dist/types/src/app/components/stack.d.ts +4 -0
  55. package/dist/types/src/app/components/stat.d.ts +4 -0
  56. package/dist/types/src/app/components/status-tile.d.ts +4 -0
  57. package/dist/types/src/app/components/table.d.ts +36 -4
  58. package/dist/types/src/app/components/tabs.d.ts +4 -0
  59. package/dist/types/src/app/components/tag.d.ts +3 -0
  60. package/dist/types/src/app/components/text.d.ts +4 -0
  61. package/dist/types/src/app/components/textarea.d.ts +3 -0
  62. package/dist/types/src/app/components/toast.d.ts +4 -0
  63. package/dist/types/src/app/components/toggle.d.ts +4 -0
  64. package/dist/types/src/app/components/tooltip.d.ts +1 -1
  65. package/dist/types/src/app/components/visually-hidden.d.ts +3 -0
  66. package/dist/types/src/app/context/hds-portal.d.ts +52 -0
  67. package/dist/types/src/app/context/hds-theme.d.ts +10 -0
  68. package/dist/types/src/app/data/manifest-types.d.ts +27 -0
  69. package/dist/types/src/app/design-system/generated-token-refs.d.ts +2 -0
  70. package/dist/types/src/icons.d.ts +13 -0
  71. package/dist/types/src/index.d.ts +20 -1
  72. package/dist/types/src/patterns.d.ts +5 -0
  73. package/dist/variables.css +4 -0
  74. package/docs/CONSUMING.md +758 -0
  75. package/hirobius.tokens.json +17 -0
  76. package/llms.txt +261 -0
  77. package/package.json +21 -4
  78. package/public/hds-manifest.json +1545 -89
  79. package/public/llms/components.txt +1090 -0
  80. package/public/llms/layout.txt +54 -0
  81. package/public/llms/scroll.txt +22 -0
  82. package/public/llms/tokens.txt +32 -0
  83. package/public/llms-full.txt +1561 -0
  84. package/public/llms.txt +261 -0
  85. package/src/app/data/component-api.json +6156 -0
@@ -0,0 +1,1561 @@
1
+ # Hirobius Design System
2
+
3
+ Generated: 2026-09-30T14:27:19.090Z
4
+ Primary sources: `public/hds-manifest.json`, `src/app/data/component-api.json`, `hirobius.tokens.json`
5
+
6
+ ## System Architecture
7
+
8
+ - Engine: React + TypeScript
9
+ - Icons: Lucide React
10
+ - Tokens: W3C DTCG
11
+ - Styling: CSS Variables
12
+ - Token pipeline: `hirobius.tokens.json` -> `pnpm tokens` -> generated CSS vars + generated TS constants
13
+ - Docs pipeline: `public/hds-manifest.json` + `src/app/data/component-api.json` -> reflective docs pages
14
+ - AI entrypoint: read `public/llms.txt` before editing code
15
+
16
+ ## Phase Snapshot
17
+
18
+ - foundation. Foundations - 63% - Token architecture, CSS pipeline, accessibility, and primitive scales.
19
+ - Criteria: done: W3C DTCG three-tier token architecture; done: CSS variable pipeline + token verify; partial: Primitive scales complete (color, type, space); todo: Token audit clean
20
+ - components. Components - 75% - Accessible React UI built from foundations and mapped toward Figma parity.
21
+ - Criteria: done: Component inventory with typed props; done: Action system architecture (buttons, links, groups); done: Prop tables and API doc coverage; todo: Figma parity mapping
22
+ - infrastructure-operations. Architecture - 55% - System delivery, Figma sync, automation, quality gates, and operational hygiene.
23
+ - Criteria: done: System manifest + llms.txt AI context; done: Release gate + full audit gate; done: Documentation automation (AST pipeline, LLMS sync); partial: Payload sweep + orphan cleanup; partial: Motion system foundations; todo: Figma library generated from tokens; todo: Code Connect CI + reverse sync; partial: AST gatekeeper + token schema validation; partial: A11y CI + visual regression pipeline; partial: Operational feedback loop + AI retrospective
24
+
25
+ ## Component Inventory (Source Of Truth)
26
+
27
+ This file intentionally does not embed the full component list to avoid duplication and excess context.
28
+
29
+ - Canonical inventory + metadata: read `public/hds-manifest.json`.
30
+ - If you see references to `public/manifest.json`, treat it as an optional alias; in this repo prefer `public/hds-manifest.json`.
31
+
32
+ ## Component API (Source Of Truth)
33
+
34
+ This file intentionally does not embed prop tables or long-form API docs.
35
+
36
+ - Detailed prop types, unions, defaults, and descriptions: read `src/app/data/component-api.json`.
37
+ - Runtime behavior: read the actual component source under `src/app/components/` (and associated styles).
38
+
39
+ ## Which one when
40
+
41
+ One line per component that declares when to use it (`@usage` / `@useInstead` in its JSDoc). Full detail, including `usage.whenNot`, `keyboard` and `aiRules`, is in `public/hds-manifest.json` and `src/app/data/component-api.json`.
42
+
43
+ Alert: Show a persistent inline message with a severity, next to the content it concerns. Use instead: ToastProvider, Badge
44
+ Avatar: Show a person or entity as an image with an initials fallback. Use instead: Icon, Badge
45
+ Badge: Label a status, state or count with a compact neutral or semantic chip. Use instead: Tag, Alert
46
+ Box: Build one-off layout that no named layout primitive covers, using token keys through `sx`. Use instead: Stack, Grid, Container
47
+ Breadcrumb: Show where the current page sits in a hierarchy and link back up it. Use instead: Tabs, Pagination
48
+ Button: Trigger an action (submit, save, open a dialog) with a text label and optional icons; for an icon-only control pass iconOnly with iconLeft. Use instead: InlineLink
49
+ ButtonGroup: Attach related Buttons into one segmented row or column that reads as a single control. Use instead: SegmentedControl, Stack
50
+ Card: Group related content on a raised surface with header, body, footer and metric slots. Use instead: Surface, Card.Metric
51
+ CardMetric: Show one headline figure (a KPI, a count, a total) with its label inside a Card.
52
+ Checkbox: Let people tick one or more independent options, or a parent choice that is partly selected. Use instead: Toggle, Radio
53
+ Combobox: Pick one value from a long list of options, with a search field that filters as you type. Use instead: Select, Menu
54
+ Container: Constrain a page region to the content or maximum width and centre it. Use instead: Stack, Grid, Box
55
+ ContextMenu: Offer actions for an item on right-click, or the equivalent keyboard gesture. Use instead: Menu
56
+ Dialog: Interrupt the page with a modal that needs a decision or focused input before people continue. Use instead: HoverCard, Alert, ToastProvider
57
+ Disclosure: Hide optional explanatory content behind a heading that people can expand. Use instead: Tabs
58
+ Divider: Separate two regions of content with a thin semantic rule. Use instead: Stack, Surface
59
+ EmptyState: Say that a list, grid or section has no data yet, with a title and an optional description. Use instead: Skeleton, Alert
60
+ Field: Show a labelled read-only value, such as a name and its value in a detail view. Use instead: Input, Card.Metric
61
+ Grid: Lay out content in responsive columns with token-governed gaps, or align nested content with subgrid. Use instead: Stack, Box
62
+ HdsThemeProvider: Wrap an app or region once to set theme, density and other root attributes for everything inside it. Use instead: Surface
63
+ HoverCard: Preview extra detail about a link or mention when it is hovered or focused, without navigating. Use instead: Dialog, Tooltip
64
+ Icon: Draw a Lucide glyph at a size and colour from the design tokens. Use instead: Button, Avatar
65
+ IconButton: Trigger an action from a compact icon-only control, always with an accessible label. Use instead: Button
66
+ InlineLink: Link to a route or external URL from inside body copy. Use instead: Button, Text
67
+ Input: Collect a single line of text, a number, an email or a password, with label, helper and error slots. Use instead: Textarea, Select, Combobox
68
+ Kbd: Show a keyboard key or shortcut hint inline, as a native kbd element. Use instead: Text
69
+ Menu: Offer a list of actions from a trigger, closed until opened. Use instead: Select
70
+ Pagination: Move between pages of a long result set, with truncated page numbers. Use instead: Breadcrumb
71
+ Progress: Show how far a task has got, as a bar that is determinate or indeterminate. Use instead: Spinner, Skeleton
72
+ Radio: Choose exactly one option from a small set that should stay visible together. Use instead: Checkbox, Select, SegmentedControl
73
+ SegmentedControl: Switch between two to five mutually exclusive views or modes in a compact row. Use instead: Radio, Tabs, Select
74
+ Select: Choose one value from a short list of options in a form field. Use instead: Menu, Combobox
75
+ Skeleton: Reserve the shape of content that is still loading, so the layout does not jump. Use instead: Progress, Spinner
76
+ Slider: Pick a number within a known range by dragging, when the exact value matters less than the position. Use instead: Input
77
+ Spinner: Show that something is loading when the wait is short or has no measurable end. Use instead: Progress, Skeleton
78
+ Stack: Space a row or column of content with token gaps and simple flex alignment. Use instead: Grid, Surface
79
+ Stat: Show one standalone headline figure with its label and an optional sub-line. Use instead: Card.Metric, StatusTile
80
+ StatusTile: Show a titled status block with optional notes and a trailing badge or affordance. Use instead: Card.Metric, StatusListItem
81
+ Surface: Wrap content in a padded, background-bearing inset surface with no header or footer anatomy. Use instead: Card, Stack
82
+ Table: Show rows of structured data in aligned columns, with optional sorting. Use instead: Field, Stack
83
+ Tabs: Switch between panels of related content in the same place, one visible at a time. Use instead: SegmentedControl, Disclosure
84
+ Tag: Show an interactive filter or category chip that people can toggle. Use instead: Badge
85
+ Text: Set any text on the type ramp, with the element chosen by `as`. Use instead: InlineLink, Kbd
86
+ Textarea: Collect multi-line free text such as a message, note or description. Use instead: Input
87
+ ToastProvider: Confirm an action with a brief message that appears and dismisses itself, through useToast. Use instead: Alert, Dialog
88
+ Toggle: Switch one setting on or off, with the effect applying immediately. Use instead: Checkbox, Radio
89
+ VisuallyHidden: Give assistive technology a label or description that sighted people do not need to see. Use instead: Text
90
+
91
+ ## Tokens (Primary Source Of Truth)
92
+
93
+ - Primary token source of truth: `hirobius.tokens.json` (W3C DTCG).
94
+ - Prefer `semantic.*` and `component.*` tokens for product UI. Use `primitive.*` only when editing the token system itself.
95
+ - CSS variable naming convention: token path `semantic.color.surface.page` maps to `var(--semantic-color-surface-page)`.
96
+
97
+ ## Quick Token Reference
98
+
99
+ | Need | Token path examples | CSS var examples |
100
+ | --- | --- | --- |
101
+ | Page/background surfaces | `semantic.color.surface.page`, `semantic.color.surface.raised` | `--semantic-color-surface-page`, `--semantic-color-surface-raised` |
102
+ | Text/content colors | `semantic.color.content.primary`, `semantic.color.content.secondary` | `--semantic-color-content-primary`, `--semantic-color-content-secondary` |
103
+ | Borders/dividers | `semantic.color.border.default`, `semantic.color.border.interactive` | `--semantic-color-border-default`, `--semantic-color-border-interactive` |
104
+ | Feedback states | `semantic.color.feedback.error`, `semantic.color.feedback.success` | `--semantic-color-feedback-error`, `--semantic-color-feedback-success` |
105
+ | Spacing (semantic tiers) | `semantic.space.scale.xs`, `semantic.space.surface.padding`, `semantic.space.region.gutter` | use semantic tokens or `--hds-space-px12` style vars |
106
+ | Radius | `semantic.radius.action` | `--semantic-radius-action` |
107
+ | Motion | `semantic.motion.productive`, `semantic.motion.expressive`, `semantic.motion.exit` | use token refs; values are structured (duration/easing) |
108
+ | Typography | `semantic.typography.body`, `semantic.typography.h2`, `semantic.typography.caption` | use token refs; values are structured (family/size/weight/etc) |
109
+
110
+ ## How To Lay Out A Screen
111
+
112
+ Canonical skeleton, outermost to innermost:
113
+
114
+ 1. `Page` (or `Container`/`Center` for a full-bleed, non-page surface) for the outermost width constraint. Never import `Container` directly inside `src/app/pages/**` — use `Page`, which wraps it and owns vertical rhythm.
115
+ 2. `Stack` (vertical rhythm between sections) or `Grid` (two-dimensional/column layout) for the structural skeleton. One section = one Section/Stack — never add a second wrapper to fake a section boundary.
116
+ 3. Reach for a named every-layout primitive before hand-rolling flex/grid math for a common intent: `Cluster` (wrapping row of same-ish things), `Center` (centered max-width column with optional gutter), `Sidebar` (fixed-width rail + fluid content, no media query), `Switcher` (row that flips to a column below a threshold, no media query), `Cover` (full-height shell with a centered main region), `Frame` (aspect-ratio-locked clipped media box), `Bleed` (controlled negative margin to escape a parent padding).
117
+ 4. `Surface` for any background-bearing, padded wrapper (card, panel, inset). Never a raw element with backgroundColor + padding hand-rolled inline.
118
+ 5. Use the screen patterns (`@hirobius/design-system/patterns`) for the parts every screen repeats: `PageHeader` once at the top (breadcrumb, `heading2` title, status, actions), `MetricTiles` for any row of headline numbers, `FormActions` for a form footer (primary right-most and last in DOM order, destructive on the far left), `DataTableSection` for a titled table (toolbar slot, consumer row actions, empty state, scrolls on narrow widths without a caller `minWidth`), and `DestructiveSection` last for an irreversible action (danger button, then an `AlertDialog` confirm). Pick between `MetricTiles`, `Stat`, `Card.Metric` and `StatusTile`, and between `Card` and `Surface`, with the "Which one, when" table in `DESIGN.md`.
119
+ 6. `Box` `sx` LAST — only for genuinely one-off layout that no named primitive covers. `sx` spacing/color keys MUST be HDS token keys, never raw hex/px.
120
+
121
+ Negative rules (apply everywhere, checked by `scripts/audit-tokens.mjs --full`, `check-hardcoded-spacing.mjs`, `check-hardcoded-colors.mjs`):
122
+
123
+ - No inline margins on children to fake spacing between siblings — gap/spacing on the parent (Stack/Grid/Cluster/Switcher/Sidebar/Cover) owns rhythm, not margin on the child.
124
+ - No raw px or hex values in any layout or color prop — every spacing value comes from the semantic gap scale (`tight | normal | inset | spacious`, or a component/subgrid step) and every color comes from a `semantic.color.*` token.
125
+ - No repeated outlined cards as the default structure for roadmap/status/process/overview UI — use open bands, dividers, rails, disclosures, and whitespace instead.
126
+
127
+ Density: put `data-density="compact"` on the same `[data-hds]` scope element (or `<html>`) to tighten `semantic.space.scale.*`, surface padding and region gutter; `Table` follows it unless given a `density` prop.
128
+
129
+ Reference: `docs/architecture/variant-contract.md` for structural/semantic/size/density variance; `src/app/data/component-api.json` for every layout primitive's full prop table and `@ai-rules` guidance.
130
+
131
+ ## How To Build A Scroll-Driven Section
132
+
133
+ Canonical primitives, cheapest-first (CSS before JS, JS before an opt-in dependency):
134
+
135
+ 1. `Reveal` (CSS `animation-timeline: view()`) for fade/slide/scale-in-on-enter — zero JS, zero deps. Pick `animation` from `fade | fade-up | fade-down | scale`. Content is visible by DEFAULT; the effect applies only where `animation-timeline` is supported and the user has not requested reduced motion — never gate visibility behind either.
136
+ 2. `Pin` (`position: sticky`) for a pinned scroll scene — the dependency-free basis for the "tall section + sticky child" pattern (GSAP's `pin: true`, done with zero JS). Give the pinned element a TALLER scrolling parent (e.g. `height: 300vh`) so it has room to travel; `top` is a CSS length offset, not a spacing token.
137
+ 3. `useScrollProgress` (from `@hirobius/design-system/scroll`) only when the 0→1 scroll value is needed in React — cross-element choreography, canvas/WebGL, or a Motion (`motion/react`) `useTransform` binding that CSS `animation-timeline` cannot express. Thin, SSR-guarded wrapper over Motion `useScroll`; adds no new dependency.
138
+ 4. `SmoothScroll` (from `@hirobius/design-system/scroll`, `lenis` as an OPTIONAL peer dep) only for opt-in momentum ("inertia") scrolling, mounted once at the app/site root. Never imported from the main barrel — consumers who skip it pay nothing. Reduced-motion-first: Lenis is not instantiated when the user prefers reduced motion, unless `ignoreReducedMotion` is set for a deliberate art-directed exception.
139
+ 5. Do not adopt GSAP/ScrollTrigger, and do not wire Lenis directly outside `SmoothScroll`, inside the core library — the CSS + Motion stack above covers reveal/pin/scrub without new dependencies. Bespoke GSAP/Lenis/WebGL scenes stay app-level/downstream (marketing sites, the clients factory), composed from these primitives (ADR-021, #116).
140
+
141
+ Negative rules:
142
+
143
+ - No hand-rolled IntersectionObserver reveal-on-scroll logic — use `Reveal`.
144
+ - No hand-rolled `position: sticky` scroll scenes — use `Pin`.
145
+ - No GSAP/ScrollTrigger or bespoke Lenis wiring inside `@hirobius/design-system` — those stay app-level/downstream, composed from `Reveal`/`Pin`/`useScrollProgress`/`SmoothScroll`.
146
+ - Every scroll effect must degrade to fully visible/static content — never gate content visibility behind `animation-timeline` support or a scroll listener with no fallback.
147
+
148
+ Reference: `src/app/components/reveal.tsx`, `src/app/components/pin.tsx`, `src/scroll/` (`use-scroll-progress.ts`, `smooth-scroll.tsx`), ADR-021, and `src/stories/patterns-scroll.stories.tsx` for golden-path examples.
149
+
150
+ ## HDS Card Anatomy (mandatory — every property is non-negotiable)
151
+
152
+ When building any card component or card-like surface, ALL of the following rules apply. There is no creative latitude here — deviation from any property is a bug.
153
+
154
+ | Property | Required value | Forbidden |
155
+ | --- | --- | --- |
156
+ | Background | `var(--semantic-color-surface-raised)` | Custom colors, gradients, tinted fills, any non-token value |
157
+ | Border | `1px solid var(--semantic-color-border-default)` | `box-shadow` as an elevation substitute |
158
+ | Border radius | `rounded-lg` (`role.radius` + 4 px: 12 px by default, follows the tenant) | `var(--component-card-radius)`, `rounded-full`, or any hard-coded value |
159
+ | Padding | `var(--semantic-space-surface-padding)` or `<Surface padding="component">` | Raw pixel values, Tailwind spacing classes, ad hoc insets |
160
+ | Shadow | Resting cards: none (`elevation.flat`). Interactive lifted state: `shadow.subtle` via `elevation.raised`. Never reach for shadow values directly — bind via `var(--semantic-elevation-{role}-shadow)` | Raw `box-shadow` values, `drop-shadow`, glow, or any depth effect not bound to a role token |
161
+ | Title | `hds.typeStyles.heading3` / `<Text variant="heading3">` | Any other type style for the primary card heading |
162
+ | Subtitle / meta | `hds.typeStyles.caption` / `<Text variant="caption">` + `var(--semantic-color-content-secondary)` | Primary color, body size, or custom color for secondary text |
163
+ | Hover (interactive cards only) | `transform: scale(1.02)` CSS transform | Background color change, fill swap, border color shift on hover |
164
+
165
+ **NEVER on any card surface:** gradient backgrounds, glow effects, frosted glass (`backdrop-filter: blur`), decorative overlays, gradient borders, colored or tinted card backgrounds, inner shadows, patterned backgrounds, AI-aesthetic shimmer or particle effects. Never reach for shadow values directly — bind to a `semantic.elevation.*` role bundle so surface + shadow + border stay coherent.
166
+
167
+ ## Elevation roles
168
+
169
+ | Surface | Role token | Background | Shadow | Border |
170
+ | --- | --- | --- | --- | --- |
171
+ | Card / panel resting | `semantic.elevation.flat` | `surface.page` | none | `border.subtle` 1px |
172
+ | Card / panel lifted (interactive only) | `semantic.elevation.raised` | `surface.raised` | `shadow.subtle` | none |
173
+ | Popover / dropdown / tooltip | `semantic.elevation.floating` | `surface.raised` | `shadow.floating` | none |
174
+ | Dialog / sheet / modal | `semantic.elevation.overlay` | `surface.overlay` | `shadow.overlay` | none |
175
+
176
+ Cards default to `elevation.flat`. Popovers/tooltips/dropdowns use `elevation.floating`. Dialogs/sheets use `elevation.overlay`. Interactive cards lift to `elevation.raised` on hover. Never combine `raised` with a border — depth is one mechanism (border OR shadow), not both stacked.
177
+
178
+ Overlays (Dialog, AlertDialog, Menu, ContextMenu, Popover, Select, HoverCard, Tooltip) portal into the nearest `data-hds` scope, so they inherit its theme (for example `<div data-hds data-theme="dark">`); pass `container` on the Content part to override.
179
+
180
+ ## Slices And Full Bundle
181
+
182
+ Load only what the task needs. Same text as this file, split by topic:
183
+
184
+ - `public/llms/layout.txt` - screen layout recipe, card anatomy, elevation roles
185
+ - `public/llms/tokens.txt` - token rules and the quick token reference
186
+ - `public/llms/scroll.txt` - scroll-driven section recipe
187
+ - `public/llms/components.txt` - component inventory pointer, API pointer, props digest
188
+
189
+ - `public/llms-full.txt` - this file + the full `DESIGN.md` + a compact props digest for every component.
190
+
191
+ Paths in this file that begin with `docs/architecture/`, `src/app/components/`, `src/scroll/`, `src/stories/` or under `scripts/`, or that name `public/manifest.json`, `DESIGN-HANDOFF.md`, `TOKEN_GOVERNANCE.md` or `SYSTEMS_REGISTRY.md` exist only in the source repo, not in the npm package. Everything under "Default context" below ships in the package.
192
+
193
+ ## Context Loading Rules (Credit Efficiency)
194
+
195
+ Default context (load first):
196
+
197
+ - `public/llms.txt`
198
+ - `public/hds-manifest.json`
199
+ - `src/app/data/component-api.json`
200
+ - `hirobius.tokens.json`
201
+ - `DESIGN.md`
202
+
203
+ On-demand only (load only if explicitly requested or the task clearly requires it):
204
+
205
+ - `DESIGN-HANDOFF.md`
206
+ - `TOKEN_GOVERNANCE.md`
207
+ - `SYSTEMS_REGISTRY.md`
208
+
209
+ ## Pattern Inventory
210
+
211
+ - DataTableSection
212
+ - DestructiveSection
213
+ - FormActions
214
+ - MetricTiles
215
+ - PageHeader
216
+
217
+ ## Icons
218
+
219
+ Icons come from the curated subpath `@hirobius/design-system/icons`; nothing extra to install.
220
+
221
+ ```tsx
222
+ import { IconButton } from '@hirobius/design-system';
223
+ import { Ellipsis } from '@hirobius/design-system/icons';
224
+
225
+ <IconButton icon={Ellipsis} label="Row actions" />
226
+ ```
227
+
228
+ Rule: icon-only actions (row menus, close, edit) use `IconButton`; do not hand-roll a button with a glyph or text "...".
229
+
230
+ Names: Archive, ArrowDown, ArrowLeft, ArrowRight, ArrowUp, Bell, Bookmark, Calendar, Check, ChevronDown, ChevronLeft, ChevronRight, ChevronUp, CircleAlert, CircleCheck, CircleHelp, Clock, Copy, Download, Ellipsis, EllipsisVertical, ExternalLink, Eye, EyeOff, FileText, Funnel, Heart, House, Image, Info, Link, Lock, LogIn, LogOut, Mail, Menu, Minus, Pencil, Plus, RefreshCw, Save, Search, Settings, Share, Star, Trash2, TriangleAlert, Upload, User, X
231
+
232
+ Legacy names map to canonical ones: MoreHorizontal -> Ellipsis, MoreVertical -> EllipsisVertical, AlertTriangle -> TriangleAlert, Home -> House, Filter -> Funnel.
233
+
234
+ Name collisions: `Calendar` and `Menu` share names with HDS components; alias the icon: `import { Calendar as CalendarIcon, Menu as MenuIcon } from '@hirobius/design-system/icons'`. For an icon outside the set, install `lucide-react@0.487.0` (same version keeps the `LucideIcon` type identical).
235
+
236
+ ## Token Rules
237
+
238
+ - Component inventory: read `public/hds-manifest.json`. Do not duplicate inventories in markdown.
239
+ - Component prop API: read `src/app/data/component-api.json`. Do not inline prop tables in `llms.txt`.
240
+ - Token source of truth: read `hirobius.tokens.json` (W3C DTCG). Prefer `semantic.*` and `component.*` tokens over `primitive.*` for product UI.
241
+ - CSS variables: token path `semantic.color.surface.page` maps to `var(--semantic-color-surface-page)` (see generated token refs).
242
+ - Docs: use `DESIGN.md` as the default lean visual spec. Load `DESIGN-HANDOFF.md` only on-demand.
243
+ - Load `TOKEN_GOVERNANCE.md` and `SYSTEMS_REGISTRY.md` only on-demand (when explicitly requested or required by the task).
244
+ - Read `public/llms.txt` before touching code so AI workflows start from the same system map as humans.
245
+
246
+ ## Agent Workflow
247
+
248
+ 1. Read `public/llms.txt` and the relevant source files.
249
+ 2. Check `public/hds-manifest.json` for component metadata and phase status.
250
+ 3. Check `src/app/data/component-api.json` for prop names, unions, defaults, and descriptions.
251
+ 4. Use `hirobius.tokens.json` (and generated CSS vars) for styling decisions, never raw hex or ad hoc values.
252
+ 5. Run `pnpm tokens:audit` or `pnpm build` after changes that affect docs, tokens, or manifests.
253
+
254
+ ## Key Files
255
+
256
+ - `public/hds-manifest.json` - canonical machine-readable system inventory, metadata, and token snapshot
257
+ - `src/app/data/component-api.json` - generated prop reference (source of truth for prop docs)
258
+ - `hirobius.tokens.json` - token source of truth (W3C DTCG)
259
+ - `public/llms.txt` - machine-readable AI context index
260
+ - `DESIGN.md` - lean agent-facing visual spec (default)
261
+ - `DESIGN-HANDOFF.md` - verbose visual language mirror (on-demand only)
262
+
263
+ ---
264
+
265
+ # DESIGN.md (full)
266
+
267
+ <!-- GENERATED FILE — DO NOT EDIT. Source: DESIGN.source.md. Regenerate with `pnpm tokens`. -->
268
+
269
+ # DESIGN.md
270
+
271
+ A machine- and human-readable specification of the Hirobius Design System for AI agents, design tools, and humans generating or reviewing UI. Values are sourced from `hirobius.tokens.json`; narrative rules are hand-authored. For the full tokens reference see `DESIGN-HANDOFF.md`.
272
+
273
+ ## Overview
274
+
275
+ Hirobius is a clean, systems-first visual language that bridges digital precision and physical fabrication through a high-contrast monochromatic palette and a single accent that each tenant sets — neutral by default (#208). Its personality is disciplined, tactile, and quietly technical: structure is explicit, motion is purposeful, and visual noise is stripped away. Whitespace is treated as material, not leftover space, so every screen should feel deliberate, breathable, and exact.
276
+
277
+ ## Colors
278
+
279
+ <!-- auto:start:colors -->
280
+ **One accent — one neutral system.**
281
+
282
+ - **Accent** (`#111111`): CTAs, active states, selected focus rings, and the single brand accent. `semantic.accent.rest` — a per-tenant knob, not a fixed hue (#208).
283
+ - **Neutral**: backgrounds, surfaces, borders, text. True monochromatic — `primitive.color.neutral.50` through `950`. Use `semantic.color.surface.*`, `semantic.color.content.*`, `semantic.color.border.*`; never reach directly for primitives in components.
284
+ - **Feedback — Error** (`#B91C1C`): destructive confirms, error banners, validation failures. `semantic.color.feedback.error`.
285
+ - **Feedback — Success** (`#047857`): positive confirmations, completed states. `semantic.color.feedback.success`.
286
+ - **Feedback — Warning** (`#92400E`): cautions, recoverable issues. `semantic.color.feedback.warning`.
287
+ - **Feedback — Info** (`#1E2EFD`): neutral announcements and inline guidance. `semantic.color.feedback.info`.
288
+
289
+ Feedback hues are never decorative; do not use them as accents. Light and dark mode values are defined per-token in `hirobius.tokens.json`.
290
+ <!-- auto:end:colors -->
291
+
292
+ ## Typography
293
+
294
+ <!-- auto:start:typography -->
295
+ HDS ships three typefaces — each with a distinct and exclusive role:
296
+
297
+ - **Display / Heading font**: Satoshi. Bound exclusively to `display`, `h1`, `h2`, and `h3` styles. Never used for body copy or UI labels.
298
+ - **Body / UI font**: Satoshi. All prose, labels, small text, captions, and UI copy.
299
+ - **Mono font**: Geist Mono. Reserved for tokens, code, technical callouts, and metric readouts.
300
+
301
+ Weights declared: `400` regular, `500` medium, `700` bold. Heading styles (display · h1 · h2 · h3) use `700` bold; body, UI, and caption use `500` medium. Declared but unused by any semantic role: `400` regular.
302
+
303
+ ### Type ramp
304
+
305
+ | Role | Size (desktop max) | Weight | Use |
306
+ | --- | --- | --- | --- |
307
+ | `semantic.typography.display` | 60px | 700 | Display headline |
308
+ | `semantic.typography.h1` | 48px | 700 | Primary section headings (h1) |
309
+ | `semantic.typography.h2` | 30px | 700 | Secondary section headings (h2) |
310
+ | `semantic.typography.h3` | 20px | 700 | Component and card headers (h3) |
311
+ | `semantic.typography.body` | 16px | 500 | Body prose |
312
+ | `semantic.typography.ui` | 14px | 500 | UI text for nav, labels, captions |
313
+ | `semantic.typography.caption` | 12px | 500 | Caption / helper text |
314
+ | `semantic.typography.eyebrow` | 12px | 500 | Eyebrow / kicker label |
315
+ | `semantic.typography.mono` | 14px | 400 | Monospace for code, token names, shortcuts |
316
+ | `semantic.typography.lineHeight.none` | | | Semantic alias for leading-none (1) |
317
+
318
+ > Responsive `clamp()` overrides live in `src/styles/theme.css`; tokens store the desktop-max static value.
319
+ <!-- auto:end:typography -->
320
+
321
+ ## Spacing
322
+
323
+ <!-- auto:start:spacing -->
324
+ **Base unit: 4px.** All spacing snaps to the primitive scale; never introduce half-steps or arbitrary px values.
325
+
326
+ Scale: `0px` (`primitive.space.0`) · `1px` (`primitive.space.px1`) · `2px` (`primitive.space.px2`) · `4px` (`primitive.space.1`) · `6px` (`primitive.space.px6`) · `8px` (`primitive.space.2`) · `10px` (`primitive.space.px10`) · `12px` (`primitive.space.3`) · `16px` (`primitive.space.4`) · `20px` (`primitive.space.5`) · `24px` (`primitive.space.6`) · `28px` (`primitive.space.7`) · `32px` (`primitive.space.8`) · `40px` (`primitive.space.10`) · `48px` (`primitive.space.12`) · `64px` (`primitive.space.16`) · `80px` (`primitive.space.20`) · `96px` (`primitive.space.24`) · `128px` (`primitive.space.32`)
327
+
328
+ Use `primitive.space.*` for layout rhythm, padding, and gaps. Use `semantic.space.*` aliases (e.g. `semantic.space.surface.padding`) when the purpose is established. `data-density="compact"` (on `<html>` or the `[data-hds]` scope element) remaps `semantic.space.scale.*`, `semantic.space.surface.padding` and `semantic.space.region.gutter` one step down the scale, and `Table` follows it. The `--hds-space-{xs…4xl}` vars are a legacy bridge that no component reads.
329
+ <!-- auto:end:spacing -->
330
+
331
+ ## Corner-Radius Policy
332
+
333
+ Shape is one knob. `semantic.radius.action` is the system's single shape value — interactive controls (buttons, inputs, badges, alerts, segmented items) all resolve to it, and Tailwind's `rounded-md` maps to it exactly so the utility and the token cannot disagree. Containers sit one step above at `rounded-lg` (`action + 4px`); `rounded-sm` (`action - 2px`) is for chrome nested inside a control. `full` is reserved for pills and circular forms, and `0px` only for intentional outer canvas or substrate boundaries, never everyday UI controls. Reshaping the whole system means overriding `role.radius` in one tenant overlay — that is how `brutalist-demo` goes square in a single value.
334
+
335
+ <!-- auto:start:radius -->
336
+ | Tier | Value | Token | Applies to |
337
+ | --- | --- | --- | --- |
338
+ | Action | `8px` | `semantic.radius.action` | Buttons, inputs, badges, alerts, disclosures, segmented control items |
339
+ | Container | `12px` | `role.radius` + 4px (`rounded-lg`) | Cards, surfaces, segmented control surface, modal/sheet containers |
340
+ | Full | `9999px` | `primitive.radius.full` | Pills, avatars, indicator dots, any intentionally circular form |
341
+ | Zero | `0px` | `primitive.radius.0` | Outer canvas / substrate boundaries only — never on everyday UI controls |
342
+ <!-- auto:end:radius -->
343
+
344
+ ## Elevation
345
+
346
+ Depth is communicated through 4 elevation roles bundled by `semantic.elevation.*`. Each role bundles a surface, shadow, and border so primitives can't mismatch them.
347
+
348
+ ### Elevation roles
349
+
350
+ | Surface | Role token | Background | Shadow | Border |
351
+ | -------------------------------------- | ----------------------------- | ----------------- | ----------------- | ------------------- |
352
+ | Card / panel resting | `semantic.elevation.flat` | `surface.page` | none | `border.subtle` 1px |
353
+ | Card / panel lifted (interactive only) | `semantic.elevation.raised` | `surface.raised` | `shadow.subtle` | none |
354
+ | Popover / dropdown / tooltip | `semantic.elevation.floating` | `surface.raised` | `shadow.floating` | none |
355
+ | Dialog / sheet / modal | `semantic.elevation.overlay` | `surface.overlay` | `shadow.overlay` | none |
356
+
357
+ Cards default to `flat`. They lift to `raised` only on interactive hover or when explicitly elevated above siblings. Never combine `raised` with a border — depth is one mechanism (border OR shadow), not both stacked.
358
+
359
+ Overlays (Dialog, AlertDialog, Menu, ContextMenu, Popover, Select, HoverCard, Tooltip) portal into the nearest `data-hds` scope, so they inherit its theme (for example `<div data-hds data-theme="dark">`); pass `container` on the Content part to override.
360
+
361
+ ## Motion
362
+
363
+ <!-- auto:start:motion -->
364
+ Motion (lift on hover, parallax) is the interaction-affordance layer; static depth comes from the `semantic.elevation.*` role-token bundles.
365
+
366
+ ### Duration tiers
367
+
368
+ | Tier | Value | When to use |
369
+ | --- | --- | --- |
370
+ | `primitive.duration.instant` | `100ms` | Immediate dismissals, binary toggles |
371
+ | `primitive.duration.short` | `150ms` | Productive micro-interactions (default for hover/focus/press) |
372
+ | `primitive.duration.medium` | `250ms` | Expressive entrances, teaching moments |
373
+ | `primitive.duration.long` | `400ms` | Spatial movement, page travel, parallax |
374
+
375
+ ### Semantic intents
376
+
377
+ | Intent | Duration | Purpose |
378
+ | --- | --- | --- |
379
+ | `semantic.motion.productive` | `150ms` | For micro-interactions and status changes. No deformation. |
380
+ | `semantic.motion.expressive` | `250ms` | For teaching moments and significant UI entries. Includes physics-based squish. |
381
+ | `semantic.motion.spatial` | `400ms` | For elements traveling long distances across the viewport. |
382
+ | `semantic.motion.exit` | `100ms` | For elements being removed from the DOM. |
383
+
384
+ Default most interactive feedback to `productive` (150ms, decelerate). Reserve `expressive` (250ms, spring) for teaching moments where the motion itself carries meaning. `spatial` (400ms) is for travel, not decoration.
385
+
386
+ ### Other semantic motion tokens
387
+
388
+ | Token | Value | Purpose |
389
+ | --- | --- | --- |
390
+ | `semantic.motion.distance` | `24px` | Travel distance for a scroll-reveal translateY offset. Coincides in value with semantic.space.scale.md today, but names a motion travel distance rather than a spacing tier (hds#242). |
391
+ <!-- auto:end:motion -->
392
+
393
+ ## Components
394
+
395
+ <!-- auto:start:components -->
396
+ | Component | Radius | States | Guidance |
397
+ | --- | --- | --- | --- |
398
+ | **Buttons** (`Button`) | `8px` (`semantic.radius.action`) | default · hover · focus · active · disabled · loading | Three variants: primary (accent-filled), secondary (outline), tertiary (ghost). Primary uses `semantic.accent.*` ramp per state. Icon buttons (`IconButton`) follow the same token surface. Icon-only actions use `IconButton` with an icon from `@hirobius/design-system/icons`. |
399
+ | **Inputs** (`Input`) | `8px` (`semantic.radius.action`) | default · focus · filled · error · disabled · loading | Border-driven treatment; no filled background by default. Focus uses `semantic.color.border.accent` plus a 2px outline offset. Error swaps to `component.input.borderError`. |
400
+ | **Cards** (`Card`) | `12px` (`rounded-lg`, role radius + 4px) | default · hover (optional parallax) · pressed (when interactive) | Cards default to `elevation.flat` (1px border `border.subtle`, no shadow). Interactive cards lift to `elevation.raised` (shadow.subtle, no border) on hover. Bind via `semantic.elevation.{role}` — never raw box-shadow values. Radius: `rounded-lg` (role radius + 4 px, follows the tenant knob) — never a hard-coded value. Padding: `var(--semantic-space-surface-padding)`. Title: `heading3`. Meta: `caption` + `var(--semantic-color-content-secondary)`. Hover (interactive): `scale(1.02)` transform + lift to raised. Never: gradients, glow, frosted glass, tinted surfaces, decorative overlays, or inner shadows. |
401
+ | **Badges** (`Badge`) | `8px` (`primitive.radius.4`) | neutral · accent · feedback (error/success/warning/info) | Single-line status markers. Feedback colors come from `semantic.color.feedback.*`. Never used as decorative chrome. |
402
+ | **Alerts** (`Alert`) | `8px` (via `hds.borderRadius.4`) | info · success · warning · error | Inline banner pattern with icon + message + optional action. Tone is carried by left-border color, not by tinted fills. |
403
+ | **Disclosures** (`Disclosure`) | `8px` (`hds.borderRadius.action`) | collapsed · expanded · hover · focus | Accordion primitive. Expansion uses `semantic.motion.productive`; no spring bounce. Dividers follow `semantic.color.border.subtle`. |
404
+ | **Toggles** (`Toggle`) | `full` (pill track + circular thumb) | off · on · focus · disabled | Accent-filled track in the on state; neutral track otherwise. Track + thumb transitions share `semantic.motion.productive`. |
405
+ | **Segmented Control** (`SegmentedControl`) | Outer `12px` · inner segments `8px` | rest · hover · selected · disabled | Selected segment fills with the accent; unselected segments are transparent. Use for 2–5 mutually exclusive options; beyond that, prefer `Select`. |
406
+
407
+ See `public/hds-manifest.json` and `src/app/data/component-api.json` for the full inventory and prop tables.
408
+ <!-- auto:end:components -->
409
+
410
+ ### Card Anatomy (mandatory — all properties non-negotiable)
411
+
412
+ Every HDS card surface must conform to this anatomy exactly. No creative interpretation is permitted on any of these properties.
413
+
414
+ | Property | Required value | Forbidden |
415
+ | ------------------------ | -------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------- |
416
+ | Background | `var(--semantic-color-surface-raised)` | Any gradient, tinted fill, or custom color |
417
+ | Border | `1px solid var(--semantic-color-border-default)` | `box-shadow` as an elevation substitute |
418
+ | Border radius | `rounded-lg` (`role.radius` + 4 px: 12 px by default, follows the tenant) | `var(--component-card-radius)`, `rounded-full`, or any hard-coded value |
419
+ | Padding | `var(--semantic-space-component-padding)` or `<HdsSurface padding="component">` | Raw pixel values or ad hoc insets |
420
+ | Shadow | Resting cards: none (`elevation.flat`). Interactive lifted state: `shadow.subtle` via `elevation.raised` | Raw `box-shadow` values, `drop-shadow`, glow, or any depth effect not bound to a role token |
421
+ | Title | `hds.typeStyles.heading3` / `<HdsText variant="heading3">` | Any other type style for the primary card heading |
422
+ | Subtitle / meta | `hds.typeStyles.caption` + `var(--semantic-color-content-secondary)` | Primary content color or body size for secondary text |
423
+ | Hover (interactive only) | `transform: scale(1.02)` | Background fill change, border color shift, or opacity fade on hover |
424
+
425
+ Never use on any card surface: gradient backgrounds, glow effects, frosted glass (`backdrop-filter: blur`), decorative overlays, gradient borders, colored or tinted backgrounds, inner shadows, patterned fills, shimmer or noise effects.
426
+
427
+ ## Screen Patterns
428
+
429
+ Five patterns sit above the primitives so that every screen is composed the same way. Import them from `@hirobius/design-system/patterns`.
430
+
431
+ ### Page title rule
432
+
433
+ Every screen has exactly one `PageHeader`. The page title is `heading2` (30px), a fixed size with no size prop; `level` changes only the DOM heading element. `display` and `h1` are reserved for marketing and landing surfaces and are never a screen title. Breadcrumb goes in the `breadcrumb` slot, one status `Badge` in `status`, screen-level actions in `actions`.
434
+
435
+ ### Which one, when
436
+
437
+ Pick by what the thing is. The first four rows are for a headline number or a state; the rest are for containers and sections.
438
+
439
+ | Component | Use it for | Use instead |
440
+ | -------------------- | ----------------------------------------------------------------------------- | ---------------------------------------------------------------------------- |
441
+ | `MetricTiles` | The default for any row of headline numbers on a screen. One fixed tile size. | Nothing: start here. |
442
+ | `Stat` | An inline number inside prose or a dense list. | `MetricTiles` when the number stands alone in a row of its own. |
443
+ | `Card.Metric` | A metric inside an existing `Card` only. | `MetricTiles` when there is no enclosing `Card`. |
444
+ | `StatusTile` | State with notes and a trailing badge, never a number. | `MetricTiles` when the tile is a number; `StatusTile` never carries a value. |
445
+ | `Card` | A titled or interactive content object (header, body, footer, or selectable). | `Surface` when there is no title and nothing to press. |
446
+ | `Surface` | A plain padded background around content that has no header of its own. | `Card` when the content is titled or interactive. |
447
+ | `DestructiveSection` | The one irreversible action on a screen, with an explanation and a confirm. | `FormActions` `destructive` slot for a delete beside a form's own buttons. |
448
+ | `DataTableSection` | A titled table with a toolbar, row actions and an empty state. | `Table` alone when there is no heading, toolbar or empty state to show. |
449
+
450
+ `Card` and `Surface` share one container radius, `rounded-lg` (`role.radius` + 4 px: 12 px by default, 4 px under `brutalist-demo`). Dialogs and alert dialogs use it too. Never read `--component-card-radius` for a container; it ignores the tenant.
451
+
452
+ `MetricTiles` has `min(tiles, 4)` columns, so a row never leaves an empty column, and every tile has one fixed min-height with the value in `heading2`, the label as an eyebrow and the sub line in `caption`. Its tone comes from the fixed feedback vocabulary: `neutral | success | warning | danger | info`.
453
+
454
+ ### Destructive and table sections
455
+
456
+ `DestructiveSection` is a titled danger zone with one danger `Button` that opens an `AlertDialog`; it never runs the action from the button itself, only from the dialog's confirm. Put it last on the screen, below the form. `DataTableSection` puts a `Table` under a heading and a toolbar slot. Row actions are consumer nodes in a trailing column, an empty `rows` array shows an `EmptyState`, and the table scrolls horizontally inside the section on narrow widths, so a caller never sets `minWidth`.
457
+
458
+ ### Form actions rule
459
+
460
+ `FormActions` puts the primary submit last in DOM order and right-most, with the secondary or cancel action immediately to its left. A destructive action goes on the far left, apart from the other two, and never to the right of the primary. The row is not sticky unless `sticky` is set.
461
+
462
+ ## Do's and Don'ts
463
+
464
+ - Don't invent new corner behavior for interactive controls; buttons, inputs, disclosures, and similar action surfaces should follow the shared action radius (`semantic.radius.action`).
465
+ - Don't introduce additional accent hues; Hirobius uses exactly one accent, resolved from `semantic.accent.rest`, over a true monochromatic neutral system. The accent is a per-tenant knob (#208) and defaults to neutral — read the token, never assume a hue.
466
+ - Don't tint neutrals warm or cool; greys should remain genuinely neutral and high-contrast.
467
+ - Don't reach for shadow values directly — bind to a `semantic.elevation.*` role so surface + shadow + border stay paired. Cards default to `flat` (border, no shadow). Popovers/tooltips/dropdowns use `floating`. Dialogs/sheets use `overlay`.
468
+ - Don't hardcode colors, spacing, radius, or typography values when governed tokens already exist.
469
+ - Don't crowd the canvas; if a layout feels compressed, remove complexity before removing breathing room.
470
+ - Don't default repeated roadmap, status, process, or overview groups to outlined cards; prefer open bands, section dividers, accent rails, tabs, disclosures, and whitespace. Cards are for genuinely discrete repeated objects, not the primary layout language.
471
+ - Don't sticker badges onto the ends of prose lines. Status and progress should live in a predictable metadata slot, rail, header zone, table column, or progress surface; badges are reserved for compact state markers where their placement is intentional.
472
+ - Don't add decorative illustration, ornamental icons, or trend-driven filler that lacks functional or structural purpose.
473
+ - Don't make motion playful or bouncy by default; movement should feel controlled, precise, and intentional, with expressive motion used sparingly and only when it teaches or clarifies.
474
+ - Don't add `whileTap` scale transforms for press feedback; use color, border, and state-contrast changes instead — transforms are reserved for spatial motion, not interaction acknowledgment.
475
+ - Don't define a global disabled-state rule (opacity multiplier, saturation ramp, etc.); disabled presentation is governed per-component through its dedicated disabled tokens.
476
+
477
+ ## Open Questions
478
+
479
+ Unresolved rules that the live repo cannot yet answer confidently are tracked in [`OPEN_DS_QUESTIONS.md`](OPEN_DS_QUESTIONS.md). Do not invent rules here to fill those gaps.
480
+
481
+ <!-- auto:start:build-meta -->
482
+ ---
483
+
484
+ > Generated from `hirobius.tokens.json` (381 tokens) and `public/hds-manifest.json` by `scripts/build-design-md.mjs`.
485
+ > Hand-edit `DESIGN.source.md`; this file (`DESIGN.md`) is overwritten by `pnpm tokens`.
486
+ <!-- auto:end:build-meta -->
487
+
488
+ ---
489
+
490
+ ## Component Props Digest
491
+
492
+ Compact: name, first line of description, then prop: type = default. Full detail in `src/app/data/component-api.json`.
493
+
494
+ ### ActivityFeed
495
+ ActivityFeed — chronological system event log. Renders a list of activity events using white space as the sole separator. No dividers, no borders between items…
496
+ - events: ActivityEvent[] = [ { id: 'evt-001', title: 'File Uploade…
497
+
498
+ ### Alert
499
+ Alert - compact feedback surface with contextual severity.
500
+ - children: ReactNode
501
+ - title: string
502
+ - tone: 'success' | 'danger' | 'warning' | 'info' = info
503
+
504
+ ### AlertDialog
505
+ AlertDialog root + parts. Controlled via `open`/`onOpenChange`, or uncontrolled with `defaultOpen`.
506
+ - children: React.ReactNode
507
+ - defaultOpen: boolean
508
+ - onOpenChange: ((open: boolean) => void)
509
+ - open: boolean
510
+
511
+ ### AspectRatio
512
+ Locks its single child to the given width-to-height `ratio` so media reserves its box up front and never causes layout shift while it loads.
513
+ - asChild: boolean
514
+ - ratio: number = 1
515
+
516
+ ### AssetImg
517
+ AssetImg - responsive asset frame with fallback placeholder handling. Contexts: default, lightbox, and detail.
518
+ - alt: string
519
+ - className: string
520
+ - context: 'default' | 'lightbox' | 'detail' = default
521
+ - draggable: boolean = false
522
+ - expandable: boolean = true
523
+ - expandLabel: string
524
+ - isDark: boolean = false
525
+ - loading: "lazy" | "eager" = lazy
526
+ - naturalHeight: number
527
+ - naturalWidth: number
528
+ - onClick: ((e: MouseEvent<Element, MouseEvent>) => void)
529
+ - onMouseDown: ((e: MouseEvent<Element, MouseEvent>) => void)
530
+ - onMouseLeave: ((e: MouseEvent<Element, MouseEvent>) => void)
531
+ - onMouseMove: ((e: MouseEvent<Element, MouseEvent>) => void)
532
+ - onMouseUp: ((e: MouseEvent<Element, MouseEvent>) => void)
533
+ - src: string
534
+ - style: CSSProperties = {}
535
+ - title: string
536
+
537
+ ### Avatar
538
+ Circular avatar. Renders the image when available, else initials from `alt`.
539
+ - alt: string
540
+ - initials: string
541
+ - size: "sm" | "md" | "lg" | null
542
+ - src: string
543
+
544
+ ### AvatarGroup
545
+ Renders up to `max` overlapping avatars followed by a `+N` overflow chip.
546
+ - children: ReactNode
547
+ - max: number
548
+ - size: "sm" | "md" | "lg" | null
549
+
550
+ ### Badge
551
+ Compact metadata/status chip. Tone is the only styling input.
552
+ - as: ElementType<any, keyof IntrinsicElements> = span
553
+ - tone: "neutral" | "danger" | "success" | "warning" | "info" | "inProgress" | null
554
+
555
+ ### Bleed
556
+ Bleed — controlled negative-margin full-bleed within a padded container. Every Layout reference: https://every-layout.dev/layouts/the-stack/ (bleed is the inve…
557
+ - amount: 'tight' | 'normal' | 'inset' | 'spacious' = normal
558
+ - as: ElementType<any, keyof IntrinsicElements> = div
559
+ - axis: 'x' | 'y' | 'both' = x
560
+ - children: ReactNode
561
+ - className: string
562
+ - style: CSSProperties
563
+
564
+ ### Blockquote
565
+ A quoted passage; pass `cite` for the source URL and `attribution` for a byline.
566
+ - attribution: ReactNode
567
+ - size: "sm" | "md" | "lg" | null
568
+
569
+ ### Box
570
+ Box — polymorphic layout primitive with a token-first `sx` engine. `sx` is a deliberate SUBSET of MUI's sx — not all of CSS-in-JS is a feature: - Spacing short…
571
+ - as: ElementType<any, keyof IntrinsicElements> = div
572
+ - children: ReactNode
573
+ - sx: SxObject
574
+
575
+ ### Breadcrumb
576
+ Breadcrumb trail. Links route through the HDS router seam (plain anchors with no router, client-side nav when a router adapter is provided). The final item is …
577
+ - items: BreadcrumbItem[]
578
+ - label: string = Breadcrumb
579
+
580
+ ### Button
581
+ Triggers an action when activated.
582
+ - asChild: boolean = false
583
+ - disabled: boolean
584
+ - iconLeft: ReactNode
585
+ - iconOnly: boolean = false
586
+ - iconRight: ReactNode
587
+ - label: string
588
+ - loading: boolean = false
589
+ - size: "sm" | "md" | "lg" | null
590
+ - tone: "neutral" | "danger" | "success" | "warning" | "info" | null
591
+ - variant: "primary" | "secondary" | "tertiary" | null
592
+
593
+ ### ButtonGroup
594
+ Groups Button (or button-like) children into a single attached segment.
595
+ - orientation: "horizontal" | "vertical" | null
596
+
597
+ ### Calendar
598
+ Renders an accessible month grid; compose it inside a Popover for the date inputs.
599
+
600
+ ### Callout
601
+ Tone-driven side-rule callout for status, quotes, hypotheses.
602
+ - italic: boolean = false
603
+ - tone: 'accent' | 'info' | 'success' | 'warning' | 'danger' = info
604
+
605
+ ### Card
606
+ Tagged per-export, not on the file block: this module exports eight components and a file-level @figma would hand all eight this one node.
607
+ - as: ElementType<any, keyof IntrinsicElements>
608
+ - bordered: boolean = false
609
+ - gap: GapOption = tight
610
+ - noPadding: boolean = false
611
+ - padding: PaddingOption = component
612
+ - tone: 'neutral' | 'danger' | 'success' | 'warning' | 'info' = neutral
613
+ - variant: 'default' | 'accent' = default
614
+
615
+ ### CardBody
616
+ Card — surface container with slot anatomy (12d-card-anatomy). Slot anatomy (DESIGN.md §"Card Anatomy"). Status, progress, and metadata are layout-bearing — th…
617
+
618
+ ### CardDescription
619
+ Card — surface container with slot anatomy (12d-card-anatomy). Slot anatomy (DESIGN.md §"Card Anatomy"). Status, progress, and metadata are layout-bearing — th…
620
+
621
+ ### CardFooter
622
+ Card — surface container with slot anatomy (12d-card-anatomy). Slot anatomy (DESIGN.md §"Card Anatomy"). Status, progress, and metadata are layout-bearing — th…
623
+
624
+ ### CardHeader
625
+ Card — surface container with slot anatomy (12d-card-anatomy). Slot anatomy (DESIGN.md §"Card Anatomy"). Status, progress, and metadata are layout-bearing — th…
626
+ - metadata: ReactNode
627
+
628
+ ### CardMetric
629
+ Card.Metric — one uppercase label, a large value and an optional sub-line inside a Card.
630
+ - label: ReactNode
631
+ - sub: ReactNode
632
+ - tone: 'neutral' | 'danger' | 'success' | 'warning' | 'info' = neutral
633
+ - value: ReactNode
634
+
635
+ ### CardProgress
636
+ Card — surface container with slot anatomy (12d-card-anatomy). Slot anatomy (DESIGN.md §"Card Anatomy"). Status, progress, and metadata are layout-bearing — th…
637
+ - label: ReactNode
638
+ - max: number = 100
639
+ - tone: 'neutral' | 'danger' | 'success' | 'warning' | 'info' = neutral
640
+ - value: number
641
+
642
+ ### CardTitle
643
+ Card — surface container with slot anatomy (12d-card-anatomy). Slot anatomy (DESIGN.md §"Card Anatomy"). Status, progress, and metadata are layout-bearing — th…
644
+
645
+ ### Carousel
646
+ Renders children as a snap-scrolling track with Prev/Next scroll buttons.
647
+ - ariaLabel: string = Carousel
648
+ - children: ReactNode
649
+ - showControls: boolean = true
650
+
651
+ ### Center
652
+ Center — max-width column, auto-centered horizontally. Every Layout reference: https://every-layout.dev/layouts/center/
653
+ - as: ElementType<any, keyof IntrinsicElements> = div
654
+ - children: ReactNode
655
+ - className: string
656
+ - gutter: 'tight' | 'normal' | 'inset' | 'spacious'
657
+ - maxWidth: 'content' | 'max' = content
658
+ - style: CSSProperties
659
+
660
+ ### Checkbox
661
+ Checkbox — custom-drawn checkbox with check / indeterminate glyph.
662
+ - checked: boolean
663
+ - indeterminate: boolean = false
664
+ - label: string
665
+ - onChange: (v: boolean) => void
666
+
667
+ ### CinematicLink
668
+ CinematicLink - cinematic editorial link treatment for portfolio surfaces.
669
+ - children: string
670
+ - href: string
671
+
672
+ ### CircularProgress
673
+ A circular progress ring; pass `value`/`max` or set `indeterminate`.
674
+ - indeterminate: boolean = false
675
+ - label: string
676
+ - max: number = 100
677
+ - size: "sm" | "md" | "lg" = md
678
+ - tone: "neutral" | "danger" | "success" | "warning" | "info" | null
679
+ - value: number = 0
680
+
681
+ ### Cluster
682
+ Cluster — wrapping horizontal group with even gaps. Every Layout reference: https://every-layout.dev/layouts/cluster/
683
+ - align: 'start' | 'center' | 'end' | 'stretch' = center
684
+ - as: ElementType<any, keyof IntrinsicElements> = div
685
+ - children: ReactNode
686
+ - className: string
687
+ - gap: 'tight' | 'normal' | 'inset' | 'spacious' = tight
688
+ - justify: 'start' | 'center' | 'end' | 'space-between' = start
689
+ - style: CSSProperties
690
+
691
+ ### CodeBlock
692
+ CodeBlock - code display with copy button and optional collapsible toggle.
693
+ - className: string
694
+ - code: string
695
+ - collapsible: boolean = false
696
+ - defaultExpanded: boolean = false
697
+ - filename: string
698
+ - language: string
699
+ - truncateFromStart: boolean = false
700
+ - variant: "inline" | "block" = block
701
+
702
+ ### Combobox
703
+ Combobox — searchable single-select (Popover + filtered listbox). A select-with-search built on the HDS Popover. The trigger shows the current selection; openi…
704
+ - aria-label: string
705
+ - className: string
706
+ - disabled: boolean = false
707
+ - emptyMessage: string = No results
708
+ - onChange: (value: string) => void
709
+ - options: ComboboxOption[]
710
+ - placeholder: string = Select…
711
+ - searchPlaceholder: string = Search…
712
+ - value: string | null
713
+
714
+ ### CommandPalette
715
+ Mountable trigger + dialog. Drop into header slot; component manages its own open state and Cmd-K / Ctrl-K global keybinding.
716
+ - className: string
717
+
718
+ ### ComponentInstanceMatrix
719
+ ComponentInstanceMatrix — responsive specimen matrix for variant and state parity.
720
+ - componentName: string
721
+ - dimensionX: string
722
+ - dimensionY: string
723
+ - freezeRowState: boolean = false
724
+ - isMobile: boolean
725
+ - renderInstance: (rowKey: string, columnKey: string) => ReactNode
726
+ - rowLabelTone: "primary" | "secondary" = primary
727
+ - rowLabelWidth: number = 120
728
+ - title: string
729
+
730
+ ### Container
731
+ Container — semantic width-constrained layout. Centers content horizontally and applies semantic max-width constraints. - maxWidth options: 'content' (760px pr…
732
+ - children: ReactNode
733
+ - className: string
734
+ - maxWidth: 'content' | 'max' = max
735
+ - padding: string = var(--semantic-space-surface-padding)
736
+ - style: CSSProperties
737
+
738
+ ### ContextMenu
739
+ ContextMenu root + parts. Wrap the right-clickable area in `ContextMenu.Trigger`. Controlled via `onOpenChange`.
740
+ - children: React.ReactNode
741
+ - dir: ("ltr" | "rtl")
742
+ - modal: boolean
743
+ - onOpenChange: ((open: boolean) => void)
744
+ - open: boolean
745
+
746
+ ### Cover
747
+ Cover — vertical shell with an auto-centered main region. Every Layout reference: https://every-layout.dev/layouts/cover/
748
+ - as: ElementType<any, keyof IntrinsicElements> = div
749
+ - centerSlot: ReactNode
750
+ - children: ReactNode
751
+ - className: string
752
+ - footer: ReactNode
753
+ - gap: 'tight' | 'normal' | 'inset' | 'spacious' = normal
754
+ - header: ReactNode
755
+ - minHeight: string = 100svh
756
+ - style: CSSProperties
757
+
758
+ ### DataTableSection
759
+ Section heading and toolbar over a `Table`. Row actions are consumer nodes in a trailing column, the table scrolls horizontally on narrow widths without a `min…
760
+ - actionsLabel: string = Actions
761
+ - columns: TableColumn[]
762
+ - emptyDescription: ReactNode
763
+ - emptyTitle: ReactNode = Nothing here yet
764
+ - level: 2 | 3 | 4 | 5 | 6 = 2
765
+ - rows: DataTableSectionRow[]
766
+ - title: ReactNode
767
+ - toolbar: ReactNode
768
+
769
+ ### DateInput
770
+ Text field + calendar popover for picking a single date.
771
+ - aria-label: string
772
+ - disabled: boolean = false
773
+ - displayFormat: string = yyyy-MM-dd
774
+ - id: string
775
+ - onChange: ((date: Date) => void) | undefined
776
+ - placeholder: string
777
+ - value: Date
778
+
779
+ ### DateRangeInput
780
+ DateRangeInput — date-range field composing the existing Popover with Calendar in range mode, so picking a start/end date reads as one overlay pattern with Com…
781
+ - aria-label: string
782
+ - disabled: boolean = false
783
+ - displayFormat: string = yyyy-MM-dd
784
+ - id: string
785
+ - numberOfMonths: number = 2
786
+ - onChange: ((range: DateRange) => void) | undefined
787
+ - placeholder: string = Select date range
788
+ - value: DateRange
789
+
790
+ ### DateTimeInput
791
+ Text date field + calendar popover, paired with a native time field, producing one Date.
792
+ - aria-label: string
793
+ - dateFormat: string = yyyy-MM-dd
794
+ - disabled: boolean = false
795
+ - id: string
796
+ - onChange: ((date: Date) => void) | undefined
797
+ - value: Date
798
+
799
+ ### DestructiveSection
800
+ Titled danger zone: a title, an explanation, and one danger `Button` that opens an `AlertDialog`. Pressing the button never runs the action; only the dialog's …
801
+ - actionLabel: ReactNode
802
+ - cancelLabel: string = Cancel
803
+ - confirmBody: ReactNode
804
+ - confirmLabel: string
805
+ - description: ReactNode
806
+ - level: 2 | 3 | 4 | 5 | 6 = 2
807
+ - onConfirm: () => void
808
+ - title: ReactNode
809
+
810
+ ### Dialog
811
+ Tagged per-export, not on the file block: this module exports ten components and a file-level @figma would hand all ten this one node.
812
+ - children: ReactNode
813
+ - defaultOpen: boolean
814
+ - modal: boolean
815
+ - onOpenChange: ((open: boolean) => void)
816
+ - open: boolean
817
+
818
+ ### DialogClose
819
+ Dialog — modal dialog (shadcn baseline, compound parts). shadcn-baseline implementation (8s-7): Radix Dialog primitive (@radix-ui/react-dialog) themed with rol…
820
+ - asChild: boolean
821
+
822
+ ### DialogContent
823
+ Dialog — modal dialog (shadcn baseline, compound parts). shadcn-baseline implementation (8s-7): Radix Dialog primitive (@radix-ui/react-dialog) themed with rol…
824
+ - asChild: boolean
825
+ - container: HTMLElement | null
826
+ - forceMount: true
827
+ - hideClose: boolean = false
828
+ - onCloseAutoFocus: ((event: Event) => void)
829
+ - onEscapeKeyDown: ((event: KeyboardEvent) => void)
830
+ - onFocusOutside: ((event: CustomEvent<{ originalEvent: FocusEvent; }>) => void)
831
+ - onInteractOutside: ((event: CustomEvent<{ originalEvent: PointerEvent; }> | CustomEvent<{ original…
832
+ - onOpenAutoFocus: ((event: Event) => void)
833
+ - onPointerDownOutside: ((event: CustomEvent<{ originalEvent: PointerEvent; }>) => void)
834
+
835
+ ### DialogDescription
836
+ Dialog — modal dialog (shadcn baseline, compound parts). shadcn-baseline implementation (8s-7): Radix Dialog primitive (@radix-ui/react-dialog) themed with rol…
837
+ - asChild: boolean
838
+
839
+ ### DialogFooter
840
+ Dialog — modal dialog (shadcn baseline, compound parts). shadcn-baseline implementation (8s-7): Radix Dialog primitive (@radix-ui/react-dialog) themed with rol…
841
+
842
+ ### DialogHeader
843
+ Dialog — modal dialog (shadcn baseline, compound parts). shadcn-baseline implementation (8s-7): Radix Dialog primitive (@radix-ui/react-dialog) themed with rol…
844
+
845
+ ### DialogOverlay
846
+ Dialog — modal dialog (shadcn baseline, compound parts). shadcn-baseline implementation (8s-7): Radix Dialog primitive (@radix-ui/react-dialog) themed with rol…
847
+ - asChild: boolean
848
+ - forceMount: true
849
+
850
+ ### DialogPortal
851
+ Dialog — modal dialog (shadcn baseline, compound parts). shadcn-baseline implementation (8s-7): Radix Dialog primitive (@radix-ui/react-dialog) themed with rol…
852
+ - children: React.ReactNode
853
+ - container: Element | DocumentFragment | null
854
+ - forceMount: true
855
+
856
+ ### DialogTitle
857
+ Dialog — modal dialog (shadcn baseline, compound parts). shadcn-baseline implementation (8s-7): Radix Dialog primitive (@radix-ui/react-dialog) themed with rol…
858
+ - asChild: boolean
859
+
860
+ ### DialogTrigger
861
+ Dialog — modal dialog (shadcn baseline, compound parts). shadcn-baseline implementation (8s-7): Radix Dialog primitive (@radix-ui/react-dialog) themed with rol…
862
+ - asChild: boolean
863
+
864
+ ### Disclosure
865
+ Disclosure - compact disclosure surface for optional explanatory content.
866
+ - accent: boolean = false
867
+ - children: ReactNode
868
+ - className: string
869
+ - contentStyle: CSSProperties
870
+ - defaultOpen: boolean = false
871
+ - label: ReactNode
872
+ - onOpenChange: ((open: boolean) => void)
873
+ - open: boolean
874
+ - triggerStyle: CSSProperties
875
+ - variant: 'panel' | 'nav' | 'card' = panel
876
+
877
+ ### Divider
878
+ Divider — semantic separator between content regions.
879
+ - orientation: "horizontal" | "vertical" | null = horizontal
880
+ - spacing: string | number
881
+ - strong: boolean
882
+ - variant: "strong" | "default" | null
883
+
884
+ ### DocLinkCard
885
+ DocLinkCard - navigation card for editorial and documentation cross-links.
886
+ - accent: boolean = false
887
+ - affordance: "up-right" | "right" | "left" = up-right
888
+ - description: string
889
+ - disabled: boolean = false
890
+ - href: string
891
+ - icon: LucideIcon
892
+ - meta: string
893
+ - metaStyle: "caption" | "ui" = caption
894
+ - title: string
895
+ - variant: "feature" | "pager" = feature
896
+
897
+ ### EmptyState
898
+ EmptyState — consistent no-data placeholder for lists, grids, and sections.
899
+ - className: string
900
+ - description: ReactNode
901
+ - title: ReactNode
902
+
903
+ ### Field
904
+ Caption label paired with a value — used in metadata grids and read-only forms.
905
+ - children: React.ReactNode
906
+ - label: string
907
+ - mono: boolean | null
908
+ - tone: "neutral" | "danger" | "success" | "warning" | "info" | null
909
+ - value: ReactNode
910
+
911
+ ### FileInput
912
+ A dashed dropzone that opens the native file picker or accepts a drag-and-drop.
913
+ - accept: string
914
+ - disabled: boolean
915
+ - label: ReactNode = Click to upload or drag and drop
916
+ - multiple: boolean
917
+ - onFiles: ((files: File[]) => void)
918
+
919
+ ### Form
920
+ Styled `<form>` with consistent vertical field rhythm. Tagged per-export: FormField and FormFieldShell share this module and have no Figma node, so a file-leve…
921
+
922
+ ### FormActions
923
+ Form footer with one fixed order: destructive (far left, if any), then secondary, then primary last and right-most. Gap is the tight layout token.
924
+ - destructive: ReactNode
925
+ - primary: ReactNode
926
+ - secondary: ReactNode
927
+ - sticky: boolean = false
928
+
929
+ ### FormField
930
+ Label + description + error wrapper that wires the a11y relationships onto its single child control via cloneElement. Validation-library agnostic — pass `error…
931
+ - children: ReactElement<any, string | JSXElementConstructor<any>>
932
+ - className: string
933
+ - description: string
934
+ - error: string
935
+ - htmlFor: string
936
+ - label: string
937
+ - required: boolean = false
938
+
939
+ ### FormFieldShell
940
+ Presentational label + control slot + helper/error markup. Renders `children` verbatim — it does NOT clone — so it is safe to use with controls that own a call…
941
+ - children: ReactNode
942
+ - className: string
943
+ - controlId: string
944
+ - description: string
945
+ - error: string
946
+ - label: string
947
+ - required: boolean = false
948
+
949
+ ### FoundationSwatch
950
+ FoundationSwatch - governed foundation specimen for color and semantic role previews.
951
+ - background: string
952
+ - bordered: boolean = false
953
+ - details: string[]
954
+ - foreground: string = var(--semantic-color-content-primary)
955
+ - hidePreviewLabel: boolean = false
956
+ - label: string
957
+ - note: ReactNode
958
+ - previewPosition: 'bottom-left' | 'top-left' | 'center' = center
959
+ - specimen: ReactNode
960
+ - swatchVar: string
961
+ - tokenDisplayPreset: 'depth1' | 'depth2' | 'full' = depth2
962
+ - tokenPath: string
963
+ - value: string
964
+
965
+ ### Frame
966
+ Frame — aspect-ratio-locked, token-clipped media box. Every Layout reference: https://every-layout.dev/layouts/frame/
967
+ - as: ElementType<any, keyof IntrinsicElements> = div
968
+ - children: ReactNode
969
+ - className: string
970
+ - radius: 'none' | 'sm' | 'md' | 'full' = md
971
+ - ratio: number = 16 / 9
972
+ - style: CSSProperties
973
+
974
+ ### Grid
975
+ Grid — responsive grid composition primitive. Enforces semantic gap and column values. No arbitrary CSS grid. - layout='fixed': responsive base (collapses via …
976
+ - as: ElementType<any, keyof IntrinsicElements> = div
977
+ - children: ReactNode
978
+ - className: string
979
+ - columns: number = 12
980
+ - gap: 'tight' | 'normal' | 'inset' | 'spacious' = inset
981
+ - layout: 'fixed' | 'auto-fit' = fixed
982
+ - style: CSSProperties
983
+ - subgrid: boolean = false
984
+
985
+ ### HdsDocsShell
986
+ HdsDocsShell — three-region docs shell (left nav rail, content, right TOC rail), driven by grid columns that default to 0 and are set per breakpoint. hds#280 s…
987
+ - children: ReactNode
988
+ - className: string
989
+ - leftRail: ReactNode
990
+ - rightRail: ReactNode
991
+ - style: CSSProperties
992
+ - topOffset: string = 0px
993
+
994
+ ### HdsThemeProvider
995
+ Renders a `data-hds` scope wrapper that carries the four theming dials as root attributes + CSS vars, and exposes them to `useHdsTheme()`.
996
+ - as: ElementType<any, keyof IntrinsicElements> = div
997
+ - brand: string
998
+ - children: React.ReactNode
999
+ - className: string
1000
+ - density: 'comfortable' | 'compact'
1001
+ - fontFamily: string
1002
+ - fontFamilyMono: string
1003
+ - style: CSSProperties
1004
+ - theme: 'light' | 'dark'
1005
+
1006
+ ### HeadingStack
1007
+ HeadingStack — enforced vertical rhythm for heading + subheading pairs. Automatically handles gap and secondary color, preventing manual stacking. - Heading le…
1008
+ - as: ElementType = div
1009
+ - gap: HdsHeadingGap = px8
1010
+ - heading: string
1011
+ - headingAs: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6'
1012
+ - level: HdsHeadingLevel
1013
+ - subheading: string
1014
+ - subheadingAs: 'p' | 'div' | 'span' = p
1015
+
1016
+ ### HoverCard
1017
+ HoverCard root + parts. Controlled via `open`/`onOpenChange`, or uncontrolled with `defaultOpen`; tune timing with `openDelay`/`closeDelay`.
1018
+ - children: React.ReactNode
1019
+ - closeDelay: number
1020
+ - defaultOpen: boolean
1021
+ - onOpenChange: ((open: boolean) => void)
1022
+ - open: boolean
1023
+ - openDelay: number
1024
+
1025
+ ### Icon
1026
+ Icon — semantic icon wrapper for Lucide icons.
1027
+ - aria-hidden: boolean | "true" | "false" = true
1028
+ - className: string
1029
+ - color: string = currentColor
1030
+ - icon: LucideIcon
1031
+ - size: IconSize = small
1032
+ - style: CSSProperties
1033
+ - weight: "fill" | "bold" | "light" | "thin" | "regular" | "duotone"
1034
+
1035
+ ### IconButton
1036
+ IconButton ” icon-only action trigger built on the shared Button primitive.
1037
+ - aria-label: string
1038
+ - asChild: boolean
1039
+ - disabled: boolean
1040
+ - icon: LucideIcon
1041
+ - iconColor: string
1042
+ - iconLeft: ReactNode
1043
+ - iconRight: ReactNode
1044
+ - iconSize: IconSize
1045
+ - label: string
1046
+ - loading: boolean
1047
+ - size: "sm" | "md" | "lg"
1048
+ - tone: "neutral" | "danger" | "success" | "warning" | "info" | null
1049
+ - variant: "primary" | "secondary" | "tertiary" | null
1050
+
1051
+ ### InlineCode
1052
+ InlineCode — inline code chip for token paths, file paths, and code-adjacent prose.
1053
+ - children: ReactNode
1054
+ - compact: boolean
1055
+ - copyable: boolean = false
1056
+ - density: "comfortable" | "compact" | null
1057
+ - style: CSSProperties
1058
+
1059
+ ### InlineLink
1060
+ InlineLink ” inline navigation and external-link primitive for body copy.
1061
+ - children: ReactNode
1062
+ - externalIcon: boolean = true
1063
+ - href: string
1064
+
1065
+ ### Input
1066
+ Input — text field primitive with label, helper, and error slots.
1067
+ - className: string
1068
+ - disabled: boolean
1069
+ - error: boolean
1070
+ - errorMessage: string
1071
+ - helperText: string
1072
+ - inputClassName: string
1073
+ - label: string
1074
+ - leadingVisual: ReactNode
1075
+ - loading: boolean = false
1076
+ - size: InputSize = md
1077
+ - textStyle: "body" | "mono" = body
1078
+ - trailingVisual: ReactNode
1079
+ - type: 'text' | 'email' | 'password' | 'search' | 'tel' | 'url' | 'number' = text
1080
+
1081
+ ### InputGroup
1082
+ A single-line input with optional `leading`/`trailing` adornments.
1083
+ - className: string
1084
+ - leading: ReactNode
1085
+ - size: "sm" | "md" | "lg" | null
1086
+ - trailing: ReactNode
1087
+
1088
+ ### Kbd
1089
+ Renders a keyboard key or shortcut token, e.g. `<Kbd>⌘K</Kbd>`.
1090
+ - size: "sm" | "md" | "lg" | null
1091
+
1092
+ ### Lightbox
1093
+ Lightbox — full-bleed image viewer built on Radix Dialog. Full-bleed image viewer built on Radix Dialog (raw primitives, not the card `Dialog` wrapper — a ligh…
1094
+ - alt: string
1095
+ - caption: string
1096
+ - captionHref: string
1097
+ - captionLabel: string
1098
+ - naturalHeight: number
1099
+ - naturalWidth: number
1100
+ - onClose: () => void
1101
+ - open: boolean
1102
+ - src: string
1103
+
1104
+ ### Menu
1105
+ Menu root + parts. Controlled via `open`/`onOpenChange`, or uncontrolled with `defaultOpen`.
1106
+ - children: React.ReactNode
1107
+ - defaultOpen: boolean
1108
+ - dir: ("ltr" | "rtl")
1109
+ - modal: boolean
1110
+ - onOpenChange: ((open: boolean) => void)
1111
+ - open: boolean
1112
+
1113
+ ### MetadataList
1114
+ Renders object metadata as a semantic `<dl>` of term/description pairs.
1115
+ - footer: ReactNode
1116
+ - items: MetadataListItem[]
1117
+ - orientation: "horizontal" | "vertical" | null = vertical
1118
+ - variant: "plain" | "divided" = plain
1119
+
1120
+ ### MetricTile
1121
+ One metric tile: eyebrow label, `heading2` value, caption sub line, on a raised surface at one fixed min-height. Wraps `Card.Metric` (the sibling with the eyeb…
1122
+ - label: ReactNode
1123
+ - sub: ReactNode
1124
+ - tone: 'neutral' | 'success' | 'warning' | 'danger' | 'info' = neutral
1125
+ - value: ReactNode
1126
+
1127
+ ### MetricTiles
1128
+ A row of `MetricTile`s. The grid has `min(tiles, 4)` columns, so three tiles fill three columns and never leave an empty fourth. The default for any row of hea…
1129
+ - children: ReactNode
1130
+
1131
+ ### MultiSelector
1132
+ MultiSelector — multi-select dropdown composing the existing Popover with a checkbox option list, so choosing several values from a fixed set reads as one over…
1133
+ - className: string
1134
+ - disabled: boolean = false
1135
+ - onChange: (next: string[]) => void
1136
+ - options: MultiSelectorOption[]
1137
+ - placeholder: string = Select…
1138
+ - value: string[]
1139
+
1140
+ ### NavGroup
1141
+ NavGroup - labeled navigation group for stacks of nav items.
1142
+ - children: ReactNode
1143
+ - className: string
1144
+ - collapsible: boolean = false
1145
+ - contentStyle: CSSProperties
1146
+ - getExact: ((item: NavItem) => boolean)
1147
+ - items: NavItem[]
1148
+ - label: string
1149
+ - level: NavLevel = section
1150
+ - onNavigate: (() => void)
1151
+ - style: CSSProperties
1152
+ - variant: 'side' | 'toc' = side
1153
+
1154
+ ### NavItem
1155
+ NavItem - navigation row primitive for sidebars, table of contents, and list navigation.
1156
+ - active: boolean = false
1157
+ - disabled: boolean = false
1158
+ - label: string
1159
+ - level: NavLevel = root
1160
+ - onNavigate: ((event: MouseEvent<HTMLAnchorElement, MouseEvent>) => void)
1161
+ - variant: NavVariant = side
1162
+
1163
+ ### OverflowList
1164
+ Renders up to `max` children followed by a `+N` overflow chip (or custom node).
1165
+ - children: ReactNode
1166
+ - max: number
1167
+ - renderOverflow: ((count: number) => ReactNode)
1168
+
1169
+ ### Page
1170
+ Page — standard page shell. Wraps page content in Container (width constraint) and applies the canonical vertical padding so content breathes against the viewp…
1171
+ - children: ReactNode
1172
+ - className: string
1173
+ - maxWidth: 'content' | 'max' = max
1174
+ - paddingY: 'default' | 'compact' | 'none' = default
1175
+ - style: CSSProperties
1176
+
1177
+ ### PageHeader
1178
+ Screen header: breadcrumb slot, the title at the one canonical page-title size (`heading2`), a status slot and an actions slot. Every screen has exactly one. `…
1179
+ - actions: ReactNode
1180
+ - breadcrumb: ReactNode
1181
+ - level: PageHeaderLevel = 1
1182
+ - status: ReactNode
1183
+ - title: ReactNode
1184
+
1185
+ ### Pagination
1186
+ Paged navigation with first/last anchors, sibling pages, and ellipses.
1187
+ - count: number
1188
+ - label: string = Pagination
1189
+ - onPageChange: (page: number) => void
1190
+ - page: number
1191
+ - siblingCount: number = 1
1192
+
1193
+ ### Pin
1194
+ Pin — sticky-pin an element within its scroll region.
1195
+ - as: ElementType<any, keyof IntrinsicElements> = div
1196
+ - children: ReactNode
1197
+ - className: string
1198
+ - style: CSSProperties
1199
+ - top: string = 0
1200
+
1201
+ ### Popover
1202
+ Popover root + parts. Controlled via `open`/`onOpenChange`, or uncontrolled with `defaultOpen`.
1203
+ - children: React.ReactNode
1204
+ - defaultOpen: boolean
1205
+ - modal: boolean
1206
+ - onOpenChange: ((open: boolean) => void)
1207
+ - open: boolean
1208
+
1209
+ ### Progress
1210
+ Linear progress. Determinate when `value` is a number, else indeterminate.
1211
+ - label: string = Progress
1212
+ - size: "sm" | "md" | "lg" | null
1213
+ - value: number | null = null
1214
+
1215
+ ### Radio
1216
+ Radio — radio button with animated selection indicator.
1217
+ - checked: boolean
1218
+ - label: string
1219
+ - onChange: (v: boolean) => void
1220
+
1221
+ ### Reveal
1222
+ Reveal — reveal-on-scroll primitive via CSS scroll-driven animation.
1223
+ - animation: 'fade' | 'fade-up' | 'fade-down' | 'scale' = fade-up
1224
+ - as: ElementType<any, keyof IntrinsicElements> = div
1225
+ - children: ReactNode
1226
+ - className: string
1227
+ - style: CSSProperties
1228
+
1229
+ ### SegmentedControl
1230
+ SegmentedControl " segmented selection input for compact mutually-exclusive choices. The active×hover×pressed×disabled×secondary state matrix is expressed thro…
1231
+ - aria-label: string
1232
+ - fullWidth: boolean = false
1233
+ - label: string
1234
+ - onChange: (value: string) => void
1235
+ - options: HdsSegmentedOption[]
1236
+ - railPadding: Padding<string | number>
1237
+ - segmentPaddingX: PaddingLeft<string | number>
1238
+ - size: NonNullable<"sm" | "md" | null> | undefined = md
1239
+ - value: string
1240
+ - variant: NonNullable<"primary" | "secondary" | null> | undefined = primary
1241
+
1242
+ ### Select
1243
+ Select — dropdown selector built on Radix Select (ADR-001 Radix convention). Radix owns the listbox a11y contract: managed focus + active-descendant, typeahead…
1244
+ - container: HTMLElement | null
1245
+ - label: string
1246
+ - onChange: (v: string) => void
1247
+ - options: { value: string; label: string; }[]
1248
+ - showLabel: boolean = true
1249
+ - value: string
1250
+
1251
+ ### SelectableCard
1252
+ A card-shaped single checkbox — click or activate to toggle selection.
1253
+ - disabled: boolean
1254
+ - onSelectedChange: ((selected: boolean) => void)
1255
+ - selected: boolean = false
1256
+
1257
+ ### SideNav
1258
+ SideNav - sidebar navigation row primitive. Two levels: root — top-level section link. Full-width row using the shared nav label type style. nested — child pag…
1259
+ - active: boolean = false
1260
+ - disabled: boolean = false
1261
+ - href: string
1262
+ - indent: number | boolean = 0
1263
+ - label: string
1264
+ - level: 'root' | 'nested' = nested
1265
+ - onNavigate: ((event: MouseEvent<HTMLAnchorElement, MouseEvent>) => void)
1266
+ - titleLabel: boolean = false
1267
+
1268
+ ### Sidebar
1269
+ Sidebar — fixed-width rail beside fluid content, no media query. Every Layout reference: https://every-layout.dev/layouts/sidebar/
1270
+ - as: ElementType<any, keyof IntrinsicElements> = div
1271
+ - children: [ReactNode, ReactNode]
1272
+ - className: string
1273
+ - contentMin: string = 50%
1274
+ - gap: 'tight' | 'normal' | 'inset' | 'spacious' = normal
1275
+ - side: 'start' | 'end' = start
1276
+ - sideWidth: string = 16rem
1277
+ - style: CSSProperties
1278
+
1279
+ ### Skeleton
1280
+ Decorative loading placeholder. Marked aria-hidden — announce the loading state on the surrounding region (e.g. aria-busy) rather than per skeleton.
1281
+ - height: string | number
1282
+ - variant: "text" | "rectangular" | "circular" | null = rectangular
1283
+ - width: string | number
1284
+
1285
+ ### Sketch
1286
+ Sketch — shared shell for generative canvases and WebGL sketches.
1287
+ - children: ReactNode
1288
+ - controls: ReactNode
1289
+ - title: string
1290
+
1291
+ ### Slider
1292
+ Slider — range slider with label and value display.
1293
+ - label: string
1294
+ - max: number
1295
+ - min: number
1296
+ - onChange: (v: number) => void
1297
+ - step: number = 1
1298
+ - value: number
1299
+
1300
+ ### Spinner
1301
+ Indeterminate spinner. Inherits the surrounding text color via currentColor.
1302
+ - label: string = Loading
1303
+ - size: "sm" | "md" | "lg" | null
1304
+
1305
+ ### Stack
1306
+ Stack — one-dimensional layout primitive.
1307
+ - align: 'start' | 'center' | 'end' | 'stretch'
1308
+ - as: ElementType<any, keyof IntrinsicElements> = div
1309
+ - children: ReactNode
1310
+ - className: string
1311
+ - direction: "row" | "column" = column
1312
+ - gap: GapOption = tight
1313
+ - justify: 'start' | 'center' | 'end' | 'space-between'
1314
+ - style: CSSProperties
1315
+ - wrap: FlexWrap
1316
+
1317
+ ### StackedCardRail
1318
+ StackedCardRail — horizontally-scrolling stacked card carousel. Scroll mechanism: vertical scroll on an absolutely-positioned inner container is mapped to hori…
1319
+ - cards: StackedCardRailCard[]
1320
+
1321
+ ### Stat
1322
+ Headline metric — large value, uppercase caption label, optional sub-line.
1323
+ - label: string
1324
+ - sub: ReactNode
1325
+ - tone: "neutral" | "danger" | "success" | "warning" | "info" | null
1326
+ - value: ReactNode
1327
+
1328
+ ### StatusDot
1329
+ A small solid dot conveying a semantic status via `tone`.
1330
+ - label: string
1331
+ - size: "sm" | "md" | "lg" | null
1332
+ - tone: "neutral" | "danger" | "success" | "warning" | "info" | "inProgress" | null
1333
+
1334
+ ### StatusListItem
1335
+ Status dot + title row with optional muted notes and trailing slot (e.g. badge).
1336
+ - notes: ReactNode[]
1337
+ - title: ReactNode
1338
+ - tone: "neutral" | "danger" | "success" | "warning" | "info" | null
1339
+ - trailing: ReactNode
1340
+
1341
+ ### StatusTile
1342
+ Block-layout sibling of StatusListItem. Renders a raised surface tile with title, optional muted notes, and a trailing slot for a badge or affordance. Status c…
1343
+ - notes: ReactNode[]
1344
+ - title: ReactNode
1345
+ - tone: 'success' | 'warning' | 'danger' | 'info' | 'neutral' = neutral
1346
+ - trailing: ReactNode
1347
+
1348
+ ### Stepper
1349
+ Step indicator for multi-step flows. Purely presentational — no navigation.
1350
+ - activeStep: number
1351
+ - orientation: "horizontal" | "vertical" = horizontal
1352
+ - steps: Step[]
1353
+
1354
+ ### StepperField
1355
+ StepperField ” numeric input with decrement/increment controls. Classification baseline: Material Design, Chakra UI, and Ant Design treat steppers as numeric i…
1356
+ - inputStep: number
1357
+ - label: string
1358
+ - max: number
1359
+ - min: number
1360
+ - onChange: (value: number) => void
1361
+ - precision: number
1362
+ - step: number
1363
+ - value: number
1364
+
1365
+ ### Surface
1366
+ Surface — governed inset surface primitive. Enforces the "Surface Inset" rule: backgrounds MUST have internal padding. - Default padding: px24 (cards) | px16 (…
1367
+ - as: ElementType<any, keyof IntrinsicElements> = div
1368
+ - children: ReactNode
1369
+ - className: string
1370
+ - overflow: Overflow
1371
+ - padding: PaddingOption = component
1372
+ - shadow: boolean = false
1373
+ - style: CSSProperties
1374
+ - theme: "light" | "dark"
1375
+
1376
+ ### Switcher
1377
+ Switcher — flips a row to a column below a width threshold, no media query. Every Layout reference: https://every-layout.dev/layouts/the-switcher/
1378
+ - as: ElementType<any, keyof IntrinsicElements> = div
1379
+ - children: ReactNode
1380
+ - className: string
1381
+ - gap: 'tight' | 'normal' | 'inset' | 'spacious' = normal
1382
+ - limit: number
1383
+ - style: CSSProperties
1384
+ - threshold: string = 30rem
1385
+
1386
+ ### Table
1387
+ Table - structured data table primitive for documentation and compact UI matrices.
1388
+ - caption: ReactNode
1389
+ - captionAction: ReactNode
1390
+ - columns: TableColumn[]
1391
+ - density: 'compact' | 'comfortable'
1392
+ - description: ReactNode
1393
+ - flush: boolean = false
1394
+ - labelledBy: string
1395
+ - minWidth: string | number
1396
+ - rows: TableRow[]
1397
+ - stickyHeader: boolean = false
1398
+
1399
+ ### Tabs
1400
+ The tab set itself. Tagged here rather than in the file block because TabsList and TabsContent share this module and have no Figma node of their own — a file-l…
1401
+ - activationMode: "automatic" | "manual"
1402
+ - asChild: boolean
1403
+ - defaultValue: string
1404
+ - dir: ("ltr" | "rtl")
1405
+ - onValueChange: ((value: string) => void)
1406
+ - orientation: "horizontal" | "vertical"
1407
+ - value: string
1408
+
1409
+ ### TabsContent
1410
+ Tabs — Radix-backed underline tabs (Root, List, Trigger, Content). Underline pattern math: - TabsList carries `border-b border-border/40` (the divider, half-st…
1411
+ - asChild: boolean
1412
+ - forceMount: true
1413
+ - value: string
1414
+
1415
+ ### TabsList
1416
+ Tabs — Radix-backed underline tabs (Root, List, Trigger, Content). Underline pattern math: - TabsList carries `border-b border-border/40` (the divider, half-st…
1417
+ - asChild: boolean
1418
+ - loop: boolean
1419
+
1420
+ ### TabsTrigger
1421
+ Tabs — Radix-backed underline tabs (Root, List, Trigger, Content). Underline pattern math: - TabsList carries `border-b border-border/40` (the divider, half-st…
1422
+ - asChild: boolean
1423
+ - value: string
1424
+
1425
+ ### Tag
1426
+ Tag — interactive filter and category chip. The outer <button> carries the accessible 44px hit target directly via the size token while the inner pill keeps th…
1427
+ - active: boolean = false
1428
+ - children: ReactNode
1429
+
1430
+ ### Text
1431
+ Text — polymorphic typography primitive spanning the full HDS type ramp.
1432
+ - as: "symbol" | "object" | "map" | "filter" | "title" | "a" | "button" | "div" | "fo… = defaultTagMap[variant]
1433
+ - children: ReactNode
1434
+ - className: string
1435
+ - style: CSSProperties
1436
+ - variant: TextVariant
1437
+
1438
+ ### TextLockup
1439
+ TextLockup - governed title-and-description pairing primitive.
1440
+ - align: 'left' | 'center' = left
1441
+ - as: ElementType = div
1442
+ - description: ReactNode
1443
+ - descriptionAs: 'div' | 'p' | 'span' = div
1444
+ - eyebrow: string
1445
+ - id: string
1446
+ - size: 'hero' | 'heroXl' | 'section' | 'metric' | 'detail' | 'numbered'
1447
+ - title: string
1448
+ - titleAs: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | 'p' | 'span'
1449
+
1450
+ ### Textarea
1451
+ Textarea — multi-line text field primitive with label, helper, and error slots. Mirrors Input's shell + token skin as a native `<textarea>`. Figma parity: the …
1452
+ - className: string
1453
+ - disabled: boolean
1454
+ - error: boolean
1455
+ - errorMessage: string
1456
+ - helperText: string
1457
+ - label: string
1458
+ - resize: TextareaResize = vertical
1459
+ - textareaClassName: string
1460
+
1461
+ ### TileGrid
1462
+ Auto-fill responsive grid for status/micro tiles. Wraps tile children in a one-line grid declaration so pages don't repeat the auto-fill minmax recipe.
1463
+ - gap: "sm" | "md" | "xs" = sm
1464
+ - minTileWidth: string = 260px
1465
+
1466
+ ### TimeInput
1467
+ A native time field skinned with HDS input chrome. Value is a `HH:mm` string.
1468
+ - size: "sm" | "md" | "lg" | null
1469
+
1470
+ ### Timestamp
1471
+ Presents a date/time with a machine-readable `dateTime` for accessibility.
1472
+ - date: string | number | Date
1473
+ - format: 'date' | 'time' | 'datetime' | 'relative' = datetime
1474
+ - locale: string
1475
+ - now: string | number | Date
1476
+
1477
+ ### ToastProvider
1478
+ Provider + viewport for the toast system. Wrap the app root once.
1479
+ - children: React.ReactNode
1480
+ - duration: number = 5000
1481
+ - swipeDirection: SwipeDirection = right
1482
+
1483
+ ### Toggle
1484
+ Toggle — boolean on/off toggle with animated thumb.
1485
+ - checked: boolean
1486
+ - label: string
1487
+ - onChange: (v: boolean) => void
1488
+
1489
+ ### ToggleButton
1490
+ A single two-state toggle button exposing a native `aria-pressed` contract — use for one independent on/off control such as bold, mute, or pin.
1491
+ - asChild: boolean
1492
+ - defaultPressed: boolean
1493
+ - onPressedChange: ((pressed: boolean) => void)
1494
+ - pressed: boolean
1495
+ - size: "sm" | "md" | "lg" | null
1496
+ - variant: "secondary" | "ghost" | null
1497
+
1498
+ ### Token
1499
+ Token - reflective token specimen for unified node-based token views. The `variant` axis (node | diagram — diagram is a deprecated alias that resolves to the s…
1500
+ - accentColor: string
1501
+ - aria-label: string
1502
+ - className: string
1503
+ - description: ReactNode
1504
+ - fullWidth: boolean
1505
+ - isSelected: boolean
1506
+ - isSourceNode: boolean
1507
+ - label: string
1508
+ - leadingSlot: ReactNode
1509
+ - nodeRef: ((el: HTMLElement | null) => void)
1510
+ - nowrap: boolean
1511
+ - onClick: (() => void) | (() => void)
1512
+ - pathDisplayDepth: number
1513
+ - pathDisplayLeadingDot: boolean
1514
+ - pathDisplayMode: "full" | "compressed"
1515
+ - rawValue: ReactNode
1516
+ - swatchVar: string
1517
+ - tokenPath: string
1518
+ - truncateFromStart: boolean
1519
+ - value: string
1520
+ - variant: "node" | "diagram"
1521
+
1522
+ ### Tokenizer
1523
+ A bordered field of Tag chips followed by a text input for adding more.
1524
+ - className: string
1525
+ - disabled: boolean
1526
+ - onChange: (next: string[]) => void
1527
+ - placeholder: string
1528
+ - value: string[]
1529
+
1530
+ ### Toolbar
1531
+ Toolbar root. Groups related controls with a single roving tab-stop. Supports the native `orientation` prop (`horizontal` | `vertical`).
1532
+ - asChild: boolean
1533
+ - dir: ("ltr" | "rtl")
1534
+ - loop: boolean
1535
+ - orientation: "horizontal" | "vertical"
1536
+
1537
+ ### Tooltip
1538
+ Tooltip root. Bakes in the Radix Provider so a single `<Tooltip>` is self-contained — no app-level provider required. Controlled via `open`/`onOpenChange`, or …
1539
+ - children: React.ReactNode
1540
+ - defaultOpen: boolean
1541
+ - delayDuration: number
1542
+ - disableHoverableContent: boolean
1543
+ - onOpenChange: ((open: boolean) => void)
1544
+ - open: boolean
1545
+
1546
+ ### TopNav
1547
+ Top navigation bar with brand, nav, and trailing action slots.
1548
+ - brand: ReactNode
1549
+ - children: ReactNode
1550
+ - sticky: boolean
1551
+ - trailing: ReactNode
1552
+
1553
+ ### TreeList
1554
+ Renders a hierarchical `role="tree"` list; nodes with children get an expand/collapse toggle.
1555
+ - defaultExpandedIds: string[]
1556
+ - items: TreeNode[]
1557
+ - onSelect: ((id: string) => void)
1558
+
1559
+ ### VisuallyHidden
1560
+ Renders its children off-screen (Tailwind `sr-only`) so they are announced by screen readers without occupying visual space — e.g. a text label for an icon-onl…
1561
+ - as: ElementType<any, keyof IntrinsicElements> = span