@hex-core/tokens 1.3.7 → 1.4.1

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.
package/dist/index.d.ts CHANGED
@@ -101,6 +101,22 @@ interface GenerateGlobalsCssOptions {
101
101
  * utilities like `bg-background` resolve directly. No `tailwind.config.ts` needed.
102
102
  */
103
103
  target?: "v3" | "v4";
104
+ /**
105
+ * Explicit content globs for Tailwind v4 to scan, relative to the CSS file.
106
+ *
107
+ * When set, the import becomes `@import "tailwindcss" source(none)` followed
108
+ * by one `@source` rule per glob — automatic detection is turned off.
109
+ *
110
+ * Pass this for an app generated *inside* an existing repository. Tailwind's
111
+ * automatic scan walks up past the app to the enclosing git root and reads
112
+ * whatever it finds — including binary files, whose bytes become class
113
+ * candidates and emit unparseable utilities. Scoping the scan to the app's
114
+ * own directories is the fix. Omit it for an app at the root of its own
115
+ * repository, where automatic detection is correct.
116
+ *
117
+ * Ignored when `target` is `"v3"`, which has no `@source` rule.
118
+ */
119
+ sources?: readonly string[];
104
120
  }
105
121
  /**
106
122
  * Generates a complete globals.css content with theme tokens and Tailwind directives.
@@ -110,6 +126,21 @@ interface GenerateGlobalsCssOptions {
110
126
  * @returns A full globals.css string ready to drop into `app/globals.css`.
111
127
  */
112
128
  declare function generateGlobalsCss(theme: Theme, options?: GenerateGlobalsCssOptions): string;
129
+ /**
130
+ * Emit only the token layer — the raw ramp, the semantic tokens, and the
131
+ * Tailwind `--color-*` bridge.
132
+ *
133
+ * Split out of {@link generateGlobalsCss} so a consumer that already owns
134
+ * its `@import`s, custom variants and non-colour `@theme` block can
135
+ * generate just the colours. The docs site does exactly that: its
136
+ * `globals.css` used to hand-copy this output four times over and carried
137
+ * a "KEEP IN SYNC" comment to prove it.
138
+ *
139
+ * @param theme - The theme to emit
140
+ * @returns The `:root` / `.dark` / `@theme inline` blocks, plus the base
141
+ * `body` and border rules
142
+ */
143
+ declare function generateThemeCssV4(theme: Theme): string;
113
144
 
114
145
  declare const defaultTheme: Theme;
115
146
 
@@ -419,4 +450,4 @@ declare function listThemes(): Array<{
419
450
  description: string;
420
451
  }>;
421
452
 
422
- export { COLOR_MODE_BANDS, type ColorMode, type DeriveDarkOptions, type DeriveForegroundOptions, type DeriveSecondaryOptions, RADIUS_PRESETS, type RadiusPreset, type ScopedRuntimeCssOptions, type TokenSetSeeds, buildTokenSet, colorInputToTokenValue, contrastRatio, defaultSemanticTokens, defaultTheme, deriveDarkFromLight, deriveForegroundFor, deriveSecondaryFromPrimary, emberTheme, generateGlobalsCss, getTheme, listThemes, midnightTheme, resolveSemanticToken, sharedTokens, themeToCss, themeToFlatJson, themeToScopedRuntimeCss, themeToTailwindConfig, themes, tokenLuminance };
453
+ export { COLOR_MODE_BANDS, type ColorMode, type DeriveDarkOptions, type DeriveForegroundOptions, type DeriveSecondaryOptions, RADIUS_PRESETS, type RadiusPreset, type ScopedRuntimeCssOptions, type TokenSetSeeds, buildTokenSet, colorInputToTokenValue, contrastRatio, defaultSemanticTokens, defaultTheme, deriveDarkFromLight, deriveForegroundFor, deriveSecondaryFromPrimary, emberTheme, generateGlobalsCss, generateThemeCssV4, getTheme, listThemes, midnightTheme, resolveSemanticToken, sharedTokens, themeToCss, themeToFlatJson, themeToScopedRuntimeCss, themeToTailwindConfig, themes, tokenLuminance };
package/dist/index.js CHANGED
@@ -1,4 +1,15 @@
1
1
  // src/transformer.ts
