@openkeyai/ui 0.1.0 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/tokens.d.cts CHANGED
@@ -1,42 +1,182 @@
1
1
  /**
2
2
  * Design tokens — colors, spacing, typography, radius, motion.
3
3
  *
4
- * Frozen-ish: visual changes that affect layout (header height, spacing
5
- * scale, font sizes) require coordinated checks against deployed tools.
6
- * See ../CLAUDE.md.
4
+ * **v1.0.0** major version: palette swap from cool indigo-violet to
5
+ * warm coral, Material 3 elevation model, light + dark themes,
6
+ * Roboto Flex display font. See README for the migration map and the
7
+ * `hub` repo's `docs/DESIGN.md` for the language behind the choices.
7
8
  *
8
9
  * Two consumption styles:
9
10
  * 1. As CSS custom properties — import `@openkeyai/ui/css` and use
10
11
  * `var(--okai-color-bg)` etc. The `<HubHeader />` component does this.
11
- * 2. As a JS object — `import { tokens } from "@openkeyai/ui/tokens"`
12
- * for programmatic colour pickups (charts, gradients).
12
+ * 2. As a JS object — `import { tokens, darkTokens, lightTokens }`
13
+ * from "@openkeyai/ui/tokens" for programmatic colour pickups
14
+ * (charts, gradients).
13
15
  *
14
16
  * The token names mirror the CSS variable names below the prefix.
15
17
  * Example: `tokens.color.bg` ↔ `--okai-color-bg`.
18
+ *
19
+ * Dark is the default. Light mode is opt-in by the consumer:
20
+ *
21
+ * <html data-theme="light">
22
+ *
23
+ * Switches every `--okai-*` color variable to the light palette.
16
24
  */
