@hirobius/design-system 0.20.0 → 0.22.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 (130) hide show
  1. package/AGENTS.md +125 -0
  2. package/CHANGELOG.md +969 -0
  3. package/CONSUMING.md +27 -11
  4. package/DESIGN.md +28 -17
  5. package/MIGRATIONS.md +603 -0
  6. package/NOTICE.md +1 -1
  7. package/README.md +39 -5
  8. package/UPGRADING.md +222 -0
  9. package/codemods/hds-prefix.mjs +28 -13
  10. package/codemods/jsx-fold.mjs +28 -13
  11. package/codemods/lib/atomic-write.mjs +28 -0
  12. package/codemods/lib/installed-version.mjs +354 -0
  13. package/codemods/lib/project.mjs +395 -0
  14. package/codemods/lib/record.mjs +110 -0
  15. package/codemods/lib/scan.mjs +323 -0
  16. package/codemods/lib/semver.mjs +57 -0
  17. package/codemods/not-found-pattern.mjs +3 -3
  18. package/codemods/patterns-subpath.mjs +28 -12
  19. package/codemods/registry.mjs +67 -0
  20. package/codemods/tile-grid.mjs +3 -3
  21. package/codemods/upgrade.mjs +909 -0
  22. package/dist/chunks/empty-state-DNoThgfV.js +1227 -0
  23. package/dist/chunks/form-By82qZcC.js +66 -0
  24. package/dist/fonts/geist-mono-400.woff2 +0 -0
  25. package/dist/fonts/satoshi-400.woff2 +0 -0
  26. package/dist/fonts/satoshi-500.woff2 +0 -0
  27. package/dist/fonts/satoshi-700.woff2 +0 -0
  28. package/dist/fonts.css +53 -0
  29. package/dist/form.js +1 -1
  30. package/dist/hirobius-ui.js +876 -877
  31. package/dist/manifest.js +3 -3
  32. package/dist/patterns.js +189 -170
  33. package/dist/styles.css +2 -2
  34. package/dist/tokens.css +1 -1
  35. package/dist/tokens.js +136 -57
  36. package/dist/types/src/app/components/alert-dialog.d.ts +5 -0
  37. package/dist/types/src/app/components/alert.d.ts +1 -1
  38. package/dist/types/src/app/components/asset-img.d.ts +1 -0
  39. package/dist/types/src/app/components/avatar-group.d.ts +1 -0
  40. package/dist/types/src/app/components/avatar.d.ts +1 -1
  41. package/dist/types/src/app/components/badge.d.ts +2 -2
  42. package/dist/types/src/app/components/blockquote.d.ts +1 -0
  43. package/dist/types/src/app/components/breadcrumb.d.ts +1 -1
  44. package/dist/types/src/app/components/button.d.ts +3 -1
  45. package/dist/types/src/app/components/callout.d.ts +1 -1
  46. package/dist/types/src/app/components/card.d.ts +4 -3
  47. package/dist/types/src/app/components/checkbox.d.ts +1 -1
  48. package/dist/types/src/app/components/code-block.d.ts +1 -1
  49. package/dist/types/src/app/components/combobox.d.ts +1 -1
  50. package/dist/types/src/app/components/data-table-section.d.ts +1 -0
  51. package/dist/types/src/app/components/destructive-section.d.ts +1 -0
  52. package/dist/types/src/app/components/dialog.d.ts +2 -1
  53. package/dist/types/src/app/components/disclosure.d.ts +1 -1
  54. package/dist/types/src/app/components/divider.d.ts +1 -1
  55. package/dist/types/src/app/components/empty-state.d.ts +1 -1
  56. package/dist/types/src/app/components/error-pattern.d.ts +6 -1
  57. package/dist/types/src/app/components/field.d.ts +1 -1
  58. package/dist/types/src/app/components/form-actions.d.ts +1 -0
  59. package/dist/types/src/app/components/form-control.d.ts +10 -0
  60. package/dist/types/src/app/components/form.d.ts +1 -1
  61. package/dist/types/src/app/components/grid.d.ts +5 -0
  62. package/dist/types/src/app/components/hds-tooltip.d.ts +1 -1
  63. package/dist/types/src/app/components/icon.d.ts +1 -0
  64. package/dist/types/src/app/components/inline-link.d.ts +1 -1
  65. package/dist/types/src/app/components/input.d.ts +1 -1
  66. package/dist/types/src/app/components/kbd.d.ts +1 -0
  67. package/dist/types/src/app/components/menu.d.ts +1 -1
  68. package/dist/types/src/app/components/metadata-list.d.ts +1 -0
  69. package/dist/types/src/app/components/metric-tiles.d.ts +1 -0
  70. package/dist/types/src/app/components/pagination.d.ts +1 -1
  71. package/dist/types/src/app/components/popover.d.ts +1 -1
  72. package/dist/types/src/app/components/progress.d.ts +2 -2
  73. package/dist/types/src/app/components/radio.d.ts +1 -1
  74. package/dist/types/src/app/components/select.d.ts +1 -1
  75. package/dist/types/src/app/components/skeleton.d.ts +2 -2
  76. package/dist/types/src/app/components/slider.d.ts +1 -1
  77. package/dist/types/src/app/components/spinner.d.ts +1 -1
  78. package/dist/types/src/app/components/stat.d.ts +5 -4
  79. package/dist/types/src/app/components/status-list-item.d.ts +1 -1
  80. package/dist/types/src/app/components/status-tile.d.ts +4 -3
  81. package/dist/types/src/app/components/table.d.ts +6 -1
  82. package/dist/types/src/app/components/tabs.d.ts +1 -1
  83. package/dist/types/src/app/components/tag.d.ts +1 -1
  84. package/dist/types/src/app/components/text.d.ts +53 -6
  85. package/dist/types/src/app/components/textarea.d.ts +1 -1
  86. package/dist/types/src/app/components/timestamp.d.ts +1 -0
  87. package/dist/types/src/app/components/toast.d.ts +1 -1
  88. package/dist/types/src/app/components/toggle.d.ts +1 -1
  89. package/dist/types/src/app/data/manifest-types.d.ts +4 -0
  90. package/dist/types/src/app/design-system/generated-token-refs.d.ts +37 -28
  91. package/dist/types/src/app/design-system/generated-token-values.d.ts +3 -0
  92. package/dist/types/src/app/design-system/tokens.d.ts +117 -15
  93. package/dist/types/src/index.d.ts +122 -72
  94. package/dist/variables.css +41 -33
  95. package/docs/CONSUMING.md +63 -39
  96. package/hirobius.tokens.json +163 -112
  97. package/llms.txt +158 -50
  98. package/mcp/catalog.mjs +369 -0
  99. package/mcp/core-set.mjs +66 -0
  100. package/mcp/guide.mjs +272 -0
  101. package/mcp/hds-mcp.mjs +49 -0
  102. package/mcp/server.mjs +94 -0
  103. package/package.json +53 -11
  104. package/public/hds-manifest.json +430 -336
  105. package/public/llms/components.txt +4 -3
  106. package/public/llms/layout.txt +1 -1
  107. package/public/llms-full.txt +190 -70
  108. package/public/llms.txt +158 -50
  109. package/scripts/eslint-plugin-hds/index.d.mts +29 -0
  110. package/scripts/eslint-plugin-hds/index.mjs +55 -0
  111. package/scripts/eslint-plugin-hds/package.json +30 -0
  112. package/scripts/eslint-plugin-hds/rules/no-raw-controls.mjs +47 -0
  113. package/scripts/eslint-plugin-hds/rules/no-raw-hex.mjs +70 -0
  114. package/scripts/eslint-plugin-hds/rules/no-raw-px-spacing.mjs +125 -0
  115. package/scripts/eslint-plugin-hds/rules/prefer-hds-layout-primitive.mjs +54 -0
  116. package/scripts/eslint-plugin-hds/rules/sx-token-first.mjs +111 -0
  117. package/scripts/eslint-plugin-hds/rules/utils.mjs +66 -0
  118. package/src/app/data/component-api.json +154 -93
  119. package/upgrade/index.json +208 -0
  120. package/upgrade/releases/0.17.0.json +962 -0
  121. package/upgrade/releases/0.18.0.json +8 -0
  122. package/upgrade/releases/0.19.0.json +233 -0
  123. package/upgrade/releases/0.19.1.json +8 -0
  124. package/upgrade/releases/0.20.0.json +5108 -0
  125. package/upgrade/releases/0.21.0.json +538 -0
  126. package/upgrade/releases/0.22.0.json +94 -0
  127. package/upgrade/schema.json +989 -0
  128. package/dist/chunks/empty-state-BBqhCx0S.js +0 -1217
  129. package/dist/chunks/form-COP3vK9_.js +0 -66
  130. package/dist/types/src/app/components/status-dot.d.ts +0 -39
@@ -2,7 +2,7 @@
2
2
  "name": "Hirobius Design System",
3
3
  "description": "Three-tier design token system for Adrian Milsap's portfolio site. Tokens flow primitive → semantic → component. All visual decisions trace back to hirobius.tokens.json.",
4
4
  "version": "1",
5
- "generated": "2026-10-01T14:42:41.226Z",
5
+ "generated": "2026-10-07T17:58:53.026Z",
6
6
  "source": "hirobius.tokens.json",
7
7
  "format": "W3C DTCG 2025.10",
8
8
  "docs": "https://hirobius-design-system.vercel.app/",
@@ -109,7 +109,6 @@
109
109
  "Spinner",
110
110
  "Stack",
111
111
  "Stat",
112
- "StatusDot",
113
112
  "StatusListItem",
114
113
  "StatusTile",
115
114
  "Surface",
@@ -130,76 +129,90 @@
130
129
  ],
131
130
  "typographyRamp": {
132
131
  "status": "active",
133
- "styleCount": 9,
132
+ "styleCount": 6,
134
133
  "source": "hirobius.tokens.json semantic.typography",
135
134
  "tokens": [
136
135
  {
137
136
  "name": "display",
138
137
  "size": "48px",
139
- "lineHeight": "1.0",
140
- "role": "Hero headlines and landing-page displays"
138
+ "lineHeight": "1.05",
139
+ "weight": 700,
140
+ "role": "One per page, hero only"
141
141
  },
142
142
  {
143
- "name": "heading1",
144
- "size": "36px",
145
- "lineHeight": "1.25",
146
- "role": "Primary section headings and h1 text"
147
- },
148
- {
149
- "name": "heading2",
150
- "size": "30px",
151
- "lineHeight": "1.25",
152
- "role": "Secondary section headings and h2 text"
153
- },
154
- {
155
- "name": "heading3",
143
+ "name": "title",
156
144
  "size": "24px",
157
145
  "lineHeight": "1.25",
158
- "role": "Component headings, card headings, and h3 text"
146
+ "weight": 700,
147
+ "role": "Section and card headings"
159
148
  },
160
149
  {
161
150
  "name": "body",
162
151
  "size": "16px",
163
- "lineHeight": "1.5",
164
- "role": "Default long-form prose and body copy"
152
+ "lineHeight": "1.6",
153
+ "weight": 400,
154
+ "role": "Prose"
165
155
  },
166
156
  {
167
157
  "name": "ui",
168
158
  "size": "14px",
169
159
  "lineHeight": "1.5",
170
- "role": "Standard interface text, nav labels, inputs, and controls"
160
+ "weight": 500,
161
+ "role": "Controls, nav, table text, values"
171
162
  },
172
163
  {
173
164
  "name": "caption",
174
165
  "size": "12px",
175
166
  "lineHeight": "1.5",
176
- "role": "Active functional role for helper text, error metadata, secondary metadata, and form annotations"
177
- },
178
- {
179
- "name": "technical",
180
- "size": "12px",
181
- "lineHeight": "1.0",
182
- "role": "Monospace token keys, code snippets, keyboard shortcuts, hashes, and aligned data readouts"
167
+ "weight": 500,
168
+ "role": "Metadata, help text and labels, in sentence case"
183
169
  },
184
170
  {
185
- "name": "badge",
186
- "size": "10px",
187
- "lineHeight": "1.0",
188
- "role": "Status badges and compact tags only"
171
+ "name": "mono",
172
+ "size": "13px",
173
+ "lineHeight": "1.5",
174
+ "weight": 400,
175
+ "role": "Code and ids"
189
176
  }
190
177
  ],
191
178
  "deprecated": [
179
+ "heading1",
180
+ "heading2",
181
+ "heading3",
182
+ "h1",
183
+ "h2",
184
+ "h3",
185
+ "technical",
186
+ "badge",
187
+ "eyebrow",
188
+ "small",
192
189
  "displayXl",
190
+ "display1",
193
191
  "display2",
194
- "title",
192
+ "headingHero",
193
+ "headingSection",
195
194
  "body2",
195
+ "bodyLarge",
196
+ "bodySmall",
196
197
  "label",
197
198
  "labelDescriptive",
198
199
  "labelTechnical",
199
200
  "micro",
200
201
  "monoXs",
201
202
  "monoSm"
202
- ]
203
+ ],
204
+ "aliasOf": {
205
+ "heading1": "title",
206
+ "heading2": "title",
207
+ "heading3": "title",
208
+ "h1": "title",
209
+ "h2": "title",
210
+ "h3": "title",
211
+ "technical": "mono",
212
+ "badge": "caption",
213
+ "eyebrow": "caption",
214
+ "small": "ui"
215
+ }
203
216
  },
204
217
  "patternInventory": [
205
218
  "DataTableSection",
@@ -378,7 +391,7 @@
378
391
  "hidden": false,
379
392
  "filePath": "src/app/components/alert.tsx",
380
393
  "description": "Alert - compact feedback surface with contextual severity.",
381
- "figmaUrl": "https://www.figma.com/design/c8MaVgwxOlxm4wr8wnH0Z4/HDS-Tokens-Components?node-id=33-34",
394
+ "figmaUrl": "https://www.figma.com/design/2VgBbVpKiDnu0aftJEVyBQ/HDS-Tokens-Components?node-id=33-34",
382
395
  "figmaId": null,
383
396
  "preview": {
384
397
  "exportName": "Alert",
@@ -466,7 +479,7 @@
466
479
  "tier": "primitive",
467
480
  "docExempt": false,
468
481
  "sourcePath": "src/app/components/Alert.tsx",
469
- "figmaLink": "https://www.figma.com/design/c8MaVgwxOlxm4wr8wnH0Z4/HDS-Tokens-Components?node-id=33-34",
482
+ "figmaLink": "https://www.figma.com/design/2VgBbVpKiDnu0aftJEVyBQ/HDS-Tokens-Components?node-id=33-34",
470
483
  "props": {
471
484
  "children": {
472
485
  "type": "ReactNode"
@@ -524,7 +537,8 @@
524
537
  "reason": "a short status label"
525
538
  }
526
539
  ]
527
- }
540
+ },
541
+ "core": true
528
542
  },
529
543
  "CodeBlock": {
530
544
  "category": "Display",
@@ -533,7 +547,7 @@
533
547
  "hidden": false,
534
548
  "filePath": "src/app/components/code-block.tsx",
535
549
  "description": "CodeBlock - code display with copy button and optional collapsible toggle.",
536
- "figmaUrl": "https://www.figma.com/design/c8MaVgwxOlxm4wr8wnH0Z4/HDS-Tokens-Components?node-id=89-154",
550
+ "figmaUrl": "https://www.figma.com/design/2VgBbVpKiDnu0aftJEVyBQ/HDS-Tokens-Components?node-id=89-154",
537
551
  "figmaId": null,
538
552
  "preview": {
539
553
  "exportName": "CodeBlock",
@@ -598,7 +612,7 @@
598
612
  "tier": "primitive",
599
613
  "docExempt": false,
600
614
  "sourcePath": "src/app/components/CodeBlock.tsx",
601
- "figmaLink": "https://www.figma.com/design/c8MaVgwxOlxm4wr8wnH0Z4/HDS-Tokens-Components?node-id=89-154",
615
+ "figmaLink": "https://www.figma.com/design/2VgBbVpKiDnu0aftJEVyBQ/HDS-Tokens-Components?node-id=89-154",
602
616
  "storyFiles": [
603
617
  "src/stories/code-block.stories.tsx"
604
618
  ],
@@ -697,7 +711,8 @@
697
711
  }
698
712
  ]
699
713
  },
700
- "aiRules": "Reach for this named layout intent before Box/sx. maxWidth MUST use the semantic width scale ('content' | 'max'), never a raw px value. Do NOT use the deprecated `padding` prop — it is a no-op; apply padding via Surface or a Stack instead. Do NOT import Container directly inside a page under src/app/pages — use Page, which wraps Container and owns vertical rhythm. For a horizontal gutter, which Container does not support, put a Box with `style={{ paddingInline }}` inside it."
714
+ "aiRules": "Reach for this named layout intent before Box/sx. maxWidth MUST use the semantic width scale ('content' | 'max'), never a raw px value. Do NOT use the deprecated `padding` prop — it is a no-op; apply padding via Surface or a Stack instead. Do NOT import Container directly inside a page under src/app/pages — use Page, which wraps Container and owns vertical rhythm. For a horizontal gutter, which Container does not support, put a Box with `style={{ paddingInline }}` inside it.",
715
+ "core": true
701
716
  },
702
717
  "Disclosure": {
703
718
  "category": "Layout",
@@ -706,7 +721,7 @@
706
721
  "hidden": false,
707
722
  "filePath": "src/app/components/disclosure.tsx",
708
723
  "description": "Disclosure - compact disclosure surface for optional explanatory content.",
709
- "figmaUrl": "https://www.figma.com/design/c8MaVgwxOlxm4wr8wnH0Z4/HDS-Tokens-Components?node-id=88-453",
724
+ "figmaUrl": "https://www.figma.com/design/2VgBbVpKiDnu0aftJEVyBQ/HDS-Tokens-Components?node-id=88-453",
710
725
  "figmaId": null,
711
726
  "preview": {
712
727
  "exportName": "Disclosure",
@@ -810,7 +825,7 @@
810
825
  }
811
826
  ],
812
827
  "sourcePath": "src/app/components/Disclosure.tsx",
