@hirobius/design-system 0.20.0 → 0.21.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 (76) hide show
  1. package/AGENTS.md +123 -0
  2. package/CONSUMING.md +4 -2
  3. package/DESIGN.md +28 -17
  4. package/NOTICE.md +1 -1
  5. package/README.md +37 -5
  6. package/dist/chunks/empty-state-DNoThgfV.js +1227 -0
  7. package/dist/chunks/form-By82qZcC.js +66 -0
  8. package/dist/fonts/geist-mono-400.woff2 +0 -0
  9. package/dist/fonts/satoshi-400.woff2 +0 -0
  10. package/dist/fonts/satoshi-500.woff2 +0 -0
  11. package/dist/fonts/satoshi-700.woff2 +0 -0
  12. package/dist/fonts.css +53 -0
  13. package/dist/form.js +1 -1
  14. package/dist/hirobius-ui.js +876 -877
  15. package/dist/manifest.js +1 -1
  16. package/dist/patterns.js +189 -170
  17. package/dist/styles.css +2 -2
  18. package/dist/tokens.css +1 -1
  19. package/dist/tokens.js +136 -57
  20. package/dist/types/src/app/components/alert-dialog.d.ts +5 -0
  21. package/dist/types/src/app/components/asset-img.d.ts +1 -0
  22. package/dist/types/src/app/components/avatar-group.d.ts +1 -0
  23. package/dist/types/src/app/components/badge.d.ts +1 -1
  24. package/dist/types/src/app/components/blockquote.d.ts +1 -0
  25. package/dist/types/src/app/components/button.d.ts +2 -0
  26. package/dist/types/src/app/components/card.d.ts +3 -2
  27. package/dist/types/src/app/components/data-table-section.d.ts +1 -0
  28. package/dist/types/src/app/components/destructive-section.d.ts +1 -0
  29. package/dist/types/src/app/components/dialog.d.ts +1 -0
  30. package/dist/types/src/app/components/error-pattern.d.ts +6 -1
  31. package/dist/types/src/app/components/form-actions.d.ts +1 -0
  32. package/dist/types/src/app/components/form-control.d.ts +10 -0
  33. package/dist/types/src/app/components/grid.d.ts +5 -0
  34. package/dist/types/src/app/components/icon.d.ts +1 -0
  35. package/dist/types/src/app/components/kbd.d.ts +1 -0
  36. package/dist/types/src/app/components/metadata-list.d.ts +1 -0
  37. package/dist/types/src/app/components/metric-tiles.d.ts +1 -0
  38. package/dist/types/src/app/components/progress.d.ts +1 -1
  39. package/dist/types/src/app/components/skeleton.d.ts +1 -1
  40. package/dist/types/src/app/components/stat.d.ts +4 -3
  41. package/dist/types/src/app/components/status-tile.d.ts +3 -2
  42. package/dist/types/src/app/components/table.d.ts +5 -0
  43. package/dist/types/src/app/components/text.d.ts +53 -6
  44. package/dist/types/src/app/components/timestamp.d.ts +1 -0
  45. package/dist/types/src/app/data/manifest-types.d.ts +4 -0
  46. package/dist/types/src/app/design-system/generated-token-refs.d.ts +37 -28
  47. package/dist/types/src/app/design-system/generated-token-values.d.ts +3 -0
  48. package/dist/types/src/app/design-system/tokens.d.ts +117 -15
  49. package/dist/types/src/index.d.ts +43 -40
  50. package/dist/variables.css +41 -33
  51. package/docs/CONSUMING.md +63 -39
  52. package/hirobius.tokens.json +77 -73
  53. package/llms.txt +158 -50
  54. package/mcp/catalog.mjs +366 -0
  55. package/mcp/guide.mjs +315 -0
  56. package/mcp/hds-mcp.mjs +49 -0
  57. package/mcp/server.mjs +94 -0
  58. package/package.json +35 -9
  59. package/public/hds-manifest.json +348 -254
  60. package/public/llms/components.txt +4 -3
  61. package/public/llms/layout.txt +1 -1
  62. package/public/llms-full.txt +190 -70
  63. package/public/llms.txt +158 -50
  64. package/scripts/eslint-plugin-hds/index.d.mts +29 -0
  65. package/scripts/eslint-plugin-hds/index.mjs +55 -0
  66. package/scripts/eslint-plugin-hds/package.json +30 -0
  67. package/scripts/eslint-plugin-hds/rules/no-raw-controls.mjs +47 -0
  68. package/scripts/eslint-plugin-hds/rules/no-raw-hex.mjs +70 -0
  69. package/scripts/eslint-plugin-hds/rules/no-raw-px-spacing.mjs +125 -0
  70. package/scripts/eslint-plugin-hds/rules/prefer-hds-layout-primitive.mjs +54 -0
  71. package/scripts/eslint-plugin-hds/rules/sx-token-first.mjs +111 -0
  72. package/scripts/eslint-plugin-hds/rules/utils.mjs +66 -0
  73. package/src/app/data/component-api.json +114 -53
  74. package/dist/chunks/empty-state-BBqhCx0S.js +0 -1217
  75. package/dist/chunks/form-COP3vK9_.js +0 -66
  76. package/dist/types/src/app/components/status-dot.d.ts +0 -39
