@tenphi/glaze 0.14.0 → 0.15.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.mjs CHANGED
@@ -256,10 +256,48 @@ const getCs = (L, a, b, cusp) => {
256
256
  cMax
257
257
  ];
258
258
  };
259
+ const CYAN_A = Math.cos(199.8 * Math.PI / 180);
260
+ const CYAN_B = Math.sin(199.8 * Math.PI / 180);
261
+ const BLUE_A = Math.cos(267.4 * Math.PI / 180);
262
+ const BLUE_B = Math.sin(267.4 * Math.PI / 180);
263
+ let cyanCusp;
264
+ let blueCusp;
265
+ /**
266
+ * Computes the maximum safe OKLCH chroma that fits inside the sRGB gamut
267
+ * for all possible hues at a given OKLab lightness `L`.
268
+ */
269
+ function computeSafeChromaOKLCH(L) {
270
+ if (!cyanCusp) cyanCusp = findCuspOKLCH(CYAN_A, CYAN_B);
271
+ if (!blueCusp) blueCusp = findCuspOKLCH(BLUE_A, BLUE_B);
272
+ const c1 = findGamutIntersectionOKLCH(CYAN_A, CYAN_B, L, 1, L, cyanCusp);
273
+ const c2 = findGamutIntersectionOKLCH(BLUE_A, BLUE_B, L, 1, L, blueCusp);
274
+ return Math.min(c1, c2);
275
+ }
276
+ /** Per-hue cusp-lightness cache. The cusp is mode-independent, so keying on
277
+ * a rounded hue is safe and keeps the cache small. */
278
+ const cuspLightnessCache = /* @__PURE__ */ new Map();
279
+ /**
280
+ * OKHSL lightness of the gamut cusp for a hue — the lightness where the
281
+ * realizable chroma peaks. Reuses the same `find_cusp` OKHSL already runs for
282
+ * its `s` normalization (no new color math); the OKLab cusp lightness is run
283
+ * through the OKHSL `toe` and clamped to `[0.001, 0.999]` so divisions that
284
+ * key off it stay safe. Cached per (rounded) hue.
285
+ *
286
+ * @param h Hue, 0–360.
287
+ */
288
+ function cuspLightness(h) {
289
+ const key = Math.round(constrainAngle(h) * 100) / 100;
290
+ const cached = cuspLightnessCache.get(key);
291
+ if (cached !== void 0) return cached;
292
+ const hNorm = key / 360;
293
+ const lc = clampVal(toe(findCuspOKLCH(Math.cos(TAU * hNorm), Math.sin(TAU * hNorm))[0]), .001, .999);
294
+ cuspLightnessCache.set(key, lc);
295
+ return lc;
296
+ }
259
297
  /**
260
298
  * Convert OKHSL (h: 0–360, s: 0–1, l: 0–1) to OKLab [L, a, b].
261
299
  */
