open-ds 0.0.0-stage → 0.1.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 (201) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +66 -2
  3. package/assets/schemes/accessible-first.json +3093 -0
  4. package/assets/schemes/brand-expressive.json +3124 -0
  5. package/assets/schemes/content-first.json +3110 -0
  6. package/assets/schemes/dense-data.json +3489 -0
  7. package/assets/schemes/grammar.json +3903 -0
  8. package/assets/schemes/multi-brand.json +4359 -0
  9. package/assets/skills/open-ds/SKILL.md +50 -0
  10. package/assets/skills/open-ds-build/SKILL.md +19 -0
  11. package/assets/skills/open-ds-change/SKILL.md +19 -0
  12. package/assets/skills/open-ds-choose/SKILL.md +18 -0
  13. package/assets/skills/open-ds-review/SKILL.md +22 -0
  14. package/assets/skills/open-ds-write/SKILL.md +13 -0
  15. package/assets/stories/accordion.stories.tsx +46 -0
  16. package/assets/stories/alert-dialog.stories.tsx +65 -0
  17. package/assets/stories/alert.stories.tsx +44 -0
  18. package/assets/stories/aspect-ratio.stories.tsx +37 -0
  19. package/assets/stories/avatar.stories.tsx +42 -0
  20. package/assets/stories/badge.stories.tsx +39 -0
  21. package/assets/stories/breadcrumb.stories.tsx +54 -0
  22. package/assets/stories/button.stories.tsx +46 -0
  23. package/assets/stories/calendar.stories.tsx +30 -0
  24. package/assets/stories/card.stories.tsx +50 -0
  25. package/assets/stories/carousel.stories.tsx +64 -0
  26. package/assets/stories/chart.stories.tsx +61 -0
  27. package/assets/stories/checkbox.stories.tsx +29 -0
  28. package/assets/stories/collapsible.stories.tsx +39 -0
  29. package/assets/stories/combobox.stories.tsx +57 -0
  30. package/assets/stories/command.stories.tsx +60 -0
  31. package/assets/stories/context-menu.stories.tsx +55 -0
  32. package/assets/stories/data-table.stories.tsx +93 -0
  33. package/assets/stories/date-picker.stories.tsx +27 -0
  34. package/assets/stories/dialog.stories.tsx +70 -0
  35. package/assets/stories/drawer.stories.tsx +62 -0
  36. package/assets/stories/dropdown-menu.stories.tsx +65 -0
  37. package/assets/stories/empty.stories.tsx +39 -0
  38. package/assets/stories/field.stories.tsx +42 -0
  39. package/assets/stories/form.stories.tsx +56 -0
  40. package/assets/stories/input-group.stories.tsx +41 -0
  41. package/assets/stories/input-otp.stories.tsx +48 -0
  42. package/assets/stories/input.stories.tsx +32 -0
  43. package/assets/stories/kbd.stories.tsx +30 -0
  44. package/assets/stories/label.stories.tsx +26 -0
  45. package/assets/stories/native-select.stories.tsx +39 -0
  46. package/assets/stories/navigation-menu.stories.tsx +41 -0
  47. package/assets/stories/pagination.stories.tsx +61 -0
  48. package/assets/stories/popover.stories.tsx +37 -0
  49. package/assets/stories/progress.stories.tsx +30 -0
  50. package/assets/stories/radio-group.stories.tsx +45 -0
  51. package/assets/stories/resizable.stories.tsx +54 -0
  52. package/assets/stories/scroll-area.stories.tsx +47 -0
  53. package/assets/stories/select.stories.tsx +57 -0
  54. package/assets/stories/separator.stories.tsx +28 -0
  55. package/assets/stories/sheet.stories.tsx +46 -0
  56. package/assets/stories/sidebar.stories.tsx +62 -0
  57. package/assets/stories/skeleton.stories.tsx +27 -0
  58. package/assets/stories/slider.stories.tsx +44 -0
  59. package/assets/stories/spinner.stories.tsx +25 -0
  60. package/assets/stories/switch.stories.tsx +29 -0
  61. package/assets/stories/table.stories.tsx +97 -0
  62. package/assets/stories/tabs.stories.tsx +55 -0
  63. package/assets/stories/textarea.stories.tsx +28 -0
  64. package/assets/stories/toast.stories.tsx +30 -0
  65. package/assets/stories/toggle-group.stories.tsx +41 -0
  66. package/assets/stories/toggle.stories.tsx +20 -0
  67. package/assets/stories/tooltip.stories.tsx +49 -0
  68. package/assets/tokens/accessible-first/content.json +32 -0
  69. package/assets/tokens/accessible-first/dark.tokens.json +581 -0
  70. package/assets/tokens/accessible-first/light.tokens.json +581 -0
  71. package/assets/tokens/accessible-first/shadcn.css +21 -0
  72. package/assets/tokens/accessible-first/theme.css +101 -0
  73. package/assets/tokens/accessible-first/tokens.css +331 -0
  74. package/assets/tokens/accessible-first/tokens.json +1616 -0
  75. package/assets/tokens/accessible-first/tokens.scoped.css +333 -0
  76. package/assets/tokens/brand-expressive/content.json +32 -0
  77. package/assets/tokens/brand-expressive/dark.tokens.json +585 -0
  78. package/assets/tokens/brand-expressive/light.tokens.json +585 -0
  79. package/assets/tokens/brand-expressive/shadcn.css +21 -0
  80. package/assets/tokens/brand-expressive/theme.css +101 -0
  81. package/assets/tokens/brand-expressive/tokens.css +331 -0
  82. package/assets/tokens/brand-expressive/tokens.json +1651 -0
  83. package/assets/tokens/brand-expressive/tokens.scoped.css +333 -0
  84. package/assets/tokens/content-first/content.json +32 -0
  85. package/assets/tokens/content-first/dark.tokens.json +582 -0
  86. package/assets/tokens/content-first/light.tokens.json +582 -0
  87. package/assets/tokens/content-first/shadcn.css +21 -0
  88. package/assets/tokens/content-first/theme.css +101 -0
  89. package/assets/tokens/content-first/tokens.css +331 -0
  90. package/assets/tokens/content-first/tokens.json +1631 -0
  91. package/assets/tokens/content-first/tokens.scoped.css +333 -0
  92. package/assets/tokens/dense-data/content.json +32 -0
  93. package/assets/tokens/dense-data/dark.tokens.json +580 -0
  94. package/assets/tokens/dense-data/light.tokens.json +580 -0
  95. package/assets/tokens/dense-data/shadcn.css +21 -0
  96. package/assets/tokens/dense-data/theme.css +101 -0
  97. package/assets/tokens/dense-data/tokens.css +331 -0
  98. package/assets/tokens/dense-data/tokens.json +1623 -0
  99. package/assets/tokens/dense-data/tokens.scoped.css +333 -0
  100. package/assets/tokens/index.json +143 -0
  101. package/assets/tokens/multi-brand/aster-dark.tokens.json +625 -0
  102. package/assets/tokens/multi-brand/aster-light.tokens.json +625 -0
  103. package/assets/tokens/multi-brand/birch-dark.tokens.json +625 -0
  104. package/assets/tokens/multi-brand/birch-light.tokens.json +625 -0
  105. package/assets/tokens/multi-brand/content.json +32 -0
  106. package/assets/tokens/multi-brand/coral-dark.tokens.json +625 -0
  107. package/assets/tokens/multi-brand/coral-light.tokens.json +625 -0
  108. package/assets/tokens/multi-brand/shadcn.css +21 -0
  109. package/assets/tokens/multi-brand/theme.css +101 -0
  110. package/assets/tokens/multi-brand/tokens.css +1002 -0
  111. package/assets/tokens/multi-brand/tokens.json +1754 -0
  112. package/assets/tokens/multi-brand/tokens.scoped.css +1022 -0
  113. package/assets/tokens/shadcn-map.json +34 -0
  114. package/assets/ui/components/accordion.tsx +60 -0
  115. package/assets/ui/components/alert-dialog.tsx +171 -0
  116. package/assets/ui/components/alert.tsx +56 -0
  117. package/assets/ui/components/aspect-ratio.tsx +17 -0
  118. package/assets/ui/components/avatar.tsx +96 -0
  119. package/assets/ui/components/badge.tsx +36 -0
  120. package/assets/ui/components/breadcrumb.tsx +99 -0
  121. package/assets/ui/components/button.tsx +53 -0
  122. package/assets/ui/components/calendar.tsx +169 -0
  123. package/assets/ui/components/card.tsx +72 -0
  124. package/assets/ui/components/carousel.tsx +224 -0
  125. package/assets/ui/components/chart.tsx +315 -0
  126. package/assets/ui/components/checkbox.tsx +29 -0
  127. package/assets/ui/components/collapsible.tsx +25 -0
  128. package/assets/ui/components/combobox.tsx +275 -0
  129. package/assets/ui/components/command.tsx +145 -0
  130. package/assets/ui/components/context-menu.tsx +218 -0
  131. package/assets/ui/components/data-table.tsx +307 -0
  132. package/assets/ui/components/date-picker.tsx +79 -0
  133. package/assets/ui/components/dialog.tsx +68 -0
  134. package/assets/ui/components/drawer.tsx +115 -0
  135. package/assets/ui/components/dropdown-menu.tsx +58 -0
  136. package/assets/ui/components/empty.tsx +92 -0
  137. package/assets/ui/components/field.tsx +234 -0
  138. package/assets/ui/components/form.tsx +146 -0
  139. package/assets/ui/components/input-group.tsx +154 -0
  140. package/assets/ui/components/input-otp.tsx +75 -0
  141. package/assets/ui/components/input.tsx +25 -0
  142. package/assets/ui/components/kbd.tsx +30 -0
  143. package/assets/ui/components/label.tsx +22 -0
  144. package/assets/ui/components/native-select.tsx +59 -0
  145. package/assets/ui/components/navigation-menu.tsx +149 -0
  146. package/assets/ui/components/pagination.tsx +108 -0
  147. package/assets/ui/components/popover.tsx +61 -0
  148. package/assets/ui/components/progress.tsx +31 -0
  149. package/assets/ui/components/radio-group.tsx +40 -0
  150. package/assets/ui/components/resizable.tsx +54 -0
  151. package/assets/ui/components/scroll-area.tsx +55 -0
  152. package/assets/ui/components/select.tsx +81 -0
  153. package/assets/ui/components/separator.tsx +35 -0
  154. package/assets/ui/components/sheet.tsx +114 -0
  155. package/assets/ui/components/sidebar.tsx +685 -0
  156. package/assets/ui/components/skeleton.tsx +15 -0
  157. package/assets/ui/components/slider.tsx +70 -0
  158. package/assets/ui/components/spinner.tsx +16 -0
  159. package/assets/ui/components/switch.tsx +32 -0
  160. package/assets/ui/components/table.tsx +78 -0
  161. package/assets/ui/components/tabs.tsx +49 -0
  162. package/assets/ui/components/textarea.tsx +25 -0
  163. package/assets/ui/components/toast.tsx +54 -0
  164. package/assets/ui/components/toggle-group.tsx +88 -0
  165. package/assets/ui/components/toggle.tsx +48 -0
  166. package/assets/ui/components/tooltip.tsx +34 -0
  167. package/assets/ui/lib/use-mobile.ts +20 -0
  168. package/assets/ui/lib/utils.ts +7 -0
  169. package/assets/ui/styles.css +27 -0
  170. package/bin/open-ds.js +6 -0
  171. package/package.json +56 -4
  172. package/src/agents.mjs +150 -0
  173. package/src/cli.mjs +445 -0
  174. package/src/components.mjs +69 -0
  175. package/src/context.mjs +143 -0
  176. package/src/create.mjs +377 -0
  177. package/src/docs.mjs +570 -0
  178. package/src/guidance.mjs +63 -0
  179. package/src/index.mjs +20 -0
  180. package/src/mcp.mjs +660 -0
  181. package/src/readmes.mjs +106 -0
  182. package/src/schemes.mjs +188 -0
  183. package/src/tokens.mjs +127 -0
  184. package/templates/project/.github/workflows/ci.yml +15 -0
  185. package/templates/project/.storybook/component-docs.mdx +26 -0
  186. package/templates/project/.storybook/main.ts +17 -0
  187. package/templates/project/.storybook/manager-head.html +3 -0
  188. package/templates/project/.storybook/manager.ts +37 -0
  189. package/templates/project/.storybook/preview-head.html +3 -0
  190. package/templates/project/.storybook/preview.tsx +82 -0
  191. package/templates/project/docs/docusaurus.config.ts +64 -0
  192. package/templates/project/docs/sidebars.ts +8 -0
  193. package/templates/project/docs/src/css/custom.css +275 -0
  194. package/templates/project/gitignore +6 -0
  195. package/templates/project/src/styles/index.css +16 -0
  196. package/templates/project/src/vite-env.d.ts +7 -0
  197. package/templates/project/stories/docs-blocks.tsx +190 -0
  198. package/templates/project/stories/samples.tsx +102 -0
  199. package/templates/project/stories/usage.tsx +31 -0
  200. package/templates/project/tokens/build.mjs +468 -0
  201. package/templates/project/tsconfig.json +15 -0