813
- "figmaLink": "https://www.figma.com/design/c8MaVgwxOlxm4wr8wnH0Z4/HDS-Tokens-Components?node-id=88-453",
828
+ "figmaLink": "https://www.figma.com/design/2VgBbVpKiDnu0aftJEVyBQ/HDS-Tokens-Components?node-id=88-453",
814
829
  "storyFiles": [
815
830
  "src/stories/disclosure.stories.tsx"
816
831
  ],
@@ -829,7 +844,8 @@
829
844
  "reason": "switching between panels of content"
830
845
  }
831
846
  ]
832
- }
847
+ },
848
+ "core": true
833
849
  },
834
850
  "Divider": {
835
851
  "category": "Layout",
@@ -838,7 +854,7 @@
838
854
  "hidden": false,
839
855
  "filePath": "src/app/components/divider.tsx",
840
856
  "description": "Divider — semantic separator between content regions.",
841
- "figmaUrl": "https://www.figma.com/design/c8MaVgwxOlxm4wr8wnH0Z4/HDS-Tokens-Components?node-id=89-26",
857
+ "figmaUrl": "https://www.figma.com/design/2VgBbVpKiDnu0aftJEVyBQ/HDS-Tokens-Components?node-id=89-26",
842
858
  "figmaId": null,
843
859
  "preview": {
844
860
  "exportName": "Divider",
@@ -877,7 +893,7 @@
877
893
  "tier": "primitive",
878
894
  "docExempt": false,
879
895
  "sourcePath": "src/app/components/Divider.tsx",
880
- "figmaLink": "https://www.figma.com/design/c8MaVgwxOlxm4wr8wnH0Z4/HDS-Tokens-Components?node-id=89-26",
896
+ "figmaLink": "https://www.figma.com/design/2VgBbVpKiDnu0aftJEVyBQ/HDS-Tokens-Components?node-id=89-26",
881
897
  "props": {
882
898
  "orientation": {
883
899
  "type": "enum",
@@ -947,7 +963,8 @@
947
963
  "reason": "a bounded region with its own background"
948
964
  }
949
965
  ]
950
- }
966
+ },
967
+ "core": true
951
968
  },
952
969
  "ErrorPattern": {
953
970
  "category": "Feedback",
@@ -1080,6 +1097,16 @@
1080
1097
  ],
1081
1098
  "tokenMapping": {},
1082
1099
  "props": {
1100
+ "align": {
1101
+ "type": "enum",
1102
+ "values": [
1103
+ "center",
1104
+ "end",
1105
+ "start",
1106
+ "stretch"
1107
+ ],
1108
+ "default": "start"
1109
+ },
1083
1110
  "as": {
1084
1111
  "type": "ElementType<any, keyof IntrinsicElements>",
1085
1112
  "default": "div"
@@ -1132,6 +1159,15 @@
1132
1159
  "*"
1133
1160
  ],
1134
1161
  "propConstraints": {
1162
+ "align": {
1163
+ "type": "enum",
1164
+ "values": [
1165
+ "center",
1166
+ "end",
1167
+ "start",
1168
+ "stretch"
1169
+ ]
1170
+ },
1135
1171
  "className": {
1136
1172
  "type": "string"
1137
1173
  },
@@ -1211,7 +1247,8 @@
1211
1247
  }
1212
1248
  ]
1213
1249
  },
1214
- "aiRules": "Use Grid for spatial layout, not for surface styling or content padding. Do NOT apply background, border, or internal padding directly to Grid to mimic a card. Do NOT use arbitrary CSS grid templates when fixed, auto-fit, auto-fill, or subgrid modes already express the layout. Do NOT use Grid for simple one-dimensional stacks where Stack is sufficient."
1250
+ "aiRules": "Use Grid for spatial layout, not for surface styling or content padding. Do NOT apply background, border, or internal padding directly to Grid to mimic a card. Do NOT use arbitrary CSS grid templates when fixed, auto-fit, auto-fill, or subgrid modes already express the layout. Do NOT use Grid for simple one-dimensional stacks where Stack is sufficient.",
1251
+ "core": true
1215
1252
  },
1216
1253
  "Icon": {
1217
1254
  "category": "Display",
@@ -1220,7 +1257,7 @@
1220
1257
  "hidden": false,
1221
1258
  "filePath": "src/app/components/icon.tsx",
1222
1259
  "description": "Icon — semantic icon wrapper for Lucide icons.",
1223
- "figmaUrl": null,
1260
+ "figmaUrl": "https://www.figma.com/design/2VgBbVpKiDnu0aftJEVyBQ/HDS-Tokens-Components?node-id=27-2",
1224
1261
  "figmaId": null,
1225
1262
  "preview": {
1226
1263
  "exportName": "Icon",
@@ -1356,7 +1393,7 @@
1356
1393
  "tier": "primitive",
1357
1394
  "docExempt": false,
1358
1395
  "sourcePath": "src/app/components/Icon.tsx",
1359
- "figmaLink": null,
1396
+ "figmaLink": "https://www.figma.com/design/2VgBbVpKiDnu0aftJEVyBQ/HDS-Tokens-Components?node-id=27-2",
1360
1397
  "storyFiles": [
1361
1398
  "src/stories/icon.stories.tsx"
1362
1399
  ],
@@ -1381,7 +1418,8 @@
1381
1418
  "reason": "a picture of a person or entity"
1382
1419
  }
1383
1420
  ]
1384
- }
1421
+ },
1422
+ "core": true
1385
1423
  },
1386
1424
  "InlineCode": {
1387
1425
  "category": "Display",
@@ -1390,7 +1428,7 @@
1390
1428
  "hidden": false,
1391
1429
  "filePath": "src/app/components/inline-code.tsx",
1392
1430
  "description": "InlineCode — inline code chip for token paths, file paths, and code-adjacent prose.",
1393
- "figmaUrl": "https://www.figma.com/design/c8MaVgwxOlxm4wr8wnH0Z4/HDS-Tokens-Components?node-id=89-155",
1431
+ "figmaUrl": "https://www.figma.com/design/2VgBbVpKiDnu0aftJEVyBQ/HDS-Tokens-Components?node-id=89-155",
1394
1432
  "figmaId": null,
1395
1433
  "preview": {
1396
1434
  "exportName": "InlineCode",
@@ -1446,7 +1484,7 @@
1446
1484
  "tier": "primitive",
1447
1485
  "docExempt": false,
1448
1486
  "sourcePath": "src/app/components/InlineCode.tsx",
1449
- "figmaLink": "https://www.figma.com/design/c8MaVgwxOlxm4wr8wnH0Z4/HDS-Tokens-Components?node-id=89-155",
1487
+ "figmaLink": "https://www.figma.com/design/2VgBbVpKiDnu0aftJEVyBQ/HDS-Tokens-Components?node-id=89-155",
1450
1488
  "storyFiles": [
1451
1489
  "src/stories/inline-code.stories.tsx"
1452
1490
  ],
@@ -1467,7 +1505,7 @@
1467
1505
  "hidden": false,
1468
1506
  "filePath": "src/app/components/inline-link.tsx",
1469
1507
  "description": "InlineLink ” inline navigation and external-link primitive for body copy.",
1470
- "figmaUrl": "https://www.figma.com/design/c8MaVgwxOlxm4wr8wnH0Z4/HDS-Tokens-Components?node-id=89-161",
1508
+ "figmaUrl": "https://www.figma.com/design/2VgBbVpKiDnu0aftJEVyBQ/HDS-Tokens-Components?node-id=89-161",
1471
1509
  "figmaId": null,
1472
1510
  "preview": {
1473
1511
  "exportName": "InlineLink",
@@ -1523,7 +1561,7 @@
1523
1561
  "tier": "primitive",
1524
1562
  "docExempt": false,
1525
1563
  "sourcePath": "src/app/components/InlineLink.tsx",
1526
- "figmaLink": "https://www.figma.com/design/c8MaVgwxOlxm4wr8wnH0Z4/HDS-Tokens-Components?node-id=89-161",
1564
+ "figmaLink": "https://www.figma.com/design/2VgBbVpKiDnu0aftJEVyBQ/HDS-Tokens-Components?node-id=89-161",
1527
1565
  "storyFiles": [
1528
1566
  "src/stories/inline-link.stories.tsx"
1529
1567
  ],
@@ -1546,7 +1584,8 @@
1546
1584
  "reason": "unlinked body copy"
1547
1585
  }
1548
1586
  ]
1549
- }
1587
+ },
1588
+ "core": true
1550
1589
  },
1551
1590
  "Input": {
1552
1591
  "category": "Inputs",
@@ -1555,7 +1594,7 @@
1555
1594
  "hidden": false,
1556
1595
  "filePath": "src/app/components/input.tsx",
1557
1596
  "description": "Input — text field primitive with label, helper, and error slots.",
1558
- "figmaUrl": "https://www.figma.com/design/c8MaVgwxOlxm4wr8wnH0Z4/HDS-Tokens-Components?node-id=38-20",
1597
+ "figmaUrl": "https://www.figma.com/design/2VgBbVpKiDnu0aftJEVyBQ/HDS-Tokens-Components?node-id=38-20",
1559
1598
  "figmaId": null,
1560
1599
  "preview": {
1561
1600
  "exportName": "Input",
@@ -1563,9 +1602,11 @@
1563
1602
  },
1564
1603
  "consumers": [
1565
1604
  "src/app/components/field.tsx",
1605
+ "src/app/components/form-control.ts",
1566
1606
  "src/app/components/form.tsx",
1567
1607
  "src/app/components/input.test.tsx",
1568
1608
  "src/app/components/segmented-control.tsx",
1609
+ "src/app/components/select.tsx",
1569
1610
  "src/app/components/slider.tsx",
1570
1611
  "src/app/components/textarea.tsx",
1571
1612
  "src/app/design-system/generated-token-descriptions.ts",
@@ -1805,7 +1846,7 @@
1805
1846
  ],
1806
1847
  "tier": "primitive",
1807
1848
  "docExempt": false,
1808
- "figmaLink": "https://www.figma.com/design/c8MaVgwxOlxm4wr8wnH0Z4/HDS-Tokens-Components?node-id=38-20",
1849
+ "figmaLink": "https://www.figma.com/design/2VgBbVpKiDnu0aftJEVyBQ/HDS-Tokens-Components?node-id=38-20",
1809
1850
  "storyFiles": [
1810
1851
  "src/stories/input.stories.tsx"
1811
1852
  ],
@@ -1837,7 +1878,8 @@
1837
1878
  "reason": "a long fixed list that needs search"
1838
1879
  }
1839
1880
  ]
1840
- }
1881
+ },
1882
+ "core": true
1841
1883
  },
1842
1884
  "SegmentedControl": {
1843
1885
  "category": "Inputs",
@@ -1846,7 +1888,7 @@
1846
1888
  "hidden": false,
1847
1889
  "filePath": "src/app/components/segmented-control.tsx",
1848
1890
  "description": "SegmentedControl \" segmented selection input for compact mutually-exclusive choices. The active×hover×pressed×disabled×secondary state matrix is expressed through `cva` compound variants keyed by `active` / `interaction` (the live-or-frozen-demo hover/pressed/rest sub-state) / `variant` / `disabled`, each resolving to the same `--semantic-*` custom properties the pre-Tailwind inline styles referenced — same tokens, same pixels, just Tailwind classes instead of a `style` object. Per ADR-015 this control keeps its own hover/focus tracking (per-segment `string | null` cardinality) rather than the shared `useInteractionState` single-element machine; only the class composition changed, not the state machine feeding it.",
1849
- "figmaUrl": "https://www.figma.com/design/c8MaVgwxOlxm4wr8wnH0Z4/HDS-Tokens-Components?node-id=82-334",
1891
+ "figmaUrl": "https://www.figma.com/design/2VgBbVpKiDnu0aftJEVyBQ/HDS-Tokens-Components?node-id=82-334",
1850
1892
  "figmaId": null,
1851
1893
  "preview": {
1852
1894
  "exportName": "SegmentedControl",
@@ -1962,7 +2004,7 @@
1962
2004
  "tier": "primitive",
1963
2005
  "docExempt": false,
1964
2006
  "sourcePath": "src/app/components/SegmentedControl.tsx",
1965
- "figmaLink": "https://www.figma.com/design/c8MaVgwxOlxm4wr8wnH0Z4/HDS-Tokens-Components?node-id=82-334",
2007
+ "figmaLink": "https://www.figma.com/design/2VgBbVpKiDnu0aftJEVyBQ/HDS-Tokens-Components?node-id=82-334",
1966
2008
  "storyFiles": [
1967
2009
  "src/stories/segmented-control.stories.tsx"
1968
2010
  ],
@@ -1989,7 +2031,8 @@
1989
2031
  "reason": "more than five options"
1990
2032
  }
1991
2033
  ]
1992
- }
2034
+ },
2035
+ "core": true
1993
2036
  },
1994
2037
  "Stack": {
1995
2038
  "category": "Layout",
@@ -2178,7 +2221,8 @@
2178
2221
  }
2179
2222
  ]
2180
2223
  },
2181
- "aiRules": "Use Stack for flow spacing and simple flex alignment only. Do NOT use Stack to create card chrome, internal surface padding, or page-width constraints. Do NOT apply arbitrary margins to Stack to fake spacing between children when the gap prop should own that rhythm. Do NOT use Stack for true two-dimensional layouts that require Grid."
2224
+ "aiRules": "Use Stack for flow spacing and simple flex alignment only. Do NOT use Stack to create card chrome, internal surface padding, or page-width constraints. Do NOT apply arbitrary margins to Stack to fake spacing between children when the gap prop should own that rhythm. Do NOT use Stack for true two-dimensional layouts that require Grid.",
2225
+ "core": true
2182
2226
  },
2183
2227
  "Table": {
2184
2228
  "category": "Display",
@@ -2187,7 +2231,7 @@
2187
2231
  "hidden": false,
2188
2232
  "filePath": "src/app/components/table.tsx",
2189
2233
  "description": "Table - structured data table primitive for documentation and compact UI matrices.",
2190
- "figmaUrl": "https://www.figma.com/design/c8MaVgwxOlxm4wr8wnH0Z4/HDS-Tokens-Components?node-id=89-300",
2234
+ "figmaUrl": "https://www.figma.com/design/2VgBbVpKiDnu0aftJEVyBQ/HDS-Tokens-Components?node-id=89-300",
2191
2235
  "figmaId": null,
2192
2236
  "preview": {
2193
2237
  "exportName": "Table",
@@ -2228,7 +2272,7 @@
2228
2272
  },
2229
2273
  "flush": {
2230
2274
  "type": "boolean",
2231
- "default": false
2275
+ "default": true
2232
2276
  },
2233
2277
  "labelledBy": {
2234
2278
  "type": "string",
@@ -2283,7 +2327,7 @@
2283
2327
  "tier": "primitive",
2284
2328
  "docExempt": false,
2285
2329
  "sourcePath": "src/app/components/Table.tsx",
2286
- "figmaLink": "https://www.figma.com/design/c8MaVgwxOlxm4wr8wnH0Z4/HDS-Tokens-Components?node-id=89-300",
2330
+ "figmaLink": "https://www.figma.com/design/2VgBbVpKiDnu0aftJEVyBQ/HDS-Tokens-Components?node-id=89-300",
2287
2331
  "storyFiles": [
2288
2332
  "src/stories/table.stories.tsx"
2289
2333
  ],
@@ -2310,7 +2354,8 @@
2310
2354
  "reason": "a short list of items"
2311
2355
  }
2312
2356
  ]
2313
- }
2357
+ },
2358
+ "core": true
2314
2359
  },
2315
2360
  "Tag": {
2316
2361
  "category": "Inputs",
@@ -2319,7 +2364,7 @@
2319
2364
  "hidden": false,
2320
2365
  "filePath": "src/app/components/tag.tsx",
2321
2366
  "description": "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 the visible surface compact. Colors (background, border-color, color) live in the pill's cva variants, painted through `group-hover`/`group-active` so the pill reacts to interaction on the shared outer button (converted off the former .hds-tag-btn/.hds-tag-pill theme.css rules for #60 — same behavior, now token-driven Tailwind classes). The `active` prop (aria-pressed selected state) is not one of the variant contract's four axes — it's expressed as the pill's `selected` cva variant, carrying the same rest → hover → pressed → focus-visible state matrix the contract expects, just keyed by selection instead of tone/size/density.",
2322
- "figmaUrl": "https://www.figma.com/design/c8MaVgwxOlxm4wr8wnH0Z4/HDS-Tokens-Components?node-id=32-11",
2367
+ "figmaUrl": "https://www.figma.com/design/2VgBbVpKiDnu0aftJEVyBQ/HDS-Tokens-Components?node-id=32-11",
2323
2368
  "figmaId": null,
2324
2369
  "preview": {
2325
2370
  "exportName": "Tag",
@@ -2435,7 +2480,7 @@
2435
2480
  "tier": "primitive",
2436
2481
  "docExempt": false,
2437
2482
  "sourcePath": "src/app/components/Tag.tsx",
2438
- "figmaLink": "https://www.figma.com/design/c8MaVgwxOlxm4wr8wnH0Z4/HDS-Tokens-Components?node-id=32-11",
2483
+ "figmaLink": "https://www.figma.com/design/2VgBbVpKiDnu0aftJEVyBQ/HDS-Tokens-Components?node-id=32-11",
2439
2484
  "storyFiles": [
2440
2485
  "src/stories/tag.stories.tsx"
2441
2486
  ],
@@ -2456,7 +2501,8 @@
2456
2501
  "reason": "a read-only status or count"
2457
2502
  }
2458
2503
  ]
2459
- }
2504
+ },
2505
+ "core": true
2460
2506
  },