2
+ function extractRef(token) {
3
+ if (typeof token === "object" && token !== null && "ref" in token) {
4
+ const { ref: ref4 } = token;
5
+ return typeof ref4 === "string" ? ref4 : void 0;
6
+ }
7
+ return void 0;
8
+ }
9
+ function renderTokenValue(token) {
10
+ const key = extractRef(token);
11
+ return key === void 0 ? extractValue(token) : `var(--${key})`;
12
+ }
2
13
  function extractValue(token) {
3
14
  if (typeof token === "object" && token !== null && "value" in token) {
4
15
  return String(token.value);
@@ -15,14 +26,17 @@ function themeToCss(theme) {
15
26
  const lines = [];
16
27
  lines.push("@layer base {");
17
28
  lines.push(" :root {");
29
+ for (const [key, value] of Object.entries(theme.palette ?? {})) {
30
+ lines.push(` --${key}: ${value};`);
31
+ }
18
32
  for (const [key, token] of Object.entries(theme.tokens.light)) {
19
- lines.push(` --${key}: ${extractValue(token)};`);
33
+ lines.push(` --${key}: ${renderTokenValue(token)};`);
20
34
  }
21
35
  lines.push(" }");
22
36
  lines.push("");
23
37
  lines.push(" .dark {");
24
38
  for (const [key, token] of Object.entries(theme.tokens.dark)) {
25
- lines.push(` --${key}: ${extractValue(token)};`);
39
+ lines.push(` --${key}: ${renderTokenValue(token)};`);
26
40
  }
27
41
  lines.push(" }");
28
42
  lines.push("}");
@@ -80,8 +94,8 @@ function themeToScopedRuntimeCss(theme, options = {}) {
80
94
  return lines.join("\n");
81
95
  }
82
96
  function generateGlobalsCss(theme, options = {}) {
83
- const { target = "v3" } = options;
84
- if (target === "v4") return generateGlobalsCssV4(theme);
97
+ const { target = "v3", sources } = options;
98
+ if (target === "v4") return generateGlobalsCssV4(theme, sources);
85
99
  return generateGlobalsCssV3(theme);
86
100
  }
87
101
  function generateGlobalsCssV3(theme) {
@@ -102,28 +116,31 @@ function generateGlobalsCssV3(theme) {
102
116
  lines.push("}");
103
117
  return lines.join("\n");
104
118
  }
105
- function generateGlobalsCssV4(theme) {
119
+ function generateThemeCssV4(theme) {
106
120
  const lines = [];
107
- lines.push(`@import "tailwindcss";`);
108
- lines.push(`@import "tw-animate-css";`);
109
- lines.push("");
110
- lines.push("/* Class-based dark mode \u2014 set `.dark` on <html> via next-themes or your own provider. */");
111
- lines.push("@custom-variant dark (&:is(.dark *));");
112
- lines.push("");
113
121
  lines.push("/*");
114
122
  lines.push(" * Raw token triplets (H S% L%) \u2014 the source of truth that `hex theme edit`");
115
123
  lines.push(" * mutates, and that the @theme inline block below aliases into Tailwind's");
116
124
  lines.push(" * --color-<key> namespace.");
125
+ if (theme.palette) {
126
+ lines.push(" *");
127
+ lines.push(" * Tier 1 is the raw ramp; the semantic tokens below point at it with");
128
+ lines.push(" * var(). Re-tint the whole theme by overriding a ramp entry \u2014 every");
129
+ lines.push(" * semantic token that references it follows.");
130
+ }
117
131
  lines.push(" */");
118
132
  lines.push(":root {");
133
+ for (const [key, value] of Object.entries(theme.palette ?? {})) {
134
+ lines.push(` --${key}: ${value};`);
135
+ }
119
136
  for (const [key, token] of Object.entries(theme.tokens.light)) {
120
- lines.push(` --${key}: ${extractValue(token)};`);
137
+ lines.push(` --${key}: ${renderTokenValue(token)};`);
121
138
  }
122
139
  lines.push("}");
123
140
  lines.push("");
124
141
  lines.push(".dark {");
125
142
  for (const [key, token] of Object.entries(theme.tokens.dark)) {
126
- lines.push(` --${key}: ${extractValue(token)};`);
143
+ lines.push(` --${key}: ${renderTokenValue(token)};`);
127
144
  }
128
145
  lines.push("}");
129
146
  lines.push("");
@@ -149,6 +166,29 @@ function generateGlobalsCssV4(theme) {
149
166
  lines.push("}");
150
167
  return lines.join("\n");
151
168
  }
169
+ function generateGlobalsCssV4(theme, sources) {
170
+ const lines = [];
171
+ const scoped = sources !== void 0 && sources.length > 0;
172
+ if (scoped) {
173
+ lines.push("/*");
174
+ lines.push(" * `source(none)` turns off Tailwind's automatic content detection, which");
175
+ lines.push(" * would otherwise walk up past this app to the enclosing repository and read");
176
+ lines.push(" * binary files as class candidates, emitting utilities that fail to parse.");
177
+ lines.push(" * The @source rules below name this app's own files instead.");
178
+ lines.push(" */");
179
+ lines.push(`@import "tailwindcss" source(none);`);
180
+ for (const source of sources) lines.push(`@source "${source}";`);
181
+ } else {
182
+ lines.push(`@import "tailwindcss";`);
183
+ }
184
+ lines.push(`@import "tw-animate-css";`);
185
+ lines.push("");
186
+ lines.push("/* Class-based dark mode \u2014 set `.dark` on <html> via next-themes or your own provider. */");
187
+ lines.push("@custom-variant dark (&:is(.dark *));");
188
+ lines.push("");
189
+ lines.push(generateThemeCssV4(theme));
190
+ return lines.join("\n");
191
+ }
152
192
 
153
193
  // src/themes/shared.ts
154
194
  var sharedTokens = {
@@ -191,136 +231,216 @@ var sharedTokens = {
191
231
  };
192
232
 
193
233
  // src/themes/default.ts
234
+ var palette = {
235
+ // Slate — brand family.
236
+ "slate-50": "0 0% 98%",
237
+ "slate-100": "222 22.5% 89%",
238
+ "slate-200": "222 8% 90%",
239
+ "slate-300": "222 8% 65%",
240
+ "slate-400": "222 30% 60%",
241
+ "slate-500": "222 8% 38%",
242
+ "slate-600": "222 12% 24%",
243
+ "slate-700": "222 8% 12%",
244
+ "slate-800": "222 12% 14%",
245
+ "slate-900": "222 25% 18%",
246
+ "slate-950": "222 30% 11%",
247
+ "slate-muted": "222 5% 95.9%",
248
+ "slate-contrast": "240 10% 3.9%",
249
+ // Surface — page and card grounds.
250
+ "surface-light": "210 20% 98%",
251
+ "surface-dark": "210 15% 2%",
252
+ "surface-dark-raised": "210 15% 8%",
253
+ // Red — destructive family.
254
+ "red-600": "0 65% 43%",
255
+ "red-300": "0 48.8% 68%",
256
+ "red-contrast": "0 0% 8%",
257
+ // Chart — categorical, cycled by index.
258
+ "chart-light-1": "12 76% 61%",
259
+ "chart-light-2": "173 58% 39%",
260
+ "chart-light-3": "197 37% 50%",
261
+ "chart-light-4": "43 74% 49%",
262
+ "chart-light-5": "280 65% 60%",
263
+ "chart-light-6": "340 75% 55%",
264
+ "chart-dark-1": "12 76% 65%",
265
+ "chart-dark-2": "173 58% 55%",
266
+ "chart-dark-3": "197 37% 60%",
267
+ "chart-dark-4": "43 74% 60%",
268
+ "chart-dark-5": "280 65% 70%",
269
+ "chart-dark-6": "340 75% 65%"
270
+ };
271
+ function ref(key, type = "color") {
272
+ return { value: palette[key], ref: key, type };
273
+ }
194
274
  var defaultTheme = {
195
275
  name: "default",
196
276
  displayName: "Default",
197
277
  description: "A modern, elegant minimalism \u2014 restrained cool-hue grayscale (~222 family) with a graphite primary and tight 0.375rem radius. Designed to recede so content leads; the cool slate carries identity across light + dark.",
278
+ palette,
198
279
  tokens: {
199
280
  light: {
200
- background: { value: "210 20% 98%", type: "color" },
201
- foreground: { value: "222 30% 11%", type: "color" },
202
- card: { value: "210 20% 98%", type: "color" },
203
- "card-foreground": { value: "222 30% 11%", type: "color" },
204
- popover: { value: "210 20% 98%", type: "color" },
205
- "popover-foreground": { value: "222 30% 11%", type: "color" },
206
- primary: { value: "222 25% 18%", type: "color" },
207
- "primary-foreground": { value: "0 0% 98%", type: "color" },
208
- secondary: { value: "222 5% 95.9%", type: "color" },
209
- "secondary-foreground": { value: "240 10% 3.9%", type: "color" },
210
- muted: { value: "222 5% 95.9%", type: "color" },
211
- "muted-foreground": { value: "222 8% 38%", type: "color" },
212
- accent: { value: "222 5% 95.9%", type: "color" },
213
- "accent-foreground": { value: "240 10% 3.9%", type: "color" },
214
- destructive: { value: "0 65% 43%", type: "color" },
215
- "destructive-foreground": { value: "0 0% 98%", type: "color" },
216
- border: { value: "222 8% 90%", type: "color" },
217
- input: { value: "222 8% 90%", type: "color" },
218
- ring: { value: "222 25% 18%", type: "color" },
281
+ background: ref("surface-light"),
282
+ foreground: ref("slate-950"),
283
+ card: ref("surface-light"),
284
+ "card-foreground": ref("slate-950"),
285
+ popover: ref("surface-light"),
286
+ "popover-foreground": ref("slate-950"),
287
+ primary: ref("slate-900"),
288
+ "primary-foreground": ref("slate-50"),
289
+ secondary: ref("slate-muted"),
290
+ "secondary-foreground": ref("slate-contrast"),
291
+ muted: ref("slate-muted"),
292
+ "muted-foreground": ref("slate-500"),
293
+ accent: ref("slate-muted"),
294
+ "accent-foreground": ref("slate-contrast"),
295
+ // L=43% achieves ≥4.5:1 on the destructive/5 alert background.
296
+ // Gated by `pnpm a11y-audit`.
297
+ destructive: ref("red-600"),
298
+ "destructive-foreground": ref("slate-50"),
299
+ border: ref("slate-200"),
300
+ input: ref("slate-200"),
301
+ ring: ref("slate-900"),
219
302
  radius: { value: "0.375rem", type: "radius" },
220
- // Chart palette — perceptually distinct hues for diagram primitives
221
- // (sunburst, treemap, sankey, chord, funnel, pyramid, venn). The
222
- // monochrome `--primary`/`--accent` family is unfit for categorical
223
- // encoding; cycle through these by index instead.
224
- "chart-1": { value: "12 76% 61%", type: "color" },
225
- "chart-2": { value: "173 58% 39%", type: "color" },
226
- "chart-3": { value: "197 37% 50%", type: "color" },
227
- "chart-4": { value: "43 74% 49%", type: "color" },
228
- "chart-5": { value: "280 65% 60%", type: "color" },
229
- "chart-6": { value: "340 75% 55%", type: "color" },
303
+ "chart-1": ref("chart-light-1"),
304
+ "chart-2": ref("chart-light-2"),
305
+ "chart-3": ref("chart-light-3"),
306
+ "chart-4": ref("chart-light-4"),
307
+ "chart-5": ref("chart-light-5"),
308
+ "chart-6": ref("chart-light-6"),
230
309
  ...sharedTokens
231
310
  },
232
311
  dark: {
233
- background: { value: "210 15% 2%", type: "color" },
234
- foreground: { value: "222 22.5% 89%", type: "color" },
235
- // Card/popover lifted from L=8% L=14% so SVG-rendered surfaces
236
- // (org-chart cards, flowchart boxes) read as elevated against bg.
237
- card: { value: "222 12% 14%", type: "color" },
238
- popover: { value: "222 12% 14%", type: "color" },
239
- primary: { value: "222 30% 60%", type: "color" },
240
- secondary: { value: "222 8% 12%", type: "color" },
241
- muted: { value: "222 8% 12%", type: "color" },
242
- accent: { value: "222 8% 12%", type: "color" },
243
- // Lightness lifted from L=58% to L=68% so `text-destructive` on
244
- // the dark `--card` (L=14%) clears WCAG AA 4.5:1 contrast (was 4.02:1).
245
- destructive: { value: "0 48.8% 68%", type: "color" },
246
- // Border lifted from L=14% → L=24% so SVG outlines (chord arcs,
247
- // sankey segments, gantt grid) have actual definition.
248
- border: { value: "222 12% 24%", type: "color" },
249
- input: { value: "222 12% 24%", type: "color" },
250
- ring: { value: "222 30% 60%", type: "color" },
312
+ background: ref("surface-dark"),
313
+ foreground: ref("slate-100"),
314
+ // Card/popover sit one surface step above background (L=14% vs 2%)
315
+ // so SVG-rendered surfaces — org-chart cards, flowchart boxes
316
+ // read as elevated without box-shadow chrome.
317
+ card: ref("slate-800"),
318
+ popover: ref("slate-800"),
319
+ primary: ref("slate-400"),
320
+ secondary: ref("slate-700"),
321
+ muted: ref("slate-700"),
322
+ accent: ref("slate-700"),
323
+ // L=68%, not 58%, so `text-destructive` on the dark card clears
324
+ // WCAG AA 4.5:1 (was 4.02:1).
325
+ destructive: ref("red-300"),
326
+ // L=24%, not 14%, so SVG outlines — chord arcs, sankey segments,
327
+ // gantt grid have actual definition against the card.
328
+ border: ref("slate-600"),
329
+ input: ref("slate-600"),
330
+ ring: ref("slate-400"),
251
331
  radius: { value: "0.375rem", type: "radius" },
252
- "card-foreground": { value: "222 22.5% 89%", type: "color" },
253
- "popover-foreground": { value: "222 22.5% 89%", type: "color" },
254
- "primary-foreground": { value: "210 15% 8%", type: "color" },
255
- "secondary-foreground": { value: "222 22.5% 89%", type: "color" },
256
- "muted-foreground": { value: "222 8% 65%", type: "color" },
257
- "accent-foreground": { value: "222 22.5% 89%", type: "color" },
258
- "destructive-foreground": { value: "0 0% 8%", type: "color" },
259
- // Lifted lightness for legibility on near-black background.
260
- "chart-1": { value: "12 76% 65%", type: "color" },
261
- "chart-2": { value: "173 58% 55%", type: "color" },
262
- "chart-3": { value: "197 37% 60%", type: "color" },
263
- "chart-4": { value: "43 74% 60%", type: "color" },
264
- "chart-5": { value: "280 65% 70%", type: "color" },
265
- "chart-6": { value: "340 75% 65%", type: "color" },
332
+ "card-foreground": ref("slate-100"),
333
+ "popover-foreground": ref("slate-100"),
334
+ "primary-foreground": ref("surface-dark-raised"),
335
+ "secondary-foreground": ref("slate-100"),
336
+ "muted-foreground": ref("slate-300"),
337
+ "accent-foreground": ref("slate-100"),
338
+ "destructive-foreground": ref("red-contrast"),
339
+ "chart-1": ref("chart-dark-1"),
340
+ "chart-2": ref("chart-dark-2"),
341
+ "chart-3": ref("chart-dark-3"),
342
+ "chart-4": ref("chart-dark-4"),
343
+ "chart-5": ref("chart-dark-5"),
344
+ "chart-6": ref("chart-dark-6"),
266
345
  ...sharedTokens
267
346
  }
268
347
  }
269
348
  };
270
349
 
271
350
  // src/themes/midnight.ts
351
+ var palette2 = {
352
+ // Indigo — brand.
353
+ "indigo-400": "226 70% 65%",
354
+ "indigo-500": "226 70% 55%",
355
+ // Slate — cool neutral ramp, both modes.
356
+ "slate-0": "0 0% 100%",
357
+ "slate-25": "220 23% 99%",
358
+ "slate-50": "220 23% 97%",
359
+ "slate-100": "220 23% 95%",
360
+ "slate-150": "220 14% 94%",
361
+ "slate-200": "220 14% 92%",
362
+ "slate-300": "220 13% 88%",
363
+ "slate-400": "220 9% 70%",
364
+ "slate-500": "220 9% 38%",
365
+ "slate-800": "224 30% 15%",
366
+ "slate-825": "224 20% 14%",
367
+ "slate-850": "224 30% 13%",
368
+ "slate-900": "224 50% 7%",
369
+ "slate-950": "224 71% 4%",
370
+ // Red — destructive.
371
+ "red-300": "0 75% 65%",
372
+ "red-600": "0 72% 45%",
373
+ "red-950": "0 75% 15%",
374
+ // Chart — categorical, cycled by index.
375
+ "chart-light-1": "226 70% 55%",
376
+ "chart-light-2": "165 60% 40%",
377
+ "chart-light-3": "20 80% 55%",
378
+ "chart-light-4": "280 65% 60%",
379
+ "chart-light-5": "45 80% 55%",
380
+ "chart-light-6": "330 70% 55%",
381
+ "chart-dark-1": "226 70% 65%",
382
+ "chart-dark-2": "165 60% 55%",
383
+ "chart-dark-3": "20 80% 65%",
384
+ "chart-dark-4": "280 65% 70%",
385
+ "chart-dark-5": "45 80% 65%",
386
+ "chart-dark-6": "330 70% 65%"
387
+ };
388
+ function ref2(key, type = "color") {
389
+ return { value: palette2[key], ref: key, type };
390
+ }
272
391
  var midnightTheme = {
273
392
  name: "midnight",
274
393
  displayName: "Midnight",
275
394
  description: "A dark-first theme with deep blues and electric accents. Built for focus-heavy interfaces and developer tools.",
395
+ palette: palette2,
276
396
  tokens: {
277
397
  light: {
278
- background: { value: "220 23% 97%", type: "color" },
279
- foreground: { value: "224 71% 4%", type: "color" },
280
- card: { value: "220 23% 99%", type: "color" },
281
- "card-foreground": { value: "224 71% 4%", type: "color" },
282
- popover: { value: "220 23% 99%", type: "color" },
283
- "popover-foreground": { value: "224 71% 4%", type: "color" },
284
- primary: { value: "226 70% 55%", type: "color" },
285
- "primary-foreground": { value: "0 0% 100%", type: "color" },
286
- secondary: { value: "220 14% 92%", type: "color" },
287
- "secondary-foreground": { value: "224 71% 4%", type: "color" },
288
- muted: { value: "220 14% 94%", type: "color" },
289
- "muted-foreground": { value: "220 9% 38%", type: "color" },
290
- accent: { value: "220 14% 92%", type: "color" },
291
- "accent-foreground": { value: "224 71% 4%", type: "color" },
292
- destructive: { value: "0 72% 45%", type: "color" },
293
- "destructive-foreground": { value: "0 0% 100%", type: "color" },
294
- border: { value: "220 13% 88%", type: "color" },
295
- input: { value: "220 13% 88%", type: "color" },
296
- ring: { value: "226 70% 55%", type: "color" },
398
+ background: ref2("slate-50"),
399
+ foreground: ref2("slate-950"),
400
+ card: ref2("slate-25"),
401
+ "card-foreground": ref2("slate-950"),
402
+ popover: ref2("slate-25"),
403
+ "popover-foreground": ref2("slate-950"),
404
+ primary: ref2("indigo-500"),
405
+ "primary-foreground": ref2("slate-0"),
406
+ secondary: ref2("slate-200"),
407
+ "secondary-foreground": ref2("slate-950"),
408
+ muted: ref2("slate-150"),
409
+ "muted-foreground": ref2("slate-500"),
410
+ accent: ref2("slate-200"),
411
+ "accent-foreground": ref2("slate-950"),
412
+ destructive: ref2("red-600"),
413
+ "destructive-foreground": ref2("slate-0"),
414
+ border: ref2("slate-300"),
415
+ input: ref2("slate-300"),
416
+ ring: ref2("indigo-500"),
297
417
  radius: { value: "0.5rem", type: "radius" },
298
418
  // Chart palette — cool-leaning hues that complement the
299
419
  // midnight blue primary while staying perceptually distinct
300
420
  // for categorical encoding.
301
- "chart-1": { value: "226 70% 55%", type: "color" },
302
- "chart-2": { value: "165 60% 40%", type: "color" },
303
- "chart-3": { value: "20 80% 55%", type: "color" },
304
- "chart-4": { value: "280 65% 60%", type: "color" },
305
- "chart-5": { value: "45 80% 55%", type: "color" },
306
- "chart-6": { value: "330 70% 55%", type: "color" },
421
+ "chart-1": ref2("chart-light-1"),
422
+ "chart-2": ref2("chart-light-2"),
423
+ "chart-3": ref2("chart-light-3"),
424
+ "chart-4": ref2("chart-light-4"),
425
+ "chart-5": ref2("chart-light-5"),
426
+ "chart-6": ref2("chart-light-6"),
307
427
  ...sharedTokens
308
428
  },
309
429
  dark: {
310
- background: { value: "224 71% 4%", type: "color" },
311
- foreground: { value: "220 23% 95%", type: "color" },
312
- card: { value: "224 50% 7%", type: "color" },
313
- "card-foreground": { value: "220 23% 95%", type: "color" },
314
- popover: { value: "224 50% 7%", type: "color" },
315
- "popover-foreground": { value: "220 23% 95%", type: "color" },
316
- primary: { value: "226 70% 55%", type: "color" },
317
- "primary-foreground": { value: "0 0% 100%", type: "color" },
318
- secondary: { value: "224 30% 13%", type: "color" },
319
- "secondary-foreground": { value: "220 23% 95%", type: "color" },
320
- muted: { value: "224 30% 13%", type: "color" },
321
- "muted-foreground": { value: "220 9% 70%", type: "color" },
322
- accent: { value: "224 30% 15%", type: "color" },
323
- "accent-foreground": { value: "220 23% 95%", type: "color" },
430
+ background: ref2("slate-950"),
431
+ foreground: ref2("slate-100"),
432
+ card: ref2("slate-900"),
433
+ "card-foreground": ref2("slate-100"),
434
+ popover: ref2("slate-900"),
435
+ "popover-foreground": ref2("slate-100"),
436
+ primary: ref2("indigo-500"),
437
+ "primary-foreground": ref2("slate-0"),
438
+ secondary: ref2("slate-850"),
439
+ "secondary-foreground": ref2("slate-100"),
440
+ muted: ref2("slate-850"),
441
+ "muted-foreground": ref2("slate-400"),
442
+ accent: ref2("slate-800"),
443
+ "accent-foreground": ref2("slate-100"),
324
444
  /*
325
445
  * Destructive in dark mode doubles as text on near-black surfaces
326
446
  * (alerts, error helper text). A lighter coral-red gives ~7:1 on
@@ -328,98 +448,141 @@ var midnightTheme = {
328
448
  * destructive-foreground for button bg + label combos. Same tuning
329
449
  * as default.ts; intentional shadcn-divergence in service of WCAG AA.
330
450
  */
331
- destructive: { value: "0 75% 65%", type: "color" },
332
- "destructive-foreground": { value: "0 75% 15%", type: "color" },
333
- border: { value: "224 20% 14%", type: "color" },
334
- input: { value: "224 20% 14%", type: "color" },
335
- ring: { value: "226 70% 55%", type: "color" },
451
+ destructive: ref2("red-300"),
452
+ "destructive-foreground": ref2("red-950"),
453
+ border: ref2("slate-825"),
454
+ input: ref2("slate-825"),
455
+ ring: ref2("indigo-500"),
336
456
  radius: { value: "0.5rem", type: "radius" },
337
457
  // Lifted lightness so segments stay legible against deep navy bg.
338
- "chart-1": { value: "226 70% 65%", type: "color" },
339
- "chart-2": { value: "165 60% 55%", type: "color" },
340
- "chart-3": { value: "20 80% 65%", type: "color" },
341
- "chart-4": { value: "280 65% 70%", type: "color" },
342
- "chart-5": { value: "45 80% 65%", type: "color" },
343
- "chart-6": { value: "330 70% 65%", type: "color" },
458
+ "chart-1": ref2("chart-dark-1"),
459
+ "chart-2": ref2("chart-dark-2"),
460
+ "chart-3": ref2("chart-dark-3"),
461
+ "chart-4": ref2("chart-dark-4"),
462
+ "chart-5": ref2("chart-dark-5"),
463
+ "chart-6": ref2("chart-dark-6"),
344
464
  ...sharedTokens
345
465
  }
346
466
  }
347
467
  };
348
468
 
349
469
  // src/themes/ember.ts
470
+ var palette3 = {
471
+ // Ember — terracotta brand.
472
+ "ember-400": "16 65% 52%",
473
+ "ember-500": "16 65% 48%",
474
+ // Sand — warm light neutrals.
475
+ "sand-0": "0 0% 100%",
476
+ "sand-25": "30 33% 99%",
477
+ "sand-50": "30 33% 98%",
478
+ "sand-100": "30 20% 94%",
479
+ "sand-200": "30 20% 92%",
480
+ "sand-300": "30 15% 87%",
481
+ "amber-100": "36 60% 90%",
482
+ // Bark — warm dark neutrals.
483
+ "bark-400": "20 6% 70%",
484
+ "bark-500": "20 6% 38%",
485
+ "bark-800": "20 20% 16%",
486
+ "bark-825": "20 10% 16%",
487
+ "bark-850": "20 12% 14%",
488
+ "bark-900": "20 14% 10%",
489
+ "bark-925": "20 14% 8%",
490
+ "bark-950": "20 14% 6%",
491
+ // Red — destructive.
492
+ "red-300": "0 75% 65%",
493
+ "red-600": "0 72% 45%",
494
+ "red-950": "0 75% 15%",
495
+ // Chart — categorical, cycled by index.
496
+ "chart-light-1": "16 75% 55%",
497
+ "chart-light-2": "180 55% 38%",
498
+ "chart-light-3": "200 60% 50%",
499
+ "chart-light-4": "45 80% 50%",
500
+ "chart-light-5": "280 60% 60%",
501
+ "chart-light-6": "330 70% 55%",
502
+ "chart-dark-1": "16 75% 60%",
503
+ "chart-dark-2": "180 55% 55%",
504
+ "chart-dark-3": "200 60% 60%",
505
+ "chart-dark-4": "45 80% 60%",
506
+ "chart-dark-5": "280 60% 70%",
507
+ "chart-dark-6": "330 70% 65%"
508
+ };
509
+ function ref3(key, type = "color") {
510
+ return { value: palette3[key], ref: key, type };
511
+ }
350
512
  var emberTheme = {
351
513
  name: "ember",
352
514
  displayName: "Ember",
353
515
  description: "A warm theme with terracotta and amber tones. Inviting and distinctive, ideal for creative and lifestyle applications.",
516
+ palette: palette3,
354
517
  tokens: {
355
518
  light: {
356
- background: { value: "30 33% 98%", type: "color" },
357
- foreground: { value: "20 14% 10%", type: "color" },
358
- card: { value: "30 33% 99%", type: "color" },
359
- "card-foreground": { value: "20 14% 10%", type: "color" },
360
- popover: { value: "30 33% 99%", type: "color" },
361
- "popover-foreground": { value: "20 14% 10%", type: "color" },
362
- primary: { value: "16 65% 48%", type: "color" },
363
- "primary-foreground": { value: "0 0% 100%", type: "color" },
364
- secondary: { value: "30 20% 92%", type: "color" },
365
- "secondary-foreground": { value: "20 14% 10%", type: "color" },
366
- muted: { value: "30 20% 94%", type: "color" },
367
- "muted-foreground": { value: "20 6% 38%", type: "color" },
368
- accent: { value: "36 60% 90%", type: "color" },
369
- "accent-foreground": { value: "20 14% 10%", type: "color" },
370
- destructive: { value: "0 72% 45%", type: "color" },
371
- "destructive-foreground": { value: "0 0% 100%", type: "color" },
372
- border: { value: "30 15% 87%", type: "color" },
373
- input: { value: "30 15% 87%", type: "color" },
374
- ring: { value: "16 65% 48%", type: "color" },
519
+ background: ref3("sand-50"),
520
+ foreground: ref3("bark-900"),
521
+ card: ref3("sand-25"),
522
+ "card-foreground": ref3("bark-900"),
523
+ popover: ref3("sand-25"),
524
+ "popover-foreground": ref3("bark-900"),
525
+ primary: ref3("ember-500"),
526
+ "primary-foreground": ref3("sand-0"),
527
+ secondary: ref3("sand-200"),
528
+ "secondary-foreground": ref3("bark-900"),
529
+ muted: ref3("sand-100"),
530
+ "muted-foreground": ref3("bark-500"),
531
+ accent: ref3("amber-100"),
532
+ "accent-foreground": ref3("bark-900"),
533
+ destructive: ref3("red-600"),
534
+ "destructive-foreground": ref3("sand-0"),
535
+ border: ref3("sand-300"),
536
+ input: ref3("sand-300"),
537
+ ring: ref3("ember-500"),
375
538
  radius: { value: "0.75rem", type: "radius" },
376
539
  // Chart palette — warm-leaning hues that complement the ember
377
540
  // terracotta primary while staying perceptually distinct from
378
541
  // each other for categorical encoding (sunburst/treemap/sankey/
379
542
  // chord/funnel/pyramid/venn/matrix).
380
- "chart-1": { value: "16 75% 55%", type: "color" },
381
- "chart-2": { value: "180 55% 38%", type: "color" },
382
- "chart-3": { value: "200 60% 50%", type: "color" },
383
- "chart-4": { value: "45 80% 50%", type: "color" },
384
- "chart-5": { value: "280 60% 60%", type: "color" },
385
- "chart-6": { value: "330 70% 55%", type: "color" },
543
+ "chart-1": ref3("chart-light-1"),
544
+ "chart-2": ref3("chart-light-2"),
545
+ "chart-3": ref3("chart-light-3"),
546
+ "chart-4": ref3("chart-light-4"),
547
+ "chart-5": ref3("chart-light-5"),
548
+ "chart-6": ref3("chart-light-6"),
386
549
  ...sharedTokens
387
550
  },
388
551
  dark: {
389
- background: { value: "20 14% 6%", type: "color" },
390
- foreground: { value: "30 20% 94%", type: "color" },
391
- card: { value: "20 14% 8%", type: "color" },
392
- "card-foreground": { value: "30 20% 94%", type: "color" },
393
- popover: { value: "20 14% 8%", type: "color" },
394
- "popover-foreground": { value: "30 20% 94%", type: "color" },
395
- primary: { value: "16 65% 52%", type: "color" },
396
- "primary-foreground": { value: "0 0% 100%", type: "color" },
397
- secondary: { value: "20 12% 14%", type: "color" },
398
- "secondary-foreground": { value: "30 20% 94%", type: "color" },
399
- muted: { value: "20 12% 14%", type: "color" },
400
- "muted-foreground": { value: "20 6% 70%", type: "color" },
401
- accent: { value: "20 20% 16%", type: "color" },
402
- "accent-foreground": { value: "30 20% 94%", type: "color" },
552
+ background: ref3("bark-950"),
553
+ foreground: ref3("sand-100"),
554
+ card: ref3("bark-925"),
555
+ "card-foreground": ref3("sand-100"),
556
+ popover: ref3("bark-925"),
557
+ "popover-foreground": ref3("sand-100"),
558
+ primary: ref3("ember-400"),
559
+ "primary-foreground": ref3("sand-0"),
560
+ secondary: ref3("bark-850"),
561
+ "secondary-foreground": ref3("sand-100"),
562
+ muted: ref3("bark-850"),
563
+ "muted-foreground": ref3("bark-400"),
564
+ accent: ref3("bark-800"),
565
+ "accent-foreground": ref3("sand-100"),
403
566
  /*
404
567
  * Destructive in dark mode doubles as text on near-black surfaces
405
568
  * (alerts, error helper text). A lighter coral-red gives ~7:1 on
406
569
  * background and ~5:1 on the same color when paired with the dark
407
570
  * destructive-foreground. Same tuning as default.ts.
408
571
  */
409
- destructive: { value: "0 75% 65%", type: "color" },
410
- "destructive-foreground": { value: "0 75% 15%", type: "color" },
411
- border: { value: "20 10% 16%", type: "color" },
412
- input: { value: "20 10% 16%", type: "color" },
413
- ring: { value: "16 65% 52%", type: "color" },
572
+ destructive: ref3("red-300"),
573
+ "destructive-foreground": ref3("red-950"),
574
+ border: ref3("bark-825"),
575
+ input: ref3("bark-825"),
576
+ ring: ref3("ember-400"),
414
577
  radius: { value: "0.75rem", type: "radius" },
415
578
  // Lifted lightness so segments stay legible against the warm
416
579
  // near-black background.
417
- "chart-1": { value: "16 75% 60%", type: "color" },
418
- "chart-2": { value: "180 55% 55%", type: "color" },
419
- "chart-3": { value: "200 60% 60%", type: "color" },
420
- "chart-4": { value: "45 80% 60%", type: "color" },
421
- "chart-5": { value: "280 60% 70%", type: "color" },
422
- "chart-6": { value: "330 70% 65%", type: "color" },
580
+ "chart-1": ref3("chart-dark-1"),
581
+ "chart-2": ref3("chart-dark-2"),
582
+ "chart-3": ref3("chart-dark-3"),
583
+ "chart-4": ref3("chart-dark-4"),
584
+ "chart-5": ref3("chart-dark-5"),
585
+ "chart-6": ref3("chart-dark-6"),
423
586
  ...sharedTokens
424
587
  }
425
588
  }
@@ -722,6 +885,7 @@ export {
722
885
  deriveSecondaryFromPrimary,
723
886
  emberTheme,
724
887
  generateGlobalsCss,
888
+ generateThemeCssV4,
725
889
  getTheme,
726
890
  listThemes,
727
891
  midnightTheme,
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/transformer.ts","../src/themes/shared.ts","../src/themes/default.ts","../src/themes/midnight.ts","../src/themes/ember.ts","../src/semantic.ts","../src/lib/derive.ts","../src/lib/build-token-set.ts","../src/index.ts"],"sourcesContent":["import type { Theme } from \"@hex-core/registry\";\n\ninterface TokenLike {\n\tvalue: string;\n\ttype?: string;\n}\n\n/**\n * Extract the value string from a token-like object or primitive.\n * @param token - A token object with a `value` property, or a primitive\n * @returns The token's value as a string\n */\nfunction extractValue(token: unknown): string {\n\tif (typeof token === \"object\" && token !== null && \"value\" in token) {\n\t\treturn String((token as TokenLike).value);\n\t}\n\treturn String(token);\n}\n\n/**\n * Extract the type annotation from a token-like object.\n * @param token - A token object potentially containing a `type` property\n * @returns The token type string, or undefined if not present\n */\nfunction extractType(token: unknown): string | undefined {\n\tif (typeof token === \"object\" && token !== null && \"type\" in token) {\n\t\treturn (token as TokenLike).type;\n\t}\n\treturn undefined;\n}\n\n/**\n * Transforms a theme's token set into CSS custom properties.\n *\n * Output uses the **raw `--<key>` namespace** — value verbatim, no `hsl()`\n * wrapper, no `--color-` prefix. Colors land as triplets (e.g. `0 0% 100%`)\n * to enable alpha composition like `hsl(var(--background) / 0.5)`. Consumers\n * on Tailwind v4 also need a `@theme` block in the `--color-<key>` namespace;\n * see the \"CSS variable namespaces\" section in ./README.md for the bridge.\n *\n * @param theme - The theme to transform\n * @returns A CSS string with `:root` and `.dark` custom property declarations inside a `@layer base` block\n */\nexport function themeToCss(theme: Theme): string {\n\tconst lines: string[] = [];\n\n\tlines.push(\"@layer base {\");\n\tlines.push(\" :root {\");\n\tfor (const [key, token] of Object.entries(theme.tokens.light)) {\n\t\tlines.push(` --${key}: ${extractValue(token)};`);\n\t}\n\tlines.push(\" }\");\n\tlines.push(\"\");\n\tlines.push(\" .dark {\");\n\tfor (const [key, token] of Object.entries(theme.tokens.dark)) {\n\t\tlines.push(` --${key}: ${extractValue(token)};`);\n\t}\n\tlines.push(\" }\");\n\tlines.push(\"}\");\n\n\treturn lines.join(\"\\n\");\n}\n\n/**\n * Transforms a theme into a flat JSON map for AI consumption.\n * This is the most token-efficient format for LLMs.\n * @param theme - The theme to transform\n * @param mode - Color mode to extract tokens for (defaults to \"light\")\n * @returns A flat record mapping CSS variable names to their values\n */\nexport function themeToFlatJson(\n\ttheme: Theme,\n\tmode: \"light\" | \"dark\" = \"light\",\n): Record<string, string> {\n\tconst flat: Record<string, string> = {};\n\tconst tokens = mode === \"light\" ? theme.tokens.light : theme.tokens.dark;\n\n\tfor (const [key, token] of Object.entries(tokens)) {\n\t\tflat[`--${key}`] = extractValue(token);\n\t}\n\n\treturn flat;\n}\n\n/**\n * Transforms a theme into Tailwind CSS config extension.\n * @param theme - The theme to transform\n * @returns An object with maps for colors, borderRadius, spacing, fontSize,\n * transitionDuration, and height — suitable for Tailwind's `theme.extend`.\n */\nexport function themeToTailwindConfig(theme: Theme): Record<string, Record<string, string>> {\n\tconst colors: Record<string, string> = {};\n\tconst borderRadius: Record<string, string> = {};\n\tconst spacing: Record<string, string> = {};\n\tconst fontSize: Record<string, string> = {};\n\tconst transitionDuration: Record<string, string> = {};\n\tconst height: Record<string, string> = {};\n\n\tfor (const [key, token] of Object.entries(theme.tokens.light)) {\n\t\tconst type = extractType(token);\n\t\tif (!type) continue;\n\n\t\tif (type === \"color\") {\n\t\t\tcolors[key] = `hsl(var(--${key}))`;\n\t\t} else if (type === \"radius\") {\n\t\t\tborderRadius[key] = `var(--${key})`;\n\t\t} else if (type === \"spacing\") {\n\t\t\t// Strip \"space-\" / \"gap-\" prefix for cleaner Tailwind usage (e.g. `p-4` vs `p-space-4`).\n\t\t\tconst stripped = key.replace(/^(space-|gap-)/, \"\");\n\t\t\tspacing[stripped] = `var(--${key})`;\n\t\t} else if (type === \"dimension\") {\n\t\t\t// control-height-md → height.control-md\n\t\t\theight[key.replace(/^control-/, \"\")] = `var(--${key})`;\n\t\t} else if (type === \"font\") {\n\t\t\tfontSize[key.replace(/^text-/, \"\")] = `var(--${key})`;\n\t\t} else if (type === \"duration\") {\n\t\t\ttransitionDuration[key.replace(/^duration-/, \"\")] = `var(--${key})`;\n\t\t}\n\t}\n\n\treturn { colors, borderRadius, spacing, fontSize, transitionDuration, height };\n}\n\n/**\n * Options for {@link themeToScopedRuntimeCss}.\n */\nexport interface ScopedRuntimeCssOptions {\n\t/**\n\t * CSS selector that the generated rule targets. Defaults to `\":root\"`.\n\t *\n\t * Pass a class selector (e.g. `\".studio-canvas-active\"` or `\".theme-vivid\"`)\n\t * to scope the override to a subtree — useful when an app needs to flip\n\t * themes at runtime without round-tripping through `globals.css`. The vars\n\t * cascade to every descendant of an element matching the selector, so the\n\t * subtree's Tailwind utilities resolve against the new values automatically.\n\t */\n\tscope?: string;\n\t/**\n\t * Which palette to render. Defaults to `\"light\"`. Pass `\"dark\"` to emit the\n\t * theme's dark token set (typically used in combination with a `.dark` scope\n\t * applied by the consumer's theme provider).\n\t */\n\tmode?: \"light\" | \"dark\";\n}\n\n/**\n * Render a theme as scoped runtime CSS for the Tailwind v4 `--color-*` namespace.\n *\n * Unlike {@link themeToCss} (which emits at `:root` for static `globals.css`),\n * this targets a configurable selector so the override applies only to that\n * subtree. The output emits **both** namespaces so the result drops in cleanly\n * regardless of how the consumer's `globals.css` is wired:\n *\n * - `--<key>: <value>;` (raw triplet) — preserves alpha-composition utilities\n * like `bg-background/50` that read the variable as bare `H S% L%`.\n * - `--color-<key>: hsl(<value>);` (full `hsl()` string) — feeds Tailwind v4's\n * `@theme` block so generated utilities like `bg-background` / `text-primary`\n * resolve against the override.\n *\n * Non-color tokens (radii, durations, spacing, font sizes) only emit the raw\n * `--<key>` form since they don't go through `@theme`'s color machinery.\n *\n * @param theme - The theme to render\n * @param options - Scope selector + light/dark mode (see {@link ScopedRuntimeCssOptions}).\n * @returns A CSS string with one rule wrapping all the token declarations.\n *\n * @example\n * ```ts\n * import { defaultTheme, themeToScopedRuntimeCss } from \"@hex-core/tokens\";\n *\n * // Default: emits at :root for the light palette.\n * const css = themeToScopedRuntimeCss(defaultTheme);\n *\n * // Subtree-scoped runtime override (e.g. a theme studio's canvas):\n * const scoped = themeToScopedRuntimeCss(defaultTheme, {\n * scope: \".studio-canvas-active\",\n * mode: \"light\",\n * });\n *\n * // Inject via a <style> tag:\n * // <style dangerouslySetInnerHTML={{ __html: scoped }} />\n * ```\n */\nexport function themeToScopedRuntimeCss(\n\ttheme: Theme,\n\toptions: ScopedRuntimeCssOptions = {},\n): string {\n\tconst { scope = \":root\", mode = \"light\" } = options;\n\tconst tokens = mode === \"light\" ? theme.tokens.light : theme.tokens.dark;\n\n\tconst lines: string[] = [];\n\tlines.push(`${scope} {`);\n\tfor (const [key, token] of Object.entries(tokens)) {\n\t\tconst value = extractValue(token);\n\t\tconst type = extractType(token);\n\t\t// Always emit the raw `--<key>` form. For colors, also emit the\n\t\t// Tailwind v4 `--color-<key>` bridge wrapped in hsl() so `@theme`\n\t\t// blocks resolve correctly without the consumer hand-authoring the\n\t\t// bridge layer.\n\t\tlines.push(` --${key}: ${value};`);\n\t\tif (type === \"color\") {\n\t\t\tlines.push(` --color-${key}: hsl(${value});`);\n\t\t}\n\t}\n\tlines.push(\"}\");\n\n\treturn lines.join(\"\\n\");\n}\n\n/**\n * Options for {@link generateGlobalsCss}.\n */\nexport interface GenerateGlobalsCssOptions {\n\t/**\n\t * Tailwind major to target.\n\t * - `\"v3\"` (default, backward compatible): emits `@tailwind base/components/utilities`\n\t * plus `@layer base { :root {} .dark {} }` blocks. Pair with a `tailwind.config.ts`\n\t * that maps the raw `--<key>` CSS variables to color/radius utilities.\n\t * - `\"v4\"`: emits `@import \"tailwindcss\"` + `@theme { --color-<key>: hsl(...) }` so\n\t * utilities like `bg-background` resolve directly. No `tailwind.config.ts` needed.\n\t */\n\ttarget?: \"v3\" | \"v4\";\n}\n\n/**\n * Generates a complete globals.css content with theme tokens and Tailwind directives.\n *\n * @param theme - The theme to generate CSS for\n * @param options - Output target (Tailwind v3 vs v4). Defaults to v3 for backward compatibility.\n * @returns A full globals.css string ready to drop into `app/globals.css`.\n */\nexport function generateGlobalsCss(theme: Theme, options: GenerateGlobalsCssOptions = {}): string {\n\tconst { target = \"v3\" } = options;\n\tif (target === \"v4\") return generateGlobalsCssV4(theme);\n\treturn generateGlobalsCssV3(theme);\n}\n\nfunction generateGlobalsCssV3(theme: Theme): string {\n\tconst lines: string[] = [];\n\n\tlines.push(\"@tailwind base;\");\n\tlines.push(\"@tailwind components;\");\n\tlines.push(\"@tailwind utilities;\");\n\tlines.push(\"\");\n\tlines.push(themeToCss(theme));\n\tlines.push(\"\");\n\tlines.push(\"@layer base {\");\n\tlines.push(\" * {\");\n\tlines.push(\" @apply border-border;\");\n\tlines.push(\" }\");\n\tlines.push(\" body {\");\n\tlines.push(\" @apply bg-background text-foreground;\");\n\tlines.push(\" }\");\n\tlines.push(\"}\");\n\n\treturn lines.join(\"\\n\");\n}\n\nfunction generateGlobalsCssV4(theme: Theme): string {\n\tconst lines: string[] = [];\n\n\tlines.push(`@import \"tailwindcss\";`);\n\t// tw-animate-css ports tailwindcss-animate's animate-in/out, fade-*, slide-*,\n\t// zoom-* utilities to v4 as a pure CSS import. Every Hex component that\n\t// transitions (dialog, dropdown-menu, popover, accordion, ...) depends on\n\t// these classes, so it's not optional.\n\tlines.push(`@import \"tw-animate-css\";`);\n\tlines.push(\"\");\n\tlines.push(\"/* Class-based dark mode — set `.dark` on <html> via next-themes or your own provider. */\");\n\tlines.push(\"@custom-variant dark (&:is(.dark *));\");\n\tlines.push(\"\");\n\t// Bridge pattern: raw `H S% L%` triplets live in :root / .dark, and the\n\t// @theme inline block aliases each `--color-<key>` to `hsl(var(--<key>))`.\n\t// This shape is deliberate:\n\t// 1. Keeps the raw `--<key>` triplet that `hex theme edit` searches for —\n\t// direct values inside @theme would silently break that command.\n\t// 2. Keeps alpha-modifier utilities (bg-primary/50) cheap because the\n\t// `<H S% L%>` triplet composes via Tailwind v4's color-mix() machinery\n\t// with no per-utility re-derivation.\n\tlines.push(\"/*\");\n\tlines.push(\" * Raw token triplets (H S% L%) — the source of truth that `hex theme edit`\");\n\tlines.push(\" * mutates, and that the @theme inline block below aliases into Tailwind's\");\n\tlines.push(\" * --color-<key> namespace.\");\n\tlines.push(\" */\");\n\tlines.push(\":root {\");\n\tfor (const [key, token] of Object.entries(theme.tokens.light)) {\n\t\tlines.push(` --${key}: ${extractValue(token)};`);\n\t}\n\tlines.push(\"}\");\n\tlines.push(\"\");\n\tlines.push(\".dark {\");\n\tfor (const [key, token] of Object.entries(theme.tokens.dark)) {\n\t\tlines.push(` --${key}: ${extractValue(token)};`);\n\t}\n\tlines.push(\"}\");\n\tlines.push(\"\");\n\tlines.push(\"/*\");\n\tlines.push(\" * Tailwind v4 namespace bridge — generated utilities like bg-background\");\n\tlines.push(\" * resolve var(--color-background) here, which in turn reads var(--background)\");\n\tlines.push(\" * from the blocks above.\");\n\tlines.push(\" */\");\n\tlines.push(\"@theme inline {\");\n\tfor (const [key, token] of Object.entries(theme.tokens.light)) {\n\t\tif (extractType(token) !== \"color\") continue;\n\t\tlines.push(` --color-${key}: hsl(var(--${key}));`);\n\t}\n\tlines.push(\"}\");\n\tlines.push(\"\");\n\tlines.push(\"body {\");\n\tlines.push(\" background: var(--color-background);\");\n\tlines.push(\" color: var(--color-foreground);\");\n\tlines.push(\"}\");\n\tlines.push(\"\");\n\tlines.push(\"* {\");\n\tlines.push(\" border-color: var(--color-border);\");\n\tlines.push(\"}\");\n\n\treturn lines.join(\"\\n\");\n}\n","import type { TokenValue } from \"@hex-core/registry\";\n\n/**\n * Layout + typography tokens shared across all themes. Colors/radius vary per\n * theme; these do not (yet). Spread into both light and dark dicts of every\n * Theme so consumers can read any token regardless of color mode.\n */\nexport const sharedTokens: Record<string, TokenValue> = {\n\t// ─── Spacing scale (rem) ───\n\t\"space-1\": { value: \"0.25rem\", type: \"spacing\" },\n\t\"space-2\": { value: \"0.5rem\", type: \"spacing\" },\n\t\"space-3\": { value: \"0.75rem\", type: \"spacing\" },\n\t\"space-4\": { value: \"1rem\", type: \"spacing\" },\n\t\"space-6\": { value: \"1.5rem\", type: \"spacing\" },\n\t\"space-8\": { value: \"2rem\", type: \"spacing\" },\n\t\"space-12\": { value: \"3rem\", type: \"spacing\" },\n\t\"space-16\": { value: \"4rem\", type: \"spacing\" },\n\n\t// ─── Gap presets (for layout primitives) ───\n\t\"gap-xs\": { value: \"0.25rem\", type: \"spacing\" },\n\t\"gap-sm\": { value: \"0.5rem\", type: \"spacing\" },\n\t\"gap-md\": { value: \"1rem\", type: \"spacing\" },\n\t\"gap-lg\": { value: \"1.5rem\", type: \"spacing\" },\n\t\"gap-xl\": { value: \"2rem\", type: \"spacing\" },\n\n\t// ─── Container max-widths (for prose / layout primitives) ───\n\t\"container-sm\": { value: \"33rem\", type: \"dimension\" },\n\t\"container-md\": { value: \"40rem\", type: \"dimension\" },\n\t\"container-lg\": { value: \"50rem\", type: \"dimension\" },\n\t\"container-xl\": { value: \"66rem\", type: \"dimension\" },\n\n\t// ─── Control heights (interactive elements) ───\n\t\"control-height-sm\": { value: \"2.25rem\", type: \"dimension\" },\n\t\"control-height-md\": { value: \"2.5rem\", type: \"dimension\" },\n\t\"control-height-lg\": { value: \"2.75rem\", type: \"dimension\" },\n\n\t// ─── Typography scale ───\n\t\"text-xs\": { value: \"0.75rem\", type: \"font\" },\n\t\"text-sm\": { value: \"0.875rem\", type: \"font\" },\n\t\"text-base\": { value: \"1rem\", type: \"font\" },\n\t\"text-lg\": { value: \"1.125rem\", type: \"font\" },\n\t\"text-xl\": { value: \"1.25rem\", type: \"font\" },\n\t\"text-2xl\": { value: \"1.5rem\", type: \"font\" },\n\t\"text-3xl\": { value: \"1.875rem\", type: \"font\" },\n\n\t// ─── Motion ───\n\t\"duration-fast\": { value: \"150ms\", type: \"duration\" },\n\t\"duration-normal\": { value: \"200ms\", type: \"duration\" },\n\t\"duration-slow\": { value: \"300ms\", type: \"duration\" },\n};\n","import type { Theme } from \"@hex-core/registry\";\nimport { sharedTokens } from \"./shared.js\";\n\nexport const defaultTheme: Theme = {\n\tname: \"default\",\n\tdisplayName: \"Default\",\n\tdescription:\n\t\t\"A modern, elegant minimalism — restrained cool-hue grayscale (~222 family) with a graphite primary and tight 0.375rem radius. Designed to recede so content leads; the cool slate carries identity across light + dark.\",\n\ttokens: {\n\t\tlight: {\n\t\t\tbackground: { value: \"210 20% 98%\", type: \"color\" },\n\t\t\tforeground: { value: \"222 30% 11%\", type: \"color\" },\n\t\t\tcard: { value: \"210 20% 98%\", type: \"color\" },\n\t\t\t\"card-foreground\": { value: \"222 30% 11%\", type: \"color\" },\n\t\t\tpopover: { value: \"210 20% 98%\", type: \"color\" },\n\t\t\t\"popover-foreground\": { value: \"222 30% 11%\", type: \"color\" },\n\t\t\tprimary: { value: \"222 25% 18%\", type: \"color\" },\n\t\t\t\"primary-foreground\": { value: \"0 0% 98%\", type: \"color\" },\n\t\t\tsecondary: { value: \"222 5% 95.9%\", type: \"color\" },\n\t\t\t\"secondary-foreground\": { value: \"240 10% 3.9%\", type: \"color\" },\n\t\t\tmuted: { value: \"222 5% 95.9%\", type: \"color\" },\n\t\t\t\"muted-foreground\": { value: \"222 8% 38%\", type: \"color\" },\n\t\t\taccent: { value: \"222 5% 95.9%\", type: \"color\" },\n\t\t\t\"accent-foreground\": { value: \"240 10% 3.9%\", type: \"color\" },\n\t\t\tdestructive: { value: \"0 65% 43%\", type: \"color\" },\n\t\t\t\"destructive-foreground\": { value: \"0 0% 98%\", type: \"color\" },\n\t\t\tborder: { value: \"222 8% 90%\", type: \"color\" },\n\t\t\tinput: { value: \"222 8% 90%\", type: \"color\" },\n\t\t\tring: { value: \"222 25% 18%\", type: \"color\" },\n\t\t\tradius: { value: \"0.375rem\", type: \"radius\" },\n\t\t\t// Chart palette — perceptually distinct hues for diagram primitives\n\t\t\t// (sunburst, treemap, sankey, chord, funnel, pyramid, venn). The\n\t\t\t// monochrome `--primary`/`--accent` family is unfit for categorical\n\t\t\t// encoding; cycle through these by index instead.\n\t\t\t\"chart-1\": { value: \"12 76% 61%\", type: \"color\" },\n\t\t\t\"chart-2\": { value: \"173 58% 39%\", type: \"color\" },\n\t\t\t\"chart-3\": { value: \"197 37% 50%\", type: \"color\" },\n\t\t\t\"chart-4\": { value: \"43 74% 49%\", type: \"color\" },\n\t\t\t\"chart-5\": { value: \"280 65% 60%\", type: \"color\" },\n\t\t\t\"chart-6\": { value: \"340 75% 55%\", type: \"color\" },\n\t\t\t...sharedTokens,\n\t\t},\n\t\tdark: {\n\t\t\tbackground: { value: \"210 15% 2%\", type: \"color\" },\n\t\t\tforeground: { value: \"222 22.5% 89%\", type: \"color\" },\n\t\t\t// Card/popover lifted from L=8% → L=14% so SVG-rendered surfaces\n\t\t\t// (org-chart cards, flowchart boxes) read as elevated against bg.\n\t\t\tcard: { value: \"222 12% 14%\", type: \"color\" },\n\t\t\tpopover: { value: \"222 12% 14%\", type: \"color\" },\n\t\t\tprimary: { value: \"222 30% 60%\", type: \"color\" },\n\t\t\tsecondary: { value: \"222 8% 12%\", type: \"color\" },\n\t\t\tmuted: { value: \"222 8% 12%\", type: \"color\" },\n\t\t\taccent: { value: \"222 8% 12%\", type: \"color\" },\n\t\t\t// Lightness lifted from L=58% to L=68% so `text-destructive` on\n\t\t\t// the dark `--card` (L=14%) clears WCAG AA 4.5:1 contrast (was 4.02:1).\n\t\t\tdestructive: { value: \"0 48.8% 68%\", type: \"color\" },\n\t\t\t// Border lifted from L=14% → L=24% so SVG outlines (chord arcs,\n\t\t\t// sankey segments, gantt grid) have actual definition.\n\t\t\tborder: { value: \"222 12% 24%\", type: \"color\" },\n\t\t\tinput: { value: \"222 12% 24%\", type: \"color\" },\n\t\t\tring: { value: \"222 30% 60%\", type: \"color\" },\n\t\t\tradius: { value: \"0.375rem\", type: \"radius\" },\n\t\t\t\"card-foreground\": { value: \"222 22.5% 89%\", type: \"color\" },\n\t\t\t\"popover-foreground\": { value: \"222 22.5% 89%\", type: \"color\" },\n\t\t\t\"primary-foreground\": { value: \"210 15% 8%\", type: \"color\" },\n\t\t\t\"secondary-foreground\": { value: \"222 22.5% 89%\", type: \"color\" },\n\t\t\t\"muted-foreground\": { value: \"222 8% 65%\", type: \"color\" },\n\t\t\t\"accent-foreground\": { value: \"222 22.5% 89%\", type: \"color\" },\n\t\t\t\"destructive-foreground\": { value: \"0 0% 8%\", type: \"color\" },\n\t\t\t// Lifted lightness for legibility on near-black background.\n\t\t\t\"chart-1\": { value: \"12 76% 65%\", type: \"color\" },\n\t\t\t\"chart-2\": { value: \"173 58% 55%\", type: \"color\" },\n\t\t\t\"chart-3\": { value: \"197 37% 60%\", type: \"color\" },\n\t\t\t\"chart-4\": { value: \"43 74% 60%\", type: \"color\" },\n\t\t\t\"chart-5\": { value: \"280 65% 70%\", type: \"color\" },\n\t\t\t\"chart-6\": { value: \"340 75% 65%\", type: \"color\" },\n\t\t\t...sharedTokens,\n\t\t},\n\t},\n};\n","import type { Theme } from \"@hex-core/registry\";\nimport { sharedTokens } from \"./shared.js\";\n\nexport const midnightTheme: Theme = {\n\tname: \"midnight\",\n\tdisplayName: \"Midnight\",\n\tdescription:\n\t\t\"A dark-first theme with deep blues and electric accents. Built for focus-heavy interfaces and developer tools.\",\n\ttokens: {\n\t\tlight: {\n\t\t\tbackground: { value: \"220 23% 97%\", type: \"color\" },\n\t\t\tforeground: { value: \"224 71% 4%\", type: \"color\" },\n\t\t\tcard: { value: \"220 23% 99%\", type: \"color\" },\n\t\t\t\"card-foreground\": { value: \"224 71% 4%\", type: \"color\" },\n\t\t\tpopover: { value: \"220 23% 99%\", type: \"color\" },\n\t\t\t\"popover-foreground\": { value: \"224 71% 4%\", type: \"color\" },\n\t\t\tprimary: { value: \"226 70% 55%\", type: \"color\" },\n\t\t\t\"primary-foreground\": { value: \"0 0% 100%\", type: \"color\" },\n\t\t\tsecondary: { value: \"220 14% 92%\", type: \"color\" },\n\t\t\t\"secondary-foreground\": { value: \"224 71% 4%\", type: \"color\" },\n\t\t\tmuted: { value: \"220 14% 94%\", type: \"color\" },\n\t\t\t\"muted-foreground\": { value: \"220 9% 38%\", type: \"color\" },\n\t\t\taccent: { value: \"220 14% 92%\", type: \"color\" },\n\t\t\t\"accent-foreground\": { value: \"224 71% 4%\", type: \"color\" },\n\t\t\tdestructive: { value: \"0 72% 45%\", type: \"color\" },\n\t\t\t\"destructive-foreground\": { value: \"0 0% 100%\", type: \"color\" },\n\t\t\tborder: { value: \"220 13% 88%\", type: \"color\" },\n\t\t\tinput: { value: \"220 13% 88%\", type: \"color\" },\n\t\t\tring: { value: \"226 70% 55%\", type: \"color\" },\n\t\t\tradius: { value: \"0.5rem\", type: \"radius\" },\n\t\t\t// Chart palette — cool-leaning hues that complement the\n\t\t\t// midnight blue primary while staying perceptually distinct\n\t\t\t// for categorical encoding.\n\t\t\t\"chart-1\": { value: \"226 70% 55%\", type: \"color\" },\n\t\t\t\"chart-2\": { value: \"165 60% 40%\", type: \"color\" },\n\t\t\t\"chart-3\": { value: \"20 80% 55%\", type: \"color\" },\n\t\t\t\"chart-4\": { value: \"280 65% 60%\", type: \"color\" },\n\t\t\t\"chart-5\": { value: \"45 80% 55%\", type: \"color\" },\n\t\t\t\"chart-6\": { value: \"330 70% 55%\", type: \"color\" },\n\t\t\t...sharedTokens,\n\t\t},\n\t\tdark: {\n\t\t\tbackground: { value: \"224 71% 4%\", type: \"color\" },\n\t\t\tforeground: { value: \"220 23% 95%\", type: \"color\" },\n\t\t\tcard: { value: \"224 50% 7%\", type: \"color\" },\n\t\t\t\"card-foreground\": { value: \"220 23% 95%\", type: \"color\" },\n\t\t\tpopover: { value: \"224 50% 7%\", type: \"color\" },\n\t\t\t\"popover-foreground\": { value: \"220 23% 95%\", type: \"color\" },\n\t\t\tprimary: { value: \"226 70% 55%\", type: \"color\" },\n\t\t\t\"primary-foreground\": { value: \"0 0% 100%\", type: \"color\" },\n\t\t\tsecondary: { value: \"224 30% 13%\", type: \"color\" },\n\t\t\t\"secondary-foreground\": { value: \"220 23% 95%\", type: \"color\" },\n\t\t\tmuted: { value: \"224 30% 13%\", type: \"color\" },\n\t\t\t\"muted-foreground\": { value: \"220 9% 70%\", type: \"color\" },\n\t\t\taccent: { value: \"224 30% 15%\", type: \"color\" },\n\t\t\t\"accent-foreground\": { value: \"220 23% 95%\", type: \"color\" },\n\t\t\t/*\n\t\t\t * Destructive in dark mode doubles as text on near-black surfaces\n\t\t\t * (alerts, error helper text). A lighter coral-red gives ~7:1 on\n\t\t\t * background and ~5:1 on the same color when paired with the dark\n\t\t\t * destructive-foreground for button bg + label combos. Same tuning\n\t\t\t * as default.ts; intentional shadcn-divergence in service of WCAG AA.\n\t\t\t */\n\t\t\tdestructive: { value: \"0 75% 65%\", type: \"color\" },\n\t\t\t\"destructive-foreground\": { value: \"0 75% 15%\", type: \"color\" },\n\t\t\tborder: { value: \"224 20% 14%\", type: \"color\" },\n\t\t\tinput: { value: \"224 20% 14%\", type: \"color\" },\n\t\t\tring: { value: \"226 70% 55%\", type: \"color\" },\n\t\t\tradius: { value: \"0.5rem\", type: \"radius\" },\n\t\t\t// Lifted lightness so segments stay legible against deep navy bg.\n\t\t\t\"chart-1\": { value: \"226 70% 65%\", type: \"color\" },\n\t\t\t\"chart-2\": { value: \"165 60% 55%\", type: \"color\" },\n\t\t\t\"chart-3\": { value: \"20 80% 65%\", type: \"color\" },\n\t\t\t\"chart-4\": { value: \"280 65% 70%\", type: \"color\" },\n\t\t\t\"chart-5\": { value: \"45 80% 65%\", type: \"color\" },\n\t\t\t\"chart-6\": { value: \"330 70% 65%\", type: \"color\" },\n\t\t\t...sharedTokens,\n\t\t},\n\t},\n};\n","import type { Theme } from \"@hex-core/registry\";\nimport { sharedTokens } from \"./shared.js\";\n\nexport const emberTheme: Theme = {\n\tname: \"ember\",\n\tdisplayName: \"Ember\",\n\tdescription:\n\t\t\"A warm theme with terracotta and amber tones. Inviting and distinctive, ideal for creative and lifestyle applications.\",\n\ttokens: {\n\t\tlight: {\n\t\t\tbackground: { value: \"30 33% 98%\", type: \"color\" },\n\t\t\tforeground: { value: \"20 14% 10%\", type: \"color\" },\n\t\t\tcard: { value: \"30 33% 99%\", type: \"color\" },\n\t\t\t\"card-foreground\": { value: \"20 14% 10%\", type: \"color\" },\n\t\t\tpopover: { value: \"30 33% 99%\", type: \"color\" },\n\t\t\t\"popover-foreground\": { value: \"20 14% 10%\", type: \"color\" },\n\t\t\tprimary: { value: \"16 65% 48%\", type: \"color\" },\n\t\t\t\"primary-foreground\": { value: \"0 0% 100%\", type: \"color\" },\n\t\t\tsecondary: { value: \"30 20% 92%\", type: \"color\" },\n\t\t\t\"secondary-foreground\": { value: \"20 14% 10%\", type: \"color\" },\n\t\t\tmuted: { value: \"30 20% 94%\", type: \"color\" },\n\t\t\t\"muted-foreground\": { value: \"20 6% 38%\", type: \"color\" },\n\t\t\taccent: { value: \"36 60% 90%\", type: \"color\" },\n\t\t\t\"accent-foreground\": { value: \"20 14% 10%\", type: \"color\" },\n\t\t\tdestructive: { value: \"0 72% 45%\", type: \"color\" },\n\t\t\t\"destructive-foreground\": { value: \"0 0% 100%\", type: \"color\" },\n\t\t\tborder: { value: \"30 15% 87%\", type: \"color\" },\n\t\t\tinput: { value: \"30 15% 87%\", type: \"color\" },\n\t\t\tring: { value: \"16 65% 48%\", type: \"color\" },\n\t\t\tradius: { value: \"0.75rem\", type: \"radius\" },\n\t\t\t// Chart palette — warm-leaning hues that complement the ember\n\t\t\t// terracotta primary while staying perceptually distinct from\n\t\t\t// each other for categorical encoding (sunburst/treemap/sankey/\n\t\t\t// chord/funnel/pyramid/venn/matrix).\n\t\t\t\"chart-1\": { value: \"16 75% 55%\", type: \"color\" },\n\t\t\t\"chart-2\": { value: \"180 55% 38%\", type: \"color\" },\n\t\t\t\"chart-3\": { value: \"200 60% 50%\", type: \"color\" },\n\t\t\t\"chart-4\": { value: \"45 80% 50%\", type: \"color\" },\n\t\t\t\"chart-5\": { value: \"280 60% 60%\", type: \"color\" },\n\t\t\t\"chart-6\": { value: \"330 70% 55%\", type: \"color\" },\n\t\t\t...sharedTokens,\n\t\t},\n\t\tdark: {\n\t\t\tbackground: { value: \"20 14% 6%\", type: \"color\" },\n\t\t\tforeground: { value: \"30 20% 94%\", type: \"color\" },\n\t\t\tcard: { value: \"20 14% 8%\", type: \"color\" },\n\t\t\t\"card-foreground\": { value: \"30 20% 94%\", type: \"color\" },\n\t\t\tpopover: { value: \"20 14% 8%\", type: \"color\" },\n\t\t\t\"popover-foreground\": { value: \"30 20% 94%\", type: \"color\" },\n\t\t\tprimary: { value: \"16 65% 52%\", type: \"color\" },\n\t\t\t\"primary-foreground\": { value: \"0 0% 100%\", type: \"color\" },\n\t\t\tsecondary: { value: \"20 12% 14%\", type: \"color\" },\n\t\t\t\"secondary-foreground\": { value: \"30 20% 94%\", type: \"color\" },\n\t\t\tmuted: { value: \"20 12% 14%\", type: \"color\" },\n\t\t\t\"muted-foreground\": { value: \"20 6% 70%\", type: \"color\" },\n\t\t\taccent: { value: \"20 20% 16%\", type: \"color\" },\n\t\t\t\"accent-foreground\": { value: \"30 20% 94%\", type: \"color\" },\n\t\t\t/*\n\t\t\t * Destructive in dark mode doubles as text on near-black surfaces\n\t\t\t * (alerts, error helper text). A lighter coral-red gives ~7:1 on\n\t\t\t * background and ~5:1 on the same color when paired with the dark\n\t\t\t * destructive-foreground. Same tuning as default.ts.\n\t\t\t */\n\t\t\tdestructive: { value: \"0 75% 65%\", type: \"color\" },\n\t\t\t\"destructive-foreground\": { value: \"0 75% 15%\", type: \"color\" },\n\t\t\tborder: { value: \"20 10% 16%\", type: \"color\" },\n\t\t\tinput: { value: \"20 10% 16%\", type: \"color\" },\n\t\t\tring: { value: \"16 65% 52%\", type: \"color\" },\n\t\t\tradius: { value: \"0.75rem\", type: \"radius\" },\n\t\t\t// Lifted lightness so segments stay legible against the warm\n\t\t\t// near-black background.\n\t\t\t\"chart-1\": { value: \"16 75% 60%\", type: \"color\" },\n\t\t\t\"chart-2\": { value: \"180 55% 55%\", type: \"color\" },\n\t\t\t\"chart-3\": { value: \"200 60% 60%\", type: \"color\" },\n\t\t\t\"chart-4\": { value: \"45 80% 60%\", type: \"color\" },\n\t\t\t\"chart-5\": { value: \"280 60% 70%\", type: \"color\" },\n\t\t\t\"chart-6\": { value: \"330 70% 65%\", type: \"color\" },\n\t\t\t...sharedTokens,\n\t\t},\n\t},\n};\n","import type { SemanticTokenSet, TokenSet, TokenValue } from \"@hex-core/registry\";\n\n/**\n * Semantic-token map (added 0.4.0) — the **intent layer** over the raw\n * `defaultTheme` tokens. Each entry references a raw token via flat\n * `{token-name}` syntax (the token name matches the literal key in\n * `defaultTheme.tokens.light` / `.dark`) and adds a `useWhen` sentence\n * describing the UI-element class it's the right choice for.\n *\n * Why this exists: the raw `--color-destructive` ships a value, but an\n * LLM picking a token for \"delete button background\" has to guess that\n * `destructive` maps to \"irreversible action\" rather than to \"validation\n * error\" or \"system alert\" — those are different design intents that\n * happen to share a hue today. Naming the *intent* lets MCP, Studio, and\n * future LLM workflows reach for the correct token without color-vibe\n * heuristics.\n *\n * Naming convention: `<component>.<state-or-slot>.<role>`. Use\n * `dialog.overlay.bg`, not `dialog-overlay-bg`. The leading segment is\n * the API — MCP groups by it.\n *\n * **Theme-portable.** The map references raw token names by reference\n * (`{destructive}`), so swapping the underlying theme automatically\n * shifts every semantic entry without any per-theme rewrite. Themes that\n * want to redefine semantic intent (e.g. a fintech theme where\n * \"destructive\" reads more muted) can ship their own `SemanticTokenSet`\n * alongside their `Theme`.\n *\n * **Coverage is intentionally partial.** Common high-leverage intents\n * are named (button, surface, form, feedback, shape, motion); arbitrary\n * combinatorial intents (`table.row.bg-hover`, `badge.intent.warning`)\n * are deferred. Consumers querying an unnamed intent fall through to\n * the raw `defaultTheme` layer.\n */\nexport const defaultSemanticTokens: SemanticTokenSet = {\n\t// ─── Button intents ─────────────────────────────────────────────\n\t\"button.primary.bg\": {\n\t\tvalue: \"{primary}\",\n\t\tuseWhen: \"the single most important action on the screen (one per view)\",\n\t\ttype: \"color\",\n\t},\n\t\"button.primary.fg\": {\n\t\tvalue: \"{primary-foreground}\",\n\t\tuseWhen: \"text on a primary button\",\n\t\ttype: \"color\",\n\t},\n\t\"button.destructive.bg\": {\n\t\tvalue: \"{destructive}\",\n\t\tuseWhen: \"irreversible actions: delete, archive, deactivate, leave, force-quit\",\n\t\ttype: \"color\",\n\t},\n\t\"button.destructive.fg\": {\n\t\tvalue: \"{destructive-foreground}\",\n\t\tuseWhen: \"text on a destructive button\",\n\t\ttype: \"color\",\n\t},\n\t\"button.secondary.bg\": {\n\t\tvalue: \"{secondary}\",\n\t\tuseWhen: \"the second-tier action next to a primary button (Cancel, Save Draft)\",\n\t\ttype: \"color\",\n\t},\n\t\"button.outline.border\": {\n\t\tvalue: \"{input}\",\n\t\tuseWhen: \"tertiary actions on flat surfaces; signals 'optional'\",\n\t\ttype: \"color\",\n\t},\n\t\"button.ghost.bg-hover\": {\n\t\tvalue: \"{accent}\",\n\t\tuseWhen: \"lowest-emphasis action; lives inside a list/toolbar where chrome should disappear\",\n\t\ttype: \"color\",\n\t},\n\n\t// ─── Surface intents ────────────────────────────────────────────\n\t\"surface.card.bg\": {\n\t\tvalue: \"{card}\",\n\t\tuseWhen: \"a content container raised one level above the page background\",\n\t\ttype: \"color\",\n\t},\n\t\"surface.popover.bg\": {\n\t\tvalue: \"{popover}\",\n\t\tuseWhen: \"a transient floating layer (dropdown, tooltip body, hover-card) above all content\",\n\t\ttype: \"color\",\n\t},\n\t\"surface.muted.bg\": {\n\t\tvalue: \"{muted}\",\n\t\tuseWhen: \"background of a section that should recede (footer, disabled state, code block)\",\n\t\ttype: \"color\",\n\t},\n\n\t// ─── Form intents ───────────────────────────────────────────────\n\t\"form.field.border\": {\n\t\tvalue: \"{input}\",\n\t\tuseWhen: \"the resting border of a form input, textarea, or select trigger\",\n\t\ttype: \"color\",\n\t},\n\t\"form.field.border-error\": {\n\t\tvalue: \"{destructive}\",\n\t\tuseWhen: \"input validation has failed and the field needs visual correction\",\n\t\ttype: \"color\",\n\t},\n\t\"form.field.ring-focus\": {\n\t\tvalue: \"{ring}\",\n\t\tuseWhen: \"the keyboard-focus ring on any focusable form control\",\n\t\ttype: \"color\",\n\t},\n\t\"form.message.error-fg\": {\n\t\tvalue: \"{destructive}\",\n\t\tuseWhen: \"inline error text below a failed field\",\n\t\ttype: \"color\",\n\t},\n\n\t// ─── Feedback intents ───────────────────────────────────────────\n\t\"feedback.success.bg\": {\n\t\tvalue: \"{primary}\",\n\t\tuseWhen: \"success toast / banner background. Note: default theme reuses primary; opinionated themes should split this from primary\",\n\t\ttype: \"color\",\n\t},\n\t\"feedback.error.bg\": {\n\t\tvalue: \"{destructive}\",\n\t\tuseWhen: \"error toast / banner background\",\n\t\ttype: \"color\",\n\t},\n\t\"feedback.muted.fg\": {\n\t\tvalue: \"{muted-foreground}\",\n\t\tuseWhen: \"secondary copy: helper text, captions, timestamps, empty-state body\",\n\t\ttype: \"color\",\n\t},\n\n\t// ─── Shape + motion intents ─────────────────────────────────────\n\t\"shape.radius.control\": {\n\t\tvalue: \"{radius}\",\n\t\tuseWhen: \"the corner radius of any interactive control (button, input, badge, chip)\",\n\t\ttype: \"radius\",\n\t},\n\t\"motion.duration.control\": {\n\t\tvalue: \"{duration-normal}\",\n\t\tuseWhen: \"hover, press, and focus transitions on interactive controls\",\n\t\ttype: \"duration\",\n\t},\n\t\"motion.duration.overlay\": {\n\t\tvalue: \"{duration-slow}\",\n\t\tuseWhen: \"dialog/sheet/drawer enter+exit; longer to telegraph the surface change\",\n\t\ttype: \"duration\",\n\t},\n};\n\n/**\n * Resolve a `{token-name}` reference against a `TokenSet` and return\n * the underlying `TokenValue`, or `null` if the reference doesn't\n * match a token in the set. Single-hop lookup — no recursion, no\n * fallback chains.\n *\n * Use this when an MCP/Studio surface needs the resolved value\n * (e.g. to render a swatch next to the semantic name) rather than the\n * `{ref}` placeholder string.\n *\n * @example\n * ```ts\n * import { defaultSemanticTokens, defaultTheme, resolveSemanticToken } from \"@hex-core/tokens\";\n *\n * const entry = defaultSemanticTokens[\"button.destructive.bg\"];\n * const resolved = resolveSemanticToken(entry.value, defaultTheme.tokens.light);\n * // resolved → { value: \"0 84% 60%\", type: \"color\" }\n * ```\n */\nexport function resolveSemanticToken(\n\treference: string,\n\ttokenSet: TokenSet,\n): TokenValue | null {\n\tconst match = /^\\{([a-z][a-z0-9-]*)\\}$/.exec(reference);\n\tif (!match) return null;\n\tconst slug = match[1];\n\tif (!slug) return null;\n\tconst value = tokenSet[slug];\n\treturn value ?? null;\n}\n\n","import { type Hsl, hsl, parse, wcagContrast, wcagLuminance } from \"culori\";\nimport type { ColorToken, TokenSet } from \"@hex-core/registry\";\n\n/**\n * Color-math helpers shared by the CLI (`hex theme init -i`) and Studio\n * (`hex-ui-platform`'s React sliders). Pure functions over the canonical\n * HSL-triplet token-value shape (`\"<H> <S>% <L>%\"`); no I/O, no UI, no\n * framework deps. Both shells (terminal + web) wrap these with their own\n * input pickers and feed the same shape back in.\n *\n * Keeping these in `@hex-core/tokens` (rather than `@hex-core/cli`) means\n * Studio reuses the same logic web-side without bundling commander or\n * '@inquirer/prompts', AND any future theme tooling lands on a single\n * source of truth for \"what should a derived foreground / dark variant /\n * secondary look like.\"\n *\n * Each helper accepts an optional opts bag so Studio's web sliders can\n * expose the magic numbers as user-tunable controls without breaking the\n * CLI's call sites. Defaults preserve the canonical Hex Core look.\n */\n\n/**\n * Parse a hex-core HSL-triplet token value (`\"240 10% 3.9%\"`) into a\n * culori `Hsl` record. Throws on malformed input — token values that\n * already passed `tokenValueSchema` validation should never throw here.\n *\n * @param value - HSL-triplet string (`\"<H> <S>% <L>%\"`)\n * @returns A culori `Hsl` color record with `s` and `l` normalized to 0–1.\n */\nfunction parseTokenHsl(value: string): Hsl {\n\tconst match = /^([\\d.]+)\\s+([\\d.]+)%\\s+([\\d.]+)%$/.exec(value.trim());\n\tif (!match) {\n\t\tthrow new Error(\n\t\t\t`Invalid HSL triplet: \"${value}\". Expected \"<H> <S>% <L>%\" (e.g. \"240 10% 3.9%\").`,\n\t\t);\n\t}\n\treturn {\n\t\tmode: \"hsl\",\n\t\th: Number(match[1]),\n\t\ts: Number(match[2]) / 100,\n\t\tl: Number(match[3]) / 100,\n\t};\n}\n\n/**\n * Format a culori Hsl record back into a hex-core token value\n * (`\"240 10% 3.9%\"`). Inverse of `parseTokenHsl`.\n *\n * Hue is rounded to the nearest integer because hex-core themes\n * traditionally ship integer hues (the human eye doesn't distinguish\n * sub-degree hue shifts in the same lightness band). Saturation and\n * lightness are kept at 1-decimal precision because the difference\n * between 4.8% and 5.2% saturation IS visible (especially on hover\n * states + borders).\n *\n * @param color - culori `Hsl` record\n * @returns Hex-core HSL-triplet string\n */\nfunction formatTokenHsl(color: Hsl): string {\n\tconst h = Math.round(color.h ?? 0);\n\tconst s = ((color.s ?? 0) * 100).toFixed(1).replace(/\\.0$/, \"\");\n\tconst l = ((color.l ?? 0) * 100).toFixed(1).replace(/\\.0$/, \"\");\n\treturn `${h} ${s}% ${l}%`;\n}\n\nconst NEAR_WHITE: ColorToken = { value: \"0 0% 98%\", type: \"color\" };\nconst NEAR_BLACK: ColorToken = { value: \"240 10% 3.9%\", type: \"color\" };\n\n/**\n * Options for `deriveForegroundFor`. Pass custom `light` / `dark`\n * anchors when your theme uses non-canonical near-white / near-black\n * shades (e.g. a warm cream on a cool charcoal).\n */\nexport interface DeriveForegroundOptions {\n\t/** Pole used for backgrounds darker than the pole's luminance. Defaults to `\"0 0% 98%\"`. */\n\tlight?: ColorToken;\n\t/** Pole used for backgrounds lighter than the pole's luminance. Defaults to `\"240 10% 3.9%\"`. */\n\tdark?: ColorToken;\n}\n\n/**\n * Pick the foreground that hits the highest WCAG contrast against\n * `bg`. Returns either the `light` or `dark` anchor (defaults: the\n * canonical near-white / near-black; pass `opts` to override). Always\n * achieves the best of the two anchors against the input.\n *\n * @param bgValue - HSL-triplet token value of the background color\n * @param opts - Optional anchor override; see {@link DeriveForegroundOptions}\n * @returns A `ColorToken` for the chosen foreground\n *\n * @example\n * deriveForegroundFor(\"240 10% 3.9%\") // → near-white { value: \"0 0% 98%\", type: \"color\" }\n * deriveForegroundFor(\"0 0% 100%\") // → near-black { value: \"240 10% 3.9%\", type: \"color\" }\n */\nexport function deriveForegroundFor(\n\tbgValue: string,\n\topts: DeriveForegroundOptions = {},\n): ColorToken {\n\tconst light = opts.light ?? NEAR_WHITE;\n\tconst dark = opts.dark ?? NEAR_BLACK;\n\tconst bg = parseTokenHsl(bgValue);\n\tconst contrastLight = wcagContrast(bg, parseTokenHsl(light.value));\n\tconst contrastDark = wcagContrast(bg, parseTokenHsl(dark.value));\n\treturn contrastLight >= contrastDark ? light : dark;\n}\n\n/**\n * Options for `deriveDarkFromLight`. Studio's sliders expose these so\n * users can dial back the saturation cut for richer dark palettes, or\n * shift the inversion pivot to match a non-symmetric lightness curve.\n */\nexport interface DeriveDarkOptions {\n\t/**\n\t * Saturation multiplier applied during inversion (default `0.75`).\n\t * HSL's perceptual non-uniformity makes fully-saturated bright\n\t * colors read as neon-toxic when flipped to low lightness — the\n\t * 25% cut compensates. Pass `1` to keep saturation; pass `0.5` for\n\t * a more muted dark mode.\n\t */\n\tsaturationFactor?: number;\n\t/**\n\t * Inversion pivot (default `0.5`). Lightness gets mirrored around\n\t * this point — `pivot=0.5` gives `0.95L → 0.05L`. A pivot above 0.5\n\t * yields a \"lighter dark mode\"; below 0.5 yields a \"darker dark\n\t * mode.\" Range `[0, 1]`.\n\t */\n\tpivotLightness?: number;\n}\n\n/**\n * Slot names that store a \"base\" color (not a foreground-of-something).\n * `*-foreground` slots get re-derived from the inverted base via\n * `deriveForegroundFor` so AA contrast survives the round-trip.\n */\nconst BASE_SLOT_REGEX = /-foreground$/;\n\n/**\n * Mirror a light-mode TokenSet into a coherent dark-mode TokenSet.\n *\n * For each base color slot (e.g. `primary`, `card`, `destructive`,\n * `background`, `border`), invert the lightness around `pivotLightness`\n * and reduce saturation by `saturationFactor` (default 0.75).\n *\n * For each `*-foreground` slot, re-derive against the inverted base\n * via `deriveForegroundFor`. **This is critical** — naïvely inverting\n * `primary-foreground` lightness produces sub-AA contrast against the\n * inverted `primary` (the foreground was previously chosen with the\n * light primary in mind). See the AA-invariant tests in\n * `derive.test.ts`.\n *\n * Authors who want a curated dark palette should pick `author-now` in\n * the CLI's dark-mode prompt and re-walk the surface seeds. This\n * helper is the \"good-enough\" default for the `auto-derive` path.\n *\n * @param light - Light-mode TokenSet (must contain all `REQUIRED_COLOR_TOKENS`)\n * @param opts - Optional saturation / pivot overrides; see {@link DeriveDarkOptions}\n * @returns A new TokenSet with bases inverted + foregrounds re-derived for AA\n */\nexport function deriveDarkFromLight(\n\tlight: TokenSet,\n\topts: DeriveDarkOptions = {},\n): TokenSet {\n\tconst saturationFactor = opts.saturationFactor ?? 0.75;\n\tconst pivot = opts.pivotLightness ?? 0.5;\n\n\t// First pass: invert every BASE color (skip `*-foreground` and\n\t// non-color tokens). Foregrounds get re-derived in pass 2.\n\tconst dark: TokenSet = {};\n\tfor (const [name, token] of Object.entries(light)) {\n\t\tif (token.type !== \"color\") {\n\t\t\tdark[name] = token;\n\t\t\tcontinue;\n\t\t}\n\t\tif (BASE_SLOT_REGEX.test(name)) continue;\n\t\tconst color = parseTokenHsl(token.value);\n\t\tconst inverted: Hsl = {\n\t\t\tmode: \"hsl\",\n\t\t\th: color.h ?? 0,\n\t\t\ts: Math.max(0, (color.s ?? 0) * saturationFactor),\n\t\t\tl: Math.max(0, Math.min(1, 2 * pivot - (color.l ?? 0))),\n\t\t};\n\t\tdark[name] = { value: formatTokenHsl(inverted), type: \"color\" };\n\t}\n\n\t// Second pass: for each `*-foreground` slot, find the matching base\n\t// in the dark set and re-derive a contrast-safe foreground. Falls\n\t// back to a naive inversion if the base isn't in the set (defensive;\n\t// shouldn't happen for a strict-validated TokenSet).\n\tfor (const [name, token] of Object.entries(light)) {\n\t\tif (token.type !== \"color\" || !BASE_SLOT_REGEX.test(name)) continue;\n\t\tconst baseName = name.replace(BASE_SLOT_REGEX, \"\");\n\t\tconst darkBase = dark[baseName];\n\t\tif (darkBase && darkBase.type === \"color\") {\n\t\t\tdark[name] = deriveForegroundFor(darkBase.value);\n\t\t} else {\n\t\t\tconst color = parseTokenHsl(token.value);\n\t\t\tdark[name] = {\n\t\t\t\tvalue: formatTokenHsl({ ...color, l: Math.max(0, Math.min(1, 2 * pivot - (color.l ?? 0))) }),\n\t\t\t\ttype: \"color\",\n\t\t\t};\n\t\t}\n\t}\n\n\treturn dark;\n}\n\n/**\n * Options for `deriveSecondaryFromPrimary`. Studio's sliders expose\n * the lightness band + saturation cap so users can author a richer or\n * more muted secondary fill.\n */\nexport interface DeriveSecondaryOptions {\n\t/**\n\t * Target lightness for the derived secondary (default `0.959`).\n\t * The canonical Hex Core secondary lightness band — keeps button\n\t * surfaces flush with `--muted` and `--accent` in light mode. Range `[0, 1]`.\n\t */\n\tlightness?: number;\n\t/**\n\t * Maximum saturation kept from the primary (default `0.05`). The\n\t * derived secondary should feel related but recede; capping\n\t * saturation at 5% gives the \"almost-gray with a hint of brand\"\n\t * effect.\n\t */\n\tsaturationCap?: number;\n}\n\n/**\n * Derive a `secondary` color from `primary` by desaturating + shifting\n * lightness toward a near-neutral. Produces the muted-but-related fill\n * Cancel/Save-Draft buttons want next to a primary CTA.\n *\n * The derived secondary preserves the primary's hue so the pairing\n * reads as intentional. Foreground pairing is the caller's job — feed\n * the result through `deriveForegroundFor` to get a contrast-safe text\n * color.\n *\n * @param primaryValue - HSL-triplet token value of the primary color\n * @param opts - Optional lightness / saturation-cap overrides; see {@link DeriveSecondaryOptions}\n * @returns A `ColorToken` for the derived secondary\n */\nexport function deriveSecondaryFromPrimary(\n\tprimaryValue: string,\n\topts: DeriveSecondaryOptions = {},\n): ColorToken {\n\tconst lightness = opts.lightness ?? 0.959;\n\tconst saturationCap = opts.saturationCap ?? 0.05;\n\tconst primary = parseTokenHsl(primaryValue);\n\tconst secondary: Hsl = {\n\t\tmode: \"hsl\",\n\t\th: primary.h ?? 0,\n\t\ts: Math.min(saturationCap, primary.s ?? 0),\n\t\tl: lightness,\n\t};\n\treturn { value: formatTokenHsl(secondary), type: \"color\" };\n}\n\n/**\n * Compute the WCAG contrast ratio between a foreground / background\n * token pair. Use as an authoring-time guard, not a runtime gate —\n * themes that ship with sub-AA pairs are caller's responsibility. AA\n * threshold is 4.5:1 for body text, 3:1 for large/UI text per WCAG 1.4.3.\n *\n * @param fgValue - foreground HSL-triplet\n * @param bgValue - background HSL-triplet\n * @returns The contrast ratio (≥4.5 means AA-pass for body text)\n */\nexport function contrastRatio(fgValue: string, bgValue: string): number {\n\tconst fg = parseTokenHsl(fgValue);\n\tconst bg = parseTokenHsl(bgValue);\n\treturn wcagContrast(fg, bg);\n}\n\n/**\n * Convenience: parse a freeform color string (`\"#1e293b\"`, `\"navy\"`,\n * `\"hsl(220 13% 18%)\"`) into a hex-core token value. Used by the CLI's\n * interactive prompt so the user can paste a hex from their design tool\n * directly without manual HSL conversion.\n *\n * Note: only standard CSS named colors (`navy`, `rebeccapurple`,\n * `tomato`, etc.) parse — Tailwind palette names like `slate` or\n * `zinc` are not in the CSS spec and return `null`.\n *\n * @param input - Anything culori's `parse` accepts (hex, CSS named,\n * `hsl()`, `rgb()`, `oklch()`, etc.)\n * @returns HSL-triplet string ready to feed back into a `ColorToken`,\n * or `null` if the input doesn't parse.\n */\nexport function colorInputToTokenValue(input: string): string | null {\n\tconst parsed = parse(input.trim());\n\tif (!parsed) return null;\n\tconst asHsl = hsl(parsed);\n\tif (!asHsl) return null;\n\treturn formatTokenHsl(asHsl);\n}\n\n/**\n * Compute the perceptual luminance of a token value. Useful when a UI\n * needs to pick an overlay tint dynamically (e.g. \"darker shimmer for\n * a light surface, lighter shimmer for a dark surface\").\n *\n * @param value - HSL-triplet token value\n * @returns The perceptual luminance (0 = absolute black, 1 = absolute white)\n */\nexport function tokenLuminance(value: string): number {\n\treturn wcagLuminance(parseTokenHsl(value));\n}\n\n/**\n * Canonical radius presets shared between `@hex-core/cli`'s interactive\n * authoring and `hex-ui-platform`'s Studio sliders. Authors who pick\n * outside the presets enter a custom `rem` string.\n *\n * - `sharp` (`0.25rem`) — Linear-style precision, tight chrome\n * - `balanced` (`0.625rem`) — versatile default, current shadcn-canon\n * - `soft` (`0.875rem`) — friendly / consumer, reads as approachable\n */\nexport const RADIUS_PRESETS = {\n\tsharp: \"0.25rem\",\n\tbalanced: \"0.625rem\",\n\tsoft: \"0.875rem\",\n} as const;\n\nexport type RadiusPreset = keyof typeof RADIUS_PRESETS;\n\n/**\n * Surface and framing lightness bands for the two color modes. Used by\n * both the CLI (`buildTokenSet`) and Studio (its preview pane) to\n * derive secondary / muted / accent / border / input slots that fit\n * the chosen background instead of always landing in the light band.\n *\n * Each mode pins `surface` (the lightness of `secondary` / `muted` /\n * `accent` button fills) and `framing` (the lightness of `border` /\n * `input` lines). Light surfaces want near-white fills with low-contrast\n * lines; dark surfaces want near-black fills with mid-contrast lines.\n */\nexport const COLOR_MODE_BANDS = {\n\tlight: { surface: 0.959, framing: 0.9 },\n\tdark: { surface: 0.159, framing: 0.16 },\n} as const;\n\nexport type ColorMode = keyof typeof COLOR_MODE_BANDS;\n","import type { ColorToken, TokenSet } from \"@hex-core/registry\";\nimport {\n\tCOLOR_MODE_BANDS,\n\ttype ColorMode,\n\tderiveForegroundFor,\n\tderiveSecondaryFromPrimary,\n} from \"./derive.js\";\n\n/**\n * Five-seed input that fully determines a coherent {@link TokenSet}.\n *\n * Mirrors the seed shape the interactive `hex theme init -i` flow asks\n * for, plus the seed shape the brand-derived preset import script\n * (`scripts/import-voltagent.ts`) extracts from a markdown brief. Both\n * paths share this helper so the rendered token sets are identical\n * given identical seeds.\n *\n * @property primary - HSL-triplet (\"<H> <S>% <L>%\"). The brand color.\n * @property foreground - HSL-triplet. Page text default. Drives\n * `muted-foreground`, `border`, and `input` lightness.\n * @property background - HSL-triplet. Page canvas. Mirrored to\n * `card` and `popover`.\n * @property destructive - HSL-triplet. Error / delete CTA color.\n * Pairs with a derived `destructive-foreground`.\n * @property radius - rem string (`\"0.375rem\"`, `\"0.625rem\"`, ...).\n * Single radius preset; consumers can override per-component via\n * the standard `--radius-*` overrides.\n */\nexport interface TokenSetSeeds {\n\tprimary: string;\n\tforeground: string;\n\tbackground: string;\n\tdestructive: string;\n\tradius: string;\n}\n\n/**\n * Build a full 19-required-slot {@link TokenSet} from a small seed\n * bag. Both the CLI authoring flow and the brand-derived preset\n * import script call this helper so output is consistent across\n * authoring surfaces.\n *\n * The mode flag picks the right surface/framing band so derived\n * neutrals (`secondary` / `muted` / `accent` / `border` / `input`)\n * land at light-mode lightness on a light surface and dark-mode\n * lightness on a dark surface.\n *\n * @param seeds - The five seed values; see {@link TokenSetSeeds}\n * @param mode - `\"light\"` or `\"dark\"` — drives band selection\n * @returns A {@link TokenSet} carrying every required color slot + radius\n */\nexport function buildTokenSet(seeds: TokenSetSeeds, mode: ColorMode): TokenSet {\n\tconst { surface, framing } = COLOR_MODE_BANDS[mode];\n\n\tconst primary: ColorToken = { value: seeds.primary, type: \"color\" };\n\tconst primaryForeground = deriveForegroundFor(seeds.primary);\n\tconst foreground: ColorToken = { value: seeds.foreground, type: \"color\" };\n\tconst background: ColorToken = { value: seeds.background, type: \"color\" };\n\tconst destructive: ColorToken = { value: seeds.destructive, type: \"color\" };\n\tconst destructiveForeground = deriveForegroundFor(seeds.destructive);\n\tconst secondary = deriveSecondaryFromPrimary(seeds.primary, { lightness: surface });\n\tconst secondaryForeground = deriveForegroundFor(secondary.value);\n\n\treturn {\n\t\tbackground,\n\t\tforeground,\n\t\tcard: background,\n\t\t\"card-foreground\": foreground,\n\t\tpopover: background,\n\t\t\"popover-foreground\": foreground,\n\t\tprimary,\n\t\t\"primary-foreground\": primaryForeground,\n\t\tsecondary,\n\t\t\"secondary-foreground\": secondaryForeground,\n\t\tmuted: secondary,\n\t\t\"muted-foreground\": {\n\t\t\tvalue: shiftLightnessTo(seeds.foreground, mode === \"light\" ? 0.38 : 0.7),\n\t\t\ttype: \"color\",\n\t\t},\n\t\taccent: secondary,\n\t\t\"accent-foreground\": secondaryForeground,\n\t\tdestructive,\n\t\t\"destructive-foreground\": destructiveForeground,\n\t\tborder: { value: shiftLightnessTo(seeds.foreground, framing), type: \"color\" },\n\t\tinput: { value: shiftLightnessTo(seeds.foreground, framing), type: \"color\" },\n\t\tring: primary,\n\t\tradius: { value: seeds.radius, type: \"radius\" },\n\t};\n}\n\n/**\n * Shift a token's lightness to a target value (0–1) while preserving\n * hue and capping saturation at 8% so derived neutrals read as\n * \"intentional tint\" rather than \"achromatic gray.\" Used internally\n * by `buildTokenSet` for `muted-foreground` / `border` / `input`.\n *\n * @param value - HSL-triplet input\n * @param lightness - Target lightness in `[0, 1]`\n * @returns A new HSL-triplet at the requested lightness, or the input\n * unchanged if it doesn't parse\n */\nfunction shiftLightnessTo(value: string, lightness: number): string {\n\tconst match = /^([\\d.]+)\\s+([\\d.]+)%\\s+([\\d.]+)%$/.exec(value.trim());\n\tif (!match) return value;\n\tconst h = Number(match[1]);\n\tconst s = Math.min(Number(match[2]), 8);\n\tconst l = Math.round(lightness * 1000) / 10;\n\treturn `${h} ${s.toFixed(1).replace(/\\.0$/, \"\")}% ${l}%`;\n}\n","export {\n\tgenerateGlobalsCss,\n\ttype ScopedRuntimeCssOptions,\n\tthemeToCss,\n\tthemeToFlatJson,\n\tthemeToScopedRuntimeCss,\n\tthemeToTailwindConfig,\n} from \"./transformer.js\";\nexport { defaultTheme } from \"./themes/default.js\";\nexport { midnightTheme } from \"./themes/midnight.js\";\nexport { emberTheme } from \"./themes/ember.js\";\nexport { sharedTokens } from \"./themes/shared.js\";\nexport { defaultSemanticTokens, resolveSemanticToken } from \"./semantic.js\";\nexport {\n\tCOLOR_MODE_BANDS,\n\tcolorInputToTokenValue,\n\tcontrastRatio,\n\tderiveDarkFromLight,\n\tderiveForegroundFor,\n\tderiveSecondaryFromPrimary,\n\tRADIUS_PRESETS,\n\ttokenLuminance,\n} from \"./lib/derive.js\";\nexport { buildTokenSet } from \"./lib/build-token-set.js\";\nexport type { TokenSetSeeds } from \"./lib/build-token-set.js\";\nexport type {\n\tColorMode,\n\tDeriveDarkOptions,\n\tDeriveForegroundOptions,\n\tDeriveSecondaryOptions,\n\tRadiusPreset,\n} from \"./lib/derive.js\";\n\nimport type { Theme } from \"@hex-core/registry\";\nimport { defaultTheme } from \"./themes/default.js\";\nimport { emberTheme } from \"./themes/ember.js\";\nimport { midnightTheme } from \"./themes/midnight.js\";\n\nexport const themes: Record<string, Theme> = {\n\tdefault: defaultTheme,\n\tmidnight: midnightTheme,\n\tember: emberTheme,\n};\n\n/**\n * Retrieve a theme by name.\n * @param name - The theme identifier (e.g. \"default\", \"midnight\", \"ember\")\n * @returns The matching Theme object, or undefined if not found\n */\nexport function getTheme(name: string): Theme | undefined {\n\treturn themes[name];\n}\n\n/**\n * List all available themes with their display metadata.\n * @returns An array of theme summaries containing name, displayName, and description\n */\nexport function listThemes(): Array<{ name: string; displayName: string; description: string }> {\n\treturn Object.values(themes).map((t) => ({\n\t\tname: t.name,\n\t\tdisplayName: t.displayName,\n\t\tdescription: t.description,\n\t}));\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/transformer.ts","../src/themes/shared.ts","../src/themes/default.ts","../src/themes/midnight.ts","../src/themes/ember.ts","../src/semantic.ts","../src/lib/derive.ts","../src/lib/build-token-set.ts","../src/index.ts"],"sourcesContent":["import type { Theme } from \"@hex-core/registry\";\n\ninterface TokenLike {\n\tvalue: string;\n\ttype?: string;\n\tref?: string;\n}\n\n/**\n * Extract the palette key a token was drawn from.\n * @param token - A token object potentially carrying a `ref`\n * @returns The palette key, or undefined when the token holds a literal\n */\nfunction extractRef(token: unknown): string | undefined {\n\tif (typeof token === \"object\" && token !== null && \"ref\" in token) {\n\t\tconst { ref } = token;\n\t\treturn typeof ref === \"string\" ? ref : undefined;\n\t}\n\treturn undefined;\n}\n\n/**\n * Render a token for CSS, pointing at its ramp entry when it has one.\n *\n * A token drawn from the palette emits `var(--slate-900)` rather than the\n * triplet it resolves to. That indirection is the point of a two-tier\n * palette: `--primary` and `--ring` come from one graphite entry, so a\n * consumer re-tints everything downstream by overriding `--slate-900` in\n * their own stylesheet.\n *\n * Tokens without a `ref` — every one of the 143 imported brand presets —\n * emit their literal value unchanged.\n * @param token - The token to render\n * @returns CSS-ready value text\n */\nfunction renderTokenValue(token: unknown): string {\n\tconst key = extractRef(token);\n\treturn key === undefined ? extractValue(token) : `var(--${key})`;\n}\n\n/**\n * Extract the value string from a token-like object or primitive.\n * @param token - A token object with a `value` property, or a primitive\n * @returns The token's value as a string\n */\nfunction extractValue(token: unknown): string {\n\tif (typeof token === \"object\" && token !== null && \"value\" in token) {\n\t\treturn String((token as TokenLike).value);\n\t}\n\treturn String(token);\n}\n\n/**\n * Extract the type annotation from a token-like object.\n * @param token - A token object potentially containing a `type` property\n * @returns The token type string, or undefined if not present\n */\nfunction extractType(token: unknown): string | undefined {\n\tif (typeof token === \"object\" && token !== null && \"type\" in token) {\n\t\treturn (token as TokenLike).type;\n\t}\n\treturn undefined;\n}\n\n/**\n * Transforms a theme's token set into CSS custom properties.\n *\n * Output uses the **raw `--<key>` namespace** — value verbatim, no `hsl()`\n * wrapper, no `--color-` prefix. Colors land as triplets (e.g. `0 0% 100%`)\n * to enable alpha composition like `hsl(var(--background) / 0.5)`. Consumers\n * on Tailwind v4 also need a `@theme` block in the `--color-<key>` namespace;\n * see the \"CSS variable namespaces\" section in ./README.md for the bridge.\n *\n * @param theme - The theme to transform\n * @returns A CSS string with `:root` and `.dark` custom property declarations inside a `@layer base` block\n */\nexport function themeToCss(theme: Theme): string {\n\tconst lines: string[] = [];\n\n\tlines.push(\"@layer base {\");\n\tlines.push(\" :root {\");\n\tfor (const [key, value] of Object.entries(theme.palette ?? {})) {\n\t\tlines.push(` --${key}: ${value};`);\n\t}\n\tfor (const [key, token] of Object.entries(theme.tokens.light)) {\n\t\tlines.push(` --${key}: ${renderTokenValue(token)};`);\n\t}\n\tlines.push(\" }\");\n\tlines.push(\"\");\n\tlines.push(\" .dark {\");\n\tfor (const [key, token] of Object.entries(theme.tokens.dark)) {\n\t\tlines.push(` --${key}: ${renderTokenValue(token)};`);\n\t}\n\tlines.push(\" }\");\n\tlines.push(\"}\");\n\n\treturn lines.join(\"\\n\");\n}\n\n/**\n * Transforms a theme into a flat JSON map for AI consumption.\n * This is the most token-efficient format for LLMs.\n * @param theme - The theme to transform\n * @param mode - Color mode to extract tokens for (defaults to \"light\")\n * @returns A flat record mapping CSS variable names to their values\n */\nexport function themeToFlatJson(\n\ttheme: Theme,\n\tmode: \"light\" | \"dark\" = \"light\",\n): Record<string, string> {\n\tconst flat: Record<string, string> = {};\n\tconst tokens = mode === \"light\" ? theme.tokens.light : theme.tokens.dark;\n\n\tfor (const [key, token] of Object.entries(tokens)) {\n\t\tflat[`--${key}`] = extractValue(token);\n\t}\n\n\treturn flat;\n}\n\n/**\n * Transforms a theme into Tailwind CSS config extension.\n * @param theme - The theme to transform\n * @returns An object with maps for colors, borderRadius, spacing, fontSize,\n * transitionDuration, and height — suitable for Tailwind's `theme.extend`.\n */\nexport function themeToTailwindConfig(theme: Theme): Record<string, Record<string, string>> {\n\tconst colors: Record<string, string> = {};\n\tconst borderRadius: Record<string, string> = {};\n\tconst spacing: Record<string, string> = {};\n\tconst fontSize: Record<string, string> = {};\n\tconst transitionDuration: Record<string, string> = {};\n\tconst height: Record<string, string> = {};\n\n\tfor (const [key, token] of Object.entries(theme.tokens.light)) {\n\t\tconst type = extractType(token);\n\t\tif (!type) continue;\n\n\t\tif (type === \"color\") {\n\t\t\tcolors[key] = `hsl(var(--${key}))`;\n\t\t} else if (type === \"radius\") {\n\t\t\tborderRadius[key] = `var(--${key})`;\n\t\t} else if (type === \"spacing\") {\n\t\t\t// Strip \"space-\" / \"gap-\" prefix for cleaner Tailwind usage (e.g. `p-4` vs `p-space-4`).\n\t\t\tconst stripped = key.replace(/^(space-|gap-)/, \"\");\n\t\t\tspacing[stripped] = `var(--${key})`;\n\t\t} else if (type === \"dimension\") {\n\t\t\t// control-height-md → height.control-md\n\t\t\theight[key.replace(/^control-/, \"\")] = `var(--${key})`;\n\t\t} else if (type === \"font\") {\n\t\t\tfontSize[key.replace(/^text-/, \"\")] = `var(--${key})`;\n\t\t} else if (type === \"duration\") {\n\t\t\ttransitionDuration[key.replace(/^duration-/, \"\")] = `var(--${key})`;\n\t\t}\n\t}\n\n\treturn { colors, borderRadius, spacing, fontSize, transitionDuration, height };\n}\n\n/**\n * Options for {@link themeToScopedRuntimeCss}.\n */\nexport interface ScopedRuntimeCssOptions {\n\t/**\n\t * CSS selector that the generated rule targets. Defaults to `\":root\"`.\n\t *\n\t * Pass a class selector (e.g. `\".studio-canvas-active\"` or `\".theme-vivid\"`)\n\t * to scope the override to a subtree — useful when an app needs to flip\n\t * themes at runtime without round-tripping through `globals.css`. The vars\n\t * cascade to every descendant of an element matching the selector, so the\n\t * subtree's Tailwind utilities resolve against the new values automatically.\n\t */\n\tscope?: string;\n\t/**\n\t * Which palette to render. Defaults to `\"light\"`. Pass `\"dark\"` to emit the\n\t * theme's dark token set (typically used in combination with a `.dark` scope\n\t * applied by the consumer's theme provider).\n\t */\n\tmode?: \"light\" | \"dark\";\n}\n\n/**\n * Render a theme as scoped runtime CSS for the Tailwind v4 `--color-*` namespace.\n *\n * Unlike {@link themeToCss} (which emits at `:root` for static `globals.css`),\n * this targets a configurable selector so the override applies only to that\n * subtree. The output emits **both** namespaces so the result drops in cleanly\n * regardless of how the consumer's `globals.css` is wired:\n *\n * - `--<key>: <value>;` (raw triplet) — preserves alpha-composition utilities\n * like `bg-background/50` that read the variable as bare `H S% L%`.\n * - `--color-<key>: hsl(<value>);` (full `hsl()` string) — feeds Tailwind v4's\n * `@theme` block so generated utilities like `bg-background` / `text-primary`\n * resolve against the override.\n *\n * Non-color tokens (radii, durations, spacing, font sizes) only emit the raw\n * `--<key>` form since they don't go through `@theme`'s color machinery.\n *\n * @param theme - The theme to render\n * @param options - Scope selector + light/dark mode (see {@link ScopedRuntimeCssOptions}).\n * @returns A CSS string with one rule wrapping all the token declarations.\n *\n * @example\n * ```ts\n * import { defaultTheme, themeToScopedRuntimeCss } from \"@hex-core/tokens\";\n *\n * // Default: emits at :root for the light palette.\n * const css = themeToScopedRuntimeCss(defaultTheme);\n *\n * // Subtree-scoped runtime override (e.g. a theme studio's canvas):\n * const scoped = themeToScopedRuntimeCss(defaultTheme, {\n * scope: \".studio-canvas-active\",\n * mode: \"light\",\n * });\n *\n * // Inject via a <style> tag:\n * // <style dangerouslySetInnerHTML={{ __html: scoped }} />\n * ```\n */\nexport function themeToScopedRuntimeCss(\n\ttheme: Theme,\n\toptions: ScopedRuntimeCssOptions = {},\n): string {\n\tconst { scope = \":root\", mode = \"light\" } = options;\n\tconst tokens = mode === \"light\" ? theme.tokens.light : theme.tokens.dark;\n\n\tconst lines: string[] = [];\n\tlines.push(`${scope} {`);\n\tfor (const [key, token] of Object.entries(tokens)) {\n\t\tconst value = extractValue(token);\n\t\tconst type = extractType(token);\n\t\t// Always emit the raw `--<key>` form. For colors, also emit the\n\t\t// Tailwind v4 `--color-<key>` bridge wrapped in hsl() so `@theme`\n\t\t// blocks resolve correctly without the consumer hand-authoring the\n\t\t// bridge layer.\n\t\tlines.push(` --${key}: ${value};`);\n\t\tif (type === \"color\") {\n\t\t\tlines.push(` --color-${key}: hsl(${value});`);\n\t\t}\n\t}\n\tlines.push(\"}\");\n\n\treturn lines.join(\"\\n\");\n}\n\n/**\n * Options for {@link generateGlobalsCss}.\n */\nexport interface GenerateGlobalsCssOptions {\n\t/**\n\t * Tailwind major to target.\n\t * - `\"v3\"` (default, backward compatible): emits `@tailwind base/components/utilities`\n\t * plus `@layer base { :root {} .dark {} }` blocks. Pair with a `tailwind.config.ts`\n\t * that maps the raw `--<key>` CSS variables to color/radius utilities.\n\t * - `\"v4\"`: emits `@import \"tailwindcss\"` + `@theme { --color-<key>: hsl(...) }` so\n\t * utilities like `bg-background` resolve directly. No `tailwind.config.ts` needed.\n\t */\n\ttarget?: \"v3\" | \"v4\";\n\t/**\n\t * Explicit content globs for Tailwind v4 to scan, relative to the CSS file.\n\t *\n\t * When set, the import becomes `@import \"tailwindcss\" source(none)` followed\n\t * by one `@source` rule per glob — automatic detection is turned off.\n\t *\n\t * Pass this for an app generated *inside* an existing repository. Tailwind's\n\t * automatic scan walks up past the app to the enclosing git root and reads\n\t * whatever it finds — including binary files, whose bytes become class\n\t * candidates and emit unparseable utilities. Scoping the scan to the app's\n\t * own directories is the fix. Omit it for an app at the root of its own\n\t * repository, where automatic detection is correct.\n\t *\n\t * Ignored when `target` is `\"v3\"`, which has no `@source` rule.\n\t */\n\tsources?: readonly string[];\n}\n\n/**\n * Generates a complete globals.css content with theme tokens and Tailwind directives.\n *\n * @param theme - The theme to generate CSS for\n * @param options - Output target (Tailwind v3 vs v4). Defaults to v3 for backward compatibility.\n * @returns A full globals.css string ready to drop into `app/globals.css`.\n */\nexport function generateGlobalsCss(theme: Theme, options: GenerateGlobalsCssOptions = {}): string {\n\tconst { target = \"v3\", sources } = options;\n\tif (target === \"v4\") return generateGlobalsCssV4(theme, sources);\n\treturn generateGlobalsCssV3(theme);\n}\n\nfunction generateGlobalsCssV3(theme: Theme): string {\n\tconst lines: string[] = [];\n\n\tlines.push(\"@tailwind base;\");\n\tlines.push(\"@tailwind components;\");\n\tlines.push(\"@tailwind utilities;\");\n\tlines.push(\"\");\n\tlines.push(themeToCss(theme));\n\tlines.push(\"\");\n\tlines.push(\"@layer base {\");\n\tlines.push(\" * {\");\n\tlines.push(\" @apply border-border;\");\n\tlines.push(\" }\");\n\tlines.push(\" body {\");\n\tlines.push(\" @apply bg-background text-foreground;\");\n\tlines.push(\" }\");\n\tlines.push(\"}\");\n\n\treturn lines.join(\"\\n\");\n}\n\n/**\n * Emit only the token layer — the raw ramp, the semantic tokens, and the\n * Tailwind `--color-*` bridge.\n *\n * Split out of {@link generateGlobalsCss} so a consumer that already owns\n * its `@import`s, custom variants and non-colour `@theme` block can\n * generate just the colours. The docs site does exactly that: its\n * `globals.css` used to hand-copy this output four times over and carried\n * a \"KEEP IN SYNC\" comment to prove it.\n *\n * @param theme - The theme to emit\n * @returns The `:root` / `.dark` / `@theme inline` blocks, plus the base\n * `body` and border rules\n */\nexport function generateThemeCssV4(theme: Theme): string {\n\tconst lines: string[] = [];\n\t// Bridge pattern: raw `H S% L%` triplets live in :root / .dark, and the\n\t// @theme inline block aliases each `--color-<key>` to `hsl(var(--<key>))`.\n\t// This shape is deliberate:\n\t// 1. Keeps the raw `--<key>` triplet that `hex theme edit` searches for —\n\t// direct values inside @theme would silently break that command.\n\t// 2. Keeps alpha-modifier utilities (bg-primary/50) cheap because the\n\t// `<H S% L%>` triplet composes via Tailwind v4's color-mix() machinery\n\t// with no per-utility re-derivation.\n\tlines.push(\"/*\");\n\tlines.push(\" * Raw token triplets (H S% L%) — the source of truth that `hex theme edit`\");\n\tlines.push(\" * mutates, and that the @theme inline block below aliases into Tailwind's\");\n\tlines.push(\" * --color-<key> namespace.\");\n\tif (theme.palette) {\n\t\tlines.push(\" *\");\n\t\tlines.push(\" * Tier 1 is the raw ramp; the semantic tokens below point at it with\");\n\t\tlines.push(\" * var(). Re-tint the whole theme by overriding a ramp entry — every\");\n\t\tlines.push(\" * semantic token that references it follows.\");\n\t}\n\tlines.push(\" */\");\n\tlines.push(\":root {\");\n\tfor (const [key, value] of Object.entries(theme.palette ?? {})) {\n\t\tlines.push(` --${key}: ${value};`);\n\t}\n\tfor (const [key, token] of Object.entries(theme.tokens.light)) {\n\t\tlines.push(` --${key}: ${renderTokenValue(token)};`);\n\t}\n\tlines.push(\"}\");\n\tlines.push(\"\");\n\tlines.push(\".dark {\");\n\tfor (const [key, token] of Object.entries(theme.tokens.dark)) {\n\t\tlines.push(` --${key}: ${renderTokenValue(token)};`);\n\t}\n\tlines.push(\"}\");\n\tlines.push(\"\");\n\tlines.push(\"/*\");\n\tlines.push(\" * Tailwind v4 namespace bridge — generated utilities like bg-background\");\n\tlines.push(\" * resolve var(--color-background) here, which in turn reads var(--background)\");\n\tlines.push(\" * from the blocks above.\");\n\tlines.push(\" */\");\n\tlines.push(\"@theme inline {\");\n\tfor (const [key, token] of Object.entries(theme.tokens.light)) {\n\t\tif (extractType(token) !== \"color\") continue;\n\t\tlines.push(` --color-${key}: hsl(var(--${key}));`);\n\t}\n\tlines.push(\"}\");\n\tlines.push(\"\");\n\tlines.push(\"body {\");\n\tlines.push(\" background: var(--color-background);\");\n\tlines.push(\" color: var(--color-foreground);\");\n\tlines.push(\"}\");\n\tlines.push(\"\");\n\tlines.push(\"* {\");\n\tlines.push(\" border-color: var(--color-border);\");\n\tlines.push(\"}\");\n\n\treturn lines.join(\"\\n\");\n}\n\nfunction generateGlobalsCssV4(theme: Theme, sources?: readonly string[]): string {\n\tconst lines: string[] = [];\n\n\tconst scoped = sources !== undefined && sources.length > 0;\n\tif (scoped) {\n\t\tlines.push(\"/*\");\n\t\tlines.push(\" * `source(none)` turns off Tailwind's automatic content detection, which\");\n\t\tlines.push(\" * would otherwise walk up past this app to the enclosing repository and read\");\n\t\tlines.push(\" * binary files as class candidates, emitting utilities that fail to parse.\");\n\t\tlines.push(\" * The @source rules below name this app's own files instead.\");\n\t\tlines.push(\" */\");\n\t\tlines.push(`@import \"tailwindcss\" source(none);`);\n\t\tfor (const source of sources) lines.push(`@source \"${source}\";`);\n\t} else {\n\t\tlines.push(`@import \"tailwindcss\";`);\n\t}\n\t// tw-animate-css ports tailwindcss-animate's animate-in/out, fade-*, slide-*,\n\t// zoom-* utilities to v4 as a pure CSS import. Every Hex component that\n\t// transitions (dialog, dropdown-menu, popover, accordion, ...) depends on\n\t// these classes, so it's not optional.\n\tlines.push(`@import \"tw-animate-css\";`);\n\tlines.push(\"\");\n\tlines.push(\"/* Class-based dark mode — set `.dark` on <html> via next-themes or your own provider. */\");\n\tlines.push(\"@custom-variant dark (&:is(.dark *));\");\n\tlines.push(\"\");\n\tlines.push(generateThemeCssV4(theme));\n\treturn lines.join(\"\\n\");\n}\n","import type { TokenValue } from \"@hex-core/registry\";\n\n/**\n * Layout + typography tokens shared across all themes. Colors/radius vary per\n * theme; these do not (yet). Spread into both light and dark dicts of every\n * Theme so consumers can read any token regardless of color mode.\n */\nexport const sharedTokens: Record<string, TokenValue> = {\n\t// ─── Spacing scale (rem) ───\n\t\"space-1\": { value: \"0.25rem\", type: \"spacing\" },\n\t\"space-2\": { value: \"0.5rem\", type: \"spacing\" },\n\t\"space-3\": { value: \"0.75rem\", type: \"spacing\" },\n\t\"space-4\": { value: \"1rem\", type: \"spacing\" },\n\t\"space-6\": { value: \"1.5rem\", type: \"spacing\" },\n\t\"space-8\": { value: \"2rem\", type: \"spacing\" },\n\t\"space-12\": { value: \"3rem\", type: \"spacing\" },\n\t\"space-16\": { value: \"4rem\", type: \"spacing\" },\n\n\t// ─── Gap presets (for layout primitives) ───\n\t\"gap-xs\": { value: \"0.25rem\", type: \"spacing\" },\n\t\"gap-sm\": { value: \"0.5rem\", type: \"spacing\" },\n\t\"gap-md\": { value: \"1rem\", type: \"spacing\" },\n\t\"gap-lg\": { value: \"1.5rem\", type: \"spacing\" },\n\t\"gap-xl\": { value: \"2rem\", type: \"spacing\" },\n\n\t// ─── Container max-widths (for prose / layout primitives) ───\n\t\"container-sm\": { value: \"33rem\", type: \"dimension\" },\n\t\"container-md\": { value: \"40rem\", type: \"dimension\" },\n\t\"container-lg\": { value: \"50rem\", type: \"dimension\" },\n\t\"container-xl\": { value: \"66rem\", type: \"dimension\" },\n\n\t// ─── Control heights (interactive elements) ───\n\t\"control-height-sm\": { value: \"2.25rem\", type: \"dimension\" },\n\t\"control-height-md\": { value: \"2.5rem\", type: \"dimension\" },\n\t\"control-height-lg\": { value: \"2.75rem\", type: \"dimension\" },\n\n\t// ─── Typography scale ───\n\t\"text-xs\": { value: \"0.75rem\", type: \"font\" },\n\t\"text-sm\": { value: \"0.875rem\", type: \"font\" },\n\t\"text-base\": { value: \"1rem\", type: \"font\" },\n\t\"text-lg\": { value: \"1.125rem\", type: \"font\" },\n\t\"text-xl\": { value: \"1.25rem\", type: \"font\" },\n\t\"text-2xl\": { value: \"1.5rem\", type: \"font\" },\n\t\"text-3xl\": { value: \"1.875rem\", type: \"font\" },\n\n\t// ─── Motion ───\n\t\"duration-fast\": { value: \"150ms\", type: \"duration\" },\n\t\"duration-normal\": { value: \"200ms\", type: \"duration\" },\n\t\"duration-slow\": { value: \"300ms\", type: \"duration\" },\n};\n","import type { Theme, TokenValue } from \"@hex-core/registry\";\nimport { sharedTokens } from \"./shared.js\";\n\n/**\n * Tier 1 — the raw ramp. Every literal colour in the default theme is\n * declared exactly once here; the semantic tokens below reference an entry\n * by name rather than repeating its value.\n *\n * The families are deliberate:\n * - `slate-*` carries brand identity across both modes (~222 hue, low\n * saturation, so the brand recedes and content leads).\n * - `surface-*` is the cool-tinted page/card ground.\n * - `red-*` is the single destructive family, tuned so `text-destructive`\n * clears WCAG AA against its own surface in each mode.\n * - `chart-*` is a categorical palette. The monochrome slate family is\n * unfit for categorical encoding, so diagram primitives cycle these by\n * index instead of reaching for `--primary`.\n */\nconst palette = {\n\t// Slate — brand family.\n\t\"slate-50\": \"0 0% 98%\",\n\t\"slate-100\": \"222 22.5% 89%\",\n\t\"slate-200\": \"222 8% 90%\",\n\t\"slate-300\": \"222 8% 65%\",\n\t\"slate-400\": \"222 30% 60%\",\n\t\"slate-500\": \"222 8% 38%\",\n\t\"slate-600\": \"222 12% 24%\",\n\t\"slate-700\": \"222 8% 12%\",\n\t\"slate-800\": \"222 12% 14%\",\n\t\"slate-900\": \"222 25% 18%\",\n\t\"slate-950\": \"222 30% 11%\",\n\t\"slate-muted\": \"222 5% 95.9%\",\n\t\"slate-contrast\": \"240 10% 3.9%\",\n\n\t// Surface — page and card grounds.\n\t\"surface-light\": \"210 20% 98%\",\n\t\"surface-dark\": \"210 15% 2%\",\n\t\"surface-dark-raised\": \"210 15% 8%\",\n\n\t// Red — destructive family.\n\t\"red-600\": \"0 65% 43%\",\n\t\"red-300\": \"0 48.8% 68%\",\n\t\"red-contrast\": \"0 0% 8%\",\n\n\t// Chart — categorical, cycled by index.\n\t\"chart-light-1\": \"12 76% 61%\",\n\t\"chart-light-2\": \"173 58% 39%\",\n\t\"chart-light-3\": \"197 37% 50%\",\n\t\"chart-light-4\": \"43 74% 49%\",\n\t\"chart-light-5\": \"280 65% 60%\",\n\t\"chart-light-6\": \"340 75% 55%\",\n\t\"chart-dark-1\": \"12 76% 65%\",\n\t\"chart-dark-2\": \"173 58% 55%\",\n\t\"chart-dark-3\": \"197 37% 60%\",\n\t\"chart-dark-4\": \"43 74% 60%\",\n\t\"chart-dark-5\": \"280 65% 70%\",\n\t\"chart-dark-6\": \"340 75% 65%\",\n} as const;\n\n/**\n * Draw a semantic token from the ramp.\n *\n * Resolves to the literal value — so contrast math, dark-mode derivation\n * and every other value consumer keep working — while recording which\n * ramp entry it came from, which is what lets the CSS emitter write\n * `var(--slate-900)` instead of repeating the triplet.\n *\n * Type-safe by construction: a typo in the key is a compile error, which\n * a string-reference convention could not give.\n * @param key - A palette entry name\n * @param type - The token type, defaulting to `color`\n * @returns A token value carrying both the literal and its provenance\n */\nfunction ref(key: keyof typeof palette, type: TokenValue[\"type\"] = \"color\"): TokenValue {\n\treturn { value: palette[key], ref: key, type };\n}\n\nexport const defaultTheme: Theme = {\n\tname: \"default\",\n\tdisplayName: \"Default\",\n\tdescription:\n\t\t\"A modern, elegant minimalism — restrained cool-hue grayscale (~222 family) with a graphite primary and tight 0.375rem radius. Designed to recede so content leads; the cool slate carries identity across light + dark.\",\n\tpalette,\n\ttokens: {\n\t\tlight: {\n\t\t\tbackground: ref(\"surface-light\"),\n\t\t\tforeground: ref(\"slate-950\"),\n\t\t\tcard: ref(\"surface-light\"),\n\t\t\t\"card-foreground\": ref(\"slate-950\"),\n\t\t\tpopover: ref(\"surface-light\"),\n\t\t\t\"popover-foreground\": ref(\"slate-950\"),\n\t\t\tprimary: ref(\"slate-900\"),\n\t\t\t\"primary-foreground\": ref(\"slate-50\"),\n\t\t\tsecondary: ref(\"slate-muted\"),\n\t\t\t\"secondary-foreground\": ref(\"slate-contrast\"),\n\t\t\tmuted: ref(\"slate-muted\"),\n\t\t\t\"muted-foreground\": ref(\"slate-500\"),\n\t\t\taccent: ref(\"slate-muted\"),\n\t\t\t\"accent-foreground\": ref(\"slate-contrast\"),\n\t\t\t// L=43% achieves ≥4.5:1 on the destructive/5 alert background.\n\t\t\t// Gated by `pnpm a11y-audit`.\n\t\t\tdestructive: ref(\"red-600\"),\n\t\t\t\"destructive-foreground\": ref(\"slate-50\"),\n\t\t\tborder: ref(\"slate-200\"),\n\t\t\tinput: ref(\"slate-200\"),\n\t\t\tring: ref(\"slate-900\"),\n\t\t\tradius: { value: \"0.375rem\", type: \"radius\" },\n\t\t\t\"chart-1\": ref(\"chart-light-1\"),\n\t\t\t\"chart-2\": ref(\"chart-light-2\"),\n\t\t\t\"chart-3\": ref(\"chart-light-3\"),\n\t\t\t\"chart-4\": ref(\"chart-light-4\"),\n\t\t\t\"chart-5\": ref(\"chart-light-5\"),\n\t\t\t\"chart-6\": ref(\"chart-light-6\"),\n\t\t\t...sharedTokens,\n\t\t},\n\t\tdark: {\n\t\t\tbackground: ref(\"surface-dark\"),\n\t\t\tforeground: ref(\"slate-100\"),\n\t\t\t// Card/popover sit one surface step above background (L=14% vs 2%)\n\t\t\t// so SVG-rendered surfaces — org-chart cards, flowchart boxes —\n\t\t\t// read as elevated without box-shadow chrome.\n\t\t\tcard: ref(\"slate-800\"),\n\t\t\tpopover: ref(\"slate-800\"),\n\t\t\tprimary: ref(\"slate-400\"),\n\t\t\tsecondary: ref(\"slate-700\"),\n\t\t\tmuted: ref(\"slate-700\"),\n\t\t\taccent: ref(\"slate-700\"),\n\t\t\t// L=68%, not 58%, so `text-destructive` on the dark card clears\n\t\t\t// WCAG AA 4.5:1 (was 4.02:1).\n\t\t\tdestructive: ref(\"red-300\"),\n\t\t\t// L=24%, not 14%, so SVG outlines — chord arcs, sankey segments,\n\t\t\t// gantt grid — have actual definition against the card.\n\t\t\tborder: ref(\"slate-600\"),\n\t\t\tinput: ref(\"slate-600\"),\n\t\t\tring: ref(\"slate-400\"),\n\t\t\tradius: { value: \"0.375rem\", type: \"radius\" },\n\t\t\t\"card-foreground\": ref(\"slate-100\"),\n\t\t\t\"popover-foreground\": ref(\"slate-100\"),\n\t\t\t\"primary-foreground\": ref(\"surface-dark-raised\"),\n\t\t\t\"secondary-foreground\": ref(\"slate-100\"),\n\t\t\t\"muted-foreground\": ref(\"slate-300\"),\n\t\t\t\"accent-foreground\": ref(\"slate-100\"),\n\t\t\t\"destructive-foreground\": ref(\"red-contrast\"),\n\t\t\t\"chart-1\": ref(\"chart-dark-1\"),\n\t\t\t\"chart-2\": ref(\"chart-dark-2\"),\n\t\t\t\"chart-3\": ref(\"chart-dark-3\"),\n\t\t\t\"chart-4\": ref(\"chart-dark-4\"),\n\t\t\t\"chart-5\": ref(\"chart-dark-5\"),\n\t\t\t\"chart-6\": ref(\"chart-dark-6\"),\n\t\t\t...sharedTokens,\n\t\t},\n\t},\n};\n","import type { Theme, TokenValue } from \"@hex-core/registry\";\nimport { sharedTokens } from \"./shared.js\";\n\n/**\n * Tier 1 — the raw ramp. Every literal colour in the Midnight theme is\n * declared exactly once here; the semantic tokens below reference an entry\n * by name rather than repeating its value.\n *\n * - `indigo-*` is the brand family, and is deliberately the same value in\n * both modes — Midnight's identity does not shift with the mode.\n * - `slate-*` is a single cool neutral ramp spanning both modes.\n * - `red-*` is the destructive family.\n * - `chart-*` is the categorical palette, cycled by index.\n */\nconst palette = {\n\t// Indigo — brand.\n\t\"indigo-400\": \"226 70% 65%\",\n\t\"indigo-500\": \"226 70% 55%\",\n\n\t// Slate — cool neutral ramp, both modes.\n\t\"slate-0\": \"0 0% 100%\",\n\t\"slate-25\": \"220 23% 99%\",\n\t\"slate-50\": \"220 23% 97%\",\n\t\"slate-100\": \"220 23% 95%\",\n\t\"slate-150\": \"220 14% 94%\",\n\t\"slate-200\": \"220 14% 92%\",\n\t\"slate-300\": \"220 13% 88%\",\n\t\"slate-400\": \"220 9% 70%\",\n\t\"slate-500\": \"220 9% 38%\",\n\t\"slate-800\": \"224 30% 15%\",\n\t\"slate-825\": \"224 20% 14%\",\n\t\"slate-850\": \"224 30% 13%\",\n\t\"slate-900\": \"224 50% 7%\",\n\t\"slate-950\": \"224 71% 4%\",\n\n\t// Red — destructive.\n\t\"red-300\": \"0 75% 65%\",\n\t\"red-600\": \"0 72% 45%\",\n\t\"red-950\": \"0 75% 15%\",\n\n\t// Chart — categorical, cycled by index.\n\t\"chart-light-1\": \"226 70% 55%\",\n\t\"chart-light-2\": \"165 60% 40%\",\n\t\"chart-light-3\": \"20 80% 55%\",\n\t\"chart-light-4\": \"280 65% 60%\",\n\t\"chart-light-5\": \"45 80% 55%\",\n\t\"chart-light-6\": \"330 70% 55%\",\n\t\"chart-dark-1\": \"226 70% 65%\",\n\t\"chart-dark-2\": \"165 60% 55%\",\n\t\"chart-dark-3\": \"20 80% 65%\",\n\t\"chart-dark-4\": \"280 65% 70%\",\n\t\"chart-dark-5\": \"45 80% 65%\",\n\t\"chart-dark-6\": \"330 70% 65%\",\n} as const;\n\n/**\n * Draw a semantic token from the ramp.\n *\n * Resolves to the literal value while recording which ramp entry it came\n * from, which is what lets the CSS emitter write `var(--slate-900)`\n * instead of repeating the triplet. A typo in the key is a compile error.\n * @param key - A palette entry name\n * @param type - The token type, defaulting to `color`\n * @returns A token value carrying both the literal and its provenance\n */\nfunction ref(key: keyof typeof palette, type: TokenValue[\"type\"] = \"color\"): TokenValue {\n\treturn { value: palette[key], ref: key, type };\n}\n\nexport const midnightTheme: Theme = {\n\tname: \"midnight\",\n\tdisplayName: \"Midnight\",\n\tdescription:\n\t\t\"A dark-first theme with deep blues and electric accents. Built for focus-heavy interfaces and developer tools.\",\n\tpalette,\n\ttokens: {\n\t\tlight: {\n\t\t\tbackground: ref(\"slate-50\"),\n\t\t\tforeground: ref(\"slate-950\"),\n\t\t\tcard: ref(\"slate-25\"),\n\t\t\t\"card-foreground\": ref(\"slate-950\"),\n\t\t\tpopover: ref(\"slate-25\"),\n\t\t\t\"popover-foreground\": ref(\"slate-950\"),\n\t\t\tprimary: ref(\"indigo-500\"),\n\t\t\t\"primary-foreground\": ref(\"slate-0\"),\n\t\t\tsecondary: ref(\"slate-200\"),\n\t\t\t\"secondary-foreground\": ref(\"slate-950\"),\n\t\t\tmuted: ref(\"slate-150\"),\n\t\t\t\"muted-foreground\": ref(\"slate-500\"),\n\t\t\taccent: ref(\"slate-200\"),\n\t\t\t\"accent-foreground\": ref(\"slate-950\"),\n\t\t\tdestructive: ref(\"red-600\"),\n\t\t\t\"destructive-foreground\": ref(\"slate-0\"),\n\t\t\tborder: ref(\"slate-300\"),\n\t\t\tinput: ref(\"slate-300\"),\n\t\t\tring: ref(\"indigo-500\"),\n\t\t\tradius: { value: \"0.5rem\", type: \"radius\" },\n\t\t\t// Chart palette — cool-leaning hues that complement the\n\t\t\t// midnight blue primary while staying perceptually distinct\n\t\t\t// for categorical encoding.\n\t\t\t\"chart-1\": ref(\"chart-light-1\"),\n\t\t\t\"chart-2\": ref(\"chart-light-2\"),\n\t\t\t\"chart-3\": ref(\"chart-light-3\"),\n\t\t\t\"chart-4\": ref(\"chart-light-4\"),\n\t\t\t\"chart-5\": ref(\"chart-light-5\"),\n\t\t\t\"chart-6\": ref(\"chart-light-6\"),\n\t\t\t...sharedTokens,\n\t\t},\n\t\tdark: {\n\t\t\tbackground: ref(\"slate-950\"),\n\t\t\tforeground: ref(\"slate-100\"),\n\t\t\tcard: ref(\"slate-900\"),\n\t\t\t\"card-foreground\": ref(\"slate-100\"),\n\t\t\tpopover: ref(\"slate-900\"),\n\t\t\t\"popover-foreground\": ref(\"slate-100\"),\n\t\t\tprimary: ref(\"indigo-500\"),\n\t\t\t\"primary-foreground\": ref(\"slate-0\"),\n\t\t\tsecondary: ref(\"slate-850\"),\n\t\t\t\"secondary-foreground\": ref(\"slate-100\"),\n\t\t\tmuted: ref(\"slate-850\"),\n\t\t\t\"muted-foreground\": ref(\"slate-400\"),\n\t\t\taccent: ref(\"slate-800\"),\n\t\t\t\"accent-foreground\": ref(\"slate-100\"),\n\t\t\t/*\n\t\t\t * Destructive in dark mode doubles as text on near-black surfaces\n\t\t\t * (alerts, error helper text). A lighter coral-red gives ~7:1 on\n\t\t\t * background and ~5:1 on the same color when paired with the dark\n\t\t\t * destructive-foreground for button bg + label combos. Same tuning\n\t\t\t * as default.ts; intentional shadcn-divergence in service of WCAG AA.\n\t\t\t */\n\t\t\tdestructive: ref(\"red-300\"),\n\t\t\t\"destructive-foreground\": ref(\"red-950\"),\n\t\t\tborder: ref(\"slate-825\"),\n\t\t\tinput: ref(\"slate-825\"),\n\t\t\tring: ref(\"indigo-500\"),\n\t\t\tradius: { value: \"0.5rem\", type: \"radius\" },\n\t\t\t// Lifted lightness so segments stay legible against deep navy bg.\n\t\t\t\"chart-1\": ref(\"chart-dark-1\"),\n\t\t\t\"chart-2\": ref(\"chart-dark-2\"),\n\t\t\t\"chart-3\": ref(\"chart-dark-3\"),\n\t\t\t\"chart-4\": ref(\"chart-dark-4\"),\n\t\t\t\"chart-5\": ref(\"chart-dark-5\"),\n\t\t\t\"chart-6\": ref(\"chart-dark-6\"),\n\t\t\t...sharedTokens,\n\t\t},\n\t},\n};\n","import type { Theme, TokenValue } from \"@hex-core/registry\";\nimport { sharedTokens } from \"./shared.js\";\n\n/**\n * Tier 1 — the raw ramp. Every literal colour in the Ember theme is\n * declared exactly once here; the semantic tokens below reference an entry\n * by name rather than repeating its value.\n *\n * - `ember-*` is the terracotta brand family.\n * - `sand-*` / `bark-*` are the warm light and dark neutral ramps; note\n * `sand-100` serves as dark-mode foreground, which is the point of a\n * shared ramp — one value, two roles.\n * - `red-*` is the destructive family.\n * - `chart-*` is the categorical palette, cycled by index.\n */\nconst palette = {\n\t// Ember — terracotta brand.\n\t\"ember-400\": \"16 65% 52%\",\n\t\"ember-500\": \"16 65% 48%\",\n\n\t// Sand — warm light neutrals.\n\t\"sand-0\": \"0 0% 100%\",\n\t\"sand-25\": \"30 33% 99%\",\n\t\"sand-50\": \"30 33% 98%\",\n\t\"sand-100\": \"30 20% 94%\",\n\t\"sand-200\": \"30 20% 92%\",\n\t\"sand-300\": \"30 15% 87%\",\n\t\"amber-100\": \"36 60% 90%\",\n\n\t// Bark — warm dark neutrals.\n\t\"bark-400\": \"20 6% 70%\",\n\t\"bark-500\": \"20 6% 38%\",\n\t\"bark-800\": \"20 20% 16%\",\n\t\"bark-825\": \"20 10% 16%\",\n\t\"bark-850\": \"20 12% 14%\",\n\t\"bark-900\": \"20 14% 10%\",\n\t\"bark-925\": \"20 14% 8%\",\n\t\"bark-950\": \"20 14% 6%\",\n\n\t// Red — destructive.\n\t\"red-300\": \"0 75% 65%\",\n\t\"red-600\": \"0 72% 45%\",\n\t\"red-950\": \"0 75% 15%\",\n\n\t// Chart — categorical, cycled by index.\n\t\"chart-light-1\": \"16 75% 55%\",\n\t\"chart-light-2\": \"180 55% 38%\",\n\t\"chart-light-3\": \"200 60% 50%\",\n\t\"chart-light-4\": \"45 80% 50%\",\n\t\"chart-light-5\": \"280 60% 60%\",\n\t\"chart-light-6\": \"330 70% 55%\",\n\t\"chart-dark-1\": \"16 75% 60%\",\n\t\"chart-dark-2\": \"180 55% 55%\",\n\t\"chart-dark-3\": \"200 60% 60%\",\n\t\"chart-dark-4\": \"45 80% 60%\",\n\t\"chart-dark-5\": \"280 60% 70%\",\n\t\"chart-dark-6\": \"330 70% 65%\",\n} as const;\n\n/**\n * Draw a semantic token from the ramp.\n *\n * Resolves to the literal value while recording which ramp entry it came\n * from, which is what lets the CSS emitter write `var(--slate-900)`\n * instead of repeating the triplet. A typo in the key is a compile error.\n * @param key - A palette entry name\n * @param type - The token type, defaulting to `color`\n * @returns A token value carrying both the literal and its provenance\n */\nfunction ref(key: keyof typeof palette, type: TokenValue[\"type\"] = \"color\"): TokenValue {\n\treturn { value: palette[key], ref: key, type };\n}\n\nexport const emberTheme: Theme = {\n\tname: \"ember\",\n\tdisplayName: \"Ember\",\n\tdescription:\n\t\t\"A warm theme with terracotta and amber tones. Inviting and distinctive, ideal for creative and lifestyle applications.\",\n\tpalette,\n\ttokens: {\n\t\tlight: {\n\t\t\tbackground: ref(\"sand-50\"),\n\t\t\tforeground: ref(\"bark-900\"),\n\t\t\tcard: ref(\"sand-25\"),\n\t\t\t\"card-foreground\": ref(\"bark-900\"),\n\t\t\tpopover: ref(\"sand-25\"),\n\t\t\t\"popover-foreground\": ref(\"bark-900\"),\n\t\t\tprimary: ref(\"ember-500\"),\n\t\t\t\"primary-foreground\": ref(\"sand-0\"),\n\t\t\tsecondary: ref(\"sand-200\"),\n\t\t\t\"secondary-foreground\": ref(\"bark-900\"),\n\t\t\tmuted: ref(\"sand-100\"),\n\t\t\t\"muted-foreground\": ref(\"bark-500\"),\n\t\t\taccent: ref(\"amber-100\"),\n\t\t\t\"accent-foreground\": ref(\"bark-900\"),\n\t\t\tdestructive: ref(\"red-600\"),\n\t\t\t\"destructive-foreground\": ref(\"sand-0\"),\n\t\t\tborder: ref(\"sand-300\"),\n\t\t\tinput: ref(\"sand-300\"),\n\t\t\tring: ref(\"ember-500\"),\n\t\t\tradius: { value: \"0.75rem\", type: \"radius\" },\n\t\t\t// Chart palette — warm-leaning hues that complement the ember\n\t\t\t// terracotta primary while staying perceptually distinct from\n\t\t\t// each other for categorical encoding (sunburst/treemap/sankey/\n\t\t\t// chord/funnel/pyramid/venn/matrix).\n\t\t\t\"chart-1\": ref(\"chart-light-1\"),\n\t\t\t\"chart-2\": ref(\"chart-light-2\"),\n\t\t\t\"chart-3\": ref(\"chart-light-3\"),\n\t\t\t\"chart-4\": ref(\"chart-light-4\"),\n\t\t\t\"chart-5\": ref(\"chart-light-5\"),\n\t\t\t\"chart-6\": ref(\"chart-light-6\"),\n\t\t\t...sharedTokens,\n\t\t},\n\t\tdark: {\n\t\t\tbackground: ref(\"bark-950\"),\n\t\t\tforeground: ref(\"sand-100\"),\n\t\t\tcard: ref(\"bark-925\"),\n\t\t\t\"card-foreground\": ref(\"sand-100\"),\n\t\t\tpopover: ref(\"bark-925\"),\n\t\t\t\"popover-foreground\": ref(\"sand-100\"),\n\t\t\tprimary: ref(\"ember-400\"),\n\t\t\t\"primary-foreground\": ref(\"sand-0\"),\n\t\t\tsecondary: ref(\"bark-850\"),\n\t\t\t\"secondary-foreground\": ref(\"sand-100\"),\n\t\t\tmuted: ref(\"bark-850\"),\n\t\t\t\"muted-foreground\": ref(\"bark-400\"),\n\t\t\taccent: ref(\"bark-800\"),\n\t\t\t\"accent-foreground\": ref(\"sand-100\"),\n\t\t\t/*\n\t\t\t * Destructive in dark mode doubles as text on near-black surfaces\n\t\t\t * (alerts, error helper text). A lighter coral-red gives ~7:1 on\n\t\t\t * background and ~5:1 on the same color when paired with the dark\n\t\t\t * destructive-foreground. Same tuning as default.ts.\n\t\t\t */\n\t\t\tdestructive: ref(\"red-300\"),\n\t\t\t\"destructive-foreground\": ref(\"red-950\"),\n\t\t\tborder: ref(\"bark-825\"),\n\t\t\tinput: ref(\"bark-825\"),\n\t\t\tring: ref(\"ember-400\"),\n\t\t\tradius: { value: \"0.75rem\", type: \"radius\" },\n\t\t\t// Lifted lightness so segments stay legible against the warm\n\t\t\t// near-black background.\n\t\t\t\"chart-1\": ref(\"chart-dark-1\"),\n\t\t\t\"chart-2\": ref(\"chart-dark-2\"),\n\t\t\t\"chart-3\": ref(\"chart-dark-3\"),\n\t\t\t\"chart-4\": ref(\"chart-dark-4\"),\n\t\t\t\"chart-5\": ref(\"chart-dark-5\"),\n\t\t\t\"chart-6\": ref(\"chart-dark-6\"),\n\t\t\t...sharedTokens,\n\t\t},\n\t},\n};\n","import type { SemanticTokenSet, TokenSet, TokenValue } from \"@hex-core/registry\";\n\n/**\n * Semantic-token map (added 0.4.0) — the **intent layer** over the raw\n * `defaultTheme` tokens. Each entry references a raw token via flat\n * `{token-name}` syntax (the token name matches the literal key in\n * `defaultTheme.tokens.light` / `.dark`) and adds a `useWhen` sentence\n * describing the UI-element class it's the right choice for.\n *\n * Why this exists: the raw `--color-destructive` ships a value, but an\n * LLM picking a token for \"delete button background\" has to guess that\n * `destructive` maps to \"irreversible action\" rather than to \"validation\n * error\" or \"system alert\" — those are different design intents that\n * happen to share a hue today. Naming the *intent* lets MCP, Studio, and\n * future LLM workflows reach for the correct token without color-vibe\n * heuristics.\n *\n * Naming convention: `<component>.<state-or-slot>.<role>`. Use\n * `dialog.overlay.bg`, not `dialog-overlay-bg`. The leading segment is\n * the API — MCP groups by it.\n *\n * **Theme-portable.** The map references raw token names by reference\n * (`{destructive}`), so swapping the underlying theme automatically\n * shifts every semantic entry without any per-theme rewrite. Themes that\n * want to redefine semantic intent (e.g. a fintech theme where\n * \"destructive\" reads more muted) can ship their own `SemanticTokenSet`\n * alongside their `Theme`.\n *\n * **Coverage is intentionally partial.** Common high-leverage intents\n * are named (button, surface, form, feedback, shape, motion); arbitrary\n * combinatorial intents (`table.row.bg-hover`, `badge.intent.warning`)\n * are deferred. Consumers querying an unnamed intent fall through to\n * the raw `defaultTheme` layer.\n */\nexport const defaultSemanticTokens: SemanticTokenSet = {\n\t// ─── Button intents ─────────────────────────────────────────────\n\t\"button.primary.bg\": {\n\t\tvalue: \"{primary}\",\n\t\tuseWhen: \"the single most important action on the screen (one per view)\",\n\t\ttype: \"color\",\n\t},\n\t\"button.primary.fg\": {\n\t\tvalue: \"{primary-foreground}\",\n\t\tuseWhen: \"text on a primary button\",\n\t\ttype: \"color\",\n\t},\n\t\"button.destructive.bg\": {\n\t\tvalue: \"{destructive}\",\n\t\tuseWhen: \"irreversible actions: delete, archive, deactivate, leave, force-quit\",\n\t\ttype: \"color\",\n\t},\n\t\"button.destructive.fg\": {\n\t\tvalue: \"{destructive-foreground}\",\n\t\tuseWhen: \"text on a destructive button\",\n\t\ttype: \"color\",\n\t},\n\t\"button.secondary.bg\": {\n\t\tvalue: \"{secondary}\",\n\t\tuseWhen: \"the second-tier action next to a primary button (Cancel, Save Draft)\",\n\t\ttype: \"color\",\n\t},\n\t\"button.outline.border\": {\n\t\tvalue: \"{input}\",\n\t\tuseWhen: \"tertiary actions on flat surfaces; signals 'optional'\",\n\t\ttype: \"color\",\n\t},\n\t\"button.ghost.bg-hover\": {\n\t\tvalue: \"{accent}\",\n\t\tuseWhen: \"lowest-emphasis action; lives inside a list/toolbar where chrome should disappear\",\n\t\ttype: \"color\",\n\t},\n\n\t// ─── Surface intents ────────────────────────────────────────────\n\t\"surface.card.bg\": {\n\t\tvalue: \"{card}\",\n\t\tuseWhen: \"a content container raised one level above the page background\",\n\t\ttype: \"color\",\n\t},\n\t\"surface.popover.bg\": {\n\t\tvalue: \"{popover}\",\n\t\tuseWhen: \"a transient floating layer (dropdown, tooltip body, hover-card) above all content\",\n\t\ttype: \"color\",\n\t},\n\t\"surface.muted.bg\": {\n\t\tvalue: \"{muted}\",\n\t\tuseWhen: \"background of a section that should recede (footer, disabled state, code block)\",\n\t\ttype: \"color\",\n\t},\n\n\t// ─── Form intents ───────────────────────────────────────────────\n\t\"form.field.border\": {\n\t\tvalue: \"{input}\",\n\t\tuseWhen: \"the resting border of a form input, textarea, or select trigger\",\n\t\ttype: \"color\",\n\t},\n\t\"form.field.border-error\": {\n\t\tvalue: \"{destructive}\",\n\t\tuseWhen: \"input validation has failed and the field needs visual correction\",\n\t\ttype: \"color\",\n\t},\n\t\"form.field.ring-focus\": {\n\t\tvalue: \"{ring}\",\n\t\tuseWhen: \"the keyboard-focus ring on any focusable form control\",\n\t\ttype: \"color\",\n\t},\n\t\"form.message.error-fg\": {\n\t\tvalue: \"{destructive}\",\n\t\tuseWhen: \"inline error text below a failed field\",\n\t\ttype: \"color\",\n\t},\n\n\t// ─── Feedback intents ───────────────────────────────────────────\n\t\"feedback.success.bg\": {\n\t\tvalue: \"{primary}\",\n\t\tuseWhen: \"success toast / banner background. Note: default theme reuses primary; opinionated themes should split this from primary\",\n\t\ttype: \"color\",\n\t},\n\t\"feedback.error.bg\": {\n\t\tvalue: \"{destructive}\",\n\t\tuseWhen: \"error toast / banner background\",\n\t\ttype: \"color\",\n\t},\n\t\"feedback.muted.fg\": {\n\t\tvalue: \"{muted-foreground}\",\n\t\tuseWhen: \"secondary copy: helper text, captions, timestamps, empty-state body\",\n\t\ttype: \"color\",\n\t},\n\n\t// ─── Shape + motion intents ─────────────────────────────────────\n\t\"shape.radius.control\": {\n\t\tvalue: \"{radius}\",\n\t\tuseWhen: \"the corner radius of any interactive control (button, input, badge, chip)\",\n\t\ttype: \"radius\",\n\t},\n\t\"motion.duration.control\": {\n\t\tvalue: \"{duration-normal}\",\n\t\tuseWhen: \"hover, press, and focus transitions on interactive controls\",\n\t\ttype: \"duration\",\n\t},\n\t\"motion.duration.overlay\": {\n\t\tvalue: \"{duration-slow}\",\n\t\tuseWhen: \"dialog/sheet/drawer enter+exit; longer to telegraph the surface change\",\n\t\ttype: \"duration\",\n\t},\n};\n\n/**\n * Resolve a `{token-name}` reference against a `TokenSet` and return\n * the underlying `TokenValue`, or `null` if the reference doesn't\n * match a token in the set. Single-hop lookup — no recursion, no\n * fallback chains.\n *\n * Use this when an MCP/Studio surface needs the resolved value\n * (e.g. to render a swatch next to the semantic name) rather than the\n * `{ref}` placeholder string.\n *\n * @example\n * ```ts\n * import { defaultSemanticTokens, defaultTheme, resolveSemanticToken } from \"@hex-core/tokens\";\n *\n * const entry = defaultSemanticTokens[\"button.destructive.bg\"];\n * const resolved = resolveSemanticToken(entry.value, defaultTheme.tokens.light);\n * // resolved → { value: \"0 84% 60%\", type: \"color\" }\n * ```\n */\nexport function resolveSemanticToken(\n\treference: string,\n\ttokenSet: TokenSet,\n): TokenValue | null {\n\tconst match = /^\\{([a-z][a-z0-9-]*)\\}$/.exec(reference);\n\tif (!match) return null;\n\tconst slug = match[1];\n\tif (!slug) return null;\n\tconst value = tokenSet[slug];\n\treturn value ?? null;\n}\n\n","import { type Hsl, hsl, parse, wcagContrast, wcagLuminance } from \"culori\";\nimport type { ColorToken, TokenSet } from \"@hex-core/registry\";\n\n/**\n * Color-math helpers shared by the CLI (`hex theme init -i`) and Studio\n * (`hex-ui-platform`'s React sliders). Pure functions over the canonical\n * HSL-triplet token-value shape (`\"<H> <S>% <L>%\"`); no I/O, no UI, no\n * framework deps. Both shells (terminal + web) wrap these with their own\n * input pickers and feed the same shape back in.\n *\n * Keeping these in `@hex-core/tokens` (rather than `@hex-core/cli`) means\n * Studio reuses the same logic web-side without bundling commander or\n * '@inquirer/prompts', AND any future theme tooling lands on a single\n * source of truth for \"what should a derived foreground / dark variant /\n * secondary look like.\"\n *\n * Each helper accepts an optional opts bag so Studio's web sliders can\n * expose the magic numbers as user-tunable controls without breaking the\n * CLI's call sites. Defaults preserve the canonical Hex Core look.\n */\n\n/**\n * Parse a hex-core HSL-triplet token value (`\"240 10% 3.9%\"`) into a\n * culori `Hsl` record. Throws on malformed input — token values that\n * already passed `tokenValueSchema` validation should never throw here.\n *\n * @param value - HSL-triplet string (`\"<H> <S>% <L>%\"`)\n * @returns A culori `Hsl` color record with `s` and `l` normalized to 0–1.\n */\nfunction parseTokenHsl(value: string): Hsl {\n\tconst match = /^([\\d.]+)\\s+([\\d.]+)%\\s+([\\d.]+)%$/.exec(value.trim());\n\tif (!match) {\n\t\tthrow new Error(\n\t\t\t`Invalid HSL triplet: \"${value}\". Expected \"<H> <S>% <L>%\" (e.g. \"240 10% 3.9%\").`,\n\t\t);\n\t}\n\treturn {\n\t\tmode: \"hsl\",\n\t\th: Number(match[1]),\n\t\ts: Number(match[2]) / 100,\n\t\tl: Number(match[3]) / 100,\n\t};\n}\n\n/**\n * Format a culori Hsl record back into a hex-core token value\n * (`\"240 10% 3.9%\"`). Inverse of `parseTokenHsl`.\n *\n * Hue is rounded to the nearest integer because hex-core themes\n * traditionally ship integer hues (the human eye doesn't distinguish\n * sub-degree hue shifts in the same lightness band). Saturation and\n * lightness are kept at 1-decimal precision because the difference\n * between 4.8% and 5.2% saturation IS visible (especially on hover\n * states + borders).\n *\n * @param color - culori `Hsl` record\n * @returns Hex-core HSL-triplet string\n */\nfunction formatTokenHsl(color: Hsl): string {\n\tconst h = Math.round(color.h ?? 0);\n\tconst s = ((color.s ?? 0) * 100).toFixed(1).replace(/\\.0$/, \"\");\n\tconst l = ((color.l ?? 0) * 100).toFixed(1).replace(/\\.0$/, \"\");\n\treturn `${h} ${s}% ${l}%`;\n}\n\nconst NEAR_WHITE: ColorToken = { value: \"0 0% 98%\", type: \"color\" };\nconst NEAR_BLACK: ColorToken = { value: \"240 10% 3.9%\", type: \"color\" };\n\n/**\n * Options for `deriveForegroundFor`. Pass custom `light` / `dark`\n * anchors when your theme uses non-canonical near-white / near-black\n * shades (e.g. a warm cream on a cool charcoal).\n */\nexport interface DeriveForegroundOptions {\n\t/** Pole used for backgrounds darker than the pole's luminance. Defaults to `\"0 0% 98%\"`. */\n\tlight?: ColorToken;\n\t/** Pole used for backgrounds lighter than the pole's luminance. Defaults to `\"240 10% 3.9%\"`. */\n\tdark?: ColorToken;\n}\n\n/**\n * Pick the foreground that hits the highest WCAG contrast against\n * `bg`. Returns either the `light` or `dark` anchor (defaults: the\n * canonical near-white / near-black; pass `opts` to override). Always\n * achieves the best of the two anchors against the input.\n *\n * @param bgValue - HSL-triplet token value of the background color\n * @param opts - Optional anchor override; see {@link DeriveForegroundOptions}\n * @returns A `ColorToken` for the chosen foreground\n *\n * @example\n * deriveForegroundFor(\"240 10% 3.9%\") // → near-white { value: \"0 0% 98%\", type: \"color\" }\n * deriveForegroundFor(\"0 0% 100%\") // → near-black { value: \"240 10% 3.9%\", type: \"color\" }\n */\nexport function deriveForegroundFor(\n\tbgValue: string,\n\topts: DeriveForegroundOptions = {},\n): ColorToken {\n\tconst light = opts.light ?? NEAR_WHITE;\n\tconst dark = opts.dark ?? NEAR_BLACK;\n\tconst bg = parseTokenHsl(bgValue);\n\tconst contrastLight = wcagContrast(bg, parseTokenHsl(light.value));\n\tconst contrastDark = wcagContrast(bg, parseTokenHsl(dark.value));\n\treturn contrastLight >= contrastDark ? light : dark;\n}\n\n/**\n * Options for `deriveDarkFromLight`. Studio's sliders expose these so\n * users can dial back the saturation cut for richer dark palettes, or\n * shift the inversion pivot to match a non-symmetric lightness curve.\n */\nexport interface DeriveDarkOptions {\n\t/**\n\t * Saturation multiplier applied during inversion (default `0.75`).\n\t * HSL's perceptual non-uniformity makes fully-saturated bright\n\t * colors read as neon-toxic when flipped to low lightness — the\n\t * 25% cut compensates. Pass `1` to keep saturation; pass `0.5` for\n\t * a more muted dark mode.\n\t */\n\tsaturationFactor?: number;\n\t/**\n\t * Inversion pivot (default `0.5`). Lightness gets mirrored around\n\t * this point — `pivot=0.5` gives `0.95L → 0.05L`. A pivot above 0.5\n\t * yields a \"lighter dark mode\"; below 0.5 yields a \"darker dark\n\t * mode.\" Range `[0, 1]`.\n\t */\n\tpivotLightness?: number;\n}\n\n/**\n * Slot names that store a \"base\" color (not a foreground-of-something).\n * `*-foreground` slots get re-derived from the inverted base via\n * `deriveForegroundFor` so AA contrast survives the round-trip.\n */\nconst BASE_SLOT_REGEX = /-foreground$/;\n\n/**\n * Mirror a light-mode TokenSet into a coherent dark-mode TokenSet.\n *\n * For each base color slot (e.g. `primary`, `card`, `destructive`,\n * `background`, `border`), invert the lightness around `pivotLightness`\n * and reduce saturation by `saturationFactor` (default 0.75).\n *\n * For each `*-foreground` slot, re-derive against the inverted base\n * via `deriveForegroundFor`. **This is critical** — naïvely inverting\n * `primary-foreground` lightness produces sub-AA contrast against the\n * inverted `primary` (the foreground was previously chosen with the\n * light primary in mind). See the AA-invariant tests in\n * `derive.test.ts`.\n *\n * Authors who want a curated dark palette should pick `author-now` in\n * the CLI's dark-mode prompt and re-walk the surface seeds. This\n * helper is the \"good-enough\" default for the `auto-derive` path.\n *\n * @param light - Light-mode TokenSet (must contain all `REQUIRED_COLOR_TOKENS`)\n * @param opts - Optional saturation / pivot overrides; see {@link DeriveDarkOptions}\n * @returns A new TokenSet with bases inverted + foregrounds re-derived for AA\n */\nexport function deriveDarkFromLight(\n\tlight: TokenSet,\n\topts: DeriveDarkOptions = {},\n): TokenSet {\n\tconst saturationFactor = opts.saturationFactor ?? 0.75;\n\tconst pivot = opts.pivotLightness ?? 0.5;\n\n\t// First pass: invert every BASE color (skip `*-foreground` and\n\t// non-color tokens). Foregrounds get re-derived in pass 2.\n\tconst dark: TokenSet = {};\n\tfor (const [name, token] of Object.entries(light)) {\n\t\tif (token.type !== \"color\") {\n\t\t\tdark[name] = token;\n\t\t\tcontinue;\n\t\t}\n\t\tif (BASE_SLOT_REGEX.test(name)) continue;\n\t\tconst color = parseTokenHsl(token.value);\n\t\tconst inverted: Hsl = {\n\t\t\tmode: \"hsl\",\n\t\t\th: color.h ?? 0,\n\t\t\ts: Math.max(0, (color.s ?? 0) * saturationFactor),\n\t\t\tl: Math.max(0, Math.min(1, 2 * pivot - (color.l ?? 0))),\n\t\t};\n\t\tdark[name] = { value: formatTokenHsl(inverted), type: \"color\" };\n\t}\n\n\t// Second pass: for each `*-foreground` slot, find the matching base\n\t// in the dark set and re-derive a contrast-safe foreground. Falls\n\t// back to a naive inversion if the base isn't in the set (defensive;\n\t// shouldn't happen for a strict-validated TokenSet).\n\tfor (const [name, token] of Object.entries(light)) {\n\t\tif (token.type !== \"color\" || !BASE_SLOT_REGEX.test(name)) continue;\n\t\tconst baseName = name.replace(BASE_SLOT_REGEX, \"\");\n\t\tconst darkBase = dark[baseName];\n\t\tif (darkBase && darkBase.type === \"color\") {\n\t\t\tdark[name] = deriveForegroundFor(darkBase.value);\n\t\t} else {\n\t\t\tconst color = parseTokenHsl(token.value);\n\t\t\tdark[name] = {\n\t\t\t\tvalue: formatTokenHsl({ ...color, l: Math.max(0, Math.min(1, 2 * pivot - (color.l ?? 0))) }),\n\t\t\t\ttype: \"color\",\n\t\t\t};\n\t\t}\n\t}\n\n\treturn dark;\n}\n\n/**\n * Options for `deriveSecondaryFromPrimary`. Studio's sliders expose\n * the lightness band + saturation cap so users can author a richer or\n * more muted secondary fill.\n */\nexport interface DeriveSecondaryOptions {\n\t/**\n\t * Target lightness for the derived secondary (default `0.959`).\n\t * The canonical Hex Core secondary lightness band — keeps button\n\t * surfaces flush with `--muted` and `--accent` in light mode. Range `[0, 1]`.\n\t */\n\tlightness?: number;\n\t/**\n\t * Maximum saturation kept from the primary (default `0.05`). The\n\t * derived secondary should feel related but recede; capping\n\t * saturation at 5% gives the \"almost-gray with a hint of brand\"\n\t * effect.\n\t */\n\tsaturationCap?: number;\n}\n\n/**\n * Derive a `secondary` color from `primary` by desaturating + shifting\n * lightness toward a near-neutral. Produces the muted-but-related fill\n * Cancel/Save-Draft buttons want next to a primary CTA.\n *\n * The derived secondary preserves the primary's hue so the pairing\n * reads as intentional. Foreground pairing is the caller's job — feed\n * the result through `deriveForegroundFor` to get a contrast-safe text\n * color.\n *\n * @param primaryValue - HSL-triplet token value of the primary color\n * @param opts - Optional lightness / saturation-cap overrides; see {@link DeriveSecondaryOptions}\n * @returns A `ColorToken` for the derived secondary\n */\nexport function deriveSecondaryFromPrimary(\n\tprimaryValue: string,\n\topts: DeriveSecondaryOptions = {},\n): ColorToken {\n\tconst lightness = opts.lightness ?? 0.959;\n\tconst saturationCap = opts.saturationCap ?? 0.05;\n\tconst primary = parseTokenHsl(primaryValue);\n\tconst secondary: Hsl = {\n\t\tmode: \"hsl\",\n\t\th: primary.h ?? 0,\n\t\ts: Math.min(saturationCap, primary.s ?? 0),\n\t\tl: lightness,\n\t};\n\treturn { value: formatTokenHsl(secondary), type: \"color\" };\n}\n\n/**\n * Compute the WCAG contrast ratio between a foreground / background\n * token pair. Use as an authoring-time guard, not a runtime gate —\n * themes that ship with sub-AA pairs are caller's responsibility. AA\n * threshold is 4.5:1 for body text, 3:1 for large/UI text per WCAG 1.4.3.\n *\n * @param fgValue - foreground HSL-triplet\n * @param bgValue - background HSL-triplet\n * @returns The contrast ratio (≥4.5 means AA-pass for body text)\n */\nexport function contrastRatio(fgValue: string, bgValue: string): number {\n\tconst fg = parseTokenHsl(fgValue);\n\tconst bg = parseTokenHsl(bgValue);\n\treturn wcagContrast(fg, bg);\n}\n\n/**\n * Convenience: parse a freeform color string (`\"#1e293b\"`, `\"navy\"`,\n * `\"hsl(220 13% 18%)\"`) into a hex-core token value. Used by the CLI's\n * interactive prompt so the user can paste a hex from their design tool\n * directly without manual HSL conversion.\n *\n * Note: only standard CSS named colors (`navy`, `rebeccapurple`,\n * `tomato`, etc.) parse — Tailwind palette names like `slate` or\n * `zinc` are not in the CSS spec and return `null`.\n *\n * @param input - Anything culori's `parse` accepts (hex, CSS named,\n * `hsl()`, `rgb()`, `oklch()`, etc.)\n * @returns HSL-triplet string ready to feed back into a `ColorToken`,\n * or `null` if the input doesn't parse.\n */\nexport function colorInputToTokenValue(input: string): string | null {\n\tconst parsed = parse(input.trim());\n\tif (!parsed) return null;\n\tconst asHsl = hsl(parsed);\n\tif (!asHsl) return null;\n\treturn formatTokenHsl(asHsl);\n}\n\n/**\n * Compute the perceptual luminance of a token value. Useful when a UI\n * needs to pick an overlay tint dynamically (e.g. \"darker shimmer for\n * a light surface, lighter shimmer for a dark surface\").\n *\n * @param value - HSL-triplet token value\n * @returns The perceptual luminance (0 = absolute black, 1 = absolute white)\n */\nexport function tokenLuminance(value: string): number {\n\treturn wcagLuminance(parseTokenHsl(value));\n}\n\n/**\n * Canonical radius presets shared between `@hex-core/cli`'s interactive\n * authoring and `hex-ui-platform`'s Studio sliders. Authors who pick\n * outside the presets enter a custom `rem` string.\n *\n * - `sharp` (`0.25rem`) — Linear-style precision, tight chrome\n * - `balanced` (`0.625rem`) — versatile default, current shadcn-canon\n * - `soft` (`0.875rem`) — friendly / consumer, reads as approachable\n */\nexport const RADIUS_PRESETS = {\n\tsharp: \"0.25rem\",\n\tbalanced: \"0.625rem\",\n\tsoft: \"0.875rem\",\n} as const;\n\nexport type RadiusPreset = keyof typeof RADIUS_PRESETS;\n\n/**\n * Surface and framing lightness bands for the two color modes. Used by\n * both the CLI (`buildTokenSet`) and Studio (its preview pane) to\n * derive secondary / muted / accent / border / input slots that fit\n * the chosen background instead of always landing in the light band.\n *\n * Each mode pins `surface` (the lightness of `secondary` / `muted` /\n * `accent` button fills) and `framing` (the lightness of `border` /\n * `input` lines). Light surfaces want near-white fills with low-contrast\n * lines; dark surfaces want near-black fills with mid-contrast lines.\n */\nexport const COLOR_MODE_BANDS = {\n\tlight: { surface: 0.959, framing: 0.9 },\n\tdark: { surface: 0.159, framing: 0.16 },\n} as const;\n\nexport type ColorMode = keyof typeof COLOR_MODE_BANDS;\n","import type { ColorToken, TokenSet } from \"@hex-core/registry\";\nimport {\n\tCOLOR_MODE_BANDS,\n\ttype ColorMode,\n\tderiveForegroundFor,\n\tderiveSecondaryFromPrimary,\n} from \"./derive.js\";\n\n/**\n * Five-seed input that fully determines a coherent {@link TokenSet}.\n *\n * Mirrors the seed shape the interactive `hex theme init -i` flow asks\n * for, plus the seed shape the brand-derived preset import script\n * (`scripts/import-voltagent.ts`) extracts from a markdown brief. Both\n * paths share this helper so the rendered token sets are identical\n * given identical seeds.\n *\n * @property primary - HSL-triplet (\"<H> <S>% <L>%\"). The brand color.\n * @property foreground - HSL-triplet. Page text default. Drives\n * `muted-foreground`, `border`, and `input` lightness.\n * @property background - HSL-triplet. Page canvas. Mirrored to\n * `card` and `popover`.\n * @property destructive - HSL-triplet. Error / delete CTA color.\n * Pairs with a derived `destructive-foreground`.\n * @property radius - rem string (`\"0.375rem\"`, `\"0.625rem\"`, ...).\n * Single radius preset; consumers can override per-component via\n * the standard `--radius-*` overrides.\n */\nexport interface TokenSetSeeds {\n\tprimary: string;\n\tforeground: string;\n\tbackground: string;\n\tdestructive: string;\n\tradius: string;\n}\n\n/**\n * Build a full 19-required-slot {@link TokenSet} from a small seed\n * bag. Both the CLI authoring flow and the brand-derived preset\n * import script call this helper so output is consistent across\n * authoring surfaces.\n *\n * The mode flag picks the right surface/framing band so derived\n * neutrals (`secondary` / `muted` / `accent` / `border` / `input`)\n * land at light-mode lightness on a light surface and dark-mode\n * lightness on a dark surface.\n *\n * @param seeds - The five seed values; see {@link TokenSetSeeds}\n * @param mode - `\"light\"` or `\"dark\"` — drives band selection\n * @returns A {@link TokenSet} carrying every required color slot + radius\n */\nexport function buildTokenSet(seeds: TokenSetSeeds, mode: ColorMode): TokenSet {\n\tconst { surface, framing } = COLOR_MODE_BANDS[mode];\n\n\tconst primary: ColorToken = { value: seeds.primary, type: \"color\" };\n\tconst primaryForeground = deriveForegroundFor(seeds.primary);\n\tconst foreground: ColorToken = { value: seeds.foreground, type: \"color\" };\n\tconst background: ColorToken = { value: seeds.background, type: \"color\" };\n\tconst destructive: ColorToken = { value: seeds.destructive, type: \"color\" };\n\tconst destructiveForeground = deriveForegroundFor(seeds.destructive);\n\tconst secondary = deriveSecondaryFromPrimary(seeds.primary, { lightness: surface });\n\tconst secondaryForeground = deriveForegroundFor(secondary.value);\n\n\treturn {\n\t\tbackground,\n\t\tforeground,\n\t\tcard: background,\n\t\t\"card-foreground\": foreground,\n\t\tpopover: background,\n\t\t\"popover-foreground\": foreground,\n\t\tprimary,\n\t\t\"primary-foreground\": primaryForeground,\n\t\tsecondary,\n\t\t\"secondary-foreground\": secondaryForeground,\n\t\tmuted: secondary,\n\t\t\"muted-foreground\": {\n\t\t\tvalue: shiftLightnessTo(seeds.foreground, mode === \"light\" ? 0.38 : 0.7),\n\t\t\ttype: \"color\",\n\t\t},\n\t\taccent: secondary,\n\t\t\"accent-foreground\": secondaryForeground,\n\t\tdestructive,\n\t\t\"destructive-foreground\": destructiveForeground,\n\t\tborder: { value: shiftLightnessTo(seeds.foreground, framing), type: \"color\" },\n\t\tinput: { value: shiftLightnessTo(seeds.foreground, framing), type: \"color\" },\n\t\tring: primary,\n\t\tradius: { value: seeds.radius, type: \"radius\" },\n\t};\n}\n\n/**\n * Shift a token's lightness to a target value (0–1) while preserving\n * hue and capping saturation at 8% so derived neutrals read as\n * \"intentional tint\" rather than \"achromatic gray.\" Used internally\n * by `buildTokenSet` for `muted-foreground` / `border` / `input`.\n *\n * @param value - HSL-triplet input\n * @param lightness - Target lightness in `[0, 1]`\n * @returns A new HSL-triplet at the requested lightness, or the input\n * unchanged if it doesn't parse\n */\nfunction shiftLightnessTo(value: string, lightness: number): string {\n\tconst match = /^([\\d.]+)\\s+([\\d.]+)%\\s+([\\d.]+)%$/.exec(value.trim());\n\tif (!match) return value;\n\tconst h = Number(match[1]);\n\tconst s = Math.min(Number(match[2]), 8);\n\tconst l = Math.round(lightness * 1000) / 10;\n\treturn `${h} ${s.toFixed(1).replace(/\\.0$/, \"\")}% ${l}%`;\n}\n","export {\n\tgenerateGlobalsCss,\n\tgenerateThemeCssV4,\n\ttype ScopedRuntimeCssOptions,\n\tthemeToCss,\n\tthemeToFlatJson,\n\tthemeToScopedRuntimeCss,\n\tthemeToTailwindConfig,\n} from \"./transformer.js\";\nexport { defaultTheme } from \"./themes/default.js\";\nexport { midnightTheme } from \"./themes/midnight.js\";\nexport { emberTheme } from \"./themes/ember.js\";\nexport { sharedTokens } from \"./themes/shared.js\";\nexport { defaultSemanticTokens, resolveSemanticToken } from \"./semantic.js\";\nexport {\n\tCOLOR_MODE_BANDS,\n\tcolorInputToTokenValue,\n\tcontrastRatio,\n\tderiveDarkFromLight,\n\tderiveForegroundFor,\n\tderiveSecondaryFromPrimary,\n\tRADIUS_PRESETS,\n\ttokenLuminance,\n} from \"./lib/derive.js\";\nexport { buildTokenSet } from \"./lib/build-token-set.js\";\nexport type { TokenSetSeeds } from \"./lib/build-token-set.js\";\nexport type {\n\tColorMode,\n\tDeriveDarkOptions,\n\tDeriveForegroundOptions,\n\tDeriveSecondaryOptions,\n\tRadiusPreset,\n} from \"./lib/derive.js\";\n\nimport type { Theme } from \"@hex-core/registry\";\nimport { defaultTheme } from \"./themes/default.js\";\nimport { emberTheme } from \"./themes/ember.js\";\nimport { midnightTheme } from \"./themes/midnight.js\";\n\nexport const themes: Record<string, Theme> = {\n\tdefault: defaultTheme,\n\tmidnight: midnightTheme,\n\tember: emberTheme,\n};\n\n/**\n * Retrieve a theme by name.\n * @param name - The theme identifier (e.g. \"default\", \"midnight\", \"ember\")\n * @returns The matching Theme object, or undefined if not found\n */\nexport function getTheme(name: string): Theme | undefined {\n\treturn themes[name];\n}\n\n/**\n * List all available themes with their display metadata.\n * @returns An array of theme summaries containing name, displayName, and description\n */\nexport function listThemes(): Array<{ name: string; displayName: string; description: string }> {\n\treturn Object.values(themes).map((t) => ({\n\t\tname: t.name,\n\t\tdisplayName: t.displayName,\n\t\tdescription: t.description,\n\t}));\n}\n"],"mappings":"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","names":["ref","palette","ref","palette","ref"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hex-core/tokens",
3
- "version": "1.3.7",
3
+ "version": "1.4.1",
4
4
  "description": "Design token engine for Hex Core — HSL tokens + typography scale shared between components and themes.",
5
5
  "keywords": [
6
6
  "hex-core",
@@ -40,13 +40,13 @@
40
40
  },
41
41
  "dependencies": {
42
42
  "culori": "^4.0.2",
43
- "zod": "^4.3.6",
44
- "@hex-core/registry": "^0.6.0"
43
+ "zod": "^4.4.3",
44
+ "@hex-core/registry": "^0.9.0"
45
45
  },
46
46
  "devDependencies": {
47
47
  "@types/culori": "^4.0.1",
48
- "postcss": "^8.5.0",
49
- "tsup": "^8.3.0",
48
+ "postcss": "^8.5.15",
49
+ "tsup": "^8.5.1",
50
50
  "typescript": "^6.0.3"
51
51
  },
52
52
  "scripts": {