@mindlogic-ai/logician-ui 3.1.0-alpha.8 → 3.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 (42) hide show
  1. package/dist/components/InfoSprinkle/InfoSprinkle.d.ts +1 -1
  2. package/dist/components/InfoSprinkle/InfoSprinkle.d.ts.map +1 -1
  3. package/dist/components/InfoSprinkle/InfoSprinkle.js +25 -2
  4. package/dist/components/InfoSprinkle/InfoSprinkle.js.map +1 -1
  5. package/dist/components/InfoSprinkle/InfoSprinkle.mjs +25 -2
  6. package/dist/components/InfoSprinkle/InfoSprinkle.mjs.map +1 -1
  7. package/dist/components/SegmentedControl/SegmentedControl.d.ts.map +1 -1
  8. package/dist/components/SegmentedControl/SegmentedControl.js +20 -4
  9. package/dist/components/SegmentedControl/SegmentedControl.js.map +1 -1
  10. package/dist/components/SegmentedControl/SegmentedControl.mjs +20 -4
  11. package/dist/components/SegmentedControl/SegmentedControl.mjs.map +1 -1
  12. package/dist/hooks/useHasHover.d.ts +13 -0
  13. package/dist/hooks/useHasHover.d.ts.map +1 -0
  14. package/dist/hooks/useHasHover.js +34 -0
  15. package/dist/hooks/useHasHover.js.map +1 -0
  16. package/dist/hooks/useHasHover.mjs +29 -0
  17. package/dist/hooks/useHasHover.mjs.map +1 -0
  18. package/dist/index.d.ts +1 -0
  19. package/dist/index.d.ts.map +1 -1
  20. package/dist/index.js +2 -0
  21. package/dist/index.js.map +1 -1
  22. package/dist/index.mjs +1 -0
  23. package/dist/index.mjs.map +1 -1
  24. package/dist/theme/colors.d.ts +196 -44
  25. package/dist/theme/colors.d.ts.map +1 -1
  26. package/dist/theme/colors.js +184 -22
  27. package/dist/theme/colors.js.map +1 -1
  28. package/dist/theme/colors.mjs +184 -22
  29. package/dist/theme/colors.mjs.map +1 -1
  30. package/dist/theme/global.d.ts.map +1 -1
  31. package/dist/theme/global.js +30 -2
  32. package/dist/theme/global.js.map +1 -1
  33. package/dist/theme/global.mjs +30 -2
  34. package/dist/theme/global.mjs.map +1 -1
  35. package/package.json +1 -1
  36. package/src/components/InfoSprinkle/InfoSprinkle.tsx +32 -0
  37. package/src/components/SegmentedControl/SegmentedControl.tsx +21 -4
  38. package/src/hooks/useHasHover.ts +32 -0
  39. package/src/index.ts +1 -0
  40. package/src/theme/SemanticTokens.mdx +61 -7
  41. package/src/theme/colors.ts +216 -26
  42. package/src/theme/global.ts +31 -2
@@ -33,32 +33,6 @@
33
33
  * @see https://www.w3.org/TR/WCAG21/#contrast-minimum
34
34
  * @version 3.0.0
35
35
  */