2461
2507
  "Surface": {
2462
2508
  "category": "Layout",
@@ -2465,7 +2511,7 @@
2465
2511
  "hidden": false,
2466
2512
  "filePath": "src/app/components/surface.tsx",
2467
2513
  "description": "Surface — governed inset surface primitive. Enforces the \"Surface Inset\" rule: backgrounds MUST have internal padding. - Default padding: px24 (cards) | px16 (items) - Default border: none (elevation model — use shadow for lift) - Radius: `rounded-lg` (role radius + 4px), the one container radius shared with Card - shadow prop: applies a two-layer elevation shadow for card lift Usage: <Surface>Card content</Surface> <Surface padding=\"item\">Compact item</Surface> <Surface shadow>Lifted card with elevation shadow.</Surface>",
2468
- "figmaUrl": "https://www.figma.com/design/c8MaVgwxOlxm4wr8wnH0Z4/HDS-Tokens-Components?node-id=89-27",
2514
+ "figmaUrl": "https://www.figma.com/design/2VgBbVpKiDnu0aftJEVyBQ/HDS-Tokens-Components?node-id=89-27",
2469
2515
  "figmaId": null,
2470
2516
  "preview": {
2471
2517
  "exportName": "Surface",
@@ -2479,6 +2525,7 @@
2479
2525
  "src/app/components/divider.tsx",
2480
2526
  "src/app/components/empty-state.tsx",
2481
2527
  "src/app/components/error-pattern.tsx",
2528
+ "src/app/components/form-control.ts",
2482
2529
  "src/app/components/metric-tiles.tsx",
2483
2530
  "src/app/components/popover.tsx",
2484
2531
  "src/app/components/slider.tsx",
@@ -2559,7 +2606,7 @@
2559
2606
  "tier": "primitive",
2560
2607
  "docExempt": true,
2561
2608
  "sourcePath": "src/app/components/Surface.tsx",
2562
- "figmaLink": "https://www.figma.com/design/c8MaVgwxOlxm4wr8wnH0Z4/HDS-Tokens-Components?node-id=89-27",
2609
+ "figmaLink": "https://www.figma.com/design/2VgBbVpKiDnu0aftJEVyBQ/HDS-Tokens-Components?node-id=89-27",
2563
2610
  "states": [
2564
2611
  "default"
2565
2612
  ],
@@ -2587,7 +2634,8 @@
2587
2634
  }
2588
2635
  ]
2589
2636
  },
2590
- "aiRules": "Use Surface only when content needs a background-bearing inset wrapper. Do NOT use Surface for macro page layouts, section spacing, or pure width constraints. Do NOT nest extra padded wrappers inside Surface to simulate another card. Do NOT recreate surface behavior with raw div padding, backgroundColor, or border styles elsewhere."
2637
+ "aiRules": "Use Surface only when content needs a background-bearing inset wrapper. Do NOT use Surface for macro page layouts, section spacing, or pure width constraints. Do NOT nest extra padded wrappers inside Surface to simulate another card. Do NOT recreate surface behavior with raw div padding, backgroundColor, or border styles elsewhere.",
2638
+ "core": true
2591
2639
  },
2592
2640
  "Card": {
2593
2641
  "category": "Display",
@@ -2596,7 +2644,7 @@
2596
2644
  "hidden": false,
2597
2645
  "filePath": "src/app/components/card.tsx",
2598
2646
  "description": "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.",
2599
- "figmaUrl": "https://www.figma.com/design/c8MaVgwxOlxm4wr8wnH0Z4/HDS-Tokens-Components?node-id=39-11",
2647
+ "figmaUrl": "https://www.figma.com/design/2VgBbVpKiDnu0aftJEVyBQ/HDS-Tokens-Components?node-id=39-11",
2600
2648
  "figmaId": null,
2601
2649
  "consumers": [
2602
2650
  "src/app/components/box-sx.test.ts",
@@ -2770,7 +2818,7 @@
2770
2818
  "Body",
2771
2819
  "Footer"
2772
2820
  ],
2773
- "figmaLink": "https://www.figma.com/design/c8MaVgwxOlxm4wr8wnH0Z4/HDS-Tokens-Components?node-id=39-11",
2821
+ "figmaLink": "https://www.figma.com/design/2VgBbVpKiDnu0aftJEVyBQ/HDS-Tokens-Components?node-id=39-11",
2774
2822
  "propConstraints": {
2775
2823
  "bordered": {
2776
2824
  "type": "boolean"
@@ -2816,6 +2864,7 @@
2816
2864
  "primitives-card--padding-variants",
2817
2865
  "primitives-card--progress-slot",
2818
2866
  "primitives-card--selectable",
2867
+ "primitives-card--tone-matrix",
2819
2868
  "primitives-card--variant-accent"
2820
2869
  ],
2821
2870
  "usage": {
@@ -2831,7 +2880,8 @@
2831
2880
  "reason": "a single headline figure"
2832
2881
  }
2833
2882
  ]
2834
- }
2883
+ },
2884
+ "core": true
2835
2885
  },
2836
2886
  "Text": {
2837
2887
  "category": "Typography",
@@ -2866,7 +2916,7 @@
2866
2916
  "a11yRules": [],
2867
2917
  "categorySource": "jsdoc",
2868
2918
  "governedCategory": true,
2869
- "figmaUrl": null,
2919
+ "figmaUrl": "https://www.figma.com/design/2VgBbVpKiDnu0aftJEVyBQ/HDS-Tokens-Components?node-id=2022-31",
2870
2920
  "figmaId": null,
2871
2921
  "preview": {
2872
2922
  "exportName": "Text",
@@ -2903,7 +2953,7 @@
2903
2953
  "tier": "primitive",
2904
2954
  "docExempt": true,
2905
2955
  "sourcePath": "src/app/components/Text.tsx",
2906
- "figmaLink": null,
2956
+ "figmaLink": "https://www.figma.com/design/2VgBbVpKiDnu0aftJEVyBQ/HDS-Tokens-Components?node-id=2022-31",
2907
2957
  "storyFiles": [
2908
2958
  "src/stories/text.stories.tsx"
2909
2959
  ],
@@ -2931,7 +2981,8 @@
2931
2981
  "reason": "a keyboard key hint"
2932
2982
  }
2933
2983
  ]
2934
- }
2984
+ },
2985
+ "core": true
2935
2986
  },
2936
2987
  "Dialog": {
2937
2988
  "category": "Overlays",
@@ -2941,7 +2992,7 @@
2941
2992
  "docExempt": true,
2942
2993
  "filePath": "src/app/components/dialog.tsx",
2943
2994
  "description": "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.",
2944
- "figmaUrl": "https://www.figma.com/design/c8MaVgwxOlxm4wr8wnH0Z4/HDS-Tokens-Components?node-id=93-27",
2995
+ "figmaUrl": "https://www.figma.com/design/2VgBbVpKiDnu0aftJEVyBQ/HDS-Tokens-Components?node-id=93-27",
2945
2996
  "figmaId": null,
2946
2997
  "tier": "primitive",
2947
2998
  "preview": {
@@ -3128,7 +3179,7 @@
3128
3179
  "Description",
3129
3180
  "Close"
3130
3181
  ],
3131
- "figmaLink": "https://www.figma.com/design/c8MaVgwxOlxm4wr8wnH0Z4/HDS-Tokens-Components?node-id=93-27",
3182
+ "figmaLink": "https://www.figma.com/design/2VgBbVpKiDnu0aftJEVyBQ/HDS-Tokens-Components?node-id=93-27",
3132
3183
  "propConstraints": {
3133
3184
  "defaultOpen": {
3134
3185
  "type": "boolean"
@@ -3165,6 +3216,10 @@
3165
3216
  {
3166
3217
  "component": "ToastProvider",
3167
3218
  "reason": "a brief confirmation"
3219
+ },
3220
+ {
3221
+ "component": "AlertDialog",
3222
+ "reason": "confirming a destructive or irreversible action"
3168
3223
  }
3169
3224
  ]
3170
3225
  },
@@ -3185,7 +3240,8 @@
3185
3240
  "keys": "Shift+Tab",
3186
3241
  "effect": "Cycles focus backwards inside the open dialog."
3187
3242
  }
3188
- ]
3243
+ ],
3244
+ "core": true
3189
3245
  },
3190
3246
  "Button": {
3191
3247
  "category": "Actions",
@@ -3195,9 +3251,9 @@
3195
3251
  "docExempt": false,
3196
3252
  "filePath": "src/app/components/button.tsx",
3197
3253
  "description": "Triggers an action when activated.",
3198
- "figmaUrl": "https://www.figma.com/design/c8MaVgwxOlxm4wr8wnH0Z4/HDS-Tokens-Components?node-id=28-138",
3254
+ "figmaUrl": "https://www.figma.com/design/2VgBbVpKiDnu0aftJEVyBQ/HDS-Tokens-Components?node-id=28-138",
3199
3255
  "figmaId": null,
3200
- "figmaLink": "https://www.figma.com/design/c8MaVgwxOlxm4wr8wnH0Z4/HDS-Tokens-Components?node-id=28-138",
3256
+ "figmaLink": "https://www.figma.com/design/2VgBbVpKiDnu0aftJEVyBQ/HDS-Tokens-Components?node-id=28-138",
3201
3257
  "tier": "primitive",
3202
3258
  "preview": {
3203
3259
  "exportName": "Button",
@@ -3224,6 +3280,7 @@
3224
3280
  "src/app/components/pagination.tsx",
3225
3281
  "src/app/components/popover.tsx",
3226
3282
  "src/app/components/segmented-control.tsx",
3283
+ "src/app/components/select.tsx",
3227
3284
  "src/app/components/toast.tsx",
3228
3285
  "src/app/context/DemoStateContext.tsx",
3229
3286
  "src/app/design-system/generated-token-descriptions.ts",
@@ -3457,7 +3514,8 @@
3457
3514
  "primitives-button--primary",
3458
3515
  "primitives-button--secondary",
3459
3516
  "primitives-button--small",
3460
- "primitives-button--tertiary"
3517
+ "primitives-button--tertiary",
3518
+ "primitives-button--tone-matrix"
3461
3519
  ],
3462
3520
  "usage": {
3463
3521
  "when": "Trigger an action (submit, save, open a dialog) with a text label and optional icons; for an icon-only control pass iconOnly with iconLeft and label; for an on/off toggle pass pressed.",
@@ -3468,7 +3526,8 @@
3468
3526
  "reason": "navigation to another page"
3469
3527
  }
3470
3528
  ]
3471
- }
3529
+ },
3530
+ "core": true
3472
3531
  },
3473
3532
  "Callout": {
3474
3533
  "category": "Feedback",
@@ -3478,9 +3537,9 @@
3478
3537
  "docExempt": false,
3479
3538
  "filePath": "src/app/components/callout.tsx",
3480
3539
  "description": "Tone-driven side-rule callout for status, quotes, hypotheses.",
3481
- "figmaUrl": "https://www.figma.com/design/c8MaVgwxOlxm4wr8wnH0Z4/HDS-Tokens-Components?node-id=88-85",
3540
+ "figmaUrl": "https://www.figma.com/design/2VgBbVpKiDnu0aftJEVyBQ/HDS-Tokens-Components?node-id=88-85",
3482
3541
  "figmaId": null,
3483
- "figmaLink": "https://www.figma.com/design/c8MaVgwxOlxm4wr8wnH0Z4/HDS-Tokens-Components?node-id=88-85",
3542
+ "figmaLink": "https://www.figma.com/design/2VgBbVpKiDnu0aftJEVyBQ/HDS-Tokens-Components?node-id=88-85",
3484
3543
  "tier": "primitive",
3485
3544
  "preview": {
3486
3545
  "exportName": "Callout",
@@ -3555,9 +3614,9 @@
3555
3614
  "docExempt": false,
3556
3615
  "filePath": "src/app/components/empty-state.tsx",
3557
3616
  "description": "EmptyState — consistent no-data placeholder for lists, grids, and sections.",
3558
- "figmaUrl": "https://www.figma.com/design/c8MaVgwxOlxm4wr8wnH0Z4/HDS-Tokens-Components?node-id=88-352",
3617
+ "figmaUrl": "https://www.figma.com/design/2VgBbVpKiDnu0aftJEVyBQ/HDS-Tokens-Components?node-id=88-352",
3559
3618
  "figmaId": null,
3560
- "figmaLink": "https://www.figma.com/design/c8MaVgwxOlxm4wr8wnH0Z4/HDS-Tokens-Components?node-id=88-352",
3619
+ "figmaLink": "https://www.figma.com/design/2VgBbVpKiDnu0aftJEVyBQ/HDS-Tokens-Components?node-id=88-352",
3561
3620
  "tier": "primitive",
3562
3621
  "preview": {
3563
3622
  "exportName": "EmptyState",
@@ -3614,7 +3673,8 @@
3614
3673
  }
3615
3674
  ]
3616
3675
  },
3617
- "aiRules": "Use only for inline empty states inside an existing section. Do NOT use for full-page errors (use ErrorPage) or for loading states (use a skeleton). Do NOT wrap in Surface or Card — the empty state is a typographic message, not a chrome-bearing container."
3676
+ "aiRules": "Use only for inline empty states inside an existing section. Do NOT use for full-page errors (use ErrorPage) or for loading states (use a skeleton). Do NOT wrap in Surface or Card — the empty state is a typographic message, not a chrome-bearing container.",
3677
+ "core": true
3618
3678
  },
3619
3679
  "Field": {
3620
3680
  "category": "Display",
@@ -3624,9 +3684,9 @@
3624
3684
  "docExempt": false,
3625
3685
  "filePath": "src/app/components/field.tsx",
3626
3686
  "description": "Caption label paired with a value — used in metadata grids and read-only forms.",
3627
- "figmaUrl": "https://www.figma.com/design/c8MaVgwxOlxm4wr8wnH0Z4/HDS-Tokens-Components?node-id=85-81",
3687
+ "figmaUrl": "https://www.figma.com/design/2VgBbVpKiDnu0aftJEVyBQ/HDS-Tokens-Components?node-id=85-81",
3628
3688
  "figmaId": null,
3629
- "figmaLink": "https://www.figma.com/design/c8MaVgwxOlxm4wr8wnH0Z4/HDS-Tokens-Components?node-id=85-81",
3689
+ "figmaLink": "https://www.figma.com/design/2VgBbVpKiDnu0aftJEVyBQ/HDS-Tokens-Components?node-id=85-81",
3630
3690
  "tier": "primitive",
3631
3691
  "preview": {
3632
3692
  "exportName": "Field",
@@ -3730,7 +3790,8 @@
3730
3790
  "reason": "a headline figure inside a Card"
3731
3791
  }
3732
3792
  ]
3733
- }
3793
+ },
3794
+ "core": true
3734
3795
  },
