css-is-awesome 1.19.0 → 1.19.2

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 (55) hide show
  1. package/AGENTS.md +1 -1
  2. package/CHANGELOG.md +19 -0
  3. package/README.md +1 -1
  4. package/dist/tokens.d.ts +1 -1
  5. package/llm.txt +1 -1
  6. package/mcp/server.cjs +5 -4
  7. package/package.json +5 -1
  8. package/public/theme.css +61 -61
  9. package/public/themes/boilerplate/theme.css +6 -6
  10. package/public/themes/boilerplate-dark/theme.css +2 -2
  11. package/public/themes/boilerplate-light/theme.css +6 -6
  12. package/public/themes/cupertino/theme.css +3 -3
  13. package/public/themes/cupertino-dark/theme.css +2 -2
  14. package/public/themes/cupertino-light/theme.css +1 -1
  15. package/public/themes/glass/theme.css +4 -4
  16. package/public/themes/glass-dark/theme.css +1 -1
  17. package/public/themes/glass-light/theme.css +3 -3
  18. package/public/themes/graphite/theme.css +5 -5
  19. package/public/themes/graphite-dark/theme.css +2 -2
  20. package/public/themes/graphite-light/theme.css +3 -3
  21. package/public/themes/press/theme.css +2 -2
  22. package/public/themes/press-dark/theme.css +1 -1
  23. package/public/themes/press-light/theme.css +2 -2
  24. package/public/themes/prism/theme.css +2 -2
  25. package/public/themes/prism-light/theme.css +4 -4
  26. package/public/themes/sketchbook/theme.css +2 -2
  27. package/public/themes/sketchbook-dark/theme.css +1 -1
  28. package/public/themes/sketchbook-light/theme.css +2 -2
  29. package/public/themes/terminal/theme.css +1 -1
  30. package/public/themes/terminal-dark/theme.css +2 -2
  31. package/public/themes/terminal-light/theme.css +4 -4
  32. package/scripts/tokens-to-theme.cjs +59 -6
  33. package/scss/themes/boilerplate-dark.scss +2 -2
  34. package/scss/themes/boilerplate-light.scss +6 -6
  35. package/scss/themes/boilerplate.scss +6 -6
  36. package/scss/themes/cupertino-dark.scss +2 -2
  37. package/scss/themes/cupertino-light.scss +1 -1
  38. package/scss/themes/cupertino.scss +3 -3
  39. package/scss/themes/glass-dark.scss +1 -1
  40. package/scss/themes/glass-light.scss +3 -3
  41. package/scss/themes/glass.scss +4 -4
  42. package/scss/themes/graphite-dark.scss +2 -2
  43. package/scss/themes/graphite-light.scss +3 -3
  44. package/scss/themes/graphite.scss +5 -5
  45. package/scss/themes/press-dark.scss +1 -1
  46. package/scss/themes/press-light.scss +2 -2
  47. package/scss/themes/press.scss +2 -2
  48. package/scss/themes/prism-light.scss +4 -4
  49. package/scss/themes/prism.scss +2 -2
  50. package/scss/themes/sketchbook-dark.scss +1 -1
  51. package/scss/themes/sketchbook-light.scss +2 -2
  52. package/scss/themes/sketchbook.scss +2 -2
  53. package/scss/themes/terminal-dark.scss +2 -2
  54. package/scss/themes/terminal-light.scss +4 -4
  55. package/scss/themes/terminal.scss +1 -1
@@ -52,7 +52,7 @@
52
52
  --ai-ink: #0058B0;
53
53
  --ai-wash: #E5F0FB;
54
54
  /* Seal — system red */
55
- --shu: #FF3B30;
55
+ --shu: #f73229;
56
56
  --shu-wash: #FFEAE8;
57
57
  /* Accent — system orange / amber */
58
58
  --ochre: #FF9F0A;