262
- function okhslToOklab(h, s, l) {
300
+ function okhslToOklab(h, s, l, pastel = false) {
263
301
  const L = toeInv(l);
264
302
  let a = 0;
265
303
  let b = 0;
@@ -267,24 +305,30 @@ function okhslToOklab(h, s, l) {
267
305
  if (L !== 0 && L !== 1 && s !== 0) {
268
306
  const a_ = Math.cos(TAU * hNorm);
269
307
  const b_ = Math.sin(TAU * hNorm);
270
- const [c0, cMid, cMax] = getCs(L, a_, b_, findCuspOKLCH(a_, b_));
271
- const mid = .8;
272
- const midInv = 1.25;
273
- let t, k0, k1, k2;
274
- if (s < mid) {
275
- t = midInv * s;
276
- k0 = 0;
277
- k1 = mid * c0;
278
- k2 = 1 - k1 / cMid;
308
+ if (pastel) {
309
+ const c = s * computeSafeChromaOKLCH(L);
310
+ a = c * a_;
311
+ b = c * b_;
279
312
  } else {
280
- t = 5 * (s - .8);
281
- k0 = cMid;
282
- k1 = .2 * cMid ** 2 * 1.25 ** 2 / c0;
283
- k2 = 1 - k1 / (cMax - cMid);
313
+ const [c0, cMid, cMax] = getCs(L, a_, b_, findCuspOKLCH(a_, b_));
314
+ const mid = .8;
315
+ const midInv = 1.25;
316
+ let t, k0, k1, k2;
317
+ if (s < mid) {
318
+ t = midInv * s;
319
+ k0 = 0;
320
+ k1 = mid * c0;
321
+ k2 = 1 - k1 / cMid;
322
+ } else {
323
+ t = 5 * (s - .8);
324
+ k0 = cMid;
325
+ k1 = .2 * cMid ** 2 * 1.25 ** 2 / c0;
326
+ k2 = 1 - k1 / (cMax - cMid);
327
+ }
328
+ const c = k0 + t * k1 / (1 - k2 * t);
329
+ a = c * a_;
330
+ b = c * b_;
284
331
  }
285
- const c = k0 + t * k1 / (1 - k2 * t);
286
- a = c * a_;
287
- b = c * b_;
288
332
  }
289
333
  return [
290
334
  L,
@@ -296,8 +340,8 @@ function okhslToOklab(h, s, l) {
296
340
  * Convert OKHSL (h: 0–360, s: 0–1, l: 0–1) to linear sRGB.
297
341
  * Channels may exceed [0, 1] near gamut boundaries — caller must clamp if needed.
298
342
  */
299
- function okhslToLinearSrgb(h, s, l) {
300
- return OKLabToLinearSRGB(okhslToOklab(h, s, l));
343
+ function okhslToLinearSrgb(h, s, l, pastel = false) {
344
+ return OKLabToLinearSRGB(okhslToOklab(h, s, l, pastel));
301
345
  }
302
346
  /**
303
347
  * Compute relative luminance Y from linear sRGB channels.
@@ -327,8 +371,8 @@ const sRGBGammaToLinear = (val) => {
327
371
  /**
328
372
  * Convert OKHSL to gamma-encoded sRGB (clamped to 0–1).
329
373
  */
330
- function okhslToSrgb(h, s, l) {
331
- const lin = okhslToLinearSrgb(h, s, l);
374
+ function okhslToSrgb(h, s, l, pastel = false) {
375
+ const lin = okhslToLinearSrgb(h, s, l, pastel);
332
376
  return [
333
377
  Math.max(0, Math.min(1, sRGBLinearToGamma(lin[0]))),
334
378
  Math.max(0, Math.min(1, sRGBLinearToGamma(lin[1]))),
@@ -370,7 +414,7 @@ const linearSrgbToOklab = (rgb) => {
370
414
  * Input: [L, a, b] where L: 0–1, a/b: roughly -0.5 to 0.5.
371
415
  * Returns [h, s, l] where h: 0–360, s: 0–1, l: 0–1.
372
416
  */
373
- const oklabToOkhsl = (lab) => {
417
+ const oklabToOkhsl = (lab, pastel = false) => {
374
418
  const L = lab[0];
375
419
  const a = lab[1];
376
420
  const b = lab[2];
@@ -390,19 +434,22 @@ const oklabToOkhsl = (lab) => {
390
434
  const b_ = b / C;
391
435
  let h = Math.atan2(b, a) * (180 / Math.PI);
392
436
  h = constrainAngle(h);
393
- const [c0, cMid, cMax] = getCs(L, a_, b_, findCuspOKLCH(a_, b_));
394
- const mid = .8;
395
- const midInv = 1.25;
396
437
  let s;
397
- if (C < cMid) {
398
- const k1 = mid * c0;
399
- s = C / (k1 + C * (1 - k1 / cMid)) / midInv;
400
- } else {
401
- const k0 = cMid;
402
- const k1 = .2 * cMid ** 2 * 1.25 ** 2 / c0;
403
- const k2 = 1 - k1 / (cMax - cMid);
404
- const cDiff = C - k0;
405
- s = mid + cDiff / (k1 + cDiff * k2) / 5;
438
+ if (pastel) s = C / computeSafeChromaOKLCH(L);
439
+ else {
440
+ const [c0, cMid, cMax] = getCs(L, a_, b_, findCuspOKLCH(a_, b_));
441
+ const mid = .8;
442
+ const midInv = 1.25;
443
+ if (C < cMid) {
444
+ const k1 = mid * c0;
445
+ s = C / (k1 + C * (1 - k1 / cMid)) / midInv;
446
+ } else {
447
+ const k0 = cMid;
448
+ const k1 = .2 * cMid ** 2 * 1.25 ** 2 / c0;
449
+ const k2 = 1 - k1 / (cMax - cMid);
450
+ const cDiff = C - k0;
451
+ s = mid + cDiff / (k1 + cDiff * k2) / 5;
452
+ }
406
453
  }
407
454
  const l = toe(L);
408
455
  return [
@@ -415,12 +462,12 @@ const oklabToOkhsl = (lab) => {
415
462
  * Convert gamma-encoded sRGB (0–1 per channel) to OKHSL.
416
463
  * Returns [h, s, l] where h: 0–360, s: 0–1, l: 0–1.
417
464
  */
418
- function srgbToOkhsl(rgb) {
465
+ function srgbToOkhsl(rgb, pastel = false) {
419
466
  return oklabToOkhsl(linearSrgbToOklab([
420
467
  sRGBGammaToLinear(rgb[0]),
421
468
  sRGBGammaToLinear(rgb[1]),
422
469
  sRGBGammaToLinear(rgb[2])
423
- ]));
470
+ ]), pastel);
424
471
  }
425
472
  /**
426
473
  * Convert CSS HSL (sRGB-based) to gamma-encoded sRGB [r, g, b] in 0–1 range.
@@ -535,24 +582,26 @@ function fmt$1(value, decimals) {
535
582
  * Format OKHSL values as a CSS `okhsl(H S% L%)` string.
536
583
  * h: 0–360, s: 0–100, l: 0–100 (percentage scale for s and l).
537
584
  */
538
- function formatOkhsl(h, s, l) {
539
- return `okhsl(${fmt$1(h, 2)} ${fmt$1(s, 2)}% ${fmt$1(l, 2)}%)`;
585
+ function formatOkhsl(h, s, l, pastel = false) {
586
+ let outS = s;
587
+ if (pastel) outS = oklabToOkhsl(okhslToOklab(h, s / 100, l / 100, true), false)[1] * 100;
588
+ return `okhsl(${fmt$1(h, 2)} ${fmt$1(outS, 2)}% ${fmt$1(l, 2)}%)`;
540
589
  }
541
590
  /**
542
591
  * Format OKHSL values as a CSS `rgb(R G B)` string.
543
592
  * Uses 2 decimal places to avoid 8-bit quantization contrast loss.
544
593
  * h: 0–360, s: 0–100, l: 0–100 (percentage scale for s and l).
545
594
  */
546
- function formatRgb(h, s, l) {
547
- const [r, g, b] = okhslToSrgb(h, s / 100, l / 100);
595
+ function formatRgb(h, s, l, pastel = false) {
596
+ const [r, g, b] = okhslToSrgb(h, s / 100, l / 100, pastel);
548
597
  return `rgb(${parseFloat((r * 255).toFixed(2))} ${parseFloat((g * 255).toFixed(2))} ${parseFloat((b * 255).toFixed(2))})`;
549
598
  }
550
599
  /**
551
600
  * Format OKHSL values as a CSS `hsl(H S% L%)` string.
552
601
  * h: 0–360, s: 0–100, l: 0–100 (percentage scale for s and l).
553
602
  */
554
- function formatHsl(h, s, l) {
555
- const [r, g, b] = okhslToSrgb(h, s / 100, l / 100);
603
+ function formatHsl(h, s, l, pastel = false) {
604
+ const [r, g, b] = okhslToSrgb(h, s / 100, l / 100, pastel);
556
605
  const max = Math.max(r, g, b);
557
606
  const min = Math.min(r, g, b);
558
607
  const delta = max - min;
@@ -571,8 +620,8 @@ function formatHsl(h, s, l) {
571
620
  * Format OKHSL values as a CSS `oklch(L C H)` string.
572
621
  * h: 0–360, s: 0–100, l: 0–100 (percentage scale for s and l).
573
622
  */
574
- function formatOklch(h, s, l) {
575
- const [L, a, b] = okhslToOklab(h, s / 100, l / 100);
623
+ function formatOklch(h, s, l, pastel = false) {
624
+ const [L, a, b] = okhslToOklab(h, s / 100, l / 100, pastel);
576
625
  const C = Math.sqrt(a * a + b * b);
577
626
  let hh = Math.atan2(b, a) * (180 / Math.PI);
578
627
  hh = constrainAngle(hh);
@@ -598,7 +647,6 @@ function defaultConfig() {
598
647
  eps: .05
599
648
  },
600
649
  darkDesaturation: .1,
601
- saturationTaper: .15,
602
650
  states: {
603
651
  dark: "@dark",
604
652
  highContrast: "@high-contrast"
@@ -607,7 +655,8 @@ function defaultConfig() {
607
655
  dark: true,
608
656
  highContrast: false
609
657
  },
610
- autoFlip: true
658
+ autoFlip: true,
659
+ pastel: false
611
660
  };
612
661
  }
613
662
  let globalConfig = defaultConfig();
@@ -637,7 +686,6 @@ function configure(config) {
637
686
  lightTone: config.lightTone ?? globalConfig.lightTone,
638
687
  darkTone: config.darkTone ?? globalConfig.darkTone,
639
688
  darkDesaturation: config.darkDesaturation ?? globalConfig.darkDesaturation,
640
- saturationTaper: config.saturationTaper ?? globalConfig.saturationTaper,
641
689
  states: {
642
690
  dark: config.states?.dark ?? globalConfig.states.dark,
643
691
  highContrast: config.states?.highContrast ?? globalConfig.states.highContrast
@@ -647,7 +695,8 @@ function configure(config) {
647
695
  highContrast: config.modes?.highContrast ?? globalConfig.modes.highContrast
648
696
  },
649
697
  shadowTuning: config.shadowTuning ?? globalConfig.shadowTuning,
650
- autoFlip: config.autoFlip ?? globalConfig.autoFlip
698
+ autoFlip: config.autoFlip ?? globalConfig.autoFlip,
699
+ pastel: config.pastel ?? globalConfig.pastel
651
700
  };
652
701
  }
653
702
  function resetConfig() {
@@ -666,11 +715,11 @@ function mergeConfig(base, override) {
666
715
  lightTone: override.lightTone !== void 0 ? override.lightTone : base.lightTone,
667
716
  darkTone: override.darkTone !== void 0 ? override.darkTone : base.darkTone,
668
717
  darkDesaturation: override.darkDesaturation ?? base.darkDesaturation,
669
- saturationTaper: override.saturationTaper ?? base.saturationTaper,
670
718
  states: base.states,
671
719
  modes: base.modes,
672
720
  shadowTuning: override.shadowTuning ?? base.shadowTuning,
673
- autoFlip: override.autoFlip ?? base.autoFlip
721
+ autoFlip: override.autoFlip ?? base.autoFlip,
722
+ pastel: override.pastel ?? base.pastel
674
723
  };
675
724
  }
676
725
 
@@ -763,8 +812,8 @@ function isAbsoluteTone(tone) {
763
812
  * - the `{ h, s, t }` <-> `{ h, s, l }` color-space converters,
764
813
  * - the resolved-variant edge adapter (`variantToOkhsl`),
765
814
  * - the per-scheme tone mapping that replaced the Möbius dark curve
766
- * (`mapToneForScheme`), the saturation reducers, and the solver's
767
- * scheme tone range.
815
+ * (`mapToneForScheme`), the dark desaturation reducer, and the solver's scheme
816
+ * tone range.
768
817
  *
769
818
  * See `docs/okhst.md` for the full specification and the calibrated
770
819
  * default constants.
@@ -907,33 +956,6 @@ function mapSaturationDark(s, mode, config) {
907
956
  if (mode === "static") return s;
908
957
  return s * (1 - config.darkDesaturation);
909
958
  }
910
- /** Smoothstep `0..1`. */
911
- function smoothstep(x) {
912
- const t = clamp(x, 0, 1);
913
- return t * t * (3 - 2 * t);
914
- }
915
- /** Fraction of the tone range over which the taper ramps in, per end. */
916
- const TAPER_REGION = .15;
917
- /**
918
- * Gently taper saturation toward the tone extremes, where in-gamut chroma
919
- * collapses and high saturation reads as noise. `taper` is the *strength*
920
- * (0–1): the maximum fraction of saturation removed at the very edges. The
921
- * rolloff ramps in smoothly over the outer {@link TAPER_REGION} of tone on
922
- * each end, so mid-tones are untouched and high-tone surfaces keep most of
923
- * their color. `taper = 0` disables the effect.
924
- *
925
- * @param s Saturation (0–1).
926
- * @param toneFinal Stored canonical tone (0–1).
927
- * @param taper Strength (0–1); default config is a gentle 0.15.
928
- */
929
- function saturationEnvelope(s, toneFinal, taper) {
930
- if (taper <= 0) return s;
931
- const t = clamp(toneFinal, 0, 1);
932
- const strength = clamp(taper, 0, 1);
933
- const edge = Math.min(t, 1 - t);
934
- if (edge >= TAPER_REGION) return s;
935
- return s * (1 - strength * (1 - smoothstep(edge / TAPER_REGION)));
936
- }
937
959
  /**
938
960
  * Tone search range (0–1) for the contrast solver in a given scheme.
939
961
  * `static` searches the full range; otherwise the scheme window's tone
@@ -1038,12 +1060,12 @@ const cacheOrder = [];
1038
1060
  * the metric's luminance basis. The metric is part of the cache key because
1039
1061
  * WCAG and APCA derive different luminances from the same color.
1040
1062
  */
1041
- function cachedLuminance(metric, h, s, t) {
1063
+ function cachedLuminance(metric, h, s, t, pastel) {
1042
1064
  const tRounded = Math.round(t * 1e4) / 1e4;
1043
- const key = `${metric}|${h}|${s}|${tRounded}`;
1065
+ const key = `${metric}|${h}|${s}|${tRounded}|${pastel}`;
1044
1066
  const cached = luminanceCache.get(key);
1045
1067
  if (cached !== void 0) return cached;
1046
- const y = metricLuminance(metric, okhslToLinearSrgb(h, s, fromTone(tRounded * 100, REF_EPS)));
1068
+ const y = metricLuminance(metric, okhslToLinearSrgb(h, s, fromTone(tRounded * 100, REF_EPS), pastel));
1047
1069
  if (luminanceCache.size >= CACHE_SIZE) {
1048
1070
  const evict = cacheOrder.shift();
1049
1071
  luminanceCache.delete(evict);
@@ -1174,14 +1196,11 @@ function solveNearestContrast(opts) {
1174
1196
  * staying as close to `preferredTone` as possible.
1175
1197
  */
1176
1198
  function findToneForContrast(options) {
1177
- const { hue, saturation, preferredTone, baseLinearRgb, contrast, toneRange = [0, 1], epsilon = 1e-4, maxIterations = 18 } = options;
1199
+ const { hue, saturation, preferredTone, baseLinearRgb, contrast, toneRange = [0, 1], epsilon = 1e-4, maxIterations = 18, pastel = false } = options;
1178
1200
  const { metric, target } = contrast;
1179
1201
  const searchTarget = metric === "wcag" ? target * 1.01 : target + .5;
1180
1202
  const yBase = metricLuminance(metric, baseLinearRgb);
1181
- const taper = options.saturationTaper ?? 0;
1182
- const lum = taper > 0 ? (t) => {
1183
- return metricLuminance(metric, okhslToLinearSrgb(hue, saturationEnvelope(saturation, t, taper), fromTone(t * 100, REF_EPS)));
1184
- } : (t) => cachedLuminance(metric, hue, saturation, t);
1203
+ const lum = (t) => cachedLuminance(metric, hue, saturation, t, pastel);
1185
1204
  const scorePref = metricScore(metric, lum(preferredTone), yBase);
1186
1205
  if (scorePref >= searchTarget) return {
1187
1206
  tone: preferredTone,
@@ -1520,7 +1539,8 @@ function toOkhslVariant(v) {
1520
1539
  h: c.h,
1521
1540
  s: c.s,
1522
1541
  l: c.l,
1523
- alpha: v.alpha
1542
+ alpha: v.alpha,
1543
+ pastel: v.pastel
1524
1544
  };
1525
1545
  }
1526
1546
  /** Edge adapter: OKHSL-lightness variant → resolved variant (`t`). */
@@ -1567,6 +1587,7 @@ function resolveDependentColor(name, def, ctx, isHighContrast, isDark, effective
1567
1587
  const mode = def.mode ?? "auto";
1568
1588
  const satFactor = clamp(def.saturation ?? 1, 0, 1);
1569
1589
  const flip = def.flip ?? ctx.config.autoFlip;
1590
+ const pastel = def.pastel ?? ctx.config.pastel;
1570
1591
  const baseVariant = getSchemeVariant(baseResolved, isDark, isHighContrast);
1571
1592
  const baseTone = baseVariant.t * 100;
1572
1593
  let preferredTone;
@@ -1585,7 +1606,7 @@ function resolveDependentColor(name, def, ctx, isHighContrast, isDark, effective
1585
1606
  const resolvedContrast = resolveContrastSpec(rawContrast, isHighContrast);
1586
1607
  const effectiveSat = isDark ? mapSaturationDark(satFactor * ctx.saturation / 100, mode, ctx.config) : satFactor * ctx.saturation / 100;
1587
1608
  const baseOkhsl = toOkhslVariant(baseVariant);
1588
- const baseLinearRgb = okhslToLinearSrgb(baseOkhsl.h, baseOkhsl.s, baseOkhsl.l);
1609
+ const baseLinearRgb = okhslToLinearSrgb(baseOkhsl.h, baseOkhsl.s, baseOkhsl.l, baseVariant.pastel ?? ctx.config.pastel);
1589
1610
  const toneRange = schemeToneRange(isDark, mode, isHighContrast, ctx.config);
1590
1611
  let initialDirection;
1591
1612
  if (preferredTone < baseTone) initialDirection = "darker";
@@ -1599,7 +1620,7 @@ function resolveDependentColor(name, def, ctx, isHighContrast, isDark, effective
1599
1620
  toneRange: [0, 1],
1600
1621
  initialDirection,
1601
1622
  flip,
1602
- saturationTaper: ctx.config.saturationTaper
1623
+ pastel
1603
1624
  });
1604
1625
  if (!result.met) warnContrastUnmet(name, isDark, isHighContrast, resolvedContrast, result.contrast);
1605
1626
  return {
@@ -1619,6 +1640,7 @@ function resolveColorForScheme(name, def, ctx, isDark, isHighContrast) {
1619
1640
  const mode = regDef.mode ?? "auto";
1620
1641
  const isRoot = isAbsoluteTone(regDef.tone) && !regDef.base;
1621
1642
  const effectiveHue = resolveEffectiveHue(ctx.hue, regDef.hue);
1643
+ const pastel = regDef.pastel ?? ctx.config.pastel;
1622
1644
  let finalTone;
1623
1645
  let satFactor;
1624
1646
  if (isRoot) {
@@ -1631,14 +1653,14 @@ function resolveColorForScheme(name, def, ctx, isDark, isHighContrast) {
1631
1653
  satFactor = dep.satFactor;
1632
1654
  }
1633
1655
  const baseSat = satFactor * ctx.saturation / 100;
1634
- let finalSat = isDark ? mapSaturationDark(baseSat, mode, ctx.config) : baseSat;
1656
+ const finalSat = isDark ? mapSaturationDark(baseSat, mode, ctx.config) : baseSat;
1635
1657
  const toneFraction = clamp(finalTone / 100, 0, 1);
1636
- finalSat = saturationEnvelope(finalSat, toneFraction, ctx.config.saturationTaper);
1637
1658
  return {
1638
1659
  h: effectiveHue,
1639
1660
  s: clamp(finalSat, 0, 1),
1640
1661
  t: toneFraction,
1641
- alpha: regDef.opacity ?? 1
1662
+ alpha: regDef.opacity ?? 1,
1663
+ pastel
1642
1664
  };
1643
1665
  }
1644
1666
  function resolveShadowForScheme(def, ctx, isDark, isHighContrast) {
@@ -1647,10 +1669,13 @@ function resolveShadowForScheme(def, ctx, isDark, isHighContrast) {
1647
1669
  if (def.fg) fgVariant = toOkhslVariant(getSchemeVariant(ctx.resolved.get(def.fg), isDark, isHighContrast));
1648
1670
  const intensity = isHighContrast ? pairHC(def.intensity) : pairNormal(def.intensity);
1649
1671
  const tuning = resolveShadowTuning(def.tuning, ctx.config.shadowTuning);
1650
- return toToneVariant(computeShadow(bgVariant, fgVariant, intensity, tuning));
1672
+ return {
1673
+ ...toToneVariant(computeShadow(bgVariant, fgVariant, intensity, tuning)),
1674
+ pastel: def.pastel ?? ctx.config.pastel
1675
+ };
1651
1676
  }
1652
- function okhslVariantToLinearRgb(v) {
1653
- return okhslToLinearSrgb(v.h, v.s, v.l);
1677
+ function okhslVariantToLinearRgb(v, pastel) {
1678
+ return okhslToLinearSrgb(v.h, v.s, v.l, pastel);
1654
1679
  }
1655
1680
  /**
1656
1681
  * Resolve hue for OKHSL mixing, handling achromatic colors.
@@ -1673,12 +1698,12 @@ function linearSrgbLerp(base, target, t) {
1673
1698
  base[2] + (target[2] - base[2]) * t
1674
1699
  ];
1675
1700
  }
1676
- function linearRgbToToneVariant(rgb) {
1701
+ function linearRgbToToneVariant(rgb, pastel) {
1677
1702
  const [h, s, l] = srgbToOkhsl([
1678
1703
  Math.max(0, Math.min(1, sRGBLinearToGamma(rgb[0]))),
1679
1704
  Math.max(0, Math.min(1, sRGBLinearToGamma(rgb[1]))),
1680
1705
  Math.max(0, Math.min(1, sRGBLinearToGamma(rgb[2])))
1681
- ]);
1706
+ ], pastel);
1682
1707
  return toToneVariant({
1683
1708
  h,
1684
1709
  s,
@@ -1694,15 +1719,16 @@ function resolveMixForScheme(def, ctx, isDark, isHighContrast) {
1694
1719
  let t = clamp(isHighContrast ? pairHC(def.value) : pairNormal(def.value), 0, 100) / 100;
1695
1720
  const blend = def.blend ?? "opaque";
1696
1721
  const space = def.space ?? "okhsl";
1697
- const baseLinear = okhslVariantToLinearRgb(baseVariant);
1698
- const targetLinear = okhslVariantToLinearRgb(targetVariant);
1722
+ const pastel = def.pastel ?? ctx.config.pastel;
1723
+ const baseLinear = okhslVariantToLinearRgb(baseVariant, baseVariant.pastel ?? ctx.config.pastel);
1724
+ const targetLinear = okhslVariantToLinearRgb(targetVariant, targetVariant.pastel ?? ctx.config.pastel);
1699
1725
  if (def.contrast !== void 0) {
1700
1726
  const resolvedContrast = resolveContrastSpec(def.contrast, isHighContrast);
1701
1727
  const metric = resolvedContrast.metric;
1702
1728
  let luminanceAt;
1703
1729
  if (blend === "transparent" || space === "srgb") luminanceAt = (v) => metricLuminance(metric, linearSrgbLerp(baseLinear, targetLinear, v));
1704
1730
  else luminanceAt = (v) => {
1705
- return metricLuminance(metric, okhslToLinearSrgb(mixHue(baseVariant, targetVariant, v), baseVariant.s + (targetVariant.s - baseVariant.s) * v, baseVariant.l + (targetVariant.l - baseVariant.l) * v));
1731
+ return metricLuminance(metric, okhslToLinearSrgb(mixHue(baseVariant, targetVariant, v), baseVariant.s + (targetVariant.s - baseVariant.s) * v, baseVariant.l + (targetVariant.l - baseVariant.l) * v, pastel));
1706
1732
  };
1707
1733
  t = findValueForMixContrast({
1708
1734
  preferredValue: t,
@@ -1713,19 +1739,28 @@ function resolveMixForScheme(def, ctx, isDark, isHighContrast) {
1713
1739
  flip: ctx.config.autoFlip
1714
1740
  }).value;
1715
1741
  }
1716
- if (blend === "transparent") return toToneVariant({
1717
- h: targetVariant.h,
1718
- s: targetVariant.s,
1719
- l: targetVariant.l,
1720
- alpha: clamp(t, 0, 1)
1721
- });
1722
- if (space === "srgb") return linearRgbToToneVariant(linearSrgbLerp(baseLinear, targetLinear, t));
1723
- return toToneVariant({
1724
- h: mixHue(baseVariant, targetVariant, t),
1725
- s: clamp(baseVariant.s + (targetVariant.s - baseVariant.s) * t, 0, 1),
1726
- l: clamp(baseVariant.l + (targetVariant.l - baseVariant.l) * t, 0, 1),
1727
- alpha: 1
1728
- });
1742
+ if (blend === "transparent") return {
1743
+ ...toToneVariant({
1744
+ h: targetVariant.h,
1745
+ s: targetVariant.s,
1746
+ l: targetVariant.l,
1747
+ alpha: clamp(t, 0, 1)
1748
+ }),
1749
+ pastel
1750
+ };
1751
+ if (space === "srgb") return {
1752
+ ...linearRgbToToneVariant(linearSrgbLerp(baseLinear, targetLinear, t), pastel),
1753
+ pastel
1754
+ };
1755
+ return {
1756
+ ...toToneVariant({
1757
+ h: mixHue(baseVariant, targetVariant, t),
1758
+ s: clamp(baseVariant.s + (targetVariant.s - baseVariant.s) * t, 0, 1),
1759
+ l: clamp(baseVariant.l + (targetVariant.l - baseVariant.l) * t, 0, 1),
1760
+ alpha: 1
1761
+ }),
1762
+ pastel
1763
+ };
1729
1764
  }
1730
1765
  function defMode(def) {
1731
1766
  if (isShadowDef(def) || isMixDef(def)) return void 0;
@@ -1776,7 +1811,7 @@ function seedField(order, ctx, field, source) {
1776
1811
  * resolved with a `base` + `contrast` may land slightly under the contrast
1777
1812
  * its tone implies because chromatic luminance drifts from the gray tone.
1778
1813
  */
1779
- function verifyContrastDrift(order, defs, result) {
1814
+ function verifyContrastDrift(order, defs, result, config) {
1780
1815
  for (const name of order) {
1781
1816
  const def = defs[name];
1782
1817
  if (isShadowDef(def) || isMixDef(def)) continue;
@@ -1812,8 +1847,10 @@ function verifyContrastDrift(order, defs, result) {
1812
1847
  const bVariant = base[s.field];
1813
1848
  const cOkhsl = toOkhslVariant(cVariant);
1814
1849
  const bOkhsl = toOkhslVariant(bVariant);
1815
- const yC = metricLuminance(spec.metric, okhslToLinearSrgb(cOkhsl.h, cOkhsl.s, cOkhsl.l));
1816
- const yB = metricLuminance(spec.metric, okhslToLinearSrgb(bOkhsl.h, bOkhsl.s, bOkhsl.l));
1850
+ const cPastel = cVariant.pastel ?? config.pastel;
1851
+ const bPastel = bVariant.pastel ?? config.pastel;
1852
+ const yC = metricLuminance(spec.metric, okhslToLinearSrgb(cOkhsl.h, cOkhsl.s, cOkhsl.l, cPastel));
1853
+ const yB = metricLuminance(spec.metric, okhslToLinearSrgb(bOkhsl.h, bOkhsl.s, bOkhsl.l, bPastel));
1817
1854
  warnContrastDrift(name, s.isDark, s.isHighContrast, spec, yC, yB);
1818
1855
  }
1819
1856
  }
@@ -1846,7 +1883,7 @@ function resolveAllColors(hue, saturation, defs, config, externalBases) {
1846
1883
  darkContrast: darkHCMap.get(name),
1847
1884
  mode: defMode(defs[name])
1848
1885
  });
1849
- verifyContrastDrift(order, defs, result);
1886
+ verifyContrastDrift(order, defs, result, config);
1850
1887
  return result;
1851
1888
  }
1852
1889
 
@@ -1871,9 +1908,10 @@ const formatters = {
1871
1908
  function fmt(value, decimals) {
1872
1909
  return parseFloat(value.toFixed(decimals)).toString();
1873
1910
  }
1874
- function formatVariant(v, format = "okhsl") {
1911
+ function formatVariant(v, format = "okhsl", pastel = false) {
1912
+ const effectivePastel = v.pastel ?? pastel;
1875
1913
  const { l } = variantToOkhsl(v);
1876
- const base = formatters[format](v.h, v.s * 100, l * 100);
1914
+ const base = formatters[format](v.h, v.s * 100, l * 100, effectivePastel);
1877
1915
  if (v.alpha >= 1) return base;
1878
1916
  const closing = base.lastIndexOf(")");
1879
1917
  return `${base.slice(0, closing)} / ${fmt(v.alpha, 4)})`;
@@ -1885,44 +1923,44 @@ function resolveModes(override) {
1885
1923
  highContrast: override?.highContrast ?? cfg.modes.highContrast
1886
1924
  };
1887
1925
  }
1888
- function buildTokenMap(resolved, prefix, states, modes, format = "okhsl") {
1926
+ function buildTokenMap(resolved, prefix, states, modes, format = "okhsl", pastel = false) {
1889
1927
  const tokens = {};
1890
1928
  for (const [name, color] of resolved) {
1891
1929
  const key = `#${prefix}${name}`;
1892
- const entry = { "": formatVariant(color.light, format) };
1893
- if (modes.dark) entry[states.dark] = formatVariant(color.dark, format);
1894
- if (modes.highContrast) entry[states.highContrast] = formatVariant(color.lightContrast, format);
1895
- if (modes.dark && modes.highContrast) entry[`${states.dark} & ${states.highContrast}`] = formatVariant(color.darkContrast, format);
1930
+ const entry = { "": formatVariant(color.light, format, pastel) };
1931
+ if (modes.dark) entry[states.dark] = formatVariant(color.dark, format, pastel);
1932
+ if (modes.highContrast) entry[states.highContrast] = formatVariant(color.lightContrast, format, pastel);
1933
+ if (modes.dark && modes.highContrast) entry[`${states.dark} & ${states.highContrast}`] = formatVariant(color.darkContrast, format, pastel);
1896
1934
  tokens[key] = entry;
1897
1935
  }
1898
1936
  return tokens;
1899
1937
  }
1900
- function buildFlatTokenMap(resolved, prefix, modes, format = "okhsl") {
1938
+ function buildFlatTokenMap(resolved, prefix, modes, format = "okhsl", pastel = false) {
1901
1939
  const result = { light: {} };
1902
1940
  if (modes.dark) result.dark = {};
1903
1941
  if (modes.highContrast) result.lightContrast = {};
1904
1942
  if (modes.dark && modes.highContrast) result.darkContrast = {};
1905
1943
  for (const [name, color] of resolved) {
1906
1944
  const key = `${prefix}${name}`;
1907
- result.light[key] = formatVariant(color.light, format);
1908
- if (modes.dark) result.dark[key] = formatVariant(color.dark, format);
1909
- if (modes.highContrast) result.lightContrast[key] = formatVariant(color.lightContrast, format);
1910
- if (modes.dark && modes.highContrast) result.darkContrast[key] = formatVariant(color.darkContrast, format);
1945
+ result.light[key] = formatVariant(color.light, format, pastel);
1946
+ if (modes.dark) result.dark[key] = formatVariant(color.dark, format, pastel);
1947
+ if (modes.highContrast) result.lightContrast[key] = formatVariant(color.lightContrast, format, pastel);
1948
+ if (modes.dark && modes.highContrast) result.darkContrast[key] = formatVariant(color.darkContrast, format, pastel);
1911
1949
  }
1912
1950
  return result;
1913
1951
  }
1914
- function buildJsonMap(resolved, modes, format = "okhsl") {
1952
+ function buildJsonMap(resolved, modes, format = "okhsl", pastel = false) {
1915
1953
  const result = {};
1916
1954
  for (const [name, color] of resolved) {
1917
- const entry = { light: formatVariant(color.light, format) };
1918
- if (modes.dark) entry.dark = formatVariant(color.dark, format);
1919
- if (modes.highContrast) entry.lightContrast = formatVariant(color.lightContrast, format);
1920
- if (modes.dark && modes.highContrast) entry.darkContrast = formatVariant(color.darkContrast, format);
1955
+ const entry = { light: formatVariant(color.light, format, pastel) };
1956
+ if (modes.dark) entry.dark = formatVariant(color.dark, format, pastel);
1957
+ if (modes.highContrast) entry.lightContrast = formatVariant(color.lightContrast, format, pastel);
1958
+ if (modes.dark && modes.highContrast) entry.darkContrast = formatVariant(color.darkContrast, format, pastel);
1921
1959
  result[name] = entry;
1922
1960
  }
1923
1961
  return result;
1924
1962
  }
1925
- function buildCssMap(resolved, prefix, suffix, format) {
1963
+ function buildCssMap(resolved, prefix, suffix, format, pastel = false) {
1926
1964
  const lines = {
1927
1965
  light: [],
1928
1966
  dark: [],
@@ -1931,10 +1969,10 @@ function buildCssMap(resolved, prefix, suffix, format) {
1931
1969
  };
1932
1970
  for (const [name, color] of resolved) {
1933
1971
  const prop = `--${prefix}${name}${suffix}`;
1934
- lines.light.push(`${prop}: ${formatVariant(color.light, format)};`);
1935
- lines.dark.push(`${prop}: ${formatVariant(color.dark, format)};`);
1936
- lines.lightContrast.push(`${prop}: ${formatVariant(color.lightContrast, format)};`);
1937
- lines.darkContrast.push(`${prop}: ${formatVariant(color.darkContrast, format)};`);
1972
+ lines.light.push(`${prop}: ${formatVariant(color.light, format, pastel)};`);
1973
+ lines.dark.push(`${prop}: ${formatVariant(color.dark, format, pastel)};`);
1974
+ lines.lightContrast.push(`${prop}: ${formatVariant(color.lightContrast, format, pastel)};`);
1975
+ lines.darkContrast.push(`${prop}: ${formatVariant(color.darkContrast, format, pastel)};`);
1938
1976
  }
1939
1977
  return {
1940
1978
  light: lines.light.join("\n"),
@@ -1986,7 +2024,6 @@ function buildValueFormConfigOverride(userOverride) {
1986
2024
  lightTone: userOverride?.lightTone !== void 0 ? userOverride.lightTone : false,
1987
2025
  darkTone: userOverride?.darkTone !== void 0 ? userOverride.darkTone : cfg.darkTone,
1988
2026
  darkDesaturation: userOverride?.darkDesaturation ?? cfg.darkDesaturation,
1989
- saturationTaper: userOverride?.saturationTaper ?? cfg.saturationTaper,
1990
2027
  autoFlip: userOverride?.autoFlip ?? cfg.autoFlip,
1991
2028
  shadowTuning: userOverride?.shadowTuning ?? cfg.shadowTuning
1992
2029
  };
@@ -2003,7 +2040,6 @@ function buildStructuredConfigOverride(userOverride) {
2003
2040
  lightTone: userOverride?.lightTone !== void 0 ? userOverride.lightTone : cfg.lightTone,
2004
2041
  darkTone: userOverride?.darkTone !== void 0 ? userOverride.darkTone : cfg.darkTone,
2005
2042
  darkDesaturation: userOverride?.darkDesaturation ?? cfg.darkDesaturation,
2006
- saturationTaper: userOverride?.saturationTaper ?? cfg.saturationTaper,
2007
2043
  autoFlip: userOverride?.autoFlip ?? cfg.autoFlip,
2008
2044
  shadowTuning: userOverride?.shadowTuning ?? cfg.shadowTuning
2009
2045
  };
@@ -2288,6 +2324,7 @@ function buildStandaloneValueDefs(main, options) {
2288
2324
  mode: options?.mode ?? "auto",
2289
2325
  flip: options?.flip,
2290
2326
  opacity: options?.opacity,
2327
+ pastel: options?.pastel,
2291
2328
  base: hasExternalBase ? STANDALONE_BASE : needsSeedAnchor ? STANDALONE_SEED : void 0
2292
2329
  };
2293
2330
  const defs = { [primary]: valueDef };
@@ -2319,7 +2356,7 @@ function createColorTokenFromDefs(seedHue, seedSaturation, defs, primary, effect
2319
2356
  };
2320
2357
  };
2321
2358
  const tokenLike = (options) => {
2322
- return buildTokenMap(resolveOnce(), "", resolveStates(options), resolveModes(options?.modes), options?.format)[`#${primary}`];
2359
+ return buildTokenMap(resolveOnce(), "", resolveStates(options), resolveModes(options?.modes), options?.format, effectiveConfig.pastel)[`#${primary}`];
2323
2360
  };
2324
2361
  return {
2325
2362
  resolve() {
@@ -2328,10 +2365,10 @@ function createColorTokenFromDefs(seedHue, seedSaturation, defs, primary, effect
2328
2365
  token: tokenLike,
2329
2366
  tasty: tokenLike,
2330
2367
  json(options) {
2331
- return buildJsonMap(resolveOnce(), resolveModes(options?.modes), options?.format)[primary];
2368
+ return buildJsonMap(resolveOnce(), resolveModes(options?.modes), options?.format, effectiveConfig.pastel)[primary];
2332
2369
  },
2333
2370
  css(options) {
2334
- return buildCssMap(new Map([[options.name, resolveOnce().get(primary)]]), "", options.suffix ?? "-color", options.format ?? "rgb");
2371
+ return buildCssMap(new Map([[options.name, resolveOnce().get(primary)]]), "", options.suffix ?? "-color", options.format ?? "rgb", effectiveConfig.pastel);
2335
2372
  },
2336
2373
  export: exportData
2337
2374
  };
@@ -2388,6 +2425,7 @@ function createColorToken(input, configOverride) {
2388
2425
  flip: input.flip,
2389
2426
  contrast: input.contrast,
2390
2427
  opacity: input.opacity,
2428
+ pastel: input.pastel,
2391
2429
  base: hasExternalBase ? STANDALONE_BASE : needsSeedAnchor ? STANDALONE_SEED : void 0
2392
2430
  } };
2393
2431
  if (needsSeedAnchor) {
@@ -2437,6 +2475,7 @@ function buildOverridesExport(options) {
2437
2475
  if (options.contrast !== void 0) out.contrast = options.contrast;
2438
2476
  if (options.opacity !== void 0) out.opacity = options.opacity;
2439
2477
  if (options.name !== void 0) out.name = options.name;
2478
+ if (options.pastel !== void 0) out.pastel = options.pastel;
2440
2479
  if (options.base !== void 0) out.base = isGlazeColorToken(options.base) ? options.base.export() : options.base;
2441
2480
  return out;
2442
2481
  }
@@ -2452,6 +2491,7 @@ function buildStructuredInputExport(input) {
2452
2491
  if (input.opacity !== void 0) out.opacity = input.opacity;
2453
2492
  if (input.contrast !== void 0) out.contrast = input.contrast;
2454
2493
  if (input.name !== void 0) out.name = input.name;
2494
+ if (input.pastel !== void 0) out.pastel = input.pastel;
2455
2495
  if (input.base !== void 0) out.base = isGlazeColorToken(input.base) ? input.base.export() : input.base;
2456
2496
  return out;
2457
2497
  }
@@ -2472,6 +2512,7 @@ function rehydrateOverrides(data) {
2472
2512
  if (data.contrast !== void 0) out.contrast = data.contrast;
2473
2513
  if (data.opacity !== void 0) out.opacity = data.opacity;
2474
2514
  if (data.name !== void 0) out.name = data.name;
2515
+ if (data.pastel !== void 0) out.pastel = data.pastel;
2475
2516
  if (data.base !== void 0) out.base = isExportedToken(data.base) ? colorFromExport(data.base) : data.base;
2476
2517
  return out;
2477
2518
  }
@@ -2487,6 +2528,7 @@ function rehydrateStructuredInput(data) {
2487
2528
  if (data.opacity !== void 0) out.opacity = data.opacity;
2488
2529
  if (data.contrast !== void 0) out.contrast = data.contrast;
2489
2530
  if (data.name !== void 0) out.name = data.name;
2531
+ if (data.pastel !== void 0) out.pastel = data.pastel;
2490
2532
  if (data.base !== void 0) out.base = isExportedToken(data.base) ? colorFromExport(data.base) : data.base;
2491
2533
  return out;
2492
2534
  }
@@ -2571,9 +2613,10 @@ function buildPaletteOutput(themes, paletteOptions, options, buildOne, merge, em
2571
2613
  const seen = /* @__PURE__ */ new Map();
2572
2614
  for (const [themeName, theme] of Object.entries(themes)) {
2573
2615
  const resolved = theme.resolve();
2616
+ const pastel = theme.getConfig().pastel;
2574
2617
  const prefix = resolvePrefix(options, themeName, true);
2575
- merge(acc, buildOne(filterCollisions(resolved, prefix, seen, themeName), prefix));
2576
- if (themeName === effectivePrimary) merge(acc, buildOne(filterCollisions(resolved, "", seen, themeName, true), ""));
2618
+ merge(acc, buildOne(filterCollisions(resolved, prefix, seen, themeName), prefix, pastel));
2619
+ if (themeName === effectivePrimary) merge(acc, buildOne(filterCollisions(resolved, "", seen, themeName, true), "", pastel));
2577
2620
  }
2578
2621
  return acc;
2579
2622
  }
@@ -2582,7 +2625,7 @@ function createPalette(themes, paletteOptions) {
2582
2625
  return {
2583
2626
  tokens(options) {
2584
2627
  const modes = resolveModes(options?.modes);
2585
- return buildPaletteOutput(themes, paletteOptions, options, (filtered, prefix) => buildFlatTokenMap(filtered, prefix, modes, options?.format), (acc, part) => {
2628
+ return buildPaletteOutput(themes, paletteOptions, options, (filtered, prefix, pastel) => buildFlatTokenMap(filtered, prefix, modes, options?.format, pastel), (acc, part) => {
2586
2629
  for (const variant of Object.keys(part)) {
2587
2630
  if (!acc[variant]) acc[variant] = {};
2588
2631
  Object.assign(acc[variant], part[variant]);
@@ -2596,18 +2639,18 @@ function createPalette(themes, paletteOptions) {
2596
2639
  highContrast: options?.states?.highContrast ?? cfg.states.highContrast
2597
2640
  };
2598
2641
  const modes = resolveModes(options?.modes);
2599
- return buildPaletteOutput(themes, paletteOptions, options, (filtered, prefix) => buildTokenMap(filtered, prefix, states, modes, options?.format), (acc, part) => Object.assign(acc, part), () => ({}));
2642
+ return buildPaletteOutput(themes, paletteOptions, options, (filtered, prefix, pastel) => buildTokenMap(filtered, prefix, states, modes, options?.format, pastel), (acc, part) => Object.assign(acc, part), () => ({}));
2600
2643
  },
2601
2644
  json(options) {
2602
2645
  const modes = resolveModes(options?.modes);
2603
2646
  const result = {};
2604
- for (const [themeName, theme] of Object.entries(themes)) result[themeName] = buildJsonMap(theme.resolve(), modes, options?.format);
2647
+ for (const [themeName, theme] of Object.entries(themes)) result[themeName] = buildJsonMap(theme.resolve(), modes, options?.format, theme.getConfig().pastel);
2605
2648
  return result;
2606
2649
  },
2607
2650
  css(options) {
2608
2651
  const suffix = options?.suffix ?? "-color";
2609
2652
  const format = options?.format ?? "rgb";
2610
- const lines = buildPaletteOutput(themes, paletteOptions, options, (filtered, prefix) => buildCssMap(filtered, prefix, suffix, format), (acc, part) => {
2653
+ const lines = buildPaletteOutput(themes, paletteOptions, options, (filtered, prefix, pastel) => buildCssMap(filtered, prefix, suffix, format, pastel), (acc, part) => {
2611
2654
  for (const key of [
2612
2655
  "light",
2613
2656
  "dark",
@@ -2674,6 +2717,9 @@ function createTheme(hue, saturation, initialColors, configOverride) {
2674
2717
  get saturation() {
2675
2718
  return saturation;
2676
2719
  },
2720
+ getConfig() {
2721
+ return getEffectiveConfig();
2722
+ },
2677
2723
  colors(defs) {
2678
2724
  colorDefs = {
2679
2725
  ...colorDefs,
@@ -2728,7 +2774,7 @@ function createTheme(hue, saturation, initialColors, configOverride) {
2728
2774
  },
2729
2775
  tokens(options) {
2730
2776
  const modes = resolveModes(options?.modes);
2731
- return buildFlatTokenMap(resolveCached(), "", modes, options?.format);
2777
+ return buildFlatTokenMap(resolveCached(), "", modes, options?.format, getEffectiveConfig().pastel);
2732
2778
  },
2733
2779
  tasty(options) {
2734
2780
  const cfg = getEffectiveConfig();
@@ -2737,14 +2783,14 @@ function createTheme(hue, saturation, initialColors, configOverride) {
2737
2783
  highContrast: options?.states?.highContrast ?? cfg.states.highContrast
2738
2784
  };
2739
2785
  const modes = resolveModes(options?.modes);
2740
- return buildTokenMap(resolveCached(), "", states, modes, options?.format);
2786
+ return buildTokenMap(resolveCached(), "", states, modes, options?.format, cfg.pastel);
2741
2787
  },
2742
2788
  json(options) {
2743
2789
  const modes = resolveModes(options?.modes);
2744
- return buildJsonMap(resolveCached(), modes, options?.format);
2790
+ return buildJsonMap(resolveCached(), modes, options?.format, getEffectiveConfig().pastel);
2745
2791
  },
2746
2792
  css(options) {
2747
- return buildCssMap(resolveCached(), "", options?.suffix ?? "-color", options?.format ?? "rgb");
2793
+ return buildCssMap(resolveCached(), "", options?.suffix ?? "-color", options?.format ?? "rgb", getEffectiveConfig().pastel);
2748
2794
  }
2749
2795
  };
2750
2796
  }
@@ -2767,7 +2813,7 @@ function createTheme(hue, saturation, initialColors, configOverride) {
2767
2813
  * Create a single-hue glaze theme.
2768
2814
  *
2769
2815
  * An optional `config` override can be supplied to customize the resolve
2770
- * behavior for this theme (tone windows, saturation taper, etc.). The
2816
+ * behavior for this theme (tone windows, etc.). The
2771
2817
  * override is **merged over the live global config at resolve time** —
2772
2818
  * the theme still reacts to later `configure()` calls for fields it
2773
2819
  * didn't override.
@@ -2827,7 +2873,7 @@ glaze.from = function from(data) {
2827
2873
  *
2828
2874
  * // Config override on any form
2829
2875
  * glaze.color('#26fcb2', { darkTone: false, autoFlip: false })
2830
- * glaze.color({ from: '#fff', base: bg }, { saturationTaper: 0 })
2876
+ * glaze.color({ from: '#fff', base: bg })
2831
2877
  * ```
2832
2878
  *
2833
2879
  * Defaults: every form defaults to `mode: 'auto'`. Value-shorthand forms
@@ -2881,8 +2927,8 @@ glaze.shadow = function shadow(input) {
2881
2927
  };
2882
2928
  };
2883
2929
  /** Format a resolved color variant as a CSS string. */
2884
- glaze.format = function format(variant, colorFormat) {
2885
- return formatVariant(variant, colorFormat);
2930
+ glaze.format = function format(variant, colorFormat, pastel) {
2931
+ return formatVariant(variant, colorFormat, pastel);
2886
2932
  };
2887
2933
  /**
2888
2934
  * Create a theme from a hex color string.
@@ -2936,5 +2982,5 @@ glaze.resetConfig = function resetConfig$1() {
2936
2982
  };
2937
2983
 
2938
2984
  //#endregion
2939
- export { REF_EPS, apcaContrast, contrastRatioFromLuminance, findToneForContrast, findValueForMixContrast, formatHsl, formatOkhsl, formatOklch, formatRgb, fromTone, gamutClampedLuminance, glaze, hslToSrgb, okhslToLinearSrgb, okhslToOkhst, okhslToOklab, okhslToSrgb, okhstToOkhsl, oklabToOkhsl, parseHex, parseHexAlpha, relativeLuminanceFromLinearRgb, resolveContrastForMode, resolveMinContrast, srgbToOkhsl, toTone, toneFromY, variantToOkhsl, yFromTone };
2985
+ export { REF_EPS, apcaContrast, contrastRatioFromLuminance, cuspLightness, findToneForContrast, findValueForMixContrast, formatHsl, formatOkhsl, formatOklch, formatRgb, fromTone, gamutClampedLuminance, glaze, hslToSrgb, okhslToLinearSrgb, okhslToOkhst, okhslToOklab, okhslToSrgb, okhstToOkhsl, oklabToOkhsl, parseHex, parseHexAlpha, relativeLuminanceFromLinearRgb, resolveContrastForMode, resolveMinContrast, srgbToOkhsl, toTone, toneFromY, variantToOkhsl, yFromTone };
2940
2986
  //# sourceMappingURL=index.mjs.map