3735
3796
  "Page": {
3736
3797
  "category": "Layout",
@@ -3824,10 +3885,10 @@
3824
3885
  "hidden": false,
3825
3886
  "docExempt": false,
3826
3887
  "filePath": "src/app/components/stat.tsx",
3827
- "description": "Headline metric — large value, uppercase caption label, optional sub-line.",
3828
- "figmaUrl": "https://www.figma.com/design/c8MaVgwxOlxm4wr8wnH0Z4/HDS-Tokens-Components?node-id=88-247",
3888
+ "description": "Headline metric — large value, caption label, optional sub-line.",
3889
+ "figmaUrl": "https://www.figma.com/design/2VgBbVpKiDnu0aftJEVyBQ/HDS-Tokens-Components?node-id=88-247",
3829
3890
  "figmaId": null,
3830
- "figmaLink": "https://www.figma.com/design/c8MaVgwxOlxm4wr8wnH0Z4/HDS-Tokens-Components?node-id=88-247",
3891
+ "figmaLink": "https://www.figma.com/design/2VgBbVpKiDnu0aftJEVyBQ/HDS-Tokens-Components?node-id=88-247",
3831
3892
  "tier": "primitive",
3832
3893
  "preview": {
3833
3894
  "exportName": "Stat",
@@ -3902,9 +3963,13 @@
3902
3963
  "primitives-stat--with-sub"
3903
3964
  ],
3904
3965
  "usage": {
3905
- "when": "Show one standalone headline figure with its label and an optional sub-line.",
3906
- "whenNot": "A figure inside a Card, or a status with a trailing badge.",
3966
+ "when": "Show one headline figure inline, inside prose or a dense list, with its label and an optional sub-line.",
3967
+ "whenNot": "A row of headline numbers on a screen, a figure inside a Card, or a status with a trailing badge.",
3907
3968
  "useInstead": [
3969
+ {
3970
+ "component": "MetricTiles",
3971
+ "reason": "a row of headline numbers (one MetricTile per number)"
3972
+ },
3908
3973
  {
3909
3974
  "component": "Card.Metric",
3910
3975
  "reason": "a figure inside a Card (hds#254 folds Stat into the Card slot)"
@@ -3924,9 +3989,9 @@
3924
3989
  "docExempt": false,
3925
3990
  "filePath": "src/app/components/status-list-item.tsx",
3926
3991
  "description": "Status dot + title row with optional muted notes and trailing slot (e.g. badge).",
3927
- "figmaUrl": "https://www.figma.com/design/c8MaVgwxOlxm4wr8wnH0Z4/HDS-Tokens-Components?node-id=88-350",
3992
+ "figmaUrl": "https://www.figma.com/design/2VgBbVpKiDnu0aftJEVyBQ/HDS-Tokens-Components?node-id=88-350",
3928
3993
  "figmaId": null,
3929
- "figmaLink": "https://www.figma.com/design/c8MaVgwxOlxm4wr8wnH0Z4/HDS-Tokens-Components?node-id=88-350",
3994
+ "figmaLink": "https://www.figma.com/design/2VgBbVpKiDnu0aftJEVyBQ/HDS-Tokens-Components?node-id=88-350",
3930
3995
  "tier": "pattern",
3931
3996
  "preview": {
3932
3997
  "exportName": "StatusListItem",
@@ -4006,9 +4071,9 @@
4006
4071
  "docExempt": false,
4007
4072
  "filePath": "src/app/components/status-tile.tsx",
4008
4073
  "description": "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 colour belongs in the trailing slot, never as a left rule on the tile — every tile should look the same so feedback signals stay reserved for genuinely interrupting states.",
4009
- "figmaUrl": "https://www.figma.com/design/c8MaVgwxOlxm4wr8wnH0Z4/HDS-Tokens-Components?node-id=88-292",
4074
+ "figmaUrl": "https://www.figma.com/design/2VgBbVpKiDnu0aftJEVyBQ/HDS-Tokens-Components?node-id=88-292",
4010
4075
  "figmaId": null,
4011
- "figmaLink": "https://www.figma.com/design/c8MaVgwxOlxm4wr8wnH0Z4/HDS-Tokens-Components?node-id=88-292",
4076
+ "figmaLink": "https://www.figma.com/design/2VgBbVpKiDnu0aftJEVyBQ/HDS-Tokens-Components?node-id=88-292",
4012
4077
  "tier": "pattern",
4013
4078
  "preview": {
4014
4079
  "exportName": "StatusTile",
@@ -4069,11 +4134,15 @@
4069
4134
  ],
4070
4135
  "usage": {
4071
4136
  "when": "Show a titled status block with optional notes and a trailing badge or affordance.",
4072
- "whenNot": "A single headline figure, or a row inside a list.",
4137
+ "whenNot": "A headline number (never a value), or a row inside a list.",
4073
4138
  "useInstead": [
4139
+ {
4140
+ "component": "MetricTiles",
4141
+ "reason": "a row of headline numbers"
4142
+ },
4074
4143
  {
4075
4144
  "component": "Card.Metric",
4076
- "reason": "a headline figure (hds#254 folds StatusTile into the Card slot)"
4145
+ "reason": "a headline figure inside a Card (hds#254 folds StatusTile into the Card slot)"
4077
4146
  },
4078
4147
  {
4079
4148
  "component": "StatusListItem",
@@ -4171,9 +4240,9 @@
4171
4240
  "governedCategory": true,
4172
4241
  "hidden": false,
4173
4242
  "docExempt": false,
4174
- "figmaUrl": "https://www.figma.com/design/c8MaVgwxOlxm4wr8wnH0Z4/HDS-Tokens-Components?node-id=31-15",
4243
+ "figmaUrl": "https://www.figma.com/design/2VgBbVpKiDnu0aftJEVyBQ/HDS-Tokens-Components?node-id=31-15",
4175
4244
  "figmaId": null,
4176
- "figmaLink": "https://www.figma.com/design/c8MaVgwxOlxm4wr8wnH0Z4/HDS-Tokens-Components?node-id=31-15",
4245
+ "figmaLink": "https://www.figma.com/design/2VgBbVpKiDnu0aftJEVyBQ/HDS-Tokens-Components?node-id=31-15",
4177
4246
  "tier": "primitive",
4178
4247
  "preview": {
4179
4248
  "exportName": "Badge",
@@ -4185,8 +4254,6 @@
4185
4254
  "src/app/components/badge.test.tsx",
4186
4255
  "src/app/components/card.tsx",
4187
4256
  "src/app/components/page-header.tsx",
4188
- "src/app/components/status-dot.test.tsx",
4189
- "src/app/components/status-dot.tsx",
4190
4257
  "src/app/components/tag.tsx",
4191
4258
  "src/app/design-system/generated-token-descriptions.ts",
4192
4259
  "src/mui/index.ts",
@@ -4230,7 +4297,8 @@
4230
4297
  "reason": "a message that needs a sentence"
4231
4298
  }
4232
4299
  ]
4233
- }
4300
+ },
4301
+ "core": true
4234
4302
  },
4235
4303
  "AssetImg": {
4236
4304
  "category": "Display",
@@ -4240,9 +4308,9 @@
4240
4308
  "docExempt": false,
4241
4309
  "filePath": "src/app/components/asset-img.tsx",
4242
4310
  "description": "AssetImg - responsive asset frame with fallback placeholder handling. Contexts: default, lightbox, and detail.",
4243
- "figmaUrl": null,
4311
+ "figmaUrl": "https://www.figma.com/design/2VgBbVpKiDnu0aftJEVyBQ/HDS-Tokens-Components?node-id=2041-67",
4244
4312
  "figmaId": null,
4245
- "figmaLink": null,
4313
+ "figmaLink": "https://www.figma.com/design/2VgBbVpKiDnu0aftJEVyBQ/HDS-Tokens-Components?node-id=2041-67",
4246
4314
  "tier": "primitive",
4247
4315
  "preview": {
4248
4316
  "exportName": "AssetImg",
@@ -4414,9 +4482,9 @@
4414
4482
  "docExempt": false,
4415
4483
  "filePath": "src/app/components/tabs.tsx",
4416
4484
  "description": "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-level @figma would silently claim this node for all four.",
4417
- "figmaUrl": "https://www.figma.com/design/c8MaVgwxOlxm4wr8wnH0Z4/HDS-Tokens-Components?node-id=86-89",
4485
+ "figmaUrl": "https://www.figma.com/design/2VgBbVpKiDnu0aftJEVyBQ/HDS-Tokens-Components?node-id=86-89",
4418
4486
  "figmaId": null,
4419
- "figmaLink": "https://www.figma.com/design/c8MaVgwxOlxm4wr8wnH0Z4/HDS-Tokens-Components?node-id=86-89",
4487
+ "figmaLink": "https://www.figma.com/design/2VgBbVpKiDnu0aftJEVyBQ/HDS-Tokens-Components?node-id=86-89",
4420
4488
  "tier": "primitive",
4421
4489
  "preview": {
4422
4490
  "exportName": "Tabs",
@@ -4499,7 +4567,8 @@
4499
4567
  "reason": "optional content that expands in place"
4500
4568
  }
4501
4569
  ]
4502
- }
4570
+ },
4571
+ "core": true
4503
4572
  },
4504
4573
  "TabsContent": {
4505
4574
  "category": "Navigation",
@@ -4657,7 +4726,7 @@
4657
4726
  "hidden": false,
4658
4727
  "filePath": "src/app/components/radio.tsx",
4659
4728
  "description": "Radio — radio button with animated selection indicator.",
4660
- "figmaUrl": "https://www.figma.com/design/c8MaVgwxOlxm4wr8wnH0Z4/HDS-Tokens-Components?node-id=36-17",
4729
+ "figmaUrl": "https://www.figma.com/design/2VgBbVpKiDnu0aftJEVyBQ/HDS-Tokens-Components?node-id=36-17",
4661
4730
  "figmaId": null,
4662
4731
  "preview": {
4663
4732
  "exportName": "Radio",
@@ -4707,7 +4776,7 @@
4707
4776
  "componentProperties": [],
4708
4777
  "tier": "primitive",
4709
4778
  "docExempt": false,
4710
- "figmaLink": "https://www.figma.com/design/c8MaVgwxOlxm4wr8wnH0Z4/HDS-Tokens-Components?node-id=36-17",
4779
+ "figmaLink": "https://www.figma.com/design/2VgBbVpKiDnu0aftJEVyBQ/HDS-Tokens-Components?node-id=36-17",
4711
4780
  "storyFiles": [
4712
4781
  "src/stories/radio.stories.tsx"
4713
4782
  ],
@@ -4735,7 +4804,8 @@
4735
4804
  "reason": "a compact switch between two to five views or modes"
4736
4805
  }
4737
4806
  ]
4738
- }
4807
+ },
4808
+ "core": true
4739
4809
  },
4740
4810
  "Select": {
4741
4811
  "category": "Inputs",
@@ -4744,7 +4814,7 @@
4744
4814
  "hidden": false,
4745
4815
  "filePath": "src/app/components/select.tsx",
4746
4816
  "description": "Select — dropdown selector built on Radix Select (ADR-001 Radix convention). Radix owns the listbox a11y contract: managed focus + active-descendant, typeahead, full keyboard (Home/End/PageUp-Down/wrap), Popper collision/flip positioning, and dismissal. The HDS surface is styled with the token-backed Tailwind idiom used by tabs.tsx / command-palette.tsx; `ref` targets the trigger button.",
4747
- "figmaUrl": "https://www.figma.com/design/c8MaVgwxOlxm4wr8wnH0Z4/HDS-Tokens-Components?node-id=82-49",
4817
+ "figmaUrl": "https://www.figma.com/design/2VgBbVpKiDnu0aftJEVyBQ/HDS-Tokens-Components?node-id=82-49",
4748
4818
  "figmaId": null,
4749
4819
  "preview": {
4750
4820
  "exportName": "Select",
@@ -4754,6 +4824,7 @@
4754
4824
  "src/app/components/checkbox.test.tsx",
4755
4825
  "src/app/components/combobox.test.tsx",
4756
4826
  "src/app/components/combobox.tsx",
4827
+ "src/app/components/form-control.ts",
4757
4828
  "src/app/components/form.tsx",
4758
4829
  "src/app/components/input.tsx",
4759
4830
  "src/app/components/menu.tsx",
@@ -4820,7 +4891,7 @@
4820
4891
  "componentProperties": [],
4821
4892
  "tier": "primitive",
4822
4893
  "docExempt": false,
4823
- "figmaLink": "https://www.figma.com/design/c8MaVgwxOlxm4wr8wnH0Z4/HDS-Tokens-Components?node-id=82-49",
4894
+ "figmaLink": "https://www.figma.com/design/2VgBbVpKiDnu0aftJEVyBQ/HDS-Tokens-Components?node-id=82-49",
4824
4895
  "storyFiles": [
4825
4896
  "src/stories/select.stories.tsx"
4826
4897
  ],
@@ -4872,7 +4943,8 @@
4872
4943
  "keys": "Tab",
4873
4944
  "effect": "Does not leave the open listbox."
4874
4945
  }
4875
- ]
4946
+ ],
4947
+ "core": true
4876
4948
  },
4877
4949
  "Slider": {
4878
4950
  "category": "Inputs",
@@ -4881,13 +4953,14 @@
4881
4953
  "hidden": false,
4882
4954
  "filePath": "src/app/components/slider.tsx",
4883
4955
  "description": "Slider — range slider with label and value display.",
4884
- "figmaUrl": "https://www.figma.com/design/c8MaVgwxOlxm4wr8wnH0Z4/HDS-Tokens-Components?node-id=82-265",
4956
+ "figmaUrl": "https://www.figma.com/design/2VgBbVpKiDnu0aftJEVyBQ/HDS-Tokens-Components?node-id=82-265",
4885
4957
  "figmaId": null,
4886
4958
  "preview": {
4887
4959
  "exportName": "Slider",
4888
4960
  "sizing": "panel"
4889
4961
  },
4890
4962
  "consumers": [
4963
+ "src/app/components/form-control.ts",
4891
4964
  "src/stories/slider.stories.tsx"
4892
4965
  ],
4893
4966
  "tokenMapping": {
@@ -4927,7 +5000,7 @@
4927
5000
  "componentProperties": [],
4928
5001
  "tier": "primitive",
4929
5002
  "docExempt": false,
4930
- "figmaLink": "https://www.figma.com/design/c8MaVgwxOlxm4wr8wnH0Z4/HDS-Tokens-Components?node-id=82-265",
5003
+ "figmaLink": "https://www.figma.com/design/2VgBbVpKiDnu0aftJEVyBQ/HDS-Tokens-Components?node-id=82-265",
4931
5004
  "storyFiles": [
4932
5005
  "src/stories/slider.stories.tsx"
4933
5006
  ],
@@ -4946,7 +5019,8 @@
4946
5019
  "reason": "a precise typed value (type=\"number\")"
4947
5020
  }
4948
5021
  ]
4949
- }
5022
+ },
5023
+ "core": true
4950
5024
  },
4951
5025
  "Toggle": {
4952
5026
  "category": "Inputs",
@@ -4955,7 +5029,7 @@
4955
5029
  "hidden": false,
4956
5030
  "filePath": "src/app/components/toggle.tsx",
4957
5031
  "description": "Toggle — boolean on/off toggle with animated thumb.",
4958
- "figmaUrl": "https://www.figma.com/design/c8MaVgwxOlxm4wr8wnH0Z4/HDS-Tokens-Components?node-id=37-19",
5032
+ "figmaUrl": "https://www.figma.com/design/2VgBbVpKiDnu0aftJEVyBQ/HDS-Tokens-Components?node-id=37-19",
4959
5033
  "figmaId": null,
4960
5034
  "preview": {
4961
5035
  "exportName": "Toggle",
@@ -5002,7 +5076,7 @@
5002
5076
  "componentProperties": [],
5003
5077
  "tier": "primitive",
5004
5078
  "docExempt": false,
5005
- "figmaLink": "https://www.figma.com/design/c8MaVgwxOlxm4wr8wnH0Z4/HDS-Tokens-Components?node-id=37-19",
5079
+ "figmaLink": "https://www.figma.com/design/2VgBbVpKiDnu0aftJEVyBQ/HDS-Tokens-Components?node-id=37-19",
5006
5080
  "storyFiles": [
5007
5081
  "src/stories/toggle.stories.tsx"
5008
5082
  ],
@@ -5026,7 +5100,8 @@
5026
5100
  "reason": "one choice from a set"
5027
5101
  }
5028
5102
  ]
5029
- }
5103
+ },
5104
+ "core": true
5030
5105
  },
5031
5106
  "Avatar": {
5032
5107
  "category": "Display",
@@ -5036,9 +5111,9 @@
5036
5111
  "docExempt": false,
5037
5112
  "filePath": "src/app/components/avatar.tsx",
5038
5113
  "description": "Circular avatar. Renders the image when available, else initials from `alt`.",
5039
- "figmaUrl": "https://www.figma.com/design/c8MaVgwxOlxm4wr8wnH0Z4/HDS-Tokens-Components?node-id=34-18",
5114
+ "figmaUrl": "https://www.figma.com/design/2VgBbVpKiDnu0aftJEVyBQ/HDS-Tokens-Components?node-id=34-18",
5040
5115
  "figmaId": null,
5041
- "figmaLink": "https://www.figma.com/design/c8MaVgwxOlxm4wr8wnH0Z4/HDS-Tokens-Components?node-id=34-18",
5116
+ "figmaLink": "https://www.figma.com/design/2VgBbVpKiDnu0aftJEVyBQ/HDS-Tokens-Components?node-id=34-18",
5042
5117
  "tier": "primitive",
5043
5118
  "preview": {
5044
5119
  "exportName": "Avatar",
@@ -5110,7 +5185,8 @@
5110
5185
  "reason": "a status marker"
5111
5186
  }
5112
5187
  ]
5113
- }
5188
+ },
5189
+ "core": true
5114
5190
  },
5115
5191
  "Progress": {
5116
5192
  "category": "Feedback",
@@ -5120,9 +5196,9 @@
5120
5196
  "docExempt": false,
5121
5197
  "filePath": "src/app/components/progress.tsx",
5122
5198
  "description": "Linear bar or circular ring. Determinate when `value` is a number, else indeterminate.",
5123
- "figmaUrl": "https://www.figma.com/design/c8MaVgwxOlxm4wr8wnH0Z4/HDS-Tokens-Components?node-id=88-91",
5199
+ "figmaUrl": "https://www.figma.com/design/2VgBbVpKiDnu0aftJEVyBQ/HDS-Tokens-Components?node-id=88-91",
5124
5200
  "figmaId": null,
5125
- "figmaLink": "https://www.figma.com/design/c8MaVgwxOlxm4wr8wnH0Z4/HDS-Tokens-Components?node-id=88-91",
5201
+ "figmaLink": "https://www.figma.com/design/2VgBbVpKiDnu0aftJEVyBQ/HDS-Tokens-Components?node-id=88-91",
5126
5202
  "tier": "primitive",
5127
5203
  "preview": {
5128
5204
  "exportName": "Progress",
@@ -5214,7 +5290,8 @@
5214
5290
  "reason": "placeholder shapes for loading content"
5215
5291
  }
5216
5292
  ]
5217
- }
5293
+ },
5294
+ "core": true
5218
5295
  },
5219
5296
  "Skeleton": {
5220
5297
  "category": "Feedback",
@@ -5224,9 +5301,9 @@
5224
5301
  "docExempt": false,
5225
5302
  "filePath": "src/app/components/skeleton.tsx",
5226
5303
  "description": "Decorative loading placeholder. Marked aria-hidden — announce the loading state on the surrounding region (e.g. aria-busy) rather than per skeleton.",
5227
- "figmaUrl": "https://www.figma.com/design/c8MaVgwxOlxm4wr8wnH0Z4/HDS-Tokens-Components?node-id=88-95",
5304
+ "figmaUrl": "https://www.figma.com/design/2VgBbVpKiDnu0aftJEVyBQ/HDS-Tokens-Components?node-id=88-95",
5228
5305
  "figmaId": null,
5229
- "figmaLink": "https://www.figma.com/design/c8MaVgwxOlxm4wr8wnH0Z4/HDS-Tokens-Components?node-id=88-95",
5306
+ "figmaLink": "https://www.figma.com/design/2VgBbVpKiDnu0aftJEVyBQ/HDS-Tokens-Components?node-id=88-95",
5230
5307
  "tier": "primitive",
5231
5308
  "preview": {
5232
5309
  "exportName": "Skeleton",
@@ -5292,7 +5369,8 @@
5292
5369
  "reason": "a short wait with no layout to reserve"
5293
5370
  }
5294
5371
  ]
5295
- }
5372
+ },
5373
+ "core": true
5296
5374
  },
5297
5375
  "Spinner": {
5298
5376
  "category": "Feedback",
@@ -5302,9 +5380,9 @@
5302
5380
  "docExempt": false,
5303
5381
  "filePath": "src/app/components/spinner.tsx",
5304
5382
  "description": "Indeterminate spinner. Inherits the surrounding text color via currentColor.",
5305
- "figmaUrl": "https://www.figma.com/design/c8MaVgwxOlxm4wr8wnH0Z4/HDS-Tokens-Components?node-id=88-106",
5383
+ "figmaUrl": "https://www.figma.com/design/2VgBbVpKiDnu0aftJEVyBQ/HDS-Tokens-Components?node-id=88-106",
5306
5384
  "figmaId": null,
5307
- "figmaLink": "https://www.figma.com/design/c8MaVgwxOlxm4wr8wnH0Z4/HDS-Tokens-Components?node-id=88-106",
5385
+ "figmaLink": "https://www.figma.com/design/2VgBbVpKiDnu0aftJEVyBQ/HDS-Tokens-Components?node-id=88-106",
5308
5386
  "tier": "primitive",
5309
5387
  "preview": {
5310
5388
  "exportName": "Spinner",
@@ -5364,7 +5442,8 @@
5364
5442
  "reason": "a region whose layout is known"
5365
5443
  }
5366
5444
  ]
5367
- }
5445
+ },
5446
+ "core": true
5368
5447
  },