package/docs/CONSUMING.md CHANGED
@@ -15,7 +15,7 @@ is the canonical consumption guide — point other teams here.
15
15
  >
16
16
  > 1. **`react-router` is now optional** — components route through an adapter and
17
17
  > fall back to plain anchors when no router is provided (§5).
18
- > 2. **Fonts are bundled** — `tokens.css` embeds the typefaces; no font files to copy (§3).
18
+ > 2. **Fonts are opt-in** — `import '@hirobius/design-system/fonts.css'` for the brand typefaces; the woff2 ship in the package, nothing to copy (§3).
19
19
  > 3. **Base styles are scoped to `[data-hds]`** — add that attribute to your root
20
20
  > or section so HDS doesn't fight a host app's resets/fonts (§4, §6).
21
21
 
@@ -43,7 +43,7 @@ HDS ships **three** stylesheets. Pick one by how much you want HDS to own:
43
43
 
44
44
  ```ts
45
45
  // RECOMMENDED for embedding in an existing app (e.g. MUI): tokens + component
46
- // styles + utilities + embedded fonts, with NO global reset. Styles every HDS
46
+ // styles + utilities, with NO global reset. Styles every HDS
47
47
  // component and changes ZERO host-element styles.
48
48
  import '@hirobius/design-system/styles.css';
49
49
 
@@ -56,17 +56,31 @@ import '@hirobius/design-system/tokens.css';
56
56
  import '@hirobius/design-system/variables.css';
57
57
  ```
58
58
 
59
- | Stylesheet | Tokens | Components + utilities | Embedded fonts | Global reset |
60
- | ------------------- | :----: | :--------------------: | :------------: | :-------------------: |
61
- | **`styles.css`** | ✅ | ✅ | ✅ | ❌ none |
62
- | **`tokens.css`** | ✅ | ✅ | ✅ | ⚠️ Tailwind preflight |
63
- | **`variables.css`** | ✅ | ❌ | ❌ | ❌ none |
59
+ | Stylesheet | Tokens | Components + utilities | Global reset |
60
+ | ------------------- | :----: | :--------------------: | :-------------------: |
61
+ | **`styles.css`** | ✅ | ✅ | ❌ none |
62
+ | **`tokens.css`** | ✅ | ✅ | ⚠️ Tailwind preflight |
63
+ | **`variables.css`** | ✅ | ❌ | ❌ none |
64
64
 
65
65
  All three:
66
66
 
67
67
  - **Need no Tailwind config** in the consumer — utilities ship compiled.
68
- - **Need no font files** — the woff2 are inlined (the file is correspondingly
69
- larger; woff2 is already compressed so gzip recovers most of it).
68
+ - **Carry no font files.** Fonts are a separate, optional import (below).
69
+
70
+ ### Brand fonts (optional)
71
+
72
+ ```ts
73
+ import '@hirobius/design-system/fonts.css'; // Satoshi 400/500/700 + Geist Mono 400
74
+ ```
75
+
76
+ `fonts.css` declares the four `@font-face` blocks with `font-display: swap`. Its
77
+ URLs are relative (`./fonts/satoshi-400.woff2`), and the woff2 files ship in the
78
+ package, so Vite, Next and webpack resolve and hash them; there is nothing to
79
+ copy. Import it alongside one of the stylesheets above to keep the HDS fonts.
80
+ Skip it to bring your own: `tokens.css` and `styles.css` keep the
81
+ `--hds-font-family*` variables, so text falls back to the family stack
82
+ (`"Satoshi", system-ui, …`) and uses your font if you declare that family
83
+ yourself.
70
84
 