17
- declare const tokens: {
25
+ /**
26
+ * Tokens for the **dark** theme (default). For programmatic use; UI
27
+ * components should reference the CSS variables in styles.css which
28
+ * automatically swap to the light palette when `data-theme="light"`.
29
+ */
30
+ declare const darkTokens: {
31
+ /** 4px base. Use multiples of these for layout — keeps the grid honest. */
32
+ readonly space: {
33
+ readonly px: "1px";
34
+ readonly "0_5": "2px";
35
+ readonly "1": "4px";
36
+ readonly "1_5": "6px";
37
+ readonly "2": "8px";
38
+ readonly "3": "12px";
39
+ readonly "4": "16px";
40
+ readonly "5": "20px";
41
+ readonly "6": "24px";
42
+ readonly "8": "32px";
43
+ readonly "10": "40px";
44
+ readonly "12": "48px";
45
+ readonly "16": "64px";
46
+ };
47
+ /**
48
+ * Material 3 shape scale. Generous radii, predictable family. One
49
+ * radius per element — NO mixed-corner shapes.
50
+ */
51
+ readonly radius: {
52
+ readonly xs: "6px";
53
+ readonly sm: "10px";
54
+ readonly md: "14px";
55
+ readonly lg: "20px";
56
+ readonly xl: "28px";
57
+ readonly "2xl": "36px";
58
+ readonly full: "9999px";
59
+ };
60
+ readonly font: {
61
+ /** Geist Sans — opt-in by the consumer's stack. We just suggest it. */
62
+ readonly sans: string;
63
+ /** Geist Mono for code + hashes + token displays. */
64
+ readonly mono: string;
65
+ /**
66
+ * Display — Roboto Flex (Apache 2.0 via Google Fonts). Consumer loads
67
+ * via next/font and exposes the CSS variable `--font-display`. If
68
+ * absent, falls back to the body sans.
69
+ */
70
+ readonly display: "var(--font-display, Geist, ui-sans-serif, system-ui, sans-serif)";
71
+ };
72
+ readonly fontSize: {
73
+ readonly xs: "11px";
74
+ readonly sm: "13px";
75
+ readonly base: "14px";
76
+ readonly md: "16px";
77
+ readonly lg: "18px";
78
+ readonly xl: "22px";
79
+ readonly "2xl": "28px";
80
+ readonly "3xl": "36px";
81
+ readonly "4xl": "48px";
82
+ /** Big display moments (marketing hero). */
83
+ readonly display: "60px";
84
+ };
85
+ readonly lineHeight: {
86
+ /** Display — tight, almost 1:1 to the cap height. */
87
+ readonly display: "1.05";
88
+ /** Headlines. */
89
+ readonly tight: "1.2";
90
+ /** UI. */
91
+ readonly normal: "1.5";
92
+ /** Long-form. */
93
+ readonly relaxed: "1.65";
94
+ };
95
+ /**
96
+ * Shadows — heavier in light (real visible shadow), lighter in dark
97
+ * (surface lift carries hierarchy; shadow is just a hairline tint).
98
+ *
99
+ * Values match the hub's `--next-shadow-*` tokens.
100
+ */
101
+ readonly shadow: {
102
+ /** Dark — cards, hover lift. */
103
+ readonly sm: "0 1px 0 oklch(1 0 0 / 0.04), 0 4px 12px oklch(0 0 0 / 0.20)";
104
+ readonly md: "0 1px 0 oklch(1 0 0 / 0.05), 0 12px 28px oklch(0 0 0 / 0.30)";
105
+ readonly lg: "0 1px 0 oklch(1 0 0 / 0.06), 0 24px 56px oklch(0 0 0 / 0.38)";
106
+ /** Light — real shadow values for the light theme. */
107
+ readonly smLight: "0 1px 2px oklch(0.13 0.008 35 / 0.06), 0 4px 12px oklch(0.13 0.008 35 / 0.06)";
108
+ readonly mdLight: "0 2px 4px oklch(0.13 0.008 35 / 0.08), 0 12px 28px oklch(0.13 0.008 35 / 0.10)";
109
+ readonly lgLight: "0 4px 8px oklch(0.13 0.008 35 / 0.10), 0 24px 56px oklch(0.13 0.008 35 / 0.14)";
110
+ };
111
+ readonly motion: {
112
+ /** Material easing — standard. Most UI transitions. */
113
+ readonly easeStandard: "cubic-bezier(0.2, 0.0, 0.0, 1.0)";
114
+ /** Material easing — emphasized. Bigger surface motions. */
115
+ readonly easeEmphasized: "cubic-bezier(0.05, 0.7, 0.1, 1.0)";
116
+ /** Quick interactions — hover, focus. */
117
+ readonly fast: "160ms";
118
+ /** Standard — dialogs, surface moves. */
119
+ readonly normal: "280ms";
120
+ /** Used for big route / page transitions. */
121
+ readonly slow: "400ms";
122
+ };
123
+ /** Z-index scale. Use these names, never raw numbers. */
124
+ readonly z: {
125
+ readonly base: 0;
126
+ readonly raised: 10;
127
+ readonly sticky: 30;
128
+ /** HubHeader sits here. */
129
+ readonly header: 40;
130
+ readonly overlay: 50;
131
+ readonly modal: 60;
132
+ readonly toast: 70;
133
+ };
134
+ /** Component-specific dimensions. */
135
+ readonly size: {
136
+ /** HubHeader height. Tools should leave this much top padding. */
137
+ readonly headerHeight: "56px";
138
+ };
18
139
  readonly color: {
19
- /** App-wide canvas. Dark navy with a touch of indigo. */
20
- readonly bg: "#0a0c1a";
140
+ /** App-wide canvas. Warm dark slate (oklch hue 35). */
141
+ readonly bg: "oklch(0.13 0.008 35)";
21
142
  /** Surface a half-step lighter than `bg`. Card / panel default. */
22
- readonly surface: "#11142a";
143
+ readonly surface: "oklch(0.17 0.010 35)";
23
144
  /** Surface above `surface` — popovers, hover states. */
24
- readonly surfaceRaised: "#181d3a";
145
+ readonly surface1: "oklch(0.17 0.010 35)";
146
+ readonly surface2: "oklch(0.21 0.012 35)";
147
+ readonly surface3: "oklch(0.25 0.014 35)";
148
+ readonly surface4: "oklch(0.29 0.016 35)";
149
+ readonly surfaceRaised: "oklch(0.21 0.012 35)";
25
150
  /** Primary readable text. */
26
- readonly foreground: "#e6e8f5";
151
+ readonly foreground: "oklch(0.96 0.005 35)";
27
152
  /** Lower-emphasis text. Captions, metadata. */
28
- readonly foregroundMuted: "#9097b8";
153
+ readonly foregroundMuted: "oklch(0.74 0.008 35)";
154
+ /** Even lower emphasis — placeholder text, ghost labels. */
155
+ readonly foregroundSubtle: "oklch(0.58 0.010 35)";
29
156
  /** Subtle border default for cards / dividers. */
30
- readonly border: "rgba(150, 160, 220, 0.12)";
31
- /** Indigo-violet primary, softened so it doesn't blow out the bg. */
32
- readonly accent: "#7c6cf5";
157
+ readonly border: "oklch(1 0 0 / 0.08)";
158
+ /** Stronger border for inputs + outlined buttons. */
159
+ readonly borderStrong: "oklch(1 0 0 / 0.14)";
160
+ /** Brand — warm coral (Material 3 key color, Claude warmth). */
161
+ readonly accent: "oklch(0.76 0.17 35)";
33
162
  /** Brighter accent for focus rings + active links. */
34
- readonly accentBright: "#9b8af9";
35
- /** Destructive action accent. */
36
- readonly destructive: "#ef4459";
37
- /** Success / positive accent. */
38
- readonly success: "#34d399";
163
+ readonly accentBright: "oklch(0.82 0.17 35)";
164
+ /** Tint that sits behind brand-on-brand content. */
165
+ readonly accentContainer: "oklch(0.30 0.13 28 / 0.25)";
166
+ /** Text/icon color on top of accentContainer. */
167
+ readonly onAccentContainer: "oklch(0.88 0.085 35)";
168
+ /** Text/icon color on top of solid accent. */
169
+ readonly onAccent: "oklch(0.13 0.008 35)";
170
+ /** Destructive action accent — warmer than the old red. */
171
+ readonly destructive: "oklch(0.74 0.18 28)";
172
+ /** Success / positive accent — sage. */
173
+ readonly success: "oklch(0.84 0.08 150)";
174
+ /** Warning accent — amber. */
175
+ readonly warning: "oklch(0.88 0.12 80)";
39
176
  };
177
+ };
178
+ /** Tokens for the **light** theme. */
179
+ declare const lightTokens: {
40
180
  /** 4px base. Use multiples of these for layout — keeps the grid honest. */
41
181
  readonly space: {
42
182
  readonly px: "1px";
@@ -53,13 +193,17 @@ declare const tokens: {
53
193
  readonly "12": "48px";
54
194
  readonly "16": "64px";
55
195
  };
196
+ /**
197
+ * Material 3 shape scale. Generous radii, predictable family. One
198
+ * radius per element — NO mixed-corner shapes.
199
+ */
56
200
  readonly radius: {
57
- readonly sm: "4px";
58
- readonly md: "8px";
59
- readonly lg: "12px";
60
- /** Default for cards and surfaces. */
61
- readonly xl: "16px";
62
- readonly "2xl": "20px";
201
+ readonly xs: "6px";
202
+ readonly sm: "10px";
203
+ readonly md: "14px";
204
+ readonly lg: "20px";
205
+ readonly xl: "28px";
206
+ readonly "2xl": "36px";
63
207
  readonly full: "9999px";
64
208
  };
65
209
  readonly font: {
@@ -67,6 +211,12 @@ declare const tokens: {
67
211
  readonly sans: string;
68
212
  /** Geist Mono for code + hashes + token displays. */
69
213
  readonly mono: string;
214
+ /**
215
+ * Display — Roboto Flex (Apache 2.0 via Google Fonts). Consumer loads
216
+ * via next/font and exposes the CSS variable `--font-display`. If
217
+ * absent, falls back to the body sans.
218
+ */
219
+ readonly display: "var(--font-display, Geist, ui-sans-serif, system-ui, sans-serif)";
70
220
  };
71
221
  readonly fontSize: {
72
222
  readonly xs: "11px";
@@ -75,29 +225,49 @@ declare const tokens: {
75
225
  readonly md: "16px";
76
226
  readonly lg: "18px";
77
227
  readonly xl: "22px";
228
+ readonly "2xl": "28px";
229
+ readonly "3xl": "36px";
230
+ readonly "4xl": "48px";
231
+ /** Big display moments (marketing hero). */
232
+ readonly display: "60px";
78
233
  };
79
234
  readonly lineHeight: {
235
+ /** Display — tight, almost 1:1 to the cap height. */
236
+ readonly display: "1.05";
237
+ /** Headlines. */
80
238
  readonly tight: "1.2";
239
+ /** UI. */
81
240
  readonly normal: "1.5";
241
+ /** Long-form. */
82
242
  readonly relaxed: "1.65";
83
243
  };
244
+ /**
245
+ * Shadows — heavier in light (real visible shadow), lighter in dark
246
+ * (surface lift carries hierarchy; shadow is just a hairline tint).
247
+ *
248
+ * Values match the hub's `--next-shadow-*` tokens.
249
+ */
84
250
  readonly shadow: {
85
- /** Subtle pop on raised cards. */
86
- readonly sm: "0 1px 2px rgba(0, 0, 0, 0.25)";
87
- /** Standard floating-pill / dropdown lift. */
88
- readonly md: "0 6px 24px -8px rgba(0, 0, 0, 0.5), 0 2px 6px rgba(0, 0, 0, 0.3)";
89
- /** Modal-style. */
90
- readonly lg: "0 20px 60px -20px rgba(0, 0, 0, 0.6), 0 8px 24px rgba(0, 0, 0, 0.4)";
251
+ /** Dark cards, hover lift. */
252
+ readonly sm: "0 1px 0 oklch(1 0 0 / 0.04), 0 4px 12px oklch(0 0 0 / 0.20)";
253
+ readonly md: "0 1px 0 oklch(1 0 0 / 0.05), 0 12px 28px oklch(0 0 0 / 0.30)";
254
+ readonly lg: "0 1px 0 oklch(1 0 0 / 0.06), 0 24px 56px oklch(0 0 0 / 0.38)";
255
+ /** Light — real shadow values for the light theme. */
256
+ readonly smLight: "0 1px 2px oklch(0.13 0.008 35 / 0.06), 0 4px 12px oklch(0.13 0.008 35 / 0.06)";
257
+ readonly mdLight: "0 2px 4px oklch(0.13 0.008 35 / 0.08), 0 12px 28px oklch(0.13 0.008 35 / 0.10)";
258
+ readonly lgLight: "0 4px 8px oklch(0.13 0.008 35 / 0.10), 0 24px 56px oklch(0.13 0.008 35 / 0.14)";
91
259
  };
92
260
  readonly motion: {
93
- /** Default easing — feels good for most UI. */
94
- readonly ease: "cubic-bezier(0.4, 0.0, 0.2, 1)";
261
+ /** Material easing — standard. Most UI transitions. */
262
+ readonly easeStandard: "cubic-bezier(0.2, 0.0, 0.0, 1.0)";
263
+ /** Material easing — emphasized. Bigger surface motions. */
264
+ readonly easeEmphasized: "cubic-bezier(0.05, 0.7, 0.1, 1.0)";
95
265
  /** Quick interactions — hover, focus. */
96
- readonly fast: "120ms";
97
- /** Standard — most state transitions. */
98
- readonly normal: "180ms";
99
- /** Used for entrance / exit animations. */
100
- readonly slow: "260ms";
266
+ readonly fast: "160ms";
267
+ /** Standard — dialogs, surface moves. */
268
+ readonly normal: "280ms";
269
+ /** Used for big route / page transitions. */
270
+ readonly slow: "400ms";
101
271
  };
102
272
  /** Z-index scale. Use these names, never raw numbers. */
103
273
  readonly z: {
@@ -115,7 +285,184 @@ declare const tokens: {
115
285
  /** HubHeader height. Tools should leave this much top padding. */
116
286
  readonly headerHeight: "56px";
117
287
  };
288
+ readonly color: {
289
+ readonly bg: "oklch(0.985 0.005 35)";
290
+ readonly surface: "oklch(1 0 0)";
291
+ readonly surface1: "oklch(1 0 0)";
292
+ readonly surface2: "oklch(0.96 0.006 35)";
293
+ readonly surface3: "oklch(0.93 0.008 35)";
294
+ readonly surface4: "oklch(0.90 0.010 35)";
295
+ readonly surfaceRaised: "oklch(0.96 0.006 35)";
296
+ readonly foreground: "oklch(0.18 0.012 35)";
297
+ readonly foregroundMuted: "oklch(0.42 0.012 50)";
298
+ readonly foregroundSubtle: "oklch(0.58 0.010 50)";
299
+ readonly border: "oklch(0 0 0 / 0.08)";
300
+ readonly borderStrong: "oklch(0 0 0 / 0.16)";
301
+ readonly accent: "oklch(0.64 0.21 30)";
302
+ readonly accentBright: "oklch(0.56 0.20 28)";
303
+ readonly accentContainer: "oklch(0.93 0.045 35)";
304
+ readonly onAccentContainer: "oklch(0.30 0.13 28)";
305
+ readonly onAccent: "oklch(1 0 0)";
306
+ readonly destructive: "oklch(0.55 0.21 28)";
307
+ readonly success: "oklch(0.52 0.10 150)";
308
+ readonly warning: "oklch(0.60 0.15 70)";
309
+ };
310
+ };
311
+ /**
312
+ * Default `tokens` export — dark palette. Kept for backwards
313
+ * compatibility with v0.x callers that did `tokens.color.bg`. The shape
314
+ * is unchanged; only color values have shifted from cool to warm.
315
+ */
316
+ declare const tokens: {
317
+ /** 4px base. Use multiples of these for layout — keeps the grid honest. */
318
+ readonly space: {
319
+ readonly px: "1px";
320
+ readonly "0_5": "2px";
321
+ readonly "1": "4px";
322
+ readonly "1_5": "6px";
323
+ readonly "2": "8px";
324
+ readonly "3": "12px";
325
+ readonly "4": "16px";
326
+ readonly "5": "20px";
327
+ readonly "6": "24px";
328
+ readonly "8": "32px";
329
+ readonly "10": "40px";
330
+ readonly "12": "48px";
331
+ readonly "16": "64px";
332
+ };
333
+ /**
334
+ * Material 3 shape scale. Generous radii, predictable family. One
335
+ * radius per element — NO mixed-corner shapes.
336
+ */
337
+ readonly radius: {
338
+ readonly xs: "6px";
339
+ readonly sm: "10px";
340
+ readonly md: "14px";
341
+ readonly lg: "20px";
342
+ readonly xl: "28px";
343
+ readonly "2xl": "36px";
344
+ readonly full: "9999px";
345
+ };
346
+ readonly font: {
347
+ /** Geist Sans — opt-in by the consumer's stack. We just suggest it. */
348
+ readonly sans: string;
349
+ /** Geist Mono for code + hashes + token displays. */
350
+ readonly mono: string;
351
+ /**
352
+ * Display — Roboto Flex (Apache 2.0 via Google Fonts). Consumer loads
353
+ * via next/font and exposes the CSS variable `--font-display`. If
354
+ * absent, falls back to the body sans.
355
+ */
356
+ readonly display: "var(--font-display, Geist, ui-sans-serif, system-ui, sans-serif)";
357
+ };
358
+ readonly fontSize: {
359
+ readonly xs: "11px";
360
+ readonly sm: "13px";
361
+ readonly base: "14px";
362
+ readonly md: "16px";
363
+ readonly lg: "18px";
364
+ readonly xl: "22px";
365
+ readonly "2xl": "28px";
366
+ readonly "3xl": "36px";
367
+ readonly "4xl": "48px";
368
+ /** Big display moments (marketing hero). */
369
+ readonly display: "60px";
370
+ };
371
+ readonly lineHeight: {
372
+ /** Display — tight, almost 1:1 to the cap height. */
373
+ readonly display: "1.05";
374
+ /** Headlines. */
375
+ readonly tight: "1.2";
376
+ /** UI. */
377
+ readonly normal: "1.5";
378
+ /** Long-form. */
379
+ readonly relaxed: "1.65";
380
+ };
381
+ /**
382
+ * Shadows — heavier in light (real visible shadow), lighter in dark
383
+ * (surface lift carries hierarchy; shadow is just a hairline tint).
384
+ *
385
+ * Values match the hub's `--next-shadow-*` tokens.
386
+ */
387
+ readonly shadow: {
388
+ /** Dark — cards, hover lift. */
389
+ readonly sm: "0 1px 0 oklch(1 0 0 / 0.04), 0 4px 12px oklch(0 0 0 / 0.20)";
390
+ readonly md: "0 1px 0 oklch(1 0 0 / 0.05), 0 12px 28px oklch(0 0 0 / 0.30)";
391
+ readonly lg: "0 1px 0 oklch(1 0 0 / 0.06), 0 24px 56px oklch(0 0 0 / 0.38)";
392
+ /** Light — real shadow values for the light theme. */
393
+ readonly smLight: "0 1px 2px oklch(0.13 0.008 35 / 0.06), 0 4px 12px oklch(0.13 0.008 35 / 0.06)";
394
+ readonly mdLight: "0 2px 4px oklch(0.13 0.008 35 / 0.08), 0 12px 28px oklch(0.13 0.008 35 / 0.10)";
395
+ readonly lgLight: "0 4px 8px oklch(0.13 0.008 35 / 0.10), 0 24px 56px oklch(0.13 0.008 35 / 0.14)";
396
+ };
397
+ readonly motion: {
398
+ /** Material easing — standard. Most UI transitions. */
399
+ readonly easeStandard: "cubic-bezier(0.2, 0.0, 0.0, 1.0)";
400
+ /** Material easing — emphasized. Bigger surface motions. */
401
+ readonly easeEmphasized: "cubic-bezier(0.05, 0.7, 0.1, 1.0)";
402
+ /** Quick interactions — hover, focus. */
403
+ readonly fast: "160ms";
404
+ /** Standard — dialogs, surface moves. */
405
+ readonly normal: "280ms";
406
+ /** Used for big route / page transitions. */
407
+ readonly slow: "400ms";
408
+ };
409
+ /** Z-index scale. Use these names, never raw numbers. */
410
+ readonly z: {
411
+ readonly base: 0;
412
+ readonly raised: 10;
413
+ readonly sticky: 30;
414
+ /** HubHeader sits here. */
415
+ readonly header: 40;
416
+ readonly overlay: 50;
417
+ readonly modal: 60;
418
+ readonly toast: 70;
419
+ };
420
+ /** Component-specific dimensions. */
421
+ readonly size: {
422
+ /** HubHeader height. Tools should leave this much top padding. */
423
+ readonly headerHeight: "56px";
424
+ };
425
+ readonly color: {
426
+ /** App-wide canvas. Warm dark slate (oklch hue 35). */
427
+ readonly bg: "oklch(0.13 0.008 35)";
428
+ /** Surface a half-step lighter than `bg`. Card / panel default. */
429
+ readonly surface: "oklch(0.17 0.010 35)";
430
+ /** Surface above `surface` — popovers, hover states. */
431
+ readonly surface1: "oklch(0.17 0.010 35)";
432
+ readonly surface2: "oklch(0.21 0.012 35)";
433
+ readonly surface3: "oklch(0.25 0.014 35)";
434
+ readonly surface4: "oklch(0.29 0.016 35)";
435
+ readonly surfaceRaised: "oklch(0.21 0.012 35)";
436
+ /** Primary readable text. */
437
+ readonly foreground: "oklch(0.96 0.005 35)";
438
+ /** Lower-emphasis text. Captions, metadata. */
439
+ readonly foregroundMuted: "oklch(0.74 0.008 35)";
440
+ /** Even lower emphasis — placeholder text, ghost labels. */
441
+ readonly foregroundSubtle: "oklch(0.58 0.010 35)";
442
+ /** Subtle border default for cards / dividers. */
443
+ readonly border: "oklch(1 0 0 / 0.08)";
444
+ /** Stronger border for inputs + outlined buttons. */
445
+ readonly borderStrong: "oklch(1 0 0 / 0.14)";
446
+ /** Brand — warm coral (Material 3 key color, Claude warmth). */
447
+ readonly accent: "oklch(0.76 0.17 35)";
448
+ /** Brighter accent for focus rings + active links. */
449
+ readonly accentBright: "oklch(0.82 0.17 35)";
450
+ /** Tint that sits behind brand-on-brand content. */
451
+ readonly accentContainer: "oklch(0.30 0.13 28 / 0.25)";
452
+ /** Text/icon color on top of accentContainer. */
453
+ readonly onAccentContainer: "oklch(0.88 0.085 35)";
454
+ /** Text/icon color on top of solid accent. */
455
+ readonly onAccent: "oklch(0.13 0.008 35)";
456
+ /** Destructive action accent — warmer than the old red. */
457
+ readonly destructive: "oklch(0.74 0.18 28)";
458
+ /** Success / positive accent — sage. */
459
+ readonly success: "oklch(0.84 0.08 150)";
460
+ /** Warning accent — amber. */
461
+ readonly warning: "oklch(0.88 0.12 80)";
462
+ };
118
463
  };
119
464
  type DesignTokens = typeof tokens;
465
+ /** Names for theming. Use to coerce stringly-typed data into the union. */
466
+ type ThemeName = "dark" | "light";
120
467
 
121
- export { type DesignTokens, tokens };
468
+ export { type DesignTokens, type ThemeName, darkTokens, lightTokens, tokens };