5369
5448
  "Breadcrumb": {
5370
5449
  "category": "Navigation",
@@ -5374,9 +5453,9 @@
5374
5453
  "docExempt": false,
5375
5454
  "filePath": "src/app/components/breadcrumb.tsx",
5376
5455
  "description": "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 marked aria-current=\"page\".",
5377
- "figmaUrl": "https://www.figma.com/design/c8MaVgwxOlxm4wr8wnH0Z4/HDS-Tokens-Components?node-id=86-159",
5456
+ "figmaUrl": "https://www.figma.com/design/2VgBbVpKiDnu0aftJEVyBQ/HDS-Tokens-Components?node-id=86-159",
5378
5457
  "figmaId": null,
5379
- "figmaLink": "https://www.figma.com/design/c8MaVgwxOlxm4wr8wnH0Z4/HDS-Tokens-Components?node-id=86-159",
5458
+ "figmaLink": "https://www.figma.com/design/2VgBbVpKiDnu0aftJEVyBQ/HDS-Tokens-Components?node-id=86-159",
5380
5459
  "tier": "pattern",
5381
5460
  "preview": {
5382
5461
  "exportName": "Breadcrumb",
@@ -5432,7 +5511,8 @@
5432
5511
  "reason": "stepping through pages of results"
5433
5512
  }
5434
5513
  ]
5435
- }
5514
+ },
5515
+ "core": true
5436
5516
  },
5437
5517
  "Pagination": {
5438
5518
  "category": "Navigation",
@@ -5442,9 +5522,9 @@
5442
5522
  "docExempt": false,
5443
5523
  "filePath": "src/app/components/pagination.tsx",
5444
5524
  "description": "Paged navigation with first/last anchors, sibling pages, and ellipses.",
5445
- "figmaUrl": "https://www.figma.com/design/c8MaVgwxOlxm4wr8wnH0Z4/HDS-Tokens-Components?node-id=86-194",
5525
+ "figmaUrl": "https://www.figma.com/design/2VgBbVpKiDnu0aftJEVyBQ/HDS-Tokens-Components?node-id=86-194",
5446
5526
  "figmaId": null,
5447
- "figmaLink": "https://www.figma.com/design/c8MaVgwxOlxm4wr8wnH0Z4/HDS-Tokens-Components?node-id=86-194",
5527
+ "figmaLink": "https://www.figma.com/design/2VgBbVpKiDnu0aftJEVyBQ/HDS-Tokens-Components?node-id=86-194",
5448
5528
  "tier": "pattern",
5449
5529
  "preview": {
5450
5530
  "exportName": "Pagination",
@@ -5503,7 +5583,8 @@
5503
5583
  "reason": "a hierarchy trail"
5504
5584
  }
5505
5585
  ]
5506
- }
5586
+ },
5587
+ "core": true
5507
5588
  },
5508
5589
  "ToastProvider": {
5509
5590
  "category": "Feedback",
@@ -5513,15 +5594,16 @@
5513
5594
  "docExempt": true,
5514
5595
  "filePath": "src/app/components/toast.tsx",
5515
5596
  "description": "Provider + viewport for the toast system. Wrap the app root once.",
5516
- "figmaUrl": "https://www.figma.com/design/c8MaVgwxOlxm4wr8wnH0Z4/HDS-Tokens-Components?node-id=93-367",
5597
+ "figmaUrl": "https://www.figma.com/design/2VgBbVpKiDnu0aftJEVyBQ/HDS-Tokens-Components?node-id=93-367",
5517
5598
  "figmaId": null,
5518
- "figmaLink": "https://www.figma.com/design/c8MaVgwxOlxm4wr8wnH0Z4/HDS-Tokens-Components?node-id=93-367",
5599
+ "figmaLink": "https://www.figma.com/design/2VgBbVpKiDnu0aftJEVyBQ/HDS-Tokens-Components?node-id=93-367",
5519
5600
  "tier": "pattern",
5520
5601
  "preview": {
5521
5602
  "exportName": "ToastProvider",
5522
5603
  "sizing": "panel"
5523
5604
  },
5524
5605
  "consumers": [
5606
+ "src/app/components/alert-dialog.tsx",
5525
5607
  "src/app/components/alert.tsx",
5526
5608
  "src/app/components/dialog.tsx",
5527
5609
  "src/app/components/toast.test.tsx",
@@ -5573,7 +5655,8 @@
5573
5655
  "reason": "a message that needs a decision"
5574
5656
  }
5575
5657
  ]
5576
- }
5658
+ },
5659
+ "core": true
5577
5660
  },
5578
5661
  "Combobox": {
5579
5662
  "category": "Inputs",
@@ -5583,9 +5666,9 @@
5583
5666
  "docExempt": true,
5584
5667
  "filePath": "src/app/components/combobox.tsx",
5585
5668
  "description": "Combobox — searchable single- or multi-select (Popover + filtered listbox). A select-with-search built on the HDS Popover. The trigger shows the current selection (with `multiple`, a count and a removable chip per value); opening reveals a search field that filters the option list. Full keyboard support (↑/↓ to move, Enter to choose, Esc/outside-click to close) and listbox/option ARIA. Controlled via `value` + `onChange`. <Combobox options={[{ value: 'us', label: 'United States' }, …]} value={country} onChange={setCountry} placeholder=\"Select a country\" />",
5586
- "figmaUrl": "https://www.figma.com/design/c8MaVgwxOlxm4wr8wnH0Z4/HDS-Tokens-Components?node-id=82-237",
5669
+ "figmaUrl": "https://www.figma.com/design/2VgBbVpKiDnu0aftJEVyBQ/HDS-Tokens-Components?node-id=82-237",
5587
5670
  "figmaId": null,
5588
- "figmaLink": "https://www.figma.com/design/c8MaVgwxOlxm4wr8wnH0Z4/HDS-Tokens-Components?node-id=82-237",
5671
+ "figmaLink": "https://www.figma.com/design/2VgBbVpKiDnu0aftJEVyBQ/HDS-Tokens-Components?node-id=82-237",
5589
5672
  "tier": "pattern",
5590
5673
  "preview": {
5591
5674
  "exportName": "Combobox",
@@ -5593,6 +5676,7 @@
5593
5676
  },
5594
5677
  "consumers": [
5595
5678
  "src/app/components/combobox.test.tsx",
5679
+ "src/app/components/form-control.ts",
5596
5680
  "src/app/components/form.tsx",
5597
5681
  "src/app/components/input.tsx",
5598
5682
  "src/app/components/select.tsx",
@@ -5714,7 +5798,8 @@
5714
5798
  "keys": "Tab",
5715
5799
  "effect": "Stays inside the open list."
5716
5800
  }
5717
- ]
5801
+ ],
5802
+ "core": true
5718
5803
  },
5719
5804
  "Form": {
5720
5805
  "category": "Inputs",
@@ -5724,9 +5809,9 @@
5724
5809
  "docExempt": true,
5725
5810
  "filePath": "src/app/components/form.tsx",
5726
5811
  "description": "Styled `<form>` with consistent vertical field rhythm. Tagged per-export: FormField and FormFieldShell share this module and have no Figma node, so a file-level @figma would claim this one for all three.",
5727
- "figmaUrl": "https://www.figma.com/design/c8MaVgwxOlxm4wr8wnH0Z4/HDS-Tokens-Components?node-id=85-94",
5812
+ "figmaUrl": "https://www.figma.com/design/2VgBbVpKiDnu0aftJEVyBQ/HDS-Tokens-Components?node-id=85-94",
5728
5813
  "figmaId": null,
5729
- "figmaLink": "https://www.figma.com/design/c8MaVgwxOlxm4wr8wnH0Z4/HDS-Tokens-Components?node-id=85-94",
5814
+ "figmaLink": "https://www.figma.com/design/2VgBbVpKiDnu0aftJEVyBQ/HDS-Tokens-Components?node-id=85-94",
5730
5815
  "tier": "pattern",
5731
5816
  "preview": {
5732
5817
  "exportName": "Form",
@@ -5988,7 +6073,8 @@
5988
6073
  "reason": "a single region with its own background"
5989
6074
  }
5990
6075
  ]
5991
- }
6076
+ },
6077
+ "core": true
5992
6078
  },
5993
6079
  "AvatarGroup": {
5994
6080
  "category": "Display",
@@ -5998,9 +6084,9 @@
5998
6084
  "docExempt": false,
5999
6085
  "filePath": "src/app/components/avatar-group.tsx",
6000
6086
  "description": "Renders up to `max` overlapping avatars followed by a `+N` overflow chip.",
6001
- "figmaUrl": null,
6087
+ "figmaUrl": "https://www.figma.com/design/2VgBbVpKiDnu0aftJEVyBQ/HDS-Tokens-Components?node-id=2030-63",
6002
6088
  "figmaId": null,
6003
- "figmaLink": null,
6089
+ "figmaLink": "https://www.figma.com/design/2VgBbVpKiDnu0aftJEVyBQ/HDS-Tokens-Components?node-id=2030-63",
6004
6090
  "tier": "primitive",
6005
6091
  "preview": {
6006
6092
  "exportName": "AvatarGroup",
@@ -6054,9 +6140,9 @@
6054
6140
  "docExempt": false,
6055
6141
  "filePath": "src/app/components/blockquote.tsx",
6056
6142
  "description": "A quoted passage; pass `cite` for the source URL and `attribution` for a byline.",
6057
- "figmaUrl": null,
6143
+ "figmaUrl": "https://www.figma.com/design/2VgBbVpKiDnu0aftJEVyBQ/HDS-Tokens-Components?node-id=2024-18",
6058
6144
  "figmaId": null,
6059
- "figmaLink": null,
6145
+ "figmaLink": "https://www.figma.com/design/2VgBbVpKiDnu0aftJEVyBQ/HDS-Tokens-Components?node-id=2024-18",
6060
6146
  "tier": "primitive",
6061
6147
  "preview": {
6062
6148
  "exportName": "Blockquote",
@@ -6107,9 +6193,9 @@
6107
6193
  "docExempt": false,
6108
6194
  "filePath": "src/app/components/kbd.tsx",
6109
6195
  "description": "Renders a keyboard key or shortcut token, e.g. `<Kbd>⌘K</Kbd>`.",
6110
- "figmaUrl": null,
6196
+ "figmaUrl": "https://www.figma.com/design/2VgBbVpKiDnu0aftJEVyBQ/HDS-Tokens-Components?node-id=2026-9",
6111
6197
  "figmaId": null,
6112
- "figmaLink": null,
6198
+ "figmaLink": "https://www.figma.com/design/2VgBbVpKiDnu0aftJEVyBQ/HDS-Tokens-Components?node-id=2026-9",
6113
6199
  "tier": "primitive",
6114
6200
  "preview": {
6115
6201
  "exportName": "Kbd",
@@ -6157,83 +6243,8 @@
6157
6243
  "reason": "inline code and other typography"
6158
6244
  }
6159
6245
  ]
6160
- }
6161
- },
6162
- "StatusDot": {
6163
- "category": "Feedback",
6164
- "categorySource": "jsdoc",
6165
- "governedCategory": true,
6166
- "hidden": false,
6167
- "docExempt": false,
6168
- "filePath": "src/app/components/status-dot.tsx",
6169
- "description": "A small solid dot conveying a semantic status via `tone`.",
6170
- "figmaUrl": null,
6171
- "figmaId": null,
6172
- "figmaLink": null,
6173
- "tier": "primitive",
6174
- "preview": {
6175
- "exportName": "StatusDot",
6176
- "sizing": "panel"
6177
- },
6178
- "consumers": [
6179
- "src/app/components/status-dot.test.tsx",
6180
- "src/stories/status-dot.stories.tsx"
6181
- ],
6182
- "tokenMapping": {},
6183
- "variantAxes": [],
6184
- "componentProperties": [],
6185
- "props": {
6186
- "label": {
6187
- "type": "string",
6188
- "optional": true
6189
- },
6190
- "size": {
6191
- "type": "enum",
6192
- "values": [
6193
- "sm",
6194
- "md",
6195
- "lg"
6196
- ],
6197
- "optional": true
6198
- },
6199
- "tone": {
6200
- "type": "enum",
6201
- "values": [
6202
- "success",
6203
- "danger",
6204
- "warning",
6205
- "info",
6206
- "neutral",
6207
- "inProgress"
6208
- ],
6209
- "optional": true
6210
- }
6211
- },
6212
- "allowedChildren": [
6213
- "*"
6214
- ],
6215
- "propConstraints": {},
6216
- "requiredProps": [],
6217
- "a11yRules": [],
6218
- "storyFiles": [
6219
- "src/stories/status-dot.stories.tsx"
6220
- ],
6221
- "storyIds": [
6222
- "primitives-status-dot--default",
6223
- "primitives-status-dot--tones",
6224
- "primitives-status-dot--with-label-text"
6225
- ],
6226
- "usage": {
6227
- "useInstead": [
6228
- {
6229
- "component": "Badge",
6230
- "reason": "with `dot`"
6231
- }
6232
- ]
6233
6246
  },
6234
- "deprecated": "Use `<Badge dot>`: `tone`, `size` and `label` are the same, and so is the dot. Badge takes no `style`, so move a `style` to a wrapper or a `className` first (MIGRATIONS.md, hds#395). Kept in 0.20.0 because ops passes StatusDot a `style` no codemod can carry over.",
6235
- "removeIn": "0.21.0",
6236
- "useInstead": "Badge"
6247
+ "core": true
6237
6248
  },
6238
6249
  "Timestamp": {
6239
6250
  "category": "Display",
@@ -6243,9 +6254,9 @@
6243
6254
  "docExempt": false,
6244
6255
  "filePath": "src/app/components/timestamp.tsx",
6245
6256
  "description": "Presents a date/time with a machine-readable `dateTime` for accessibility.",
6246
- "figmaUrl": null,
6257
+ "figmaUrl": "https://www.figma.com/design/2VgBbVpKiDnu0aftJEVyBQ/HDS-Tokens-Components?node-id=2031-11",
6247
6258
  "figmaId": null,
6248
- "figmaLink": null,
6259
+ "figmaLink": "https://www.figma.com/design/2VgBbVpKiDnu0aftJEVyBQ/HDS-Tokens-Components?node-id=2031-11",
6249
6260
  "tier": "primitive",
6250
6261
  "preview": {
6251
6262
  "exportName": "Timestamp",
@@ -6345,7 +6356,8 @@
6345
6356
  "reason": "text that everyone should read"
6346
6357
  }
6347
6358
  ]
6348
- }
6359
+ },
6360
+ "core": true
6349
6361
  },
6350
6362
  "MetadataList": {
6351
6363
  "category": "Display",
@@ -6355,9 +6367,9 @@
6355
6367
  "docExempt": false,
6356
6368
  "filePath": "src/app/components/metadata-list.tsx",
6357
6369
  "description": "Renders object metadata as a semantic `<dl>` of term/description pairs.",
6358
- "figmaUrl": null,
6370
+ "figmaUrl": "https://www.figma.com/design/2VgBbVpKiDnu0aftJEVyBQ/HDS-Tokens-Components?node-id=2041-47",
6359
6371
  "figmaId": null,
6360
- "figmaLink": null,
6372
+ "figmaLink": "https://www.figma.com/design/2VgBbVpKiDnu0aftJEVyBQ/HDS-Tokens-Components?node-id=2041-47",
6361
6373
  "tier": "pattern",
6362
6374
  "preview": {
6363
6375
  "exportName": "MetadataList",
@@ -6418,9 +6430,9 @@
6418
6430
  "docExempt": true,
6419
6431
  "filePath": "src/app/components/alert-dialog.tsx",
6420
6432
  "description": "AlertDialog root + parts. Controlled via `open`/`onOpenChange`, or uncontrolled with `defaultOpen`.",
6421
- "figmaUrl": null,
6433
+ "figmaUrl": "https://www.figma.com/design/2VgBbVpKiDnu0aftJEVyBQ/HDS-Tokens-Components?node-id=2035-24",
6422
6434
  "figmaId": null,
6423
- "figmaLink": null,
6435
+ "figmaLink": "https://www.figma.com/design/2VgBbVpKiDnu0aftJEVyBQ/HDS-Tokens-Components?node-id=2035-24",
6424
6436
  "tier": "primitive",
6425
6437
  "preview": {
6426
6438
  "exportName": "AlertDialog",
@@ -6429,6 +6441,7 @@
6429
6441
  "consumers": [
6430
6442
  "src/app/components/alert-dialog.test.tsx",
6431
6443
  "src/app/components/destructive-section.tsx",
6444
+ "src/app/components/dialog.tsx",
6432
6445
  "src/app/context/__tests__/portal-hydration.test.tsx",
6433
6446
  "src/app/context/__tests__/portal-scope.test.tsx",
6434
6447
  "src/stories/alert-dialog.stories.tsx",
@@ -6468,7 +6481,21 @@
6468
6481
  "storyIds": [
6469
6482
  "primitives-alert-dialog--dark-scope",
6470
6483
  "primitives-alert-dialog--default"
6471
- ]
6484
+ ],
6485
+ "usage": {
6486
+ "when": "Confirm a destructive or irreversible action (delete, archive, remove) before it runs, with Cancel and Action buttons.",
6487
+ "whenNot": "A modal that collects input or shows content, or a confirmation after the action is done.",
6488
+ "useInstead": [
6489
+ {
6490
+ "component": "Dialog",
6491
+ "reason": "a modal with a form or other content"
6492
+ },
6493
+ {
6494
+ "component": "ToastProvider",
6495
+ "reason": "a brief confirmation after the action"
6496
+ }
6497
+ ]
6498
+ }
6472
6499
  },
6473
6500
  "Box": {
6474
6501
  "category": "Layout",
@@ -6554,7 +6581,8 @@
6554
6581
  }
6555
6582
  ]
6556
6583
  },
6557
- "aiRules": "Reach for Stack/Grid/Container/the every-layout primitives first. Use Box `sx` ONLY for genuinely one-off layout. sx colors/spacing MUST use token keys, not raw hex/px. Prefer named layout primitives over ad-hoc flex."
6584
+ "aiRules": "Reach for Stack/Grid/Container/the every-layout primitives first. Use Box `sx` ONLY for genuinely one-off layout. sx colors/spacing MUST use token keys, not raw hex/px. Prefer named layout primitives over ad-hoc flex.",
6585
+ "core": true
6558
6586
  },
