@oxyhq/bloom 0.36.0 → 0.37.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 (235) hide show
  1. package/lib/commonjs/theme/build-theme.js +31 -43
  2. package/lib/commonjs/theme/build-theme.js.map +1 -1
  3. package/lib/commonjs/theme/color-engine/cam16.js +161 -0
  4. package/lib/commonjs/theme/color-engine/cam16.js.map +1 -0
  5. package/lib/commonjs/theme/color-engine/color-role.js +183 -0
  6. package/lib/commonjs/theme/color-engine/color-role.js.map +1 -0
  7. package/lib/commonjs/theme/color-engine/color-roles.js +416 -0
  8. package/lib/commonjs/theme/color-engine/color-roles.js.map +1 -0
  9. package/lib/commonjs/theme/color-engine/color-utils.js +157 -0
  10. package/lib/commonjs/theme/color-engine/color-utils.js.map +1 -0
  11. package/lib/commonjs/theme/color-engine/contrast-curve.js +32 -0
  12. package/lib/commonjs/theme/color-engine/contrast-curve.js.map +1 -0
  13. package/lib/commonjs/theme/color-engine/contrast.js +70 -0
  14. package/lib/commonjs/theme/color-engine/contrast.js.map +1 -0
  15. package/lib/commonjs/theme/color-engine/dislike-analyzer.js +26 -0
  16. package/lib/commonjs/theme/color-engine/dislike-analyzer.js.map +1 -0
  17. package/lib/commonjs/theme/color-engine/dynamic-scheme.js +70 -0
  18. package/lib/commonjs/theme/color-engine/dynamic-scheme.js.map +1 -0
  19. package/lib/commonjs/theme/color-engine/hct-solver.js +236 -0
  20. package/lib/commonjs/theme/color-engine/hct-solver.js.map +1 -0
  21. package/lib/commonjs/theme/color-engine/hct.js +67 -0
  22. package/lib/commonjs/theme/color-engine/hct.js.map +1 -0
  23. package/lib/commonjs/theme/color-engine/index.js +173 -0
  24. package/lib/commonjs/theme/color-engine/index.js.map +1 -0
  25. package/lib/commonjs/theme/color-engine/lab-point-provider.js +32 -0
  26. package/lib/commonjs/theme/color-engine/lab-point-provider.js.map +1 -0
  27. package/lib/commonjs/theme/color-engine/math-utils.js +77 -0
  28. package/lib/commonjs/theme/color-engine/math-utils.js.map +1 -0
  29. package/lib/commonjs/theme/color-engine/quantizer-map.js +24 -0
  30. package/lib/commonjs/theme/color-engine/quantizer-map.js.map +1 -0
  31. package/lib/commonjs/theme/color-engine/quantizer-wu.js +266 -0
  32. package/lib/commonjs/theme/color-engine/quantizer-wu.js.map +1 -0
  33. package/lib/commonjs/theme/color-engine/scheme-variants.js +102 -0
  34. package/lib/commonjs/theme/color-engine/scheme-variants.js.map +1 -0
  35. package/lib/commonjs/theme/color-engine/score.js +80 -0
  36. package/lib/commonjs/theme/color-engine/score.js.map +1 -0
  37. package/lib/commonjs/theme/color-engine/seed-from-image.js +73 -0
  38. package/lib/commonjs/theme/color-engine/seed-from-image.js.map +1 -0
  39. package/lib/commonjs/theme/color-engine/tonal-palette.js +95 -0
  40. package/lib/commonjs/theme/color-engine/tonal-palette.js.map +1 -0
  41. package/lib/commonjs/theme/color-engine/tone-delta-pair.js +26 -0
  42. package/lib/commonjs/theme/color-engine/tone-delta-pair.js.map +1 -0
  43. package/lib/commonjs/theme/color-engine/variant.js +26 -0
  44. package/lib/commonjs/theme/color-engine/variant.js.map +1 -0
  45. package/lib/commonjs/theme/color-engine/viewing-conditions.js +61 -0
  46. package/lib/commonjs/theme/color-engine/viewing-conditions.js.map +1 -0
  47. package/lib/commonjs/theme/color-presets.js +44 -572
  48. package/lib/commonjs/theme/color-presets.js.map +1 -1
  49. package/lib/commonjs/theme/preset-vars.js +64 -47
  50. package/lib/commonjs/theme/preset-vars.js.map +1 -1
  51. package/lib/module/theme/build-theme.js +32 -44
  52. package/lib/module/theme/build-theme.js.map +1 -1
  53. package/lib/module/theme/color-engine/cam16.js +155 -0
  54. package/lib/module/theme/color-engine/cam16.js.map +1 -0
  55. package/lib/module/theme/color-engine/color-role.js +177 -0
  56. package/lib/module/theme/color-engine/color-role.js.map +1 -0
  57. package/lib/module/theme/color-engine/color-roles.js +411 -0
  58. package/lib/module/theme/color-engine/color-roles.js.map +1 -0
  59. package/lib/module/theme/color-engine/color-utils.js +135 -0
  60. package/lib/module/theme/color-engine/color-utils.js.map +1 -0
  61. package/lib/module/theme/color-engine/contrast-curve.js +26 -0
  62. package/lib/module/theme/color-engine/contrast-curve.js.map +1 -0
  63. package/lib/module/theme/color-engine/contrast.js +61 -0
  64. package/lib/module/theme/color-engine/contrast.js.map +1 -0
  65. package/lib/module/theme/color-engine/dislike-analyzer.js +20 -0
  66. package/lib/module/theme/color-engine/dislike-analyzer.js.map +1 -0
  67. package/lib/module/theme/color-engine/dynamic-scheme.js +65 -0
  68. package/lib/module/theme/color-engine/dynamic-scheme.js.map +1 -0
  69. package/lib/module/theme/color-engine/hct-solver.js +231 -0
  70. package/lib/module/theme/color-engine/hct-solver.js.map +1 -0
  71. package/lib/module/theme/color-engine/hct.js +61 -0
  72. package/lib/module/theme/color-engine/hct.js.map +1 -0
  73. package/lib/module/theme/color-engine/index.js +57 -0
  74. package/lib/module/theme/color-engine/index.js.map +1 -0
  75. package/lib/module/theme/color-engine/lab-point-provider.js +25 -0
  76. package/lib/module/theme/color-engine/lab-point-provider.js.map +1 -0
  77. package/lib/module/theme/color-engine/math-utils.js +65 -0
  78. package/lib/module/theme/color-engine/math-utils.js.map +1 -0
  79. package/lib/module/theme/color-engine/quantizer-map.js +20 -0
  80. package/lib/module/theme/color-engine/quantizer-map.js.map +1 -0
  81. package/lib/module/theme/color-engine/quantizer-wu.js +261 -0
  82. package/lib/module/theme/color-engine/quantizer-wu.js.map +1 -0
  83. package/lib/module/theme/color-engine/scheme-variants.js +93 -0
  84. package/lib/module/theme/color-engine/scheme-variants.js.map +1 -0
  85. package/lib/module/theme/color-engine/score.js +75 -0
  86. package/lib/module/theme/color-engine/score.js.map +1 -0
  87. package/lib/module/theme/color-engine/seed-from-image.js +67 -0
  88. package/lib/module/theme/color-engine/seed-from-image.js.map +1 -0
  89. package/lib/module/theme/color-engine/tonal-palette.js +89 -0
  90. package/lib/module/theme/color-engine/tonal-palette.js.map +1 -0
  91. package/lib/module/theme/color-engine/tone-delta-pair.js +21 -0
  92. package/lib/module/theme/color-engine/tone-delta-pair.js.map +1 -0
  93. package/lib/module/theme/color-engine/variant.js +22 -0
  94. package/lib/module/theme/color-engine/variant.js.map +1 -0
  95. package/lib/module/theme/color-engine/viewing-conditions.js +55 -0
  96. package/lib/module/theme/color-engine/viewing-conditions.js.map +1 -0
  97. package/lib/module/theme/color-presets.js +44 -572
  98. package/lib/module/theme/color-presets.js.map +1 -1
  99. package/lib/module/theme/preset-vars.js +64 -46
  100. package/lib/module/theme/preset-vars.js.map +1 -1
  101. package/lib/typescript/commonjs/theme/build-theme.d.ts.map +1 -1
  102. package/lib/typescript/commonjs/theme/color-engine/cam16.d.ts +26 -0
  103. package/lib/typescript/commonjs/theme/color-engine/cam16.d.ts.map +1 -0
  104. package/lib/typescript/commonjs/theme/color-engine/color-role.d.ts +36 -0
  105. package/lib/typescript/commonjs/theme/color-engine/color-role.d.ts.map +1 -0
  106. package/lib/typescript/commonjs/theme/color-engine/color-roles.d.ts +58 -0
  107. package/lib/typescript/commonjs/theme/color-engine/color-roles.d.ts.map +1 -0
  108. package/lib/typescript/commonjs/theme/color-engine/color-utils.d.ts +32 -0
  109. package/lib/typescript/commonjs/theme/color-engine/color-utils.d.ts.map +1 -0
  110. package/lib/typescript/commonjs/theme/color-engine/contrast-curve.d.ts +9 -0
  111. package/lib/typescript/commonjs/theme/color-engine/contrast-curve.d.ts.map +1 -0
  112. package/lib/typescript/commonjs/theme/color-engine/contrast.d.ts +12 -0
  113. package/lib/typescript/commonjs/theme/color-engine/contrast.d.ts.map +1 -0
  114. package/lib/typescript/commonjs/theme/color-engine/dislike-analyzer.d.ts +11 -0
  115. package/lib/typescript/commonjs/theme/color-engine/dislike-analyzer.d.ts.map +1 -0
  116. package/lib/typescript/commonjs/theme/color-engine/dynamic-scheme.d.ts +47 -0
  117. package/lib/typescript/commonjs/theme/color-engine/dynamic-scheme.d.ts.map +1 -0
  118. package/lib/typescript/commonjs/theme/color-engine/hct-solver.d.ts +6 -0
  119. package/lib/typescript/commonjs/theme/color-engine/hct-solver.d.ts.map +1 -0
  120. package/lib/typescript/commonjs/theme/color-engine/hct.d.ts +20 -0
  121. package/lib/typescript/commonjs/theme/color-engine/hct.d.ts.map +1 -0
  122. package/lib/typescript/commonjs/theme/color-engine/index.d.ts +44 -0
  123. package/lib/typescript/commonjs/theme/color-engine/index.d.ts.map +1 -0
  124. package/lib/typescript/commonjs/theme/color-engine/lab-point-provider.d.ts +6 -0
  125. package/lib/typescript/commonjs/theme/color-engine/lab-point-provider.d.ts.map +1 -0
  126. package/lib/typescript/commonjs/theme/color-engine/math-utils.d.ts +46 -0
  127. package/lib/typescript/commonjs/theme/color-engine/math-utils.d.ts.map +1 -0
  128. package/lib/typescript/commonjs/theme/color-engine/quantizer-map.d.ts +3 -0
  129. package/lib/typescript/commonjs/theme/color-engine/quantizer-map.d.ts.map +1 -0
  130. package/lib/typescript/commonjs/theme/color-engine/quantizer-wu.d.ts +3 -0
  131. package/lib/typescript/commonjs/theme/color-engine/quantizer-wu.d.ts.map +1 -0
  132. package/lib/typescript/commonjs/theme/color-engine/scheme-variants.d.ts +23 -0
  133. package/lib/typescript/commonjs/theme/color-engine/scheme-variants.d.ts.map +1 -0
  134. package/lib/typescript/commonjs/theme/color-engine/score.d.ts +8 -0
  135. package/lib/typescript/commonjs/theme/color-engine/score.d.ts.map +1 -0
  136. package/lib/typescript/commonjs/theme/color-engine/seed-from-image.d.ts +13 -0
  137. package/lib/typescript/commonjs/theme/color-engine/seed-from-image.d.ts.map +1 -0
  138. package/lib/typescript/commonjs/theme/color-engine/tonal-palette.d.ts +24 -0
  139. package/lib/typescript/commonjs/theme/color-engine/tonal-palette.d.ts.map +1 -0
  140. package/lib/typescript/commonjs/theme/color-engine/tone-delta-pair.d.ts +19 -0
  141. package/lib/typescript/commonjs/theme/color-engine/tone-delta-pair.d.ts.map +1 -0
  142. package/lib/typescript/commonjs/theme/color-engine/variant.d.ts +19 -0
  143. package/lib/typescript/commonjs/theme/color-engine/variant.d.ts.map +1 -0
  144. package/lib/typescript/commonjs/theme/color-engine/viewing-conditions.d.ts +18 -0
  145. package/lib/typescript/commonjs/theme/color-engine/viewing-conditions.d.ts.map +1 -0
  146. package/lib/typescript/commonjs/theme/color-presets.d.ts +25 -20
  147. package/lib/typescript/commonjs/theme/color-presets.d.ts.map +1 -1
  148. package/lib/typescript/commonjs/theme/preset-vars.d.ts +16 -12
  149. package/lib/typescript/commonjs/theme/preset-vars.d.ts.map +1 -1
  150. package/lib/typescript/module/theme/build-theme.d.ts.map +1 -1
  151. package/lib/typescript/module/theme/color-engine/cam16.d.ts +26 -0
  152. package/lib/typescript/module/theme/color-engine/cam16.d.ts.map +1 -0
  153. package/lib/typescript/module/theme/color-engine/color-role.d.ts +36 -0
  154. package/lib/typescript/module/theme/color-engine/color-role.d.ts.map +1 -0
  155. package/lib/typescript/module/theme/color-engine/color-roles.d.ts +58 -0
  156. package/lib/typescript/module/theme/color-engine/color-roles.d.ts.map +1 -0
  157. package/lib/typescript/module/theme/color-engine/color-utils.d.ts +32 -0
  158. package/lib/typescript/module/theme/color-engine/color-utils.d.ts.map +1 -0
  159. package/lib/typescript/module/theme/color-engine/contrast-curve.d.ts +9 -0
  160. package/lib/typescript/module/theme/color-engine/contrast-curve.d.ts.map +1 -0
  161. package/lib/typescript/module/theme/color-engine/contrast.d.ts +12 -0
  162. package/lib/typescript/module/theme/color-engine/contrast.d.ts.map +1 -0
  163. package/lib/typescript/module/theme/color-engine/dislike-analyzer.d.ts +11 -0
  164. package/lib/typescript/module/theme/color-engine/dislike-analyzer.d.ts.map +1 -0
  165. package/lib/typescript/module/theme/color-engine/dynamic-scheme.d.ts +47 -0
  166. package/lib/typescript/module/theme/color-engine/dynamic-scheme.d.ts.map +1 -0
  167. package/lib/typescript/module/theme/color-engine/hct-solver.d.ts +6 -0
  168. package/lib/typescript/module/theme/color-engine/hct-solver.d.ts.map +1 -0
  169. package/lib/typescript/module/theme/color-engine/hct.d.ts +20 -0
  170. package/lib/typescript/module/theme/color-engine/hct.d.ts.map +1 -0
  171. package/lib/typescript/module/theme/color-engine/index.d.ts +44 -0
  172. package/lib/typescript/module/theme/color-engine/index.d.ts.map +1 -0
  173. package/lib/typescript/module/theme/color-engine/lab-point-provider.d.ts +6 -0
  174. package/lib/typescript/module/theme/color-engine/lab-point-provider.d.ts.map +1 -0
  175. package/lib/typescript/module/theme/color-engine/math-utils.d.ts +46 -0
  176. package/lib/typescript/module/theme/color-engine/math-utils.d.ts.map +1 -0
  177. package/lib/typescript/module/theme/color-engine/quantizer-map.d.ts +3 -0
  178. package/lib/typescript/module/theme/color-engine/quantizer-map.d.ts.map +1 -0
  179. package/lib/typescript/module/theme/color-engine/quantizer-wu.d.ts +3 -0
  180. package/lib/typescript/module/theme/color-engine/quantizer-wu.d.ts.map +1 -0
  181. package/lib/typescript/module/theme/color-engine/scheme-variants.d.ts +23 -0
  182. package/lib/typescript/module/theme/color-engine/scheme-variants.d.ts.map +1 -0
  183. package/lib/typescript/module/theme/color-engine/score.d.ts +8 -0
  184. package/lib/typescript/module/theme/color-engine/score.d.ts.map +1 -0
  185. package/lib/typescript/module/theme/color-engine/seed-from-image.d.ts +13 -0
  186. package/lib/typescript/module/theme/color-engine/seed-from-image.d.ts.map +1 -0
  187. package/lib/typescript/module/theme/color-engine/tonal-palette.d.ts +24 -0
  188. package/lib/typescript/module/theme/color-engine/tonal-palette.d.ts.map +1 -0
  189. package/lib/typescript/module/theme/color-engine/tone-delta-pair.d.ts +19 -0
  190. package/lib/typescript/module/theme/color-engine/tone-delta-pair.d.ts.map +1 -0
  191. package/lib/typescript/module/theme/color-engine/variant.d.ts +19 -0
  192. package/lib/typescript/module/theme/color-engine/variant.d.ts.map +1 -0
  193. package/lib/typescript/module/theme/color-engine/viewing-conditions.d.ts +18 -0
  194. package/lib/typescript/module/theme/color-engine/viewing-conditions.d.ts.map +1 -0
  195. package/lib/typescript/module/theme/color-presets.d.ts +25 -20
  196. package/lib/typescript/module/theme/color-presets.d.ts.map +1 -1
  197. package/lib/typescript/module/theme/preset-vars.d.ts +16 -12
  198. package/lib/typescript/module/theme/preset-vars.d.ts.map +1 -1
  199. package/package.json +1 -1
  200. package/src/__tests__/BloomThemeProvider.test.tsx +9 -4
  201. package/src/__tests__/native-root-vars.test.ts +8 -4
  202. package/src/__tests__/preset-vars.test.ts +66 -37
  203. package/src/__tests__/theme.test.ts +20 -12
  204. package/src/theme/__tests__/__fixtures__/golden-resolved-tokens.json +509 -509
  205. package/src/theme/__tests__/__snapshots__/visual-gallery.test.tsx.snap +613 -613
  206. package/src/theme/__tests__/color-engine-golden.test.ts +81 -0
  207. package/src/theme/__tests__/fixtures/color-engine-golden.json +1 -0
  208. package/src/theme/__tests__/golden-tokens.test.ts +6 -7
  209. package/src/theme/__tests__/runtime-contract.test.ts +8 -8
  210. package/src/theme/__tests__/theme-colors-parity.test.ts +44 -88
  211. package/src/theme/build-theme.ts +32 -44
  212. package/src/theme/color-engine/cam16.ts +179 -0
  213. package/src/theme/color-engine/color-role.ts +217 -0
  214. package/src/theme/color-engine/color-roles.ts +435 -0
  215. package/src/theme/color-engine/color-utils.ts +157 -0
  216. package/src/theme/color-engine/contrast-curve.ts +25 -0
  217. package/src/theme/color-engine/contrast.ts +59 -0
  218. package/src/theme/color-engine/dislike-analyzer.ts +19 -0
  219. package/src/theme/color-engine/dynamic-scheme.ts +90 -0
  220. package/src/theme/color-engine/hct-solver.ts +263 -0
  221. package/src/theme/color-engine/hct.ts +69 -0
  222. package/src/theme/color-engine/index.ts +73 -0
  223. package/src/theme/color-engine/lab-point-provider.ts +26 -0
  224. package/src/theme/color-engine/math-utils.ts +69 -0
  225. package/src/theme/color-engine/quantizer-map.ts +17 -0
  226. package/src/theme/color-engine/quantizer-wu.ts +320 -0
  227. package/src/theme/color-engine/scheme-variants.ts +113 -0
  228. package/src/theme/color-engine/score.ts +82 -0
  229. package/src/theme/color-engine/seed-from-image.ts +64 -0
  230. package/src/theme/color-engine/tonal-palette.ts +94 -0
  231. package/src/theme/color-engine/tone-delta-pair.ts +21 -0
  232. package/src/theme/color-engine/variant.ts +18 -0
  233. package/src/theme/color-engine/viewing-conditions.ts +77 -0
  234. package/src/theme/color-presets.ts +54 -631
  235. package/src/theme/preset-vars.ts +65 -49
