@tenphi/glaze 0.0.0-snapshot.f3bb46b → 0.0.0-snapshot.fdc17e3

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.cts CHANGED
@@ -1,48 +1,93 @@
1
1
  //#region src/contrast-solver.d.ts
2
- /**
3
- * OKHSL Contrast Solver
4
- *
5
- * Finds the closest OKHSL lightness that satisfies a WCAG 2 contrast target
6
- * against a base color. Used by glaze when resolving dependent colors
7
- * with `contrast`.
8
- */
9
2
  type LinearRgb = [number, number, number];
10
3
  type ContrastPreset = 'AA' | 'AAA' | 'AA-large' | 'AAA-large';
11
4
  type MinContrast$1 = number | ContrastPreset;
12
- interface FindLightnessForContrastOptions {
5
+ /**
6
+ * Named APCA Lc floor presets (APCA Bronze Simple Mode conformance levels),
7
+ * independent of role. Use them anywhere an APCA target is accepted.
8
+ *
9
+ * | Preset | Lc | Use case |
10
+ * | ------------- | --- | ---------------------------------------------------- |
11
+ * | `'preferred'` | 90 | Preferred body / column text |
12
+ * | `'body'` | 75 | Minimum body / column text |
13
+ * | `'content'` | 60 | Readable non-body content (~WCAG AA 4.5:1) |
14
+ * | `'large'` | 45 | Large/bold headlines; fine icons/outlines (~3:1) |
15
+ * | `'non-text'` | 30 | Solid icons/controls; placeholder/disabled text |
16
+ * | `'min'` | 15 | Dividers/decorative; APCA "point of invisibility" |
17
+ */
18
+ type ApcaPreset = 'preferred' | 'body' | 'content' | 'large' | 'non-text' | 'min';
19
+ /**
20
+ * Resolve an APCA target — a raw Lc number (kept as-is) or an `ApcaPreset`
21
+ * keyword mapped to its Lc value. The magnitude is forced non-negative.
22
+ */
23
+ declare function resolveApcaTarget(value: number | ApcaPreset): number;
24
+ /** Metric + numeric target after resolving a `ContrastSpec` for a mode. */
25
+ interface ResolvedContrast {
26
+ metric: 'wcag' | 'apca';
27
+ /** WCAG ratio (>= 1) or APCA Lc magnitude (0–106). */
28
+ target: number;
29
+ /**
30
+ * APCA argument order: which side the resolved (candidate) color plays
31
+ * against the base. `'fg'` (default) → `apcaContrast(yCandidate, yBase)`;
32
+ * `'bg'` → `apcaContrast(yBase, yCandidate)`. Always `'fg'` for WCAG
33
+ * (symmetric, ignored).
34
+ */
35
+ polarity?: 'fg' | 'bg';
36
+ }
37
+ declare function resolveMinContrast(value: MinContrast$1): number;
38
+ /**
39
+ * Resolve a `ContrastSpec` (already selected from any outer HC pair) for a
40
+ * given mode into `{ metric, target }`. Handles the inner metric HC pair and
41
+ * preset resolution. `polarity` is passed through to the result for the APCA
42
+ * branch (it controls argument order in the solver); WCAG ignores it.
43
+ */
44
+ declare function resolveContrastForMode(spec: ContrastSpec, isHighContrast: boolean, polarity?: 'fg' | 'bg'): ResolvedContrast;
45
+ /**
46
+ * APCA lightness contrast (Lc), signed: positive for dark text on light bg,
47
+ * negative for light text on dark bg. Inputs are screen luminances (0–1).
48
+ */
49
+ declare function apcaContrast(yText: number, yBg: number): number;
50
+ interface FindToneForContrastOptions {
13
51
  /** Hue of the candidate color (0–360). */
14
52
  hue: number;
15
53
  /** Saturation of the candidate color (0–1). */
16
54
  saturation: number;
17
- /** Preferred lightness of the candidate (0–1). */
18
- preferredLightness: number;
19
- /** Base/reference color as linear sRGB (channels may be outside 0–1 before clamp). */
20
- baseLinearRgb: [number, number, number];
21
- /** WCAG contrast ratio target floor. */
22
- contrast: MinContrast$1;
23
- /** Search bounds for lightness. Default: [0, 1]. */
24
- lightnessRange?: [number, number];
55
+ /** Preferred tone of the candidate (0–1). */
56
+ preferredTone: number;
57
+ /** Base/reference color as linear sRGB. */
58
+ baseLinearRgb: LinearRgb;
59
+ /** Resolved contrast floor (metric + target). */
60
+ contrast: ResolvedContrast;
61
+ /** Search bounds for tone. Default: [0, 1]. */
62
+ toneRange?: [number, number];
25
63
  /** Convergence threshold. Default: 1e-4. */
26
64
  epsilon?: number;
27
- /** Maximum binary-search iterations per branch. Default: 14. */
65
+ /** Maximum binary-search iterations per branch. Default: 18. */
28
66
  maxIterations?: number;
67
+ /** Preferred search direction before auto-flip is considered. */
68
+ initialDirection?: 'lighter' | 'darker';
69
+ /** Auto-flip tone direction when contrast can't be met. Default: false. */
70
+ flip?: boolean;
71
+ /** Use the hue-independent "safe" chroma boundary. Default: false. */
72
+ pastel?: boolean;
29
73
  }
30
- interface FindLightnessForContrastResult {
31
- /** Chosen lightness in 0–1. */
32
- lightness: number;
33
- /** Achieved WCAG contrast ratio. */
74
+ interface FindToneForContrastResult {
75
+ /** Chosen tone in 0–1. */
76
+ tone: number;
77
+ /** Achieved score (WCAG ratio or APCA Lc magnitude). */
34
78
  contrast: number;
35
79
  /** Whether the target was reached. */
36
80
  met: boolean;
37
81
  /** Which branch was selected. */
38
82
  branch: 'lighter' | 'darker' | 'preferred';
83
+ /** Whether the result auto-flipped to the opposite direction. */
84
+ flipped?: boolean;
39
85
  }
40
- declare function resolveMinContrast(value: MinContrast$1): number;
41
86
  /**
42
- * Find the OKHSL lightness that satisfies a WCAG 2 contrast target
43
- * against a base color, staying as close to `preferredLightness` as possible.
87
+ * Find the tone that satisfies a contrast floor against a base color,
88
+ * staying as close to `preferredTone` as possible.
44
89
  */
45
- declare function findLightnessForContrast(options: FindLightnessForContrastOptions): FindLightnessForContrastResult;
90
+ declare function findToneForContrast(options: FindToneForContrastOptions): FindToneForContrastResult;
46
91
  interface FindValueForMixContrastOptions {
47
92
  /** Preferred mix parameter (0–1). */
48
93
  preferredValue: number;
@@ -50,42 +95,84 @@ interface FindValueForMixContrastOptions {
50
95
  baseLinearRgb: LinearRgb;
51
96
  /** Target color as linear sRGB. */
52
97
  targetLinearRgb: LinearRgb;
53
- /** WCAG contrast target. */
54
- contrast: MinContrast$1;
55
- /**
56
- * Compute the luminance of the mixed color at parameter t.
57
- * For opaque: luminance of OKHSL-interpolated color.
58
- * For transparent: luminance of alpha-composited color over base.
59
- */
98
+ /** Resolved contrast floor (metric + target). */
99
+ contrast: ResolvedContrast;
100
+ /** Compute the luminance of the mixed color at parameter t. */
60
101
  luminanceAtValue: (t: number) => number;
61
102
  /** Convergence threshold. Default: 1e-4. */
62
103
  epsilon?: number;
63
104
  /** Maximum binary-search iterations per branch. Default: 20. */
64
105
  maxIterations?: number;
106
+ /** Auto-flip mix direction when contrast can't be met. Default: false. */
107
+ flip?: boolean;
65
108
  }
66
109
  interface FindValueForMixContrastResult {
67
- /** Chosen mix parameter (0–1). */
68
110
  value: number;
69
- /** Achieved WCAG contrast ratio. */
70
111
  contrast: number;
71
- /** Whether the target was reached. */
72
112
  met: boolean;
113
+ flipped?: boolean;
73
114
  }
74
115
  /**
75
- * Find the mix parameter (ratio or opacity) that satisfies a WCAG 2 contrast
76
- * target against a base color, staying as close to `preferredValue` as possible.
116
+ * Find the mix parameter (ratio or opacity) that satisfies a contrast floor
117
+ * against a base color, staying as close to `preferredValue` as possible.
77
118
  */
78
119
  declare function findValueForMixContrast(options: FindValueForMixContrastOptions): FindValueForMixContrastResult;
79
120
  //#endregion
80
121
  //#region src/types.d.ts
81
122
  /** A value or [normal, high-contrast] pair. */
82
123
  type HCPair<T> = T | [T, T];
124
+ /** Bare WCAG contrast target: a ratio number or a named preset. */
83
125
  type MinContrast = number | ContrastPreset;
126
+ /**
127
+ * A contrast floor with a pluggable metric.
128
+ *
129
+ * - `number` / `ContrastPreset`: a WCAG ratio (bare form).
130
+ * - `{ wcag }`: WCAG ratio or preset, optionally an HC pair.
131
+ * - `{ apca }`: APCA Lc target (absolute value or preset), optionally an HC pair.
132
+ *
133
+ * The `[normal, highContrast]` pair may live at the outer level
134
+ * (`[4.5, 7]`, `[{ wcag: 4.5 }, { wcag: 7 }]`) or inside the metric
135
+ * (`{ wcag: [4.5, 7] }`, `{ apca: [45, 60] }`, `{ apca: ['content', 'body'] }`).
136
+ */
137
+ type ContrastSpec = number | ContrastPreset | {
138
+ wcag: HCPair<number | ContrastPreset>;
139
+ } | {
140
+ apca: HCPair<number | ApcaPreset>;
141
+ };
142
+ /**
143
+ * The semantic role a color plays against its base, used to fix APCA contrast
144
+ * polarity (which side is the foreground vs the background). WCAG is
145
+ * symmetric, so role never changes WCAG results.
146
+ */
147
+ type Role = 'text' | 'surface' | 'border';
148
+ /**
149
+ * Any string accepted as a `role`. Canonical values plus aliases normalized by
150
+ * `normalizeRole` (see `roles.ts`): `surface` (bg/background/fill/canvas/
151
+ * paper/layer), `text` (fg/foreground/content/ink/label/stroke), `border`
152
+ * (divider/outline/separator/hairline/rule).
153
+ */
154
+ type RoleInput = Role | 'bg' | 'background' | 'fill' | 'canvas' | 'paper' | 'layer' | 'fg' | 'foreground' | 'content' | 'ink' | 'label' | 'stroke' | 'divider' | 'outline' | 'separator' | 'hairline' | 'rule';
84
155
  type AdaptationMode = 'auto' | 'fixed' | 'static';
85
156
  /** A signed relative offset string, e.g. '+20' or '-15.5'. */
86
157
  type RelativeValue = `+${number}` | `-${number}`;
158
+ /**
159
+ * Force a color to a tone extreme:
160
+ * - `'max'`: the highest tone in the active scheme range/window.
161
+ * - `'min'`: the lowest tone.
162
+ *
163
+ * Under `mode: 'auto'` the extreme inverts in the dark scheme (so `'max'`
164
+ * tracks the inversion and becomes the darkest tone). No `base` required.
165
+ */
166
+ type ExtremeValue = 'max' | 'min';
167
+ /**
168
+ * A tone value as authored on a color.
169
+ * - Number: absolute tone (0–100).
170
+ * - `'+N'` / `'-N'`: relative to the base's tone (requires `base`).
171
+ * - `'max'` / `'min'`: forced to the scheme's tone extreme (no base needed).
172
+ */
173
+ type ToneValue = number | RelativeValue | ExtremeValue;
87
174
  /** Color format for output. */
88
- type GlazeColorFormat = 'okhsl' | 'rgb' | 'hsl' | 'oklch';
175
+ type GlazeColorFormat = 'okhsl' | 'okhst' | 'rgb' | 'hsl' | 'oklch';
89
176
  /**
90
177
  * Controls which scheme variants are generated in the export.
91
178
  * Light is always included (it's the default).
@@ -104,13 +191,35 @@ interface OkhslColor {
104
191
  s: number;
105
192
  l: number;
106
193
  }
194
+ /**
195
+ * Direct OKHST color input — OKHSL with the lightness axis replaced by the
196
+ * contrast-uniform tone axis. `h`: 0–360, `s`: 0–1, `t`: 0–1 (tone).
197
+ */
198
+ interface OkhstColor {
199
+ h: number;
200
+ s: number;
201
+ t: number;
202
+ }
203
+ /** sRGB components in 0–255 (value-shorthand object form). */
204
+ interface RgbColor {
205
+ r: number;
206
+ g: number;
207
+ b: number;
208
+ }
209
+ /** OKLCh components matching CSS `oklch(L C H)` (L/C: 0–1, H: degrees). */
210
+ interface OklchColor {
211
+ l: number;
212
+ c: number;
213
+ h: number;
214
+ }
107
215
  interface RegularColorDef {
108
216
  /**
109
- * Lightness value (0–100).
110
- * - Number: absolute lightness.
111
- * - String ('+N' / '-N'): relative to base color's lightness (requires `base`).
217
+ * Tone value (0–100, contrast-uniform — see `docs/okhst.md`).
218
+ * - Number: absolute tone.
219
+ * - String ('+N' / '-N'): relative to base color's tone (requires `base`).
220
+ * - `'max'` / `'min'`: force to the scheme's tone extreme (no base needed).
112
221
  */
113
- lightness?: HCPair<number | RelativeValue>;
222
+ tone?: HCPair<ToneValue>;
114
223
  /** Saturation factor applied to the seed saturation (0–1, default: 1). */
115
224
  saturation?: number;
116
225
  /**
@@ -121,18 +230,55 @@ interface RegularColorDef {
121
230
  hue?: number | RelativeValue;
122
231
  /** Name of another color in the same theme (dependent color). */
123
232
  base?: string;
124
- /** WCAG contrast ratio floor against the base color. */
125
- contrast?: HCPair<MinContrast>;
233
+ /**
234
+ * Contrast floor against the base color. A bare number/preset is WCAG;
235
+ * use `{ wcag }` / `{ apca }` to pick the metric. Accepts an HC pair.
236
+ */
237
+ contrast?: HCPair<ContrastSpec>;
126
238
  /** Adaptation mode. Default: 'auto'. */
127
239
  mode?: AdaptationMode;
240
+ /**
241
+ * Whether to flip out-of-bounds results to the opposite side instead of
242
+ * clamping to the extreme. Affects both:
243
+ * - relative `tone`: when `base ± delta` exceeds `[0, 100]`, mirror the
244
+ * delta to the other side of the base.
245
+ * - `contrast`: when the requested direction can't meet the floor, try the
246
+ * opposite side (same as the global `autoFlip`).
247
+ *
248
+ * Defaults to the global `autoFlip` config (default `true`). Set `false`
249
+ * to clamp instead.
250
+ */
251
+ flip?: boolean;
128
252
  /**
129
253
  * Fixed opacity (0–1).
130
254
  * Output includes alpha in the CSS value.
131
255
  * Does not affect contrast resolution — a semi-transparent color
132
- * has no fixed perceived lightness, so `contrast` and `opacity`
256
+ * has no fixed perceived tone, so `contrast` and `opacity`
133
257
  * should not be combined (a console.warn is emitted).
134
258
  */
135
259
  opacity?: number;
260
+ /**
261
+ * Per-color override for the hue-independent "safe" chroma limit used in
262
+ * OKHSL↔sRGB conversions (luminance, contrast solving, output formatting).
263
+ * Falls through to the global / per-theme `pastel` config when omitted.
264
+ * @see GlazeConfig.pastel
265
+ */
266
+ pastel?: boolean;
267
+ /**
268
+ * Semantic role against `base`: how this color is used. Fixes APCA contrast
269
+ * polarity (the argument order in `apcaContrast`). WCAG is symmetric so it
270
+ * never affects WCAG results.
271
+ *
272
+ * Resolution: explicit `role` wins; else inferred from the color name when
273
+ * `inferRole` is enabled (default); else the opposite of the base's role;
274
+ * else defaults to `'text'` (foreground).
275
+ */
276
+ role?: RoleInput;
277
+ /**
278
+ * Whether this color is inherited by child themes created via `extend()`.
279
+ * Default: true. Set to false to make this color local to the current theme.
280
+ */
281
+ inherit?: boolean;
136
282
  }
137
283
  /** Shadow tuning knobs. All values use the 0–1 scale (OKHSL). */
138
284
  interface ShadowTuning {
@@ -177,6 +323,18 @@ interface ShadowColorDef {
177
323
  intensity: HCPair<number>;
178
324
  /** Override default tuning. Merged field-by-field with global `shadowTuning`. */
179
325
  tuning?: ShadowTuning;
326
+ /**
327
+ * Per-color override for the hue-independent "safe" chroma limit used in
328
+ * OKHSL↔sRGB conversions (luminance, contrast solving, output formatting).
329
+ * Falls through to the global / per-theme `pastel` config when omitted.
330
+ * @see GlazeConfig.pastel
331
+ */
332
+ pastel?: boolean;
333
+ /**
334
+ * Whether this color is inherited by child themes created via `extend()`.
335
+ * Default: true. Set to false to make this color local to the current theme.
336
+ */
337
+ inherit?: boolean;
180
338
  }
181
339
  interface MixColorDef {
182
340
  type: 'mix';
@@ -205,25 +363,56 @@ interface MixColorDef {
205
363
  */
206
364
  space?: 'okhsl' | 'srgb';
207
365
  /**
208
- * Minimum WCAG contrast between the base and the resulting color.
366
+ * Minimum contrast between the base and the resulting color.
209
367
  * In 'opaque' mode, adjusts the mix ratio to meet contrast.
210
368
  * In 'transparent' mode, adjusts opacity to meet contrast against the composite.
211
- * Supports [normal, highContrast] pair.
369
+ * A bare number/preset is WCAG; use `{ wcag }` / `{ apca }` to pick the
370
+ * metric. Supports [normal, highContrast] pair.
212
371
  */
213
- contrast?: HCPair<MinContrast>;
372
+ contrast?: HCPair<ContrastSpec>;
373
+ /**
374
+ * Per-color override for the hue-independent "safe" chroma limit used in
375
+ * OKHSL↔sRGB conversions (luminance, contrast solving, output formatting).
376
+ * Falls through to the global / per-theme `pastel` config when omitted.
377
+ * @see GlazeConfig.pastel
378
+ */
379
+ pastel?: boolean;
380
+ /**
381
+ * Semantic role of the mixed result against `base`. Same semantics as
382
+ * `RegularColorDef.role` (fixes APCA polarity). Resolution and defaults
383
+ * are identical.
384
+ */
385
+ role?: RoleInput;
386
+ /**
387
+ * Whether this color is inherited by child themes created via `extend()`.
388
+ * Default: true. Set to false to make this color local to the current theme.
389
+ */
390
+ inherit?: boolean;
214
391
  }
215
392
  type ColorDef = RegularColorDef | ShadowColorDef | MixColorDef;
216
393
  type ColorMap = Record<string, ColorDef>;
217
- /** Resolved color for a single scheme variant. */
394
+ /**
395
+ * Resolved color for a single scheme variant.
396
+ *
397
+ * Stored in OKHST: `h` / `s` are OKHSL hue/saturation, `t` is the canonical
398
+ * contrast-uniform tone (0–1, reference eps). Convert to OKHSL lightness via
399
+ * `variantToOkhsl` at the rendering / luminance edges.
400
+ */
218
401
  interface ResolvedColorVariant {
219
402
  /** OKHSL hue (0–360). */
220
403
  h: number;
221
404
  /** OKHSL saturation (0–1). */
222
405
  s: number;
223
- /** OKHSL lightness (0–1). */
224
- l: number;
406
+ /** Canonical tone (0–1, reference eps). */
407
+ t: number;
225
408
  /** Opacity (0–1). Default: 1. */
226
409
  alpha: number;
410
+ /**
411
+ * Effective `pastel` flag used while resolving this variant (author def or
412
+ * config fallback). Carried on the variant so output formatting matches the
413
+ * gamut mapping applied during resolution.
414
+ */
415
+ pastel?: boolean;
227
416
  }
228
417
  /** Fully resolved color across all scheme variants. */
229
418
  interface ResolvedColor {
@@ -235,20 +424,27 @@ interface ResolvedColor {
235
424
  /** Adaptation mode. Present only for regular colors, omitted for shadows. */
236
425
  mode?: AdaptationMode;
237
426
  }
427
+ /**
428
+ * A scheme tone window.
429
+ * - `[lo, hi]`: OKHSL-lightness endpoints (0–100) the authored tone is
430
+ * remapped into, using the reference eps `0.05`. The common form.
431
+ * - `{ lo, hi, eps }`: same, with an explicit render curvature `eps`
432
+ * (advanced — most palettes never need this).
433
+ * - `false`: disable clamping (full range `[0, 100]` at the reference eps).
434
+ * This removes the *boundaries*, not the tone curve.
435
+ */
436
+ type ToneWindow = false | [number, number] | {
437
+ lo: number;
438
+ hi: number;
439
+ eps: number;
440
+ };
238
441
  interface GlazeConfig {
239
- /** Light scheme lightness window [lo, hi]. Default: [10, 100]. */
240
- lightLightness?: [number, number];
241
- /** Dark scheme lightness window [lo, hi]. Default: [15, 95]. */
242
- darkLightness?: [number, number];
442
+ /** Light scheme tone window — `[lo, hi]` (default `[10, 100]`), `{ lo, hi, eps }` for advanced eps tuning, or `false` to disable clamping. */
443
+ lightTone?: ToneWindow;
444
+ /** Dark scheme tone window — `[lo, hi]` (default `[15, 95]`), `{ lo, hi, eps }`, or `false` to disable clamping. */
445
+ darkTone?: ToneWindow;
243
446
  /** Saturation reduction factor for dark scheme (0–1). Default: 0.1. */
244
447
  darkDesaturation?: number;
245
- /**
246
- * Möbius beta for dark auto-inversion (0–1).
247
- * Lower values expand subtle near-white distinctions in dark mode.
248
- * Set to 1 for linear (legacy) behavior. Default: 0.5.
249
- * Accepts [normal, highContrast] pair for separate HC tuning.
250
- */
251
- darkCurve?: HCPair<number>;
252
448
  /** State alias names for token export. */
253
449
  states?: {
254
450
  dark?: string;
@@ -258,42 +454,303 @@ interface GlazeConfig {
258
454
  modes?: GlazeOutputModes;
259
455
  /** Default tuning for all shadow colors. Per-color tuning merges field-by-field. */
260
456
  shadowTuning?: ShadowTuning;
457
+ /**
458
+ * Automatically flip tone direction when contrast can't be met.
459
+ *
460
+ * When enabled (default `true`), the solver searches the requested
461
+ * tone direction first. If that direction can't reach the target,
462
+ * it tries the opposite direction and uses it when it passes. If neither
463
+ * side passes, the tone is pinned to the requested-direction
464
+ * extreme and a warning is emitted.
465
+ *
466
+ * Set to `false` for strict "no flip" behavior. The opposite
467
+ * direction is never considered: if the requested direction can't
468
+ * meet the target, the tone is pinned to its extreme (never
469
+ * falls back to the originally requested tone).
470
+ */
471
+ autoFlip?: boolean;
472
+ /**
473
+ * If true, uses a hue-independent "safe" chroma limit across all colors
474
+ * so that scaling saturation never exceeds the sRGB boundary at any hue
475
+ * for the given lightness.
476
+ * @default false
477
+ */
478
+ pastel?: boolean;
479
+ /**
480
+ * If true (default), infer a color's `role` from its name when no explicit
481
+ * `role` is set. Set to `false` to opt out of name-based inference (the
482
+ * base-opposite and default-foreground fallbacks still apply).
483
+ * @default true
484
+ */
485
+ inferRole?: boolean;
261
486
  }
262
487
  interface GlazeConfigResolved {
263
- lightLightness: [number, number];
264
- darkLightness: [number, number];
488
+ lightTone: ToneWindow;
489
+ darkTone: ToneWindow;
265
490
  darkDesaturation: number;
266
- darkCurve: HCPair<number>;
267
491
  states: {
268
492
  dark: string;
269
493
  highContrast: string;
270
494
  };
271
495
  modes: Required<GlazeOutputModes>;
272
496
  shadowTuning?: ShadowTuning;
497
+ autoFlip: boolean;
498
+ pastel: boolean;
499
+ inferRole: boolean;
500
+ }
501
+ /**
502
+ * Per-instance config override for `glaze.color()` and `glaze()` themes.
503
+ * Fields that are set take priority over the live global config. Fields
504
+ * that are omitted fall through to the live global at resolve time.
505
+ *
506
+ * `false` for a tone window disables clamping (full range at reference eps).
507
+ */
508
+ interface GlazeConfigOverride {
509
+ /** Light scheme tone window, or `false` to disable clamping. */
510
+ lightTone?: ToneWindow;
511
+ /** Dark scheme tone window, or `false` to disable clamping. */
512
+ darkTone?: ToneWindow;
513
+ /** Saturation reduction factor for dark scheme (0–1). */
514
+ darkDesaturation?: number;
515
+ /** Whether to auto-flip tone when contrast can't be met. */
516
+ autoFlip?: boolean;
517
+ /**
518
+ * If true, uses a hue-independent "safe" chroma limit across all colors
519
+ * so that scaling saturation never exceeds the sRGB boundary at any hue
520
+ * for the given lightness.
521
+ */
522
+ pastel?: boolean;
523
+ /**
524
+ * If true, infer a color's `role` from its name when no explicit `role` is
525
+ * set. Falls through to the live global at resolve time when omitted.
526
+ */
527
+ inferRole?: boolean;
528
+ /**
529
+ * Shadow tuning defaults. Only meaningful for themes; harmless on
530
+ * standalone color tokens.
531
+ */
532
+ shadowTuning?: ShadowTuning;
273
533
  }
274
534
  /** Serialized theme configuration (no resolved values). */
275
535
  interface GlazeThemeExport {
276
536
  hue: number;
277
537
  saturation: number;
278
538
  colors: ColorMap;
539
+ /** Per-theme config override, if any. */
540
+ config?: GlazeConfigOverride;
279
541
  }
280
542
  /** Input for `glaze.shadow()` standalone factory. */
281
543
  interface GlazeShadowInput {
282
- /** Background color — hex string or OKHSL { h, s (0-1), l (0-1) }. */
283
- bg: HexColor | OkhslColor;
284
- /** Foreground color for tinting + intensity modulation. */
285
- fg?: HexColor | OkhslColor;
544
+ /**
545
+ * Background color — accepts any `GlazeColorValue` form: hex
546
+ * (`#rgb` / `#rrggbb` / `#rrggbbaa`), `rgb()` / `hsl()` / `okhsl()`
547
+ * / `oklch()` strings, or literal objects (`{ r, g, b }`, `{ h, s, l }`,
548
+ * `{ l, c, h }`). Alpha components are dropped with a warning.
549
+ */
550
+ bg: GlazeColorValue;
551
+ /**
552
+ * Foreground color for tinting + intensity modulation. Accepts the
553
+ * same forms as `bg`.
554
+ */
555
+ fg?: GlazeColorValue;
286
556
  /** Intensity 0-100. */
287
557
  intensity: number;
288
558
  tuning?: ShadowTuning;
289
559
  }
290
- /** Input for `glaze.color()` standalone factory. */
560
+ /** Input for the structured `glaze.color()` overload. */
291
561
  interface GlazeColorInput {
292
562
  hue: number;
293
563
  saturation: number;
294
- lightness: HCPair<number>;
564
+ tone: HCPair<number | ExtremeValue>;
295
565
  saturationFactor?: number;
296
566
  mode?: AdaptationMode;
567
+ /** Flip out-of-bounds results instead of clamping. Default: global `autoFlip`. */
568
+ flip?: boolean;
569
+ /**
570
+ * Fixed opacity (0–1). Output includes alpha in the CSS value.
571
+ * Combining with `contrast` is not recommended (perceived tone
572
+ * becomes unpredictable) — a `console.warn` is emitted in that case.
573
+ */
574
+ opacity?: number;
575
+ /**
576
+ * Optional dependency on another color. Same semantics as
577
+ * `GlazeColorOverrides.base` — `contrast` and relative `tone`
578
+ * anchor to the base per scheme.
579
+ */
580
+ base?: GlazeColorToken | GlazeColorValue;
581
+ /**
582
+ * Contrast floor against `base`. Requires `base` to be set. A bare
583
+ * number/preset is WCAG; use `{ wcag }` / `{ apca }` to pick the metric.
584
+ */
585
+ contrast?: HCPair<ContrastSpec>;
586
+ /**
587
+ * Optional human-readable name for the token. Used in error and
588
+ * warning messages (otherwise an internal name like `"value"` is
589
+ * used). Does not affect output keys.
590
+ */
591
+ name?: string;
592
+ /**
593
+ * Per-color override for the hue-independent "safe" chroma limit used in
594
+ * OKHSL↔sRGB conversions (luminance, contrast solving, output formatting).
595
+ * Falls through to the global / per-theme `pastel` config when omitted.
596
+ * @see GlazeConfig.pastel
597
+ */
598
+ pastel?: boolean;
599
+ /**
600
+ * Semantic role against `base` / the literal seed: how this token is used.
601
+ * Fixes APCA contrast polarity. Same resolution chain as
602
+ * `RegularColorDef.role` (explicit → name inference → opposite of base →
603
+ * `'text'`). For standalone tokens the name is internal, so set `role`
604
+ * explicitly or rely on the base-opposite / foreground default.
605
+ */
606
+ role?: RoleInput;
607
+ }
608
+ /**
609
+ * Any single-color input form accepted by the value-shorthand
610
+ * overload of `glaze.color()`.
611
+ *
612
+ * Strings cover hex (`#rgb` / `#rrggbb` / `#rrggbbaa`, alpha dropped
613
+ * with a warning) and the four CSS color functions Glaze itself emits:
614
+ * `rgb()`, `hsl()`, `okhsl()`, `oklch()` (alpha components also dropped
615
+ * with a warning).
616
+ *
617
+ * Literal object forms:
618
+ * - `{ h, s, l }` — OKHSL (h: 0–360, s/l: 0–1). Passing 0–100 for `s`/`l`
619
+ * throws with a hint to use the structured form.
620
+ * - `{ h, s, t }` — OKHST (h: 0–360, s/t: 0–1). Tone in 0–1.
621
+ * - `{ r, g, b }` — sRGB 0–255.
622
+ * - `{ l, c, h }` — OKLCh (L/C: 0–1, H: degrees), same as `oklch()` strings.
623
+ */
624
+ type GlazeColorValue = string | OkhslColor | OkhstColor | RgbColor | OklchColor;
625
+ /** Color overrides for the `from` and value-shorthand inputs. */
626
+ interface GlazeColorOverrides {
627
+ /**
628
+ * Override hue. Number is absolute (0–360); `'+N'`/`'-N'` is relative
629
+ * to the extracted (or overridden) seed hue — same semantics as
630
+ * `RegularColorDef.hue`.
631
+ */
632
+ hue?: number | RelativeValue;
633
+ /** Override seed saturation (0–100). Default: extracted from value. */
634
+ saturation?: number;
635
+ /**
636
+ * Override tone. Number is absolute (0–100, contrast-uniform); `'+N'`/`'-N'`
637
+ * is relative to the literal seed (the value passed to `glaze.color()`);
638
+ * `'max'` / `'min'` force to the scheme's tone extreme.
639
+ * Supports HCPair for high-contrast.
640
+ */
641
+ tone?: HCPair<ToneValue>;
642
+ /** Saturation multiplier on the seed (0–1). Default: 1. */
643
+ saturationFactor?: number;
644
+ /**
645
+ * Adaptation mode. Defaults to `'auto'` for every input form, so
646
+ * colors automatically adapt between light and dark like an ordinary
647
+ * theme color. All value-shorthand inputs (strings and literal objects)
648
+ * preserve light tone (`lightTone: false`) and snapshot
649
+ * `globalConfig.darkTone` on the dark side. Only the structured
650
+ * `{ hue, saturation, tone }` form also snapshots
651
+ * `globalConfig.lightTone`.
652
+ *
653
+ * Pass `'fixed'` explicitly to opt back into the linear, non-
654
+ * inverting mapping; pass `'static'` to pin the same tone
655
+ * across every variant.
656
+ */
657
+ mode?: AdaptationMode;
658
+ /**
659
+ * Flip out-of-bounds results (relative `tone` overshoot / unmet
660
+ * `contrast`) to the opposite side instead of clamping. Defaults to
661
+ * the global `autoFlip`.
662
+ */
663
+ flip?: boolean;
664
+ /**
665
+ * Contrast floor. By default solved against the literal seed
666
+ * (the value itself); when `base` is set, solved against the base's
667
+ * resolved variant per scheme. Same shape as `RegularColorDef.contrast`
668
+ * (bare number/preset = WCAG; `{ wcag }` / `{ apca }` to pick the metric).
669
+ */
670
+ contrast?: HCPair<ContrastSpec>;
671
+ /**
672
+ * Optional dependency on another color. Accepts either a
673
+ * `GlazeColorToken` (returned by another `glaze.color()`) or a raw
674
+ * `GlazeColorValue` (hex / CSS strings / `{ r, g, b }` / `{ h, s, l }` / …),
675
+ * which is automatically wrapped in `glaze.color(value)`.
676
+ *
677
+ * When set:
678
+ * - `contrast` is solved against the base's resolved variant
679
+ * per-scheme (light / dark / lightContrast / darkContrast).
680
+ * - Relative `tone: '+N'` / `'-N'` is anchored to the base's
681
+ * tone per-scheme (matches theme behavior for dependent colors).
682
+ * - Relative `hue: '+N'` / `'-N'` still anchors to the seed (the
683
+ * value passed to `glaze.color()`), not the base.
684
+ * - When the base was created via the structured form (with explicit
685
+ * `hue`/`saturation`/`tone`), it is resolved at full range
686
+ * (`lightTone: false`) for the linking math — ensuring the
687
+ * contrast/tone anchor matches the input tone, not the
688
+ * windowed output. The base's own `.resolve()` output is unaffected.
689
+ *
690
+ * The base token's `.resolve()` is called lazily on first resolve and
691
+ * its result is captured by reference; later mutations to the base's
692
+ * defining call don't apply (matches existing token snapshot semantics).
693
+ */
694
+ base?: GlazeColorToken | GlazeColorValue;
695
+ /**
696
+ * Fixed opacity (0–1). Output includes alpha in the CSS value.
697
+ * Combining with `contrast` is not recommended (perceived tone
698
+ * becomes unpredictable) — a `console.warn` is emitted in that case.
699
+ */
700
+ opacity?: number;
701
+ /**
702
+ * Optional human-readable name for the token. Used in error and
703
+ * warning messages (otherwise an internal name like `"value"` is
704
+ * used). Does not affect output keys.
705
+ */
706
+ name?: string;
707
+ /**
708
+ * Per-color override for the hue-independent "safe" chroma limit used in
709
+ * OKHSL↔sRGB conversions (luminance, contrast solving, output formatting).
710
+ * Falls through to the global / per-theme `pastel` config when omitted.
711
+ * @see GlazeConfig.pastel
712
+ */
713
+ pastel?: boolean;
714
+ /**
715
+ * Semantic role against `base` / the literal seed: how this token is used.
716
+ * Fixes APCA contrast polarity. Same resolution chain as
717
+ * `RegularColorDef.role`.
718
+ */
719
+ role?: RoleInput;
720
+ }
721
+ /**
722
+ * Object input for `glaze.color()` that carries a raw color value plus
723
+ * optional color overrides in the same object.
724
+ *
725
+ * ```ts
726
+ * glaze.color({ from: '#1a1a2e', base: bg, contrast: 'AA' })
727
+ * glaze.color({ from: { r: 38, g: 252, b: 178 }, tone: '+10' })
728
+ * ```
729
+ */
730
+ interface GlazeFromInput extends GlazeColorOverrides {
731
+ /** The source color value. Accepts the same forms as a bare `GlazeColorValue`. */
732
+ from: GlazeColorValue;
733
+ }
734
+ /** Options for `GlazeColorToken.css()`. */
735
+ interface GlazeColorCssOptions {
736
+ /**
737
+ * Custom property base name (without leading `--`). Required.
738
+ * Becomes the variable identifier in the output, e.g.
739
+ * `name: 'brand'` → `--brand-color: …`.
740
+ */
741
+ name: string;
742
+ /** Output color format. Default: 'rgb' (matches `theme.css` default). */
743
+ format?: GlazeColorFormat;
744
+ /**
745
+ * Suffix appended to the name. Default: '-color' (matches
746
+ * `theme.css` default).
747
+ */
748
+ suffix?: string;
749
+ /**
750
+ * Emit hue as a separate custom property, referenced via `var()`.
751
+ * Requires `format: 'oklch'` and a pastel token. oklch + all-pastel only.
752
+ */
753
+ splitHue?: boolean;
297
754
  }
298
755
  /** Return type for `glaze.color()`. */
299
756
  interface GlazeColorToken {
@@ -304,17 +761,110 @@ interface GlazeColorToken {
304
761
  /**
305
762
  * Export as a tasty style-to-state binding (no color name key).
306
763
  * Uses `#name` keys and state aliases (`''`, `@dark`, etc.).
307
- * @see https://cube-ui-kit.vercel.app/?path=/docs/tasty-documentation--docs
764
+ * @see https://tasty.style/docs
308
765
  */
309
766
  tasty(options?: GlazeTokenOptions): Record<string, string>;
310
767
  /** Export as a flat JSON map (no color name key). */
311
768
  json(options?: GlazeJsonOptions): Record<string, string>;
769
+ /** Export as CSS custom property declarations grouped by scheme variant. */
770
+ css(options: GlazeColorCssOptions): GlazeCssResult;
771
+ /**
772
+ * Export as W3C DTCG color tokens (one per scheme variant, no color name
773
+ * key). Each entry is a full `{ $type: 'color', $value }` token.
774
+ * @see https://www.designtokens.org/
775
+ */
776
+ dtcg(options?: GlazeDtcgOptions): GlazeColorDtcgResult;
777
+ /**
778
+ * Export as a single W3C DTCG Resolver-Module document for this color,
779
+ * keyed by `name` across all scheme variants. `name` is required.
780
+ * @see https://www.designtokens.org/
781
+ */
782
+ dtcgResolver(options: GlazeColorDtcgResolverOptions): GlazeDtcgResolverDocument;
783
+ /**
784
+ * Export as a Tailwind CSS v4 `@theme` block (light baseline) plus dark /
785
+ * high-contrast overrides. Returns a single ready-to-paste CSS string.
786
+ * `name` is required (forms `--color-<name>`).
787
+ * @see https://tailwindcss.com/docs/theme
788
+ */
789
+ tailwind(options: GlazeColorTailwindOptions): string;
790
+ /**
791
+ * Serialize the token as a JSON-safe object. Captures the original
792
+ * input value, overrides, and config so it can be rehydrated via
793
+ * `glaze.colorFrom(...)`. `base` is recursively serialized.
794
+ */
795
+ export(): GlazeColorTokenExport;
796
+ }
797
+ /**
798
+ * JSON-safe serialization of a `glaze.color()` token. Pass to
799
+ * `glaze.colorFrom(...)` to rehydrate.
800
+ */
801
+ interface GlazeColorTokenExport {
802
+ /**
803
+ * Discriminator for the source overload that created the token.
804
+ * - `'value'`: created via `glaze.color(value)` or `glaze.color({ from, ...overrides })`.
805
+ * - `'structured'`: created via `glaze.color({ hue, saturation, ... })`.
806
+ */
807
+ form: 'value' | 'structured';
808
+ /** Original input. For `form: 'value'` this is the raw `GlazeColorValue`; for `form: 'structured'` this is the structured input. */
809
+ input: GlazeColorValue | GlazeColorInputExport;
810
+ /**
811
+ * Overrides recorded at creation time. `base` is recursively
812
+ * serialized. Only present for `form: 'value'`.
813
+ */
814
+ overrides?: GlazeColorOverridesExport;
815
+ /**
816
+ * Effective config snapshot at creation time — captures the merged
817
+ * result of the global config + any per-call override at the moment
818
+ * the token was created. Only fields that differ from their
819
+ * post-merge defaults are present. Used by `glaze.colorFrom()` to
820
+ * reproduce deterministic behavior across `configure()` calls.
821
+ */
822
+ config?: GlazeConfigOverride;
823
+ }
824
+ /**
825
+ * Serializable shape of a structured `glaze.color({...})` input.
826
+ * Differs from `GlazeColorInput` only in that `base` is replaced by an
827
+ * `export` instead of a token reference.
828
+ */
829
+ interface GlazeColorInputExport {
830
+ hue: number;
831
+ saturation: number;
832
+ tone: HCPair<number | ExtremeValue>;
833
+ saturationFactor?: number;
834
+ mode?: AdaptationMode;
835
+ flip?: boolean;
836
+ opacity?: number;
837
+ base?: GlazeColorTokenExport | GlazeColorValue;
838
+ contrast?: HCPair<ContrastSpec>;
839
+ name?: string;
840
+ pastel?: boolean;
841
+ role?: RoleInput;
842
+ }
843
+ /**
844
+ * Serializable shape of `GlazeColorOverrides`. `base` is replaced by
845
+ * its export (or left as a `GlazeColorValue` if it was originally a value).
846
+ */
847
+ interface GlazeColorOverridesExport {
848
+ hue?: number | RelativeValue;
849
+ saturation?: number;
850
+ tone?: HCPair<ToneValue>;
851
+ saturationFactor?: number;
852
+ mode?: AdaptationMode;
853
+ flip?: boolean;
854
+ contrast?: HCPair<ContrastSpec>;
855
+ base?: GlazeColorTokenExport | GlazeColorValue;
856
+ opacity?: number;
857
+ name?: string;
858
+ pastel?: boolean;
859
+ role?: RoleInput;
312
860
  }
313
861
  interface GlazeTheme {
314
862
  /** The hue seed (0–360). */
315
863
  readonly hue: number;
316
864
  /** The saturation seed (0–100). */
317
865
  readonly saturation: number;
866
+ /** The effective config for this theme. */
867
+ getConfig(): GlazeConfigResolved;
318
868
  /** Add/replace colors (additive merge with existing definitions). */
319
869
  colors(defs: ColorMap): void;
320
870
  /** Get a color definition by name. */
@@ -348,18 +898,41 @@ interface GlazeTheme {
348
898
  * Export as tasty style-to-state bindings.
349
899
  * Uses `#name` color token keys and state aliases (`''`, `@dark`, etc.).
350
900
  * Spread into component styles or register as a recipe via `configure({ recipes })`.
351
- * @see https://cube-ui-kit.vercel.app/?path=/docs/tasty-documentation--docs
901
+ * @see https://tasty.style/docs
352
902
  */
353
903
  tasty(options?: GlazeTokenOptions): Record<string, Record<string, string>>;
354
904
  /** Export as plain JSON. */
355
905
  json(options?: GlazeJsonOptions): Record<string, Record<string, string>>;
356
906
  /** Export as CSS custom property declarations. */
357
907
  css(options?: GlazeCssOptions): GlazeCssResult;
908
+ /**
909
+ * Export as W3C Design Tokens Format Module (2025.10) documents, one per
910
+ * scheme variant. Consumable by Figma, Tokens Studio, Style Dictionary,
911
+ * Terrazzo, and any DTCG-compatible tool.
912
+ * @see https://www.designtokens.org/
913
+ */
914
+ dtcg(options?: GlazeDtcgOptions): GlazeDtcgResult;
915
+ /**
916
+ * Export as a single W3C DTCG Resolver-Module document describing every
917
+ * scheme variant as one `sets` entry plus a single `scheme` modifier with a
918
+ * context per variant. Consumable by resolver tools such as Dispersa.
919
+ * @see https://www.designtokens.org/
920
+ */
921
+ dtcgResolver(options?: GlazeDtcgResolverOptions): GlazeDtcgResolverDocument;
922
+ /**
923
+ * Export as a Tailwind CSS v4 `@theme` block (light baseline) plus dark /
924
+ * high-contrast overrides under configurable selectors. Returns a single
925
+ * ready-to-paste CSS string.
926
+ * @see https://tailwindcss.com/docs/theme
927
+ */
928
+ tailwind(options?: GlazeTailwindOptions): string;
358
929
  }
359
930
  interface GlazeExtendOptions {
360
931
  hue?: number;
361
932
  saturation?: number;
362
933
  colors?: ColorMap;
934
+ /** Config override for the child theme. Merged with the parent's override. */
935
+ config?: GlazeConfigOverride;
363
936
  }
364
937
  interface GlazeTokenOptions {
365
938
  /** Prefix mode. `true` uses "<themeName>-", or provide a custom map. */
@@ -373,6 +946,16 @@ interface GlazeTokenOptions {
373
946
  modes?: GlazeOutputModes;
374
947
  /** Output color format. Default: 'okhsl'. */
375
948
  format?: GlazeColorFormat;
949
+ /**
950
+ * Emit hue as a separate custom property, referenced via `var()`.
951
+ * Requires `format: 'oklch'` and every color to be pastel.
952
+ */
953
+ splitHue?: boolean;
954
+ /**
955
+ * Base name for the theme-level hue var (`--{name}-hue`). Default: `'theme'`.
956
+ * Palette export auto-derives this from the theme name.
957
+ */
958
+ name?: string;
376
959
  }
377
960
  interface GlazeJsonOptions {
378
961
  /** Override which scheme variants to include. */
@@ -385,6 +968,16 @@ interface GlazeCssOptions {
385
968
  format?: GlazeColorFormat;
386
969
  /** Suffix appended to each CSS custom property name. Default: '-color'. */
387
970
  suffix?: string;
971
+ /**
972
+ * Emit hue as a separate custom property, referenced via `var()`.
973
+ * Requires `format: 'oklch'` and every color to be pastel.
974
+ */
975
+ splitHue?: boolean;
976
+ /**
977
+ * Base name for the theme-level hue var (`--{name}-hue`). Default: `'theme'`.
978
+ * Palette export auto-derives this from the theme name.
979
+ */
980
+ name?: string;
388
981
  }
389
982
  /** CSS custom property declarations grouped by scheme variant. */
390
983
  interface GlazeCssResult {
@@ -393,6 +986,182 @@ interface GlazeCssResult {
393
986
  lightContrast: string;
394
987
  darkContrast: string;
395
988
  }
989
+ /**
990
+ * Color space used for DTCG `$value` color objects.
991
+ * @see https://www.designtokens.org/
992
+ */
993
+ type DtcgColorSpace = 'srgb' | 'oklch';
994
+ /**
995
+ * A DTCG color `$value` in the sRGB color space: gamma sRGB components in
996
+ * 0–1 plus a 6-digit `hex` hint. Universally understood by Figma, Tokens
997
+ * Studio, Style Dictionary, and every DTCG reader.
998
+ */
999
+ interface DtcgSrgbColorValue {
1000
+ colorSpace: 'srgb';
1001
+ components: [number, number, number];
1002
+ hex: HexColor;
1003
+ /** Opacity 0–1. Omitted when fully opaque (alpha = 1). */
1004
+ alpha?: number;
1005
+ }
1006
+ /**
1007
+ * A DTCG color `$value` in the OKLCH color space: `[L, C, H]` components
1008
+ * (L/C: 0–1, H: degrees). Wide-gamut and Glaze-native; no `hex` is emitted.
1009
+ */
1010
+ interface DtcgOklchColorValue {
1011
+ colorSpace: 'oklch';
1012
+ components: [number, number, number];
1013
+ /** Opacity 0–1. Omitted when fully opaque (alpha = 1). */
1014
+ alpha?: number;
1015
+ }
1016
+ /** A DTCG `$value` for a color token, in either supported color space. */
1017
+ type DtcgColorValue = DtcgSrgbColorValue | DtcgOklchColorValue;
1018
+ /**
1019
+ * A single W3C DTCG color token: `{ $type: 'color', $value }`.
1020
+ * `$description` is optional and not populated by Glaze today.
1021
+ */
1022
+ interface DtcgColorToken {
1023
+ $type: 'color';
1024
+ $value: DtcgColorValue;
1025
+ $description?: string;
1026
+ }
1027
+ /**
1028
+ * A W3C Design Tokens Format Module (2025.10) token tree for one scheme.
1029
+ * Glaze emits one document per scheme variant — the most tool-compatible
1030
+ * convention (one file per Style Dictionary theme / Tokens Studio set /
1031
+ * Figma variable mode).
1032
+ */
1033
+ type DtcgDocument = Record<string, DtcgColorToken>;
1034
+ /** DTCG token documents grouped by scheme variant. Light is always present. */
1035
+ interface GlazeDtcgResult {
1036
+ light: DtcgDocument;
1037
+ dark?: DtcgDocument;
1038
+ lightContrast?: DtcgDocument;
1039
+ darkContrast?: DtcgDocument;
1040
+ }
1041
+ /** A single DTCG color token grouped by scheme variant (standalone tokens). */
1042
+ interface GlazeColorDtcgResult {
1043
+ light: DtcgColorToken;
1044
+ dark?: DtcgColorToken;
1045
+ lightContrast?: DtcgColorToken;
1046
+ darkContrast?: DtcgColorToken;
1047
+ }
1048
+ /** Options for `theme.dtcg()` / `palette.dtcg()`. */
1049
+ interface GlazeDtcgOptions {
1050
+ /** Override which scheme variants to include. */
1051
+ modes?: GlazeOutputModes;
1052
+ /**
1053
+ * DTCG color space. `'srgb'` (default) emits sRGB components plus a `hex`
1054
+ * hint — universally understood (Figma, Tokens Studio). `'oklch'` emits
1055
+ * OKLCH components with no hex — Glaze-native, wide-gamut.
1056
+ */
1057
+ colorSpace?: DtcgColorSpace;
1058
+ }
1059
+ /**
1060
+ * A node in a DTCG Resolver-Module token tree: either a leaf color token or a
1061
+ * nested group. A flat `DtcgDocument` (top-level color-name keys) is a valid
1062
+ * shallow tree, so Glaze's per-scheme documents slot directly into
1063
+ * `sets.<name>.sources` and `modifiers.<name>.contexts.<ctx>` entries.
1064
+ */
1065
+ interface DtcgTokenTree {
1066
+ [key: string]: DtcgColorToken | DtcgTokenTree;
1067
+ }
1068
+ /** A named set in a resolver document: a list of token-tree sources. */
1069
+ interface DtcgResolverSet {
1070
+ sources: DtcgTokenTree[];
1071
+ }
1072
+ /**
1073
+ * A named modifier (an axis such as `scheme`) in a resolver document.
1074
+ * `default` names the context applied when no override is selected; `contexts`
1075
+ * maps each context name to the token-tree overrides applied for it.
1076
+ */
1077
+ interface DtcgResolverModifier {
1078
+ default: string;
1079
+ contexts: Record<string, DtcgTokenTree[]>;
1080
+ }
1081
+ /** A JSON-pointer `$ref` entry in a resolver document's `resolutionOrder`. */
1082
+ interface DtcgResolverRef {
1083
+ $ref: string;
1084
+ }
1085
+ /**
1086
+ * A W3C DTCG Resolver-Module document. Describes every scheme variant in a
1087
+ * single file as `sets` (base token sources) plus `modifiers` (per-context
1088
+ * overrides) composed in `resolutionOrder`. Consumable by resolver tools such
1089
+ * as Dispersa.
1090
+ * @see https://www.designtokens.org/
1091
+ */
1092
+ interface GlazeDtcgResolverDocument {
1093
+ version: string;
1094
+ sets: Record<string, DtcgResolverSet>;
1095
+ modifiers: Record<string, DtcgResolverModifier>;
1096
+ resolutionOrder: DtcgResolverRef[];
1097
+ }
1098
+ /** Renaming of the four scheme variants as resolver-modifier context names. */
1099
+ interface GlazeDtcgResolverContextNames {
1100
+ light?: string;
1101
+ dark?: string;
1102
+ lightContrast?: string;
1103
+ darkContrast?: string;
1104
+ }
1105
+ /**
1106
+ * Options for `theme.dtcgResolver()` / `palette.dtcgResolver()`. Extends
1107
+ * `GlazeDtcgOptions` so `modes` + `colorSpace` pass through to the underlying
1108
+ * per-scheme `dtcg()` build.
1109
+ */
1110
+ interface GlazeDtcgResolverOptions extends GlazeDtcgOptions {
1111
+ /** Name of the single set holding the default (light) token tree. Default `'base'`. */
1112
+ setName?: string;
1113
+ /**
1114
+ * Name of the modifier describing the scheme axis. Default `'scheme'`
1115
+ * (Glaze's term for the light / dark / high-contrast axis).
1116
+ */
1117
+ modifierName?: string;
1118
+ /**
1119
+ * Override the four context names emitted on the modifier. Defaults to the
1120
+ * Glaze variant keys: `light` / `dark` / `lightContrast` / `darkContrast`.
1121
+ */
1122
+ contextNames?: GlazeDtcgResolverContextNames;
1123
+ /** Resolver document version. Default `'2025.10'`. */
1124
+ version?: string;
1125
+ }
1126
+ /** Options for `glaze.color().dtcgResolver()`. `name` is required. */
1127
+ interface GlazeColorDtcgResolverOptions extends GlazeDtcgResolverOptions {
1128
+ /** Token name keying the color within each token tree. Required. */
1129
+ name: string;
1130
+ }
1131
+ /** Options for `theme.tailwind()` / `palette.tailwind()`. */
1132
+ interface GlazeTailwindOptions {
1133
+ /** Override which scheme variants to include. */
1134
+ modes?: GlazeOutputModes;
1135
+ /** Output color format. Default: 'oklch'. */
1136
+ format?: GlazeColorFormat;
1137
+ /**
1138
+ * CSS custom property namespace, forming `--<namespace><name>`.
1139
+ * Default: `'color-'` → `--color-surface`. (Tailwind v4's `--color-*`
1140
+ * convention, which auto-generates `bg-*` / `text-*` / `border-*`.)
1141
+ *
1142
+ * Named `namespace` rather than `prefix` to avoid clashing with the
1143
+ * palette theme-prefix option on `palette.tailwind()`.
1144
+ */
1145
+ namespace?: string;
1146
+ /**
1147
+ * Selector wrapping the dark-scheme overrides. Default: `'.dark'`.
1148
+ * Pass a media query such as `'@media (prefers-color-scheme: dark)'` to
1149
+ * drive dark mode from the OS preference instead of a class.
1150
+ */
1151
+ darkSelector?: string;
1152
+ /**
1153
+ * Selector wrapping the light high-contrast overrides. Default:
1154
+ * `'.high-contrast'`. The combined dark + high-contrast overrides are
1155
+ * emitted under `${darkSelector}${highContrastSelector}` (e.g.
1156
+ * `.dark.high-contrast`).
1157
+ */
1158
+ highContrastSelector?: string;
1159
+ }
1160
+ /** Options for `glaze.color().tailwind()`. `name` is required. */
1161
+ interface GlazeColorTailwindOptions extends GlazeTailwindOptions {
1162
+ /** Custom property base name (without leading `--`). Required. */
1163
+ name: string;
1164
+ }
396
1165
  /** Options for `glaze.palette()` creation. */
397
1166
  interface GlazePaletteOptions {
398
1167
  /**
@@ -424,6 +1193,11 @@ interface GlazePaletteExportOptions {
424
1193
  * When omitted, inherits the palette-level `primary`.
425
1194
  */
426
1195
  primary?: string | false;
1196
+ /**
1197
+ * Emit hue as a separate custom property, referenced via `var()`.
1198
+ * Requires `format: 'oklch'` and every color to be pastel.
1199
+ */
1200
+ splitHue?: boolean;
427
1201
  }
428
1202
  interface GlazePalette {
429
1203
  /**
@@ -442,7 +1216,7 @@ interface GlazePalette {
442
1216
  * Export all themes as tasty style-to-state bindings.
443
1217
  * Uses `#name` color token keys and state aliases (`''`, `@dark`, etc.).
444
1218
  * Prefix defaults to `true`. Inherits the palette-level `primary`.
445
- * @see https://cube-ui-kit.vercel.app/?path=/docs/tasty-documentation--docs
1219
+ * @see https://tasty.style/docs
446
1220
  */
447
1221
  tasty(options?: GlazeTokenOptions & GlazePaletteExportOptions): Record<string, Record<string, string>>;
448
1222
  /** Export all themes as plain JSON grouped by theme name. */
@@ -451,6 +1225,25 @@ interface GlazePalette {
451
1225
  }): Record<string, Record<string, Record<string, string>>>;
452
1226
  /** Export all themes as CSS custom property declarations. */
453
1227
  css(options?: GlazeCssOptions & GlazePaletteExportOptions): GlazeCssResult;
1228
+ /**
1229
+ * Export all themes as W3C DTCG documents, one per scheme variant.
1230
+ * Prefix defaults to `true`. Inherits the palette-level `primary`.
1231
+ * @see https://www.designtokens.org/
1232
+ */
1233
+ dtcg(options?: GlazeDtcgOptions & GlazePaletteExportOptions): GlazeDtcgResult;
1234
+ /**
1235
+ * Export all themes as a single W3C DTCG Resolver-Module document. Prefix
1236
+ * defaults to `true`. Inherits the palette-level `primary`.
1237
+ * @see https://www.designtokens.org/
1238
+ */
1239
+ dtcgResolver(options?: GlazeDtcgResolverOptions & GlazePaletteExportOptions): GlazeDtcgResolverDocument;
1240
+ /**
1241
+ * Export all themes as a Tailwind CSS v4 `@theme` block plus dark /
1242
+ * high-contrast overrides. Returns a single ready-to-paste CSS string.
1243
+ * Prefix defaults to `true`.
1244
+ * @see https://tailwindcss.com/docs/theme
1245
+ */
1246
+ tailwind(options?: GlazeTailwindOptions & GlazePaletteExportOptions): string;
454
1247
  }
455
1248
  //#endregion
456
1249
  //#region src/glaze.d.ts
@@ -458,54 +1251,201 @@ type PaletteInput = Record<string, GlazeTheme>;
458
1251
  /**
459
1252
  * Create a single-hue glaze theme.
460
1253
  *
1254
+ * An optional `config` override can be supplied to customize the resolve
1255
+ * behavior for this theme (tone windows, etc.). The
1256
+ * override is **merged over the live global config at resolve time** —
1257
+ * the theme still reacts to later `configure()` calls for fields it
1258
+ * didn't override.
1259
+ *
461
1260
  * @example
462
1261
  * ```ts
463
- * const primary = glaze({ hue: 280, saturation: 80 });
464
- * // or shorthand:
465
1262
  * const primary = glaze(280, 80);
1263
+ * // or shorthand:
1264
+ * const primary = glaze({ hue: 280, saturation: 80 });
1265
+ * // with config override:
1266
+ * const raw = glaze(280, 80, { lightTone: false });
466
1267
  * ```
467
1268
  */
468
1269
  declare function glaze(hueOrOptions: number | {
469
1270
  hue: number;
470
1271
  saturation: number;
471
- }, saturation?: number): GlazeTheme;
1272
+ }, saturation?: number, config?: GlazeConfigOverride): GlazeTheme;
472
1273
  declare namespace glaze {
473
1274
  var configure: (config: GlazeConfig) => void;
474
- var palette: (themes: PaletteInput, options?: GlazePaletteOptions) => {
475
- tokens(options?: GlazeJsonOptions & GlazePaletteExportOptions): Record<string, Record<string, string>>;
476
- tasty(options?: GlazeTokenOptions & GlazePaletteExportOptions): Record<string, Record<string, string>>;
477
- json(options?: GlazeJsonOptions & {
478
- prefix?: boolean | Record<string, string>;
479
- }): Record<string, Record<string, Record<string, string>>>;
480
- css(options?: GlazeCssOptions & GlazePaletteExportOptions): GlazeCssResult;
481
- };
1275
+ var palette: (themes: PaletteInput, options?: GlazePaletteOptions) => GlazePalette;
482
1276
  var from: (data: GlazeThemeExport) => GlazeTheme;
483
- var color: (input: GlazeColorInput) => GlazeColorToken;
1277
+ var color: (input: GlazeFromInput | GlazeColorInput | GlazeColorValue, config?: GlazeConfigOverride) => GlazeColorToken;
484
1278
  var shadow: (input: GlazeShadowInput) => ResolvedColorVariant;
485
- var format: (variant: ResolvedColorVariant, colorFormat?: GlazeColorFormat) => string;
1279
+ var format: (variant: ResolvedColorVariant, colorFormat?: GlazeColorFormat, pastel?: boolean) => string;
486
1280
  var fromHex: (hex: string) => GlazeTheme;
487
1281
  var fromRgb: (r: number, g: number, b: number) => GlazeTheme;
1282
+ var colorFrom: (data: GlazeColorTokenExport) => GlazeColorToken;
488
1283
  var getConfig: () => GlazeConfigResolved;
489
1284
  var resetConfig: () => void;
490
1285
  }
491
1286
  //#endregion
1287
+ //#region src/channels.d.ts
1288
+ interface HueDeclaration {
1289
+ prop: string;
1290
+ value: string;
1291
+ }
1292
+ interface HuePlan {
1293
+ /** CSS `var()` reference spliced into `oklch(L C <hueVar>)`. */
1294
+ hueVar: string;
1295
+ /** When true, emit a full inline color (shadow/mix/achromatic). */
1296
+ inline: boolean;
1297
+ /** Scheme-independent `--*-hue` declarations for this color. */
1298
+ declarations: HueDeclaration[];
1299
+ }
1300
+ interface ChannelCtx {
1301
+ seedHue: number;
1302
+ /** Theme-level hue var base name (without `--` / `-hue`). */
1303
+ baseName: string;
1304
+ /** Token / custom-property name prefix used for hue var naming (`brand-` etc.). */
1305
+ prefix: string;
1306
+ defs: ColorMap;
1307
+ mode: 'theme' | 'standalone';
1308
+ /** Standalone: resolved hue from the primary variant (scheme-independent). */
1309
+ resolvedHue?: number;
1310
+ /**
1311
+ * When false, hue declarations are not emitted (the pass only references
1312
+ * hue vars already declared by a sibling pass). Used by palette primary
1313
+ * unprefixed aliases so they reference the themed `--{themeName}-*-hue`
1314
+ * vars without re-declaring (and colliding with) other themes' base vars.
1315
+ * Defaults to true.
1316
+ */
1317
+ emitDeclarations?: boolean;
1318
+ }
1319
+ //#endregion
1320
+ //#region src/format-guard.d.ts
1321
+ /**
1322
+ * Throw when a non-native Glaze color space is requested for an export that
1323
+ * emits raw CSS or non-Tasty token maps.
1324
+ */
1325
+ declare function assertNativeFormat(format: GlazeColorFormat | undefined, method: string): void;
1326
+ /**
1327
+ * Throw when `splitHue` is enabled but any exported color is not pastel.
1328
+ * Hue rotation is only clip-free when chroma is bounded by the hue-independent
1329
+ * safe chroma (`computeSafeChromaOKLCH`).
1330
+ */
1331
+ declare function assertAllPastel(resolved: Map<string, ResolvedColor>, modes: Required<GlazeOutputModes>): void;
1332
+ //#endregion
1333
+ //#region src/roles.d.ts
1334
+ /**
1335
+ * Normalize a `RoleInput` (canonical value or alias) into a canonical `Role`.
1336
+ * Returns `undefined` for unrecognized strings so callers can fall through to
1337
+ * the next step of the resolution chain.
1338
+ */
1339
+ declare function normalizeRole(input: RoleInput | undefined): Role | undefined;
1340
+ /**
1341
+ * Infer a `Role` from a color name by matching its tokens against the role
1342
+ * keyword sets. When multiple tokens match, the **last** recognized token
1343
+ * wins (so `button-text` → `text`, `input-bg` → `surface`, `card-border` →
1344
+ * `border`). Returns `undefined` when no token matches.
1345
+ */
1346
+ declare function inferRoleFromName(name: string): Role | undefined;
1347
+ /** APCA argument order: which side the resolved color plays. */
1348
+ type Polarity = 'fg' | 'bg';
1349
+ /**
1350
+ * Map a role to its APCA polarity. `text` and `border` are foreground spots
1351
+ * against their base (the candidate is the text argument); `surface` is the
1352
+ * background (the base is the text argument).
1353
+ */
1354
+ declare function roleToPolarity(role: Role): Polarity;
1355
+ /**
1356
+ * The opposite role of `role`, used when a color with no explicit role and no
1357
+ * inferable name depends on a base: the dependent color plays the opposite
1358
+ * role of its base. `surface` ↔ `text`; `border` is treated as a foreground
1359
+ * spot, so its opposite is `surface`.
1360
+ */
1361
+ declare function oppositeRole(role: Role): Role;
1362
+ //#endregion
1363
+ //#region src/okhst.d.ts
1364
+ /**
1365
+ * Reference eps for the OKHST color space. WCAG 2 contrast is
1366
+ * `(Y_hi + 0.05) / (Y_lo + 0.05)`, so an eps of `0.05` makes equal tone
1367
+ * steps yield equal WCAG contrast. This is the canonical eps used by
1368
+ * `okhst()` input, `{ h, s, t }` input, stored `ResolvedColorVariant.t`,
1369
+ * relative `tone` offsets, and the contrast solver.
1370
+ */
1371
+ declare const REF_EPS = 0.05;
1372
+ /**
1373
+ * Map a luminance `Y` (0–1) to tone (0–100) at the given eps.
1374
+ * `toneFromY(0) === 0` and `toneFromY(1) === 100` for any eps.
1375
+ */
1376
+ declare function toneFromY(y: number, eps?: number): number;
1377
+ /** Map a tone (0–100) back to luminance (0–1). Inverse of {@link toneFromY}. */
1378
+ declare function yFromTone(t: number, eps?: number): number;
1379
+ /** OKHSL lightness (0–1) -> tone (0–100). */
1380
+ declare function toTone(l: number, eps?: number): number;
1381
+ /** Tone (0–100) -> OKHSL lightness (0–1). Inverse of {@link toTone}. */
1382
+ declare function fromTone(t: number, eps?: number): number;
1383
+ /** Convert OKHST `{ h, s, t }` (t in 0–1) to OKHSL `{ h, s, l }`. */
1384
+ declare function okhstToOkhsl(c: {
1385
+ h: number;
1386
+ s: number;
1387
+ t: number;
1388
+ }): {
1389
+ h: number;
1390
+ s: number;
1391
+ l: number;
1392
+ };
1393
+ /** Convert OKHSL `{ h, s, l }` to OKHST `{ h, s, t }` (t in 0–1). */
1394
+ declare function okhslToOkhst(c: {
1395
+ h: number;
1396
+ s: number;
1397
+ l: number;
1398
+ }): {
1399
+ h: number;
1400
+ s: number;
1401
+ t: number;
1402
+ };
1403
+ /**
1404
+ * Edge adapter: a resolved variant stores canonical tone `t` (0–1). Convert
1405
+ * it to the OKHSL `{ h, s, l }` the formatters and luminance pipeline expect.
1406
+ */
1407
+ declare function variantToOkhsl(v: {
1408
+ h: number;
1409
+ s: number;
1410
+ t: number;
1411
+ }): {
1412
+ h: number;
1413
+ s: number;
1414
+ l: number;
1415
+ };
1416
+ //#endregion
492
1417
  //#region src/okhsl-color-math.d.ts
493
1418
  /**
494
1419
  * OKHSL color math primitives for the glaze theme generator.
495
1420
  *
496
- * Provides bidirectional OKHSL ↔ sRGB conversion, relative luminance
497
- * computation for WCAG 2 contrast calculations, and multi-format output
498
- * (okhsl, rgb, hsl, oklch).
1421
+ * Provides bidirectional OKHSL ↔ sRGB conversion, luminance computation
1422
+ * for both contrast metrics (WCAG 2 relative luminance and APCA screen
1423
+ * luminance `Ys`), and multi-format output (okhsl, rgb, hsl, oklch).
1424
+ */
1425
+ type Vec3 = [number, number, number];
1426
+ /**
1427
+ * OKHSL toe function: maps OKLab lightness L to perceptual lightness l.
1428
+ * Exported for the OKHST tone transfers in `okhst.ts`.
1429
+ */
1430
+ /**
1431
+ * OKHSL lightness of the gamut cusp for a hue — the lightness where the
1432
+ * realizable chroma peaks. Reuses the same `find_cusp` OKHSL already runs for
1433
+ * its `s` normalization (no new color math); the OKLab cusp lightness is run
1434
+ * through the OKHSL `toe` and clamped to `[0.001, 0.999]` so divisions that
1435
+ * key off it stay safe. Cached per (rounded) hue.
1436
+ *
1437
+ * @param h Hue, 0–360.
499
1438
  */
1439
+ declare function cuspLightness(h: number): number;
500
1440
  /**
501
1441
  * Convert OKHSL (h: 0–360, s: 0–1, l: 0–1) to OKLab [L, a, b].
502
1442
  */
503
- declare function okhslToOklab(h: number, s: number, l: number): [number, number, number];
1443
+ declare function okhslToOklab(h: number, s: number, l: number, pastel?: boolean): [number, number, number];
504
1444
  /**
505
1445
  * Convert OKHSL (h: 0–360, s: 0–1, l: 0–1) to linear sRGB.
506
1446
  * Channels may exceed [0, 1] near gamut boundaries — caller must clamp if needed.
507
1447
  */
508
- declare function okhslToLinearSrgb(h: number, s: number, l: number): [number, number, number];
1448
+ declare function okhslToLinearSrgb(h: number, s: number, l: number, pastel?: boolean): [number, number, number];
509
1449
  /**
510
1450
  * Compute relative luminance Y from linear sRGB channels.
511
1451
  * Per WCAG 2: Y = 0.2126·R + 0.7152·G + 0.0722·B
@@ -518,44 +1458,90 @@ declare function contrastRatioFromLuminance(yA: number, yB: number): number;
518
1458
  /**
519
1459
  * Convert OKHSL to gamma-encoded sRGB (clamped to 0–1).
520
1460
  */
521
- declare function okhslToSrgb(h: number, s: number, l: number): [number, number, number];
1461
+ declare function okhslToSrgb(h: number, s: number, l: number, pastel?: boolean): [number, number, number];
522
1462
  /**
523
1463
  * Compute WCAG 2 relative luminance from linear sRGB, matching the browser
524
1464
  * rendering pipeline: gamma-encode, clamp to sRGB gamut [0,1], then linearize.
525
1465
  * This avoids over/under-estimating luminance for out-of-gamut OKHSL colors.
526
1466
  */
527
1467
  declare function gamutClampedLuminance(linearRgb: [number, number, number]): number;
1468
+ /**
1469
+ * Convert OKLab to OKHSL.
1470
+ * Input: [L, a, b] where L: 0–1, a/b: roughly -0.5 to 0.5.
1471
+ * Returns [h, s, l] where h: 0–360, s: 0–1, l: 0–1.
1472
+ */
1473
+ declare const oklabToOkhsl: (lab: Vec3, pastel?: boolean) => Vec3;
528
1474
  /**
529
1475
  * Convert gamma-encoded sRGB (0–1 per channel) to OKHSL.
530
1476
  * Returns [h, s, l] where h: 0–360, s: 0–1, l: 0–1.
531
1477
  */
532
- declare function srgbToOkhsl(rgb: [number, number, number]): [number, number, number];
1478
+ declare function srgbToOkhsl(rgb: [number, number, number], pastel?: boolean): [number, number, number];
1479
+ /**
1480
+ * Convert CSS HSL (sRGB-based) to gamma-encoded sRGB [r, g, b] in 0–1 range.
1481
+ * h: 0–360, s: 0–1, l: 0–1.
1482
+ *
1483
+ * Note: CSS HSL is not the same as OKHSL — it's HSL in the sRGB color space.
1484
+ * Use this when parsing `hsl(...)` strings before passing to `srgbToOkhsl`.
1485
+ */
1486
+ declare function hslToSrgb(h: number, s: number, l: number): [number, number, number];
533
1487
  /**
534
1488
  * Parse a hex color string (#rgb or #rrggbb) to sRGB [r, g, b] in 0–1 range.
535
1489
  * Returns null if the string is not a valid hex color.
1490
+ *
1491
+ * For 8-digit hex (`#rrggbbaa`) and 4-digit hex (`#rgba`) with alpha,
1492
+ * use {@link parseHexAlpha}.
536
1493
  */
537
1494
  declare function parseHex(hex: string): [number, number, number] | null;
1495
+ /**
1496
+ * Parse a hex color string (#rgb, #rrggbb, #rgba, or #rrggbbaa) to
1497
+ * sRGB [r, g, b] in 0–1 range plus an optional alpha (0–1).
1498
+ * Returns null if the string is not a valid hex color.
1499
+ */
1500
+ declare function parseHexAlpha(hex: string): {
1501
+ rgb: [number, number, number];
1502
+ alpha?: number;
1503
+ } | null;
538
1504
  /**
539
1505
  * Format OKHSL values as a CSS `okhsl(H S% L%)` string.
540
1506
  * h: 0–360, s: 0–100, l: 0–100 (percentage scale for s and l).
541
1507
  */
542
- declare function formatOkhsl(h: number, s: number, l: number): string;
1508
+ declare function formatOkhsl(h: number, s: number, l: number, pastel?: boolean): string;
1509
+ /**
1510
+ * Format OKHST values as a CSS `okhst(H S% T%)` string.
1511
+ * h: 0–360, s: 0–100, t: 0–100 (percentage scale for s and t).
1512
+ *
1513
+ * Pastel recompute matches `formatOkhsl`: convert via OKLab so external
1514
+ * parsers that only understand non-pastel OKHST render identically.
1515
+ */
1516
+ declare function formatOkhst(h: number, s: number, t: number, pastel?: boolean): string;
543
1517
  /**
544
1518
  * Format OKHSL values as a CSS `rgb(R G B)` string.
545
1519
  * Uses 2 decimal places to avoid 8-bit quantization contrast loss.
546
1520
  * h: 0–360, s: 0–100, l: 0–100 (percentage scale for s and l).
547
1521
  */
548
- declare function formatRgb(h: number, s: number, l: number): string;
1522
+ declare function formatRgb(h: number, s: number, l: number, pastel?: boolean): string;
549
1523
  /**
550
1524
  * Format OKHSL values as a CSS `hsl(H S% L%)` string.
551
1525
  * h: 0–360, s: 0–100, l: 0–100 (percentage scale for s and l).
552
1526
  */
553
- declare function formatHsl(h: number, s: number, l: number): string;
1527
+ declare function formatHsl(h: number, s: number, l: number, pastel?: boolean): string;
554
1528
  /**
555
1529
  * Format OKHSL values as a CSS `oklch(L C H)` string.
556
1530
  * h: 0–360, s: 0–100, l: 0–100 (percentage scale for s and l).
557
1531
  */
558
- declare function formatOklch(h: number, s: number, l: number): string;
1532
+ declare function formatOklch(h: number, s: number, l: number, pastel?: boolean): string;
1533
+ /**
1534
+ * Convert gamma-encoded sRGB channels (0–1) to a 6-digit lowercase hex
1535
+ * string (`#rrggbb`). Channels are clamped to [0,1] and rounded to 8-bit.
1536
+ * Alpha is not encoded here — DTCG carries it as a separate `alpha` field.
1537
+ */
1538
+ declare function srgbToHex(rgb: [number, number, number]): `#${string}`;
1539
+ /**
1540
+ * Convert OKHSL (h: 0–360, s: 0–1, l: 0–1) to OKLCH components `[L, C, H]`.
1541
+ * L: 0–1, C: 0–~0.4 (chroma), H: 0–360 (hue). Shared by `formatOklch` and
1542
+ * the DTCG `oklch` colorSpace exporter so the two never drift apart.
1543
+ */
1544
+ declare function okhslToOklch(h: number, s: number, l: number, pastel?: boolean): [number, number, number];
559
1545
  //#endregion
560
- export { type AdaptationMode, type ColorDef, type ColorMap, type ContrastPreset, type FindLightnessForContrastOptions, type FindLightnessForContrastResult, type FindValueForMixContrastOptions, type FindValueForMixContrastResult, type GlazeColorFormat, type GlazeColorInput, type GlazeColorToken, type GlazeConfig, type GlazeCssOptions, type GlazeCssResult, type GlazeExtendOptions, type GlazeJsonOptions, type GlazeOutputModes, type GlazePalette, type GlazePaletteExportOptions, type GlazePaletteOptions, type GlazeShadowInput, type GlazeTheme, type GlazeThemeExport, type GlazeTokenOptions, type HCPair, type HexColor, type MinContrast, type MixColorDef, type OkhslColor, type RegularColorDef, type RelativeValue, type ResolvedColor, type ResolvedColorVariant, type ShadowColorDef, type ShadowTuning, contrastRatioFromLuminance, findLightnessForContrast, findValueForMixContrast, formatHsl, formatOkhsl, formatOklch, formatRgb, gamutClampedLuminance, glaze, okhslToLinearSrgb, okhslToOklab, okhslToSrgb, parseHex, relativeLuminanceFromLinearRgb, resolveMinContrast, srgbToOkhsl };
1546
+ export { type AdaptationMode, type ApcaPreset, type ChannelCtx, type ColorDef, type ColorMap, type ContrastPreset, type ContrastSpec, type DtcgColorSpace, type DtcgColorToken, type DtcgColorValue, type DtcgDocument, type DtcgOklchColorValue, type DtcgResolverModifier, type DtcgResolverRef, type DtcgResolverSet, type DtcgSrgbColorValue, type DtcgTokenTree, type ExtremeValue, type FindToneForContrastOptions, type FindToneForContrastResult, type FindValueForMixContrastOptions, type FindValueForMixContrastResult, type GlazeColorCssOptions, type GlazeColorDtcgResolverOptions, type GlazeColorDtcgResult, type GlazeColorFormat, type GlazeColorInput, type GlazeColorInputExport, type GlazeColorOverrides, type GlazeColorOverridesExport, type GlazeColorTailwindOptions, type GlazeColorToken, type GlazeColorTokenExport, type GlazeColorValue, type GlazeConfig, type GlazeConfigOverride, type GlazeConfigResolved, type GlazeCssOptions, type GlazeCssResult, type GlazeDtcgOptions, type GlazeDtcgResolverContextNames, type GlazeDtcgResolverDocument, type GlazeDtcgResolverOptions, type GlazeDtcgResult, type GlazeExtendOptions, type GlazeFromInput, type GlazeJsonOptions, type GlazeOutputModes, type GlazePalette, type GlazePaletteExportOptions, type GlazePaletteOptions, type GlazeShadowInput, type GlazeTailwindOptions, type GlazeTheme, type GlazeThemeExport, type GlazeTokenOptions, type HCPair, type HexColor, type HueDeclaration, type HuePlan, type MinContrast, type MixColorDef, type OkhslColor, type OkhstColor, type OklchColor, type Polarity, REF_EPS, type RegularColorDef, type RelativeValue, type ResolvedColor, type ResolvedColorVariant, type ResolvedContrast, type RgbColor, type Role, type RoleInput, type ShadowColorDef, type ShadowTuning, type ToneValue, type ToneWindow, apcaContrast, assertAllPastel, assertNativeFormat, contrastRatioFromLuminance, cuspLightness, findToneForContrast, findValueForMixContrast, formatHsl, formatOkhsl, formatOkhst, formatOklch, formatRgb, fromTone, gamutClampedLuminance, glaze, hslToSrgb, inferRoleFromName, normalizeRole, okhslToLinearSrgb, okhslToOkhst, okhslToOklab, okhslToOklch, okhslToSrgb, okhstToOkhsl, oklabToOkhsl, oppositeRole, parseHex, parseHexAlpha, relativeLuminanceFromLinearRgb, resolveApcaTarget, resolveContrastForMode, resolveMinContrast, roleToPolarity, srgbToHex, srgbToOkhsl, toTone, toneFromY, variantToOkhsl, yFromTone };
561
1547
  //# sourceMappingURL=index.d.cts.map