6559
6587
  "Sidebar": {
6560
6588
  "category": "Layout",
@@ -6859,16 +6887,18 @@
6859
6887
  "docExempt": false,
6860
6888
  "filePath": "src/app/components/textarea.tsx",
6861
6889
  "description": "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 four states Default / Focus / Error / Disabled map to the focus-ring, `error`, and `disabled` treatments below.",
6862
- "figmaUrl": "https://www.figma.com/design/c8MaVgwxOlxm4wr8wnH0Z4/HDS-Tokens-Components?node-id=85-14",
6890
+ "figmaUrl": "https://www.figma.com/design/2VgBbVpKiDnu0aftJEVyBQ/HDS-Tokens-Components?node-id=85-14",
6863
6891
  "figmaId": null,
6864
- "figmaLink": "https://www.figma.com/design/c8MaVgwxOlxm4wr8wnH0Z4/HDS-Tokens-Components?node-id=85-14",
6892
+ "figmaLink": "https://www.figma.com/design/2VgBbVpKiDnu0aftJEVyBQ/HDS-Tokens-Components?node-id=85-14",
6865
6893
  "tier": "primitive",
6866
6894
  "preview": {
6867
6895
  "exportName": "Textarea",
6868
6896
  "sizing": "panel"
6869
6897
  },
6870
6898
  "consumers": [
6899
+ "src/app/components/form-control.ts",
6871
6900
  "src/app/components/input.tsx",
6901
+ "src/app/components/select.tsx",
6872
6902
  "src/stories/patterns-client-detail.stories.tsx",
6873
6903
  "src/stories/textarea.stories.tsx"
6874
6904
  ],
@@ -6934,7 +6964,8 @@
6934
6964
  "reason": "a single line of text"
6935
6965
  }
6936
6966
  ]
6937
- }
6967
+ },
6968
+ "core": true
6938
6969
  },
6939
6970
  "CardBody": {
6940
6971
  "category": "Display",
@@ -6943,7 +6974,7 @@
6943
6974
  "hidden": false,
6944
6975
  "docExempt": false,
6945
6976
  "filePath": "src/app/components/card.tsx",
6946
- "description": "Card — surface container with slot anatomy (12d-card-anatomy). Slot anatomy (DESIGN.md §\"Card Anatomy\"). Status, progress, and metadata are layout-bearing — they live in slots, never inline next to prose. <Card variant=\"accent\"> <Card.Header metadata={<Badge tone=\"warning\">in-progress</Badge>}> <Card.Title>Discovery phase</Card.Title> <Card.Description>Stakeholder interviews and audit prep.</Card.Description> </Card.Header> <Card.Progress value={42} max={100} label=\"5 / 12 tasks\" /> <Card.Metric label=\"Retainer\" value=\"$3,500\" sub=\"Active\" /> <Card.Body>…</Card.Body> <Card.Footer>…</Card.Footer> </Card> Slot reservations: - Header: title (h3) + optional description (caption) + optional metadata zone (right-aligned, holds <Badge> / <Tag> for status, never raw spans). - Progress: full-width 4px bar in a reserved 16px vertical rail. Owns its spacing — never crowds adjacent prose. - Metric: single label-uppercase + big value (h2) + optional sub-line. Reserved vertical block. Use multiple side-by-side via flex/grid container. - Body: prose, lists, structured content. NO inline status, progress, or thin colored bars. Group sections via separate <Card.Body> blocks. - Footer: actions, secondary metadata, timestamps. `variant`: 'default' (borderless) | 'accent' (2px accent border) — the structural axis, for highlighted entries like \"recommended package\". `tone`: neutral | danger | success | warning | info — the fixed feedback axis (#60 variant contract), for status-driven cards where the border IS the signal. `variant`/`tone` together replace hand-rolled `pkgHighlight`-style overrides. Legacy props (padding / gap / noPadding / as / style) are retained. Existing callers that pass raw children continue to work; new callers should prefer compound parts + `padding=\"none\"`. Depth comes from semantic.color.border.default (role.border) at rest; elevation tokens are not bound by default — pass `className=\"shadow-...\"` for a hover/floating treatment on interactive cards.",
6977
+ "description": "Card — surface container with slot anatomy (12d-card-anatomy). Slot anatomy (DESIGN.md §\"Card Anatomy\"). Status, progress, and metadata are layout-bearing — they live in slots, never inline next to prose. <Card variant=\"accent\"> <Card.Header metadata={<Badge tone=\"warning\">in-progress</Badge>}> <Card.Title>Discovery phase</Card.Title> <Card.Description>Stakeholder interviews and audit prep.</Card.Description> </Card.Header> <Card.Progress value={42} max={100} label=\"5 / 12 tasks\" /> <Card.Metric label=\"Retainer\" value=\"$3,500\" sub=\"Active\" /> <Card.Body>…</Card.Body> <Card.Footer>…</Card.Footer> </Card> Slot reservations: - Header: title (h3) + optional description (caption) + optional metadata zone (right-aligned, holds <Badge> / <Tag> for status, never raw spans). - Progress: full-width 4px bar in a reserved 16px vertical rail. Owns its spacing — never crowds adjacent prose. - Metric: single label + big value (title) + optional sub-line. Reserved vertical block. Use multiple side-by-side via flex/grid container. - Body: prose, lists, structured content. NO inline status, progress, or thin colored bars. Group sections via separate <Card.Body> blocks. - Footer: actions, secondary metadata, timestamps. `variant`: 'default' (borderless) | 'accent' (2px accent border) — the structural axis, for highlighted entries like \"recommended package\". `tone`: neutral | danger | success | warning | info — the fixed feedback axis (#60 variant contract), for status-driven cards where the border IS the signal. `variant`/`tone` together replace hand-rolled `pkgHighlight`-style overrides. Legacy props (padding / gap / noPadding / as / style) are retained. Existing callers that pass raw children continue to work; new callers should prefer compound parts + `padding=\"none\"`. Depth comes from semantic.color.border.default (role.border) at rest; elevation tokens are not bound by default — pass `className=\"shadow-...\"` for a hover/floating treatment on interactive cards.",
6947
6978
  "figmaUrl": null,
6948
6979
  "figmaId": null,
6949
6980
  "figmaLink": null,
@@ -6979,6 +7010,7 @@
6979
7010
  "primitives-card--padding-variants",
6980
7011
  "primitives-card--progress-slot",
6981
7012
  "primitives-card--selectable",
7013
+ "primitives-card--tone-matrix",
6982
7014
  "primitives-card--variant-accent"
6983
7015
  ]
6984
7016
  },
@@ -6989,7 +7021,7 @@
6989
7021
  "hidden": false,
6990
7022
  "docExempt": false,
6991
7023
  "filePath": "src/app/components/card.tsx",
6992
- "description": "Card — surface container with slot anatomy (12d-card-anatomy). Slot anatomy (DESIGN.md §\"Card Anatomy\"). Status, progress, and metadata are layout-bearing — they live in slots, never inline next to prose. <Card variant=\"accent\"> <Card.Header metadata={<Badge tone=\"warning\">in-progress</Badge>}> <Card.Title>Discovery phase</Card.Title> <Card.Description>Stakeholder interviews and audit prep.</Card.Description> </Card.Header> <Card.Progress value={42} max={100} label=\"5 / 12 tasks\" /> <Card.Metric label=\"Retainer\" value=\"$3,500\" sub=\"Active\" /> <Card.Body>…</Card.Body> <Card.Footer>…</Card.Footer> </Card> Slot reservations: - Header: title (h3) + optional description (caption) + optional metadata zone (right-aligned, holds <Badge> / <Tag> for status, never raw spans). - Progress: full-width 4px bar in a reserved 16px vertical rail. Owns its spacing — never crowds adjacent prose. - Metric: single label-uppercase + big value (h2) + optional sub-line. Reserved vertical block. Use multiple side-by-side via flex/grid container. - Body: prose, lists, structured content. NO inline status, progress, or thin colored bars. Group sections via separate <Card.Body> blocks. - Footer: actions, secondary metadata, timestamps. `variant`: 'default' (borderless) | 'accent' (2px accent border) — the structural axis, for highlighted entries like \"recommended package\". `tone`: neutral | danger | success | warning | info — the fixed feedback axis (#60 variant contract), for status-driven cards where the border IS the signal. `variant`/`tone` together replace hand-rolled `pkgHighlight`-style overrides. Legacy props (padding / gap / noPadding / as / style) are retained. Existing callers that pass raw children continue to work; new callers should prefer compound parts + `padding=\"none\"`. Depth comes from semantic.color.border.default (role.border) at rest; elevation tokens are not bound by default — pass `className=\"shadow-...\"` for a hover/floating treatment on interactive cards.",
7024
+ "description": "Card — surface container with slot anatomy (12d-card-anatomy). Slot anatomy (DESIGN.md §\"Card Anatomy\"). Status, progress, and metadata are layout-bearing — they live in slots, never inline next to prose. <Card variant=\"accent\"> <Card.Header metadata={<Badge tone=\"warning\">in-progress</Badge>}> <Card.Title>Discovery phase</Card.Title> <Card.Description>Stakeholder interviews and audit prep.</Card.Description> </Card.Header> <Card.Progress value={42} max={100} label=\"5 / 12 tasks\" /> <Card.Metric label=\"Retainer\" value=\"$3,500\" sub=\"Active\" /> <Card.Body>…</Card.Body> <Card.Footer>…</Card.Footer> </Card> Slot reservations: - Header: title (h3) + optional description (caption) + optional metadata zone (right-aligned, holds <Badge> / <Tag> for status, never raw spans). - Progress: full-width 4px bar in a reserved 16px vertical rail. Owns its spacing — never crowds adjacent prose. - Metric: single label + big value (title) + optional sub-line. Reserved vertical block. Use multiple side-by-side via flex/grid container. - Body: prose, lists, structured content. NO inline status, progress, or thin colored bars. Group sections via separate <Card.Body> blocks. - Footer: actions, secondary metadata, timestamps. `variant`: 'default' (borderless) | 'accent' (2px accent border) — the structural axis, for highlighted entries like \"recommended package\". `tone`: neutral | danger | success | warning | info — the fixed feedback axis (#60 variant contract), for status-driven cards where the border IS the signal. `variant`/`tone` together replace hand-rolled `pkgHighlight`-style overrides. Legacy props (padding / gap / noPadding / as / style) are retained. Existing callers that pass raw children continue to work; new callers should prefer compound parts + `padding=\"none\"`. Depth comes from semantic.color.border.default (role.border) at rest; elevation tokens are not bound by default — pass `className=\"shadow-...\"` for a hover/floating treatment on interactive cards.",
6993
7025
  "figmaUrl": null,
6994
7026
  "figmaId": null,
6995
7027
  "figmaLink": null,
@@ -7025,6 +7057,7 @@
7025
7057
  "primitives-card--padding-variants",
7026
7058
  "primitives-card--progress-slot",
7027
7059
  "primitives-card--selectable",
7060
+ "primitives-card--tone-matrix",
7028
7061
  "primitives-card--variant-accent"
7029
7062
  ]
7030
7063
  },
@@ -7035,7 +7068,7 @@
7035
7068
  "hidden": false,
7036
7069
  "docExempt": false,
7037
7070
  "filePath": "src/app/components/card.tsx",
7038
- "description": "Card — surface container with slot anatomy (12d-card-anatomy). Slot anatomy (DESIGN.md §\"Card Anatomy\"). Status, progress, and metadata are layout-bearing — they live in slots, never inline next to prose. <Card variant=\"accent\"> <Card.Header metadata={<Badge tone=\"warning\">in-progress</Badge>}> <Card.Title>Discovery phase</Card.Title> <Card.Description>Stakeholder interviews and audit prep.</Card.Description> </Card.Header> <Card.Progress value={42} max={100} label=\"5 / 12 tasks\" /> <Card.Metric label=\"Retainer\" value=\"$3,500\" sub=\"Active\" /> <Card.Body>…</Card.Body> <Card.Footer>…</Card.Footer> </Card> Slot reservations: - Header: title (h3) + optional description (caption) + optional metadata zone (right-aligned, holds <Badge> / <Tag> for status, never raw spans). - Progress: full-width 4px bar in a reserved 16px vertical rail. Owns its spacing — never crowds adjacent prose. - Metric: single label-uppercase + big value (h2) + optional sub-line. Reserved vertical block. Use multiple side-by-side via flex/grid container. - Body: prose, lists, structured content. NO inline status, progress, or thin colored bars. Group sections via separate <Card.Body> blocks. - Footer: actions, secondary metadata, timestamps. `variant`: 'default' (borderless) | 'accent' (2px accent border) — the structural axis, for highlighted entries like \"recommended package\". `tone`: neutral | danger | success | warning | info — the fixed feedback axis (#60 variant contract), for status-driven cards where the border IS the signal. `variant`/`tone` together replace hand-rolled `pkgHighlight`-style overrides. Legacy props (padding / gap / noPadding / as / style) are retained. Existing callers that pass raw children continue to work; new callers should prefer compound parts + `padding=\"none\"`. Depth comes from semantic.color.border.default (role.border) at rest; elevation tokens are not bound by default — pass `className=\"shadow-...\"` for a hover/floating treatment on interactive cards.",
7071
+ "description": "Card — surface container with slot anatomy (12d-card-anatomy). Slot anatomy (DESIGN.md §\"Card Anatomy\"). Status, progress, and metadata are layout-bearing — they live in slots, never inline next to prose. <Card variant=\"accent\"> <Card.Header metadata={<Badge tone=\"warning\">in-progress</Badge>}> <Card.Title>Discovery phase</Card.Title> <Card.Description>Stakeholder interviews and audit prep.</Card.Description> </Card.Header> <Card.Progress value={42} max={100} label=\"5 / 12 tasks\" /> <Card.Metric label=\"Retainer\" value=\"$3,500\" sub=\"Active\" /> <Card.Body>…</Card.Body> <Card.Footer>…</Card.Footer> </Card> Slot reservations: - Header: title (h3) + optional description (caption) + optional metadata zone (right-aligned, holds <Badge> / <Tag> for status, never raw spans). - Progress: full-width 4px bar in a reserved 16px vertical rail. Owns its spacing — never crowds adjacent prose. - Metric: single label + big value (title) + optional sub-line. Reserved vertical block. Use multiple side-by-side via flex/grid container. - Body: prose, lists, structured content. NO inline status, progress, or thin colored bars. Group sections via separate <Card.Body> blocks. - Footer: actions, secondary metadata, timestamps. `variant`: 'default' (borderless) | 'accent' (2px accent border) — the structural axis, for highlighted entries like \"recommended package\". `tone`: neutral | danger | success | warning | info — the fixed feedback axis (#60 variant contract), for status-driven cards where the border IS the signal. `variant`/`tone` together replace hand-rolled `pkgHighlight`-style overrides. Legacy props (padding / gap / noPadding / as / style) are retained. Existing callers that pass raw children continue to work; new callers should prefer compound parts + `padding=\"none\"`. Depth comes from semantic.color.border.default (role.border) at rest; elevation tokens are not bound by default — pass `className=\"shadow-...\"` for a hover/floating treatment on interactive cards.",
7039
7072
  "figmaUrl": null,
7040
7073
  "figmaId": null,
7041
7074
  "figmaLink": null,
@@ -7071,6 +7104,7 @@
7071
7104
  "primitives-card--padding-variants",
7072
7105
  "primitives-card--progress-slot",
7073
7106
  "primitives-card--selectable",
7107
+ "primitives-card--tone-matrix",
7074
7108
  "primitives-card--variant-accent"
7075
7109
  ]
7076
7110
  },
@@ -7081,7 +7115,7 @@
7081
7115
  "hidden": false,
7082
7116
  "docExempt": false,
7083
7117
  "filePath": "src/app/components/card.tsx",
7084
- "description": "Card — surface container with slot anatomy (12d-card-anatomy). Slot anatomy (DESIGN.md §\"Card Anatomy\"). Status, progress, and metadata are layout-bearing — they live in slots, never inline next to prose. <Card variant=\"accent\"> <Card.Header metadata={<Badge tone=\"warning\">in-progress</Badge>}> <Card.Title>Discovery phase</Card.Title> <Card.Description>Stakeholder interviews and audit prep.</Card.Description> </Card.Header> <Card.Progress value={42} max={100} label=\"5 / 12 tasks\" /> <Card.Metric label=\"Retainer\" value=\"$3,500\" sub=\"Active\" /> <Card.Body>…</Card.Body> <Card.Footer>…</Card.Footer> </Card> Slot reservations: - Header: title (h3) + optional description (caption) + optional metadata zone (right-aligned, holds <Badge> / <Tag> for status, never raw spans). - Progress: full-width 4px bar in a reserved 16px vertical rail. Owns its spacing — never crowds adjacent prose. - Metric: single label-uppercase + big value (h2) + optional sub-line. Reserved vertical block. Use multiple side-by-side via flex/grid container. - Body: prose, lists, structured content. NO inline status, progress, or thin colored bars. Group sections via separate <Card.Body> blocks. - Footer: actions, secondary metadata, timestamps. `variant`: 'default' (borderless) | 'accent' (2px accent border) — the structural axis, for highlighted entries like \"recommended package\". `tone`: neutral | danger | success | warning | info — the fixed feedback axis (#60 variant contract), for status-driven cards where the border IS the signal. `variant`/`tone` together replace hand-rolled `pkgHighlight`-style overrides. Legacy props (padding / gap / noPadding / as / style) are retained. Existing callers that pass raw children continue to work; new callers should prefer compound parts + `padding=\"none\"`. Depth comes from semantic.color.border.default (role.border) at rest; elevation tokens are not bound by default — pass `className=\"shadow-...\"` for a hover/floating treatment on interactive cards.",
7118
+ "description": "Card — surface container with slot anatomy (12d-card-anatomy). Slot anatomy (DESIGN.md §\"Card Anatomy\"). Status, progress, and metadata are layout-bearing — they live in slots, never inline next to prose. <Card variant=\"accent\"> <Card.Header metadata={<Badge tone=\"warning\">in-progress</Badge>}> <Card.Title>Discovery phase</Card.Title> <Card.Description>Stakeholder interviews and audit prep.</Card.Description> </Card.Header> <Card.Progress value={42} max={100} label=\"5 / 12 tasks\" /> <Card.Metric label=\"Retainer\" value=\"$3,500\" sub=\"Active\" /> <Card.Body>…</Card.Body> <Card.Footer>…</Card.Footer> </Card> Slot reservations: - Header: title (h3) + optional description (caption) + optional metadata zone (right-aligned, holds <Badge> / <Tag> for status, never raw spans). - Progress: full-width 4px bar in a reserved 16px vertical rail. Owns its spacing — never crowds adjacent prose. - Metric: single label + big value (title) + optional sub-line. Reserved vertical block. Use multiple side-by-side via flex/grid container. - Body: prose, lists, structured content. NO inline status, progress, or thin colored bars. Group sections via separate <Card.Body> blocks. - Footer: actions, secondary metadata, timestamps. `variant`: 'default' (borderless) | 'accent' (2px accent border) — the structural axis, for highlighted entries like \"recommended package\". `tone`: neutral | danger | success | warning | info — the fixed feedback axis (#60 variant contract), for status-driven cards where the border IS the signal. `variant`/`tone` together replace hand-rolled `pkgHighlight`-style overrides. Legacy props (padding / gap / noPadding / as / style) are retained. Existing callers that pass raw children continue to work; new callers should prefer compound parts + `padding=\"none\"`. Depth comes from semantic.color.border.default (role.border) at rest; elevation tokens are not bound by default — pass `className=\"shadow-...\"` for a hover/floating treatment on interactive cards.",
7085
7119
  "figmaUrl": null,