@@ -0,0 +1,3489 @@
1
+ {
2
+ "$schema": "../schema/scheme.schema.json",
3
+ "id": "dense-data",
4
+ "name": "Dense data",
5
+ "version": "0.1.0",
6
+ "status": "draft",
7
+ "summary": "Compact, exact and quiet, for analysts who scan alerts and compare signals all day.",
8
+ "description": "Dense data is an Open DS scheme: a full set of answers to the Open DS grammar, with the reasons behind each, usage rules, voice and tone, and the tokens that follow. Compact, exact and quiet, for analysts who scan alerts and compare signals all day.",
9
+ "ai": {
10
+ "use_when": "Security operations, threat detection, model monitoring, admin panels and analytics: many records, daily expert users, mouse and keyboard.",
11
+ "avoid_when": "Public sites, reading products, or first-time visitors on phones.",
12
+ "example_products": [
13
+ "Security operations console",
14
+ "Threat detection",
15
+ "AI model monitoring",
16
+ "Analytics dashboard"
17
+ ]
18
+ },
19
+ "scenarios": [
20
+ {
21
+ "text": "A security analyst opens the alert queue at 8:00 and scans 200 rows for escalated threats.",
22
+ "follows": [
23
+ "scenarios.q1",
24
+ "scenarios.q2",
25
+ "tasks.q1"
26
+ ]
27
+ },
28
+ {
29
+ "text": "An analyst compares this week's detections with last week's, model by model and column by column.",
30
+ "follows": [
31
+ "tasks.q1",
32
+ "content.q1"
33
+ ]
34
+ }
35
+ ],
36
+ "voice": {
37
+ "summary": {
38
+ "text": "Terse and exact. Say what happened and what to do, in as few words as possible.",
39
+ "follows": [
40
+ "voice.values",
41
+ "people.q1"
42
+ ]
43
+ },
44
+ "principles": [
45
+ {
46
+ "text": "Lead with the object, then the state: \"Alert 2041 contained.\"",
47
+ "follows": [
48
+ "voice.values",
49
+ "content.q1"
50
+ ]
51
+ },
52
+ {
53
+ "text": "Use numbers, not words for numbers.",
54
+ "follows": [
55
+ "content.q1"
56
+ ]
57
+ },
58
+ {
59
+ "text": "One verb per button. No \"please\", no exclamation marks.",
60
+ "follows": [
61
+ "voice.definition",
62
+ "voice.values"
63
+ ]
64
+ }
65
+ ],
66
+ "words": {
67
+ "use": [
68
+ "Investigate",
69
+ "Filter",
70
+ "Assign",
71
+ "Escalated",
72
+ "Resolved"
73
+ ],
74
+ "avoid": [
75
+ "Oops",
76
+ "Awesome",
77
+ "Please",
78
+ "Simply"
79
+ ],
80
+ "follows": [
81
+ "voice.definition"
82
+ ]
83
+ }
84
+ },
85
+ "inventory": {
86
+ "description": "The components this system carries, picked from the grammar catalogue by the components answers. Anything not listed is out.",
87
+ "follows": [
88
+ "components.roles",
89
+ "components.count",
90
+ "components.definition"
91
+ ],
92
+ "in": [
93
+ {
94
+ "id": "button",
95
+ "why": "Every action."
96
+ },
97
+ {
98
+ "id": "toggle-group",
99
+ "why": "Switches a table between views and densities."
100
+ },
101
+ {
102
+ "id": "input",
103
+ "why": "Search and edit fields."
104
+ },
105
+ {
106
+ "id": "input-group",
107
+ "why": "Search with an icon and a clear button."
108
+ },
109
+ {
110
+ "id": "slider",
111
+ "why": "Narrows a filter to a range of risk scores by dragging."
112
+ },
113
+ {
114
+ "id": "select",
115
+ "why": "Picks one value in filters and forms."
116
+ },
117
+ {
118
+ "id": "radio-group",
119
+ "why": "Picks one of two or three options, all visible at once."
120
+ },
121
+ {
122
+ "id": "combobox",
123
+ "why": "Picks an asset or a user from thousands."
124
+ },
125
+ {
126
+ "id": "checkbox",
127
+ "why": "Selects rows and filter values."
128
+ },
129
+ {
130
+ "id": "switch",
131
+ "why": "Settings that apply at once."
132
+ },
133
+ {
134
+ "id": "label",
135
+ "why": "Names every control."
136
+ },
137
+ {
138
+ "id": "field",
139
+ "why": "Lays out label, control and error the same way everywhere."
140
+ },
141
+ {
142
+ "id": "form",
143
+ "why": "Keeps validation and errors the same on every record edit."
144
+ },
145
+ {
146
+ "id": "textarea",
147
+ "why": "Notes on an alert, for the next analyst."
148
+ },
149
+ {
150
+ "id": "calendar",
151
+ "why": "Date ranges for reports."
152
+ },
153
+ {
154
+ "id": "date-picker",
155
+ "why": "Picks a date range for reports and filters from a button in the toolbar."
156
+ },
157
+ {
158
+ "id": "table",
159
+ "why": "The heart of the product: rows of records."
160
+ },
161
+ {
162
+ "id": "data-table",
163
+ "why": "Analysts scan hundreds of alerts, filter by status and asset group, sort by risk and act on many rows at once."
164
+ },
165
+ {
166
+ "id": "pagination",
167
+ "why": "Moves through long result sets."
168
+ },
169
+ {
170
+ "id": "badge",
171
+ "why": "Alert status in rows."
172
+ },
173
+ {
174
+ "id": "chart",
175
+ "why": "Totals over time on dashboards."
176
+ },
177
+ {
178
+ "id": "command",
179
+ "why": "Keyboard-first jump to any record or action."
180
+ },
181
+ {
182
+ "id": "dropdown-menu",
183
+ "why": "Row actions."
184
+ },
185
+ {
186
+ "id": "context-menu",
187
+ "why": "Right-click on a row, for experts."
188
+ },
189
+ {
190
+ "id": "tabs",
191
+ "why": "Views of one record."
192
+ },
193
+ {
194
+ "id": "sidebar",
195
+ "why": "App navigation that stays open all shift."
196
+ },
197
+ {
198
+ "id": "kbd",
199
+ "why": "Shows the shortcuts experts learn."
200
+ },
201
+ {
202
+ "id": "alert",
203
+ "why": "A problem that stays on the page."
204
+ },
205
+ {
206
+ "id": "toast",
207
+ "why": "Confirms a saved change."
208
+ },
209
+ {
210
+ "id": "skeleton",
211
+ "why": "Rows while a table loads."
212
+ },
213
+ {
214
+ "id": "empty",
215
+ "why": "An empty table says what to do next."
216
+ },
217
+ {
218
+ "id": "dialog",
219
+ "why": "Edit one record without leaving the table."
220
+ },
221
+ {
222
+ "id": "alert-dialog",
223
+ "why": "Confirms a delete."
224
+ },
225
+ {
226
+ "id": "sheet",
227
+ "why": "Record details beside the table."
228
+ },
229
+ {
230
+ "id": "popover",
231
+ "why": "Filters next to the column."
232
+ },
233
+ {
234
+ "id": "tooltip",
235
+ "why": "Explains an icon button."
236
+ },
237
+ {
238
+ "id": "card",
239
+ "why": "Dashboard figures."
240
+ },
241
+ {
242
+ "id": "separator",
243
+ "why": "Groups toolbar actions."
244
+ },
245
+ {
246
+ "id": "scroll-area",
247
+ "why": "Long tables in fixed panels."
248
+ },
249
+ {
250
+ "id": "resizable",
251
+ "why": "Experts size the table and detail panes."
252
+ }
253
+ ],
254
+ "out": [
255
+ {
256
+ "id": "carousel",
257
+ "why": "Slides hide records; experts need them all in view."
258
+ },
259
+ {
260
+ "id": "drawer",
261
+ "why": "A desk tool with a mouse and keyboard does not need phone drawers."
262
+ },
263
+ {
264
+ "id": "accordion",
265
+ "why": "Hiding fields slows people who use them all day."
266
+ }
267
+ ]
268
+ },
269
+ "samples": {
270
+ "description": "Sample content for showing this system: written from its use scenarios, in its voice, with every status mapped to a meaning. Storybook, the site and the docs read it; it is never shared between schemes.",
271
+ "follows": [
272
+ "scenarios.q1",
273
+ "content.q1",
274
+ "voice.values",
275
+ "voice.definition"
276
+ ],
277
+ "screen": "Open alerts",
278
+ "actions": {
279
+ "primary": "Investigate",
280
+ "secondary": "Export"
281
+ },
282
+ "statuses": [
283
+ {
284
+ "label": "New",
285
+ "meaning": "neutral",
286
+ "why": "Not triaged yet; nothing is confirmed."
287
+ },
288
+ {
289
+ "label": "Investigating",
290
+ "meaning": "info",
291
+ "why": "An analyst is on it: news, nothing for you to act on."
292
+ },
293
+ {
294
+ "label": "Escalated",
295
+ "meaning": "warning",
296
+ "why": "Needs a senior analyst soon, still containable."
297
+ },
298
+ {
299
+ "label": "Breach confirmed",
300
+ "meaning": "danger",
301
+ "why": "Data left or an account was taken over: a real loss."
302
+ },
303
+ {
304
+ "label": "Resolved",
305
+ "meaning": "success",
306
+ "why": "Contained and closed."
307
+ },
308
+ {
309
+ "label": "False positive",
310
+ "meaning": "neutral",
311
+ "why": "The detection was wrong; a finished outcome, not a failure."
312
+ }
313
+ ],
314
+ "table": {
315
+ "caption": "Open alerts",
316
+ "columns": [
317
+ {
318
+ "label": "Alert"
319
+ },
320
+ {
321
+ "label": "Asset"
322
+ },
323
+ {
324
+ "label": "Detected"
325
+ },
326
+ {
327
+ "label": "Risk score",
328
+ "numeric": true
329
+ },
330
+ {
331
+ "label": "Status"
332
+ }
333
+ ],
334
+ "rows": [
335
+ {
336
+ "cells": [
337
+ "ALR-2041",
338
+ "api-gateway-01",
339
+ "08:30",
340
+ "92"
341
+ ],
342
+ "status": "Resolved"
343
+ },
344
+ {
345
+ "cells": [
346
+ "ALR-2042",
347
+ "llm-inference-02",
348
+ "09:10",
349
+ "78"
350
+ ],
351
+ "status": "Escalated"
352
+ },
353
+ {
354
+ "cells": [
355
+ "ALR-2043",
356
+ "vpn-edge-03",
357
+ "09:45",
358
+ "99"
359
+ ],
360
+ "status": "Breach confirmed"
361
+ },
362
+ {
363
+ "cells": [
364
+ "ALR-2044",
365
+ "model-registry",
366
+ "10:20",
367
+ "31"
368
+ ],
369
+ "status": "False positive"
370
+ },
371
+ {
372
+ "cells": [
373
+ "ALR-2045",
374
+ "auth-service",
375
+ "11:00",
376
+ "64"
377
+ ],
378
+ "status": "Investigating"
379
+ },
380
+ {
381
+ "cells": [
382
+ "ALR-2046",
383
+ "db-primary",
384
+ "11:30",
385
+ "81"
386
+ ],
387
+ "status": "Escalated"
388
+ },
389
+ {
390
+ "cells": [
391
+ "ALR-2047",
392
+ "build-runner-07",
393
+ "11:45",
394
+ "57"
395
+ ],
396
+ "status": "Resolved"
397
+ },
398
+ {
399
+ "cells": [
400
+ "ALR-2048",
401
+ "llm-inference-04",
402
+ "12:00",
403
+ "45"
404
+ ],
405
+ "status": "New"
406
+ },
407
+ {
408
+ "cells": [
409
+ "ALR-2049",
410
+ "api-gateway-01",
411
+ "12:15",
412
+ "70"
413
+ ],
414
+ "status": "Resolved"
415
+ },
416
+ {
417
+ "cells": [
418
+ "ALR-2050",
419
+ "llm-inference-02",
420
+ "12:30",
421
+ "97"
422
+ ],
423
+ "status": "Breach confirmed"
424
+ },
425
+ {
426
+ "cells": [
427
+ "ALR-2051",
428
+ "vpn-edge-03",
429
+ "12:45",
430
+ "52"
431
+ ],
432
+ "status": "Resolved"
433
+ },
434
+ {
435
+ "cells": [
436
+ "ALR-2052",
437
+ "model-registry",
438
+ "13:00",
439
+ "84"
440
+ ],
441
+ "status": "Escalated"
442
+ },
443
+ {
444
+ "cells": [
445
+ "ALR-2053",
446
+ "auth-service",
447
+ "13:15",
448
+ "28"
449
+ ],
450
+ "status": "False positive"
451
+ },
452
+ {
453
+ "cells": [
454
+ "ALR-2054",
455
+ "db-primary",
456
+ "13:30",
457
+ "49"
458
+ ],
459
+ "status": "New"
460
+ },
461
+ {
462
+ "cells": [
463
+ "ALR-2055",
464
+ "build-runner-07",
465
+ "13:45",
466
+ "66"
467
+ ],
468
+ "status": "Resolved"
469
+ },
470
+ {
471
+ "cells": [
472
+ "ALR-2056",
473
+ "llm-inference-04",
474
+ "14:00",
475
+ "73"
476
+ ],
477
+ "status": "Resolved"
478
+ },
479
+ {
480
+ "cells": [
481
+ "ALR-2057",
482
+ "api-gateway-01",
483
+ "14:15",
484
+ "88"
485
+ ],
486
+ "status": "Escalated"
487
+ },
488
+ {
489
+ "cells": [
490
+ "ALR-2058",
491
+ "llm-inference-02",
492
+ "14:30",
493
+ "61"
494
+ ],
495
+ "status": "Resolved"
496
+ },
497
+ {
498
+ "cells": [
499
+ "ALR-2059",
500
+ "vpn-edge-03",
501
+ "14:45",
502
+ "55"
503
+ ],
504
+ "status": "Investigating"
505
+ },
506
+ {
507
+ "cells": [
508
+ "ALR-2060",
509
+ "model-registry",
510
+ "15:00",
511
+ "69"
512
+ ],
513
+ "status": "Resolved"
514
+ },
515
+ {
516
+ "cells": [
517
+ "ALR-2061",
518
+ "auth-service",
519
+ "15:15",
520
+ "22"
521
+ ],
522
+ "status": "False positive"
523
+ },
524
+ {
525
+ "cells": [
526
+ "ALR-2062",
527
+ "db-primary",
528
+ "15:30",
529
+ "74"
530
+ ],
531
+ "status": "Resolved"
532
+ },
533
+ {
534
+ "cells": [
535
+ "ALR-2063",
536
+ "build-runner-07",
537
+ "15:45",
538
+ "86"
539
+ ],
540
+ "status": "Escalated"
541
+ },
542
+ {
543
+ "cells": [
544
+ "ALR-2064",
545
+ "llm-inference-04",
546
+ "16:00",
547
+ "43"
548
+ ],
549
+ "status": "New"
550
+ }
551
+ ]
552
+ },
553
+ "metrics": [
554
+ {
555
+ "label": "Open alerts",
556
+ "value": "142"
557
+ },
558
+ {
559
+ "label": "Escalated",
560
+ "value": "7"
561
+ },
562
+ {
563
+ "label": "Model precision",
564
+ "value": "96.4%"
565
+ },
566
+ {
567
+ "label": "Mean time to contain",
568
+ "value": "38 min"
569
+ }
570
+ ],
571
+ "field": {
572
+ "label": "Risk threshold",
573
+ "placeholder": "0",
574
+ "hint": "From 0 to 100.",
575
+ "error": "Threshold must be between 0 and 100.",
576
+ "invalid": "140"
577
+ },
578
+ "checkbox": [
579
+ "Escalated only",
580
+ "Assigned to me",
581
+ "Archived"
582
+ ],
583
+ "select": {
584
+ "label": "Asset group",
585
+ "options": [
586
+ "Production",
587
+ "Staging",
588
+ "Model endpoints"
589
+ ],
590
+ "value": "Model endpoints"
591
+ },
592
+ "switches": [
593
+ "Compact rows",
594
+ "Live updates"
595
+ ],
596
+ "messages": {
597
+ "success": "12 alerts exported.",
598
+ "error": {
599
+ "title": "Alert ALR-2042 not saved.",
600
+ "description": "Threshold must be between 0 and 100."
601
+ },
602
+ "neutral": "Filters cleared."
603
+ },
604
+ "confirm": {
605
+ "trigger": "Dismiss 3 alerts",
606
+ "title": "Dismiss 3 alerts?",
607
+ "body": "They leave the queue for good. This cannot be undone.",
608
+ "confirm": "Dismiss",
609
+ "cancel": "Keep them"
610
+ },
611
+ "card": {
612
+ "title": "Alert ALR-2043",
613
+ "description": "llm-inference-02 · prompt injection attempt",
614
+ "status": "Escalated",
615
+ "primary": "Investigate",
616
+ "secondary": "View"
617
+ },
618
+ "tabs": [
619
+ {
620
+ "label": "Open",
621
+ "content": "142 open alerts."
622
+ },
623
+ {
624
+ "label": "Escalated",
625
+ "content": "7 escalated alerts."
626
+ },
627
+ {
628
+ "label": "Resolved",
629
+ "content": "1,240 resolved this month."
630
+ }
631
+ ],
632
+ "menu": {
633
+ "trigger": "Actions for alert ALR-2041",
634
+ "items": [
635
+ "Assign",
636
+ "Add note"
637
+ ],
638
+ "destructive": "Dismiss"
639
+ },
640
+ "icon_action": "Filter"
641
+ },
642
+ "themes": [
643
+ {
644
+ "id": "light",
645
+ "brand": "default",
646
+ "mode": "light"
647
+ },
648
+ {
649
+ "id": "dark",
650
+ "brand": "default",
651
+ "mode": "dark"
652
+ }
653
+ ],
654
+ "answers": [
655
+ {
656
+ "question": "business.q1",
657
+ "option": "operate",
658
+ "why": "The product runs daily security operations: alerts, incidents and the assets they touch.",
659
+ "because": []
660
+ },
661
+ {
662
+ "question": "business.q2",
663
+ "option": "one",
664
+ "why": "One internal product, one brand.",
665
+ "because": []
666
+ },
667
+ {
668
+ "question": "people.q1",
669
+ "option": "experts",
670
+ "why": "The same people use it all day, every day.",
671
+ "because": [
672
+ "business.q1"
673
+ ]
674
+ },
675
+ {
676
+ "question": "people.q2",
677
+ "option": "aa",
678
+ "why": "AA is the floor for an internal tool used by trained staff.",
679
+ "because": [
680
+ "people.q1"
681
+ ]
682
+ },
683
+ {
684
+ "question": "content.q1",
685
+ "option": "numbers",
686
+ "why": "Most of the screen is numbers and records.",
687
+ "because": [
688
+ "business.q1"
689
+ ]
690
+ },
691
+ {
692
+ "question": "content.q2",
693
+ "option": "a-lot",
694
+ "why": "Experts want many records on one screen.",
695
+ "because": [
696
+ "people.q1",
697
+ "content.q1"
698
+ ]
699
+ },
700
+ {
701
+ "question": "tasks.q1",
702
+ "option": "compare",
703
+ "why": "People scan rows and compare values.",
704
+ "because": [
705
+ "content.q1"
706
+ ]
707
+ },
708
+ {
709
+ "question": "tasks.q2",
710
+ "option": "constantly",
711
+ "why": "The same actions repeat many times an hour.",
712
+ "because": [
713
+ "people.q1"
714
+ ]
715
+ },
716
+ {
717
+ "question": "human.q1",
718
+ "option": "place",
719
+ "why": "Losing your place in a long table costs time and errors.",
720
+ "because": [
721
+ "tasks.q1"
722
+ ]
723
+ },
724
+ {
725
+ "question": "human.q2",
726
+ "option": "learned",
727
+ "why": "Daily users learn the interface and recognise it.",
728
+ "because": [
729
+ "people.q1"
730
+ ]
731
+ },
732
+ {
733
+ "question": "outcomes.q1",
734
+ "option": "time-on-task",
735
+ "why": "Speed on repeated tasks is the measure.",
736
+ "because": [
737
+ "tasks.q2"
738
+ ]
739
+ },
740
+ {
741
+ "question": "outcomes.q2",
742
+ "option": "wrong-record",
743
+ "why": "Acting on the wrong row is the costly error.",
744
+ "because": [
745
+ "tasks.q1"
746
+ ]
747
+ },
748
+ {
749
+ "question": "brand.q1",
750
+ "option": "precise",
751
+ "why": "The interface must feel exact and trustworthy.",
752
+ "because": [
753
+ "content.q1"
754
+ ]
755
+ },
756
+ {
757
+ "question": "brand.q2",
758
+ "option": "quiet",
759
+ "why": "The data is the hero; the brand steps back.",
760
+ "because": [
761
+ "content.q2"
762
+ ]
763
+ },
764
+ {
765
+ "question": "scenarios.q1",
766
+ "option": "desk",
767
+ "why": "Experts work at a desk with a mouse and keyboard.",
768
+ "because": [
769
+ "people.q1"
770
+ ]
771
+ },
772
+ {
773
+ "question": "scenarios.q2",
774
+ "option": "all-day",
775
+ "why": "The tool stays open for the whole shift.",
776
+ "because": [
777
+ "tasks.q2"
778
+ ]
779
+ },
780
+ {
781
+ "question": "team.q1",
782
+ "option": "small",
783
+ "why": "A small team keeps the system right.",
784
+ "because": []
785
+ },
786
+ {
787
+ "question": "team.q2",
788
+ "option": "monthly",
789
+ "why": "Features ship every month; the system must keep up.",
790
+ "because": []
791
+ },
792
+ {
793
+ "question": "typography.roles",
794
+ "option": "core-data",
795
+ "why": "A data role keeps numbers in aligned columns.",
796
+ "because": [
797
+ "content.q1",
798
+ "tasks.q1"
799
+ ]
800
+ },
801
+ {
802
+ "question": "typography.count",
803
+ "option": "few",
804
+ "why": "A screen full of records stays calm with only the sizes it needs.",
805
+ "because": [
806
+ "content.q2"
807
+ ]
808
+ },
809
+ {
810
+ "question": "typography.definition",
811
+ "option": "ratio-grid",
812
+ "why": "Lines stay on the grid so rows align, and grow with the user's text size.",
813
+ "because": [
814
+ "tasks.q1",
815
+ "people.q2"
816
+ ]
817
+ },
818
+ {
819
+ "question": "typography.values",
820
+ "option": "small",
821
+ "why": "Small body text fits more rows on the screen.",
822
+ "because": [
823
+ "content.q2"
824
+ ]
825
+ },
826
+ {
827
+ "question": "typography.lands",
828
+ "option": "tables-inputs",
829
+ "why": "Most text sits in table cells and inputs.",
830
+ "because": [
831
+ "content.q1"
832
+ ]
833
+ },
834
+ {
835
+ "question": "color.roles",
836
+ "option": "core",
837
+ "why": "Surface, text, action and status cover an operations tool.",
838
+ "because": [
839
+ "brand.q2"
840
+ ]
841
+ },
842
+ {
843
+ "question": "color.count",
844
+ "option": "three",
845
+ "why": "One primary per view; the rest step back.",
846
+ "because": [
847
+ "tasks.q2"
848
+ ]
849
+ },
850
+ {
851
+ "question": "color.definition",
852
+ "option": "neutral-brand",
853
+ "why": "One product, one brand ramp on cool neutrals.",
854
+ "because": [
855
+ "business.q2"
856
+ ]
857
+ },
858
+ {
859
+ "question": "color.values",
860
+ "option": "muted",
861
+ "why": "Muted color keeps attention on the data.",
862
+ "because": [
863
+ "brand.q2"
864
+ ]
865
+ },
866
+ {
867
+ "question": "color.lands",
868
+ "option": "status",
869
+ "why": "Color earns its place by marking late and failed records.",
870
+ "because": [
871
+ "outcomes.q2"
872
+ ]
873
+ },
874
+ {
875
+ "question": "spacing.roles",
876
+ "option": "gap-inset-row",
877
+ "why": "Row height is a decision of its own in a table product.",
878
+ "because": [
879
+ "content.q1"
880
+ ]
881
+ },
882
+ {
883
+ "question": "spacing.count",
884
+ "option": "two",
885
+ "why": "A second, denser size serves tables and toolbars.",
886
+ "because": [
887
+ "tasks.q1"
888
+ ]
889
+ },
890
+ {
891
+ "question": "spacing.definition",
892
+ "option": "fine",
893
+ "why": "A fine base unit gives the small steps dense screens need.",
894
+ "because": [
895
+ "content.q2"
896
+ ]
897
+ },
898
+ {
899
+ "question": "spacing.values",
900
+ "option": "compact",
901
+ "why": "Compact spacing shows more records.",
902
+ "because": [
903
+ "content.q2"
904
+ ]
905
+ },
906
+ {
907
+ "question": "spacing.lands",
908
+ "option": "rows-cells",
909
+ "why": "Space is spent inside rows and cells.",
910
+ "because": [
911
+ "tasks.q1"
912
+ ]
913
+ },
914
+ {
915
+ "question": "shape.roles",
916
+ "option": "control-badge-container",
917
+ "why": "Badges sit in columns and need their own corner.",
918
+ "because": [
919
+ "tasks.q1"
920
+ ]
921
+ },
922
+ {
923
+ "question": "shape.count",
924
+ "option": "three",
925
+ "why": "Control, badge and container corners differ.",
926
+ "because": [
927
+ "shape.roles"
928
+ ]
929
+ },
930
+ {
931
+ "question": "shape.definition",
932
+ "option": "fixed",
933
+ "why": "One brand, one fixed set of corners.",
934
+ "because": [
935
+ "business.q2"
936
+ ]
937
+ },
938
+ {
939
+ "question": "shape.values",
940
+ "option": "slightly-rounded",
941
+ "why": "Small corners keep dense rows straight.",
942
+ "because": [
943
+ "brand.q1"
944
+ ]
945
+ },
946
+ {
947
+ "question": "shape.lands",
948
+ "option": "controls",
949
+ "why": "Corners show most on controls in dense rows.",
950
+ "because": [
951
+ "content.q2"
952
+ ]
953
+ },
954
+ {
955
+ "question": "elevation.roles",
956
+ "option": "floating-only",
957
+ "why": "Only menus and dialogs float; cards use lines.",
958
+ "because": [
959
+ "elevation.definition"
960
+ ]
961
+ },
962
+ {
963
+ "question": "elevation.count",
964
+ "option": "one",
965
+ "why": "One shadow for everything that floats.",
966
+ "because": [
967
+ "elevation.roles"
968
+ ]
969
+ },
970
+ {
971
+ "question": "elevation.definition",
972
+ "option": "lines",
973
+ "why": "Thin lines guide the eye along rows.",
974
+ "because": [
975
+ "human.q1"
976
+ ]
977
+ },
978
+ {
979
+ "question": "elevation.values",
980
+ "option": "subtle",
981
+ "why": "Subtle shadows keep the grid crisp.",
982
+ "because": [
983
+ "brand.q1"
984
+ ]
985
+ },
986
+ {
987
+ "question": "elevation.lands",
988
+ "option": "menus-dialogs",
989
+ "why": "Menus and dialogs are the only layers.",
990
+ "because": [
991
+ "elevation.roles"
992
+ ]
993
+ },
994
+ {
995
+ "question": "motion.roles",
996
+ "option": "feedback",
997
+ "why": "Motion confirms an action; nothing else moves.",
998
+ "because": [
999
+ "human.q1"
1000
+ ]
1001
+ },
1002
+ {
1003
+ "question": "motion.count",
1004
+ "option": "one",
1005
+ "why": "One speed is enough for feedback.",
1006
+ "because": [
1007
+ "motion.roles"
1008
+ ]
1009
+ },
1010
+ {
1011
+ "question": "motion.definition",
1012
+ "option": "standard",
1013
+ "why": "A standard ease-out never draws attention.",
1014
+ "because": [
1015
+ "brand.q1"
1016
+ ]
1017
+ },
1018
+ {
1019
+ "question": "motion.values",
1020
+ "option": "fast",
1021
+ "why": "Fast feedback keeps up with experts.",
1022
+ "because": [
1023
+ "outcomes.q1"
1024
+ ]
1025
+ },
1026
+ {
1027
+ "question": "motion.lands",
1028
+ "option": "state-only",
1029
+ "why": "Only state changes move.",
1030
+ "because": [
1031
+ "motion.roles"
1032
+ ]
1033
+ },
1034
+ {
1035
+ "question": "iconography.roles",
1036
+ "option": "actions-status",
1037
+ "why": "Icons mark row actions and status.",
1038
+ "because": [
1039
+ "tasks.q2"
1040
+ ]
1041
+ },
1042
+ {
1043
+ "question": "iconography.count",
1044
+ "option": "one",
1045
+ "why": "One size, matched to the small text.",
1046
+ "because": [
1047
+ "typography.values"
1048
+ ]
1049
+ },
1050
+ {
1051
+ "question": "iconography.definition",
1052
+ "option": "outline",
1053
+ "why": "Outline icons stay light next to dense text.",
1054
+ "because": [
1055
+ "content.q2"
1056
+ ]
1057
+ },
1058
+ {
1059
+ "question": "iconography.values",
1060
+ "option": "match-text",
1061
+ "why": "Icons match the label so they do not outweigh it.",
1062
+ "because": [
1063
+ "content.q2"
1064
+ ]
1065
+ },
1066
+ {
1067
+ "question": "iconography.lands",
1068
+ "option": "toolbars-rows",
1069
+ "why": "Icons work hardest in toolbars and row actions.",
1070
+ "because": [
1071
+ "tasks.q2"
1072
+ ]
1073
+ },
1074
+ {
1075
+ "question": "theming.roles",
1076
+ "option": "mode",
1077
+ "why": "One brand, so only the mode changes.",
1078
+ "because": [
1079
+ "business.q2"
1080
+ ]
1081
+ },
1082
+ {
1083
+ "question": "theming.count",
1084
+ "option": "two",
1085
+ "why": "Light and dark.",
1086
+ "because": [
1087
+ "theming.values"
1088
+ ]
1089
+ },
1090
+ {
1091
+ "question": "theming.definition",
1092
+ "option": "single",
1093
+ "why": "One product, one brand.",
1094
+ "because": [
1095
+ "business.q2"
1096
+ ]
1097
+ },
1098
+ {
1099
+ "question": "theming.values",
1100
+ "option": "light-dark",
1101
+ "why": "Light first, always; dark ships as standard for night shifts.",
1102
+ "because": [
1103
+ "scenarios.q2"
1104
+ ]
1105
+ },
1106
+ {
1107
+ "question": "theming.lands",
1108
+ "option": "colors",
1109
+ "why": "A mode switch changes colors only, so layout never moves.",
1110
+ "because": [
1111
+ "human.q1"
1112
+ ]
1113
+ },
1114
+ {
1115
+ "question": "accessibility.roles",
1116
+ "option": "hover-focus-disabled",
1117
+ "why": "Pressed reuses hover; experts do not need more.",
1118
+ "because": [
1119
+ "people.q1"
1120
+ ]
1121
+ },
1122
+ {
1123
+ "question": "accessibility.count",
1124
+ "option": "color-icon-word",
1125
+ "why": "Many statuses share one table; color alone is not enough.",
1126
+ "because": [
1127
+ "people.q2",
1128
+ "content.q1"
1129
+ ]
1130
+ },
1131
+ {
1132
+ "question": "accessibility.definition",
1133
+ "option": "aa",
1134
+ "why": "AA contrast for every text.",
1135
+ "because": [
1136
+ "people.q2"
1137
+ ]
1138
+ },
1139
+ {
1140
+ "question": "accessibility.values",
1141
+ "option": "pointer",
1142
+ "why": "Mouse and keyboard; compact targets are enough.",
1143
+ "because": [
1144
+ "scenarios.q1"
1145
+ ]
1146
+ },
1147
+ {
1148
+ "question": "accessibility.lands",
1149
+ "option": "dense-tables",
1150
+ "why": "Small text and thin lines in tables need the most care.",
1151
+ "because": [
1152
+ "content.q2"
1153
+ ]
1154
+ },
1155
+ {
1156
+ "question": "naming.roles",
1157
+ "option": "tokens-keys",
1158
+ "why": "Components get their own keys.",
1159
+ "because": [
1160
+ "team.q2"
1161
+ ]
1162
+ },
1163
+ {
1164
+ "question": "naming.count",
1165
+ "option": "three",
1166
+ "why": "Primitives, semantics and component keys.",
1167
+ "because": [
1168
+ "team.q2"
1169
+ ]
1170
+ },
1171
+ {
1172
+ "question": "naming.definition",
1173
+ "option": "by-role",
1174
+ "why": "Role names survive a redesign.",
1175
+ "because": [
1176
+ "team.q1"
1177
+ ]
1178
+ },
1179
+ {
1180
+ "question": "naming.values",
1181
+ "option": "kebab-paths",
1182
+ "why": "Lowercase paths read the same in CSS, JSON and Figma.",
1183
+ "because": [
1184
+ "team.q1"
1185
+ ]
1186
+ },
1187
+ {
1188
+ "question": "naming.lands",
1189
+ "option": "keys",
1190
+ "why": "A component API keeps changes local.",
1191
+ "because": [
1192
+ "team.q2"
1193
+ ]
1194
+ },
1195
+ {
1196
+ "question": "voice.roles",
1197
+ "option": "ui",
1198
+ "why": "Labels and messages are all the copy an operations tool needs.",
1199
+ "because": [
1200
+ "business.q1"
1201
+ ]
1202
+ },
1203
+ {
1204
+ "question": "voice.count",
1205
+ "option": "one",
1206
+ "why": "One flat tone everywhere; experts want no surprises.",
1207
+ "because": [
1208
+ "people.q1"
1209
+ ]
1210
+ },
1211
+ {
1212
+ "question": "voice.definition",
1213
+ "option": "word-list",
1214
+ "why": "A word list keeps labels identical across screens.",
1215
+ "because": [
1216
+ "team.q1",
1217
+ "tasks.q2"
1218
+ ]
1219
+ },
1220
+ {
1221
+ "question": "voice.values",
1222
+ "option": "terse",
1223
+ "why": "Experts want short labels and short messages.",
1224
+ "because": [
1225
+ "people.q1",
1226
+ "brand.q1"
1227
+ ]
1228
+ },
1229
+ {
1230
+ "question": "voice.lands",
1231
+ "option": "errors-empty",
1232
+ "why": "Errors and empty tables are where words decide the next action.",
1233
+ "because": [
1234
+ "outcomes.q2"
1235
+ ]
1236
+ },
1237
+ {
1238
+ "question": "components.roles",
1239
+ "option": "core-data",
1240
+ "why": "Records need tables, filters and fast ways to move between them.",
1241
+ "because": [
1242
+ "content.q1",
1243
+ "tasks.q1"
1244
+ ]
1245
+ },
1246
+ {
1247
+ "question": "components.count",
1248
+ "option": "some",
1249
+ "why": "A full operations tool with the parts its next screens will need, still few enough for a small team to keep right.",
1250
+ "because": [
1251
+ "content.q2",
1252
+ "team.q1"
1253
+ ]
1254
+ },
1255
+ {
1256
+ "question": "components.definition",
1257
+ "option": "scenario",
1258
+ "why": "A component joins only when a daily task needs it.",
1259
+ "because": [
1260
+ "scenarios.q1",
1261
+ "tasks.q2"
1262
+ ]
1263
+ },
1264
+ {
1265
+ "question": "components.values",
1266
+ "option": "few",
1267
+ "why": "Repeated screens stay identical when a component changes only with its meaning.",
1268
+ "because": [
1269
+ "brand.q2",
1270
+ "tasks.q2"
1271
+ ]
1272
+ },
1273
+ {
1274
+ "question": "components.lands",
1275
+ "option": "tables-forms",
1276
+ "why": "Most work happens in tables and the forms that edit them.",
1277
+ "because": [
1278
+ "content.q1",
1279
+ "tasks.q1"
1280
+ ]
1281
+ }
1282
+ ],
1283
+ "usage": [
1284
+ {
1285
+ "situation": "page-title",
1286
+ "use": "type.title",
1287
+ "not": "type.display",
1288
+ "why": "Titles stay small so the table starts higher on the screen.",
1289
+ "because": [
1290
+ "content.q2"
1291
+ ]
1292
+ },
1293
+ {
1294
+ "situation": "number-in-table",
1295
+ "use": "type.data",
1296
+ "not": "type.body",
1297
+ "why": "Mono digits line up in columns, so values compare at a glance.",
1298
+ "because": [
1299
+ "typography.roles",
1300
+ "tasks.q1"
1301
+ ]
1302
+ },
1303
+ {
1304
+ "situation": "paragraph",
1305
+ "use": "type.body",
1306
+ "not": "type.label",
1307
+ "why": "Help text is read in passing; body size keeps it quick.",
1308
+ "because": [
1309
+ "outcomes.q1"
1310
+ ]
1311
+ },
1312
+ {
1313
+ "situation": "field-label",
1314
+ "use": "type.label",
1315
+ "not": "type.heading",
1316
+ "why": "Headers repeat on every column; a heavy style would compete with the data.",
1317
+ "because": [
1318
+ "tasks.q1"
1319
+ ]
1320
+ },
1321
+ {
1322
+ "situation": "selected-row",
1323
+ "use": "color.surface.selected",
1324
+ "not": "color.action.primary as a fill",
1325
+ "why": "A light tint shows selection without hiding the data.",
1326
+ "because": [
1327
+ "tasks.q1"
1328
+ ]
1329
+ },
1330
+ {
1331
+ "situation": "error-message",
1332
+ "use": "color.status.danger with an icon",
1333
+ "not": "color.status.warning",
1334
+ "why": "Red always means fix this, and the icon says it without color.",
1335
+ "because": [
1336
+ "accessibility.count",
1337
+ "outcomes.q2"
1338
+ ]
1339
+ },
1340
+ {
1341
+ "situation": "link",
1342
+ "use": "color.text.link",
1343
+ "not": "color.action.primary",
1344
+ "why": "Links and buttons look different, so people know which one navigates.",
1345
+ "because": [
1346
+ "human.q2"
1347
+ ]
1348
+ },
1349
+ {
1350
+ "situation": "status-label",
1351
+ "use": "Badge with a subtle fill, an icon and a word",
1352
+ "not": "A full-strength fill",
1353
+ "why": "Subtle fills let many statuses share one table.",
1354
+ "because": [
1355
+ "accessibility.count",
1356
+ "content.q1"
1357
+ ]
1358
+ },
1359
+ {
1360
+ "situation": "related-items",
1361
+ "use": "space.gap.tight",
1362
+ "not": "space.gap.group",
1363
+ "why": "Things that belong together sit close.",
1364
+ "because": [
1365
+ "human.q2"
1366
+ ]
1367
+ },
1368
+ {
1369
+ "situation": "between-sections",
1370
+ "use": "space.gap.section and a hairline",
1371
+ "not": "A card around every section",
1372
+ "why": "Lines separate without taking room from the data.",
1373
+ "because": [
1374
+ "elevation.definition",
1375
+ "content.q2"
1376
+ ]
1377
+ },
1378
+ {
1379
+ "situation": "table-row",
1380
+ "use": "size.row (compact)",
1381
+ "not": "The comfortable row",
1382
+ "why": "Compact rows show more records without scrolling.",
1383
+ "because": [
1384
+ "content.q2",
1385
+ "spacing.count"
1386
+ ]
1387
+ },
1388
+ {
1389
+ "situation": "control-corner",
1390
+ "use": "radius.control",
1391
+ "not": "radius.round",
1392
+ "why": "Small corners keep dense rows straight.",
1393
+ "because": [
1394
+ "shape.values"
1395
+ ]
1396
+ },
1397
+ {
1398
+ "situation": "status-shape",
1399
+ "use": "radius.badge (rectangle)",
1400
+ "not": "A pill",
1401
+ "why": "Rectangles line up in a column.",
1402
+ "because": [
1403
+ "shape.roles"
1404
+ ]
1405
+ },
1406
+ {
1407
+ "situation": "card",
1408
+ "use": "A hairline border, no shadow",
1409
+ "not": "A shadow",
1410
+ "why": "On a busy grid, lines separate. Shadows blur the edges.",
1411
+ "because": [
1412
+ "elevation.roles"
1413
+ ]
1414
+ },
1415
+ {
1416
+ "situation": "menu-or-dialog",
1417
+ "use": "elevation.overlay and a dimmed page for dialogs",
1418
+ "not": "A border only",
1419
+ "why": "Floating things need a shadow so they read as on top.",
1420
+ "because": [
1421
+ "elevation.lands"
1422
+ ]
1423
+ },
1424
+ {
1425
+ "situation": "hover-feedback",
1426
+ "use": "motion.duration.feedback (fast)",
1427
+ "not": "No transition",
1428
+ "why": "Fast feedback confirms the pointer without slowing experts.",
1429
+ "because": [
1430
+ "motion.values"
1431
+ ]
1432
+ },
1433
+ {
1434
+ "situation": "reduced-motion",
1435
+ "use": "No motion",
1436
+ "not": "A shorter version of the motion",
1437
+ "why": "When people ask for less motion, nothing moves.",
1438
+ "because": [
1439
+ "motion.roles"
1440
+ ]
1441
+ },
1442
+ {
1443
+ "situation": "icon-alone",
1444
+ "use": "Icon button with a tooltip",
1445
+ "not": "A bare icon",
1446
+ "why": "Experts learn icons; the tooltip covers the first uses.",
1447
+ "because": [
1448
+ "iconography.roles"
1449
+ ]
1450
+ },
1451
+ {
1452
+ "situation": "dark-mode",
1453
+ "use": "The dark semantic mode",
1454
+ "not": "A second palette in components",
1455
+ "why": "Only semantic colors change, so layout never moves.",
1456
+ "because": [
1457
+ "theming.values"
1458
+ ]
1459
+ },
1460
+ {
1461
+ "situation": "keyboard-focus",
1462
+ "use": "button/focus-ring at border-width.focus",
1463
+ "not": "Removing the outline",
1464
+ "why": "Keyboard users must always see where they are.",
1465
+ "because": [
1466
+ "people.q2"
1467
+ ]
1468
+ },
1469
+ {
1470
+ "situation": "smallest-target",
1471
+ "use": "size.control.compact",
1472
+ "not": "Anything smaller",
1473
+ "why": "Compact still fits a mouse. Touch is not this product's input.",
1474
+ "because": [
1475
+ "accessibility.values"
1476
+ ]
1477
+ },
1478
+ {
1479
+ "situation": "commit-action",
1480
+ "use": "Button primary, one per view",
1481
+ "not": "Two primaries side by side",
1482
+ "why": "One primary makes the committing action obvious.",
1483
+ "because": [
1484
+ "color.count",
1485
+ "outcomes.q2"
1486
+ ]
1487
+ },
1488
+ {
1489
+ "situation": "alternative-action",
1490
+ "use": "Button secondary",
1491
+ "not": "Button ghost",
1492
+ "why": "Cancel must be easy to find next to the primary.",
1493
+ "because": [
1494
+ "human.q2"
1495
+ ]
1496
+ },
1497
+ {
1498
+ "situation": "destructive-action",
1499
+ "use": "Button secondary, then confirm in a dialog",
1500
+ "not": "Button primary as the first step",
1501
+ "why": "Deleting is rare and costly; a confirm step catches mistakes.",
1502
+ "because": [
1503
+ "outcomes.q2"
1504
+ ]
1505
+ },
1506
+ {
1507
+ "situation": "row-action",
1508
+ "use": "Icon button, ghost, compact",
1509
+ "not": "Button secondary in every row",
1510
+ "why": "Rows repeat dozens of times; a quiet icon keeps the table readable.",
1511
+ "because": [
1512
+ "tasks.q2"
1513
+ ]
1514
+ },
1515
+ {
1516
+ "situation": "missing-token",
1517
+ "use": "The closest semantic token, then ask for a new one",
1518
+ "not": "A raw value in the component",
1519
+ "why": "Raw values break dark mode and the next redesign.",
1520
+ "because": [
1521
+ "naming.lands"
1522
+ ]
1523
+ },
1524
+ {
1525
+ "situation": "button-label",
1526
+ "use": "One verb from the word list",
1527
+ "not": "A sentence or \"Please\"",
1528
+ "why": "Labels repeat on every screen; one verb reads fastest.",
1529
+ "because": [
1530
+ "voice.values",
1531
+ "voice.definition"
1532
+ ],
1533
+ "example": "Export"
1534
+ },
1535
+ {
1536
+ "situation": "error-words",
1537
+ "use": "Name the record, then the fix. Flat and specific.",
1538
+ "not": "\"Oops\" or a vague apology",
1539
+ "why": "Experts act on the message; the record and the fix are all they need.",
1540
+ "because": [
1541
+ "voice.values",
1542
+ "voice.lands"
1543
+ ],
1544
+ "example": "Alert ALR-2042 not saved. Threshold must be between 0 and 100."
1545
+ },
1546
+ {
1547
+ "situation": "success-words",
1548
+ "use": "A short confirmation with the count",
1549
+ "not": "Celebration",
1550
+ "why": "Confirm and get out of the way; the next task is waiting.",
1551
+ "because": [
1552
+ "voice.values",
1553
+ "tasks.q2"
1554
+ ],
1555
+ "example": "12 alerts exported."
1556
+ },
1557
+ {
1558
+ "situation": "empty-words",
1559
+ "use": "Why it is empty and the one action that fills it",
1560
+ "not": "A blank table",
1561
+ "why": "An empty table with no words looks like an error.",
1562
+ "because": [
1563
+ "voice.lands"
1564
+ ],
1565
+ "example": "No escalated alerts. Change the date range to see older ones."
1566
+ },
1567
+ {
1568
+ "situation": "confirm-words",
1569
+ "use": "Name the exact object and the consequence",
1570
+ "not": "\"Are you sure?\"",
1571
+ "why": "Acting on the wrong record is the costly mistake.",
1572
+ "because": [
1573
+ "outcomes.q2"
1574
+ ],
1575
+ "example": "Dismiss 3 alerts? This cannot be undone."
1576
+ },
1577
+ {
1578
+ "situation": "first-visit",
1579
+ "use": "No tour. Show the data, with a tooltip where needed.",
1580
+ "not": "A welcome tour",
1581
+ "why": "Daily experts skip tours; tooltips cover the first uses.",
1582
+ "because": [
1583
+ "people.q1",
1584
+ "voice.count"
1585
+ ],
1586
+ "example": "Hover any column header to see what it counts."
1587
+ },
1588
+ {
1589
+ "situation": "missing-component",
1590
+ "use": "a component from the inventory, composed (for example a popover with a command list)",
1591
+ "not": "a one-off component built for one screen",
1592
+ "why": "A small team keeps fewer parts right, and experts expect the same parts everywhere.",
1593
+ "because": [
1594
+ "team.q1",
1595
+ "components.definition"
1596
+ ]
1597
+ }
1598
+ ],
1599
+ "tokens": {
1600
+ "primitive": {
1601
+ "color": {
1602
+ "$description": "Colour options: raw hue ramps. Each hue has a light ramp and a dark ramp (the same steps tuned for dark backgrounds). Steps only: each theme decides its own base (@). Themes pick from these; components never read them.",
1603
+ "slate": {
1604
+ "$type": "color",
1605
+ "$description": "The slate hue: a light ramp, a dark ramp and its base value.",
1606
+ "light": {
1607
+ "0": {
1608
+ "$value": "#FFFFFF"
1609
+ },
1610
+ "50": {
1611
+ "$value": "#F7F8FA"
1612
+ },
1613
+ "100": {
1614
+ "$value": "#EEF1F5"
1615
+ },
1616
+ "200": {
1617
+ "$value": "#DDE2EA"
1618
+ },
1619
+ "300": {
1620
+ "$value": "#C4CBD6"
1621
+ },
1622
+ "400": {
1623
+ "$value": "#969FAD",
1624
+ "$description": "Derived: the OKLab midpoint of 300 and 500. Added so muted text can pass 4.5:1 and stay quieter than secondary."
1625
+ },
1626
+ "500": {
1627
+ "$value": "#6B7585"
1628
+ },
1629
+ "600": {
1630
+ "$value": "#535D6D",
1631
+ "$description": "Derived: the OKLab midpoint of 500 and 700. Added so muted text can pass 4.5:1 and stay quieter than secondary."
1632
+ },
1633
+ "700": {
1634
+ "$value": "#3D4655"
1635
+ },
1636
+ "800": {
1637
+ "$value": "#262D38"
1638
+ },
1639
+ "900": {
1640
+ "$value": "#161B23"
1641
+ },
1642
+ "950": {
1643
+ "$value": "#0D1117"
1644
+ }
1645
+ },
1646
+ "dark": {
1647
+ "0": {
1648
+ "$value": "#0D1117"
1649
+ },
1650
+ "50": {
1651
+ "$value": "#161B23"
1652
+ },
1653
+ "100": {
1654
+ "$value": "#262D38"
1655
+ },
1656
+ "200": {
1657
+ "$value": "#3D4655"
1658
+ },
1659
+ "300": {
1660
+ "$value": "#6B7585"
1661
+ },
1662
+ "400": {
1663
+ "$value": "#969FAD",
1664
+ "$description": "Derived: the OKLab midpoint of 300 and 500. Added so muted text can pass 4.5:1 and stay quieter than secondary."
1665
+ },
1666
+ "500": {
1667
+ "$value": "#C4CBD6"
1668
+ },
1669
+ "600": {
1670
+ "$value": "#D0D6E0",
1671
+ "$description": "Derived: the OKLab midpoint of 500 and 700. Added so muted text can pass 4.5:1 and stay quieter than secondary."
1672
+ },
1673
+ "700": {
1674
+ "$value": "#DDE2EA"
1675
+ },
1676
+ "800": {
1677
+ "$value": "#EEF1F5"
1678
+ },
1679
+ "900": {
1680
+ "$value": "#F7F8FA"
1681
+ },
1682
+ "950": {
1683
+ "$value": "#FFFFFF"
1684
+ }
1685
+ }
1686
+ },
1687
+ "violet": {
1688
+ "$type": "color",
1689
+ "$description": "The violet hue: a light ramp, a dark ramp and its base value.",
1690
+ "light": {
1691
+ "100": {
1692
+ "$value": "#EEEDFE"
1693
+ },
1694
+ "300": {
1695
+ "$value": "#A9A3F6"
1696
+ },
1697
+ "500": {
1698
+ "$value": "#5B4FE8"
1699
+ },
1700
+ "600": {
1701
+ "$value": "#4B3FD9"
1702
+ },
1703
+ "700": {
1704
+ "$value": "#3B31B0"
1705
+ },
1706
+ "800": {
1707
+ "$value": "#2C2588"
1708
+ }
1709
+ },
1710
+ "dark": {
1711
+ "100": {
1712
+ "$value": "#2C2588"
1713
+ },
1714
+ "300": {
1715
+ "$value": "#3B31B0"
1716
+ },
1717
+ "500": {
1718
+ "$value": "#4B3FD9"
1719
+ },
1720
+ "600": {
1721
+ "$value": "#5B4FE8"
1722
+ },
1723
+ "700": {
1724
+ "$value": "#A9A3F6"
1725
+ },
1726
+ "800": {
1727
+ "$value": "#EEEDFE"
1728
+ }
1729
+ }
1730
+ },
1731
+ "green": {
1732
+ "$type": "color",
1733
+ "$description": "The green hue: a light ramp, a dark ramp and its base value.",
1734
+ "light": {
1735
+ "100": {
1736
+ "$value": "#E3F4EA"
1737
+ },
1738
+ "300": {
1739
+ "$value": "#5CC283"
1740
+ },
1741
+ "700": {
1742
+ "$value": "#1F7A3A"
1743
+ },
1744
+ "900": {
1745
+ "$value": "#123322"
1746
+ }
1747
+ },
1748
+ "dark": {
1749
+ "100": {
1750
+ "$value": "#123322"
1751
+ },
1752
+ "300": {
1753
+ "$value": "#1F7A3A"
1754
+ },
1755
+ "700": {
1756
+ "$value": "#5CC283"
1757
+ },
1758
+ "900": {
1759
+ "$value": "#E3F4EA"
1760
+ }
1761
+ }
1762
+ },
1763
+ "amber": {
1764
+ "$type": "color",
1765
+ "$description": "The amber hue: a light ramp, a dark ramp and its base value.",
1766
+ "light": {
1767
+ "100": {
1768
+ "$value": "#FFF3D6"
1769
+ },
1770
+ "300": {
1771
+ "$value": "#F2B84B"
1772
+ },
1773
+ "700": {
1774
+ "$value": "#8A5600"
1775
+ },
1776
+ "900": {
1777
+ "$value": "#3A2A05"
1778
+ }
1779
+ },
1780
+ "dark": {
1781
+ "100": {
1782
+ "$value": "#3A2A05"
1783
+ },
1784
+ "300": {
1785
+ "$value": "#8A5600"
1786
+ },
1787
+ "700": {
1788
+ "$value": "#F2B84B"
1789
+ },
1790
+ "900": {
1791
+ "$value": "#FFF3D6"
1792
+ }
1793
+ }
1794
+ },
1795
+ "red": {
1796
+ "$type": "color",
1797
+ "$description": "The red hue: a light ramp, a dark ramp and its base value.",
1798
+ "light": {
1799
+ "100": {
1800
+ "$value": "#FDE7E7"
1801
+ },
1802
+ "300": {
1803
+ "$value": "#F28B8B"
1804
+ },
1805
+ "700": {
1806
+ "$value": "#C42B2B"
1807
+ },
1808
+ "900": {
1809
+ "$value": "#3D1414"
1810
+ }
1811
+ },
1812
+ "dark": {
1813
+ "100": {
1814
+ "$value": "#3D1414"
1815
+ },
1816
+ "300": {
1817
+ "$value": "#C42B2B"
1818
+ },
1819
+ "700": {
1820
+ "$value": "#F28B8B"
1821
+ },
1822
+ "900": {
1823
+ "$value": "#FDE7E7"
1824
+ }
1825
+ }
1826
+ },
1827
+ "black": {
1828
+ "$type": "color",
1829
+ "$description": "See-through black for scrims behind dialogs, light and dark.",
1830
+ "light": {
1831
+ "scrim": {
1832
+ "$value": "#0000008C"
1833
+ }
1834
+ },
1835
+ "dark": {
1836
+ "scrim": {
1837
+ "$value": "#000000B3"
1838
+ }
1839
+ }
1840
+ },
1841
+ "blue": {
1842
+ "$type": "color",
1843
+ "$description": "Blue ramp for the info status and categories. Same values as the accessible-first blue ramp: borrowed, not invented.",
1844
+ "light": {
1845
+ "100": {
1846
+ "$value": "#E1ECFF"
1847
+ },
1848
+ "300": {
1849
+ "$value": "#8AB4F8"
1850
+ },
1851
+ "500": {
1852
+ "$value": "#1A5DD0"
1853
+ },
1854
+ "600": {
1855
+ "$value": "#0B4FC0"
1856
+ },
1857
+ "700": {
1858
+ "$value": "#083C93"
1859
+ },
1860
+ "800": {
1861
+ "$value": "#062C6E"
1862
+ }
1863
+ },
1864
+ "dark": {
1865
+ "100": {
1866
+ "$value": "#062C6E"
1867
+ },
1868
+ "300": {
1869
+ "$value": "#083C93"
1870
+ },
1871
+ "500": {
1872
+ "$value": "#0B4FC0"
1873
+ },
1874
+ "600": {
1875
+ "$value": "#1A5DD0"
1876
+ },
1877
+ "700": {
1878
+ "$value": "#8AB4F8"
1879
+ },
1880
+ "800": {
1881
+ "$value": "#E1ECFF"
1882
+ }
1883
+ }
1884
+ }
1885
+ },
1886
+ "space": {
1887
+ "4": {
1888
+ "$type": "dimension",
1889
+ "$value": "0.25rem"
1890
+ },
1891
+ "8": {
1892
+ "$type": "dimension",
1893
+ "$value": "0.5rem"
1894
+ },
1895
+ "12": {
1896
+ "$type": "dimension",
1897
+ "$value": "0.75rem"
1898
+ },
1899
+ "16": {
1900
+ "$type": "dimension",
1901
+ "$value": "1rem"
1902
+ },
1903
+ "24": {
1904
+ "$type": "dimension",
1905
+ "$value": "1.5rem"
1906
+ },
1907
+ "$description": "Space options. Names give the size in pixels at the default text size; values are rem."
1908
+ },
1909
+ "size": {
1910
+ "16": {
1911
+ "$type": "dimension",
1912
+ "$value": "1rem"
1913
+ },
1914
+ "20": {
1915
+ "$type": "dimension",
1916
+ "$value": "1.25rem"
1917
+ },
1918
+ "24": {
1919
+ "$type": "dimension",
1920
+ "$value": "1.5rem"
1921
+ },
1922
+ "32": {
1923
+ "$type": "dimension",
1924
+ "$value": "2rem"
1925
+ },
1926
+ "$description": "Size options for controls, rows and icons."
1927
+ },
1928
+ "radius": {
1929
+ "0": {
1930
+ "$type": "dimension",
1931
+ "$value": "0rem"
1932
+ },
1933
+ "2": {
1934
+ "$type": "dimension",
1935
+ "$value": "0.125rem"
1936
+ },
1937
+ "4": {
1938
+ "$type": "dimension",
1939
+ "$value": "0.25rem"
1940
+ },
1941
+ "6": {
1942
+ "$type": "dimension",
1943
+ "$value": "0.375rem"
1944
+ },
1945
+ "$description": "Corner options.",
1946
+ "full": {
1947
+ "$type": "dimension",
1948
+ "$value": "9999px",
1949
+ "$description": "Fully round."
1950
+ }
1951
+ },
1952
+ "border-width": {
1953
+ "1": {
1954
+ "$type": "dimension",
1955
+ "$value": "1px"
1956
+ },
1957
+ "2": {
1958
+ "$type": "dimension",
1959
+ "$value": "2px"
1960
+ },
1961
+ "$description": "Border width options."
1962
+ },
1963
+ "font": {
1964
+ "size": {
1965
+ "12": {
1966
+ "$type": "dimension",
1967
+ "$value": "0.75rem"
1968
+ },
1969
+ "13": {
1970
+ "$type": "dimension",
1971
+ "$value": "0.8125rem"
1972
+ },
1973
+ "14": {
1974
+ "$type": "dimension",
1975
+ "$value": "0.875rem"
1976
+ },
1977
+ "16": {
1978
+ "$type": "dimension",
1979
+ "$value": "1rem"
1980
+ },
1981
+ "20": {
1982
+ "$type": "dimension",
1983
+ "$value": "1.25rem"
1984
+ },
1985
+ "24": {
1986
+ "$type": "dimension",
1987
+ "$value": "1.5rem"
1988
+ },
1989
+ "$description": "Type size options. Names are pixels at the default text size; values are rem, so text grows with the user's setting."
1990
+ },
1991
+ "weight": {
1992
+ "400": {
1993
+ "$type": "fontWeight",
1994
+ "$value": 400
1995
+ },
1996
+ "500": {
1997
+ "$type": "fontWeight",
1998
+ "$value": 500
1999
+ },
2000
+ "600": {
2001
+ "$type": "fontWeight",
2002
+ "$value": 600
2003
+ }
2004
+ },
2005
+ "line-height": {
2006
+ "16": {
2007
+ "$type": "dimension",
2008
+ "$value": "1rem",
2009
+ "$description": "On the 4px grid, in rem so it grows with the user's text size."
2010
+ },
2011
+ "20": {
2012
+ "$type": "dimension",
2013
+ "$value": "1.25rem",
2014
+ "$description": "On the 4px grid, in rem so it grows with the user's text size."
2015
+ },
2016
+ "24": {
2017
+ "$type": "dimension",
2018
+ "$value": "1.5rem",
2019
+ "$description": "On the 4px grid, in rem so it grows with the user's text size."
2020
+ },
2021
+ "28": {
2022
+ "$type": "dimension",
2023
+ "$value": "1.75rem",
2024
+ "$description": "On the 4px grid, in rem so it grows with the user's text size."
2025
+ }
2026
+ },
2027
+ "family": {
2028
+ "$description": "Font family options. Each brand's theme picks its display, body, interface and data fonts from these.",
2029
+ "ibm-plex-sans": {
2030
+ "$type": "fontFamily",
2031
+ "$value": "\"IBM Plex Sans\", system-ui, sans-serif"
2032
+ },
2033
+ "ibm-plex-mono": {
2034
+ "$type": "fontFamily",
2035
+ "$value": "\"IBM Plex Mono\", ui-monospace, monospace"
2036
+ }
2037
+ }
2038
+ },
2039
+ "duration": {
2040
+ "fast": {
2041
+ "$type": "duration",
2042
+ "$value": "120ms",
2043
+ "$description": "Fast: the usual convention for feedback, about 120ms."
2044
+ },
2045
+ "moderate": {
2046
+ "$type": "duration",
2047
+ "$value": "200ms",
2048
+ "$description": "Moderate: a calm, easy-to-follow speed, about 200ms."
2049
+ },
2050
+ "relaxed": {
2051
+ "$type": "duration",
2052
+ "$value": "320ms",
2053
+ "$description": "Relaxed: a slower, springy speed for expressive motion, about 320ms."
2054
+ }
2055
+ },
2056
+ "easing": {
2057
+ "standard": {
2058
+ "$type": "cubicBezier",
2059
+ "$value": [
2060
+ 0.2,
2061
+ 0,
2062
+ 0,
2063
+ 1
2064
+ ],
2065
+ "$description": "The easing for feedback transitions."
2066
+ }
2067
+ },
2068
+ "opacity": {
2069
+ "40": {
2070
+ "$type": "number",
2071
+ "$value": 0.4,
2072
+ "$description": "An opacity option."
2073
+ }
2074
+ },
2075
+ "shadow": {
2076
+ "$description": "Raw shadows. Elevation semantics point at these.",
2077
+ "none": {
2078
+ "$type": "shadow",
2079
+ "$value": {
2080
+ "color": "#00000000",
2081
+ "offsetX": "0px",
2082
+ "offsetY": "0px",
2083
+ "blur": "0px",
2084
+ "spread": "0px"
2085
+ },
2086
+ "$description": "No shadow: flat surfaces."
2087
+ },
2088
+ "overlay": {
2089
+ "$type": "shadow",
2090
+ "$value": {
2091
+ "color": "#0D111729",
2092
+ "offsetX": "0px",
2093
+ "offsetY": "8px",
2094
+ "blur": "24px",
2095
+ "spread": "0px"
2096
+ },
2097
+ "$description": "Raw shadow for overlay in light mode."
2098
+ },
2099
+ "overlay-dark": {
2100
+ "$type": "shadow",
2101
+ "$value": {
2102
+ "color": "#00000080",
2103
+ "offsetX": "0px",
2104
+ "offsetY": "8px",
2105
+ "blur": "24px",
2106
+ "spread": "0px"
2107
+ },
2108
+ "$description": "Raw shadow for overlay in dark mode."
2109
+ }
2110
+ }
2111
+ },
2112
+ "brands": {
2113
+ "default": {
2114
+ "label": "Dense data",
2115
+ "description": "The single brand: precise blue on cool grey.",
2116
+ "theme": {
2117
+ "$description": "The Dense data theme: what each brand-dependent semantic key picks, in light and dark, plus mode-free picks (fonts, corners) in base. Info uses blue, kept apart from the brand colour so it never reads as an action. Categories 1 to 5 are violet, blue, green, amber, slate: distinct hues for tags and chart series, with no meaning. Disabled uses the neutral slate.",
2118
+ "base": {
2119
+ "radius": {
2120
+ "control": {
2121
+ "$type": "dimension",
2122
+ "$value": "{radius.2}"
2123
+ },
2124
+ "badge": {
2125
+ "$type": "dimension",
2126
+ "$value": "{radius.0}"
2127
+ },
2128
+ "container": {
2129
+ "$type": "dimension",
2130
+ "$value": "{radius.4}"
2131
+ }
2132
+ },
2133
+ "type": {
2134
+ "display": {
2135
+ "font-family": {
2136
+ "$type": "fontFamily",
2137
+ "$value": "{font.family.ibm-plex-sans}"
2138
+ }
2139
+ },
2140
+ "title": {
2141
+ "font-family": {
2142
+ "$type": "fontFamily",
2143
+ "$value": "{font.family.ibm-plex-sans}"
2144
+ }
2145
+ },
2146
+ "heading": {
2147
+ "font-family": {
2148
+ "$type": "fontFamily",
2149
+ "$value": "{font.family.ibm-plex-sans}"
2150
+ }
2151
+ },
2152
+ "body": {
2153
+ "font-family": {
2154
+ "$type": "fontFamily",
2155
+ "$value": "{font.family.ibm-plex-sans}"
2156
+ }
2157
+ },
2158
+ "label": {
2159
+ "font-family": {
2160
+ "$type": "fontFamily",
2161
+ "$value": "{font.family.ibm-plex-sans}"
2162
+ }
2163
+ },
2164
+ "caption": {
2165
+ "font-family": {
2166
+ "$type": "fontFamily",
2167
+ "$value": "{font.family.ibm-plex-sans}"
2168
+ }
2169
+ },
2170
+ "data": {
2171
+ "font-family": {
2172
+ "$type": "fontFamily",
2173
+ "$value": "{font.family.ibm-plex-mono}"
2174
+ }
2175
+ }
2176
+ }
2177
+ },
2178
+ "light": {
2179
+ "color": {
2180
+ "surface": {
2181
+ "canvas": {
2182
+ "$type": "color",
2183
+ "$value": "{color.slate.light.50}"
2184
+ },
2185
+ "default": {
2186
+ "$type": "color",
2187
+ "$value": "{color.slate.light.0}"
2188
+ },
2189
+ "raised": {
2190
+ "$type": "color",
2191
+ "$value": "{color.slate.light.0}"
2192
+ },
2193
+ "sunken": {
2194
+ "$type": "color",
2195
+ "$value": "{color.slate.light.100}"
2196
+ },
2197
+ "selected": {
2198
+ "$type": "color",
2199
+ "$value": "{color.violet.light.100}"
2200
+ },
2201
+ "inverse": {
2202
+ "$type": "color",
2203
+ "$value": "{color.slate.light.900}"
2204
+ },
2205
+ "scrim": {
2206
+ "$type": "color",
2207
+ "$value": "{color.black.light.scrim}"
2208
+ }
2209
+ },
2210
+ "text": {
2211
+ "primary": {
2212
+ "$type": "color",
2213
+ "$value": "{color.slate.light.900}"
2214
+ },
2215
+ "secondary": {
2216
+ "$type": "color",
2217
+ "$value": "{color.slate.light.700}"
2218
+ },
2219
+ "muted": {
2220
+ "$type": "color",
2221
+ "$value": "{color.slate.light.600}"
2222
+ },
2223
+ "inverse": {
2224
+ "$type": "color",
2225
+ "$value": "{color.slate.light.0}"
2226
+ },
2227
+ "on-action": {
2228
+ "$type": "color",
2229
+ "$value": "{color.slate.light.0}"
2230
+ },
2231
+ "link": {
2232
+ "$type": "color",
2233
+ "$value": "{color.violet.light.700}"
2234
+ }
2235
+ },
2236
+ "border": {
2237
+ "default": {
2238
+ "$type": "color",
2239
+ "$value": "{color.slate.light.200}"
2240
+ },
2241
+ "strong": {
2242
+ "$type": "color",
2243
+ "$value": "{color.slate.light.500}"
2244
+ },
2245
+ "focus": {
2246
+ "$type": "color",
2247
+ "$value": "{color.violet.light.600}"
2248
+ }
2249
+ },
2250
+ "action": {
2251
+ "primary": {
2252
+ "@": {
2253
+ "$type": "color",
2254
+ "$value": "{color.violet.light.600}"
2255
+ },
2256
+ "hover": {
2257
+ "$type": "color",
2258
+ "$value": "{color.violet.light.700}"
2259
+ }
2260
+ },
2261
+ "secondary": {
2262
+ "@": {
2263
+ "$type": "color",
2264
+ "$value": "{color.slate.light.0}"
2265
+ },
2266
+ "hover": {
2267
+ "$type": "color",
2268
+ "$value": "{color.slate.light.100}"
2269
+ }
2270
+ }
2271
+ },
2272
+ "status": {
2273
+ "info": {
2274
+ "@": {
2275
+ "$type": "color",
2276
+ "$value": "{color.blue.light.700}"
2277
+ },
2278
+ "subtle": {
2279
+ "$type": "color",
2280
+ "$value": "{color.blue.light.100}"
2281
+ }
2282
+ },
2283
+ "success": {
2284
+ "@": {
2285
+ "$type": "color",
2286
+ "$value": "{color.green.light.700}"
2287
+ },
2288
+ "subtle": {
2289
+ "$type": "color",
2290
+ "$value": "{color.green.light.100}"
2291
+ }
2292
+ },
2293
+ "warning": {
2294
+ "@": {
2295
+ "$type": "color",
2296
+ "$value": "{color.amber.light.700}"
2297
+ },
2298
+ "subtle": {
2299
+ "$type": "color",
2300
+ "$value": "{color.amber.light.100}"
2301
+ }
2302
+ },
2303
+ "danger": {
2304
+ "@": {
2305
+ "$type": "color",
2306
+ "$value": "{color.red.light.700}"
2307
+ },
2308
+ "subtle": {
2309
+ "$type": "color",
2310
+ "$value": "{color.red.light.100}"
2311
+ }
2312
+ }
2313
+ },
2314
+ "category": {
2315
+ "1": {
2316
+ "@": {
2317
+ "$type": "color",
2318
+ "$value": "{color.violet.light.600}"
2319
+ },
2320
+ "subtle": {
2321
+ "$type": "color",
2322
+ "$value": "{color.violet.light.100}"
2323
+ }
2324
+ },
2325
+ "2": {
2326
+ "@": {
2327
+ "$type": "color",
2328
+ "$value": "{color.blue.light.600}"
2329
+ },
2330
+ "subtle": {
2331
+ "$type": "color",
2332
+ "$value": "{color.blue.light.100}"
2333
+ }
2334
+ },
2335
+ "3": {
2336
+ "@": {
2337
+ "$type": "color",
2338
+ "$value": "{color.green.light.700}"
2339
+ },
2340
+ "subtle": {
2341
+ "$type": "color",
2342
+ "$value": "{color.green.light.100}"
2343
+ }
2344
+ },
2345
+ "4": {
2346
+ "@": {
2347
+ "$type": "color",
2348
+ "$value": "{color.amber.light.700}"
2349
+ },
2350
+ "subtle": {
2351
+ "$type": "color",
2352
+ "$value": "{color.amber.light.100}"
2353
+ }
2354
+ },
2355
+ "5": {
2356
+ "@": {
2357
+ "$type": "color",
2358
+ "$value": "{color.slate.light.500}"
2359
+ },
2360
+ "subtle": {
2361
+ "$type": "color",
2362
+ "$value": "{color.slate.light.100}"
2363
+ }
2364
+ }
2365
+ },
2366
+ "disabled": {
2367
+ "text": {
2368
+ "$type": "color",
2369
+ "$value": "{color.slate.light.500}"
2370
+ },
2371
+ "surface": {
2372
+ "$type": "color",
2373
+ "$value": "{color.slate.light.100}"
2374
+ },
2375
+ "border": {
2376
+ "$type": "color",
2377
+ "$value": "{color.slate.light.200}"
2378
+ }
2379
+ }
2380
+ },
2381
+ "elevation": {
2382
+ "card": {
2383
+ "$type": "shadow",
2384
+ "$value": "{shadow.none}"
2385
+ },
2386
+ "overlay": {
2387
+ "$type": "shadow",
2388
+ "$value": "{shadow.overlay}"
2389
+ }
2390
+ }
2391
+ },
2392
+ "dark": {
2393
+ "color": {
2394
+ "surface": {
2395
+ "canvas": {
2396
+ "$type": "color",
2397
+ "$value": "{color.slate.dark.0}"
2398
+ },
2399
+ "default": {
2400
+ "$type": "color",
2401
+ "$value": "{color.slate.dark.50}"
2402
+ },
2403
+ "raised": {
2404
+ "$type": "color",
2405
+ "$value": "{color.slate.dark.100}"
2406
+ },
2407
+ "sunken": {
2408
+ "$type": "color",
2409
+ "$value": "{color.slate.dark.100}"
2410
+ },
2411
+ "selected": {
2412
+ "$type": "color",
2413
+ "$value": "{color.violet.dark.100}"
2414
+ },
2415
+ "inverse": {
2416
+ "$type": "color",
2417
+ "$value": "{color.slate.dark.900}"
2418
+ },
2419
+ "scrim": {
2420
+ "$type": "color",
2421
+ "$value": "{color.black.dark.scrim}"
2422
+ }
2423
+ },
2424
+ "text": {
2425
+ "primary": {
2426
+ "$type": "color",
2427
+ "$value": "{color.slate.dark.900}"
2428
+ },
2429
+ "secondary": {
2430
+ "$type": "color",
2431
+ "$value": "{color.slate.dark.500}"
2432
+ },
2433
+ "muted": {
2434
+ "$type": "color",
2435
+ "$value": "{color.slate.dark.400}"
2436
+ },
2437
+ "inverse": {
2438
+ "$type": "color",
2439
+ "$value": "{color.slate.dark.50}"
2440
+ },
2441
+ "on-action": {
2442
+ "$type": "color",
2443
+ "$value": "{color.slate.dark.0}"
2444
+ },
2445
+ "link": {
2446
+ "$type": "color",
2447
+ "$value": "{color.violet.dark.700}"
2448
+ }
2449
+ },
2450
+ "border": {
2451
+ "default": {
2452
+ "$type": "color",
2453
+ "$value": "{color.slate.dark.100}"
2454
+ },
2455
+ "strong": {
2456
+ "$type": "color",
2457
+ "$value": "{color.slate.dark.300}"
2458
+ },
2459
+ "focus": {
2460
+ "$type": "color",
2461
+ "$value": "{color.violet.dark.700}"
2462
+ }
2463
+ },
2464
+ "action": {
2465
+ "primary": {
2466
+ "@": {
2467
+ "$type": "color",
2468
+ "$value": "{color.violet.dark.700}"
2469
+ },
2470
+ "hover": {
2471
+ "$type": "color",
2472
+ "$value": "{color.violet.dark.800}"
2473
+ }
2474
+ },
2475
+ "secondary": {
2476
+ "@": {
2477
+ "$type": "color",
2478
+ "$value": "{color.slate.dark.50}"
2479
+ },
2480
+ "hover": {
2481
+ "$type": "color",
2482
+ "$value": "{color.slate.dark.100}"
2483
+ }
2484
+ }
2485
+ },
2486
+ "status": {
2487
+ "info": {
2488
+ "@": {
2489
+ "$type": "color",
2490
+ "$value": "{color.blue.dark.700}"
2491
+ },
2492
+ "subtle": {
2493
+ "$type": "color",
2494
+ "$value": "{color.blue.dark.100}"
2495
+ }
2496
+ },
2497
+ "success": {
2498
+ "@": {
2499
+ "$type": "color",
2500
+ "$value": "{color.green.dark.700}"
2501
+ },
2502
+ "subtle": {
2503
+ "$type": "color",
2504
+ "$value": "{color.green.dark.100}"
2505
+ }
2506
+ },
2507
+ "warning": {
2508
+ "@": {
2509
+ "$type": "color",
2510
+ "$value": "{color.amber.dark.700}"
2511
+ },
2512
+ "subtle": {
2513
+ "$type": "color",
2514
+ "$value": "{color.amber.dark.100}"
2515
+ }
2516
+ },
2517
+ "danger": {
2518
+ "@": {
2519
+ "$type": "color",
2520
+ "$value": "{color.red.dark.700}"
2521
+ },
2522
+ "subtle": {
2523
+ "$type": "color",
2524
+ "$value": "{color.red.dark.100}"
2525
+ }
2526
+ }
2527
+ },
2528
+ "category": {
2529
+ "1": {
2530
+ "@": {
2531
+ "$type": "color",
2532
+ "$value": "{color.violet.dark.700}"
2533
+ },
2534
+ "subtle": {
2535
+ "$type": "color",
2536
+ "$value": "{color.violet.dark.100}"
2537
+ }
2538
+ },
2539
+ "2": {
2540
+ "@": {
2541
+ "$type": "color",
2542
+ "$value": "{color.blue.dark.700}"
2543
+ },
2544
+ "subtle": {
2545
+ "$type": "color",
2546
+ "$value": "{color.blue.dark.100}"
2547
+ }
2548
+ },
2549
+ "3": {
2550
+ "@": {
2551
+ "$type": "color",
2552
+ "$value": "{color.green.dark.700}"
2553
+ },
2554
+ "subtle": {
2555
+ "$type": "color",
2556
+ "$value": "{color.green.dark.100}"
2557
+ }
2558
+ },
2559
+ "4": {
2560
+ "@": {
2561
+ "$type": "color",
2562
+ "$value": "{color.amber.dark.700}"
2563
+ },
2564
+ "subtle": {
2565
+ "$type": "color",
2566
+ "$value": "{color.amber.dark.100}"
2567
+ }
2568
+ },
2569
+ "5": {
2570
+ "@": {
2571
+ "$type": "color",
2572
+ "$value": "{color.slate.dark.700}"
2573
+ },
2574
+ "subtle": {
2575
+ "$type": "color",
2576
+ "$value": "{color.slate.dark.100}"
2577
+ }
2578
+ }
2579
+ },
2580
+ "disabled": {
2581
+ "text": {
2582
+ "$type": "color",
2583
+ "$value": "{color.slate.dark.500}"
2584
+ },
2585
+ "surface": {
2586
+ "$type": "color",
2587
+ "$value": "{color.slate.dark.100}"
2588
+ },
2589
+ "border": {
2590
+ "$type": "color",
2591
+ "$value": "{color.slate.dark.200}"
2592
+ }
2593
+ }
2594
+ },
2595
+ "elevation": {
2596
+ "card": {
2597
+ "$type": "shadow",
2598
+ "$value": "{shadow.none}"
2599
+ },
2600
+ "overlay": {
2601
+ "$type": "shadow",
2602
+ "$value": "{shadow.overlay-dark}"
2603
+ }
2604
+ }
2605
+ }
2606
+ }
2607
+ }
2608
+ },
2609
+ "semantic": {
2610
+ "space": {
2611
+ "gap": {
2612
+ "tight": {
2613
+ "$type": "dimension",
2614
+ "$value": "{space.4}",
2615
+ "$description": "Between things that belong together."
2616
+ },
2617
+ "default": {
2618
+ "$type": "dimension",
2619
+ "$value": "{space.8}",
2620
+ "$description": "Between items in one group."
2621
+ },
2622
+ "group": {
2623
+ "$type": "dimension",
2624
+ "$value": "{space.16}",
2625
+ "$description": "Between groups."
2626
+ },
2627
+ "section": {
2628
+ "$type": "dimension",
2629
+ "$value": "{space.24}",
2630
+ "$description": "Between page sections."
2631
+ }
2632
+ },
2633
+ "inset": {
2634
+ "control-x": {
2635
+ "$type": "dimension",
2636
+ "$value": "{space.12}",
2637
+ "$description": "Horizontal padding inside controls."
2638
+ },
2639
+ "container": {
2640
+ "$type": "dimension",
2641
+ "$value": "{space.16}",
2642
+ "$description": "Padding inside cards and dialogs."
2643
+ },
2644
+ "cell-x": {
2645
+ "$type": "dimension",
2646
+ "$value": "{space.12}",
2647
+ "$description": "Horizontal padding inside table cells."
2648
+ }
2649
+ }
2650
+ },
2651
+ "size": {
2652
+ "control": {
2653
+ "default": {
2654
+ "$type": "dimension",
2655
+ "$value": "{size.32}",
2656
+ "$description": "Height of buttons and inputs, and the smallest target."
2657
+ },
2658
+ "compact": {
2659
+ "$type": "dimension",
2660
+ "$value": "{size.24}",
2661
+ "$description": "Height of compact controls."
2662
+ }
2663
+ },
2664
+ "row": {
2665
+ "$type": "dimension",
2666
+ "$value": "{size.32}",
2667
+ "$description": "Height of one table row."
2668
+ },
2669
+ "icon": {
2670
+ "$type": "dimension",
2671
+ "$value": "{size.16}",
2672
+ "$description": "Icon size next to text."
2673
+ }
2674
+ },
2675
+ "radius": {
2676
+ "control": {
2677
+ "$type": "dimension",
2678
+ "$value": "{theme.radius.control}",
2679
+ "$description": "Corner of buttons and inputs."
2680
+ },
2681
+ "badge": {
2682
+ "$type": "dimension",
2683
+ "$value": "{theme.radius.badge}",
2684
+ "$description": "Corner of badges and checkboxes."
2685
+ },
2686
+ "container": {
2687
+ "$type": "dimension",
2688
+ "$value": "{theme.radius.container}",
2689
+ "$description": "Corner of cards, menus and dialogs."
2690
+ },
2691
+ "round": {
2692
+ "$type": "dimension",
2693
+ "$value": "{radius.full}",
2694
+ "$description": "Fully round: avatars and dots."
2695
+ }
2696
+ },
2697
+ "border-width": {
2698
+ "default": {
2699
+ "$type": "dimension",
2700
+ "$value": "{border-width.1}",
2701
+ "$description": "Every border."
2702
+ },
2703
+ "focus": {
2704
+ "$type": "dimension",
2705
+ "$value": "{border-width.2}",
2706
+ "$description": "The focus ring."
2707
+ }
2708
+ },
2709
+ "type": {
2710
+ "display": {
2711
+ "font-family": {
2712
+ "$type": "fontFamily",
2713
+ "$value": "{theme.type.display.font-family}"
2714
+ },
2715
+ "font-size": {
2716
+ "$type": "dimension",
2717
+ "$value": "{font.size.24}"
2718
+ },
2719
+ "line-height": {
2720
+ "$type": "dimension",
2721
+ "$value": "{font.line-height.28}"
2722
+ },
2723
+ "font-weight": {
2724
+ "$type": "fontWeight",
2725
+ "$value": "{font.weight.600}"
2726
+ },
2727
+ "$description": "The display text role."
2728
+ },
2729
+ "title": {
2730
+ "font-family": {
2731
+ "$type": "fontFamily",
2732
+ "$value": "{theme.type.title.font-family}"
2733
+ },
2734
+ "font-size": {
2735
+ "$type": "dimension",
2736
+ "$value": "{font.size.20}"
2737
+ },
2738
+ "line-height": {
2739
+ "$type": "dimension",
2740
+ "$value": "{font.line-height.24}"
2741
+ },
2742
+ "font-weight": {
2743
+ "$type": "fontWeight",
2744
+ "$value": "{font.weight.600}"
2745
+ },
2746
+ "$description": "The title text role."
2747
+ },
2748
+ "heading": {
2749
+ "font-family": {
2750
+ "$type": "fontFamily",
2751
+ "$value": "{theme.type.heading.font-family}"
2752
+ },
2753
+ "font-size": {
2754
+ "$type": "dimension",
2755
+ "$value": "{font.size.16}"
2756
+ },
2757
+ "line-height": {
2758
+ "$type": "dimension",
2759
+ "$value": "{font.line-height.20}"
2760
+ },
2761
+ "font-weight": {
2762
+ "$type": "fontWeight",
2763
+ "$value": "{font.weight.600}"
2764
+ },
2765
+ "$description": "The heading text role."
2766
+ },
2767
+ "body": {
2768
+ "font-family": {
2769
+ "$type": "fontFamily",
2770
+ "$value": "{theme.type.body.font-family}"
2771
+ },
2772
+ "font-size": {
2773
+ "$type": "dimension",
2774
+ "$value": "{font.size.14}"
2775
+ },
2776
+ "line-height": {
2777
+ "$type": "dimension",
2778
+ "$value": "{font.line-height.20}"
2779
+ },
2780
+ "font-weight": {
2781
+ "$type": "fontWeight",
2782
+ "$value": "{font.weight.400}"
2783
+ },
2784
+ "$description": "The body text role."
2785
+ },
2786
+ "label": {
2787
+ "font-family": {
2788
+ "$type": "fontFamily",
2789
+ "$value": "{theme.type.label.font-family}"
2790
+ },
2791
+ "font-size": {
2792
+ "$type": "dimension",
2793
+ "$value": "{font.size.12}"
2794
+ },
2795
+ "line-height": {
2796
+ "$type": "dimension",
2797
+ "$value": "{font.line-height.16}"
2798
+ },
2799
+ "font-weight": {
2800
+ "$type": "fontWeight",
2801
+ "$value": "{font.weight.500}"
2802
+ },
2803
+ "$description": "The label text role."
2804
+ },
2805
+ "caption": {
2806
+ "font-family": {
2807
+ "$type": "fontFamily",
2808
+ "$value": "{theme.type.caption.font-family}"
2809
+ },
2810
+ "font-size": {
2811
+ "$type": "dimension",
2812
+ "$value": "{font.size.12}"
2813
+ },
2814
+ "line-height": {
2815
+ "$type": "dimension",
2816
+ "$value": "{font.line-height.16}"
2817
+ },
2818
+ "font-weight": {
2819
+ "$type": "fontWeight",
2820
+ "$value": "{font.weight.400}"
2821
+ },
2822
+ "$description": "The caption text role."
2823
+ },
2824
+ "data": {
2825
+ "font-family": {
2826
+ "$type": "fontFamily",
2827
+ "$value": "{theme.type.data.font-family}"
2828
+ },
2829
+ "font-size": {
2830
+ "$type": "dimension",
2831
+ "$value": "{font.size.13}"
2832
+ },
2833
+ "line-height": {
2834
+ "$type": "dimension",
2835
+ "$value": "{font.line-height.16}"
2836
+ },
2837
+ "font-weight": {
2838
+ "$type": "fontWeight",
2839
+ "$value": "{font.weight.400}"
2840
+ },
2841
+ "$description": "The data text role."
2842
+ }
2843
+ },
2844
+ "motion": {
2845
+ "duration": {
2846
+ "feedback": {
2847
+ "$type": "duration",
2848
+ "$value": "{duration.fast}",
2849
+ "$description": "Feedback speed: fast."
2850
+ }
2851
+ },
2852
+ "easing": {
2853
+ "standard": {
2854
+ "$type": "cubicBezier",
2855
+ "$value": "{easing.standard}",
2856
+ "$description": "Feedback easing."
2857
+ }
2858
+ }
2859
+ },
2860
+ "opacity": {
2861
+ "disabled": {
2862
+ "$type": "number",
2863
+ "$value": "{opacity.40}",
2864
+ "$description": "Disabled controls."
2865
+ }
2866
+ },
2867
+ "color": {
2868
+ "surface": {
2869
+ "canvas": {
2870
+ "$type": "color",
2871
+ "$description": "The page background.",
2872
+ "$value": "{theme.color.surface.canvas}"
2873
+ },
2874
+ "default": {
2875
+ "$type": "color",
2876
+ "$description": "Cards, inputs and tables.",
2877
+ "$value": "{theme.color.surface.default}"
2878
+ },
2879
+ "raised": {
2880
+ "$type": "color",
2881
+ "$description": "Menus, dialogs, toasts.",
2882
+ "$value": "{theme.color.surface.raised}"
2883
+ },
2884
+ "sunken": {
2885
+ "$type": "color",
2886
+ "$description": "Table headers and wells.",
2887
+ "$value": "{theme.color.surface.sunken}"
2888
+ },
2889
+ "selected": {
2890
+ "$type": "color",
2891
+ "$description": "A selected row or item.",
2892
+ "$value": "{theme.color.surface.selected}"
2893
+ },
2894
+ "inverse": {
2895
+ "$type": "color",
2896
+ "$description": "Tooltips.",
2897
+ "$value": "{theme.color.surface.inverse}"
2898
+ },
2899
+ "scrim": {
2900
+ "$type": "color",
2901
+ "$description": "Dims the page behind a dialog.",
2902
+ "$value": "{theme.color.surface.scrim}"
2903
+ }
2904
+ },
2905
+ "text": {
2906
+ "primary": {
2907
+ "$type": "color",
2908
+ "$description": "Main text.",
2909
+ "$value": "{theme.color.text.primary}"
2910
+ },
2911
+ "secondary": {
2912
+ "$type": "color",
2913
+ "$description": "Supporting text; passes AA.",
2914
+ "$value": "{theme.color.text.secondary}"
2915
+ },
2916
+ "muted": {
2917
+ "$type": "color",
2918
+ "$description": "Hints and placeholders.",
2919
+ "$value": "{theme.color.text.muted}"
2920
+ },
2921
+ "inverse": {
2922
+ "$type": "color",
2923
+ "$description": "Text on inverse surfaces.",
2924
+ "$value": "{theme.color.text.inverse}"
2925
+ },
2926
+ "on-action": {
2927
+ "$type": "color",
2928
+ "$description": "Text on the primary action.",
2929
+ "$value": "{theme.color.text.on-action}"
2930
+ },
2931
+ "link": {
2932
+ "$type": "color",
2933
+ "$description": "Links.",
2934
+ "$value": "{theme.color.text.link}"
2935
+ }
2936
+ },
2937
+ "border": {
2938
+ "default": {
2939
+ "$type": "color",
2940
+ "$description": "Row lines and card borders.",
2941
+ "$value": "{theme.color.border.default}"
2942
+ },
2943
+ "strong": {
2944
+ "$type": "color",
2945
+ "$description": "Input and secondary button borders.",
2946
+ "$value": "{theme.color.border.strong}"
2947
+ },
2948
+ "focus": {
2949
+ "$type": "color",
2950
+ "$description": "The keyboard focus ring.",
2951
+ "$value": "{theme.color.border.focus}"
2952
+ }
2953
+ },
2954
+ "action": {
2955
+ "primary": {
2956
+ "@": {
2957
+ "$type": "color",
2958
+ "$description": "The primary action.",
2959
+ "$value": "{theme.color.action.primary.@}"
2960
+ },
2961
+ "hover": {
2962
+ "$type": "color",
2963
+ "$description": "Primary action on hover.",
2964
+ "$value": "{theme.color.action.primary.hover}"
2965
+ }
2966
+ },
2967
+ "secondary": {
2968
+ "@": {
2969
+ "$type": "color",
2970
+ "$description": "Secondary action fill.",
2971
+ "$value": "{theme.color.action.secondary.@}"
2972
+ },
2973
+ "hover": {
2974
+ "$type": "color",
2975
+ "$description": "Secondary action on hover.",
2976
+ "$value": "{theme.color.action.secondary.hover}"
2977
+ }
2978
+ }
2979
+ },
2980
+ "status": {
2981
+ "info": {
2982
+ "@": {
2983
+ "$type": "color",
2984
+ "$description": "Info text and icons: neutral news, no action needed.",
2985
+ "$value": "{theme.color.status.info.@}"
2986
+ },
2987
+ "subtle": {
2988
+ "$type": "color",
2989
+ "$description": "Info badge and banner fill.",
2990
+ "$value": "{theme.color.status.info.subtle}"
2991
+ }
2992
+ },
2993
+ "success": {
2994
+ "@": {
2995
+ "$type": "color",
2996
+ "$description": "Success text and icons.",
2997
+ "$value": "{theme.color.status.success.@}"
2998
+ },
2999
+ "subtle": {
3000
+ "$type": "color",
3001
+ "$description": "Success badge fill.",
3002
+ "$value": "{theme.color.status.success.subtle}"
3003
+ }
3004
+ },
3005
+ "warning": {
3006
+ "@": {
3007
+ "$type": "color",
3008
+ "$description": "Warning text and icons.",
3009
+ "$value": "{theme.color.status.warning.@}"
3010
+ },
3011
+ "subtle": {
3012
+ "$type": "color",
3013
+ "$description": "Warning badge fill.",
3014
+ "$value": "{theme.color.status.warning.subtle}"
3015
+ }
3016
+ },
3017
+ "danger": {
3018
+ "@": {
3019
+ "$type": "color",
3020
+ "$description": "Danger text and icons.",
3021
+ "$value": "{theme.color.status.danger.@}"
3022
+ },
3023
+ "subtle": {
3024
+ "$type": "color",
3025
+ "$description": "Danger badge fill.",
3026
+ "$value": "{theme.color.status.danger.subtle}"
3027
+ }
3028
+ }
3029
+ },
3030
+ "category": {
3031
+ "$description": "Identity colours for tags, labels and chart series. They tell items apart and carry no meaning.",
3032
+ "1": {
3033
+ "@": {
3034
+ "$type": "color",
3035
+ "$description": "Category 1: chart series, tag dots and icons. Tag text uses color.text.primary.",
3036
+ "$value": "{theme.color.category.1.@}"
3037
+ },
3038
+ "subtle": {
3039
+ "$type": "color",
3040
+ "$description": "Category 1: tag fill.",
3041
+ "$value": "{theme.color.category.1.subtle}"
3042
+ }
3043
+ },
3044
+ "2": {
3045
+ "@": {
3046
+ "$type": "color",
3047
+ "$description": "Category 2: chart series, tag dots and icons. Tag text uses color.text.primary.",
3048
+ "$value": "{theme.color.category.2.@}"
3049
+ },
3050
+ "subtle": {
3051
+ "$type": "color",
3052
+ "$description": "Category 2: tag fill.",
3053
+ "$value": "{theme.color.category.2.subtle}"
3054
+ }
3055
+ },
3056
+ "3": {
3057
+ "@": {
3058
+ "$type": "color",
3059
+ "$description": "Category 3: chart series, tag dots and icons. Tag text uses color.text.primary.",
3060
+ "$value": "{theme.color.category.3.@}"
3061
+ },
3062
+ "subtle": {
3063
+ "$type": "color",
3064
+ "$description": "Category 3: tag fill.",
3065
+ "$value": "{theme.color.category.3.subtle}"
3066
+ }
3067
+ },
3068
+ "4": {
3069
+ "@": {
3070
+ "$type": "color",
3071
+ "$description": "Category 4: chart series, tag dots and icons. Tag text uses color.text.primary.",
3072
+ "$value": "{theme.color.category.4.@}"
3073
+ },
3074
+ "subtle": {
3075
+ "$type": "color",
3076
+ "$description": "Category 4: tag fill.",
3077
+ "$value": "{theme.color.category.4.subtle}"
3078
+ }
3079
+ },
3080
+ "5": {
3081
+ "@": {
3082
+ "$type": "color",
3083
+ "$description": "Category 5: chart series, tag dots and icons. Tag text uses color.text.primary.",
3084
+ "$value": "{theme.color.category.5.@}"
3085
+ },
3086
+ "subtle": {
3087
+ "$type": "color",
3088
+ "$description": "Category 5: tag fill.",
3089
+ "$value": "{theme.color.category.5.subtle}"
3090
+ }
3091
+ }
3092
+ },
3093
+ "disabled": {
3094
+ "$description": "The shared look of controls that cannot be used right now.",
3095
+ "text": {
3096
+ "$type": "color",
3097
+ "$description": "Text and icons of a disabled control.",
3098
+ "$value": "{theme.color.disabled.text}"
3099
+ },
3100
+ "surface": {
3101
+ "$type": "color",
3102
+ "$description": "Fill of a disabled control.",
3103
+ "$value": "{theme.color.disabled.surface}"
3104
+ },
3105
+ "border": {
3106
+ "$type": "color",
3107
+ "$description": "Border of a disabled control.",
3108
+ "$value": "{theme.color.disabled.border}"
3109
+ }
3110
+ }
3111
+ },
3112
+ "elevation": {
3113
+ "card": {
3114
+ "$type": "shadow",
3115
+ "$description": "No shadow in this scheme.",
3116
+ "$value": "{theme.elevation.card}"
3117
+ },
3118
+ "overlay": {
3119
+ "$type": "shadow",
3120
+ "$value": "{theme.elevation.overlay}"
3121
+ }
3122
+ }
3123
+ },
3124
+ "component": {
3125
+ "button": {
3126
+ "primary": {
3127
+ "background": {
3128
+ "@": {
3129
+ "$value": "{color.action.primary.@}",
3130
+ "$description": "Primary button fill."
3131
+ },
3132
+ "hover": {
3133
+ "$value": "{color.action.primary.hover}",
3134
+ "$description": "Primary button fill on hover."
3135
+ }
3136
+ },
3137
+ "label": {
3138
+ "$value": "{color.text.on-action}",
3139
+ "$description": "Primary button label color."
3140
+ }
3141
+ },
3142
+ "secondary": {
3143
+ "background": {
3144
+ "@": {
3145
+ "$value": "{color.action.secondary.@}",
3146
+ "$description": "Secondary button fill."
3147
+ },
3148
+ "hover": {
3149
+ "$value": "{color.action.secondary.hover}",
3150
+ "$description": "Secondary button fill on hover."
3151
+ }
3152
+ },
3153
+ "label": {
3154
+ "$value": "{color.text.primary}",
3155
+ "$description": "Secondary button label color."
3156
+ },
3157
+ "border": {
3158
+ "$value": "{color.border.strong}",
3159
+ "$description": "Secondary button border."
3160
+ }
3161
+ },
3162
+ "ghost": {
3163
+ "background-hover": {
3164
+ "$value": "{color.surface.sunken}",
3165
+ "$description": "Ghost button fill on hover."
3166
+ },
3167
+ "label": {
3168
+ "$value": "{color.text.link}",
3169
+ "$description": "Ghost button label color."
3170
+ }
3171
+ },
3172
+ "height": {
3173
+ "$value": "{size.control.default}",
3174
+ "$description": "Button height."
3175
+ },
3176
+ "padding-x": {
3177
+ "$value": "{space.inset.control-x}",
3178
+ "$description": "Horizontal padding inside a button."
3179
+ },
3180
+ "radius": {
3181
+ "$value": "{radius.control}",
3182
+ "$description": "Button corner radius."
3183
+ },
3184
+ "font-size": {
3185
+ "$value": "{type.label.font-size}",
3186
+ "$description": "Button label size."
3187
+ },
3188
+ "font-weight": {
3189
+ "$value": "{type.label.font-weight}",
3190
+ "$description": "Button label weight."
3191
+ },
3192
+ "focus-ring": {
3193
+ "$value": "{color.border.focus}",
3194
+ "$description": "Focus ring color on any button."
3195
+ },
3196
+ "icon-size": {
3197
+ "$value": "{size.icon}",
3198
+ "$description": "Size of an icon inside a button."
3199
+ },
3200
+ "disabled": {
3201
+ "background": {
3202
+ "$value": "{color.disabled.surface}",
3203
+ "$description": "Fill of a disabled button."
3204
+ },
3205
+ "label": {
3206
+ "$value": "{color.disabled.text}",
3207
+ "$description": "Label of a disabled button."
3208
+ },
3209
+ "border": {
3210
+ "$value": "{color.disabled.border}",
3211
+ "$description": "Border of a disabled secondary button."
3212
+ }
3213
+ }
3214
+ },
3215
+ "input": {
3216
+ "background": {
3217
+ "$value": "{color.surface.default}",
3218
+ "$description": "Input fill."
3219
+ },
3220
+ "border": {
3221
+ "@": {
3222
+ "$value": "{color.border.strong}",
3223
+ "$description": "Input border at rest."
3224
+ },
3225
+ "focus": {
3226
+ "$value": "{color.border.focus}",
3227
+ "$description": "Input border when focused."
3228
+ }
3229
+ },
3230
+ "text": {
3231
+ "$value": "{color.text.primary}",
3232
+ "$description": "Typed text color."
3233
+ },
3234
+ "placeholder": {
3235
+ "$value": "{color.text.muted}",
3236
+ "$description": "Placeholder text color."
3237
+ },
3238
+ "height": {
3239
+ "$value": "{size.control.default}",
3240
+ "$description": "Input height."
3241
+ },
3242
+ "padding-x": {
3243
+ "$value": "{space.inset.control-x}",
3244
+ "$description": "Horizontal padding inside an input."
3245
+ },
3246
+ "radius": {
3247
+ "$value": "{radius.control}",
3248
+ "$description": "Input corner radius."
3249
+ },
3250
+ "font-size": {
3251
+ "$value": "{type.body.font-size}",
3252
+ "$description": "Typed text size."
3253
+ },
3254
+ "disabled": {
3255
+ "background": {
3256
+ "$value": "{color.disabled.surface}",
3257
+ "$description": "Fill of a disabled input."
3258
+ },
3259
+ "border": {
3260
+ "$value": "{color.disabled.border}",
3261
+ "$description": "Border of a disabled input."
3262
+ },
3263
+ "text": {
3264
+ "$value": "{color.disabled.text}",
3265
+ "$description": "Text in a disabled input."
3266
+ }
3267
+ }
3268
+ },
3269
+ "control": {
3270
+ "checked": {
3271
+ "$value": "{color.action.primary.@}",
3272
+ "$description": "Fill of a checked checkbox or an on switch."
3273
+ },
3274
+ "track": {
3275
+ "$value": "{color.border.strong}",
3276
+ "$description": "Track of an off switch."
3277
+ },
3278
+ "thumb": {
3279
+ "$value": "{color.surface.default}",
3280
+ "$description": "Switch thumb and checkmark color."
3281
+ },
3282
+ "radius": {
3283
+ "$value": "{radius.badge}",
3284
+ "$description": "Checkbox corner radius."
3285
+ }
3286
+ },
3287
+ "badge": {
3288
+ "radius": {
3289
+ "$value": "{radius.badge}",
3290
+ "$description": "Badge corner radius."
3291
+ },
3292
+ "padding-x": {
3293
+ "$value": "{space.gap.tight}",
3294
+ "$description": "Horizontal padding inside a badge."
3295
+ },
3296
+ "font-size": {
3297
+ "$value": "{type.caption.font-size}",
3298
+ "$description": "Badge label size."
3299
+ },
3300
+ "neutral": {
3301
+ "background": {
3302
+ "$value": "{color.surface.sunken}",
3303
+ "$description": "Neutral badge fill."
3304
+ },
3305
+ "label": {
3306
+ "$value": "{color.text.secondary}",
3307
+ "$description": "Neutral badge label."
3308
+ }
3309
+ },
3310
+ "success": {
3311
+ "background": {
3312
+ "$value": "{color.status.success.subtle}",
3313
+ "$description": "Success badge fill."
3314
+ },
3315
+ "label": {
3316
+ "$value": "{color.status.success.@}",
3317
+ "$description": "Success badge label."
3318
+ }
3319
+ },
3320
+ "warning": {
3321
+ "background": {
3322
+ "$value": "{color.status.warning.subtle}",
3323
+ "$description": "Warning badge fill."
3324
+ },
3325
+ "label": {
3326
+ "$value": "{color.status.warning.@}",
3327
+ "$description": "Warning badge label."
3328
+ }
3329
+ },
3330
+ "danger": {
3331
+ "background": {
3332
+ "$value": "{color.status.danger.subtle}",
3333
+ "$description": "Danger badge fill."
3334
+ },
3335
+ "label": {
3336
+ "$value": "{color.status.danger.@}",
3337
+ "$description": "Danger badge label."
3338
+ }
3339
+ },
3340
+ "info": {
3341
+ "background": {
3342
+ "$value": "{color.status.info.subtle}",
3343
+ "$description": "Info badge fill."
3344
+ },
3345
+ "label": {
3346
+ "$value": "{color.status.info.@}",
3347
+ "$description": "Info badge label."
3348
+ }
3349
+ }
3350
+ },
3351
+ "card": {
3352
+ "background": {
3353
+ "$value": "{color.surface.default}",
3354
+ "$description": "Card fill."
3355
+ },
3356
+ "border": {
3357
+ "$value": "{color.border.default}",
3358
+ "$description": "Card border."
3359
+ },
3360
+ "radius": {
3361
+ "$value": "{radius.container}",
3362
+ "$description": "Card corner radius."
3363
+ },
3364
+ "padding": {
3365
+ "$value": "{space.inset.container}",
3366
+ "$description": "Padding inside a card."
3367
+ },
3368
+ "shadow": {
3369
+ "$value": "{elevation.card}",
3370
+ "$description": "Card shadow."
3371
+ }
3372
+ },
3373
+ "table": {
3374
+ "header-background": {
3375
+ "$value": "{color.surface.sunken}",
3376
+ "$description": "Header row fill."
3377
+ },
3378
+ "row-height": {
3379
+ "$value": "{size.row}",
3380
+ "$description": "Height of one data row."
3381
+ },
3382
+ "cell-padding-x": {
3383
+ "$value": "{space.inset.cell-x}",
3384
+ "$description": "Horizontal padding inside a cell."
3385
+ },
3386
+ "row-border": {
3387
+ "$value": "{color.border.default}",
3388
+ "$description": "Line between rows."
3389
+ },
3390
+ "row-selected": {
3391
+ "$value": "{color.surface.selected}",
3392
+ "$description": "Fill of a selected row."
3393
+ },
3394
+ "font-size": {
3395
+ "$value": "{type.data.font-size}",
3396
+ "$description": "Cell text size."
3397
+ }
3398
+ },
3399
+ "tabs": {
3400
+ "indicator": {
3401
+ "$value": "{color.action.primary.@}",
3402
+ "$description": "Active tab indicator."
3403
+ },
3404
+ "label": {
3405
+ "@": {
3406
+ "$value": "{color.text.secondary}",
3407
+ "$description": "Inactive tab label."
3408
+ },
3409
+ "active": {
3410
+ "$value": "{color.text.primary}",
3411
+ "$description": "Active tab label."
3412
+ }
3413
+ }
3414
+ },
3415
+ "overlay": {
3416
+ "background": {
3417
+ "$value": "{color.surface.raised}",
3418
+ "$description": "Fill of a dialog, menu or toast."
3419
+ },
3420
+ "radius": {
3421
+ "$value": "{radius.container}",
3422
+ "$description": "Corner radius of overlays."
3423
+ },
3424
+ "shadow": {
3425
+ "$value": "{elevation.overlay}",
3426
+ "$description": "Shadow of overlays."
3427
+ },
3428
+ "scrim": {
3429
+ "$value": "{color.surface.scrim}",
3430
+ "$description": "Color that dims the page behind a dialog."
3431
+ },
3432
+ "item-height": {
3433
+ "$value": "{size.control.default}",
3434
+ "$description": "Height of a menu item."
3435
+ }
3436
+ },
3437
+ "tooltip": {
3438
+ "background": {
3439
+ "$value": "{color.surface.inverse}",
3440
+ "$description": "Tooltip fill."
3441
+ },
3442
+ "label": {
3443
+ "$value": "{color.text.inverse}",
3444
+ "$description": "Tooltip text."
3445
+ }
3446
+ },
3447
+ "transition": {
3448
+ "duration": {
3449
+ "$value": "{motion.duration.feedback}",
3450
+ "$description": "Duration of feedback transitions."
3451
+ },
3452
+ "easing": {
3453
+ "$value": "{motion.easing.standard}",
3454
+ "$description": "Easing of feedback transitions."
3455
+ }
3456
+ }
3457
+ },
3458
+ "content": {
3459
+ "$description": "Voice tokens: the words components use for common actions. Text, not CSS.",
3460
+ "action": {
3461
+ "commit": {
3462
+ "$type": "string",
3463
+ "$value": "Save",
3464
+ "$description": "The label of the action that completes a task."
3465
+ },
3466
+ "cancel": {
3467
+ "$type": "string",
3468
+ "$value": "Cancel",
3469
+ "$description": "The label of the way out next to the main action."
3470
+ },
3471
+ "destroy": {
3472
+ "$type": "string",
3473
+ "$value": "Delete",
3474
+ "$description": "The label of an action that deletes data."
3475
+ },
3476
+ "retry": {
3477
+ "$type": "string",
3478
+ "$value": "Retry",
3479
+ "$description": "The label that repeats a failed action."
3480
+ },
3481
+ "empty-action": {
3482
+ "$type": "string",
3483
+ "$value": "Change filters",
3484
+ "$description": "The label of the action in an empty state."
3485
+ }
3486
+ }
3487
+ }
3488
+ }
3489
+ }