36
- /**
37
- * Semantic color tokens that map primitive colors to UI intent.
38
- *
39
- * Use these tokens in components instead of raw color values:
40
- * - `primary.*`: Buttons, links, focus states
41
- * - `secondary.*`: Accent elements, highlights
42
- * - `success.*`: Success messages, confirmations
43
- * - `warning.*`: Warning messages, caution states
44
- * - `danger.*`: Error messages, destructive actions
45
- *
46
- * Each category includes:
47
- * - `lightest`: Lightest backgrounds (ghost states, very subtle fills)
48
- * - `extralight`: Extra-light backgrounds (badges, subtle fills)
49
- * - `lighter`: Light backgrounds (toast backgrounds, subtle fills)
50
- * - `light`: Medium backgrounds (hover states, medium fills)
51
- * - `main`: Primary color (buttons, text, icons)
52
- * - `dark`: Dark variant (text on light backgrounds)
53
- * - `darker`: Darkest variant (high-contrast text)
54
- *
55
- * @example
56
- * ```tsx
57
- * <Button bgColor="primary.main" />
58
- * <Alert bgColor="danger.lighter" color="danger.dark" />
59
- * <Badge bgColor="success.lightest" color="success.dark" />
60
- * ```
61
- */
62
36
  export declare const semanticTokens: {
63
37
  readonly colors: {
64
38
  /**
@@ -117,6 +91,18 @@ export declare const semanticTokens: {
117
91
  readonly _dark: "{colors.blue.100}";
118
92
  };
119
93
  };
94
+ readonly fill: {
95
+ readonly value: {
96
+ readonly base: "{colors.blue.500}";
97
+ readonly _dark: "{colors.blue.700}";
98
+ };
99
+ };
100
+ readonly fillStrong: {
101
+ readonly value: {
102
+ readonly base: "{colors.blue.700}";
103
+ readonly _dark: "{colors.blue.800}";
104
+ };
105
+ };
120
106
  };
121
107
  /**
122
108
  * Secondary colors (Violet-based)
@@ -329,6 +315,135 @@ export declare const semanticTokens: {
329
315
  };
330
316
  };
331
317
  };
318
+ /**
319
+ * `slate.*` — the foundational **mode-aware neutral family**.
320
+ *
321
+ * A first-class neutral palette alongside the raw `gray.*` primitives, but
322
+ * mode-aware: each `slate.N` resolves to `gray.N` in light and to the
323
+ * desaturated counterpart of the *mirrored* step in dark, so a single token
324
+ * carries the same tonal level in both modes (e.g. `slate.300` is a light
325
+ * divider in light and the equivalent dark divider in dark — no `_dark={{…}}`
326
+ * at the call site). It lives under `semanticTokens` only because Chakra
327
+ * requires that for the `_dark` flip; conceptually it is a *foundation*
328
+ * (a tonal scale), not a *role*.
329
+ *
330
+ * When to use which:
331
+ * - Prefer the **role tokens** (`fg`/`bg`/`border`) when one matches the
332
+ * intent — they carry semantics and AA-tuned dark values.
333
+ * - Reach for **`slate.N`** when you need a specific neutral tonal step that
334
+ * no role names (mirroring how you'd otherwise drop to a raw `gray.N`, but
335
+ * keeping the dark flip). `slate` and the role tokens are *distinct* ramps
336
+ * (slate is a mechanical mirror; roles are hand-tuned), so they are not
337
+ * interchangeable in dark mode.
338
+ *
339
+ * `600`/`700` are lifted off the straight mirror (#8E939F/#7C818D) so the
340
+ * secondary/muted text they most often carry clears WCAG AA 4.5:1 on the
341
+ * dark canvas/surface — the straight mirrors measured ~3.0–3.9 there.
342
+ */
343
+ readonly slate: {
344
+ readonly 0: {
345
+ readonly value: {
346
+ readonly base: "{colors.gray.0}";
347
+ readonly _dark: "#0E1014";
348
+ };
349
+ };
350
+ readonly 50: {
351
+ readonly value: {
352
+ readonly base: "{colors.gray.50}";
353
+ readonly _dark: "#181A20";
354
+ };
355
+ };
356
+ readonly 100: {
357
+ readonly value: {
358
+ readonly base: "{colors.gray.100}";
359
+ readonly _dark: "#23262E";
360
+ };
361
+ };
362
+ readonly 200: {
363
+ readonly value: {
364
+ readonly base: "{colors.gray.200}";
365
+ readonly _dark: "#30343C";
366
+ };
367
+ };
368
+ readonly 300: {
369
+ readonly value: {
370
+ readonly base: "{colors.gray.300}";
371
+ readonly _dark: "#3C404B";
372
+ };
373
+ };
374
+ readonly 400: {
375
+ readonly value: {
376
+ readonly base: "{colors.gray.400}";
377
+ readonly _dark: "#4A4E5A";
378
+ };
379
+ };
380
+ readonly 500: {
381
+ readonly value: {
382
+ readonly base: "{colors.gray.500}";
383
+ readonly _dark: "#595E6B";
384
+ };
385
+ };
386
+ readonly 600: {
387
+ readonly value: {
388
+ readonly base: "{colors.gray.600}";
389
+ readonly _dark: "#898E99";
390
+ };
391
+ };
392
+ readonly 700: {
393
+ readonly value: {
394
+ readonly base: "{colors.gray.700}";
395
+ readonly _dark: "#8D919D";
396
+ };
397
+ };
398
+ readonly 800: {
399
+ readonly value: {
400
+ readonly base: "{colors.gray.800}";
401
+ readonly _dark: "#8E939F";
402
+ };
403
+ };
404
+ readonly 900: {
405
+ readonly value: {
406
+ readonly base: "{colors.gray.900}";
407
+ readonly _dark: "#A2A6B1";
408
+ };
409
+ };
410
+ readonly 1000: {
411
+ readonly value: {
412
+ readonly base: "{colors.gray.1000}";
413
+ readonly _dark: "#B6BAC3";
414
+ };
415
+ };
416
+ readonly 1100: {
417
+ readonly value: {
418
+ readonly base: "{colors.gray.1100}";
419
+ readonly _dark: "#D2D5DB";
420
+ };
421
+ };
422
+ readonly 1200: {
423
+ readonly value: {
424
+ readonly base: "{colors.gray.1200}";
425
+ readonly _dark: "#E5E8EC";
426
+ };
427
+ };
428
+ readonly 1300: {
429
+ readonly value: {
430
+ readonly base: "{colors.gray.1300}";
431
+ readonly _dark: "#F2F4F7";
432
+ };
433
+ };
434
+ readonly 1400: {
435
+ readonly value: {
436
+ readonly base: "{colors.gray.1400}";
437
+ readonly _dark: "#F8F9FB";
438
+ };
439
+ };
440
+ readonly 1500: {
441
+ readonly value: {
442
+ readonly base: "{colors.gray.1500}";
443
+ readonly _dark: "#FEFEFF";
444
+ };
445
+ };
446
+ };
332
447
  /**
333
448
  * Neutral background tokens — map onto the gray.0–1500 scale.
334
449
  * Use for: page/canvas, raised surfaces (cards, menus), subtle/muted fills,
@@ -341,40 +456,58 @@ export declare const semanticTokens: {
341
456
  * - inverse: high-contrast surface (flips to light in dark mode)
342
457
  */
343
458
  readonly bg: {
459
+ readonly DEFAULT: {
460
+ readonly value: {
461
+ readonly _light: "{colors.white}";
462
+ readonly _dark: "#0E1014";
463
+ };
464
+ };
344
465
  readonly canvas: {
345
466
  readonly value: {
346
467
  readonly base: "{colors.gray.0}";
347
- readonly _dark: "{colors.gray.1500}";
468
+ readonly _dark: "#0E1014";
348
469
  };
349
470
  };
350
471
  readonly surface: {
351
472
  readonly value: {
352
473
  readonly base: "{colors.white}";
353
- readonly _dark: "{colors.gray.1400}";
474
+ readonly _dark: "#181A20";
475
+ };
476
+ };
477
+ readonly raised: {
478
+ readonly value: {
479
+ readonly base: "{colors.white}";
480
+ readonly _dark: "#3C404B";
354
481
  };
355
482
  };
356
483
  readonly subtle: {
357
484
  readonly value: {
358
485
  readonly base: "{colors.gray.50}";
359
- readonly _dark: "{colors.gray.1300}";
486
+ readonly _dark: "#23262E";
360
487
  };
361
488
  };
362
489
  readonly muted: {
363
490
  readonly value: {
364
491
  readonly base: "{colors.gray.100}";
365
- readonly _dark: "{colors.gray.1200}";
492
+ readonly _dark: "#30343C";
366
493
  };
367
494
  };
368
495
  readonly inverse: {
369
496
  readonly value: {
370
497
  readonly base: "{colors.gray.1300}";
371
- readonly _dark: "{colors.gray.50}";
498
+ readonly _dark: "#F8F9FB";
499
+ };
500
+ };
501
+ readonly sunken: {
502
+ readonly value: {
503
+ readonly base: "{colors.gray.50}";
504
+ readonly _dark: "#0E1014";
372
505
  };
373
506
  };
374
507
  readonly panel: {
375
508
  readonly value: {
376
509
  readonly base: "{colors.white}";
377
- readonly _dark: "{colors.gray.1400}";
510
+ readonly _dark: "#181A20";
378
511
  };
379
512
  };
380
513
  /**
@@ -417,28 +550,40 @@ export declare const semanticTokens: {
417
550
  * - inverse: text on inverse surfaces (flips with mode)
418
551
  */
419
552
  readonly fg: {
420
- readonly default: {
553
+ readonly DEFAULT: {
554
+ readonly value: {
555
+ readonly _light: "{colors.black}";
556
+ readonly _dark: "#F8F9FB";
557
+ };
558
+ };
559
+ readonly emphasized: {
421
560
  readonly value: {
422
561
  readonly base: "{colors.gray.1300}";
423
- readonly _dark: "{colors.gray.200}";
562
+ readonly _dark: "#E5E8EC";
563
+ };
564
+ };
565
+ readonly default: {
566
+ readonly value: {
567
+ readonly base: "{colors.gray.1000}";
568
+ readonly _dark: "#D2D5DB";
424
569
  };
425
570
  };
426
571
  readonly muted: {
427
572
  readonly value: {
428
573
  readonly base: "{colors.gray.900}";
429
- readonly _dark: "{colors.gray.300}";
574
+ readonly _dark: "#B6BAC3";
430
575
  };
431
576
  };
432
577
  readonly subtle: {
433
578
  readonly value: {
434
579
  readonly base: "{colors.gray.700}";
435
- readonly _dark: "{colors.gray.600}";
580
+ readonly _dark: "#989DA9";
436
581
  };
437
582
  };
438
583
  readonly inverse: {
439
584
  readonly value: {
440
585
  readonly base: "{colors.gray.0}";
441
- readonly _dark: "{colors.gray.1400}";
586
+ readonly _dark: "#181A20";
442
587
  };
443
588
  };
444
589
  };
@@ -450,22 +595,28 @@ export declare const semanticTokens: {
450
595
  * - strong: high-emphasis borders, focus outlines on neutral
451
596
  */
452
597
  readonly border: {
598
+ readonly DEFAULT: {
599
+ readonly value: {
600
+ readonly _light: "{colors.gray.200}";
601
+ readonly _dark: "#6A6F7C";
602
+ };
603
+ };
453
604
  readonly default: {
454
605
  readonly value: {
455
606
  readonly base: "{colors.gray.300}";
456
- readonly _dark: "{colors.gray.1100}";
607
+ readonly _dark: "#3C404B";
457
608
  };
458
609
  };
459
610
  readonly subtle: {
460
611
  readonly value: {
461
612
  readonly base: "{colors.gray.200}";
462
- readonly _dark: "{colors.gray.1300}";
613
+ readonly _dark: "#23262E";
463
614
  };
464
615
  };
465
616
  readonly strong: {
466
617
  readonly value: {
467
618
  readonly base: "{colors.gray.500}";
468
- readonly _dark: "{colors.gray.900}";
619
+ readonly _dark: "#595E6B";
469
620
  };
470
621
  };
471
622
  };
@@ -479,11 +630,12 @@ export declare const semanticTokens: {
479
630
  * by reviewers. It is intentionally hand-maintained alongside `semanticTokens`
480
631
  * so a rename here is a visible, reviewable diff.
481
632
  *
482
- * Note: `bg.panel` is deliberately omitted it is an internal realignment of a
483
- * Chakra default (for overlay surfaces), not part of the public migration
484
- * contract. App code should use `bg.surface`/`bg.canvas`.
633
+ * Note: `bg.panel` and the bare `bg`/`fg`/`border` DEFAULT tokens are
634
+ * deliberately omitted they are internal realignments of Chakra defaults
635
+ * (overlay surfaces and html-level globals), not part of the public migration
636
+ * contract. App code should use `bg.surface`/`bg.canvas`, `fg.default`, etc.
485
637
  */
486
- export type SemanticColorToken = `bg.${'canvas' | 'surface' | 'subtle' | 'muted' | 'inverse' | 'selected' | 'highlighted'}` | 'bg.invalid.subtle' | `fg.${'default' | 'muted' | 'subtle' | 'inverse'}` | `border.${'default' | 'subtle' | 'strong'}` | `${'primary' | 'secondary' | 'danger' | 'success' | 'warning'}.${'lightest' | 'extralight' | 'lighter' | 'light' | 'main' | 'dark' | 'darker'}`;
638
+ export type SemanticColorToken = `bg.${'canvas' | 'surface' | 'raised' | 'subtle' | 'muted' | 'sunken' | 'inverse' | 'selected' | 'highlighted'}` | 'bg.invalid.subtle' | `fg.${'emphasized' | 'default' | 'muted' | 'subtle' | 'inverse'}` | `border.${'default' | 'subtle' | 'strong'}` | `slate.${0 | 50 | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900 | 1000 | 1100 | 1200 | 1300 | 1400 | 1500}` | `primary.${'fill' | 'fillStrong'}` | `${'primary' | 'secondary' | 'danger' | 'success' | 'warning'}.${'lightest' | 'extralight' | 'lighter' | 'light' | 'main' | 'dark' | 'darker'}`;
487
639
  /**
488
640
  * Primitive color palette following the Golden Ratio system.
489
641
  *
@@ -1 +1 @@
1
- {"version":3,"file":"colors.d.ts","sourceRoot":"","sources":["../../src/theme/colors.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AAEH;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,eAAO,MAAM,cAAc;;QAEvB;;;;;;;;;;;;WAYG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAyBH;;;;;;;WAOG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QA6BH;;;;;;;WAOG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAyBH;;;;;;;WAOG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAyBH;;;;;;;;;;WAUG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAyBH;;;;;;;;;;WAUG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;YAwBD;;;;;;;;;eASG;;;;;;;;;;;;;;;;;;;;;;QAcL;;;;;;;WAOG;;;;;;;;;;;;;;;;;;;;;;;;;;;QAyBH;;;;;;WAMG;;;;;;;;;;;;;;;;;;;;;;CAaG,CAAC;AAEX;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,kBAAkB,GAC1B,MACI,QAAQ,GACR,SAAS,GACT,QAAQ,GACR,OAAO,GACP,SAAS,GACT,UAAU,GACV,aAAa,EAAE,GACnB,mBAAmB,GACnB,MAAM,SAAS,GAAG,OAAO,GAAG,QAAQ,GAAG,SAAS,EAAE,GAClD,UAAU,SAAS,GAAG,QAAQ,GAAG,QAAQ,EAAE,GAC3C,GAAG,SAAS,GAAG,WAAW,GAAG,QAAQ,GAAG,SAAS,GAAG,SAAS,IACzD,UAAU,GACV,YAAY,GACZ,SAAS,GACT,OAAO,GACP,MAAM,GACN,MAAM,GACN,QAAQ,EAAE,CAAC;AAEnB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,eAAO,MAAM,MAAM;IACjB;;;OAGG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAcH;;;OAGG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAcH;;;OAGG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAcH;;;OAGG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAcH;;;OAGG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAcH;;;;;;;;;;OAUG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAqBH;;;OAGG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAaH;;;OAGG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAaH;;;OAGG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAgBJ,CAAC"}
1
+ {"version":3,"file":"colors.d.ts","sourceRoot":"","sources":["../../src/theme/colors.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AA2DH,eAAO,MAAM,cAAc;;QAEvB;;;;;;;;;;;;WAYG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAqCH;;;;;;;WAOG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QA6BH;;;;;;;WAOG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAyBH;;;;;;;WAOG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAyBH;;;;;;;;;;WAUG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAyBH;;;;;;;;;;;;;;;;;;;;;;;;WAwBG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QA+CH;;;;;;;;;;WAUG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;YAoDD;;;;;;;;;eASG;;;;;;;;;;;;;;;;;;;;;;QAcL;;;;;;;WAOG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAyCH;;;;;;WAMG;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAoBG,CAAC;AAEX;;;;;;;;;;;;GAYG;AACH,MAAM,MAAM,kBAAkB,GAC1B,MACI,QAAQ,GACR,SAAS,GACT,QAAQ,GACR,QAAQ,GACR,OAAO,GACP,QAAQ,GACR,SAAS,GACT,UAAU,GACV,aAAa,EAAE,GACnB,mBAAmB,GACnB,MAAM,YAAY,GAAG,SAAS,GAAG,OAAO,GAAG,QAAQ,GAAG,SAAS,EAAE,GACjE,UAAU,SAAS,GAAG,QAAQ,GAAG,QAAQ,EAAE,GAI3C,SACI,CAAC,GACD,EAAE,GACF,GAAG,GACH,GAAG,GACH,GAAG,GACH,GAAG,GACH,GAAG,GACH,GAAG,GACH,GAAG,GACH,GAAG,GACH,GAAG,GACH,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,EAAE,GACV,WAAW,MAAM,GAAG,YAAY,EAAE,GAClC,GAAG,SAAS,GAAG,WAAW,GAAG,QAAQ,GAAG,SAAS,GAAG,SAAS,IACzD,UAAU,GACV,YAAY,GACZ,SAAS,GACT,OAAO,GACP,MAAM,GACN,MAAM,GACN,QAAQ,EAAE,CAAC;AAEnB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,eAAO,MAAM,MAAM;IACjB;;;OAGG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAcH;;;OAGG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAcH;;;OAGG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAcH;;;OAGG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAcH;;;OAGG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAcH;;;;;;;;;;OAUG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAqBH;;;OAGG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAaH;;;OAGG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAaH;;;OAGG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAgBJ,CAAC"}
@@ -62,6 +62,35 @@
62
62
  * <Badge bgColor="success.lightest" color="success.dark" />
63
63
  * ```
64
64
  */
65
+ /**
66
+ * Halved-saturation counterpart of each primitive `gray.N` — same hue and
67
+ * lightness, HSL saturation cut by ~50% (e.g. `gray.1300` #1E2433 @ 26% →
68
+ * #23262E @ 13%). The blue-tinted `gray` ramp reads as the right neutral in
69
+ * light mode but turns muddy/over-chromatic as a dark surface, so every
70
+ * dark-mode neutral below (`slate.*`, and the `_dark` of `bg`/`fg`/`border`)
71
+ * resolves to this desaturated mirror instead of the raw `gray` step. Light
72
+ * mode is untouched — it keeps referencing `{colors.gray.*}` verbatim.
73
+ *
74
+ * Single source of truth: change a dark neutral here, not at each token.
75
+ */
76
+ const desaturatedGray = {
77
+ 0: '#FEFEFF',
78
+ 50: '#F8F9FB',
79
+ 100: '#F2F4F7',
80
+ 200: '#E5E8EC',
81
+ 300: '#D2D5DB',
82
+ 400: '#B6BAC3',
83
+ 500: '#A2A6B1',
84
+ 600: '#8E939F',
85
+ 800: '#6A6F7C',
86
+ 900: '#595E6B',
87
+ 1000: '#4A4E5A',
88
+ 1100: '#3C404B',
89
+ 1200: '#30343C',
90
+ 1300: '#23262E',
91
+ 1400: '#181A20',
92
+ 1500: '#0E1014',
93
+ };
65
94
  const semanticTokens = {
66
95
  colors: {
67
96
  /**
@@ -99,6 +128,18 @@ const semanticTokens = {
99
128
  darker: {
100
129
  value: { base: '{colors.blue.900}', _dark: '{colors.blue.100}' },
101
130
  }, // high-contrast text
131
+ // Solid brand-blue *fills* for surfaces with white text/icons on top
132
+ // (modal headers, hero/banner gradients, brand badges). `primary.main`/
133
+ // `primary.dark` lighten ~2 stops in dark — right for foreground, too
134
+ // light as a fill — so these stay a deep blue in dark instead. `base`
135
+ // repeats the old main/dark values, so light is unchanged. Bare accents
136
+ // (dots, progress bars) keep `primary.main`.
137
+ fill: {
138
+ value: { base: '{colors.blue.500}', _dark: '{colors.blue.700}' },
139
+ },
140
+ fillStrong: {
141
+ value: { base: '{colors.blue.700}', _dark: '{colors.blue.800}' },
142
+ },
102
143
  },
103
144
  /**
104
145
  * Secondary colors (Violet-based)
@@ -231,6 +272,76 @@ const semanticTokens = {
231
272
  value: { base: '{colors.gold.900}', _dark: '{colors.gold.100}' },
232
273
  },
233
274
  },
275
+ /**
276
+ * `slate.*` — the foundational **mode-aware neutral family**.
277
+ *
278
+ * A first-class neutral palette alongside the raw `gray.*` primitives, but
279
+ * mode-aware: each `slate.N` resolves to `gray.N` in light and to the
280
+ * desaturated counterpart of the *mirrored* step in dark, so a single token
281
+ * carries the same tonal level in both modes (e.g. `slate.300` is a light
282
+ * divider in light and the equivalent dark divider in dark — no `_dark={{…}}`
283
+ * at the call site). It lives under `semanticTokens` only because Chakra
284
+ * requires that for the `_dark` flip; conceptually it is a *foundation*
285
+ * (a tonal scale), not a *role*.
286
+ *
287
+ * When to use which:
288
+ * - Prefer the **role tokens** (`fg`/`bg`/`border`) when one matches the
289
+ * intent — they carry semantics and AA-tuned dark values.
290
+ * - Reach for **`slate.N`** when you need a specific neutral tonal step that
291
+ * no role names (mirroring how you'd otherwise drop to a raw `gray.N`, but
292
+ * keeping the dark flip). `slate` and the role tokens are *distinct* ramps
293
+ * (slate is a mechanical mirror; roles are hand-tuned), so they are not
294
+ * interchangeable in dark mode.
295
+ *
296
+ * `600`/`700` are lifted off the straight mirror (#8E939F/#7C818D) so the
297
+ * secondary/muted text they most often carry clears WCAG AA 4.5:1 on the
298
+ * dark canvas/surface — the straight mirrors measured ~3.0–3.9 there.
299
+ */
300
+ slate: {
301
+ 0: { value: { base: '{colors.gray.0}', _dark: desaturatedGray[1500] } },
302
+ 50: { value: { base: '{colors.gray.50}', _dark: desaturatedGray[1400] } },
303
+ 100: {
304
+ value: { base: '{colors.gray.100}', _dark: desaturatedGray[1300] },
305
+ },
306
+ 200: {
307
+ value: { base: '{colors.gray.200}', _dark: desaturatedGray[1200] },
308
+ },
309
+ 300: {
310
+ value: { base: '{colors.gray.300}', _dark: desaturatedGray[1100] },
311
+ },
312
+ 400: {
313
+ value: { base: '{colors.gray.400}', _dark: desaturatedGray[1000] },
314
+ },
315
+ 500: {
316
+ value: { base: '{colors.gray.500}', _dark: desaturatedGray[900] },
317
+ },
318
+ 600: { value: { base: '{colors.gray.600}', _dark: '#898E99' } },
319
+ 700: { value: { base: '{colors.gray.700}', _dark: '#8D919D' } },
320
+ 800: {
321
+ value: { base: '{colors.gray.800}', _dark: desaturatedGray[600] },
322
+ },
323
+ 900: {
324
+ value: { base: '{colors.gray.900}', _dark: desaturatedGray[500] },
325
+ },
326
+ 1000: {
327
+ value: { base: '{colors.gray.1000}', _dark: desaturatedGray[400] },
328
+ },
329
+ 1100: {
330
+ value: { base: '{colors.gray.1100}', _dark: desaturatedGray[300] },
331
+ },
332
+ 1200: {
333
+ value: { base: '{colors.gray.1200}', _dark: desaturatedGray[200] },
334
+ },
335
+ 1300: {
336
+ value: { base: '{colors.gray.1300}', _dark: desaturatedGray[100] },
337
+ },
338
+ 1400: {
339
+ value: { base: '{colors.gray.1400}', _dark: desaturatedGray[50] },
340
+ },
341
+ 1500: {
342
+ value: { base: '{colors.gray.1500}', _dark: desaturatedGray[0] },
343
+ },
344
+ },
234
345
  /**
235
346
  * Neutral background tokens — map onto the gray.0–1500 scale.
236
347
  * Use for: page/canvas, raised surfaces (cards, menus), subtle/muted fills,
@@ -243,27 +354,55 @@ const semanticTokens = {
243
354
  * - inverse: high-contrast surface (flips to light in dark mode)
244
355
  */
245
356
  bg: {
357
+ // Chakra's own global css paints `html { background: bg }` — the *plain*
358
+ // `bg` token, not `bg.canvas` — so this is the actual page background
359
+ // wherever no component paints over it. `_light` is pure white (Chakra's
360
+ // value, so light is untouched); `_dark` rejoins our neutral floor instead
361
+ // of Chakra's off-palette black.
362
+ DEFAULT: {
363
+ value: { _light: '{colors.white}', _dark: desaturatedGray[1500] },
364
+ },
246
365
  canvas: {
247
- value: { base: '{colors.gray.0}', _dark: '{colors.gray.1500}' },
366
+ value: { base: '{colors.gray.0}', _dark: desaturatedGray[1500] },
248
367
  },
249
368
  surface: {
250
- value: { base: '{colors.white}', _dark: '{colors.gray.1400}' },
369
+ value: { base: '{colors.white}', _dark: desaturatedGray[1400] },
370
+ },
371
+ // Strongly-raised neutral surface — one level above `surface` (e.g. the
372
+ // selected thumb of a SegmentedControl). In dark this is the *lightest*
373
+ // neutral bg token so a raised element reads as lifted toward the light,
374
+ // not recessed. (The `bg.*` dark ramp is otherwise compressed such that
375
+ // `surface` sits below `subtle`/`muted`; `raised` deliberately tops the
376
+ // scale so "raised" has a token that behaves correctly in dark.)
377
+ // NB: named `raised`, not Chakra's `emphasized` — that default token name
378
+ // cannot be overridden via semanticTokens in this setup (it keeps
379
+ // resolving to Chakra's own gray.200), whereas a fresh name is honoured.
380
+ raised: {
381
+ value: { base: '{colors.white}', _dark: desaturatedGray[1100] },
251
382
  },
252
383
  subtle: {
253
- value: { base: '{colors.gray.50}', _dark: '{colors.gray.1300}' },
384
+ value: { base: '{colors.gray.50}', _dark: desaturatedGray[1300] },
254
385
  },
255
386
  muted: {
256
- value: { base: '{colors.gray.100}', _dark: '{colors.gray.1200}' },
387
+ value: { base: '{colors.gray.100}', _dark: desaturatedGray[1200] },
257
388
  },
258
389
  inverse: {
259
- value: { base: '{colors.gray.1300}', _dark: '{colors.gray.50}' },
390
+ value: { base: '{colors.gray.1300}', _dark: desaturatedGray[50] },
391
+ },
392
+ // Sunken page wash for list/overview surfaces: a gray floor in light so
393
+ // `bg.surface` cards read as raised above it. In dark the `bg.*` ramp is
394
+ // compressed (`subtle` sits *lighter* than `surface`), which would invert
395
+ // that elevation — so the dark value drops to the canvas floor instead.
396
+ // Component-level fills (hover, chips, inner blocks) keep using `bg.subtle`.
397
+ sunken: {
398
+ value: { base: '{colors.gray.50}', _dark: desaturatedGray[1500] },
260
399
  },
261
400
  // Override Chakra's default `bg.panel` (whose `_dark` resolves to Chakra's
262
401
  // own gray.950 = #111111, off our slate palette). Light value is white —
263
402
  // identical to Chakra's default — so this only realigns dark overlay
264
403
  // surfaces (Menu / Modal / Popover / Toast) onto our gray scale.
265
404
  panel: {
266
- value: { base: '{colors.white}', _dark: '{colors.gray.1400}' },
405
+ value: { base: '{colors.white}', _dark: desaturatedGray[1400] },
267
406
  },
268
407
  /**
269
408
  * Row/selection state tints. Use these for selected rows,
@@ -296,26 +435,42 @@ const semanticTokens = {
296
435
  * - inverse: text on inverse surfaces (flips with mode)
297
436
  */
298
437
  fg: {
438
+ // Plain `fg` is Chakra's html-level text color (`html { color: fg }`).
439
+ // `_light` repeats Chakra's value (black); `_dark` rejoins our desaturated
440
+ // neutral so legacy html-level text tracks `fg.default`.
441
+ DEFAULT: {
442
+ value: { _light: '{colors.black}', _dark: desaturatedGray[50] },
443
+ },
444
+ // Strongest text — headings, titles, key figures, emphasis. This is the
445
+ // near-black step that `fg.default` used to be; `default` is now re-pegged
446
+ // to a lighter body weight (see below), so reach for `emphasized` when you
447
+ // specifically want maximum contrast.
448
+ emphasized: {
449
+ value: { base: '{colors.gray.1300}', _dark: desaturatedGray[200] },
450
+ },
299
451
  default: {
300
- // _dark is gray.200 (not gray.50): near-white text on the dark canvas
301
- // ran ~18:1 brighter than the light baseline (~15:1) and close to pure
302
- // white, which causes glare/halation. gray.200 matches the light
303
- // contrast (~15.4:1) while staying AAA.
304
- value: { base: '{colors.gray.1300}', _dark: '{colors.gray.200}' },
452
+ // Primary *body* text. Re-pegged from gray.1300 gray.1000: near-black
453
+ // (gray.1300, ~14:1 on white) is unusually heavy for running copy, and
454
+ // real product usage clustered well below it. gray.1000 (~9:1) is a
455
+ // comfortable AAA body weight; the old near-black step lives on as
456
+ // `fg.emphasized`. _dark drops one step from emphasized for hierarchy.
457
+ value: { base: '{colors.gray.1000}', _dark: desaturatedGray[300] },
305
458
  },
306
459
  muted: {
307
- // _dark lifts gray.400 gray.300: secondary text read as too dim on the
308
- // dark canvas next to fg.default (gray.200). gray.300 sits one step under
309
- // default — restoring the light-mode hierarchy gap — while staying well
310
- // clear of AA (~12.8:1 on bg.canvas, ~11.7:1 on bg.surface). Light value
311
- // (gray.900) is unchanged.
312
- value: { base: '{colors.gray.900}', _dark: '{colors.gray.300}' },
460
+ // Secondary text. _dark sits one step below `default` (~9.5:1 on the dark
461
+ // canvas) to keep the default→muted hierarchy gap. Light value (gray.900)
462
+ // is unchanged.
463
+ value: { base: '{colors.gray.900}', _dark: desaturatedGray[400] },
313
464
  },
314
465
  subtle: {
315
- value: { base: '{colors.gray.700}', _dark: '{colors.gray.600}' },
466
+ // Tertiary / placeholder / icon text. _dark a11y-bumped from the straight
467
+ // mirror (desaturatedGray[600] #8E939F, ~4.06:1 on bg.muted) to #989DA9
468
+ // (~4.6:1) so it clears AA while staying below fg.muted. Light value
469
+ // (gray.700) is unchanged.
470
+ value: { base: '{colors.gray.700}', _dark: '#989DA9' },
316
471
  },
317
472
  inverse: {
318
- value: { base: '{colors.gray.0}', _dark: '{colors.gray.1400}' },
473
+ value: { base: '{colors.gray.0}', _dark: desaturatedGray[1400] },
319
474
  },
320
475
  },
321
476
  /**
@@ -326,14 +481,21 @@ const semanticTokens = {
326
481
  * - strong: high-emphasis borders, focus outlines on neutral
327
482
  */
328
483
  border: {
484
+ // Plain `border` feeds Chakra's `--global-color-border` (the implicit
485
+ // default border color). Not a text color, so its `_dark` takes the
486
+ // straight halved-saturation mirror (no a11y bump). `_light` repeats
487
+ // Chakra's value so light is untouched.
488
+ DEFAULT: {
489
+ value: { _light: '{colors.gray.200}', _dark: desaturatedGray[800] },
490
+ },
329
491
  default: {
330
- value: { base: '{colors.gray.300}', _dark: '{colors.gray.1100}' },
492
+ value: { base: '{colors.gray.300}', _dark: desaturatedGray[1100] },
331
493
  },
332
494
  subtle: {
333
- value: { base: '{colors.gray.200}', _dark: '{colors.gray.1300}' },
495
+ value: { base: '{colors.gray.200}', _dark: desaturatedGray[1300] },
334
496
  },
335
497
  strong: {
336
- value: { base: '{colors.gray.500}', _dark: '{colors.gray.900}' },
498
+ value: { base: '{colors.gray.500}', _dark: desaturatedGray[900] },
337
499
  },
338
500
  },
339
501
  },