7086
7120
  "figmaId": null,
7087
7121
  "figmaLink": null,
@@ -7122,6 +7156,7 @@
7122
7156
  "primitives-card--padding-variants",
7123
7157
  "primitives-card--progress-slot",
7124
7158
  "primitives-card--selectable",
7159
+ "primitives-card--tone-matrix",
7125
7160
  "primitives-card--variant-accent"
7126
7161
  ]
7127
7162
  },
@@ -7132,7 +7167,7 @@
7132
7167
  "hidden": false,
7133
7168
  "docExempt": false,
7134
7169
  "filePath": "src/app/components/card.tsx",
7135
- "description": "Card.Metric — one uppercase label, a large value and an optional sub-line inside a Card.",
7170
+ "description": "Card.Metric — one label, a large value and an optional sub-line inside a Card.",
7136
7171
  "figmaUrl": null,
7137
7172
  "figmaId": null,
7138
7173
  "figmaLink": null,
@@ -7190,11 +7225,18 @@
7190
7225
  "primitives-card--padding-variants",
7191
7226
  "primitives-card--progress-slot",
7192
7227
  "primitives-card--selectable",
7228
+ "primitives-card--tone-matrix",
7193
7229
  "primitives-card--variant-accent"
7194
7230
  ],
7195
7231
  "usage": {
7196
7232
  "when": "Show one headline figure (a KPI, a count, a total) with its label inside a Card.",
7197
- "whenNot": "A metric outside a Card, or several figures that share one label."
7233
+ "whenNot": "A metric outside a Card, or several figures that share one label.",
7234
+ "useInstead": [
7235
+ {
7236
+ "component": "MetricTiles",
7237
+ "reason": "a row of headline numbers with no enclosing Card"
7238
+ }
7239
+ ]
7198
7240
  }
7199
7241
  },
7200
7242
  "CardProgress": {
@@ -7204,7 +7246,7 @@
7204
7246
  "hidden": false,
7205
7247
  "docExempt": false,
7206
7248
  "filePath": "src/app/components/card.tsx",
7207
- "description": "Card — surface container with slot anatomy (12d-card-anatomy). Slot anatomy (DESIGN.md §\"Card Anatomy\"). Status, progress, and metadata are layout-bearing — they live in slots, never inline next to prose. <Card variant=\"accent\"> <Card.Header metadata={<Badge tone=\"warning\">in-progress</Badge>}> <Card.Title>Discovery phase</Card.Title> <Card.Description>Stakeholder interviews and audit prep.</Card.Description> </Card.Header> <Card.Progress value={42} max={100} label=\"5 / 12 tasks\" /> <Card.Metric label=\"Retainer\" value=\"$3,500\" sub=\"Active\" /> <Card.Body>…</Card.Body> <Card.Footer>…</Card.Footer> </Card> Slot reservations: - Header: title (h3) + optional description (caption) + optional metadata zone (right-aligned, holds <Badge> / <Tag> for status, never raw spans). - Progress: full-width 4px bar in a reserved 16px vertical rail. Owns its spacing — never crowds adjacent prose. - Metric: single label-uppercase + big value (h2) + optional sub-line. Reserved vertical block. Use multiple side-by-side via flex/grid container. - Body: prose, lists, structured content. NO inline status, progress, or thin colored bars. Group sections via separate <Card.Body> blocks. - Footer: actions, secondary metadata, timestamps. `variant`: 'default' (borderless) | 'accent' (2px accent border) — the structural axis, for highlighted entries like \"recommended package\". `tone`: neutral | danger | success | warning | info — the fixed feedback axis (#60 variant contract), for status-driven cards where the border IS the signal. `variant`/`tone` together replace hand-rolled `pkgHighlight`-style overrides. Legacy props (padding / gap / noPadding / as / style) are retained. Existing callers that pass raw children continue to work; new callers should prefer compound parts + `padding=\"none\"`. Depth comes from semantic.color.border.default (role.border) at rest; elevation tokens are not bound by default — pass `className=\"shadow-...\"` for a hover/floating treatment on interactive cards.",
7249
+ "description": "Card — surface container with slot anatomy (12d-card-anatomy). Slot anatomy (DESIGN.md §\"Card Anatomy\"). Status, progress, and metadata are layout-bearing — they live in slots, never inline next to prose. <Card variant=\"accent\"> <Card.Header metadata={<Badge tone=\"warning\">in-progress</Badge>}> <Card.Title>Discovery phase</Card.Title> <Card.Description>Stakeholder interviews and audit prep.</Card.Description> </Card.Header> <Card.Progress value={42} max={100} label=\"5 / 12 tasks\" /> <Card.Metric label=\"Retainer\" value=\"$3,500\" sub=\"Active\" /> <Card.Body>…</Card.Body> <Card.Footer>…</Card.Footer> </Card> Slot reservations: - Header: title (h3) + optional description (caption) + optional metadata zone (right-aligned, holds <Badge> / <Tag> for status, never raw spans). - Progress: full-width 4px bar in a reserved 16px vertical rail. Owns its spacing — never crowds adjacent prose. - Metric: single label + big value (title) + optional sub-line. Reserved vertical block. Use multiple side-by-side via flex/grid container. - Body: prose, lists, structured content. NO inline status, progress, or thin colored bars. Group sections via separate <Card.Body> blocks. - Footer: actions, secondary metadata, timestamps. `variant`: 'default' (borderless) | 'accent' (2px accent border) — the structural axis, for highlighted entries like \"recommended package\". `tone`: neutral | danger | success | warning | info — the fixed feedback axis (#60 variant contract), for status-driven cards where the border IS the signal. `variant`/`tone` together replace hand-rolled `pkgHighlight`-style overrides. Legacy props (padding / gap / noPadding / as / style) are retained. Existing callers that pass raw children continue to work; new callers should prefer compound parts + `padding=\"none\"`. Depth comes from semantic.color.border.default (role.border) at rest; elevation tokens are not bound by default — pass `className=\"shadow-...\"` for a hover/floating treatment on interactive cards.",
7208
7250
  "figmaUrl": null,
7209
7251
  "figmaId": null,
7210
7252
  "figmaLink": null,
@@ -7263,6 +7305,7 @@
7263
7305
  "primitives-card--padding-variants",
7264
7306
  "primitives-card--progress-slot",
7265
7307
  "primitives-card--selectable",
7308
+ "primitives-card--tone-matrix",
7266
7309
  "primitives-card--variant-accent"
7267
7310
  ]
7268
7311
  },
@@ -7273,7 +7316,7 @@
7273
7316
  "hidden": false,
7274
7317
  "docExempt": false,
7275
7318
  "filePath": "src/app/components/card.tsx",
7276
- "description": "Card — surface container with slot anatomy (12d-card-anatomy). Slot anatomy (DESIGN.md §\"Card Anatomy\"). Status, progress, and metadata are layout-bearing — they live in slots, never inline next to prose. <Card variant=\"accent\"> <Card.Header metadata={<Badge tone=\"warning\">in-progress</Badge>}> <Card.Title>Discovery phase</Card.Title> <Card.Description>Stakeholder interviews and audit prep.</Card.Description> </Card.Header> <Card.Progress value={42} max={100} label=\"5 / 12 tasks\" /> <Card.Metric label=\"Retainer\" value=\"$3,500\" sub=\"Active\" /> <Card.Body>…</Card.Body> <Card.Footer>…</Card.Footer> </Card> Slot reservations: - Header: title (h3) + optional description (caption) + optional metadata zone (right-aligned, holds <Badge> / <Tag> for status, never raw spans). - Progress: full-width 4px bar in a reserved 16px vertical rail. Owns its spacing — never crowds adjacent prose. - Metric: single label-uppercase + big value (h2) + optional sub-line. Reserved vertical block. Use multiple side-by-side via flex/grid container. - Body: prose, lists, structured content. NO inline status, progress, or thin colored bars. Group sections via separate <Card.Body> blocks. - Footer: actions, secondary metadata, timestamps. `variant`: 'default' (borderless) | 'accent' (2px accent border) — the structural axis, for highlighted entries like \"recommended package\". `tone`: neutral | danger | success | warning | info — the fixed feedback axis (#60 variant contract), for status-driven cards where the border IS the signal. `variant`/`tone` together replace hand-rolled `pkgHighlight`-style overrides. Legacy props (padding / gap / noPadding / as / style) are retained. Existing callers that pass raw children continue to work; new callers should prefer compound parts + `padding=\"none\"`. Depth comes from semantic.color.border.default (role.border) at rest; elevation tokens are not bound by default — pass `className=\"shadow-...\"` for a hover/floating treatment on interactive cards.",
7319
+ "description": "Card — surface container with slot anatomy (12d-card-anatomy). Slot anatomy (DESIGN.md §\"Card Anatomy\"). Status, progress, and metadata are layout-bearing — they live in slots, never inline next to prose. <Card variant=\"accent\"> <Card.Header metadata={<Badge tone=\"warning\">in-progress</Badge>}> <Card.Title>Discovery phase</Card.Title> <Card.Description>Stakeholder interviews and audit prep.</Card.Description> </Card.Header> <Card.Progress value={42} max={100} label=\"5 / 12 tasks\" /> <Card.Metric label=\"Retainer\" value=\"$3,500\" sub=\"Active\" /> <Card.Body>…</Card.Body> <Card.Footer>…</Card.Footer> </Card> Slot reservations: - Header: title (h3) + optional description (caption) + optional metadata zone (right-aligned, holds <Badge> / <Tag> for status, never raw spans). - Progress: full-width 4px bar in a reserved 16px vertical rail. Owns its spacing — never crowds adjacent prose. - Metric: single label + big value (title) + optional sub-line. Reserved vertical block. Use multiple side-by-side via flex/grid container. - Body: prose, lists, structured content. NO inline status, progress, or thin colored bars. Group sections via separate <Card.Body> blocks. - Footer: actions, secondary metadata, timestamps. `variant`: 'default' (borderless) | 'accent' (2px accent border) — the structural axis, for highlighted entries like \"recommended package\". `tone`: neutral | danger | success | warning | info — the fixed feedback axis (#60 variant contract), for status-driven cards where the border IS the signal. `variant`/`tone` together replace hand-rolled `pkgHighlight`-style overrides. Legacy props (padding / gap / noPadding / as / style) are retained. Existing callers that pass raw children continue to work; new callers should prefer compound parts + `padding=\"none\"`. Depth comes from semantic.color.border.default (role.border) at rest; elevation tokens are not bound by default — pass `className=\"shadow-...\"` for a hover/floating treatment on interactive cards.",
7277
7320
  "figmaUrl": null,
7278
7321
  "figmaId": null,
7279
7322
  "figmaLink": null,
@@ -7309,6 +7352,7 @@
7309
7352
  "primitives-card--padding-variants",
7310
7353
  "primitives-card--progress-slot",
7311
7354
  "primitives-card--selectable",
7355
+ "primitives-card--tone-matrix",
7312
7356
  "primitives-card--variant-accent"
7313
7357
  ]
7314
7358
  },
@@ -7763,7 +7807,7 @@
7763
7807
  "docExempt": true,
7764
7808
  "filePath": "src/app/components/hds-tooltip.tsx",
7765
7809
  "description": "Tooltip root. Bakes in the Radix Provider so a single `<Tooltip>` is self-contained — no app-level provider required. Controlled via `open`/`onOpenChange`, or uncontrolled with `defaultOpen`.",
7766
- "figmaUrl": "https://www.figma.com/design/c8MaVgwxOlxm4wr8wnH0Z4/HDS-Tokens-Components?node-id=93-15",
7810
+ "figmaUrl": "https://www.figma.com/design/2VgBbVpKiDnu0aftJEVyBQ/HDS-Tokens-Components?node-id=93-15",
7767
7811
  "figmaId": null,
7768
7812
  "tier": "primitive",
7769
7813
  "preview": {
@@ -7782,7 +7826,7 @@
7782
7826
  "tokenMapping": {},
7783
7827
  "variantAxes": [],
7784
7828
  "componentProperties": [],
7785
- "figmaLink": "https://www.figma.com/design/c8MaVgwxOlxm4wr8wnH0Z4/HDS-Tokens-Components?node-id=93-15",
7829
+ "figmaLink": "https://www.figma.com/design/2VgBbVpKiDnu0aftJEVyBQ/HDS-Tokens-Components?node-id=93-15",
7786
7830
  "props": {
7787
7831
  "children": {
7788
7832
  "type": "React.ReactNode",
@@ -7849,7 +7893,8 @@
7849
7893
  "keys": "Tab",
7850
7894
  "effect": "Moves on to the next control and closes the tooltip."
7851
7895
  }
7852
- ]
7896
+ ],
7897
+ "core": true
7853
7898
  },
7854
7899
  "Menu": {
7855
7900
  "category": "Overlays",
@@ -7859,9 +7904,9 @@
7859
7904
  "docExempt": true,
7860
7905
  "filePath": "src/app/components/menu.tsx",
7861
7906
  "description": "Menu root + parts. Controlled via `open`/`onOpenChange`, or uncontrolled with `defaultOpen`.",
7862
- "figmaUrl": "https://www.figma.com/design/c8MaVgwxOlxm4wr8wnH0Z4/HDS-Tokens-Components?node-id=93-59",
7907
+ "figmaUrl": "https://www.figma.com/design/2VgBbVpKiDnu0aftJEVyBQ/HDS-Tokens-Components?node-id=93-59",
7863
7908
  "figmaId": null,
7864
- "figmaLink": "https://www.figma.com/design/c8MaVgwxOlxm4wr8wnH0Z4/HDS-Tokens-Components?node-id=93-59",
7909
+ "figmaLink": "https://www.figma.com/design/2VgBbVpKiDnu0aftJEVyBQ/HDS-Tokens-Components?node-id=93-59",
7865
7910
  "tier": "primitive",
7866
7911
  "preview": {
7867
7912
  "exportName": "Menu",
@@ -7972,7 +8017,8 @@
7972
8017
  "keys": "Tab",
7973
8018
  "effect": "Does not leave the open menu."
7974
8019
  }
7975
- ]
8020
+ ],
8021
+ "core": true
7976
8022
  },
7977
8023
  "Popover": {
7978
8024
  "category": "Overlays",
@@ -7982,9 +8028,9 @@
7982
8028
  "docExempt": true,
7983
8029
  "filePath": "src/app/components/popover.tsx",
7984
8030
  "description": "Popover root + parts. Controlled via `open`/`onOpenChange`, or uncontrolled with `defaultOpen`.",
7985
- "figmaUrl": "https://www.figma.com/design/c8MaVgwxOlxm4wr8wnH0Z4/HDS-Tokens-Components?node-id=93-32",
8031
+ "figmaUrl": "https://www.figma.com/design/2VgBbVpKiDnu0aftJEVyBQ/HDS-Tokens-Components?node-id=93-32",
7986
8032
  "figmaId": null,
7987
- "figmaLink": "https://www.figma.com/design/c8MaVgwxOlxm4wr8wnH0Z4/HDS-Tokens-Components?node-id=93-32",
8033
+ "figmaLink": "https://www.figma.com/design/2VgBbVpKiDnu0aftJEVyBQ/HDS-Tokens-Components?node-id=93-32",
7988
8034
  "tier": "primitive",
7989
8035
  "preview": {
7990
8036
  "exportName": "Popover",
@@ -8073,7 +8119,8 @@
8073
8119
  "keys": "Tab",
8074
8120
  "effect": "Cycles focus inside the open popover; the page behind stays reachable."
8075
8121
  }
8076
- ]
8122
+ ],
8123
+ "core": true
8077
8124
  },
8078
8125
  "Checkbox": {
8079
8126
  "category": "Inputs",
@@ -8083,9 +8130,9 @@
8083
8130
  "docExempt": false,
8084
8131
  "filePath": "src/app/components/checkbox.tsx",
8085
8132
  "description": "Checkbox — custom-drawn checkbox with check / indeterminate glyph.",
8086
- "figmaUrl": "https://www.figma.com/design/c8MaVgwxOlxm4wr8wnH0Z4/HDS-Tokens-Components?node-id=35-29",
8133
+ "figmaUrl": "https://www.figma.com/design/2VgBbVpKiDnu0aftJEVyBQ/HDS-Tokens-Components?node-id=35-29",
8087
8134
  "figmaId": null,
8088
- "figmaLink": "https://www.figma.com/design/c8MaVgwxOlxm4wr8wnH0Z4/HDS-Tokens-Components?node-id=35-29",
8135
+ "figmaLink": "https://www.figma.com/design/2VgBbVpKiDnu0aftJEVyBQ/HDS-Tokens-Components?node-id=35-29",
8089
8136
  "tier": "primitive",
8090
8137
  "preview": {
8091
8138
  "exportName": "Checkbox",
@@ -8145,7 +8192,8 @@
8145
8192
  "reason": "exactly one choice from a set"
8146
8193
  }
8147
8194
  ]