71
85
  HDS's own base styles (type baseline, resets) are scoped to the `[data-hds]`
72
86
  subtree (§4) in **all** bundles, so they never touch host elements. The only
@@ -155,7 +169,7 @@ If your app runs MUI `<CssBaseline>` + Emotion (or any opinionated global CSS),
155
169
  resets will fight if both target `body`.
156
170
  - **Styled path (recommended for MUI/host embedding):** import
157
171
  `@hirobius/design-system/styles.css` instead of `tokens.css`. It ships the full
158
- component styling (tokens + utilities + fonts) but **no global reset** — HDS's
172
+ component styling (tokens + utilities) but **no global reset** — HDS's
159
173
  own base is scoped to `[data-hds]`, so it styles every HDS component and
160
174
  **cannot** restyle your host's `*`, `body`, headings, `button`, `a`, or form
161
175
  controls. This is the clean way to run HDS next to `<CssBaseline>`: no reset
@@ -211,23 +225,25 @@ export function Example() {
211
225
 
212
226
  ### Subpath exports
213
227
 
214
- | Import | What you get |
215
- | --------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- |
216
- | `@hirobius/design-system` | The core components + the router seam (`HdsRouterProvider`, `useHdsRouter`); the `pattern` tier is in `/patterns` |
217
- | `@hirobius/design-system/styles.css` | Components + utilities + tokens + fonts, NO global reset (host-safe; recommended for embedding) |
218
- | `@hirobius/design-system/tokens.css` | The complete stylesheet — styles.css PLUS a global Tailwind-preflight reset |
219
- | `@hirobius/design-system/variables.css` | Design tokens as CSS custom properties ONLY — no reset/preflight (host-safe) |
220
- | `@hirobius/design-system/tokens` | Design-token values as typed TS |
221
- | `@hirobius/design-system/cn` | The `cn()` className-merge helper |
222
- | `@hirobius/design-system/manifest` | Machine-readable component inventory (`hds-manifest.json`) |
223
- | `@hirobius/design-system/contexts` | React context providers, incl. the router seam (see below) |
224
- | `@hirobius/design-system/form` | Optional React Hook Form + Zod form adapter (see §8.5) |
225
- | `@hirobius/design-system/mui` | Optional Material UI theme preset — maps HDS tokens to an MUI palette (see §6) |
226
- | `@hirobius/design-system/brand` | Framework-free palette → HDS-semantic overlay bridge for static/SSR targets (see §12) |
227
- | `@hirobius/design-system/scroll` | Opt-in scroll-motion: `SmoothScroll` (Lenis) + `useScrollProgress` (Motion). Optional peer `lenis` (see §13) |
228
- | `@hirobius/design-system/static.css` | CSS-only static-primitive layer — `.hds-badge`/`.hds-card`/`.hds-alert`/`.hds-divider`/`.hds-tag` classes, no React (see §14) |
229
- | `@hirobius/design-system/patterns` | The `pattern`-tier components (`Page`, `PageHeader`, `Form`, `FormField`, `CodeBlock`); root copies removed in 0.20.0 |
230
- | `@hirobius/design-system/icons` | Curated Lucide icon set for `Icon` and `Button iconOnly` (see §15) |
228
+ | Import | What you get |
229
+ | --------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
230
+ | `@hirobius/design-system` | The 43-component core set ([README → What belongs in the system](../README.md#what-belongs-in-the-system)), the rest of the allow-list, and the router seam (`HdsRouterProvider`, `useHdsRouter`); the `pattern` tier is in `/patterns` |
231
+ | `@hirobius/design-system/styles.css` | Components + utilities + tokens, NO global reset (host-safe; recommended for embedding) |
232
+ | `@hirobius/design-system/fonts.css` | Optional brand fonts: Satoshi 400/500/700 + Geist Mono 400 (`@font-face`, relative woff2 URLs) |
233
+ | `@hirobius/design-system/tokens.css` | The complete stylesheet — styles.css PLUS a global Tailwind-preflight reset |
234
+ | `@hirobius/design-system/variables.css` | Design tokens as CSS custom properties ONLY — no reset/preflight (host-safe) |
235
+ | `@hirobius/design-system/tokens` | Design-token values as typed TS |
236
+ | `@hirobius/design-system/cn` | The `cn()` className-merge helper |
237
+ | `@hirobius/design-system/manifest` | Machine-readable component inventory (`hds-manifest.json`) |
238
+ | `@hirobius/design-system/contexts` | React context providers, incl. the router seam (see below) |
239
+ | `@hirobius/design-system/form` | Optional React Hook Form + Zod form adapter (see §8.5) |
240
+ | `@hirobius/design-system/mui` | Optional Material UI theme preset — maps HDS tokens to an MUI palette (see §6) |
241
+ | `@hirobius/design-system/brand` | Framework-free palette → HDS-semantic overlay bridge for static/SSR targets (see §12) |
242
+ | `@hirobius/design-system/scroll` | Opt-in scroll-motion: `SmoothScroll` (Lenis) + `useScrollProgress` (Motion). Optional peer `lenis` (see §13) |
243
+ | `@hirobius/design-system/static.css` | CSS-only static-primitive layer — `.hds-badge`/`.hds-card`/`.hds-alert`/`.hds-divider`/`.hds-tag` classes, no React (see §14) |
244
+ | `@hirobius/design-system/patterns` | The 12 pattern modules (`Page`, `PageHeader`, `Form`, `FormField`, `CodeBlock`, …); root copies removed in 0.20.0 |
245
+ | `@hirobius/design-system/icons` | Curated Lucide icon set for `Icon` and `Button iconOnly` (see §15) |
246
+ | `@hirobius/design-system/eslint-plugin` | The consumer ESLint plugin; spread `configs.recommended` into `eslint.config.mjs` (see §11) |
231
247
 
232
248
  ### Semantic feedback / status tokens
233
249
 
@@ -432,16 +448,15 @@ by `scripts/check-hardcoded-colors.mjs`, `scripts/check-hardcoded-spacing.mjs`,
432
448
  and `scripts/check-layout-discipline.mjs` — internal scripts that only run
433
449
  here. `@hirobius/eslint-plugin-hds` (`scripts/eslint-plugin-hds/`) ships the
434
450
  same discipline as an installable ESLint plugin for consumer apps, flagging
435
- raw hex/px values in `style`, `className`, and `Box` `sx` props before they
436
- reach code review.
451
+ raw hex/px values in `style`, `className`, and `Box` `sx` props, and raw HTML
452
+ form controls, before they reach code review.
437
453
 
438
- ```bash
439
- pnpm add -D "@hirobius/eslint-plugin-hds@github:hirobius/hds#path:/scripts/eslint-plugin-hds"
440
- ```
454
+ It ships inside this package as the `@hirobius/design-system/eslint-plugin`
455
+ subpath, so an app that has the design system installed needs only `eslint`:
441
456
 
442
457
  ```js
443
458
  // eslint.config.mjs
444
- import hds from '@hirobius/eslint-plugin-hds';
459
+ import hds from '@hirobius/design-system/eslint-plugin';
445
460
 
446
461
  export default [
447
462
  {
@@ -452,12 +467,21 @@ export default [
452
467
  ];
453
468
  ```
454
469
 
455
- Four rules ship in `recommended`: `no-raw-hex` (error), `no-raw-px-spacing`
456
- (error), `sx-token-first` (error — raw hex/px inside `Box` `sx`, where token
457
- keys are mandatory), and `prefer-hds-layout-primitive` (warn — ad-hoc
458
- `display: flex`/`grid` where Stack/Grid likely fits). Full rule docs, examples,
459
- and the "why `scripts/eslint-plugin-hds/` and not a top-level workspace
460
- package" packaging note live in
470
+ Without the package (for example in a repo that only lints), install the same
471
+ plugin from git:
472
+
473
+ ```bash
474
+ pnpm add -D "@hirobius/eslint-plugin-hds@github:hirobius/hds#path:/scripts/eslint-plugin-hds"
475
+ ```
476
+
477
+ and import it as `@hirobius/eslint-plugin-hds`.
478
+
479
+ Five rules ship in `recommended`: `no-raw-hex` (error), `no-raw-px-spacing`
480
+ (error), `no-raw-controls` (error — raw `<button>`, `<input>`, `<select>`,
481
+ `<textarea>` or `<form>` where an HDS component exists), `sx-token-first`
482
+ (error — raw hex/px inside `Box` `sx`, where token keys are mandatory), and
483
+ `prefer-hds-layout-primitive` (warn — ad-hoc `display: flex`/`grid` where
484
+ Stack/Grid likely fits). Full rule docs and examples live in
461
485
  [`scripts/eslint-plugin-hds/README.md`](../scripts/eslint-plugin-hds/README.md).
462
486
 
463
487
  ### Agent skill
@@ -486,7 +486,7 @@
486
486
  "Segoe UI",
487
487
  "sans-serif"
488
488
  ],
489
- "$description": "Display face: Satoshi Bold (ITF), bound to display/h1/h2/h3 composites."
489
+ "$description": "Display face: Satoshi Bold (ITF), bound to the display and title composites."
490
490
  },
491
491
  "mono": {
492
492
  "$value": ["Geist Mono", "Courier New", "monospace"],
@@ -564,6 +564,13 @@
564
564
  "unit": "px"
565
565
  },
566
566
  "$description": "Swiss-canon display size (hds#283 ramp). Static desktop value; fluid in theme.css. Tailwind 4 default text-6xl."
567
+ },
568
+ "code": {
569
+ "$value": {
570
+ "value": 13,
571
+ "unit": "px"
572
+ },
573
+ "$description": "13px code size. The mono role (hds#485): one px below ui so code sits level with 14px prose."
567
574
  }