@@ -1,4 +1,4 @@
1
- import { APP_COLOR_NAMES, APP_COLOR_PRESETS } from '../theme/color-presets';
1
+ import { APP_COLOR_NAMES } from '../theme/color-presets';
2
2
  import { getPresetVars } from '../theme/preset-vars';
3
3
  import { getResolvedTokens } from '../theme/token-registry';
4
4
 
@@ -20,70 +20,99 @@ const EXTENDED_KEYS = [
20
20
  '--sidebar-ring',
21
21
  ] as const;
22
22
 
23
- describe('getPresetVars', () => {
24
- it('includes every base preset token plus extended tokens for all presets and modes', () => {
23
+ const BASE_KEYS = [
24
+ '--background',
25
+ '--foreground',
26
+ '--surface',
27
+ '--surface-foreground',
28
+ '--popover',
29
+ '--popover-foreground',
30
+ '--primary',
31
+ '--primary-foreground',
32
+ '--secondary',
33
+ '--secondary-foreground',
34
+ '--muted',
35
+ '--muted-foreground',
36
+ '--accent',
37
+ '--accent-foreground',
38
+ '--destructive',
39
+ '--border',
40
+ '--input',
41
+ '--ring',
42
+ '--sidebar',
43
+ ] as const;
44
+
45
+ describe('getPresetVars (engine-backed)', () => {
46
+ it('emits every base + extended token as a full rgb() color for all presets and modes', () => {
25
47
  for (const name of APP_COLOR_NAMES) {
26
48
  for (const mode of ['light', 'dark'] as const) {
27
49
  const vars = getPresetVars(name, mode);
28
- const base = mode === 'light' ? APP_COLOR_PRESETS[name].light : APP_COLOR_PRESETS[name].dark;
29
-
30
- for (const key of Object.keys(base)) {
31
- expect(vars[key]).toBe(base[key]);
32
- }
33
- for (const key of EXTENDED_KEYS) {
50
+ for (const key of [...BASE_KEYS, ...EXTENDED_KEYS]) {
34
51
  expect(vars[key]).toBeDefined();
52
+ // The engine emits `rgb(r g b)` directly — never a bare HSL triple.
53
+ expect(vars[key]).toMatch(/^rgb\(\d+ \d+ \d+\)$/);
35
54
  }
36
55
  }
37
56
  }
38
57
  });
39
58
 
40
- it('derives chart/sidebar hue from the preset primary', () => {
59
+ it('drives sidebar-primary / ring from the engine primary role', () => {
41
60
  const vars = getPresetVars('blue', 'light');
42
- const primary = APP_COLOR_PRESETS.blue.light['--primary'] ?? '';
43
- const primaryHue = primary.split(' ')[0] ?? '';
44
- const chart1 = vars['--chart-1'] ?? '';
45
- expect(chart1.startsWith(`${primaryHue} `)).toBe(true);
46
- expect(vars['--sidebar-primary']).toBe(primary);
61
+ expect(vars['--sidebar-primary']).toBe(vars['--primary']);
62
+ expect(vars['--ring']).toBe(vars['--primary']);
63
+ expect(vars['--chart-1']).toBe(vars['--primary']);
64
+ });
65
+
66
+ it('makes secondary a real contrast color, not a mirror of primary (the fix)', () => {
67
+ for (const name of APP_COLOR_NAMES) {
68
+ for (const mode of ['light', 'dark'] as const) {
69
+ const vars = getPresetVars(name, mode);
70
+ expect(vars['--secondary']).not.toBe(vars['--primary']);
71
+ }
72
+ }
47
73
  });
48
74
 
49
- it('returns raw HSL triples (no resolved colors) getResolvedTokens owns rgb', () => {
50
- // `getPresetVars` is the raw triple source feeding the single canonical
51
- // resolver. It must NOT pre-resolve to rgb/hsl, and the legacy resolved-color
52
- // companion universe must be gone (no key carries the resolved-color prefix).
75
+ it('makes card the lightest surface in light mode, darkest in dark (the fix)', () => {
76
+ const channels = (rgb: string): number[] =>
77
+ (rgb.match(/\d+/g) ?? []).map(Number);
78
+ const sum = (rgb: string): number => channels(rgb).reduce((a, b) => a + b, 0);
79
+
80
+ for (const name of APP_COLOR_NAMES) {
81
+ const light = getPresetVars(name, 'light');
82
+ // card (surfaceContainerLowest) must be lighter than background in light.
83
+ expect(sum(light['--card'] ?? '')).toBeGreaterThan(sum(light['--background'] ?? ''));
84
+
85
+ const dark = getPresetVars(name, 'dark');
86
+ // card must be darker than (or equal to) background in dark — correct inversion.
87
+ expect(sum(dark['--card'] ?? '')).toBeLessThanOrEqual(sum(dark['--background'] ?? ''));
88
+ }
89
+ });
90
+
91
+ it('carries no legacy resolved-color companion universe', () => {
53
92
  const vars = getPresetVars('green', 'dark');
54
- expect(vars['--primary']).toBe(APP_COLOR_PRESETS.green.dark['--primary']);
55
- expect(/^-?\d[\d.]*\s+[\d.]+%/.test(vars['--primary'] ?? '')).toBe(true);
56
93
  const legacyPrefix = `--${'color'}-`;
57
94
  expect(Object.keys(vars).some((k) => k.startsWith(legacyPrefix))).toBe(false);
58
95
  });
59
96
  });
60
97
 
61
98
  describe('getResolvedTokens (single canonical rgb pipeline)', () => {
62
- it('resolves every base + extended token to a space-separated rgb() string', () => {
99
+ it('passes the engine rgb() values through unchanged', () => {
63
100
  const resolved = getResolvedTokens('green', 'dark');
64
- const primaryTriple = APP_COLOR_PRESETS.green.dark['--primary'] ?? '';
65
- // No resolved-color companion universe anymore the base token is rgb.
66
- const legacyPrefix = `--${'color'}-`;
67
- expect(Object.keys(resolved).some((k) => k.startsWith(legacyPrefix))).toBe(false);
101
+ const raw = getPresetVars('green', 'dark');
102
+ // The engine already emits rgb(); getResolvedTokens must not re-touch it.
103
+ expect(resolved['--primary']).toBe(raw['--primary']);
104
+ expect(resolved['--card']).toBe(raw['--card']);
68
105
  expect(resolved['--primary']).toMatch(/^rgb\(\d+ \d+ \d+\)$/);
69
106
  expect(resolved['--card']).toMatch(/^rgb\(\d+ \d+ \d+\)$/);
70
- // primary triple resolves to the same rgb the registry produces.
71
- expect(resolved['--primary']).toBe(getResolvedTokens('green', 'dark')['--primary']);
72
- expect(primaryTriple).toMatch(/%/);
73
- });
74
-
75
- it('resolves --primary to rgb for the blue preset (matches web reference)', () => {
76
- // `blue` preset light `--primary` is `205 87% 53%` → rgb(31 153 239).
77
- const resolved = getResolvedTokens('blue', 'light');
78
- expect(resolved['--primary']).toBe('rgb(31 153 239)');
107
+ const legacyPrefix = `--${'color'}-`;
108
+ expect(Object.keys(resolved).some((k) => k.startsWith(legacyPrefix))).toBe(false);
79
109
  });
80
110
 
81
111
  it('produces a full CSS color for every base preset token of every preset/mode', () => {
82
112
  for (const name of APP_COLOR_NAMES) {
83
113
  for (const mode of ['light', 'dark'] as const) {
84
- const base = mode === 'light' ? APP_COLOR_PRESETS[name].light : APP_COLOR_PRESETS[name].dark;
85
114
  const resolved = getResolvedTokens(name, mode);
86
- for (const key of Object.keys(base)) {
115
+ for (const key of BASE_KEYS) {
87
116
  const value = resolved[key] ?? '';
88
117
  // A bare triple (`185 50% 5%`) is INVALID CSS — the incident. Every
89
118
  // base token must come out as a complete color the browser parses.
@@ -5,6 +5,7 @@ import {
5
5
  hexToAppColorName,
6
6
  } from '../theme/color-presets';
7
7
  import { buildTheme } from '../theme/build-theme';
8
+ import { getPresetVars } from '../theme/preset-vars';
8
9
  import { THEME_GRADIENTS } from '../theme/gradients';
9
10
  import type { Theme, ThemeColors, ThemeMode } from '../theme/types';
10
11
 
@@ -18,7 +19,9 @@ describe('Theme system', () => {
18
19
  }
19
20
  });
20
21
 
21
- it('each preset has both light and dark color variables', () => {
22
+ it('each preset generates both light and dark canonical tokens from its seed', () => {
23
+ // The palette is now engine-derived from the seed; every preset must
24
+ // produce a full canonical token set in both modes via `getPresetVars`.
22
25
  const requiredVars = [
23
26
  '--background',
24
27
  '--foreground',
@@ -32,31 +35,36 @@ describe('Theme system', () => {
32
35
  ];
33
36
 
34
37
  for (const name of APP_COLOR_NAMES) {
35
- const preset = APP_COLOR_PRESETS[name]!;
38
+ const light = getPresetVars(name, 'light');
39
+ const dark = getPresetVars(name, 'dark');
36
40
  for (const v of requiredVars) {
37
- expect(preset.light[v]).toBeDefined();
38
- expect(preset.dark[v]).toBeDefined();
41
+ expect(light[v]).toBeDefined();
42
+ expect(dark[v]).toBeDefined();
39
43
  }
40
44
  }
41
45
  });
42
46
 
43
47
  it('light and dark variants have different values', () => {
44
48
  for (const name of APP_COLOR_NAMES) {
45
- const preset = APP_COLOR_PRESETS[name]!;
46
49
  // Background should differ between light and dark
47
- expect(preset.light['--background']).not.toBe(preset.dark['--background']);
50
+ expect(getPresetVars(name, 'light')['--background']).not.toBe(
51
+ getPresetVars(name, 'dark')['--background'],
52
+ );
48
53
  }
49
54
  });
50
55
  });
51
56
 
52
57
  describe('buildTheme primaryForeground', () => {
53
58
  it('resolves a readable foreground for the primary fill per preset', () => {
54
- // blue's --primary-foreground is `0 0% 100%` → white (canonical sRGB rgb)
55
- expect(buildTheme('blue', 'light').colors.primaryForeground).toBe('rgb(255 255 255)');
56
- expect(buildTheme('blue', 'dark').colors.primaryForeground).toBe('rgb(255 255 255)');
57
- // yellow's --primary-foreground is `0 0% 0%` black (canonical sRGB rgb)
58
- expect(buildTheme('yellow', 'light').colors.primaryForeground).toBe('rgb(0 0 0)');
59
- expect(buildTheme('yellow', 'dark').colors.primaryForeground).toBe('rgb(0 0 0)');
59
+ // Every preset's primary foreground is the engine's `on-primary` role,
60
+ // surfaced as `--primary-foreground` — a legible on-primary contrast color.
61
+ for (const name of APP_COLOR_NAMES) {
62
+ for (const mode of ['light', 'dark'] as const) {
63
+ expect(buildTheme(name, mode).colors.primaryForeground).toBe(
64
+ getPresetVars(name, mode)['--primary-foreground'],
65
+ );
66
+ }
67
+ }
60
68
  });
61
69
 
62
70
  it('sets a primaryForeground for every preset in both modes', () => {