8148
- }
8195
+ },
8196
+ "core": true
8149
8197
  },
8150
8198
  "FormActions": {
8151
8199
  "category": "Actions",
@@ -8155,9 +8203,9 @@
8155
8203
  "docExempt": false,
8156
8204
  "filePath": "src/app/components/form-actions.tsx",
8157
8205
  "description": "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.",
8158
- "figmaUrl": null,
8206
+ "figmaUrl": "https://www.figma.com/design/2VgBbVpKiDnu0aftJEVyBQ/HDS-Tokens-Components?node-id=2075-87",
8159
8207
  "figmaId": null,
8160
- "figmaLink": null,
8208
+ "figmaLink": "https://www.figma.com/design/2VgBbVpKiDnu0aftJEVyBQ/HDS-Tokens-Components?node-id=2075-87",
8161
8209
  "tier": "pattern",
8162
8210
  "preview": {
8163
8211
  "exportName": "FormActions",
@@ -8212,9 +8260,9 @@
8212
8260
  "docExempt": false,
8213
8261
  "filePath": "src/app/components/metric-tiles.tsx",
8214
8262
  "description": "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 eyebrow / h2 / caption scale) and adds the surface and the fixed height, so a tile needs no enclosing `Card`.",
8215
- "figmaUrl": null,
8263
+ "figmaUrl": "https://www.figma.com/design/2VgBbVpKiDnu0aftJEVyBQ/HDS-Tokens-Components?node-id=2075-114",
8216
8264
  "figmaId": null,
8217
- "figmaLink": null,
8265
+ "figmaLink": "https://www.figma.com/design/2VgBbVpKiDnu0aftJEVyBQ/HDS-Tokens-Components?node-id=2075-114",
8218
8266
  "tier": "pattern",
8219
8267
  "preview": {
8220
8268
  "exportName": "MetricTile",
@@ -8222,6 +8270,8 @@
8222
8270
  },
8223
8271
  "consumers": [
8224
8272
  "src/app/components/metric-tiles.test.tsx",
8273
+ "src/app/components/stat.tsx",
8274
+ "src/stories/metric-tile.stories.tsx",
8225
8275
  "src/stories/metric-tiles.stories.tsx",
8226
8276
  "src/stories/patterns-client-detail.stories.tsx"
8227
8277
  ],
@@ -8258,9 +8308,12 @@
8258
8308
  "requiredProps": [],
8259
8309
  "a11yRules": [],
8260
8310
  "storyFiles": [
8311
+ "src/stories/metric-tile.stories.tsx",
8261
8312
  "src/stories/metric-tiles.stories.tsx"
8262
8313
  ],
8263
8314
  "storyIds": [
8315
+ "patterns-metrictile--danger",
8316
+ "patterns-metrictile--default",
8264
8317
  "patterns-metrictiles--four-tiles",
8265
8318
  "patterns-metrictiles--sub-line-optional",
8266
8319
  "patterns-metrictiles--three-tiles",
@@ -8284,7 +8337,11 @@
8284
8337
  "sizing": "panel"
8285
8338
  },
8286
8339
  "consumers": [
8340
+ "src/app/components/card.tsx",
8287
8341
  "src/app/components/metric-tiles.test.tsx",
8342
+ "src/app/components/stat.tsx",
8343
+ "src/app/components/status-tile.tsx",
8344
+ "src/stories/metric-tile.stories.tsx",
8288
8345
  "src/stories/metric-tiles.stories.tsx",
8289
8346
  "src/stories/patterns-client-detail.stories.tsx"
8290
8347
  ],
@@ -8303,9 +8360,12 @@
8303
8360
  "requiredProps": [],
8304
8361
  "a11yRules": [],
8305
8362
  "storyFiles": [
8363
+ "src/stories/metric-tile.stories.tsx",
8306
8364
  "src/stories/metric-tiles.stories.tsx"
8307
8365
  ],
8308
8366
  "storyIds": [
8367
+ "patterns-metrictile--danger",
8368
+ "patterns-metrictile--default",
8309
8369
  "patterns-metrictiles--four-tiles",
8310
8370
  "patterns-metrictiles--sub-line-optional",
8311
8371
  "patterns-metrictiles--three-tiles",
@@ -8387,9 +8447,9 @@
8387
8447
  "docExempt": false,
8388
8448
  "filePath": "src/app/components/data-table-section.tsx",
8389
8449
  "description": "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 `minWidth` from the caller, and zero rows shows an `EmptyState`.",
8390
- "figmaUrl": null,
8450
+ "figmaUrl": "https://www.figma.com/design/2VgBbVpKiDnu0aftJEVyBQ/HDS-Tokens-Components?node-id=2075-268",
8391
8451
  "figmaId": null,
8392
- "figmaLink": null,
8452
+ "figmaLink": "https://www.figma.com/design/2VgBbVpKiDnu0aftJEVyBQ/HDS-Tokens-Components?node-id=2075-268",
8393
8453
  "tier": "pattern",
8394
8454
  "preview": {
8395
8455
  "exportName": "DataTableSection",
@@ -8459,9 +8519,9 @@
8459
8519
  "docExempt": false,
8460
8520
  "filePath": "src/app/components/destructive-section.tsx",
8461
8521
  "description": "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 confirm does. Place it last on the screen, below the form.",
8462
- "figmaUrl": null,
8522
+ "figmaUrl": "https://www.figma.com/design/2VgBbVpKiDnu0aftJEVyBQ/HDS-Tokens-Components?node-id=2076-3",
8463
8523
  "figmaId": null,
8464
- "figmaLink": null,
8524
+ "figmaLink": "https://www.figma.com/design/2VgBbVpKiDnu0aftJEVyBQ/HDS-Tokens-Components?node-id=2076-3",
8465
8525
  "tier": "pattern",
8466
8526
  "preview": {
8467
8527
  "exportName": "DestructiveSection",
@@ -8561,7 +8621,8 @@
8561
8621
  "storyIds": [],
8562
8622
  "usage": {
8563
8623
  "when": "Wrap the app root once so HDS links and navigation use your client router; with no provider they stay plain anchors."
8564
- }
8624
+ },
8625
+ "core": true
8565
8626
  },
8566
8627
  "HdsPhosphor": {
8567
8628
  "category": "Compiler",
@@ -9658,7 +9719,7 @@
9658
9719
  "path": "primitive.typography.family.display",
9659
9720
  "cssVar": "--primitive-typography-family-display",
9660
9721
  "type": "fontFamily",
9661
- "description": "Display face: Satoshi Bold (ITF), bound to display/h1/h2/h3 composites.",
9722
+ "description": "Display face: Satoshi Bold (ITF), bound to the display and title composites.",
9662
9723
  "value": "Satoshi, system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", sans-serif"
9663
9724
  },
9664
9725
  {
@@ -9738,6 +9799,13 @@
9738
9799
  "description": "Swiss-canon display size (hds#283 ramp). Static desktop value; fluid in theme.css. Tailwind 4 default text-6xl.",
9739
9800
  "value": "60px"
9740
9801
  },
9802
+ {
9803
+ "path": "primitive.typography.size.code",
9804
+ "cssVar": "--primitive-typography-size-code",
9805
+ "type": "dimension",
9806
+ "description": "13px code size. The mono role (hds#485): one px below ui so code sits level with 14px prose.",
9807
+ "value": "13px"
9808
+ },
9741
9809
  {
9742
9810
  "path": "primitive.typography.weight.regular",
9743
9811
  "cssVar": "--primitive-typography-weight-regular",
@@ -9794,6 +9862,20 @@
9794
9862
  "description": "Swiss-canon relaxed rhythm (10t-5). Used by body/small/mono composites for long-form prose comfort.",
9795
9863
  "value": "1.625"
9796
9864
  },
9865
+ {
9866
+ "path": "primitive.typography.lineHeight.display",
9867
+ "cssVar": "--primitive-typography-lineHeight-display",
9868
+ "type": "number",
9869
+ "description": "Display role leading (hds#485).",
9870
+ "value": "1.05"
9871
+ },
9872
+ {
9873
+ "path": "primitive.typography.lineHeight.body",
9874
+ "cssVar": "--primitive-typography-lineHeight-body",
9875
+ "type": "number",
9876
+ "description": "Body role leading (hds#485).",
9877
+ "value": "1.6"
9878
+ },
9797
9879
  {
9798
9880
  "path": "primitive.typography.letterSpacing.tight",
9799
9881
  "cssVar": "--primitive-typography-letterSpacing-tight",
@@ -10904,65 +10986,39 @@
10904
10986
  "path": "semantic.typography.display",
10905
10987
  "cssVar": "--semantic-typography-display",
10906
10988
  "type": "typography",
10907
- "description": "Display headline. 60px / Satoshi bold 700 / leading-none (hds#283: was 72px/5xl).",
10908
- "composite": {
10909
- "fontFamily": "Satoshi, system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", sans-serif",
10910
- "fontSize": "60px",
10911
- "fontWeight": "700",
10912
- "letterSpacing": "-0.01em",
10913
- "lineHeight": "1"
10914
- }
10915
- },
10916
- {
10917
- "path": "semantic.typography.h1",
10918
- "cssVar": "--semantic-typography-h1",
10919
- "type": "typography",
10920
- "description": "Primary section headings (h1). 48px / Satoshi bold 700 / leading-tight (hds#283: rung renamed 4xl→5xl, px unchanged).",
10989
+ "description": "One per page, hero only. 48px / 1.05 / 700. Role 1 of 6.",
10921
10990
  "composite": {
10922
10991
  "fontFamily": "Satoshi, system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", sans-serif",
10923
10992
  "fontSize": "48px",
10924
10993
  "fontWeight": "700",
10925
10994
  "letterSpacing": "-0.01em",
10926
- "lineHeight": "1.25"
10995
+ "lineHeight": "1.05"
10927
10996
  }
10928
10997
  },
10929
10998
  {
10930
- "path": "semantic.typography.h2",
10931
- "cssVar": "--semantic-typography-h2",
10999
+ "path": "semantic.typography.title",
11000
+ "cssVar": "--semantic-typography-title",
10932
11001
  "type": "typography",
10933
- "description": "Secondary section headings (h2). Satoshi bold 700, 30px, line-height 40px (hds#283: rung renamed, was 42px).",
11002
+ "description": "Section and card headings. 24px / 1.25 / 700. Role 2 of 6.",
10934
11003
  "composite": {
10935
11004
  "fontFamily": "Satoshi, system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", sans-serif",
10936
- "fontSize": "30px",
11005
+ "fontSize": "24px",
10937
11006
  "fontWeight": "700",
10938
11007
  "letterSpacing": "-0.01em",
10939
- "lineHeight": "40px"
10940
- }
10941
- },
10942
- {
10943
- "path": "semantic.typography.h3",
10944
- "cssVar": "--semantic-typography-h3",
10945
- "type": "typography",
10946
- "description": "Component and card headers (h3). 20px / Satoshi bold 700 500 / leading-snug (hds#283: rung renamed lg→xl, px unchanged).",
10947
- "composite": {
10948
- "fontFamily": "Satoshi, system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", sans-serif",
10949
- "fontSize": "20px",
10950
- "fontWeight": "700",
10951
- "letterSpacing": "0em",
10952
- "lineHeight": "28px"
11008
+ "lineHeight": "1.25"
10953
11009
  }
10954
11010
  },
10955
11011
  {
10956
11012
  "path": "semantic.typography.body",
10957
11013
  "cssVar": "--semantic-typography-body",
10958
11014
  "type": "typography",
10959
- "description": "Body prose. Satoshi medium, 16px, line-height 24px, max 60ch measure (hds#283: was 17px/28px).",
11015
+ "description": "Prose. 16px / 1.6 / 400, 60ch measure. Role 3 of 6.",
10960
11016
  "composite": {
10961
11017
  "fontFamily": "Satoshi, system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", sans-serif",
10962
11018
  "fontSize": "16px",
10963
- "fontWeight": "500",
11019
+ "fontWeight": "400",
10964
11020
  "letterSpacing": "0em",
10965
- "lineHeight": "24px",
11021
+ "lineHeight": "1.6",
10966
11022
  "maxWidth": "60ch"
10967
11023
  }
10968
11024
  },
@@ -10970,13 +11026,13 @@
10970
11026
  "path": "semantic.typography.ui",
10971
11027
  "cssVar": "--semantic-typography-ui",
10972
11028
  "type": "typography",
10973
- "description": "UI text for nav, labels, captions. Satoshi medium, 14px, line-height 20px (hds#283: was 15px/24px).",
11029
+ "description": "Controls, nav, table text, values. 14px / 1.5 / 500. Role 4 of 6.",
10974
11030
  "composite": {
10975
11031
  "fontFamily": "Satoshi, system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", sans-serif",
10976
11032
  "fontSize": "14px",
10977
11033
  "fontWeight": "500",
10978
11034
  "letterSpacing": "0em",
10979
- "lineHeight": "20px",
11035
+ "lineHeight": "1.5",
10980
11036
  "maxWidth": "60ch"
10981
11037
  }
10982
11038
  },
@@ -10984,41 +11040,79 @@
10984
11040
  "path": "semantic.typography.caption",
10985
11041
  "cssVar": "--semantic-typography-caption",
10986
11042
  "type": "typography",
10987
- "description": "Caption / helper text. Satoshi medium, 12px, line-height 16px. Matches the Figma typography/caption text style; now sourced from primitive.xs (hds#283).",
11043
+ "description": "Metadata, help text and labels, in sentence case. 12px / 1.5 / 500. Role 5 of 6.",
10988
11044
  "composite": {
10989
11045
  "fontFamily": "Satoshi, system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", sans-serif",
10990
11046
  "fontSize": "12px",
10991
11047
  "fontWeight": "500",
10992
11048
  "letterSpacing": "0em",
10993
- "lineHeight": "16px"
11049
+ "lineHeight": "1.5"
10994
11050
  }
10995
11051
  },
10996
11052
  {
10997
- "path": "semantic.typography.eyebrow",
10998
- "cssVar": "--semantic-typography-eyebrow",
11053
+ "path": "semantic.typography.mono",
11054
+ "cssVar": "--semantic-typography-mono",
11055
+ "type": "typography",
11056
+ "description": "Code and ids. 13px / 1.5 / 400. The mono companion, role 6 of 6.",
11057
+ "composite": {
11058
+ "fontFamily": "\"Geist Mono\", \"Courier New\", monospace",
11059
+ "fontSize": "13px",
11060
+ "fontWeight": "400",
11061
+ "letterSpacing": "0em",
11062
+ "lineHeight": "1.5",
11063
+ "maxWidth": "60ch"
11064
+ }
11065
+ },
11066
+ {
11067
+ "path": "semantic.typography.h1",
11068
+ "cssVar": "--semantic-typography-h1",
10999
11069
  "type": "typography",
11000
- "description": "Eyebrow / kicker label. Satoshi medium, 12px, caps tracking, uppercase (hds#283: was 13px/20px).",
11070
+ "description": "deprecated: use semantic.typography.title",
11001
11071
  "composite": {
11002
11072
  "fontFamily": "Satoshi, system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", sans-serif",
11003
- "fontSize": "12px",
11004
- "fontWeight": "500",
11005
- "letterSpacing": "0.06em",
11006
- "lineHeight": "16px",
11007
- "textTransform": "uppercase"
11073
+ "fontSize": "24px",
11074
+ "fontWeight": "700",
11075
+ "letterSpacing": "-0.01em",
11076
+ "lineHeight": "1.25"
11008
11077
  }
11009
11078
  },
11010
11079
  {
11011
- "path": "semantic.typography.mono",
11012
- "cssVar": "--semantic-typography-mono",
11080
+ "path": "semantic.typography.h2",
11081
+ "cssVar": "--semantic-typography-h2",
11013
11082
  "type": "typography",
11014
- "description": "Monospace for code, token names, shortcuts. Geist Mono regular, 14px (hds#283: repointed xs→sm; xs alone would give 12px).",
11083
+ "description": "deprecated: use semantic.typography.title",
11015
11084
  "composite": {
11016
- "fontFamily": "\"Geist Mono\", \"Courier New\", monospace",
11017
- "fontSize": "14px",
11018
- "fontWeight": "400",
11085
+ "fontFamily": "Satoshi, system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", sans-serif",
11086
+ "fontSize": "24px",
11087
+ "fontWeight": "700",
11088
+ "letterSpacing": "-0.01em",
11089
+ "lineHeight": "1.25"
11090
+ }
11091
+ },
11092
+ {
11093
+ "path": "semantic.typography.h3",
11094
+ "cssVar": "--semantic-typography-h3",
11095
+ "type": "typography",
11096
+ "description": "deprecated: use semantic.typography.title",
11097
+ "composite": {
11098
+ "fontFamily": "Satoshi, system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", sans-serif",
11099
+ "fontSize": "24px",
11100
+ "fontWeight": "700",
11101
+ "letterSpacing": "-0.01em",
11102
+ "lineHeight": "1.25"
11103
+ }
11104
+ },
11105
+ {
11106
+ "path": "semantic.typography.eyebrow",
11107
+ "cssVar": "--semantic-typography-eyebrow",
11108
+ "type": "typography",
11109
+ "description": "deprecated: use semantic.typography.caption",
11110
+ "composite": {
11111
+ "fontFamily": "Satoshi, system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", sans-serif",
11112
+ "fontSize": "12px",
11113
+ "fontWeight": "500",
11019
11114
  "letterSpacing": "0em",
11020
- "lineHeight": "20px",
11021
- "maxWidth": "60ch"
11115
+ "lineHeight": "1.5"
11022
11116
  }
11023
11117
  },
11024
11118
  {
@@ -11483,10 +11577,10 @@
11483
11577
  {
11484
11578
  "path": "component.tag.lineHeight",
11485
11579
  "cssVar": "--component-tag-lineHeight",
11486
- "type": "dimension",
11580
+ "type": "number",
11487
11581
  "description": "Readable label rhythm for tags.",
11488
11582
  "alias": "{primitive.typography.lineHeight.normal}",
11489
- "resolvedValue": "undefinedundefined"
11583
+ "resolvedValue": "1.5"
11490
11584
  },
11491
11585
  {
11492
11586
  "path": "component.tag.minWidth",