@ttoss/fsl-theme 1.1.11

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 (40) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +390 -0
  3. package/dist/Types-6tR0_2Ss.d.ts +1452 -0
  4. package/dist/css.d.ts +164 -0
  5. package/dist/dataviz/index.d.ts +62 -0
  6. package/dist/dtcg.d.ts +49 -0
  7. package/dist/esm/chunk-4Q4P3JBB.js +185 -0
  8. package/dist/esm/chunk-5PWPAQMC.js +9 -0
  9. package/dist/esm/chunk-BXKVVQEP.js +29 -0
  10. package/dist/esm/chunk-DU4QDQUC.js +29 -0
  11. package/dist/esm/chunk-FBVUI2PK.js +147 -0
  12. package/dist/esm/chunk-HRNXVRS3.js +54 -0
  13. package/dist/esm/chunk-IJGA42O6.js +141 -0
  14. package/dist/esm/chunk-PQPQNZ73.js +262 -0
  15. package/dist/esm/chunk-SE5Z52RE.js +1898 -0
  16. package/dist/esm/chunk-TPMN75JM.js +29 -0
  17. package/dist/esm/chunk-UMRQ4OTX.js +11 -0
  18. package/dist/esm/chunk-VL6EGE6Z.js +222 -0
  19. package/dist/esm/chunk-WVQSTQD5.js +192 -0
  20. package/dist/esm/css.js +6 -0
  21. package/dist/esm/dataviz/index.js +19 -0
  22. package/dist/esm/dtcg.js +65 -0
  23. package/dist/esm/index.js +10 -0
  24. package/dist/esm/react.js +8 -0
  25. package/dist/esm/runtime-entry.js +4 -0
  26. package/dist/esm/themes/bruttal.js +6 -0
  27. package/dist/esm/themes/corporate.js +6 -0
  28. package/dist/esm/themes/oca.js +6 -0
  29. package/dist/esm/themes/ventures.js +6 -0
  30. package/dist/esm/vars.js +28 -0
  31. package/dist/index.d.ts +86 -0
  32. package/dist/react.d.ts +346 -0
  33. package/dist/runtime-entry.d.ts +95 -0
  34. package/dist/themes/bruttal.d.ts +5 -0
  35. package/dist/themes/corporate.d.ts +5 -0
  36. package/dist/themes/oca.d.ts +5 -0
  37. package/dist/themes/ventures.d.ts +5 -0
  38. package/dist/vars.d.ts +127 -0
  39. package/llms.txt +731 -0
  40. package/package.json +88 -0