@@ -12,18 +12,18 @@
12
12
  --ink-soft: light-dark(#3A3A3C, #C8CFE0);
13
13
  --ink-faint: light-dark(#65656A, #8A92A8);
14
14
  --graphite: light-dark(#2C2C2E, #DCE2F0);
15
- --muted: light-dark(#6E6E73, #5A627A);
15
+ --muted: light-dark(#6E6E73, #727b93);
16
16
  /* Construction lines — translucent */
17
17
  --guide: light-dark(rgba(29, 29, 31, 0.14), rgba(240, 244, 255, 0.16));
18
18
  --guide-soft: light-dark(rgba(29, 29, 31, 0.10), rgba(240, 244, 255, 0.08));
19
19
  --hair: light-dark(rgba(29, 29, 31, 0.08), rgba(240, 244, 255, 0.12));
20
20
  --hair-soft: light-dark(rgba(29, 29, 31, 0.04), rgba(240, 244, 255, 0.06));
21
21
  /* Primary accent — iOS indigo / vibrant dark blue */
22
- --ai: light-dark(#5957E2, #6FA9FF);
22
+ --ai: light-dark(#5653de, #6FA9FF);
23
23
  --ai-ink: light-dark(#3634A3, #93C2FF);
24
24
  --ai-wash: light-dark(rgba(89, 87, 226, 0.12), rgba(111, 169, 255, 0.16));
25
25
  /* Seal — iOS system pink */
26
- --shu: light-dark(#FF375F, #FF6B8A);
26
+ --shu: light-dark(#f32856, #FF6B8A);
27
27
  --shu-wash: light-dark(rgba(255, 55, 95, 0.12), rgba(255, 107, 138, 0.16));
28
28
  /* Draft / marginalia — iOS orange */
29
29
  --ochre: light-dark(#FF9500, #FFC56B);
@@ -33,7 +33,7 @@
33
33
  --code-ink: light-dark(#F5F5F7, #F0F4FF);
34
34
  --code-muted: light-dark(#BCBCC0, #8A92A8);
35
35
  --code-accent: #FFD60A;
36
- --code-green: light-dark(#30D158, #5FE37F);
36
+ --code-green: light-dark(#3ad85e, #5FE37F);
37
37
  --code-blue: light-dark(#64D2FF, #93C2FF);
38
38
  /* Typography — SF stack, identical */
39
39
  --font-display: -apple-system, BlinkMacSystemFont, 'SF Pro Display', 'Inter', system-ui, sans-serif;
@@ -31,7 +31,7 @@
31
31
  --ink-soft: #C8CFE0;
32
32
  --ink-faint: #8A92A8;
33
33
  --graphite: #DCE2F0;
34
- --muted: #5A627A;
34
+ --muted: #727b93;
35
35
  /* Construction lines — translucent white hairlines */
36
36
  --guide: rgba(240, 244, 255, 0.16);
37
37
  --guide-soft: rgba(240, 244, 255, 0.08);
@@ -55,11 +55,11 @@
55
55
  --hair: rgba(29, 29, 31, 0.08);
56
56
  --hair-soft: rgba(29, 29, 31, 0.04);
57
57
  /* Primary accent — iOS indigo */
58
- --ai: #5957E2;
58
+ --ai: #5653de;
59
59
  --ai-ink: #3634A3;
60
60
  --ai-wash: rgba(89, 87, 226, 0.12);
61
61
  /* Seal — iOS system pink (draft / emphasis) */
62
- --shu: #FF375F;
62
+ --shu: #f32856;
63
63
  --shu-wash: rgba(255, 55, 95, 0.12);
64
64
  /* Draft / marginalia — iOS orange */
65
65
  --ochre: #FF9500;
@@ -69,7 +69,7 @@
69
69
  --code-ink: #F5F5F7;
70
70
  --code-muted: #BABABE;
71
71
  --code-accent: #FFD60A;
72
- --code-green: #30D158;
72
+ --code-green: #3ad85e;
73
73
  --code-blue: #64D2FF;
74
74
  /* Typography — SF system stack */
75
75
  --font-display: -apple-system, BlinkMacSystemFont, 'SF Pro Display', 'Inter', system-ui, sans-serif;
@@ -12,14 +12,14 @@
12
12
  --ink-soft: light-dark(#3A4048, #C7C7CC);
13
13
  --ink-faint: light-dark(#5E646D, #98989D);
14
14
  --graphite: light-dark(#2A2F36, #AEAEB2);
15
- --muted: light-dark(#878D95, #6A6A6E);
15
+ --muted: light-dark(#6a7078, #6A6A6E);
16
16
  /* Construction lines — translucent ink (light) / translucent white (dark) */
17
17
  --guide: light-dark(rgba(26, 31, 38, 0.16), rgba(255, 255, 255, 0.16));
18
18
  --guide-soft: light-dark(rgba(26, 31, 38, 0.08), rgba(255, 255, 255, 0.08));
19
19
  --hair: light-dark(rgba(26, 31, 38, 0.12), rgba(255, 255, 255, 0.12));
20
20
  --hair-soft: light-dark(rgba(26, 31, 38, 0.06), rgba(255, 255, 255, 0.06));
21
21
  /* Primary accent — cool blue-gray (light) / Apple dark blue (dark) */
22
- --ai: light-dark(#4A6585, #0A84FF);
22
+ --ai: light-dark(#4A6585, #178aff);
23
23
  --ai-ink: light-dark(#2F4866, #409CFF);
24
24
  --ai-wash: light-dark(rgba(74, 101, 133, 0.10), rgba(10, 132, 255, 0.14));
25
25
  /* Seal */
@@ -32,8 +32,8 @@
32
32
  --code-bg: light-dark(#F6F7F9, #0D0D0F);
33
33
  --code-ink: light-dark(#1A1F26, #E8E8ED);
34
34
  --code-muted: light-dark(#666B73, #818186);
35
- --code-accent: light-dark(#87652B, #FFB86C);
36
- --code-green: light-dark(#3D7746, #A8E6A1);
35
+ --code-accent: light-dark(#86642a, #FFB86C);
36
+ --code-green: light-dark(#3d7646, #A8E6A1);
37
37
  --code-blue: light-dark(#4A6585, #9AD4F7);
38
38
  /* Typography — SF stack, identical */
39
39
  --font-display: -apple-system, BlinkMacSystemFont, 'SF Pro Display', 'Inter', 'Segoe UI', Helvetica, Arial, sans-serif;
@@ -113,7 +113,7 @@
113
113
  --info-text: light-dark(var(--ai-ink), #409CFF);
114
114
  --success-default: light-dark(#28A745, #30D158);
115
115
  --success-subtle: light-dark(rgba(40, 167, 69, 0.10), rgba(48, 209, 88, 0.14));
116
- --success-text: light-dark(#1B7530, #5FE37F);
116
+ --success-text: light-dark(#1b7530, #5FE37F);
117
117
  --warning-default: var(--ochre);
118
118
  --warning-subtle: light-dark(rgba(181, 135, 58, 0.10), rgba(255, 159, 10, 0.14));
119
119
  --warning-text: light-dark(#7A5A22, #FFB340);
@@ -52,14 +52,14 @@
52
52
  --ink-soft: #C7C7CC;
53
53
  --ink-faint: #98989D;
54
54
  --graphite: #AEAEB2;
55
- --muted: #6A6A6E;
55
+ --muted: #818286;
56
56
  /* Construction lines — translucent white hairlines */
57
57
  --guide: rgba(255, 255, 255, 0.16);
58
58
  --guide-soft: rgba(255, 255, 255, 0.08);
59
59
  --hair: rgba(255, 255, 255, 0.12);
60
60
  --hair-soft: rgba(255, 255, 255, 0.06);
61
61
  /* Primary accent — Apple dark-mode system blue */
62
- --ai: #0A84FF;
62
+ --ai: #178aff;
63
63
  --ai-ink: #409CFF;
64
64
  --ai-wash: rgba(10, 132, 255, 0.14);
65
65
  /* Seal — Apple dark-mode red (reserve for emphasis) */
@@ -30,7 +30,7 @@
30
30
  --ink-soft: #3A4048;
31
31
  --ink-faint: #5E646D;
32
32
  --graphite: #2A2F36;
33
- --muted: #878D95;
33
+ --muted: #6a7078;
34
34
  /* Construction lines — translucent ink hairlines */
35
35
  --guide: rgba(26, 31, 38, 0.16);
36
36
  --guide-soft: rgba(26, 31, 38, 0.08);
@@ -51,7 +51,7 @@
51
51
  --code-ink: #1A1F26;
52
52
  --code-muted: #656A72;
53
53
  --code-accent: #86642B;
54
- --code-green: #3F7A48;
54
+ --code-green: #3c7645;
55
55
  --code-blue: #4A6585;
56
56
  /* Typography — match Graphite (SF system stack) */
57
57
  --font-display: -apple-system, BlinkMacSystemFont, 'SF Pro Display', 'Inter', 'Segoe UI', Helvetica, Arial, sans-serif;
@@ -141,7 +141,7 @@
141
141
  /* Status — success (Apple light-mode green) */
142
142
  --success-default: #28A745;
143
143
  --success-subtle: rgba(40, 167, 69, 0.10);
144
- --success-text: #1B7530;
144
+ --success-text: #1b7530;
145
145
  /* Status — warning */
146
146
  --warning-default: var(--ochre);
147
147
  --warning-subtle: rgba(181, 135, 58, 0.10);
@@ -14,9 +14,9 @@
14
14
  ---------------------------------------------------------------- */
15
15
  --ink: light-dark(#0A0A0A, #FAFAF7);
16
16
  --ink-soft: light-dark(#555, #C8C6C0);
17
- --ink-faint: light-dark(#727069, #8A8A86);
17
+ --ink-faint: light-dark(#6e6c66, #8A8A86);
18
18
  --graphite: light-dark(#1A1A1A, #ECEAE4);
19
- --muted: light-dark(#8E8C86, #6B6963);
19
+ --muted: light-dark(#75736e, #6B6963);
20
20
  /* Rules / hairlines */
21
21
  --guide: light-dark(#1A1A1A, #ECEAE4);
22
22
  --guide-soft: light-dark(#D9D7D1, #2A2A2A);
@@ -29,7 +29,7 @@
29
29
  --ink-soft: #C8C6C0;
30
30
  --ink-faint: #8A8A86;
31
31
  --graphite: #ECEAE4;
32
- --muted: #6B6963;
32
+ --muted: #7d7b74;
33
33
  /* Rules / hairlines — thin editorial rules on dark */
34
34
  --guide: #ECEAE4;
35
35
  --guide-soft: #2A2A2A;
@@ -44,9 +44,9 @@
44
44
  /* Ink — warm near-black */
45
45
  --ink: #0A0A0A;
46
46
  --ink-soft: #555;
47
- --ink-faint: #727069;
47
+ --ink-faint: #6e6c66;
48
48
  --graphite: #1A1A1A;
49
- --muted: #8E8C86;
49
+ --muted: #75736e;
50
50
  /* Rules / hairlines — thin editorial rules */
51
51
  --guide: #1A1A1A;
52
52
  --guide-soft: #D9D7D1;
@@ -32,7 +32,7 @@
32
32
  --code-bg: light-dark(#fafafa, #0a0a0a);
33
33
  --code-ink: light-dark(#18181b, #e4e4e7);
34
34
  --code-muted: light-dark(#6B6B73, #808089);
35
- --code-accent: light-dark(#C1410C, #fb923c);
35
+ --code-accent: light-dark(#c0410b, #fb923c);
36
36
  --code-green: light-dark(#117D39, #4ade80);
37
37
  --code-blue: light-dark(#2462EB, #60a5fa);
38
38
  /* Typography — identical across modes */
@@ -110,7 +110,7 @@
110
110
  --info-text: light-dark(var(--ai-ink), #85BFFF);
111
111
  --success-default: light-dark(#16a34a, #22c55e);
112
112
  --success-subtle: light-dark(#f0fdf4, #14532d);
113
- --success-text: light-dark(#15803d, #4ade80);
113
+ --success-text: light-dark(#0e7c3a, #4ade80);
114
114
  --warning-default: light-dark(#ca8a04, #eab308);
115
115
  --warning-subtle: light-dark(#fefce8, #422006);
116
116
  --warning-text: light-dark(#854d0e, #fde047);
@@ -45,10 +45,10 @@
45
45
  /* Code — light syntax surface */
46
46
  --code-bg: #fafafa;
47
47
  --code-ink: #18181b;
48
- --code-muted: #71717a;
49
- --code-accent: #c2410c;
48
+ --code-muted: #6c6b74;
49
+ --code-accent: #c1400b;
50
50
  --code-green: #117C38;
51
- --code-blue: #2563eb;
51
+ --code-blue: #2462e9;
52
52
  /* Typography */
53
53
  --font-display: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
54
54
  --font-script: 'Inter', cursive;
@@ -134,7 +134,7 @@
134
134
  /* Status — success */
135
135
  --success-default: #16a34a;
136
136
  --success-subtle: #f0fdf4;
137
- --success-text: #15803d;
137
+ --success-text: #0e7c3a;
138
138
  /* Status — warning */
139
139
  --warning-default: #ca8a04;
140
140
  --warning-subtle: #fefce8;
@@ -10,9 +10,9 @@
10
10
  /* Ink — warm pencil + sumi / warm cream */
11
11
  --ink: light-dark(#2A241E, #F4EFE2);
12
12
  --ink-soft: light-dark(#4A4037, #D8D0BE);
13
- --ink-faint: light-dark(#726858, #A89E89);
13
+ --ink-faint: light-dark(#706757, #A89E89);
14
14
  --graphite: light-dark(#3A332B, #E8E0CE);
15
- --muted: light-dark(#948977, #7A715F);
15
+ --muted: light-dark(#786e5d, #89806d);
16
16
  /* Construction lines */
17
17
  --guide: light-dark(#C9BDA5, #4A4239);
18
18
  --guide-soft: light-dark(#DDD4C0, #382F27);
@@ -33,7 +33,7 @@
33
33
  --ink-soft: #D8D0BE;
34
34
  --ink-faint: #A89E89;
35
35
  --graphite: #E8E0CE;
36
- --muted: #7A715F;
36
+ --muted: #89806d;
37
37
  /* Construction lines — warm dark hairlines */
38
38
  --guide: #4A4239;
39
39
  --guide-soft: #382F27;
@@ -9,9 +9,9 @@
9
9
  /* Ink — warm pencil + sumi */
10
10
  --ink: #2A241E;
11
11
  --ink-soft: #4A4037;
12
- --ink-faint: #726858;
12
+ --ink-faint: #706757;
13
13
  --graphite: #3A332B;
14
- --muted: #948977;
14
+ --muted: #786e5d;
15
15
  /* Construction lines */
16
16
  --guide: #C9BDA5;
17
17
  --guide-soft: #DDD4C0;
@@ -9,7 +9,7 @@
9
9
  --paper-glass: rgba(79, 224, 120, 0.06);
10
10
  /* Ink — phosphor green on the tube */
11
11
  --ink: #4FE078;
12
- --ink-soft: #2A8B42;
12
+ --ink-soft: #34944a;
13
13
  --ink-faint: #3DAF4F;
14
14
  --graphite: #1A3D22;
15
15
  --muted: #2A8B42;
@@ -44,7 +44,7 @@
44
44
  --paper-glass: rgba(79, 224, 120, 0.06);
45
45
  /* Ink — phosphor green on the tube */
46
46
  --ink: #4FE078;
47
- --ink-soft: #2A8B42;
47
+ --ink-soft: #34944a;
48
48
  --ink-faint: #3DAF4F;
49
49
  --graphite: #1A3D22;
50
50
  --muted: #2A8B42;
@@ -66,7 +66,7 @@
66
66
  /* Code surface */
67
67
  --code-bg: #070A07;
68
68
  --code-ink: #4FE078;
69
- --code-muted: #2A8B42;
69
+ --code-muted: #329248;
70
70
  --code-accent: #F0A030;
71
71
  --code-green: #8FFCA8;
72
72
  --code-blue: #7FDBFF;
@@ -10,9 +10,9 @@
10
10
  /* Ink — near-black mono */
11
11
  --ink: #1A1A1A;
12
12
  --ink-soft: #404040;
13
- --ink-faint: #666;
13
+ --ink-faint: #626161;
14
14
  --graphite: #0A0A0A;
15
- --muted: #7C7C7C;
15
+ --muted: #696868;
16
16
  /* Hairlines — medium gray */
17
17
  --guide: #B8B8B8;
18
18
  --guide-soft: #C8C8C8;
@@ -31,9 +31,9 @@
31
31
  /* Code surface */
32
32
  --code-bg: #DDD;
33
33
  --code-ink: #1A1A1A;
34
- --code-muted: #5B5B5B;
34
+ --code-muted: #5b5a5a;
35
35
  --code-accent: #934407;
36
- --code-green: #006A28;
36
+ --code-green: #006928;
37
37
  --code-blue: #0451A5;
38
38
  /* Typography — mono everywhere */
39
39
  --font-mono: 'JetBrains Mono', 'IBM Plex Mono', 'Fira Code', ui-monospace, Consolas, Menlo, 'Courier New', monospace;
@@ -48,8 +48,11 @@
48
48
  // LIGHT + DARK
49
49
  // Pass `dark` (a second tokens object, same format) and every colour token
50
50
  // that differs becomes `light-dark(light, dark)` with `color-scheme: light dark`.
51
- // A single Tokens Studio file with paired top-level groups (`color-light` +
52
- // `color-dark`, or `light` + `dark`) is split the same way automatically.
51
+ // A single file with paired top-level groups is split automatically, and the
52
+ // two conventions mean different things: `color-light`/`color-dark` name a
53
+ // COLOUR SET (children are colours), while `light`/`dark` name a MODE whose
54
+ // group holds a FULL token set — colours, spacing, fonts, component
55
+ // overrides — which merges beside any groups shared outside the pair.
53
56
  // Without a dark side the block is single-mode: `color-scheme: <mode>`
54
57
  // (`mode`, default light).
55
58
  // ============================================================================
@@ -490,6 +493,17 @@ function applyPathAliases(p) {
490
493
 
491
494
  /** Returns { token, mapped: true } or { token, mapped: false } (verbatim fallback). */
492
495
  function mapPath(tokenPath, contract) {
496
+ if (typeof tokenPath !== 'string' || !tokenPath.trim()) {
497
+ throw new Error('mapPath: first argument must be a non-empty token path, e.g. "color.text.primary"');
498
+ }
499
+ // The contract is optional: omit it and the installed one is loaded. It used
500
+ // to be required, but only the generic-rule branch touched it — so a path in
501
+ // the explicit table appeared to work and the mistake surfaced later as a
502
+ // TypeError on some other path. Fail clearly or not at all.
503
+ if (contract == null) contract = loadContract(path.join(__dirname, '..'));
504
+ else if (!contract.all || typeof contract.all.has !== 'function') {
505
+ throw new Error('mapPath: second argument must be a contract from loadContract(); omit it to load the installed contract automatically');
506
+ }
493
507
  if (TOKEN_MAP[tokenPath]) return { token: TOKEN_MAP[tokenPath], mapped: true };
494
508
  const aliased = applyPathAliases(tokenPath);
495
509
  if (TOKEN_MAP[aliased]) return { token: TOKEN_MAP[aliased], mapped: true };
@@ -498,6 +512,26 @@ function mapPath(tokenPath, contract) {
498
512
  // camelCase segments → kebab (linkHover → link-hover), one more try.
499
513
  const kebab = `--${aliased.replace(/([a-z0-9])([A-Z])/g, '$1-$2').replace(/\./g, '-').toLowerCase()}`;
500
514
  if (contract.all.has(kebab)) return { token: kebab, mapped: true };
515
+ // Flat per-component form: `component.btn-radius` → `--btn-radius`. The
516
+ // explicit table carries the nested shape (`component.button.radius`), and
517
+ // it is tried first; this catches exporters that flatten the group instead.
518
+ // Generic-rule first means this can never shadow a real `--component-*`.
519
+ const flat = aliased.replace(/^components?\./, '');
520
+ if (flat !== aliased) {
521
+ const body = flat.replace(/\./g, '-').toLowerCase();
522
+ // `component.btn-radius` → `--btn-radius`.
523
+ if (contract.all.has(`--${body}`)) return { token: `--${body}`, mapped: true };
524
+ // The contract names per-component overrides two ways: radius trails the
525
+ // component (`--card-radius`) but shadow, border and duration lead it
526
+ // (`--shadow-card`). A flat exporter cannot know which, so try the swap:
527
+ // `card-shadow` → `--shadow-card`, `button-hover-duration` →
528
+ // `--duration-button-hover`. Only accepted if it is a real token.
529
+ const cut = body.lastIndexOf('-');
530
+ if (cut > 0) {
531
+ const swapped = `--${body.slice(cut + 1)}-${body.slice(0, cut)}`;
532
+ if (contract.all.has(swapped)) return { token: swapped, mapped: true };
533
+ }
534
+ }
501
535
  return { token: generic, mapped: false };
502
536
  }
503
537
 
@@ -530,16 +564,35 @@ function loadBase(ciaRoot, base) {
530
564
  // ---------------------------------------------------------------------------
531
565
  // Paired-mode detection for a single Tokens Studio / DTCG file
532
566
  // ---------------------------------------------------------------------------
533
- const PAIRS = [['color-light', 'color-dark'], ['light', 'dark'], ['colors-light', 'colors-dark']];
567
+ // Two different conventions look alike and must NOT be treated alike:
568
+ //
569
+ // `color-light` / `color-dark` name a COLOUR SET. The group's children are
570
+ // colours (`color-light.brand.primary`), so they nest under `color.`.
571
+ // `light` / `dark` name a MODE. The group holds a FULL token
572
+ // set — `color.*`, `spacing.*`, `font.*`, `component.*` — so its
573
+ // children merge at the TOP level, beside any shared groups.
574
+ //
575
+ // Wrapping a mode group in `color.` (which this did for every pair until
576
+ // 2026-09-19) silently mis-routed every non-colour group: `spacing.unit`
577
+ // became `color.spacing.unit` → `--spacing-unit`, so the theme lost its
578
+ // density knob while `validation.ok` stayed true, because the required token
579
+ // was quietly inherited from the base theme instead. Reported by a consumer
580
+ // against boilerplate's canonical DTCG layout.
581
+ const PAIRS = [
582
+ { light: 'color-light', dark: 'color-dark', wrap: 'color' },
583
+ { light: 'colors-light', dark: 'colors-dark', wrap: 'color' },
584
+ { light: 'light', dark: 'dark', wrap: null },
585
+ ];
534
586
 
535
587
  function splitPairedModes(tokens) {
536
588
  if (!isPlainObject(tokens)) return null;
537
- for (const [l, d] of PAIRS) {
589
+ for (const { light: l, dark: d, wrap } of PAIRS) {
538
590
  if (isPlainObject(tokens[l]) && isPlainObject(tokens[d])) {
539
591
  const rest = {};
540
592
  for (const [k, v] of Object.entries(tokens)) if (k !== l && k !== d) rest[k] = v;
541
- const light = { ...rest, color: tokens[l] };
542
- const dark = { ...rest, color: tokens[d] };
593
+ // Mode-specific groups win over shared ones on a key collision.
594
+ const light = wrap ? { ...rest, [wrap]: tokens[l] } : { ...rest, ...tokens[l] };
595
+ const dark = wrap ? { ...rest, [wrap]: tokens[d] } : { ...rest, ...tokens[d] };
543
596
  return { light, dark, groups: [l, d] };
544
597
  }
545
598
  }
@@ -25,7 +25,7 @@
25
25
  --ink-soft: #e2e8f0;
26
26
  --ink-faint: #94a3b8;
27
27
  --graphite: #f1f5f9;
28
- --muted: #64748b;
28
+ --muted: #718299;
29
29
 
30
30
  /* Lines — dark slate borders */
31
31
  --guide: #334155;
@@ -34,7 +34,7 @@
34
34
  --hair-soft: #0f172a;
35
35
 
36
36
  /* Primary accent — brighter blue for dark surfaces */
37
- --ai: #3b82f6;
37
+ --ai: #3d85f9;
38
38
  --ai-ink: #60a5fa;
39
39
  --ai-wash: #1e3a8a;
40
40
 
@@ -46,10 +46,10 @@
46
46
  /* Code — neutral light syntax surface */
47
47
  --code-bg: #f8fafc;
48
48
  --code-ink: #0f172a;
49
- --code-muted: #64748b;
50
- --code-accent: #c2410c;
51
- --code-green: #15803d;
52
- --code-blue: #2563eb;
49
+ --code-muted: #5e6d84;
50
+ --code-accent: #c04009;
51
+ --code-green: #0e7c3a;
52
+ --code-blue: #2461e9;
53
53
 
54
54
  /* Typography — system stacks only (no @import) */
55
55
  --font-display: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
@@ -151,12 +151,12 @@
151
151
  /* Status — success */
152
152
  --success-default: #16a34a;
153
153
  --success-subtle: #f0fdf4;
154
- --success-text: #15803d;
154
+ --success-text: #0e7c3a;
155
155
 
156
156
  /* Status — warning */
157
157
  --warning-default: var(--ochre);
158
158
  --warning-subtle: var(--ochre-wash);
159
- --warning-text: #b45309;
159
+ --warning-text: #b15003;
160
160
 
161
161
  /* Status — error */
162
162
  --error-default: var(--shu);
@@ -28,7 +28,7 @@
28
28
  --ink-soft: light-dark(#1e293b, #e2e8f0);
29
29
  --ink-faint: light-dark(#475569, #94a3b8);
30
30
  --graphite: light-dark(#0f172a, #f1f5f9);
31
- --muted: light-dark(#64748b, #64748b);
31
+ --muted: light-dark(#718299, #64748b);
32
32
 
33
33
  /* Lines */
34
34
  --guide: light-dark(#cbd5e1, #334155);
@@ -37,7 +37,7 @@
37
37
  --hair-soft: light-dark(#f1f5f9, #0f172a);
38
38
 
39
39
  /* Primary accent */
40
- --ai: light-dark(#2563eb, #3b82f6);
40
+ --ai: light-dark(#2563eb, #3d85f9);
41
41
  --ai-ink: light-dark(#1d4ed8, #60a5fa);
42
42
  --ai-wash: light-dark(#eff6ff, #1e3a8a);
43
43
 
@@ -53,9 +53,9 @@
53
53
  --code-bg: light-dark(#f8fafc, #020617);
54
54
  --code-ink: light-dark(#0f172a, #e2e8f0);
55
55
  --code-muted: light-dark(#5E6D83, #6F8098);
56
- --code-accent: light-dark(#C1410C, #fb923c);
56
+ --code-accent: light-dark(#c0400b, #fb923c);
57
57
  --code-green: light-dark(#147C3B, #4ade80);
58
- --code-blue: light-dark(#2362EB, #60a5fa);
58
+ --code-blue: light-dark(#2361ea, #60a5fa);
59
59
 
60
60
  /* Typography — system stacks, no @import, identical */
61
61
  --font-display: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
@@ -144,11 +144,11 @@
144
144
 
145
145
  --success-default: light-dark(#16a34a, #22c55e);
146
146
  --success-subtle: light-dark(#f0fdf4, #14532d);
147
- --success-text: light-dark(#15803d, #4ade80);
147
+ --success-text: light-dark(#0e7c3a, #4ade80);
148
148
 
149
149
  --warning-default: var(--ochre);
150
150
  --warning-subtle: var(--ochre-wash);
151
- --warning-text: light-dark(#b45309, #fbbf24);
151
+ --warning-text: light-dark(#b15003, #fbbf24);
152
152
 
153
153
  --error-default: var(--shu);
154
154
  --error-subtle: var(--shu-wash);
@@ -34,7 +34,7 @@
34
34
  --ink-soft: #C7C7CC;
35
35
  --ink-faint: #98989D;
36
36
  --graphite: #AEAEB2;
37
- --muted: #6E6E73;
37
+ --muted: #84858a;
38
38
 
39
39
  /* Hairlines / guides — translucent white */
40
40
  --guide: rgba(255, 255, 255, 0.16);
@@ -43,7 +43,7 @@
43
43
  --hair-soft: rgba(255, 255, 255, 0.06);
44
44
 
45
45
  /* Primary accent — Apple system blue (dark variant) */
46
- --ai: #0A84FF;
46
+ --ai: #1e8eff;
47
47
  --ai-ink: #409CFF;
48
48
  --ai-wash: rgba(10, 132, 255, 0.16);
49
49
 
@@ -59,7 +59,7 @@
59
59
  --ai-wash: #E5F0FB;
60
60
 
61
61
  /* Seal — system red */
62
- --shu: #FF3B30;
62
+ --shu: #f73229;
63
63
  --shu-wash: #FFEAE8;
64
64
 
65
65
  /* Accent — system orange / amber */
@@ -25,7 +25,7 @@
25
25
  --ink-soft: light-dark(#3A3A3C, #C7C7CC);
26
26
  --ink-faint: light-dark(#66666B, #98989D);
27
27
  --graphite: light-dark(#2C2C2E, #AEAEB2);
28
- --muted: light-dark(#6E6E73, #6E6E73);
28
+ --muted: light-dark(#84858a, #6E6E73);
29
29
 
30
30
  /* Hairlines — solid in light, translucent white in dark */
31
31
  --guide: light-dark(#D2D2D7, rgba(255, 255, 255, 0.16));
@@ -34,12 +34,12 @@
34
34
  --hair-soft: light-dark(#E5E5EA, rgba(255, 255, 255, 0.06));
35
35
 
36
36
  /* Primary accent — Apple system blue (dark variant brighter) */
37
- --ai: light-dark(#005EBB, #0A84FF);
37
+ --ai: light-dark(#005EBB, #1e8eff);
38
38
  --ai-ink: light-dark(#0058B0, #409CFF);
39
39
  --ai-wash: light-dark(#E5F0FB, rgba(10, 132, 255, 0.16));
40
40
 
41
41
  /* Seal — Apple system red */
42
- --shu: light-dark(#FF3B30, #FF453A);
42
+ --shu: light-dark(#f73229, #FF453A);
43
43
  --shu-wash: light-dark(#FFEAE8, rgba(255, 69, 58, 0.16));
44
44
 
45
45
  /* Accent — Apple system orange */
@@ -35,7 +35,7 @@
35
35
  --ink-soft: #C8CFE0;
36
36
  --ink-faint: #8A92A8;
37
37
  --graphite: #DCE2F0;
38
- --muted: #5A627A;
38
+ --muted: #727b93;
39
39
 
40
40
  /* Construction lines — translucent white hairlines */
41
41
  --guide: rgba(240, 244, 255, 0.16);
@@ -61,12 +61,12 @@
61
61
  --hair-soft: rgba(29, 29, 31, 0.04);
62
62
 
63
63
  /* Primary accent — iOS indigo */
64
- --ai: #5957E2;
64
+ --ai: #5653de;
65
65
  --ai-ink: #3634A3;
66
66
  --ai-wash: rgba(89, 87, 226, 0.12);
67
67
 
68
68
  /* Seal — iOS system pink (draft / emphasis) */
69
- --shu: #FF375F;
69
+ --shu: #f32856;
70
70
  --shu-wash: rgba(255, 55, 95, 0.12);
71
71
 
72
72
  /* Draft / marginalia — iOS orange */
@@ -78,7 +78,7 @@
78
78
  --code-ink: #F5F5F7;
79
79
  --code-muted: #BABABE;
80
80
  --code-accent: #FFD60A;
81
- --code-green: #30D158;
81
+ --code-green: #3ad85e;
82
82
  --code-blue: #64D2FF;
83
83
 
84
84
  /* Typography — SF system stack */
@@ -29,7 +29,7 @@
29
29
  --ink-soft: light-dark(#3A3A3C, #C8CFE0);
30
30
  --ink-faint: light-dark(#65656A, #8A92A8);
31
31
  --graphite: light-dark(#2C2C2E, #DCE2F0);
32
- --muted: light-dark(#6E6E73, #5A627A);
32
+ --muted: light-dark(#6E6E73, #727b93);
33
33
 
34
34
  /* Construction lines — translucent */
35
35
  --guide: light-dark(rgba(29, 29, 31, 0.14), rgba(240, 244, 255, 0.16));
@@ -38,12 +38,12 @@
38
38
  --hair-soft: light-dark(rgba(29, 29, 31, 0.04), rgba(240, 244, 255, 0.06));
39
39
 
40
40
  /* Primary accent — iOS indigo / vibrant dark blue */
41
- --ai: light-dark(#5957E2, #6FA9FF);
41
+ --ai: light-dark(#5653de, #6FA9FF);
42
42
  --ai-ink: light-dark(#3634A3, #93C2FF);
43
43
  --ai-wash: light-dark(rgba(89, 87, 226, 0.12), rgba(111, 169, 255, 0.16));
44
44
 
45
45
  /* Seal — iOS system pink */
46
- --shu: light-dark(#FF375F, #FF6B8A);
46
+ --shu: light-dark(#f32856, #FF6B8A);
47
47
  --shu-wash: light-dark(rgba(255, 55, 95, 0.12), rgba(255, 107, 138, 0.16));
48
48
 
49
49
  /* Draft / marginalia — iOS orange */
@@ -55,7 +55,7 @@
55
55
  --code-ink: light-dark(#F5F5F7, #F0F4FF);
56
56
  --code-muted: light-dark(#BCBCC0, #8A92A8);
57
57
  --code-accent: #FFD60A;
58
- --code-green: light-dark(#30D158, #5FE37F);
58
+ --code-green: light-dark(#3ad85e, #5FE37F);
59
59
  --code-blue: light-dark(#64D2FF, #93C2FF);
60
60
 
61
61
  /* Typography — SF stack, identical */