568
575
  },
569
576
  "weight": {
@@ -599,6 +606,14 @@
599
606
  "relaxed": {
600
607
  "$value": 1.625,
601
608
  "$description": "Swiss-canon relaxed rhythm (10t-5). Used by body/small/mono composites for long-form prose comfort."
609
+ },
610
+ "display": {
611
+ "$value": 1.05,
612
+ "$description": "Display role leading (hds#485)."
613
+ },
614
+ "body": {
615
+ "$value": 1.6,
616
+ "$description": "Body role leading (hds#485)."
602
617
  }
603
618
  },
604
619
  "letterSpacing": {
@@ -1677,84 +1692,40 @@
1677
1692
  },
1678
1693
  "typography": {
1679
1694
  "$type": "typography",
1680
- "$description": "8-style Swiss-canon type ramp: display, h1–h3, body, small, caption, mono.",
1695
+ "$description": "5-role type ramp plus mono (hds#483): display, title, body, ui, caption, mono. h1, h2, h3 and eyebrow are deprecated aliases.",
1681
1696
  "display": {
1682
- "$value": {
1683
- "fontFamily": "{primitive.typography.family.display}",
1684
- "fontSize": "{primitive.typography.size.6xl}",
1685
- "fontWeight": "{primitive.typography.weight.bold}",
1686
- "letterSpacing": "{primitive.typography.letterSpacing.tight}",
1687
- "lineHeight": "{primitive.typography.lineHeight.none}"
1688
- },
1689
- "$description": "Display headline. 60px / Satoshi bold 700 / leading-none (hds#283: was 72px/5xl).",
1690
- "$extensions": {
1691
- "com.figma.variables": {
1692
- "fontSize": "clamp(40px, 8vw, 60px)",
1693
- "note": "Figma stores the 60px desktop-max static value. Browser CSS overrides with fluid scaling (40px min → 60px max). See src/styles/theme.css."
1694
- }
1695
- }
1696
- },
1697
- "h1": {
1698
1697
  "$value": {
1699
1698
  "fontFamily": "{primitive.typography.family.display}",
1700
1699
  "fontSize": "{primitive.typography.size.5xl}",
1701
1700
  "fontWeight": "{primitive.typography.weight.bold}",
1702
1701
  "letterSpacing": "{primitive.typography.letterSpacing.tight}",
1703
- "lineHeight": "{primitive.typography.lineHeight.tight}"
1702
+ "lineHeight": "{primitive.typography.lineHeight.display}"
1704
1703
  },
1705
- "$description": "Primary section headings (h1). 48px / Satoshi bold 700 / leading-tight (hds#283: rung renamed 4xl→5xl, px unchanged).",
1706
- "$extensions": {
1707
- "com.figma.variables": {
1708
- "fontSize": "clamp(32px, 6vw, 48px)",
1709
- "note": "Figma stores the 48px desktop-max static value. Browser CSS overrides with fluid scaling (32px min → 48px max). See src/styles/theme.css."
1710
- }
1711
- }
1704
+ "$description": "One per page, hero only. 48px / 1.05 / 700. Role 1 of 6."
1712
1705
  },
1713
- "h2": {
1706
+ "title": {
1714
1707
  "$value": {
1715
1708
  "fontFamily": "{primitive.typography.family.display}",
1716
- "fontSize": "{primitive.typography.size.3xl}",
1709
+ "fontSize": "{primitive.typography.size.2xl}",
1717
1710
  "fontWeight": "{primitive.typography.weight.bold}",
1718
1711
  "letterSpacing": "{primitive.typography.letterSpacing.tight}",
1719
- "lineHeight": "40px"
1720
- },
1721
- "$description": "Secondary section headings (h2). Satoshi bold 700, 30px, line-height 40px (hds#283: rung renamed, was 42px).",
1722
- "$extensions": {
1723
- "com.figma.variables": {
1724
- "fontSize": "clamp(24px, 3.5vw, 30px)",
1725
- "note": "Figma stores the 30px desktop-max static value. Browser CSS overrides with fluid scaling (24px min → 30px max). See src/styles/theme.css."
1726
- }
1727
- }
1728
- },
1729
- "h3": {
1730
- "$value": {
1731
- "fontFamily": "{primitive.typography.family.display}",
1732
- "fontSize": "{primitive.typography.size.xl}",
1733
- "fontWeight": "{primitive.typography.weight.bold}",
1734
- "letterSpacing": "{primitive.typography.letterSpacing.normal}",
1735
- "lineHeight": "28px"
1712
+ "lineHeight": "{primitive.typography.lineHeight.tight}"
1736
1713
  },
1737
- "$description": "Component and card headers (h3). 20px / Satoshi bold 700 500 / leading-snug (hds#283: rung renamed lg→xl, px unchanged).",
1738
- "$extensions": {
1739
- "com.figma.variables": {
1740
- "fontSize": "clamp(18px, 2vw, 20px)",
1741
- "note": "Figma stores the 20px desktop-max static value. Browser CSS overrides with fluid scaling (18px min → 20px max). See src/styles/theme.css."
1742
- }
1743
- }
1714
+ "$description": "Section and card headings. 24px / 1.25 / 700. Role 2 of 6."
1744
1715
  },
1745
1716
  "body": {
1746
1717
  "$value": {
1747
1718
  "fontFamily": "{primitive.typography.family.primary}",
1748
1719
  "fontSize": "{primitive.typography.size.base}",
1749
- "fontWeight": "{primitive.typography.weight.medium}",
1720
+ "fontWeight": "{primitive.typography.weight.regular}",
1750
1721
  "letterSpacing": "{primitive.typography.letterSpacing.normal}",
1751
- "lineHeight": "24px",
1722
+ "lineHeight": "{primitive.typography.lineHeight.body}",
1752
1723
  "maxWidth": {
1753
1724
  "value": 60,
1754
1725
  "unit": "ch"
1755
1726
  }
1756
1727
  },
1757
- "$description": "Body prose. Satoshi medium, 16px, line-height 24px, max 60ch measure (hds#283: was 17px/28px)."
1728
+ "$description": "Prose. 16px / 1.6 / 400, 60ch measure. Role 3 of 6."
1758
1729
  },
1759
1730
  "ui": {
1760
1731
  "$value": {
@@ -1762,13 +1733,13 @@
1762
1733
  "fontSize": "{primitive.typography.size.sm}",
1763
1734
  "fontWeight": "{primitive.typography.weight.medium}",
1764
1735
  "letterSpacing": "{primitive.typography.letterSpacing.normal}",
1765
- "lineHeight": "20px",
1736
+ "lineHeight": "{primitive.typography.lineHeight.normal}",
1766
1737
  "maxWidth": {
1767
1738
  "value": 60,
1768
1739
  "unit": "ch"
1769
1740
  }
1770
1741
  },
1771
- "$description": "UI text for nav, labels, captions. Satoshi medium, 14px, line-height 20px (hds#283: was 15px/24px)."
1742
+ "$description": "Controls, nav, table text, values. 14px / 1.5 / 500. Role 4 of 6."
1772
1743
  },
1773
1744
  "caption": {
1774
1745
  "$value": {
@@ -1776,34 +1747,67 @@
1776
1747
  "fontSize": "{primitive.typography.size.xs}",
1777
1748
  "fontWeight": "{primitive.typography.weight.medium}",
1778
1749
  "letterSpacing": "{primitive.typography.letterSpacing.normal}",
1779
- "lineHeight": "16px"
1750
+ "lineHeight": "{primitive.typography.lineHeight.normal}"
1780
1751
  },
1781
- "$description": "Caption / helper text. Satoshi medium, 12px, line-height 16px. Matches the Figma typography/caption text style; now sourced from primitive.xs (hds#283)."
1782
- },
1783
- "eyebrow": {
1784
- "$value": {
1785
- "fontFamily": "{primitive.typography.family.primary}",
1786
- "fontSize": "{primitive.typography.size.xs}",
1787
- "fontWeight": "{primitive.typography.weight.medium}",
1788
- "letterSpacing": "{primitive.typography.letterSpacing.caps}",
1789
- "lineHeight": "16px",
1790
- "textTransform": "uppercase"
1791
- },
1792
- "$description": "Eyebrow / kicker label. Satoshi medium, 12px, caps tracking, uppercase (hds#283: was 13px/20px)."
1752
+ "$description": "Metadata, help text and labels, in sentence case. 12px / 1.5 / 500. Role 5 of 6."
1793
1753
  },
1794
1754
  "mono": {
1795
1755
  "$value": {
1796
1756
  "fontFamily": "{primitive.typography.family.mono}",
1797
- "fontSize": "{primitive.typography.size.sm}",
1757
+ "fontSize": "{primitive.typography.size.code}",
1798
1758
  "fontWeight": "{primitive.typography.weight.regular}",
1799
1759
  "letterSpacing": "{primitive.typography.letterSpacing.normal}",
1800
- "lineHeight": "20px",
1760
+ "lineHeight": "{primitive.typography.lineHeight.normal}",
1801
1761
  "maxWidth": {
1802
1762
  "value": 60,
1803
1763
  "unit": "ch"
1804
1764
  }
1805
1765
  },
1806
- "$description": "Monospace for code, token names, shortcuts. Geist Mono regular, 14px (hds#283: repointed xs→sm; xs alone would give 12px)."
1766
+ "$description": "Code and ids. 13px / 1.5 / 400. The mono companion, role 6 of 6."
1767
+ },
1768
+ "h1": {
1769
+ "$value": {
1770
+ "fontFamily": "{primitive.typography.family.display}",
1771
+ "fontSize": "{primitive.typography.size.2xl}",
1772
+ "fontWeight": "{primitive.typography.weight.bold}",
1773
+ "letterSpacing": "{primitive.typography.letterSpacing.tight}",
1774
+ "lineHeight": "{primitive.typography.lineHeight.tight}"
1775
+ },
1776
+ "$description": "deprecated: use semantic.typography.title",
1777
+ "$deprecated": "hds#483 — use semantic.typography.title"
1778
+ },
1779
+ "h2": {
1780
+ "$value": {
1781
+ "fontFamily": "{primitive.typography.family.display}",
1782
+ "fontSize": "{primitive.typography.size.2xl}",
1783
+ "fontWeight": "{primitive.typography.weight.bold}",
1784
+ "letterSpacing": "{primitive.typography.letterSpacing.tight}",
1785
+ "lineHeight": "{primitive.typography.lineHeight.tight}"
1786
+ },
1787
+ "$description": "deprecated: use semantic.typography.title",
1788
+ "$deprecated": "hds#483 — use semantic.typography.title"
1789
+ },
1790
+ "h3": {
1791
+ "$value": {
1792
+ "fontFamily": "{primitive.typography.family.display}",
1793
+ "fontSize": "{primitive.typography.size.2xl}",
1794
+ "fontWeight": "{primitive.typography.weight.bold}",
1795
+ "letterSpacing": "{primitive.typography.letterSpacing.tight}",
1796
+ "lineHeight": "{primitive.typography.lineHeight.tight}"
1797
+ },
1798
+ "$description": "deprecated: use semantic.typography.title",
1799
+ "$deprecated": "hds#483 — use semantic.typography.title"
1800
+ },
1801
+ "eyebrow": {
1802
+ "$value": {
1803
+ "fontFamily": "{primitive.typography.family.primary}",
1804
+ "fontSize": "{primitive.typography.size.xs}",
1805
+ "fontWeight": "{primitive.typography.weight.medium}",
1806
+ "letterSpacing": "{primitive.typography.letterSpacing.normal}",
1807
+ "lineHeight": "{primitive.typography.lineHeight.normal}"
1808
+ },
1809
+ "$description": "deprecated: use semantic.typography.caption",
1810
+ "$deprecated": "hds#483 — use semantic.typography.caption"
1807
1811
  },
1808
1812
  "lineHeight": {
1809
1813
  "none": {