@@ -0,0 +1,1898 @@
1
+ /** Powered by @ttoss/config. https://ttoss.dev/docs/modules/packages/config/ */
2
+ import { __name, deepMerge, validateRefs } from "./chunk-WVQSTQD5.js";
3
+
4
+ // src/baseTheme.ts
5
+ var baseTheme = {
6
+ // ==========================================================================
7
+ // CORE TOKENS — raw primitives and responsive engines
8
+ // ==========================================================================
9
+ core: {
10
+ // -- Colors -------------------------------------------------------------
11
+ // Core colors are intent-free primitives. Scale positions only.
12
+ colors: {
13
+ brand: {
14
+ 50: "#eff6ff",
15
+ 100: "#dbeafe",
16
+ 200: "#bfdbfe",
17
+ 300: "#60a5fa",
18
+ 400: "#2b87f5",
19
+ 500: "#0469e3",
20
+ 600: "#035fca",
21
+ 700: "#034da6",
22
+ 800: "#023d85",
23
+ 900: "#022e63"
24
+ },
25
+ neutral: {
26
+ 0: "#ffffff",
27
+ 50: "#f8fafc",
28
+ 100: "#f1f5f9",
29
+ 200: "#e2e8f0",
30
+ 300: "#cbd5e1",
31
+ 400: "#94a3b8",
32
+ 500: "#64748b",
33
+ 700: "#334155",
34
+ 900: "#0f172a",
35
+ 1e3: "#020617"
36
+ },
37
+ red: {
38
+ 100: "#fee2e2",
39
+ 300: "#fca5a5",
40
+ 500: "#ef4444",
41
+ 700: "#b91c1c",
42
+ 900: "#7f1d1d"
43
+ },
44
+ orange: {
45
+ 100: "#ffedd5",
46
+ 300: "#fdba74",
47
+ 500: "#f97316",
48
+ 700: "#c2410c",
49
+ 900: "#7c2d12"
50
+ },
51
+ green: {
52
+ 100: "#dcfce7",
53
+ 300: "#86efac",
54
+ 500: "#22c55e",
55
+ 700: "#15803d",
56
+ 900: "#14532d"
57
+ },
58
+ yellow: {
59
+ 100: "#fef9c3",
60
+ 300: "#fde047",
61
+ 500: "#eab308",
62
+ 700: "#a16207",
63
+ 900: "#713f12"
64
+ },
65
+ teal: {
66
+ 100: "#ccfbf1",
67
+ 300: "#5eead4",
68
+ 500: "#14b8a6",
69
+ 700: "#0f766e",
70
+ 900: "#134e4a"
71
+ },
72
+ purple: {
73
+ 100: "#f3e8ff",
74
+ 300: "#d8b4fe",
75
+ 500: "#a855f7",
76
+ 700: "#7e22ce",
77
+ 900: "#581c87"
78
+ },
79
+ pink: {
80
+ 100: "#fce7f3",
81
+ 300: "#f9a8d4",
82
+ 500: "#ec4899",
83
+ 700: "#be185d",
84
+ 900: "#831843"
85
+ }
86
+ },
87
+ // -- Elevation ----------------------------------------------------------
88
+ elevation: {
89
+ level: {
90
+ 0: "none",
91
+ 1: "0 1px 2px rgba(0,0,0,0.06), 0 1px 1px rgba(0,0,0,0.04)",
92
+ 2: "0 4px 8px rgba(0,0,0,0.08), 0 2px 4px rgba(0,0,0,0.06)",
93
+ 3: "0 8px 16px rgba(0,0,0,0.10), 0 4px 8px rgba(0,0,0,0.08)",
94
+ 4: "0 16px 32px rgba(0,0,0,0.14), 0 8px 16px rgba(0,0,0,0.10)"
95
+ },
96
+ // High-opacity recipes — stronger depth contrast for dark or heavily-colored surfaces
97
+ emphatic: {
98
+ 0: "none",
99
+ 1: "0 1px 2px rgba(0,0,0,0.20), 0 1px 1px rgba(0,0,0,0.14)",
100
+ 2: "0 4px 8px rgba(0,0,0,0.24), 0 2px 4px rgba(0,0,0,0.18)",
101
+ 3: "0 8px 16px rgba(0,0,0,0.28), 0 4px 8px rgba(0,0,0,0.22)",
102
+ 4: "0 16px 32px rgba(0,0,0,0.34), 0 8px 16px rgba(0,0,0,0.28)"
103
+ }
104
+ },
105
+ // -- Font Primitives ----------------------------------------------------
106
+ font: {
107
+ family: {
108
+ sans: 'ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, Arial, "Apple Color Emoji", "Segoe UI Emoji"',
109
+ serif: 'ui-serif, Georgia, Cambria, "Times New Roman", Times, serif',
110
+ mono: 'ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace'
111
+ },
112
+ weight: {
113
+ regular: 400,
114
+ medium: 500,
115
+ semibold: 600,
116
+ bold: 700
117
+ },
118
+ leading: {
119
+ tight: 1.15,
120
+ snug: 1.25,
121
+ normal: 1.5,
122
+ relaxed: 1.7
123
+ },
124
+ tracking: {
125
+ tight: "-0.02em",
126
+ normal: "0em",
127
+ wide: "0.04em"
128
+ },
129
+ optical: {
130
+ auto: "auto",
131
+ none: "none"
132
+ },
133
+ numeric: {
134
+ proportional: "proportional-nums",
135
+ tabular: "tabular-nums",
136
+ lining: "lining-nums",
137
+ oldstyle: "oldstyle-nums",
138
+ slashedZero: "slashed-zero",
139
+ ordinal: "ordinal",
140
+ normal: "normal"
141
+ },
142
+ // -- Font Size Scale (Responsive Engine) --------------------------------
143
+ scale: {
144
+ text: {
145
+ 1: "clamp(12px, calc(0.6cqi + 10px), 14px)",
146
+ 2: "clamp(14px, calc(0.7cqi + 11px), 16px)",
147
+ 3: "clamp(16px, calc(0.8cqi + 12px), 18px)",
148
+ 4: "clamp(18px, calc(0.9cqi + 13px), 20px)",
149
+ 5: "clamp(20px, calc(1.0cqi + 14px), 24px)",
150
+ 6: "clamp(24px, calc(1.2cqi + 16px), 28px)"
151
+ },
152
+ display: {
153
+ 1: "clamp(20px, calc(1.2cqi + 16px), 28px)",
154
+ 2: "clamp(24px, calc(1.4cqi + 18px), 32px)",
155
+ 3: "clamp(28px, calc(1.6cqi + 20px), 40px)",
156
+ 4: "clamp(32px, calc(1.8cqi + 22px), 48px)",
157
+ 5: "clamp(40px, calc(2.2cqi + 26px), 64px)",
158
+ 6: "clamp(48px, calc(2.6cqi + 30px), 80px)"
159
+ }
160
+ }
161
+ },
162
+ // -- Spacing (Responsive Engine) ----------------------------------------
163
+ // Tuned for medium-high density (mouse-first). The engine caps at 6px
164
+ // — above that, button paddings compound with hit floors and produce
165
+ // visually heavy controls (>48px desktop) that fight modern UI rhythm
166
+ // (Material 40px, GitHub 32–40px, Bootstrap 38px). Touch density is
167
+ // restored automatically via `@media (any-pointer: coarse)` overrides.
168
+ //
169
+ // CSS-coupled tokens (registered in model.md §8 → "CSS-coupled core
170
+ // tokens"):
171
+ // • `engine.unit` — fluid primitive (`clamp()` + `cqi`); viewport
172
+ // fallback emitted by `toCssVars`.
173
+ // • steps 1..16 — cascade-preserving aliases that reference
174
+ // `--tt-core-spacing-engine-unit` directly so the engine stays a
175
+ // single point of override. Replacing `var()` with a token ref
176
+ // would inline `clamp(...cqi...)` into every step and inflate the
177
+ // `@supports (width: 1cqi)` block. Non-CSS consumers receive the
178
+ // unresolved expression — see model.md §8.
179
+ spacing: {
180
+ engine: {
181
+ unit: "clamp(4px, 0.25cqi + 3px, 6px)"
182
+ },
183
+ 0: "0px",
184
+ 1: "calc(1 * var(--tt-core-spacing-engine-unit))",
185
+ 2: "calc(2 * var(--tt-core-spacing-engine-unit))",
186
+ 3: "calc(3 * var(--tt-core-spacing-engine-unit))",
187
+ 4: "calc(4 * var(--tt-core-spacing-engine-unit))",
188
+ 6: "calc(6 * var(--tt-core-spacing-engine-unit))",
189
+ 8: "calc(8 * var(--tt-core-spacing-engine-unit))",
190
+ 12: "calc(12 * var(--tt-core-spacing-engine-unit))",
191
+ 16: "calc(16 * var(--tt-core-spacing-engine-unit))"
192
+ },
193
+ // -- Sizing (Responsive Engine) -----------------------------------------
194
+ sizing: {
195
+ ramp: {
196
+ ui: {
197
+ 1: "clamp(12px, 0.6cqi + 10px, 16px)",
198
+ 2: "clamp(14px, 0.8cqi + 11px, 20px)",
199
+ 3: "clamp(16px, 1.0cqi + 12px, 24px)",
200
+ 4: "clamp(20px, 1.2cqi + 14px, 32px)",
201
+ 5: "clamp(24px, 1.5cqi + 16px, 40px)",
202
+ 6: "clamp(32px, 1.8cqi + 20px, 56px)",
203
+ 7: "clamp(40px, 2.2cqi + 24px, 72px)",
204
+ 8: "clamp(48px, 2.6cqi + 28px, 96px)"
205
+ },
206
+ layout: {
207
+ 1: "clamp(320px, 40cqi, 480px)",
208
+ 2: "clamp(384px, 50cqi, 640px)",
209
+ 3: "clamp(480px, 60cqi, 800px)",
210
+ 4: "clamp(560px, 70cqi, 960px)",
211
+ 5: "clamp(640px, 80cqi, 1120px)",
212
+ 6: "clamp(768px, 90cqi, 1280px)"
213
+ }
214
+ },
215
+ relative: {
216
+ em: "1em",
217
+ rem: "1rem"
218
+ },
219
+ behavior: {
220
+ auto: "auto",
221
+ full: "100%",
222
+ fit: "fit-content",
223
+ min: "min-content",
224
+ max: "max-content"
225
+ },
226
+ viewport: {
227
+ height: {
228
+ full: "100dvh"
229
+ },
230
+ width: {
231
+ full: "100dvw"
232
+ }
233
+ },
234
+ hit: {
235
+ // Fine: clamp(floor, preferred, max) — floor is the fixed ergonomic
236
+ // minimum; preferred scales with rem so user font-size preferences
237
+ // (accessibility) are respected. Caps tuned to medium-high density:
238
+ // min 32px → secondary / icon-only / dense list controls
239
+ // base 40px → default button (Material 40, GitHub 40, Tailwind 40)
240
+ // prominent 48px → hero CTAs and primary form submits
241
+ // 24px WCAG 2.2 minimum is well exceeded at every step.
242
+ fine: {
243
+ min: "clamp(28px, 1.75rem, 32px)",
244
+ base: "clamp(32px, 2rem, 40px)",
245
+ prominent: "clamp(40px, 2.5rem, 48px)"
246
+ },
247
+ // Coarse: always fixed px — touch ergonomics require predictable,
248
+ // reliable targets (Apple HIG 44px floor, Material 48dp default).
249
+ coarse: {
250
+ min: "32px",
251
+ base: "48px",
252
+ prominent: "56px"
253
+ }
254
+ }
255
+ },
256
+ // -- Radii --------------------------------------------------------------
257
+ radii: {
258
+ none: "0px",
259
+ sm: "4px",
260
+ md: "8px",
261
+ lg: "12px",
262
+ xl: "16px",
263
+ full: "9999px"
264
+ },
265
+ // -- Borders ------------------------------------------------------------
266
+ border: {
267
+ width: {
268
+ none: "0px",
269
+ default: "1px",
270
+ selected: "2px",
271
+ focused: "2px"
272
+ },
273
+ style: {
274
+ solid: "solid",
275
+ dashed: "dashed",
276
+ dotted: "dotted",
277
+ none: "none"
278
+ }
279
+ },
280
+ // -- Opacity ------------------------------------------------------------
281
+ opacity: {
282
+ 100: 1,
283
+ 75: 0.75,
284
+ 50: 0.5,
285
+ 25: 0.25,
286
+ 0: 0
287
+ },
288
+ // -- Motion -------------------------------------------------------------
289
+ motion: {
290
+ duration: {
291
+ none: "0ms",
292
+ xs: "50ms",
293
+ sm: "100ms",
294
+ md: "200ms",
295
+ lg: "300ms",
296
+ xl: "500ms"
297
+ },
298
+ easing: {
299
+ standard: "cubic-bezier(0.4, 0, 0.2, 1)",
300
+ enter: "cubic-bezier(0, 0, 0.2, 1)",
301
+ exit: "cubic-bezier(0.4, 0, 1, 1)",
302
+ linear: "linear"
303
+ }
304
+ },
305
+ // -- Z-Index ------------------------------------------------------------
306
+ zIndex: {
307
+ level: {
308
+ 0: 0,
309
+ 1: 100,
310
+ 2: 200,
311
+ 3: 300,
312
+ 4: 400
313
+ }
314
+ },
315
+ // -- Breakpoints --------------------------------------------------------
316
+ breakpoints: {
317
+ sm: "30rem",
318
+ md: "48rem",
319
+ lg: "64rem",
320
+ xl: "80rem",
321
+ "2xl": "96rem"
322
+ }
323
+ },
324
+ // ==========================================================================
325
+ // SEMANTIC TOKENS — stable aliases consumed by components
326
+ //
327
+ // Semantic tokens reference core tokens only.
328
+ // No raw values are allowed in this layer.
329
+ // ==========================================================================
330
+ semantic: {
331
+ // -- Colors -------------------------------------------------------------
332
+ // Grammar: {ux}.{role}.{dimension}.{state?}
333
+ // Components consume semantic colors only. Core colors are never referenced directly.
334
+ colors: {
335
+ // Grammar: {ux}.{role}.{dimension}.{state?}
336
+ // States are only defined when they produce a VALUE DIFFERENT from the
337
+ // default state in that dimension. Hover/active/focused/selected/current
338
+ // that resolve to the same color as default are intentionally omitted —
339
+ // a token that looks identical to default is semantically invisible.
340
+ //
341
+ // Checked pairs enforced by the distinguishability test:
342
+ // hover, active, focused, selected, current → must differ from default
343
+ // Other states (disabled, droptarget, pressed, expanded, checked,
344
+ // indeterminate, visited) may match default when semantically justified.
345
+ action: {
346
+ primary: {
347
+ // neutral.1000 (black) background — authoritative, neutral primary action.
348
+ // Contrast: neutral.0 text on neutral.1000 → ~20:1 ✓ ; neutral.700 hover → ~12:1 ✓
349
+ background: {
350
+ default: "{core.colors.neutral.1000}",
351
+ hover: "{core.colors.neutral.900}",
352
+ active: "{core.colors.neutral.700}",
353
+ disabled: "{core.colors.neutral.200}",
354
+ droptarget: "{core.colors.neutral.100}",
355
+ pressed: "{core.colors.neutral.700}",
356
+ expanded: "{core.colors.neutral.900}"
357
+ },
358
+ border: {
359
+ default: "{core.colors.neutral.1000}",
360
+ hover: "{core.colors.neutral.900}",
361
+ active: "{core.colors.neutral.700}",
362
+ focused: "{core.colors.brand.500}",
363
+ disabled: "{core.colors.neutral.200}",
364
+ pressed: "{core.colors.neutral.700}",
365
+ expanded: "{core.colors.neutral.900}"
366
+ },
367
+ text: {
368
+ default: "{core.colors.neutral.0}",
369
+ disabled: "{core.colors.neutral.500}",
370
+ // On droptarget background (neutral.100 = light), dark text is required
371
+ droptarget: "{core.colors.neutral.900}"
372
+ }
373
+ },
374
+ secondary: {
375
+ // neutral.100 background, neutral.300 border, neutral.900 text
376
+ background: {
377
+ default: "{core.colors.neutral.200}",
378
+ hover: "{core.colors.neutral.300}",
379
+ active: "{core.colors.neutral.400}",
380
+ disabled: "{core.colors.neutral.100}",
381
+ droptarget: "{core.colors.neutral.50}",
382
+ pressed: "{core.colors.neutral.400}",
383
+ expanded: "{core.colors.neutral.200}"
384
+ },
385
+ border: {
386
+ default: "{core.colors.neutral.200}",
387
+ hover: "{core.colors.neutral.300}",
388
+ active: "{core.colors.neutral.400}",
389
+ focused: "{core.colors.brand.500}",
390
+ disabled: "{core.colors.neutral.200}",
391
+ pressed: "{core.colors.neutral.400}",
392
+ expanded: "{core.colors.brand.500}"
393
+ },
394
+ text: {
395
+ default: "{core.colors.neutral.900}",
396
+ disabled: "{core.colors.neutral.500}"
397
+ }
398
+ },
399
+ accent: {
400
+ // brand.500 background — vivid blue that draws attention in the UI.
401
+ // Contrast: neutral.0 text on brand.500 (#0469e3) → ~5.7:1 ✓ AA
402
+ // All interactive states darken further → neutral.0 text remains valid.
403
+ background: {
404
+ default: "{core.colors.brand.500}",
405
+ hover: "{core.colors.brand.700}",
406
+ active: "{core.colors.brand.900}",
407
+ disabled: "{core.colors.neutral.200}",
408
+ droptarget: "{core.colors.brand.50}",
409
+ pressed: "{core.colors.brand.900}",
410
+ expanded: "{core.colors.brand.700}"
411
+ },
412
+ border: {
413
+ default: "{core.colors.brand.500}",
414
+ hover: "{core.colors.brand.700}",
415
+ active: "{core.colors.brand.900}",
416
+ focused: "{core.colors.brand.700}",
417
+ disabled: "{core.colors.neutral.200}",
418
+ pressed: "{core.colors.brand.900}",
419
+ expanded: "{core.colors.brand.700}"
420
+ },
421
+ text: {
422
+ // brand.500 is dark enough — neutral.0 meets ≥ 4.5:1 AA on all states
423
+ default: "{core.colors.neutral.0}",
424
+ disabled: "{core.colors.neutral.500}",
425
+ droptarget: "{core.colors.neutral.900}"
426
+ }
427
+ },
428
+ negative: {
429
+ // red.500 background, red.500 border, neutral.0 text
430
+ background: {
431
+ default: "{core.colors.red.500}",
432
+ hover: "{core.colors.red.700}",
433
+ active: "{core.colors.red.900}",
434
+ disabled: "{core.colors.neutral.200}",
435
+ droptarget: "{core.colors.red.100}",
436
+ pressed: "{core.colors.red.900}",
437
+ expanded: "{core.colors.red.700}"
438
+ },
439
+ border: {
440
+ default: "{core.colors.red.500}",
441
+ hover: "{core.colors.red.700}",
442
+ active: "{core.colors.red.900}",
443
+ focused: "{core.colors.red.700}",
444
+ disabled: "{core.colors.neutral.200}",
445
+ pressed: "{core.colors.red.900}",
446
+ expanded: "{core.colors.red.700}"
447
+ },
448
+ text: {
449
+ default: "{core.colors.neutral.0}",
450
+ disabled: "{core.colors.neutral.500}",
451
+ droptarget: "{core.colors.neutral.900}"
452
+ }
453
+ },
454
+ muted: {
455
+ // neutral.0 background, neutral.200 border, neutral.700 text
456
+ background: {
457
+ default: "{core.colors.neutral.0}",
458
+ hover: "{core.colors.neutral.50}",
459
+ active: "{core.colors.neutral.100}",
460
+ disabled: "{core.colors.neutral.100}",
461
+ droptarget: "{core.colors.neutral.50}",
462
+ pressed: "{core.colors.neutral.100}",
463
+ expanded: "{core.colors.neutral.50}"
464
+ },
465
+ border: {
466
+ default: "{core.colors.neutral.200}",
467
+ hover: "{core.colors.neutral.300}",
468
+ active: "{core.colors.neutral.300}",
469
+ focused: "{core.colors.brand.500}",
470
+ disabled: "{core.colors.neutral.200}",
471
+ pressed: "{core.colors.neutral.300}",
472
+ expanded: "{core.colors.brand.500}"
473
+ },
474
+ text: {
475
+ default: "{core.colors.neutral.700}",
476
+ hover: "{core.colors.neutral.900}",
477
+ active: "{core.colors.neutral.900}",
478
+ disabled: "{core.colors.neutral.500}",
479
+ pressed: "{core.colors.neutral.900}",
480
+ expanded: "{core.colors.neutral.900}"
481
+ }
482
+ }
483
+ },
484
+ input: {
485
+ primary: {
486
+ // neutral.0 background, neutral.300 border, neutral.900 text
487
+ background: {
488
+ default: "{core.colors.neutral.0}",
489
+ hover: "{core.colors.neutral.50}",
490
+ active: "{core.colors.neutral.50}",
491
+ disabled: "{core.colors.neutral.100}",
492
+ selected: "{core.colors.brand.50}",
493
+ droptarget: "{core.colors.neutral.50}",
494
+ checked: "{core.colors.brand.500}",
495
+ indeterminate: "{core.colors.brand.300}",
496
+ pressed: "{core.colors.neutral.100}",
497
+ expanded: "{core.colors.neutral.50}"
498
+ },
499
+ border: {
500
+ default: "{core.colors.neutral.300}",
501
+ hover: "{core.colors.neutral.500}",
502
+ active: "{core.colors.brand.500}",
503
+ focused: "{core.colors.brand.500}",
504
+ disabled: "{core.colors.neutral.200}",
505
+ selected: "{core.colors.brand.500}",
506
+ checked: "{core.colors.brand.500}",
507
+ indeterminate: "{core.colors.brand.300}",
508
+ pressed: "{core.colors.neutral.500}",
509
+ expanded: "{core.colors.brand.500}"
510
+ },
511
+ text: {
512
+ default: "{core.colors.neutral.900}",
513
+ disabled: "{core.colors.neutral.500}",
514
+ checked: "{core.colors.neutral.0}",
515
+ // brand.300 (indeterminate bg) is light — use dark text for contrast
516
+ indeterminate: "{core.colors.neutral.900}"
517
+ }
518
+ },
519
+ // Lower-emphasis input field (inline editors, filter pills, optional fields).
520
+ // Mirrors primary controls but uses a lighter chrome — default border is
521
+ // neutral.200 (vs primary's neutral.300) so it recedes until interacted with.
522
+ secondary: {
523
+ background: {
524
+ default: "{core.colors.neutral.0}",
525
+ hover: "{core.colors.neutral.50}",
526
+ active: "{core.colors.neutral.100}",
527
+ disabled: "{core.colors.neutral.100}",
528
+ selected: "{core.colors.brand.50}",
529
+ droptarget: "{core.colors.neutral.50}",
530
+ checked: "{core.colors.brand.500}",
531
+ indeterminate: "{core.colors.brand.300}",
532
+ pressed: "{core.colors.neutral.100}",
533
+ expanded: "{core.colors.neutral.50}"
534
+ },
535
+ border: {
536
+ default: "{core.colors.neutral.200}",
537
+ hover: "{core.colors.neutral.300}",
538
+ active: "{core.colors.brand.500}",
539
+ focused: "{core.colors.brand.500}",
540
+ disabled: "{core.colors.neutral.200}",
541
+ selected: "{core.colors.brand.500}",
542
+ checked: "{core.colors.brand.500}",
543
+ indeterminate: "{core.colors.brand.300}",
544
+ pressed: "{core.colors.neutral.300}",
545
+ expanded: "{core.colors.brand.500}"
546
+ },
547
+ text: {
548
+ default: "{core.colors.neutral.900}",
549
+ disabled: "{core.colors.neutral.500}",
550
+ checked: "{core.colors.neutral.0}",
551
+ indeterminate: "{core.colors.neutral.900}"
552
+ }
553
+ },
554
+ negative: {
555
+ background: {
556
+ default: "{core.colors.red.100}",
557
+ disabled: "{core.colors.neutral.100}",
558
+ // red.700 (not red.500) so neutral.0 text meets 4.5:1 AA contrast
559
+ checked: "{core.colors.red.700}",
560
+ indeterminate: "{core.colors.red.300}"
561
+ },
562
+ border: {
563
+ default: "{core.colors.red.500}",
564
+ active: "{core.colors.red.700}",
565
+ focused: "{core.colors.red.700}",
566
+ disabled: "{core.colors.neutral.200}",
567
+ indeterminate: "{core.colors.red.300}",
568
+ pressed: "{core.colors.red.700}",
569
+ expanded: "{core.colors.red.700}"
570
+ },
571
+ text: {
572
+ default: "{core.colors.red.700}",
573
+ disabled: "{core.colors.neutral.500}",
574
+ checked: "{core.colors.neutral.0}"
575
+ }
576
+ },
577
+ positive: {
578
+ background: {
579
+ default: "{core.colors.green.100}",
580
+ disabled: "{core.colors.neutral.100}",
581
+ // green.700 (not green.500) so neutral.0 text meets 4.5:1 AA contrast
582
+ checked: "{core.colors.green.700}",
583
+ indeterminate: "{core.colors.green.300}"
584
+ },
585
+ border: {
586
+ default: "{core.colors.green.500}",
587
+ active: "{core.colors.green.700}",
588
+ focused: "{core.colors.green.700}",
589
+ disabled: "{core.colors.neutral.200}",
590
+ indeterminate: "{core.colors.green.300}",
591
+ pressed: "{core.colors.green.700}",
592
+ expanded: "{core.colors.green.700}"
593
+ },
594
+ text: {
595
+ default: "{core.colors.green.700}",
596
+ disabled: "{core.colors.neutral.500}",
597
+ checked: "{core.colors.neutral.0}"
598
+ }
599
+ },
600
+ caution: {
601
+ background: {
602
+ default: "{core.colors.yellow.100}",
603
+ disabled: "{core.colors.neutral.100}",
604
+ checked: "{core.colors.yellow.500}",
605
+ indeterminate: "{core.colors.yellow.300}"
606
+ },
607
+ border: {
608
+ default: "{core.colors.yellow.500}",
609
+ active: "{core.colors.yellow.700}",
610
+ focused: "{core.colors.yellow.700}",
611
+ disabled: "{core.colors.neutral.200}",
612
+ indeterminate: "{core.colors.yellow.300}",
613
+ pressed: "{core.colors.yellow.700}",
614
+ expanded: "{core.colors.yellow.700}"
615
+ },
616
+ text: {
617
+ default: "{core.colors.yellow.900}",
618
+ disabled: "{core.colors.neutral.500}",
619
+ // yellow.500 is light — dark text required for 4.5:1 AA
620
+ checked: "{core.colors.neutral.900}"
621
+ }
622
+ },
623
+ muted: {
624
+ background: {
625
+ default: "{core.colors.neutral.100}",
626
+ active: "{core.colors.neutral.200}",
627
+ selected: "{core.colors.neutral.200}",
628
+ checked: "{core.colors.neutral.500}",
629
+ indeterminate: "{core.colors.neutral.300}"
630
+ },
631
+ border: {
632
+ default: "{core.colors.neutral.200}",
633
+ hover: "{core.colors.neutral.300}",
634
+ active: "{core.colors.neutral.500}",
635
+ focused: "{core.colors.brand.500}",
636
+ disabled: "{core.colors.neutral.200}",
637
+ selected: "{core.colors.neutral.500}",
638
+ checked: "{core.colors.neutral.500}",
639
+ indeterminate: "{core.colors.neutral.300}",
640
+ pressed: "{core.colors.neutral.500}",
641
+ expanded: "{core.colors.brand.500}"
642
+ },
643
+ text: {
644
+ default: "{core.colors.neutral.700}",
645
+ disabled: "{core.colors.neutral.500}",
646
+ checked: "{core.colors.neutral.0}"
647
+ }
648
+ }
649
+ },
650
+ informational: {
651
+ primary: {
652
+ background: {
653
+ default: "{core.colors.neutral.0}",
654
+ hover: "{core.colors.neutral.50}",
655
+ active: "{core.colors.neutral.100}",
656
+ disabled: "{core.colors.neutral.100}",
657
+ selected: "{core.colors.brand.50}",
658
+ droptarget: "{core.colors.brand.50}",
659
+ visited: "{core.colors.neutral.50}"
660
+ },
661
+ border: {
662
+ default: "{core.colors.neutral.200}",
663
+ hover: "{core.colors.neutral.300}",
664
+ active: "{core.colors.neutral.300}",
665
+ focused: "{core.colors.brand.500}",
666
+ disabled: "{core.colors.neutral.100}",
667
+ selected: "{core.colors.brand.300}",
668
+ droptarget: "{core.colors.brand.300}"
669
+ },
670
+ text: {
671
+ default: "{core.colors.neutral.900}",
672
+ disabled: "{core.colors.neutral.500}",
673
+ visited: "{core.colors.neutral.700}"
674
+ }
675
+ },
676
+ secondary: {
677
+ background: {
678
+ default: "{core.colors.neutral.50}",
679
+ hover: "{core.colors.neutral.100}",
680
+ active: "{core.colors.neutral.200}",
681
+ disabled: "{core.colors.neutral.100}",
682
+ selected: "{core.colors.brand.50}",
683
+ droptarget: "{core.colors.neutral.100}",
684
+ visited: "{core.colors.neutral.100}"
685
+ },
686
+ border: {
687
+ default: "{core.colors.neutral.200}",
688
+ hover: "{core.colors.neutral.300}",
689
+ active: "{core.colors.neutral.300}",
690
+ focused: "{core.colors.brand.500}",
691
+ disabled: "{core.colors.neutral.100}",
692
+ selected: "{core.colors.brand.300}"
693
+ },
694
+ text: {
695
+ default: "{core.colors.neutral.700}",
696
+ active: "{core.colors.neutral.900}",
697
+ disabled: "{core.colors.neutral.500}",
698
+ // neutral.700 (not neutral.500) to meet 4.5:1 AA on neutral.100 background
699
+ visited: "{core.colors.neutral.700}"
700
+ }
701
+ },
702
+ muted: {
703
+ background: {
704
+ default: "{core.colors.neutral.100}",
705
+ hover: "{core.colors.neutral.200}",
706
+ active: "{core.colors.neutral.300}",
707
+ selected: "{core.colors.neutral.200}",
708
+ droptarget: "{core.colors.neutral.200}"
709
+ },
710
+ border: {
711
+ default: "{core.colors.neutral.200}",
712
+ hover: "{core.colors.neutral.300}",
713
+ active: "{core.colors.neutral.500}",
714
+ focused: "{core.colors.brand.500}",
715
+ selected: "{core.colors.neutral.500}"
716
+ },
717
+ text: {
718
+ default: "{core.colors.neutral.500}",
719
+ hover: "{core.colors.neutral.700}",
720
+ active: "{core.colors.neutral.900}",
721
+ disabled: "{core.colors.neutral.300}",
722
+ selected: "{core.colors.neutral.700}",
723
+ droptarget: "{core.colors.neutral.700}"
724
+ }
725
+ },
726
+ positive: {
727
+ background: {
728
+ default: "{core.colors.green.100}",
729
+ disabled: "{core.colors.neutral.100}",
730
+ selected: "{core.colors.green.300}"
731
+ },
732
+ border: {
733
+ default: "{core.colors.green.500}",
734
+ active: "{core.colors.green.700}",
735
+ focused: "{core.colors.green.700}",
736
+ disabled: "{core.colors.neutral.200}",
737
+ selected: "{core.colors.green.700}"
738
+ },
739
+ text: {
740
+ default: "{core.colors.green.900}",
741
+ disabled: "{core.colors.neutral.500}",
742
+ visited: "{core.colors.green.700}"
743
+ }
744
+ },
745
+ caution: {
746
+ background: {
747
+ default: "{core.colors.yellow.100}",
748
+ disabled: "{core.colors.neutral.100}",
749
+ selected: "{core.colors.yellow.300}"
750
+ },
751
+ border: {
752
+ default: "{core.colors.yellow.500}",
753
+ active: "{core.colors.yellow.700}",
754
+ focused: "{core.colors.yellow.700}",
755
+ disabled: "{core.colors.neutral.200}",
756
+ selected: "{core.colors.yellow.700}"
757
+ },
758
+ text: {
759
+ default: "{core.colors.yellow.900}",
760
+ disabled: "{core.colors.neutral.500}",
761
+ visited: "{core.colors.yellow.700}"
762
+ }
763
+ },
764
+ negative: {
765
+ background: {
766
+ default: "{core.colors.red.100}",
767
+ disabled: "{core.colors.neutral.100}",
768
+ selected: "{core.colors.red.300}"
769
+ },
770
+ border: {
771
+ default: "{core.colors.red.500}",
772
+ active: "{core.colors.red.700}",
773
+ focused: "{core.colors.red.700}",
774
+ disabled: "{core.colors.neutral.200}",
775
+ selected: "{core.colors.red.700}"
776
+ },
777
+ text: {
778
+ default: "{core.colors.red.900}",
779
+ disabled: "{core.colors.neutral.500}",
780
+ visited: "{core.colors.red.700}"
781
+ }
782
+ },
783
+ accent: {
784
+ // brand.400 bg — louder than primary (brand.500). Outlined/tinted card accent.
785
+ // Follows filled pattern for selected, rest stays light.
786
+ background: {
787
+ default: "{core.colors.brand.50}",
788
+ hover: "{core.colors.brand.100}",
789
+ active: "{core.colors.brand.200}",
790
+ disabled: "{core.colors.neutral.100}",
791
+ // selected uses brand.500 (not brand.400) so neutral.0 text meets
792
+ // AA Normal (≥ 4.5:1). brand.400 on white fails the normal threshold.
793
+ selected: "{core.colors.brand.500}"
794
+ },
795
+ border: {
796
+ default: "{core.colors.brand.400}",
797
+ hover: "{core.colors.brand.500}",
798
+ active: "{core.colors.brand.600}",
799
+ focused: "{core.colors.brand.700}",
800
+ disabled: "{core.colors.neutral.200}",
801
+ selected: "{core.colors.brand.600}"
802
+ },
803
+ text: {
804
+ default: "{core.colors.brand.700}",
805
+ hover: "{core.colors.brand.900}",
806
+ active: "{core.colors.brand.900}",
807
+ disabled: "{core.colors.neutral.500}",
808
+ // selected uses filled bg (brand.500) — neutral.0 meets 4.5:1
809
+ selected: "{core.colors.neutral.0}",
810
+ visited: "{core.colors.brand.700}"
811
+ }
812
+ }
813
+ },
814
+ feedback: {
815
+ // Feedback is informational — surfaces show state, not interactions.
816
+ // Legal states: default | focused (close button or focusable wrapper) | disabled.
817
+ // hover, active, selected, pressed, expanded are absent: FSL §7.
818
+ primary: {
819
+ background: {
820
+ default: "{core.colors.neutral.50}"
821
+ },
822
+ border: {
823
+ default: "{core.colors.neutral.300}",
824
+ focused: "{core.colors.brand.500}"
825
+ },
826
+ text: {
827
+ default: "{core.colors.neutral.900}",
828
+ disabled: "{core.colors.neutral.500}"
829
+ }
830
+ },
831
+ muted: {
832
+ background: {
833
+ default: "{core.colors.neutral.100}"
834
+ },
835
+ border: {
836
+ default: "{core.colors.neutral.300}",
837
+ focused: "{core.colors.brand.500}"
838
+ },
839
+ text: {
840
+ default: "{core.colors.neutral.700}",
841
+ disabled: "{core.colors.neutral.500}"
842
+ }
843
+ },
844
+ positive: {
845
+ background: {
846
+ default: "{core.colors.green.100}"
847
+ },
848
+ border: {
849
+ default: "{core.colors.green.500}",
850
+ focused: "{core.colors.green.700}"
851
+ },
852
+ text: {
853
+ default: "{core.colors.green.900}",
854
+ disabled: "{core.colors.neutral.500}"
855
+ }
856
+ },
857
+ caution: {
858
+ background: {
859
+ default: "{core.colors.yellow.100}"
860
+ },
861
+ border: {
862
+ default: "{core.colors.yellow.500}",
863
+ focused: "{core.colors.yellow.700}"
864
+ },
865
+ text: {
866
+ default: "{core.colors.yellow.900}",
867
+ disabled: "{core.colors.neutral.500}"
868
+ }
869
+ },
870
+ negative: {
871
+ background: {
872
+ default: "{core.colors.red.100}"
873
+ },
874
+ border: {
875
+ default: "{core.colors.red.500}",
876
+ focused: "{core.colors.red.700}"
877
+ },
878
+ text: {
879
+ default: "{core.colors.red.900}",
880
+ disabled: "{core.colors.neutral.500}"
881
+ }
882
+ }
883
+ },
884
+ navigation: {
885
+ primary: {
886
+ // Inline link on light surfaces: transparent bg, brand text underline.
887
+ // Contrast: brand.700 (#034da6) on neutral.0 (#ffffff) → ~9.5:1 ✓
888
+ background: {
889
+ default: "{core.colors.neutral.0}",
890
+ hover: "{core.colors.neutral.50}",
891
+ active: "{core.colors.neutral.100}",
892
+ disabled: "{core.colors.neutral.0}",
893
+ current: "{core.colors.neutral.50}",
894
+ visited: "{core.colors.neutral.0}",
895
+ expanded: "{core.colors.neutral.50}"
896
+ },
897
+ border: {
898
+ default: "{core.colors.neutral.0}",
899
+ focused: "{core.colors.brand.500}"
900
+ },
901
+ text: {
902
+ default: "{core.colors.brand.700}",
903
+ hover: "{core.colors.brand.900}",
904
+ active: "{core.colors.brand.900}",
905
+ disabled: "{core.colors.neutral.500}",
906
+ current: "{core.colors.brand.900}",
907
+ visited: "{core.colors.neutral.500}",
908
+ expanded: "{core.colors.brand.900}"
909
+ }
910
+ },
911
+ secondary: {
912
+ // Light nav: neutral.50 background, neutral.200 border, neutral.700 text
913
+ background: {
914
+ default: "{core.colors.neutral.50}",
915
+ hover: "{core.colors.neutral.100}",
916
+ active: "{core.colors.neutral.200}",
917
+ disabled: "{core.colors.neutral.100}",
918
+ selected: "{core.colors.brand.50}",
919
+ droptarget: "{core.colors.neutral.100}",
920
+ current: "{core.colors.brand.100}",
921
+ visited: "{core.colors.neutral.100}",
922
+ expanded: "{core.colors.neutral.100}"
923
+ },
924
+ border: {
925
+ default: "{core.colors.neutral.200}",
926
+ hover: "{core.colors.neutral.300}",
927
+ active: "{core.colors.neutral.300}",
928
+ focused: "{core.colors.brand.500}",
929
+ disabled: "{core.colors.neutral.200}",
930
+ selected: "{core.colors.brand.400}",
931
+ current: "{core.colors.brand.500}"
932
+ },
933
+ text: {
934
+ default: "{core.colors.neutral.700}",
935
+ hover: "{core.colors.neutral.900}",
936
+ disabled: "{core.colors.neutral.500}",
937
+ selected: "{core.colors.brand.700}",
938
+ current: "{core.colors.brand.700}",
939
+ visited: "{core.colors.neutral.700}",
940
+ expanded: "{core.colors.neutral.900}"
941
+ }
942
+ },
943
+ accent: {
944
+ // Brand accent nav: brand.50 background with brand border — louder than secondary.
945
+ // Targeted use: highlighted/featured nav items.
946
+ background: {
947
+ default: "{core.colors.brand.50}",
948
+ hover: "{core.colors.brand.100}",
949
+ active: "{core.colors.brand.200}",
950
+ disabled: "{core.colors.neutral.100}",
951
+ selected: "{core.colors.brand.700}",
952
+ current: "{core.colors.brand.700}",
953
+ expanded: "{core.colors.brand.100}"
954
+ },
955
+ border: {
956
+ default: "{core.colors.brand.400}",
957
+ hover: "{core.colors.brand.500}",
958
+ active: "{core.colors.brand.600}",
959
+ focused: "{core.colors.brand.700}",
960
+ disabled: "{core.colors.neutral.200}",
961
+ selected: "{core.colors.brand.700}",
962
+ current: "{core.colors.brand.700}"
963
+ },
964
+ text: {
965
+ default: "{core.colors.brand.700}",
966
+ hover: "{core.colors.brand.900}",
967
+ disabled: "{core.colors.neutral.500}",
968
+ // selected/current use brand.700 bg — neutral.0 meets ≥ 4.5:1
969
+ selected: "{core.colors.neutral.0}",
970
+ current: "{core.colors.neutral.0}",
971
+ visited: "{core.colors.brand.500}",
972
+ expanded: "{core.colors.brand.900}"
973
+ }
974
+ },
975
+ muted: {
976
+ // Subdued nav: transparent / neutral.100 background, none border, neutral.500 text.
977
+ // Used for secondary nav items, breadcrumbs, or inactive sidebar links.
978
+ background: {
979
+ default: "{core.colors.neutral.0}",
980
+ hover: "{core.colors.neutral.50}",
981
+ active: "{core.colors.neutral.100}",
982
+ disabled: "{core.colors.neutral.100}",
983
+ selected: "{core.colors.neutral.100}",
984
+ current: "{core.colors.neutral.100}",
985
+ expanded: "{core.colors.neutral.50}"
986
+ },
987
+ border: {
988
+ default: "{core.colors.neutral.200}",
989
+ hover: "{core.colors.neutral.300}",
990
+ active: "{core.colors.neutral.300}",
991
+ focused: "{core.colors.brand.500}",
992
+ disabled: "{core.colors.neutral.200}",
993
+ selected: "{core.colors.neutral.500}",
994
+ current: "{core.colors.brand.400}"
995
+ },
996
+ text: {
997
+ default: "{core.colors.neutral.500}",
998
+ hover: "{core.colors.neutral.700}",
999
+ active: "{core.colors.neutral.900}",
1000
+ disabled: "{core.colors.neutral.300}",
1001
+ selected: "{core.colors.neutral.900}",
1002
+ current: "{core.colors.brand.700}",
1003
+ visited: "{core.colors.neutral.500}",
1004
+ expanded: "{core.colors.neutral.700}"
1005
+ }
1006
+ }
1007
+ }
1008
+ },
1009
+ // -- Elevation ----------------------------------------------------------
1010
+ // Grammar: elevation.surface.{stratum}
1011
+ elevation: {
1012
+ surface: {
1013
+ flat: "{core.elevation.level.0}",
1014
+ raised: "{core.elevation.level.2}",
1015
+ overlay: "{core.elevation.level.3}",
1016
+ blocking: "{core.elevation.level.4}"
1017
+ }
1018
+ },
1019
+ // -- Typography ---------------------------------------------------------
1020
+ // Grammar: text.{family}.{step}
1021
+ text: {
1022
+ display: {
1023
+ lg: {
1024
+ fontFamily: "{core.font.family.sans}",
1025
+ fontSize: "{core.font.scale.display.5}",
1026
+ fontWeight: "{core.font.weight.bold}",
1027
+ lineHeight: "{core.font.leading.tight}",
1028
+ letterSpacing: "{core.font.tracking.tight}",
1029
+ fontOpticalSizing: "{core.font.optical.auto}"
1030
+ },
1031
+ md: {
1032
+ fontFamily: "{core.font.family.sans}",
1033
+ fontSize: "{core.font.scale.display.4}",
1034
+ fontWeight: "{core.font.weight.bold}",
1035
+ lineHeight: "{core.font.leading.tight}",
1036
+ letterSpacing: "{core.font.tracking.tight}",
1037
+ fontOpticalSizing: "{core.font.optical.auto}"
1038
+ },
1039
+ sm: {
1040
+ fontFamily: "{core.font.family.sans}",
1041
+ fontSize: "{core.font.scale.display.3}",
1042
+ fontWeight: "{core.font.weight.semibold}",
1043
+ lineHeight: "{core.font.leading.tight}",
1044
+ letterSpacing: "{core.font.tracking.tight}",
1045
+ fontOpticalSizing: "{core.font.optical.auto}"
1046
+ }
1047
+ },
1048
+ headline: {
1049
+ lg: {
1050
+ fontFamily: "{core.font.family.sans}",
1051
+ fontSize: "{core.font.scale.display.3}",
1052
+ fontWeight: "{core.font.weight.semibold}",
1053
+ lineHeight: "{core.font.leading.snug}",
1054
+ letterSpacing: "{core.font.tracking.normal}",
1055
+ fontOpticalSizing: "{core.font.optical.auto}"
1056
+ },
1057
+ md: {
1058
+ fontFamily: "{core.font.family.sans}",
1059
+ fontSize: "{core.font.scale.display.2}",
1060
+ fontWeight: "{core.font.weight.semibold}",
1061
+ lineHeight: "{core.font.leading.snug}",
1062
+ letterSpacing: "{core.font.tracking.normal}",
1063
+ fontOpticalSizing: "{core.font.optical.auto}"
1064
+ },
1065
+ sm: {
1066
+ fontFamily: "{core.font.family.sans}",
1067
+ fontSize: "{core.font.scale.display.1}",
1068
+ fontWeight: "{core.font.weight.semibold}",
1069
+ lineHeight: "{core.font.leading.snug}",
1070
+ letterSpacing: "{core.font.tracking.normal}",
1071
+ fontOpticalSizing: "{core.font.optical.auto}"
1072
+ }
1073
+ },
1074
+ title: {
1075
+ lg: {
1076
+ fontFamily: "{core.font.family.sans}",
1077
+ fontSize: "{core.font.scale.text.6}",
1078
+ fontWeight: "{core.font.weight.semibold}",
1079
+ lineHeight: "{core.font.leading.snug}",
1080
+ letterSpacing: "{core.font.tracking.normal}",
1081
+ fontOpticalSizing: "{core.font.optical.auto}"
1082
+ },
1083
+ md: {
1084
+ fontFamily: "{core.font.family.sans}",
1085
+ fontSize: "{core.font.scale.text.5}",
1086
+ fontWeight: "{core.font.weight.semibold}",
1087
+ lineHeight: "{core.font.leading.snug}",
1088
+ letterSpacing: "{core.font.tracking.normal}",
1089
+ fontOpticalSizing: "{core.font.optical.auto}"
1090
+ },
1091
+ sm: {
1092
+ fontFamily: "{core.font.family.sans}",
1093
+ fontSize: "{core.font.scale.text.4}",
1094
+ fontWeight: "{core.font.weight.medium}",
1095
+ lineHeight: "{core.font.leading.snug}",
1096
+ letterSpacing: "{core.font.tracking.normal}",
1097
+ fontOpticalSizing: "{core.font.optical.auto}"
1098
+ }
1099
+ },
1100
+ body: {
1101
+ lg: {
1102
+ fontFamily: "{core.font.family.sans}",
1103
+ fontSize: "{core.font.scale.text.4}",
1104
+ fontWeight: "{core.font.weight.regular}",
1105
+ lineHeight: "{core.font.leading.normal}",
1106
+ letterSpacing: "{core.font.tracking.normal}",
1107
+ fontOpticalSizing: "{core.font.optical.auto}"
1108
+ },
1109
+ md: {
1110
+ fontFamily: "{core.font.family.sans}",
1111
+ fontSize: "{core.font.scale.text.3}",
1112
+ fontWeight: "{core.font.weight.regular}",
1113
+ lineHeight: "{core.font.leading.normal}",
1114
+ letterSpacing: "{core.font.tracking.normal}",
1115
+ fontOpticalSizing: "{core.font.optical.auto}"
1116
+ },
1117
+ sm: {
1118
+ fontFamily: "{core.font.family.sans}",
1119
+ fontSize: "{core.font.scale.text.2}",
1120
+ fontWeight: "{core.font.weight.regular}",
1121
+ lineHeight: "{core.font.leading.normal}",
1122
+ letterSpacing: "{core.font.tracking.normal}",
1123
+ fontOpticalSizing: "{core.font.optical.auto}"
1124
+ }
1125
+ },
1126
+ label: {
1127
+ lg: {
1128
+ fontFamily: "{core.font.family.sans}",
1129
+ fontSize: "{core.font.scale.text.3}",
1130
+ fontWeight: "{core.font.weight.medium}",
1131
+ lineHeight: "{core.font.leading.snug}",
1132
+ letterSpacing: "{core.font.tracking.normal}",
1133
+ fontOpticalSizing: "{core.font.optical.auto}"
1134
+ },
1135
+ md: {
1136
+ fontFamily: "{core.font.family.sans}",
1137
+ fontSize: "{core.font.scale.text.2}",
1138
+ fontWeight: "{core.font.weight.medium}",
1139
+ lineHeight: "{core.font.leading.snug}",
1140
+ letterSpacing: "{core.font.tracking.normal}",
1141
+ fontOpticalSizing: "{core.font.optical.auto}"
1142
+ },
1143
+ sm: {
1144
+ fontFamily: "{core.font.family.sans}",
1145
+ fontSize: "{core.font.scale.text.1}",
1146
+ fontWeight: "{core.font.weight.medium}",
1147
+ lineHeight: "{core.font.leading.snug}",
1148
+ letterSpacing: "{core.font.tracking.wide}",
1149
+ fontOpticalSizing: "{core.font.optical.auto}"
1150
+ }
1151
+ },
1152
+ code: {
1153
+ md: {
1154
+ fontFamily: "{core.font.family.mono}",
1155
+ fontSize: "{core.font.scale.text.2}",
1156
+ fontWeight: "{core.font.weight.regular}",
1157
+ lineHeight: "{core.font.leading.normal}",
1158
+ letterSpacing: "{core.font.tracking.normal}",
1159
+ fontVariantNumeric: "{core.font.numeric.tabular}"
1160
+ },
1161
+ sm: {
1162
+ fontFamily: "{core.font.family.mono}",
1163
+ fontSize: "{core.font.scale.text.1}",
1164
+ fontWeight: "{core.font.weight.regular}",
1165
+ lineHeight: "{core.font.leading.normal}",
1166
+ letterSpacing: "{core.font.tracking.normal}",
1167
+ fontVariantNumeric: "{core.font.numeric.tabular}"
1168
+ }
1169
+ }
1170
+ },
1171
+ // -- Spacing ------------------------------------------------------------
1172
+ // Grammar: {pattern}.{context}.{step?}
1173
+ spacing: {
1174
+ inset: {
1175
+ // Mapped to the documented defaults from spacing.md. Medium-high
1176
+ // density is delivered by `core.sizing.hit.fine.*` (40px base)
1177
+ // combined with the spacing engine clamp — not by tightening
1178
+ // inset.control, which previously caused cramped vertical padding
1179
+ // (~4px) when content grew beyond `min-height: hit.base`.
1180
+ control: {
1181
+ sm: "{core.spacing.2}",
1182
+ md: "{core.spacing.3}",
1183
+ lg: "{core.spacing.4}"
1184
+ },
1185
+ // Surfaces breathe more than controls; the invariant
1186
+ // inset.surface.X ≥ inset.control.X is preserved.
1187
+ surface: {
1188
+ sm: "{core.spacing.3}",
1189
+ md: "{core.spacing.4}",
1190
+ lg: "{core.spacing.6}"
1191
+ }
1192
+ },
1193
+ gap: {
1194
+ stack: {
1195
+ xs: "{core.spacing.2}",
1196
+ sm: "{core.spacing.3}",
1197
+ md: "{core.spacing.4}",
1198
+ lg: "{core.spacing.6}",
1199
+ xl: "{core.spacing.8}"
1200
+ },
1201
+ inline: {
1202
+ xs: "{core.spacing.1}",
1203
+ sm: "{core.spacing.2}",
1204
+ md: "{core.spacing.3}",
1205
+ lg: "{core.spacing.4}",
1206
+ xl: "{core.spacing.6}"
1207
+ }
1208
+ },
1209
+ gutter: {
1210
+ page: "clamp({core.spacing.4}, {core.spacing.6}, {core.spacing.12})",
1211
+ section: "clamp({core.spacing.3}, {core.spacing.4}, {core.spacing.12})"
1212
+ },
1213
+ separation: {
1214
+ interactive: {
1215
+ min: "clamp(8px, {core.spacing.2}, 12px)"
1216
+ }
1217
+ }
1218
+ },
1219
+ // -- Sizing -------------------------------------------------------------
1220
+ // Grammar: {family}.{stepOrProperty}
1221
+ sizing: {
1222
+ hit: {
1223
+ min: "{core.sizing.hit.fine.min}",
1224
+ base: "{core.sizing.hit.fine.base}",
1225
+ prominent: "{core.sizing.hit.fine.prominent}"
1226
+ },
1227
+ icon: {
1228
+ sm: "{core.sizing.ramp.ui.2}",
1229
+ md: "{core.sizing.ramp.ui.3}",
1230
+ lg: "{core.sizing.ramp.ui.4}"
1231
+ },
1232
+ identity: {
1233
+ sm: "{core.sizing.ramp.ui.5}",
1234
+ md: "{core.sizing.ramp.ui.6}",
1235
+ lg: "{core.sizing.ramp.ui.7}",
1236
+ xl: "{core.sizing.ramp.ui.8}"
1237
+ },
1238
+ measure: {
1239
+ reading: "clamp(45ch, 60ch, 75ch)"
1240
+ },
1241
+ surface: {
1242
+ maxWidth: "{core.sizing.ramp.layout.5}"
1243
+ },
1244
+ viewport: {
1245
+ height: {
1246
+ full: "{core.sizing.viewport.height.full}"
1247
+ },
1248
+ width: {
1249
+ full: "{core.sizing.viewport.width.full}"
1250
+ }
1251
+ }
1252
+ },
1253
+ // -- Radii --------------------------------------------------------------
1254
+ radii: {
1255
+ control: "{core.radii.md}",
1256
+ surface: "{core.radii.lg}",
1257
+ round: "{core.radii.full}"
1258
+ },
1259
+ // -- Borders ------------------------------------------------------------
1260
+ border: {
1261
+ divider: {
1262
+ width: "{core.border.width.default}",
1263
+ style: "{core.border.style.solid}"
1264
+ },
1265
+ outline: {
1266
+ surface: {
1267
+ width: "{core.border.width.default}",
1268
+ style: "{core.border.style.solid}"
1269
+ },
1270
+ control: {
1271
+ width: "{core.border.width.default}",
1272
+ style: "{core.border.style.solid}"
1273
+ },
1274
+ selected: {
1275
+ width: "{core.border.width.selected}",
1276
+ style: "{core.border.style.solid}"
1277
+ }
1278
+ }
1279
+ },
1280
+ // -- Focus --------------------------------------------------------------
1281
+ focus: {
1282
+ ring: {
1283
+ width: "{core.border.width.focused}",
1284
+ style: "{core.border.style.solid}",
1285
+ // References the semantic accent focused border so mode overrides
1286
+ // remap focus color automatically (e.g. brand.300 in dark mode).
1287
+ color: "{semantic.colors.action.accent.border.focused}"
1288
+ }
1289
+ },
1290
+ // -- Overlay ------------------------------------------------------------
1291
+ overlay: {
1292
+ // Full modal backdrop color. Alpha is sourced from semantic.opacity.scrim
1293
+ // so both tokens stay in sync across themes and modes.
1294
+ // RawValue rationale: rgba() composing a token ref cannot be expressed
1295
+ // as a single TokenRef — see model.md §8 RawValue inventory.
1296
+ scrim: "rgba(0, 0, 0, {semantic.opacity.scrim})"
1297
+ },
1298
+ // -- Opacity ------------------------------------------------------------
1299
+ opacity: {
1300
+ scrim: "{core.opacity.50}",
1301
+ loading: "{core.opacity.50}",
1302
+ disabled: "{core.opacity.50}"
1303
+ },
1304
+ // -- Motion -------------------------------------------------------------
1305
+ motion: {
1306
+ feedback: {
1307
+ duration: "{core.motion.duration.sm}",
1308
+ easing: "{core.motion.easing.standard}"
1309
+ },
1310
+ transition: {
1311
+ enter: {
1312
+ duration: "{core.motion.duration.md}",
1313
+ easing: "{core.motion.easing.enter}"
1314
+ },
1315
+ exit: {
1316
+ duration: "{core.motion.duration.sm}",
1317
+ easing: "{core.motion.easing.exit}"
1318
+ }
1319
+ },
1320
+ emphasis: {
1321
+ duration: "{core.motion.duration.lg}",
1322
+ easing: "{core.motion.easing.standard}"
1323
+ },
1324
+ decorative: {
1325
+ duration: "{core.motion.duration.xl}",
1326
+ easing: "{core.motion.easing.linear}"
1327
+ }
1328
+ },
1329
+ // -- Z-Index ------------------------------------------------------------
1330
+ zIndex: {
1331
+ layer: {
1332
+ base: "{core.zIndex.level.0}",
1333
+ sticky: "{core.zIndex.level.1}",
1334
+ overlay: "{core.zIndex.level.2}",
1335
+ blocking: "{core.zIndex.level.3}",
1336
+ transient: "{core.zIndex.level.4}"
1337
+ }
1338
+ }
1339
+ }
1340
+ };
1341
+ var darkAlternate = {
1342
+ semantic: {
1343
+ colors: {
1344
+ action: {
1345
+ primary: {
1346
+ // White button on dark surface — inverted authority for dark contexts.
1347
+ // Contrast: neutral.900 text on neutral.0 → ~19:1 ✓
1348
+ background: {
1349
+ default: "{core.colors.neutral.0}",
1350
+ hover: "{core.colors.neutral.100}",
1351
+ active: "{core.colors.neutral.200}",
1352
+ pressed: "{core.colors.neutral.200}",
1353
+ expanded: "{core.colors.neutral.100}",
1354
+ disabled: "{core.colors.neutral.700}",
1355
+ droptarget: "{core.colors.neutral.700}"
1356
+ },
1357
+ border: {
1358
+ default: "{core.colors.neutral.0}",
1359
+ hover: "{core.colors.neutral.100}",
1360
+ active: "{core.colors.neutral.200}",
1361
+ focused: "{core.colors.brand.300}",
1362
+ disabled: "{core.colors.neutral.700}"
1363
+ },
1364
+ text: {
1365
+ default: "{core.colors.neutral.900}",
1366
+ disabled: "{core.colors.neutral.500}",
1367
+ // droptarget bg is now neutral.700 (dark) — neutral.0 required for contrast
1368
+ droptarget: "{core.colors.neutral.0}"
1369
+ }
1370
+ },
1371
+ secondary: {
1372
+ background: {
1373
+ default: "{core.colors.neutral.700}",
1374
+ hover: "{core.colors.neutral.500}",
1375
+ active: "{core.colors.neutral.300}",
1376
+ disabled: "{core.colors.neutral.700}",
1377
+ droptarget: "{core.colors.neutral.700}",
1378
+ expanded: "{core.colors.neutral.500}"
1379
+ },
1380
+ border: {
1381
+ default: "{core.colors.neutral.500}",
1382
+ hover: "{core.colors.neutral.300}",
1383
+ active: "{core.colors.neutral.100}",
1384
+ focused: "{core.colors.brand.500}",
1385
+ disabled: "{core.colors.neutral.700}"
1386
+ },
1387
+ text: {
1388
+ default: "{core.colors.neutral.50}",
1389
+ disabled: "{core.colors.neutral.500}"
1390
+ }
1391
+ },
1392
+ muted: {
1393
+ background: {
1394
+ default: "{core.colors.neutral.700}",
1395
+ hover: "{core.colors.neutral.500}",
1396
+ active: "{core.colors.neutral.500}",
1397
+ disabled: "{core.colors.neutral.700}",
1398
+ droptarget: "{core.colors.neutral.700}",
1399
+ pressed: "{core.colors.neutral.700}",
1400
+ expanded: "{core.colors.neutral.500}"
1401
+ },
1402
+ border: {
1403
+ default: "{core.colors.neutral.500}",
1404
+ focused: "{core.colors.brand.500}",
1405
+ disabled: "{core.colors.neutral.700}"
1406
+ },
1407
+ text: {
1408
+ default: "{core.colors.neutral.50}",
1409
+ disabled: "{core.colors.neutral.500}",
1410
+ // neutral.900 text on neutral.700 dark bg → ~3:1 — fails WCAG AA
1411
+ hover: "{core.colors.neutral.0}",
1412
+ active: "{core.colors.neutral.0}",
1413
+ pressed: "{core.colors.neutral.0}",
1414
+ expanded: "{core.colors.neutral.0}"
1415
+ }
1416
+ },
1417
+ // negative: red.500 bg/border + neutral.0 text remain valid on dark
1418
+ // pages (vivid destructive colour). Only state-specific overrides.
1419
+ negative: {
1420
+ background: {
1421
+ disabled: "{core.colors.neutral.700}",
1422
+ droptarget: "{core.colors.neutral.700}"
1423
+ },
1424
+ border: {
1425
+ disabled: "{core.colors.neutral.700}"
1426
+ },
1427
+ text: {
1428
+ // droptarget bg is now neutral.700 (dark) — neutral.0 required for contrast
1429
+ droptarget: "{core.colors.neutral.0}"
1430
+ }
1431
+ },
1432
+ // accent: brand.500 bg/border + neutral.0 text remain valid on dark
1433
+ // surface. Only remap states that use light-mode fills that fail on dark.
1434
+ accent: {
1435
+ background: {
1436
+ disabled: "{core.colors.neutral.700}",
1437
+ droptarget: "{core.colors.brand.900}"
1438
+ },
1439
+ border: {
1440
+ focused: "{core.colors.brand.300}",
1441
+ disabled: "{core.colors.neutral.700}"
1442
+ },
1443
+ text: {
1444
+ droptarget: "{core.colors.neutral.0}"
1445
+ }
1446
+ }
1447
+ },
1448
+ input: {
1449
+ primary: {
1450
+ background: {
1451
+ default: "{core.colors.neutral.700}",
1452
+ hover: "{core.colors.neutral.500}",
1453
+ active: "{core.colors.neutral.500}",
1454
+ disabled: "{core.colors.neutral.900}",
1455
+ selected: "{core.colors.brand.700}",
1456
+ droptarget: "{core.colors.neutral.700}",
1457
+ pressed: "{core.colors.neutral.500}",
1458
+ expanded: "{core.colors.neutral.500}"
1459
+ },
1460
+ border: {
1461
+ default: "{core.colors.neutral.500}",
1462
+ hover: "{core.colors.neutral.300}",
1463
+ focused: "{core.colors.brand.500}",
1464
+ disabled: "{core.colors.neutral.700}"
1465
+ },
1466
+ text: {
1467
+ default: "{core.colors.neutral.0}",
1468
+ disabled: "{core.colors.neutral.500}"
1469
+ }
1470
+ },
1471
+ // input.secondary: lower-emphasis field, matches primary dark values since both
1472
+ // render on a dark page. base neutral.0 default fails on dark — full override.
1473
+ secondary: {
1474
+ background: {
1475
+ default: "{core.colors.neutral.700}",
1476
+ hover: "{core.colors.neutral.500}",
1477
+ active: "{core.colors.neutral.500}",
1478
+ disabled: "{core.colors.neutral.900}",
1479
+ selected: "{core.colors.brand.700}",
1480
+ droptarget: "{core.colors.neutral.700}",
1481
+ pressed: "{core.colors.neutral.500}",
1482
+ expanded: "{core.colors.neutral.500}"
1483
+ },
1484
+ border: {
1485
+ default: "{core.colors.neutral.500}",
1486
+ hover: "{core.colors.neutral.300}",
1487
+ active: "{core.colors.brand.500}",
1488
+ focused: "{core.colors.brand.500}",
1489
+ disabled: "{core.colors.neutral.700}",
1490
+ selected: "{core.colors.brand.500}",
1491
+ checked: "{core.colors.brand.500}",
1492
+ indeterminate: "{core.colors.brand.300}",
1493
+ pressed: "{core.colors.neutral.300}",
1494
+ expanded: "{core.colors.brand.500}"
1495
+ },
1496
+ text: {
1497
+ default: "{core.colors.neutral.0}",
1498
+ disabled: "{core.colors.neutral.500}",
1499
+ checked: "{core.colors.neutral.0}"
1500
+ }
1501
+ },
1502
+ negative: {
1503
+ background: {
1504
+ default: "{core.colors.neutral.900}",
1505
+ disabled: "{core.colors.neutral.700}"
1506
+ },
1507
+ border: {
1508
+ default: "{core.colors.red.500}"
1509
+ },
1510
+ text: {
1511
+ default: "{core.colors.red.300}"
1512
+ }
1513
+ },
1514
+ positive: {
1515
+ background: {
1516
+ default: "{core.colors.neutral.900}",
1517
+ disabled: "{core.colors.neutral.700}"
1518
+ },
1519
+ border: {
1520
+ default: "{core.colors.green.500}"
1521
+ },
1522
+ text: {
1523
+ default: "{core.colors.green.300}"
1524
+ }
1525
+ },
1526
+ caution: {
1527
+ background: {
1528
+ default: "{core.colors.neutral.900}",
1529
+ disabled: "{core.colors.neutral.700}"
1530
+ },
1531
+ border: {
1532
+ default: "{core.colors.yellow.500}"
1533
+ },
1534
+ text: {
1535
+ default: "{core.colors.yellow.300}"
1536
+ }
1537
+ },
1538
+ muted: {
1539
+ background: {
1540
+ default: "{core.colors.neutral.700}",
1541
+ active: "{core.colors.neutral.500}",
1542
+ selected: "{core.colors.neutral.500}"
1543
+ },
1544
+ border: {
1545
+ default: "{core.colors.neutral.500}",
1546
+ active: "{core.colors.neutral.300}",
1547
+ selected: "{core.colors.neutral.300}"
1548
+ },
1549
+ text: {
1550
+ default: "{core.colors.neutral.300}"
1551
+ }
1552
+ }
1553
+ },
1554
+ informational: {
1555
+ primary: {
1556
+ background: {
1557
+ default: "{core.colors.neutral.900}",
1558
+ hover: "{core.colors.neutral.700}",
1559
+ active: "{core.colors.neutral.700}",
1560
+ disabled: "{core.colors.neutral.700}",
1561
+ selected: "{core.colors.brand.900}",
1562
+ droptarget: "{core.colors.neutral.700}",
1563
+ visited: "{core.colors.neutral.700}"
1564
+ },
1565
+ border: {
1566
+ default: "{core.colors.neutral.700}"
1567
+ },
1568
+ text: {
1569
+ default: "{core.colors.neutral.0}",
1570
+ // neutral.700 on neutral.900 dark bg → ~2:1 — fails WCAG AA
1571
+ visited: "{core.colors.neutral.300}"
1572
+ }
1573
+ },
1574
+ secondary: {
1575
+ background: {
1576
+ default: "{core.colors.neutral.700}",
1577
+ hover: "{core.colors.neutral.500}",
1578
+ active: "{core.colors.neutral.500}",
1579
+ disabled: "{core.colors.neutral.700}",
1580
+ selected: "{core.colors.brand.900}",
1581
+ droptarget: "{core.colors.neutral.700}",
1582
+ visited: "{core.colors.neutral.700}"
1583
+ },
1584
+ border: {
1585
+ default: "{core.colors.neutral.700}"
1586
+ },
1587
+ text: {
1588
+ default: "{core.colors.neutral.50}",
1589
+ // neutral.900 on neutral.700 dark bg → ~3:1 — fails WCAG AA
1590
+ active: "{core.colors.neutral.0}",
1591
+ // neutral.700 on neutral.700 → 1:1 — invisible
1592
+ visited: "{core.colors.neutral.300}"
1593
+ }
1594
+ },
1595
+ muted: {
1596
+ background: {
1597
+ default: "{core.colors.neutral.500}",
1598
+ hover: "{core.colors.neutral.300}",
1599
+ selected: "{core.colors.neutral.300}",
1600
+ droptarget: "{core.colors.neutral.300}"
1601
+ },
1602
+ border: {
1603
+ default: "{core.colors.neutral.700}"
1604
+ },
1605
+ text: {
1606
+ default: "{core.colors.neutral.300}"
1607
+ }
1608
+ },
1609
+ positive: {
1610
+ background: {
1611
+ default: "{core.colors.neutral.900}",
1612
+ disabled: "{core.colors.neutral.700}"
1613
+ },
1614
+ border: {
1615
+ default: "{core.colors.green.500}"
1616
+ },
1617
+ text: {
1618
+ default: "{core.colors.green.300}"
1619
+ }
1620
+ },
1621
+ caution: {
1622
+ background: {
1623
+ default: "{core.colors.neutral.900}",
1624
+ disabled: "{core.colors.neutral.700}"
1625
+ },
1626
+ border: {
1627
+ default: "{core.colors.yellow.500}"
1628
+ },
1629
+ text: {
1630
+ default: "{core.colors.yellow.300}"
1631
+ }
1632
+ },
1633
+ negative: {
1634
+ background: {
1635
+ default: "{core.colors.neutral.900}",
1636
+ disabled: "{core.colors.neutral.700}"
1637
+ },
1638
+ border: {
1639
+ default: "{core.colors.red.500}"
1640
+ },
1641
+ text: {
1642
+ default: "{core.colors.red.300}"
1643
+ }
1644
+ },
1645
+ // Full remap: base brand.50/100/200 backgrounds are near-white and fail on dark pages.
1646
+ accent: {
1647
+ background: {
1648
+ default: "{core.colors.brand.900}",
1649
+ hover: "{core.colors.brand.700}",
1650
+ active: "{core.colors.brand.700}",
1651
+ disabled: "{core.colors.neutral.700}"
1652
+ },
1653
+ border: {
1654
+ default: "{core.colors.brand.300}",
1655
+ hover: "{core.colors.brand.400}",
1656
+ active: "{core.colors.brand.400}",
1657
+ // brand.100 for focused — must differ from default (brand.300) for state distinguishability
1658
+ focused: "{core.colors.brand.100}",
1659
+ disabled: "{core.colors.neutral.700}",
1660
+ selected: "{core.colors.brand.400}"
1661
+ },
1662
+ text: {
1663
+ // brand.700 on neutral.900 bg → ~1.3:1 — invisible; use brand.300
1664
+ default: "{core.colors.brand.300}",
1665
+ hover: "{core.colors.brand.100}",
1666
+ active: "{core.colors.brand.100}",
1667
+ visited: "{core.colors.brand.300}"
1668
+ }
1669
+ }
1670
+ },
1671
+ feedback: {
1672
+ primary: {
1673
+ background: {
1674
+ default: "{core.colors.neutral.700}"
1675
+ },
1676
+ border: {
1677
+ default: "{core.colors.neutral.500}"
1678
+ },
1679
+ text: {
1680
+ default: "{core.colors.neutral.0}"
1681
+ }
1682
+ },
1683
+ muted: {
1684
+ background: {
1685
+ default: "{core.colors.neutral.700}"
1686
+ },
1687
+ border: {
1688
+ default: "{core.colors.neutral.500}"
1689
+ },
1690
+ text: {
1691
+ default: "{core.colors.neutral.300}"
1692
+ }
1693
+ },
1694
+ positive: {
1695
+ background: {
1696
+ default: "{core.colors.neutral.900}"
1697
+ },
1698
+ border: {
1699
+ default: "{core.colors.green.500}"
1700
+ },
1701
+ text: {
1702
+ default: "{core.colors.green.300}"
1703
+ }
1704
+ },
1705
+ caution: {
1706
+ background: {
1707
+ default: "{core.colors.neutral.900}"
1708
+ },
1709
+ border: {
1710
+ default: "{core.colors.yellow.500}"
1711
+ },
1712
+ text: {
1713
+ default: "{core.colors.yellow.300}"
1714
+ }
1715
+ },
1716
+ negative: {
1717
+ background: {
1718
+ default: "{core.colors.neutral.900}"
1719
+ },
1720
+ border: {
1721
+ default: "{core.colors.red.500}"
1722
+ },
1723
+ text: {
1724
+ default: "{core.colors.red.300}"
1725
+ }
1726
+ }
1727
+ },
1728
+ navigation: {
1729
+ // Stacked-surface separation in dark mode.
1730
+ // The page background and informational.primary.background.default both
1731
+ // resolve to neutral.900 here. Per the prescribed pattern (see
1732
+ // colors.md → "Stacking informational surfaces"), separation is paid in
1733
+ // elevation + border + theme-side step displacement, never in colour.
1734
+ // navigation.primary applies (3): hover/active/current/expanded shift to
1735
+ // neutral.700 so a nav item reads as a distinct affordance against the
1736
+ // page surface even with no elevation of its own.
1737
+ primary: {
1738
+ // Inline link on dark surfaces: transparent bg, brand.300 text.
1739
+ // Contrast: brand.300 (#60a5fa) on neutral.900 (#0f172a) → ~6.8:1 ✓
1740
+ background: {
1741
+ default: "{core.colors.neutral.900}",
1742
+ hover: "{core.colors.neutral.700}",
1743
+ active: "{core.colors.neutral.700}",
1744
+ disabled: "{core.colors.neutral.900}",
1745
+ current: "{core.colors.neutral.700}",
1746
+ visited: "{core.colors.neutral.900}",
1747
+ expanded: "{core.colors.neutral.700}"
1748
+ },
1749
+ border: {
1750
+ default: "{core.colors.neutral.900}",
1751
+ focused: "{core.colors.brand.400}"
1752
+ },
1753
+ text: {
1754
+ default: "{core.colors.brand.300}",
1755
+ hover: "{core.colors.brand.100}",
1756
+ active: "{core.colors.brand.100}",
1757
+ disabled: "{core.colors.neutral.500}",
1758
+ current: "{core.colors.brand.100}",
1759
+ visited: "{core.colors.neutral.300}",
1760
+ expanded: "{core.colors.brand.100}"
1761
+ }
1762
+ },
1763
+ secondary: {
1764
+ background: {
1765
+ default: "{core.colors.neutral.900}",
1766
+ hover: "{core.colors.neutral.700}",
1767
+ active: "{core.colors.neutral.700}",
1768
+ selected: "{core.colors.brand.900}",
1769
+ current: "{core.colors.brand.900}",
1770
+ visited: "{core.colors.neutral.900}",
1771
+ expanded: "{core.colors.neutral.700}",
1772
+ disabled: "{core.colors.neutral.700}",
1773
+ droptarget: "{core.colors.neutral.700}"
1774
+ },
1775
+ border: {
1776
+ default: "{core.colors.neutral.700}",
1777
+ hover: "{core.colors.neutral.500}",
1778
+ active: "{core.colors.neutral.500}",
1779
+ focused: "{core.colors.brand.400}",
1780
+ selected: "{core.colors.brand.500}",
1781
+ current: "{core.colors.brand.500}"
1782
+ },
1783
+ text: {
1784
+ default: "{core.colors.neutral.300}",
1785
+ hover: "{core.colors.neutral.0}",
1786
+ disabled: "{core.colors.neutral.500}",
1787
+ selected: "{core.colors.brand.300}",
1788
+ current: "{core.colors.brand.300}",
1789
+ visited: "{core.colors.neutral.300}",
1790
+ expanded: "{core.colors.neutral.50}"
1791
+ }
1792
+ },
1793
+ accent: {
1794
+ background: {
1795
+ default: "{core.colors.neutral.900}",
1796
+ hover: "{core.colors.neutral.700}",
1797
+ active: "{core.colors.neutral.700}",
1798
+ selected: "{core.colors.brand.700}",
1799
+ current: "{core.colors.brand.700}",
1800
+ expanded: "{core.colors.neutral.700}",
1801
+ disabled: "{core.colors.neutral.700}"
1802
+ },
1803
+ border: {
1804
+ default: "{core.colors.brand.500}",
1805
+ hover: "{core.colors.brand.400}",
1806
+ active: "{core.colors.brand.300}",
1807
+ focused: "{core.colors.brand.400}",
1808
+ selected: "{core.colors.brand.400}",
1809
+ current: "{core.colors.brand.400}"
1810
+ },
1811
+ text: {
1812
+ default: "{core.colors.brand.300}",
1813
+ hover: "{core.colors.brand.100}",
1814
+ disabled: "{core.colors.neutral.500}",
1815
+ selected: "{core.colors.neutral.0}",
1816
+ current: "{core.colors.neutral.0}",
1817
+ visited: "{core.colors.brand.500}",
1818
+ expanded: "{core.colors.brand.200}"
1819
+ }
1820
+ },
1821
+ muted: {
1822
+ background: {
1823
+ default: "{core.colors.neutral.900}",
1824
+ hover: "{core.colors.neutral.700}",
1825
+ active: "{core.colors.neutral.700}",
1826
+ selected: "{core.colors.neutral.700}",
1827
+ current: "{core.colors.neutral.700}",
1828
+ expanded: "{core.colors.neutral.700}",
1829
+ disabled: "{core.colors.neutral.700}"
1830
+ },
1831
+ border: {
1832
+ default: "{core.colors.neutral.700}",
1833
+ hover: "{core.colors.neutral.500}",
1834
+ active: "{core.colors.neutral.500}",
1835
+ focused: "{core.colors.brand.400}",
1836
+ selected: "{core.colors.neutral.300}",
1837
+ current: "{core.colors.brand.500}"
1838
+ },
1839
+ text: {
1840
+ default: "{core.colors.neutral.500}",
1841
+ hover: "{core.colors.neutral.300}",
1842
+ active: "{core.colors.neutral.0}",
1843
+ disabled: "{core.colors.neutral.700}",
1844
+ selected: "{core.colors.neutral.0}",
1845
+ current: "{core.colors.brand.300}",
1846
+ visited: "{core.colors.neutral.700}",
1847
+ expanded: "{core.colors.neutral.300}"
1848
+ }
1849
+ }
1850
+ }
1851
+ },
1852
+ elevation: {
1853
+ surface: {
1854
+ flat: "{core.elevation.emphatic.0}",
1855
+ raised: "{core.elevation.emphatic.2}",
1856
+ overlay: "{core.elevation.emphatic.3}",
1857
+ blocking: "{core.elevation.emphatic.4}"
1858
+ }
1859
+ }
1860
+ }
1861
+ };
1862
+
1863
+ // src/createTheme.ts
1864
+ var buildTheme = /* @__PURE__ */__name(({
1865
+ base = baseTheme,
1866
+ overrides = {}
1867
+ } = {}) => {
1868
+ const merged = deepMerge(base, overrides);
1869
+ if (process.env.NODE_ENV !== "production") {
1870
+ validateRefs(merged);
1871
+ }
1872
+ return structuredClone(merged);
1873
+ }, "buildTheme");
1874
+ var resolveAlternate = /* @__PURE__ */__name((alternate, parentBundle) => {
1875
+ if (alternate === null) return void 0;
1876
+ if (alternate !== void 0) return alternate;
1877
+ return parentBundle?.alternate ?? darkAlternate;
1878
+ }, "resolveAlternate");
1879
+ var createTheme = /* @__PURE__ */__name(({
1880
+ extends: parentBundle,
1881
+ baseMode,
1882
+ base,
1883
+ overrides,
1884
+ alternate
1885
+ } = {}) => {
1886
+ const resolvedBase = base ?? parentBundle?.base;
1887
+ const resolvedBaseMode = baseMode ?? parentBundle?.baseMode ?? "light";
1888
+ const resolvedAlternate = resolveAlternate(alternate, parentBundle);
1889
+ return {
1890
+ baseMode: resolvedBaseMode,
1891
+ base: buildTheme({
1892
+ base: resolvedBase,
1893
+ overrides
1894
+ }),
1895
+ alternate: resolvedAlternate
1896
+ };
1897
+ }, "createTheme");
1898
+ export { baseTheme, darkAlternate, buildTheme, createTheme };