@tenphi/glaze 1.1.0 → 1.1.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.
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":["fmt","configure","resetConfig"],"sources":["../src/okhsl-color-math.ts","../src/config.ts","../src/types.ts","../src/serialize.ts","../src/format-guard.ts","../src/hc-pair.ts","../src/okhst.ts","../src/contrast-solver.ts","../src/roles.ts","../src/shadow.ts","../src/validation.ts","../src/warnings.ts","../src/resolver.ts","../src/channels.ts","../src/formatters.ts","../src/color-token.ts","../src/theme.ts","../src/palette.ts","../src/glaze.ts"],"sourcesContent":["/**\n * OKHSL color math primitives for the glaze theme generator.\n *\n * Provides bidirectional OKHSL ↔ sRGB conversion, luminance computation\n * for both contrast metrics (WCAG 2 relative luminance and APCA screen\n * luminance `Ys`), and multi-format output (okhsl, rgb, hsl, oklch).\n */\n\ntype Vec3 = [number, number, number];\n\n// ============================================================================\n// Matrices (from texel-color / Björn Ottosson's reference)\n// ============================================================================\n\nconst OKLab_to_LMS_M: Vec3[] = [\n [1.0, 0.3963377773761749, 0.2158037573099136],\n [1.0, -0.1055613458156586, -0.0638541728258133],\n [1.0, -0.0894841775298119, -1.2914855480194092],\n];\n\nconst LMS_to_linear_sRGB_M: Vec3[] = [\n [4.076741636075959, -3.307711539258062, 0.2309699031821041],\n [-1.2684379732850313, 2.6097573492876878, -0.3413193760026569],\n [-0.004196076138675526, -0.703418617935936, 1.7076146940746113],\n];\n\nconst linear_sRGB_to_LMS_M: Vec3[] = [\n [0.4122214708, 0.5363325363, 0.0514459929],\n [0.2119034982, 0.6806995451, 0.1073969566],\n [0.0883024619, 0.2817188376, 0.6299787005],\n];\n\nconst LMS_to_OKLab_M: Vec3[] = [\n [0.2104542553, 0.793617785, -0.0040720468],\n [1.9779984951, -2.428592205, 0.4505937099],\n [0.0259040371, 0.7827717662, -0.808675766],\n];\n\nconst OKLab_to_linear_sRGB_coefficients: [\n [[number, number], number[]],\n [[number, number], number[]],\n [[number, number], number[]],\n] = [\n [\n [-1.8817030993265873, -0.8093650129914302],\n [1.19086277, 1.76576728, 0.59662641, 0.75515197, 0.56771245],\n ],\n [\n [1.8144407988010998, -1.194452667805235],\n [0.73956515, -0.45954404, 0.08285427, 0.1254107, 0.14503204],\n ],\n [\n [0.13110757611180954, 1.813339709266608],\n [1.35733652, -0.00915799, -1.1513021, -0.50559606, 0.00692167],\n ],\n];\n\n// ============================================================================\n// Constants\n// ============================================================================\n\nconst TAU = 2 * Math.PI;\nconst K1 = 0.206;\nconst K2 = 0.03;\nconst K3 = (1.0 + K1) / (1.0 + K2);\nconst EPSILON = 1e-10;\n\n// ============================================================================\n// Helpers\n// ============================================================================\n\nconst constrainAngle = (angle: number): number => ((angle % 360) + 360) % 360;\n/**\n * OKHSL toe function: maps OKLab lightness L to perceptual lightness l.\n * Exported for the OKHST tone transfers in `okhst.ts`.\n */\nexport const toe = (x: number): number =>\n 0.5 *\n (K3 * x - K1 + Math.sqrt((K3 * x - K1) * (K3 * x - K1) + 4 * K2 * K3 * x));\n/** Inverse OKHSL toe: maps perceptual lightness l back to OKLab lightness L. */\nexport const toeInv = (x: number): number =>\n (x ** 2 + K1 * x) / (K3 * (x + K2));\nconst dot3 = (a: Vec3, b: Vec3): number =>\n a[0] * b[0] + a[1] * b[1] + a[2] * b[2];\nconst dotXY = (a: [number, number], b: [number, number]): number =>\n a[0] * b[0] + a[1] * b[1];\nconst transform = (input: Vec3, matrix: Vec3[]): Vec3 => [\n dot3(input, matrix[0]),\n dot3(input, matrix[1]),\n dot3(input, matrix[2]),\n];\nconst cubed3 = (lms: Vec3): Vec3 => [lms[0] ** 3, lms[1] ** 3, lms[2] ** 3];\nconst cbrt3 = (lms: Vec3): Vec3 => [\n Math.cbrt(lms[0]),\n Math.cbrt(lms[1]),\n Math.cbrt(lms[2]),\n];\nconst clampVal = (v: number, min: number, max: number): number =>\n Math.max(min, Math.min(max, v));\n\n// ============================================================================\n// Internal OKHSL pipeline\n// ============================================================================\n\nconst OKLabToLinearSRGB = (lab: Vec3): Vec3 => {\n const lms = transform(lab, OKLab_to_LMS_M);\n return transform(cubed3(lms), LMS_to_linear_sRGB_M);\n};\n\nconst computeMaxSaturationOKLC = (a: number, b: number): number => {\n const okCoeff = OKLab_to_linear_sRGB_coefficients;\n const lmsToRgb = LMS_to_linear_sRGB_M;\n const tmp2: [number, number] = [a, b];\n const tmp3: Vec3 = [0, a, b];\n\n let chnlCoeff: number[];\n let chnlLMS: Vec3;\n\n if (dotXY(okCoeff[0][0], tmp2) > 1) {\n chnlCoeff = okCoeff[0][1];\n chnlLMS = lmsToRgb[0];\n } else if (dotXY(okCoeff[1][0], tmp2) > 1) {\n chnlCoeff = okCoeff[1][1];\n chnlLMS = lmsToRgb[1];\n } else {\n chnlCoeff = okCoeff[2][1];\n chnlLMS = lmsToRgb[2];\n }\n\n const [k0, k1, k2, k3, k4] = chnlCoeff;\n const [wl, wm, ws] = chnlLMS;\n\n let sat = k0 + k1 * a + k2 * b + k3 * (a * a) + k4 * a * b;\n\n const dotYZ = (mat: Vec3, vec: Vec3): number =>\n mat[1] * vec[1] + mat[2] * vec[2];\n\n const kl = dotYZ(OKLab_to_LMS_M[0], tmp3);\n const km = dotYZ(OKLab_to_LMS_M[1], tmp3);\n const ks = dotYZ(OKLab_to_LMS_M[2], tmp3);\n\n const l_ = 1.0 + sat * kl;\n const m_ = 1.0 + sat * km;\n const s_ = 1.0 + sat * ks;\n\n const l = l_ ** 3;\n const m = m_ ** 3;\n const s = s_ ** 3;\n\n const lds = 3.0 * kl * l_ * l_;\n const mds = 3.0 * km * m_ * m_;\n const sds = 3.0 * ks * s_ * s_;\n\n const lds2 = 6.0 * kl * kl * l_;\n const mds2 = 6.0 * km * km * m_;\n const sds2 = 6.0 * ks * ks * s_;\n\n const f = wl * l + wm * m + ws * s;\n const f1 = wl * lds + wm * mds + ws * sds;\n const f2 = wl * lds2 + wm * mds2 + ws * sds2;\n\n sat = sat - (f * f1) / (f1 * f1 - 0.5 * f * f2);\n\n return sat;\n};\n\nconst findCuspOKLCH = (a: number, b: number): [number, number] => {\n const S_cusp = computeMaxSaturationOKLC(a, b);\n const lab: Vec3 = [1, S_cusp * a, S_cusp * b];\n const rgb_at_max = OKLabToLinearSRGB(lab);\n const L_cusp = Math.cbrt(\n 1 /\n Math.max(\n Math.max(rgb_at_max[0], rgb_at_max[1]),\n Math.max(rgb_at_max[2], 0.0),\n ),\n );\n return [L_cusp, L_cusp * S_cusp];\n};\n\nconst findGamutIntersectionOKLCH = (\n a: number,\n b: number,\n l1: number,\n c1: number,\n l0: number,\n cusp: [number, number],\n): number => {\n const lmsToRgb = LMS_to_linear_sRGB_M;\n const tmp3: Vec3 = [0, a, b];\n const floatMax = Number.MAX_VALUE;\n\n let t: number;\n\n const dotYZ = (mat: Vec3, vec: Vec3): number =>\n mat[1] * vec[1] + mat[2] * vec[2];\n const dotXYZ = (vec: Vec3, x: number, y: number, z: number): number =>\n vec[0] * x + vec[1] * y + vec[2] * z;\n\n if ((l1 - l0) * cusp[1] - (cusp[0] - l0) * c1 <= 0.0) {\n const denom = c1 * cusp[0] + cusp[1] * (l0 - l1);\n t = denom === 0 ? 0 : (cusp[1] * l0) / denom;\n } else {\n const denom = c1 * (cusp[0] - 1.0) + cusp[1] * (l0 - l1);\n t = denom === 0 ? 0 : (cusp[1] * (l0 - 1.0)) / denom;\n\n const dl = l1 - l0;\n const dc = c1;\n const kl = dotYZ(OKLab_to_LMS_M[0], tmp3);\n const km = dotYZ(OKLab_to_LMS_M[1], tmp3);\n const ks = dotYZ(OKLab_to_LMS_M[2], tmp3);\n\n const L = l0 * (1.0 - t) + t * l1;\n const C = t * c1;\n\n const l_ = L + C * kl;\n const m_ = L + C * km;\n const s_ = L + C * ks;\n\n const l = l_ ** 3;\n const m = m_ ** 3;\n const s = s_ ** 3;\n\n const ldt = 3 * (dl + dc * kl) * l_ * l_;\n const mdt = 3 * (dl + dc * km) * m_ * m_;\n const sdt = 3 * (dl + dc * ks) * s_ * s_;\n\n const ldt2 = 6 * (dl + dc * kl) ** 2 * l_;\n const mdt2 = 6 * (dl + dc * km) ** 2 * m_;\n const sdt2 = 6 * (dl + dc * ks) ** 2 * s_;\n\n const r_ = dotXYZ(lmsToRgb[0], l, m, s) - 1;\n const r1 = dotXYZ(lmsToRgb[0], ldt, mdt, sdt);\n const r2 = dotXYZ(lmsToRgb[0], ldt2, mdt2, sdt2);\n const ur = r1 / (r1 * r1 - 0.5 * r_ * r2);\n let tr = -r_ * ur;\n\n const g_ = dotXYZ(lmsToRgb[1], l, m, s) - 1;\n const g1 = dotXYZ(lmsToRgb[1], ldt, mdt, sdt);\n const g2 = dotXYZ(lmsToRgb[1], ldt2, mdt2, sdt2);\n const ug = g1 / (g1 * g1 - 0.5 * g_ * g2);\n let tg = -g_ * ug;\n\n const b_ = dotXYZ(lmsToRgb[2], l, m, s) - 1;\n const b1 = dotXYZ(lmsToRgb[2], ldt, mdt, sdt);\n const b2 = dotXYZ(lmsToRgb[2], ldt2, mdt2, sdt2);\n const ub = b1 / (b1 * b1 - 0.5 * b_ * b2);\n let tb = -b_ * ub;\n\n tr = ur >= 0.0 ? tr : floatMax;\n tg = ug >= 0.0 ? tg : floatMax;\n tb = ub >= 0.0 ? tb : floatMax;\n\n t += Math.min(tr, Math.min(tg, tb));\n }\n\n return t;\n};\n\nconst computeSt = (cusp: [number, number]): [number, number] => [\n cusp[1] / cusp[0],\n cusp[1] / (1 - cusp[0]),\n];\n\nconst computeStMid = (a: number, b: number): [number, number] => [\n 0.11516993 +\n 1.0 /\n (7.4477897 +\n 4.1590124 * b +\n a *\n (-2.19557347 +\n 1.75198401 * b +\n a *\n (-2.13704948 -\n 10.02301043 * b +\n a * (-4.24894561 + 5.38770819 * b + 4.69891013 * a)))),\n 0.11239642 +\n 1.0 /\n (1.6132032 -\n 0.68124379 * b +\n a *\n (0.40370612 +\n 0.90148123 * b +\n a *\n (-0.27087943 +\n 0.6122399 * b +\n a * (0.00299215 - 0.45399568 * b - 0.14661872 * a)))),\n];\n\nconst getCs = (\n L: number,\n a: number,\n b: number,\n cusp: [number, number],\n): [number, number, number] => {\n const cMax = findGamutIntersectionOKLCH(a, b, L, 1, L, cusp);\n const stMax = computeSt(cusp);\n const k = cMax / Math.min(L * stMax[0], (1 - L) * stMax[1]);\n const stMid = computeStMid(a, b);\n let ca = L * stMid[0];\n let cb = (1.0 - L) * stMid[1];\n const cMid =\n 0.9 * k * Math.sqrt(Math.sqrt(1.0 / (1.0 / ca ** 4 + 1.0 / cb ** 4)));\n ca = L * 0.4;\n cb = (1.0 - L) * 0.8;\n const c0 = Math.sqrt(1.0 / (1.0 / ca ** 2 + 1.0 / cb ** 2));\n return [c0, cMid, cMax];\n};\n\nconst CYAN_A = Math.cos((199.8 * Math.PI) / 180);\nconst CYAN_B = Math.sin((199.8 * Math.PI) / 180);\nconst BLUE_A = Math.cos((267.4 * Math.PI) / 180);\nconst BLUE_B = Math.sin((267.4 * Math.PI) / 180);\n\nlet cyanCusp: [number, number] | undefined;\nlet blueCusp: [number, number] | undefined;\n\n/**\n * Computes the maximum safe OKLCH chroma that fits inside the sRGB gamut\n * for all possible hues at a given OKLab lightness `L`.\n */\nexport function computeSafeChromaOKLCH(L: number): number {\n if (!cyanCusp) cyanCusp = findCuspOKLCH(CYAN_A, CYAN_B);\n if (!blueCusp) blueCusp = findCuspOKLCH(BLUE_A, BLUE_B);\n\n const c1 = findGamutIntersectionOKLCH(CYAN_A, CYAN_B, L, 1, L, cyanCusp);\n const c2 = findGamutIntersectionOKLCH(BLUE_A, BLUE_B, L, 1, L, blueCusp);\n return Math.min(c1, c2);\n}\n\n// ============================================================================\n// Public API\n// ============================================================================\n\n/** Per-hue cusp-lightness cache. The cusp is mode-independent, so keying on\n * a rounded hue is safe and keeps the cache small. */\nconst cuspLightnessCache = new Map<number, number>();\n\n/**\n * OKHSL lightness of the gamut cusp for a hue — the lightness where the\n * realizable chroma peaks. Reuses the same `find_cusp` OKHSL already runs for\n * its `s` normalization (no new color math); the OKLab cusp lightness is run\n * through the OKHSL `toe` and clamped to `[0.001, 0.999]` so divisions that\n * key off it stay safe. Cached per (rounded) hue.\n *\n * @param h Hue, 0–360.\n */\nexport function cuspLightness(h: number): number {\n const key = Math.round(constrainAngle(h) * 100) / 100;\n const cached = cuspLightnessCache.get(key);\n if (cached !== undefined) return cached;\n\n const hNorm = key / 360.0;\n const cusp = findCuspOKLCH(Math.cos(TAU * hNorm), Math.sin(TAU * hNorm));\n const lc = clampVal(toe(cusp[0]), 0.001, 0.999);\n cuspLightnessCache.set(key, lc);\n return lc;\n}\n\n/**\n * Convert OKHSL (h: 0–360, s: 0–1, l: 0–1) to OKLab [L, a, b].\n */\nexport function okhslToOklab(\n h: number,\n s: number,\n l: number,\n pastel = false,\n): [number, number, number] {\n const L = toeInv(l);\n let a = 0;\n let b = 0;\n\n const hNorm = constrainAngle(h) / 360.0;\n\n if (L !== 0.0 && L !== 1.0 && s !== 0) {\n const a_ = Math.cos(TAU * hNorm);\n const b_ = Math.sin(TAU * hNorm);\n\n if (pastel) {\n const c = s * computeSafeChromaOKLCH(L);\n a = c * a_;\n b = c * b_;\n } else {\n const cusp = findCuspOKLCH(a_, b_);\n const Cs = getCs(L, a_, b_, cusp);\n const [c0, cMid, cMax] = Cs;\n\n const mid = 0.8;\n const midInv = 1.25;\n let t: number, k0: number, k1: number, k2: number;\n\n if (s < mid) {\n t = midInv * s;\n k0 = 0.0;\n k1 = mid * c0;\n k2 = 1.0 - k1 / cMid;\n } else {\n t = 5 * (s - 0.8);\n k0 = cMid;\n k1 = (0.2 * cMid ** 2 * 1.25 ** 2) / c0;\n k2 = 1.0 - k1 / (cMax - cMid);\n }\n\n const c = k0 + (t * k1) / (1.0 - k2 * t);\n a = c * a_;\n b = c * b_;\n }\n }\n\n return [L, a, b];\n}\n\n/**\n * Convert OKHSL (h: 0–360, s: 0–1, l: 0–1) to linear sRGB.\n * Channels may exceed [0, 1] near gamut boundaries — caller must clamp if needed.\n */\nexport function okhslToLinearSrgb(\n h: number,\n s: number,\n l: number,\n pastel = false,\n): [number, number, number] {\n return OKLabToLinearSRGB(okhslToOklab(h, s, l, pastel));\n}\n\n/**\n * Compute relative luminance Y from linear sRGB channels.\n * Per WCAG 2: Y = 0.2126·R + 0.7152·G + 0.0722·B\n */\nexport function relativeLuminanceFromLinearRgb(\n rgb: [number, number, number],\n): number {\n return 0.2126 * rgb[0] + 0.7152 * rgb[1] + 0.0722 * rgb[2];\n}\n\n/**\n * WCAG 2 contrast ratio from two luminance values.\n */\nexport function contrastRatioFromLuminance(yA: number, yB: number): number {\n const lighter = Math.max(yA, yB);\n const darker = Math.min(yA, yB);\n return (lighter + 0.05) / (darker + 0.05);\n}\n\nexport const sRGBLinearToGamma = (val: number): number => {\n const sign = val < 0 ? -1 : 1;\n const abs = Math.abs(val);\n return abs > 0.0031308\n ? sign * (1.055 * Math.pow(abs, 1 / 2.4) - 0.055)\n : 12.92 * val;\n};\n\nexport const sRGBGammaToLinear = (val: number): number => {\n const sign = val < 0 ? -1 : 1;\n const abs = Math.abs(val);\n return abs <= 0.04045\n ? val / 12.92\n : sign * Math.pow((abs + 0.055) / 1.055, 2.4);\n};\n\n/**\n * Convert OKHSL to gamma-encoded sRGB (clamped to 0–1).\n */\nexport function okhslToSrgb(\n h: number,\n s: number,\n l: number,\n pastel = false,\n): [number, number, number] {\n const lin = okhslToLinearSrgb(h, s, l, pastel);\n return [\n Math.max(0, Math.min(1, sRGBLinearToGamma(lin[0]))),\n Math.max(0, Math.min(1, sRGBLinearToGamma(lin[1]))),\n Math.max(0, Math.min(1, sRGBLinearToGamma(lin[2]))),\n ];\n}\n\n/**\n * Compute WCAG 2 relative luminance from linear sRGB, matching the browser\n * rendering pipeline: gamma-encode, clamp to sRGB gamut [0,1], then linearize.\n * This avoids over/under-estimating luminance for out-of-gamut OKHSL colors.\n */\nexport function gamutClampedLuminance(\n linearRgb: [number, number, number],\n): number {\n const r = sRGBGammaToLinear(\n Math.max(0, Math.min(1, sRGBLinearToGamma(linearRgb[0]))),\n );\n const g = sRGBGammaToLinear(\n Math.max(0, Math.min(1, sRGBLinearToGamma(linearRgb[1]))),\n );\n const b = sRGBGammaToLinear(\n Math.max(0, Math.min(1, sRGBLinearToGamma(linearRgb[2]))),\n );\n return 0.2126 * r + 0.7152 * g + 0.0722 * b;\n}\n\n/**\n * Compute APCA screen luminance (`Ys`) from linear sRGB.\n *\n * APCA does not use the WCAG piecewise sRGB EOTF; it defines its own\n * luminance as `0.2126·R^2.4 + 0.7152·G^2.4 + 0.0722·B^2.4` over the\n * gamma-encoded (display) channels with a simple 2.4 exponent. The APCA\n * soft-clamp threshold in `apcaContrast` is calibrated against this basis,\n * so the solver must feed it `Ys`, not WCAG relative luminance. Channels\n * are gamut-clamped to [0, 1] first, matching `gamutClampedLuminance`.\n */\nexport function apcaLuminanceFromLinearRgb(\n linearRgb: [number, number, number],\n): number {\n const r = Math.max(0, Math.min(1, sRGBLinearToGamma(linearRgb[0])));\n const g = Math.max(0, Math.min(1, sRGBLinearToGamma(linearRgb[1])));\n const b = Math.max(0, Math.min(1, sRGBLinearToGamma(linearRgb[2])));\n return (\n 0.2126 * Math.pow(r, 2.4) +\n 0.7152 * Math.pow(g, 2.4) +\n 0.0722 * Math.pow(b, 2.4)\n );\n}\n\n// ============================================================================\n// Reverse pipeline: sRGB → OKHSL\n// ============================================================================\n\nconst linearSrgbToOklab = (rgb: Vec3): Vec3 => {\n const lms = transform(rgb, linear_sRGB_to_LMS_M);\n const lms_ = cbrt3(lms);\n return transform(lms_, LMS_to_OKLab_M);\n};\n\n/**\n * Convert OKLab to OKHSL.\n * Input: [L, a, b] where L: 0–1, a/b: roughly -0.5 to 0.5.\n * Returns [h, s, l] where h: 0–360, s: 0–1, l: 0–1.\n */\nexport const oklabToOkhsl = (lab: Vec3, pastel = false): Vec3 => {\n const L = lab[0];\n const a = lab[1];\n const b = lab[2];\n\n const C = Math.sqrt(a * a + b * b);\n\n if (C < EPSILON) {\n return [0, 0, toe(L)];\n }\n\n // Lightness-extreme achromatic guard.\n //\n // At L → 1 (white) and L → 0 (black) the in-gamut chroma collapses to\n // a single point: cMax, cMid, c0 all approach zero. Pure white is the\n // most visible failure case — `linearSrgbToOklab([1, 1, 1])` leaves\n // tiny floating-point residue in the a / b channels (`a ≈ 8e-11`,\n // `b ≈ 3.7e-8` → `C ≈ 3.7e-8`) that's well above `EPSILON` (`1e-10`),\n // so the chroma early-return above doesn't catch it. The chromatic\n // path then runs, the gamut at L ≈ 1 has nowhere to put any chroma,\n // and the saturation formula in `getCs` divides through ~zero values,\n // producing nonsense h/s for what is physically an achromatic color\n // (`#FFFFFF` → `okhsl(89.88 55.83% 100%)` instead of\n // `okhsl(0 0% 100%)`).\n //\n // The threshold (`1e-6`) is much wider than `EPSILON` because the fp\n // wobble in L for pure white lands at `1 - 6.5e-9` — `EPSILON = 1e-10`\n // misses it. `1e-6` is still well below any human-perceivable\n // difference in lightness (JNDs in OKHSL L are several orders of\n // magnitude larger), so we don't falsely flatten any in-gamut color.\n //\n // Treat both extremes as achromatic. The lightness window itself is\n // preserved through `toe(L)`.\n const L_EXTREME_EPSILON = 1e-6;\n if (L >= 1 - L_EXTREME_EPSILON || L <= L_EXTREME_EPSILON) {\n return [0, 0, toe(L)];\n }\n\n const a_ = a / C;\n const b_ = b / C;\n\n let h = Math.atan2(b, a) * (180 / Math.PI);\n h = constrainAngle(h);\n\n let s: number;\n\n if (pastel) {\n s = C / computeSafeChromaOKLCH(L);\n } else {\n const cusp = findCuspOKLCH(a_, b_);\n const Cs = getCs(L, a_, b_, cusp);\n const [c0, cMid, cMax] = Cs;\n\n const mid = 0.8;\n const midInv = 1.25;\n\n if (C < cMid) {\n const k1 = mid * c0;\n const k2 = 1.0 - k1 / cMid;\n const t = C / (k1 + C * k2);\n s = t / midInv;\n } else {\n const k0 = cMid;\n const k1 = (0.2 * cMid ** 2 * 1.25 ** 2) / c0;\n const k2 = 1.0 - k1 / (cMax - cMid);\n const cDiff = C - k0;\n const t = cDiff / (k1 + cDiff * k2);\n s = mid + t / 5;\n }\n }\n\n const l = toe(L);\n\n return [h, clampVal(s, 0, 1), clampVal(l, 0, 1)];\n};\n\n/**\n * Convert gamma-encoded sRGB (0–1 per channel) to OKHSL.\n * Returns [h, s, l] where h: 0–360, s: 0–1, l: 0–1.\n */\nexport function srgbToOkhsl(\n rgb: [number, number, number],\n pastel = false,\n): [number, number, number] {\n const linear: Vec3 = [\n sRGBGammaToLinear(rgb[0]),\n sRGBGammaToLinear(rgb[1]),\n sRGBGammaToLinear(rgb[2]),\n ];\n const oklab = linearSrgbToOklab(linear);\n return oklabToOkhsl(oklab, pastel) as [number, number, number];\n}\n\n/**\n * Convert CSS HSL (sRGB-based) to gamma-encoded sRGB [r, g, b] in 0–1 range.\n * h: 0–360, s: 0–1, l: 0–1.\n *\n * Note: CSS HSL is not the same as OKHSL — it's HSL in the sRGB color space.\n * Use this when parsing `hsl(...)` strings before passing to `srgbToOkhsl`.\n */\nexport function hslToSrgb(\n h: number,\n s: number,\n l: number,\n): [number, number, number] {\n const hh = (((h % 360) + 360) % 360) / 360;\n const ss = clampVal(s, 0, 1);\n const ll = clampVal(l, 0, 1);\n\n if (ss === 0) {\n return [ll, ll, ll];\n }\n\n const q = ll < 0.5 ? ll * (1 + ss) : ll + ss - ll * ss;\n const p = 2 * ll - q;\n\n const hueToChannel = (t: number): number => {\n let tt = t;\n if (tt < 0) tt += 1;\n if (tt > 1) tt -= 1;\n if (tt < 1 / 6) return p + (q - p) * 6 * tt;\n if (tt < 1 / 2) return q;\n if (tt < 2 / 3) return p + (q - p) * (2 / 3 - tt) * 6;\n return p;\n };\n\n return [hueToChannel(hh + 1 / 3), hueToChannel(hh), hueToChannel(hh - 1 / 3)];\n}\n\n/**\n * Parse a hex color string (#rgb or #rrggbb) to sRGB [r, g, b] in 0–1 range.\n * Returns null if the string is not a valid hex color.\n *\n * For 8-digit hex (`#rrggbbaa`) and 4-digit hex (`#rgba`) with alpha,\n * use {@link parseHexAlpha}.\n */\nexport function parseHex(hex: string): [number, number, number] | null {\n const result = parseHexAlpha(hex);\n if (!result || result.alpha !== undefined) return null;\n return result.rgb;\n}\n\n/**\n * Parse a hex color string (#rgb, #rrggbb, #rgba, or #rrggbbaa) to\n * sRGB [r, g, b] in 0–1 range plus an optional alpha (0–1).\n * Returns null if the string is not a valid hex color.\n */\nexport function parseHexAlpha(\n hex: string,\n): { rgb: [number, number, number]; alpha?: number } | null {\n const h = hex.startsWith('#') ? hex.slice(1) : hex;\n\n if (h.length === 3) {\n const r = parseInt(h[0] + h[0], 16);\n const g = parseInt(h[1] + h[1], 16);\n const b = parseInt(h[2] + h[2], 16);\n if (isNaN(r) || isNaN(g) || isNaN(b)) return null;\n return { rgb: [r / 255, g / 255, b / 255] };\n }\n\n if (h.length === 4) {\n const r = parseInt(h[0] + h[0], 16);\n const g = parseInt(h[1] + h[1], 16);\n const b = parseInt(h[2] + h[2], 16);\n const a = parseInt(h[3] + h[3], 16);\n if (isNaN(r) || isNaN(g) || isNaN(b) || isNaN(a)) return null;\n return { rgb: [r / 255, g / 255, b / 255], alpha: a / 255 };\n }\n\n if (h.length === 6) {\n const r = parseInt(h.slice(0, 2), 16);\n const g = parseInt(h.slice(2, 4), 16);\n const b = parseInt(h.slice(4, 6), 16);\n if (isNaN(r) || isNaN(g) || isNaN(b)) return null;\n return { rgb: [r / 255, g / 255, b / 255] };\n }\n\n if (h.length === 8) {\n const r = parseInt(h.slice(0, 2), 16);\n const g = parseInt(h.slice(2, 4), 16);\n const b = parseInt(h.slice(4, 6), 16);\n const a = parseInt(h.slice(6, 8), 16);\n if (isNaN(r) || isNaN(g) || isNaN(b) || isNaN(a)) return null;\n return { rgb: [r / 255, g / 255, b / 255], alpha: a / 255 };\n }\n\n return null;\n}\n\n// ============================================================================\n// Format functions\n// ============================================================================\n\nfunction fmt(value: number, decimals: number): string {\n return parseFloat(value.toFixed(decimals)).toString();\n}\n\n/**\n * Format OKHSL values as a CSS `okhsl(H S% L%)` string.\n * h: 0–360, s: 0–100, l: 0–100 (percentage scale for s and l).\n */\nexport function formatOkhsl(\n h: number,\n s: number,\n l: number,\n pastel = false,\n): string {\n let outS = s;\n if (pastel) {\n // If it's a pastel color, we need to find the equivalent normal OKHSL `s`\n // so it renders identically in external parsers that don't know about `pastel`.\n const oklab = okhslToOklab(h, s / 100, l / 100, true);\n const normalOkhsl = oklabToOkhsl(oklab, false);\n outS = normalOkhsl[1] * 100;\n }\n return `okhsl(${fmt(h, 2)} ${fmt(outS, 2)}% ${fmt(l, 2)}%)`;\n}\n\n/**\n * Format OKHST values as a CSS `okhst(H S% T%)` string.\n * h: 0–360, s: 0–100, t: 0–100 (percentage scale for s and t).\n *\n * Pastel recompute matches `formatOkhsl`: convert via OKLab so external\n * parsers that only understand non-pastel OKHST render identically.\n */\nexport function formatOkhst(\n h: number,\n s: number,\n t: number,\n pastel = false,\n): string {\n let outS = s;\n if (pastel) {\n const REF_EPS = 0.05;\n const den = Math.log(1 + REF_EPS) - Math.log(REF_EPS);\n const y = Math.exp((t / 100) * den + Math.log(REF_EPS)) - REF_EPS;\n const l = toe(Math.cbrt(Math.max(0, y)));\n const oklab = okhslToOklab(h, s / 100, l, true);\n const normalOkhsl = oklabToOkhsl(oklab, false);\n outS = normalOkhsl[1] * 100;\n }\n return `okhst(${fmt(h, 2)} ${fmt(outS, 2)}% ${fmt(t, 2)}%)`;\n}\n\n/**\n * Format OKHSL values as a CSS `rgb(R G B)` string.\n * Uses 2 decimal places to avoid 8-bit quantization contrast loss.\n * h: 0–360, s: 0–100, l: 0–100 (percentage scale for s and l).\n */\nexport function formatRgb(\n h: number,\n s: number,\n l: number,\n pastel = false,\n): string {\n const [r, g, b] = okhslToSrgb(h, s / 100, l / 100, pastel);\n return `rgb(${parseFloat((r * 255).toFixed(2))} ${parseFloat((g * 255).toFixed(2))} ${parseFloat((b * 255).toFixed(2))})`;\n}\n\n/**\n * Format OKHSL values as a CSS `hsl(H S% L%)` string.\n * h: 0–360, s: 0–100, l: 0–100 (percentage scale for s and l).\n */\nexport function formatHsl(\n h: number,\n s: number,\n l: number,\n pastel = false,\n): string {\n const [r, g, b] = okhslToSrgb(h, s / 100, l / 100, pastel);\n\n const max = Math.max(r, g, b);\n const min = Math.min(r, g, b);\n const delta = max - min;\n\n let hh = 0;\n let ss = 0;\n const ll = (max + min) / 2;\n\n if (delta > 0) {\n ss = ll > 0.5 ? delta / (2 - max - min) : delta / (max + min);\n\n if (max === r) {\n hh = ((g - b) / delta + (g < b ? 6 : 0)) * 60;\n } else if (max === g) {\n hh = ((b - r) / delta + 2) * 60;\n } else {\n hh = ((r - g) / delta + 4) * 60;\n }\n }\n\n return `hsl(${fmt(hh, 2)} ${fmt(ss * 100, 2)}% ${fmt(ll * 100, 2)}%)`;\n}\n\n/**\n * Format OKHSL values as a CSS `oklch(L C H)` string.\n * h: 0–360, s: 0–100, l: 0–100 (percentage scale for s and l).\n */\nexport function formatOklch(\n h: number,\n s: number,\n l: number,\n pastel = false,\n): string {\n const [L, C, hh] = okhslToOklch(h, s / 100, l / 100, pastel);\n return `oklch(${fmt(L, 4)} ${fmt(C, 4)} ${fmt(hh, 2)})`;\n}\n\n// ============================================================================\n// Structured (non-string) color accessors — used by the DTCG exporter.\n// ============================================================================\n\n/**\n * Convert gamma-encoded sRGB channels (0–1) to a 6-digit lowercase hex\n * string (`#rrggbb`). Channels are clamped to [0,1] and rounded to 8-bit.\n * Alpha is not encoded here — DTCG carries it as a separate `alpha` field.\n */\nexport function srgbToHex(rgb: [number, number, number]): `#${string}` {\n const toByte = (c: number): number =>\n Math.max(0, Math.min(255, Math.round(c * 255)));\n const r = toByte(rgb[0]);\n const g = toByte(rgb[1]);\n const b = toByte(rgb[2]);\n return `#${r.toString(16).padStart(2, '0')}${g.toString(16).padStart(2, '0')}${b.toString(16).padStart(2, '0')}`;\n}\n\n/**\n * Convert OKHSL (h: 0–360, s: 0–1, l: 0–1) to OKLCH components `[L, C, H]`.\n * L: 0–1, C: 0–~0.4 (chroma), H: 0–360 (hue). Shared by `formatOklch` and\n * the DTCG `oklch` colorSpace exporter so the two never drift apart.\n */\nexport function okhslToOklch(\n h: number,\n s: number,\n l: number,\n pastel = false,\n): [number, number, number] {\n const [L, a, b] = okhslToOklab(h, s, l, pastel);\n const C = Math.sqrt(a * a + b * b);\n const hh = constrainAngle(Math.atan2(b, a) * (180 / Math.PI));\n return [L, C, hh];\n}\n","/**\n * Glaze global configuration singleton.\n *\n * `configure()` mutates the singleton; every other module reads it via\n * `getConfig()` at call time so changes take effect for subsequent\n * resolves. Per-instance overrides (themes / color tokens) stay sparse —\n * omitted fields fall through to the live global at resolve time.\n * Authoring exports freeze the effective merge at export call time.\n *\n * `pastel` is instance-only (theme / token override or per-color def),\n * never set via `configure()`.\n */\n\nimport type {\n GlazeConfig,\n GlazeConfigOverride,\n GlazeConfigResolved,\n} from './types';\n\n/**\n * Build a fresh defaults object. Called from module init and from\n * `resetConfig()` so the two paths can't drift.\n *\n * `pastel: false` is a fixed instance default — not globally configurable.\n */\nexport function defaultConfig(): GlazeConfigResolved {\n return {\n lightTone: { lo: 10, hi: 100, eps: 0.05 },\n darkTone: { lo: 15, hi: 95, eps: 0.05 },\n darkDesaturation: 0.1,\n states: {\n dark: '@media(prefers-color-scheme: dark)',\n highContrast: '@media(prefers-contrast: more)',\n },\n modes: {\n dark: true,\n highContrast: false,\n },\n autoFlip: true,\n pastel: false,\n inferRole: true,\n };\n}\n\nlet globalConfig: GlazeConfigResolved = defaultConfig();\n\n/**\n * Monotonic counter incremented on every `configure()` / `resetConfig()`\n * call. Theme / palette caches read this to invalidate stale resolve\n * results when the config changes between exports.\n */\nlet configVersion = 0;\n\n/** Live reference to the current config. Mutated by `configure()` / `resetConfig()`. */\nexport function getConfig(): GlazeConfigResolved {\n return globalConfig;\n}\n\nexport function getConfigVersion(): number {\n return configVersion;\n}\n\n/**\n * Public-facing snapshot used by `glaze.getConfig()`. Returns a shallow\n * copy so callers can't mutate the live config.\n */\nexport function snapshotConfig(): GlazeConfigResolved {\n return { ...globalConfig };\n}\n\nexport function configure(config: GlazeConfig): void {\n configVersion++;\n globalConfig = {\n lightTone: config.lightTone ?? globalConfig.lightTone,\n darkTone: config.darkTone ?? globalConfig.darkTone,\n darkDesaturation: config.darkDesaturation ?? globalConfig.darkDesaturation,\n states: {\n dark: config.states?.dark ?? globalConfig.states.dark,\n highContrast:\n config.states?.highContrast ?? globalConfig.states.highContrast,\n },\n modes: {\n dark: config.modes?.dark ?? globalConfig.modes.dark,\n highContrast:\n config.modes?.highContrast ?? globalConfig.modes.highContrast,\n },\n shadowTuning: config.shadowTuning ?? globalConfig.shadowTuning,\n autoFlip: config.autoFlip ?? globalConfig.autoFlip,\n // Instance-only; never configurable globally.\n pastel: false,\n inferRole: config.inferRole ?? globalConfig.inferRole,\n };\n}\n\nexport function resetConfig(): void {\n configVersion++;\n globalConfig = defaultConfig();\n}\n\n/**\n * Merge a per-instance config override over a base resolved config.\n * Only fields present in `override` are replaced; others fall through\n * from `base`. `false` for tone windows passes through as-is\n * (treated as the full range by `activeWindow()` in okhst.ts).\n *\n * `pastel` is instance-only: `override.pastel ?? false`, never inherited\n * from the global base.\n */\nexport function mergeConfig(\n base: GlazeConfigResolved,\n override?: GlazeConfigOverride,\n): GlazeConfigResolved {\n if (!override) {\n return base.pastel === false ? base : { ...base, pastel: false };\n }\n return {\n lightTone:\n override.lightTone !== undefined ? override.lightTone : base.lightTone,\n darkTone:\n override.darkTone !== undefined ? override.darkTone : base.darkTone,\n darkDesaturation: override.darkDesaturation ?? base.darkDesaturation,\n states: base.states,\n modes: base.modes,\n shadowTuning: override.shadowTuning ?? base.shadowTuning,\n autoFlip: override.autoFlip ?? base.autoFlip,\n pastel: override.pastel ?? false,\n inferRole: override.inferRole ?? base.inferRole,\n };\n}\n\n/**\n * Freeze `getConfig() ∪ instanceLocal ∪ exportArg` as a plain, resolve-relevant\n * override for authoring export, so restored snapshots pin these fields. Later\n * wins; nested objects (`shadowTuning`) replace wholesale. The final\n * `structuredClone` detaches tone-window / shadow objects that `mergeConfig`\n * may still share with the live global config.\n */\nexport function freezeConfigForExport(\n instanceLocal?: GlazeConfigOverride,\n exportArg?: GlazeConfigOverride,\n): GlazeConfigOverride {\n const effective = mergeConfig(getConfig(), {\n ...instanceLocal,\n ...exportArg,\n });\n const out: GlazeConfigOverride = {\n lightTone: effective.lightTone,\n darkTone: effective.darkTone,\n darkDesaturation: effective.darkDesaturation,\n autoFlip: effective.autoFlip,\n pastel: effective.pastel,\n inferRole: effective.inferRole,\n };\n if (effective.shadowTuning !== undefined) {\n out.shadowTuning = effective.shadowTuning;\n }\n return structuredClone(out);\n}\n","/**\n * Glaze type definitions.\n */\n\nimport type { ApcaPreset, ContrastPreset } from './contrast-solver';\n\n// ============================================================================\n// Value types\n// ============================================================================\n\n/** A value or [normal, high-contrast] pair. */\nexport type HCPair<T> = T | [T, T];\n\n/** Bare WCAG contrast target: a ratio number or a named preset. */\nexport type MinContrast = number | ContrastPreset;\n\n/**\n * A contrast floor with a pluggable metric.\n *\n * - `number` / `ContrastPreset`: a WCAG ratio (bare form).\n * - `{ wcag }`: WCAG ratio or preset, optionally an HC pair.\n * - `{ apca }`: APCA Lc target (absolute value or preset), optionally an HC pair.\n *\n * The `[normal, highContrast]` pair may live at the outer level\n * (`[4.5, 7]`, `[{ wcag: 4.5 }, { wcag: 7 }]`) or inside the metric\n * (`{ wcag: [4.5, 7] }`, `{ apca: [45, 60] }`, `{ apca: ['content', 'body'] }`).\n */\nexport type ContrastSpec =\n | number\n | ContrastPreset\n | { wcag: HCPair<number | ContrastPreset> }\n | { apca: HCPair<number | ApcaPreset> };\n\n// ============================================================================\n// Color role\n// ============================================================================\n\n/**\n * The semantic role a color plays against its base, used to fix APCA contrast\n * polarity (which side is the foreground vs the background). WCAG is\n * symmetric, so role never changes WCAG results.\n */\nexport type Role = 'text' | 'surface' | 'border';\n\n/**\n * Any string accepted as a `role`. Canonical values plus aliases normalized by\n * `normalizeRole` (see `roles.ts`): `surface` (bg/background/fill/canvas/\n * paper/layer), `text` (fg/foreground/content/ink/label/stroke), `border`\n * (divider/outline/separator/hairline/rule).\n */\nexport type RoleInput =\n | Role\n | 'bg'\n | 'background'\n | 'fill'\n | 'canvas'\n | 'paper'\n | 'layer'\n | 'fg'\n | 'foreground'\n | 'content'\n | 'ink'\n | 'label'\n | 'stroke'\n | 'divider'\n | 'outline'\n | 'separator'\n | 'hairline'\n | 'rule';\n\nexport type AdaptationMode = 'auto' | 'fixed' | 'static';\n\n/** A signed relative offset string, e.g. '+20' or '-15.5'. */\nexport type RelativeValue = `+${number}` | `-${number}`;\n\n/**\n * Force a color to a tone extreme:\n * - `'max'`: the highest tone in the active scheme range/window.\n * - `'min'`: the lowest tone.\n *\n * Under `mode: 'auto'` the extreme inverts in the dark scheme (so `'max'`\n * tracks the inversion and becomes the darkest tone). No `base` required.\n */\nexport type ExtremeValue = 'max' | 'min';\n\n/**\n * A tone value as authored on a color.\n * - Number: absolute tone (0–100).\n * - `'+N'` / `'-N'`: relative to the base's tone (requires `base`).\n * - `'max'` / `'min'`: forced to the scheme's tone extreme (no base needed).\n */\nexport type ToneValue = number | RelativeValue | ExtremeValue;\n\n/** Color format for output. */\nexport type GlazeColorFormat = 'okhsl' | 'okhst' | 'rgb' | 'hsl' | 'oklch';\n\n/**\n * Controls which scheme variants are generated in the export.\n * Light is always included (it's the default).\n */\nexport interface GlazeOutputModes {\n /** Include dark scheme variants. Default: true. */\n dark?: boolean;\n /** Include high-contrast variants (both light-HC and dark-HC). Default: false. */\n highContrast?: boolean;\n}\n\n// ============================================================================\n// Color definitions\n// ============================================================================\n\n/** Hex color string for DX hints. Runtime validation in `parseHex()`. */\nexport type HexColor = `#${string}`;\n\n/** Direct OKHSL color input. */\nexport interface OkhslColor {\n h: number;\n s: number;\n l: number;\n}\n\n/**\n * Direct OKHST color input — OKHSL with the lightness axis replaced by the\n * contrast-uniform tone axis. `h`: 0–360, `s`: 0–1, `t`: 0–1 (tone).\n */\nexport interface OkhstColor {\n h: number;\n s: number;\n t: number;\n}\n\n/** sRGB components in 0–255 (value-shorthand object form). */\nexport interface RgbColor {\n r: number;\n g: number;\n b: number;\n}\n\n/** OKLCh components matching CSS `oklch(L C H)` (L/C: 0–1, H: degrees). */\nexport interface OklchColor {\n l: number;\n c: number;\n h: number;\n}\n\nexport interface RegularColorDef {\n /**\n * Tone value (0–100, contrast-uniform — see `docs/okhst.md`).\n * - Number: absolute tone.\n * - String ('+N' / '-N'): relative to base color's tone (requires `base`).\n * - `'max'` / `'min'`: force to the scheme's tone extreme (no base needed).\n */\n tone?: HCPair<ToneValue>;\n /** Saturation factor applied to the seed saturation (0–1, default: 1). */\n saturation?: number;\n /**\n * Hue override for this color.\n * - Number: absolute hue (0–360).\n * - String ('+N' / '-N'): relative to the theme seed hue.\n */\n hue?: number | RelativeValue;\n\n /** Name of another color in the same theme (dependent color). */\n base?: string;\n /**\n * Contrast floor against the base color. A bare number/preset is WCAG;\n * use `{ wcag }` / `{ apca }` to pick the metric. Accepts an HC pair.\n */\n contrast?: HCPair<ContrastSpec>;\n\n /** Adaptation mode. Default: 'auto'. */\n mode?: AdaptationMode;\n\n /**\n * Whether to flip out-of-bounds results to the opposite side instead of\n * clamping to the extreme. Affects both:\n * - relative `tone`: when `base ± delta` exceeds `[0, 100]`, mirror the\n * delta to the other side of the base.\n * - `contrast`: when the requested direction can't meet the floor, try the\n * opposite side (same as the global `autoFlip`).\n *\n * Defaults to the global `autoFlip` config (default `true`). Set `false`\n * to clamp instead.\n */\n autoFlip?: boolean;\n\n /**\n * Fixed opacity (0–1).\n * Output includes alpha in the CSS value.\n * Does not affect contrast resolution — a semi-transparent color\n * has no fixed perceived tone, so `contrast` and `opacity`\n * should not be combined (a console.warn is emitted).\n */\n opacity?: number;\n\n /**\n * Per-color override for the hue-independent \"safe\" chroma limit used in\n * OKHSL↔sRGB conversions (luminance, contrast solving, output formatting).\n * Falls through to the per-theme / per-token `pastel` override when omitted.\n * @see GlazeConfigOverride.pastel\n */\n pastel?: boolean;\n\n /**\n * Semantic role against `base`: how this color is used. Fixes APCA contrast\n * polarity (the argument order in `apcaContrast`). WCAG is symmetric so it\n * never affects WCAG results.\n *\n * Resolution: explicit `role` wins; else inferred from the color name when\n * `inferRole` is enabled (default); else the opposite of the base's role;\n * else defaults to `'text'` (foreground).\n */\n role?: RoleInput;\n\n /**\n * Whether this color is inherited by child themes created via `extend()`.\n * Default: true. Set to false to make this color local to the current theme.\n */\n inherit?: boolean;\n}\n\n/** Shadow tuning knobs. All values use the 0–1 scale (OKHSL). */\nexport interface ShadowTuning {\n /** Fraction of fg saturation kept in pigment (0-1). Default: 0.18. */\n saturationFactor?: number;\n /** Upper clamp on pigment saturation (0-1). Default: 0.25. */\n maxSaturation?: number;\n /** Multiplier for bg lightness → pigment lightness. Default: 0.25. */\n lightnessFactor?: number;\n /** [min, max] clamp for pigment lightness (0-1). Default: [0.05, 0.20]. */\n lightnessBounds?: [number, number];\n /**\n * Target minimum gap between pigment lightness and bg lightness (0-1).\n * Default: 0.05.\n */\n minGapTarget?: number;\n /** Max alpha (0-1). Reached at intensity=100 with max contrast. Default: 1.0. */\n alphaMax?: number;\n /**\n * Blend weight (0-1) pulling pigment hue toward bg hue.\n * 0 = pure fg hue, 1 = pure bg hue. Default: 0.2.\n */\n bgHueBlend?: number;\n}\n\nexport interface ShadowColorDef {\n type: 'shadow';\n /**\n * Background color name — the surface the shadow sits on.\n * Must reference a non-shadow color in the same theme.\n */\n bg: string;\n /**\n * Foreground color name for tinting and intensity modulation.\n * Must reference a non-shadow color in the same theme.\n * Omit for achromatic shadow at full user-specified intensity.\n */\n fg?: string;\n /**\n * Shadow intensity, 0-100.\n * Supports [normal, highContrast] pair.\n */\n intensity: HCPair<number>;\n /** Override default tuning. Merged field-by-field with global `shadowTuning`. */\n tuning?: ShadowTuning;\n\n /**\n * Per-color override for the hue-independent \"safe\" chroma limit used in\n * OKHSL↔sRGB conversions (luminance, contrast solving, output formatting).\n * Falls through to the per-theme / per-token `pastel` override when omitted.\n * @see GlazeConfigOverride.pastel\n */\n pastel?: boolean;\n\n /**\n * Whether this color is inherited by child themes created via `extend()`.\n * Default: true. Set to false to make this color local to the current theme.\n */\n inherit?: boolean;\n}\n\nexport interface MixColorDef {\n type: 'mix';\n /** Background/base color name — the \"from\" color. */\n base: string;\n /** Target color name — the \"to\" color to mix toward. */\n target: string;\n /**\n * Mix ratio 0–100 (0 = pure base, 100 = pure target).\n * In 'transparent' blend mode, this controls the opacity of the target.\n * Supports [normal, highContrast] pair.\n */\n value: HCPair<number>;\n /**\n * Blending mode. Default: 'opaque'.\n * - 'opaque': produces a solid color by interpolating base and target.\n * - 'transparent': produces the target color with alpha = value/100.\n */\n blend?: 'opaque' | 'transparent';\n /**\n * Interpolation color space for opaque blending. Default: 'okhsl'.\n * - 'okhsl': perceptually uniform, consistent with Glaze's internal model.\n * - 'srgb': linear sRGB interpolation, matches browser compositing.\n *\n * Ignored for 'transparent' blend (always composites in linear sRGB).\n */\n space?: 'okhsl' | 'srgb';\n /**\n * Minimum contrast between the base and the resulting color.\n * In 'opaque' mode, adjusts the mix ratio to meet contrast.\n * In 'transparent' mode, adjusts opacity to meet contrast against the composite.\n * A bare number/preset is WCAG; use `{ wcag }` / `{ apca }` to pick the\n * metric. Supports [normal, highContrast] pair.\n */\n contrast?: HCPair<ContrastSpec>;\n\n /**\n * Per-color override for the hue-independent \"safe\" chroma limit used in\n * OKHSL↔sRGB conversions (luminance, contrast solving, output formatting).\n * Falls through to the per-theme / per-token `pastel` override when omitted.\n * @see GlazeConfigOverride.pastel\n */\n pastel?: boolean;\n\n /**\n * Semantic role of the mixed result against `base`. Same semantics as\n * `RegularColorDef.role` (fixes APCA polarity). Resolution and defaults\n * are identical.\n */\n role?: RoleInput;\n\n /**\n * Whether this color is inherited by child themes created via `extend()`.\n * Default: true. Set to false to make this color local to the current theme.\n */\n inherit?: boolean;\n}\n\nexport type ColorDef = RegularColorDef | ShadowColorDef | MixColorDef;\n\nexport type ColorMap = Record<string, ColorDef>;\n\n// ============================================================================\n// Resolved internal types\n// ============================================================================\n\n/**\n * Resolved color for a single scheme variant.\n *\n * Stored in OKHST: `h` / `s` are OKHSL hue/saturation, `t` is the canonical\n * contrast-uniform tone (0–1, reference eps). Convert to OKHSL lightness via\n * `variantToOkhsl` at the rendering / luminance edges.\n */\nexport interface ResolvedColorVariant {\n /** OKHSL hue (0–360). */\n h: number;\n /** OKHSL saturation (0–1). */\n s: number;\n /** Canonical tone (0–1, reference eps). */\n t: number;\n /** Opacity (0–1). Default: 1. */\n alpha: number;\n /**\n * Effective `pastel` flag used while resolving this variant (author def or\n * config fallback). Carried on the variant so output formatting matches the\n * gamut mapping applied during resolution.\n */\n pastel?: boolean;\n}\n\n/** Fully resolved color across all scheme variants. */\nexport interface ResolvedColor {\n name: string;\n light: ResolvedColorVariant;\n dark: ResolvedColorVariant;\n lightContrast: ResolvedColorVariant;\n darkContrast: ResolvedColorVariant;\n /** Adaptation mode. Present only for regular colors, omitted for shadows. */\n mode?: AdaptationMode;\n}\n\n// ============================================================================\n// Configuration\n// ============================================================================\n\n/**\n * A scheme tone window.\n * - `[lo, hi]`: OKHSL-lightness endpoints (0–100) the authored tone is\n * remapped into, using the reference eps `0.05`. The common form.\n * - `{ lo, hi, eps }`: same, with an explicit render curvature `eps`\n * (advanced — most palettes never need this).\n * - `false`: disable clamping (full range `[0, 100]` at the reference eps).\n * This removes the *boundaries*, not the tone curve.\n */\nexport type ToneWindow =\n | false\n | [number, number]\n | { lo: number; hi: number; eps: number };\n\nexport interface GlazeConfig {\n /** Light scheme tone window — `[lo, hi]` (default `[10, 100]`), `{ lo, hi, eps }` for advanced eps tuning, or `false` to disable clamping. */\n lightTone?: ToneWindow;\n /** Dark scheme tone window — `[lo, hi]` (default `[15, 95]`), `{ lo, hi, eps }`, or `false` to disable clamping. */\n darkTone?: ToneWindow;\n /** Saturation reduction factor for dark scheme (0–1). Default: 0.1. */\n darkDesaturation?: number;\n /**\n * State alias names for Tasty token export. Default to media-query states\n * (`'@media(prefers-color-scheme: dark)'` / `'@media(prefers-contrast: more)'`)\n * so tokens react to the OS preference without registering custom states.\n */\n states?: {\n dark?: string;\n highContrast?: string;\n };\n /** Which scheme variants to include in exports. Default: both true. */\n modes?: GlazeOutputModes;\n /** Default tuning for all shadow colors. Per-color tuning merges field-by-field. */\n shadowTuning?: ShadowTuning;\n /**\n * Automatically flip tone direction when contrast can't be met.\n *\n * When enabled (default `true`), the solver searches the requested\n * tone direction first. If that direction can't reach the target,\n * it tries the opposite direction and uses it when it passes. If neither\n * side passes, the tone is pinned to the requested-direction\n * extreme and a warning is emitted.\n *\n * Set to `false` for strict \"no flip\" behavior. The opposite\n * direction is never considered: if the requested direction can't\n * meet the target, the tone is pinned to its extreme (never\n * falls back to the originally requested tone).\n */\n autoFlip?: boolean;\n /**\n * If true (default), infer a color's `role` from its name when no explicit\n * `role` is set. Set to `false` to opt out of name-based inference (the\n * base-opposite and default-foreground fallbacks still apply).\n * @default true\n */\n inferRole?: boolean;\n}\n\nexport interface GlazeConfigResolved {\n lightTone: ToneWindow;\n darkTone: ToneWindow;\n darkDesaturation: number;\n states: {\n dark: string;\n highContrast: string;\n };\n modes: Required<GlazeOutputModes>;\n shadowTuning?: ShadowTuning;\n autoFlip: boolean;\n /**\n * Instance-level pastel default (`def.pastel ?? config.pastel`).\n * Not set via `glaze.configure()` — only via per-theme / per-token\n * `GlazeConfigOverride` (default `false`).\n */\n pastel: boolean;\n inferRole: boolean;\n}\n\n/**\n * Per-instance config override for `glaze.color()` and `glaze()` themes.\n * Fields that are set take priority over the live global config. Fields\n * that are omitted fall through to the live global at resolve time\n * (`pastel` is instance-only and defaults to `false` when omitted).\n *\n * `false` for a tone window disables clamping (full range at reference eps).\n */\nexport interface GlazeConfigOverride {\n /** Light scheme tone window, or `false` to disable clamping. */\n lightTone?: ToneWindow;\n /** Dark scheme tone window, or `false` to disable clamping. */\n darkTone?: ToneWindow;\n /** Saturation reduction factor for dark scheme (0–1). */\n darkDesaturation?: number;\n /** Whether to auto-flip tone when contrast can't be met. */\n autoFlip?: boolean;\n /**\n * Instance-level pastel default for colors that omit per-color `pastel`.\n * Not available on `glaze.configure()` — set here or per-color.\n * @default false\n */\n pastel?: boolean;\n /**\n * If true, infer a color's `role` from its name when no explicit `role` is\n * set. Falls through to the live global at resolve time when omitted.\n */\n inferRole?: boolean;\n /**\n * Shadow tuning defaults. Only meaningful for themes; harmless on\n * standalone color tokens.\n */\n shadowTuning?: ShadowTuning;\n}\n\n// ============================================================================\n// Serialization\n// ============================================================================\n\n/**\n * Current authoring-export schema version. Bump when the export shape\n * changes in a non-compatible way. Written on every `.export()` snapshot.\n */\nexport const GLAZE_EXPORT_VERSION = 1 as const;\n\n/** Literal type of {@link GLAZE_EXPORT_VERSION}. */\nexport type GlazeExportVersion = typeof GLAZE_EXPORT_VERSION;\n\n/** Discriminator for authoring export snapshots. */\nexport type GlazeExportKind = 'theme' | 'color' | 'palette';\n\n/** Serialized theme configuration (no resolved values). */\nexport interface GlazeThemeExport {\n /** Snapshot kind. Always written by `theme.export()`; optional on legacy hand-written configs. */\n kind?: 'theme';\n /** Schema version. Always written by `theme.export()`; optional on legacy configs. */\n version?: number;\n hue: number;\n saturation: number;\n colors: ColorMap;\n /**\n * Effective config freeze from `.export()` —\n * `getConfig() ∪ instance local ∪ exportArg`. May be sparse on legacy\n * snapshots (omitted fields fall through to the live global at restore).\n */\n config?: GlazeConfigOverride;\n}\n\n// ============================================================================\n// Standalone shadow\n// ============================================================================\n\n/** Input for `glaze.shadow()` standalone factory. */\nexport interface GlazeShadowInput {\n /**\n * Background color — accepts any `GlazeColorValue` form: hex\n * (`#rgb` / `#rrggbb` / `#rrggbbaa`), `rgb()` / `hsl()` / `okhsl()`\n * / `oklch()` strings, or literal objects (`{ r, g, b }`, `{ h, s, l }`,\n * `{ l, c, h }`). Alpha components are dropped with a warning.\n */\n bg: GlazeColorValue;\n /**\n * Foreground color for tinting + intensity modulation. Accepts the\n * same forms as `bg`.\n */\n fg?: GlazeColorValue;\n /** Intensity 0-100. */\n intensity: number;\n tuning?: ShadowTuning;\n}\n\n// ============================================================================\n// Standalone color token\n// ============================================================================\n\n/** Input for the structured `glaze.color()` overload. */\nexport interface GlazeColorInput {\n hue: number;\n saturation: number;\n tone: HCPair<number | ExtremeValue>;\n saturationFactor?: number;\n mode?: AdaptationMode;\n /** Flip out-of-bounds results instead of clamping. Default: global `autoFlip`. */\n autoFlip?: boolean;\n /**\n * Fixed opacity (0–1). Output includes alpha in the CSS value.\n * Combining with `contrast` is not recommended (perceived tone\n * becomes unpredictable) — a `console.warn` is emitted in that case.\n */\n opacity?: number;\n /**\n * Optional dependency on another color. Same semantics as\n * `GlazeColorOverrides.base` — `contrast` and relative `tone`\n * anchor to the base per scheme.\n */\n base?: GlazeColorToken | GlazeColorValue;\n /**\n * Contrast floor against `base`. Requires `base` to be set. A bare\n * number/preset is WCAG; use `{ wcag }` / `{ apca }` to pick the metric.\n */\n contrast?: HCPair<ContrastSpec>;\n /**\n * Optional human-readable name for the token. Used in error and\n * warning messages (otherwise an internal name like `\"value\"` is\n * used). Does not affect output keys.\n */\n name?: string;\n\n /**\n * Per-color override for the hue-independent \"safe\" chroma limit used in\n * OKHSL↔sRGB conversions (luminance, contrast solving, output formatting).\n * Falls through to the per-theme / per-token `pastel` override when omitted.\n * @see GlazeConfigOverride.pastel\n */\n pastel?: boolean;\n\n /**\n * Semantic role against `base` / the literal seed: how this token is used.\n * Fixes APCA contrast polarity. Same resolution chain as\n * `RegularColorDef.role` (explicit → name inference → opposite of base →\n * `'text'`). For standalone tokens the name is internal, so set `role`\n * explicitly or rely on the base-opposite / foreground default.\n */\n role?: RoleInput;\n}\n\n/**\n * Any single-color input form accepted by the value-shorthand\n * overload of `glaze.color()`.\n *\n * Strings cover hex (`#rgb` / `#rrggbb` / `#rrggbbaa`, alpha dropped\n * with a warning) and the four CSS color functions Glaze itself emits:\n * `rgb()`, `hsl()`, `okhsl()`, `oklch()` (alpha components also dropped\n * with a warning).\n *\n * Literal object forms:\n * - `{ h, s, l }` — OKHSL (h: 0–360, s/l: 0–1). Passing 0–100 for `s`/`l`\n * throws with a hint to use the structured form.\n * - `{ h, s, t }` — OKHST (h: 0–360, s/t: 0–1). Tone in 0–1.\n * - `{ r, g, b }` — sRGB 0–255.\n * - `{ l, c, h }` — OKLCh (L/C: 0–1, H: degrees), same as `oklch()` strings.\n */\nexport type GlazeColorValue =\n | string\n | OkhslColor\n | OkhstColor\n | RgbColor\n | OklchColor;\n\n/** Color overrides for the `from` and value-shorthand inputs. */\nexport interface GlazeColorOverrides {\n /**\n * Override hue. Number is absolute (0–360); `'+N'`/`'-N'` is relative\n * to the extracted (or overridden) seed hue — same semantics as\n * `RegularColorDef.hue`.\n */\n hue?: number | RelativeValue;\n /** Override seed saturation (0–100). Default: extracted from value. */\n saturation?: number;\n /**\n * Override tone. Number is absolute (0–100, contrast-uniform); `'+N'`/`'-N'`\n * is relative to the literal seed (the value passed to `glaze.color()`);\n * `'max'` / `'min'` force to the scheme's tone extreme.\n * Supports HCPair for high-contrast.\n */\n tone?: HCPair<ToneValue>;\n /** Saturation multiplier on the seed (0–1). Default: 1. */\n saturationFactor?: number;\n /**\n * Adaptation mode. Defaults to `'auto'` for every input form, so\n * colors automatically adapt between light and dark like an ordinary\n * theme color. Value-shorthand inputs (strings and literal objects)\n * preserve light tone via a local `lightTone: false` default; other\n * omitted config fields fall through to the live global at resolve\n * time. Structured `{ hue, saturation, tone }` form also falls\n * through for both tone windows unless overridden.\n *\n * Pass `'fixed'` explicitly to opt back into the linear, non-\n * inverting mapping; pass `'static'` to pin the same tone\n * across every variant.\n */\n mode?: AdaptationMode;\n\n /**\n * Flip out-of-bounds results (relative `tone` overshoot / unmet\n * `contrast`) to the opposite side instead of clamping. Defaults to\n * the global `autoFlip`.\n */\n autoFlip?: boolean;\n\n /**\n * Contrast floor. By default solved against the literal seed\n * (the value itself); when `base` is set, solved against the base's\n * resolved variant per scheme. Same shape as `RegularColorDef.contrast`\n * (bare number/preset = WCAG; `{ wcag }` / `{ apca }` to pick the metric).\n */\n contrast?: HCPair<ContrastSpec>;\n\n /**\n * Optional dependency on another color. Accepts either a\n * `GlazeColorToken` (returned by another `glaze.color()`) or a raw\n * `GlazeColorValue` (hex / CSS strings / `{ r, g, b }` / `{ h, s, l }` / …),\n * which is automatically wrapped in `glaze.color(value)`.\n *\n * When set:\n * - `contrast` is solved against the base's resolved variant\n * per-scheme (light / dark / lightContrast / darkContrast).\n * - Relative `tone: '+N'` / `'-N'` is anchored to the base's\n * tone per-scheme (matches theme behavior for dependent colors).\n * - Relative `hue: '+N'` / `'-N'` still anchors to the seed (the\n * value passed to `glaze.color()`), not the base.\n * - When the base was created via the structured form (with explicit\n * `hue`/`saturation`/`tone`), it is resolved at full range\n * (`lightTone: false`) for the linking math — ensuring the\n * contrast/tone anchor matches the input tone, not the\n * windowed output. The base's own `.resolve()` output is unaffected.\n *\n * The base token's `.resolve()` is called lazily on first resolve and\n * its result is captured by reference; later mutations to the base's\n * defining call don't apply (matches existing token snapshot semantics).\n */\n base?: GlazeColorToken | GlazeColorValue;\n\n /**\n * Fixed opacity (0–1). Output includes alpha in the CSS value.\n * Combining with `contrast` is not recommended (perceived tone\n * becomes unpredictable) — a `console.warn` is emitted in that case.\n */\n opacity?: number;\n\n /**\n * Optional human-readable name for the token. Used in error and\n * warning messages (otherwise an internal name like `\"value\"` is\n * used). Does not affect output keys.\n */\n name?: string;\n\n /**\n * Per-color override for the hue-independent \"safe\" chroma limit used in\n * OKHSL↔sRGB conversions (luminance, contrast solving, output formatting).\n * Falls through to the per-theme / per-token `pastel` override when omitted.\n * @see GlazeConfigOverride.pastel\n */\n pastel?: boolean;\n\n /**\n * Semantic role against `base` / the literal seed: how this token is used.\n * Fixes APCA contrast polarity. Same resolution chain as\n * `RegularColorDef.role`.\n */\n role?: RoleInput;\n}\n\n/**\n * Object input for `glaze.color()` that carries a raw color value plus\n * optional color overrides in the same object.\n *\n * ```ts\n * glaze.color({ from: '#1a1a2e', base: bg, contrast: 'AA' })\n * glaze.color({ from: { r: 38, g: 252, b: 178 }, tone: '+10' })\n * ```\n */\nexport interface GlazeFromInput extends GlazeColorOverrides {\n /** The source color value. Accepts the same forms as a bare `GlazeColorValue`. */\n from: GlazeColorValue;\n}\n\n/** Options for `GlazeColorToken.css()`. */\nexport interface GlazeColorCssOptions {\n /**\n * Custom property base name (without leading `--`). Required.\n * Becomes the variable identifier in the output, e.g.\n * `name: 'brand'` → `--brand-color: …`.\n */\n name: string;\n /** Output color format. Default: 'oklch'. */\n format?: GlazeColorFormat;\n /**\n * Suffix appended to the name. Default: '-color' (matches\n * `theme.css` default).\n */\n suffix?: string;\n /**\n * Emit hue as a separate custom property, referenced via `var()`.\n * Requires `format: 'oklch'` and a pastel token. oklch + all-pastel only.\n */\n splitHue?: boolean;\n}\n\n/** Return type for `glaze.color()`. */\nexport interface GlazeColorToken {\n /** Resolve the color across all scheme variants. */\n resolve(): ResolvedColor;\n /** Export as a flat token map (no color name key). */\n token(options?: GlazeTokenOptions): Record<string, string>;\n /**\n * Export as a tasty style-to-state binding (no color name key).\n * Uses `#name` keys and state aliases (`''`, `'@media(prefers-color-scheme: dark)'`, etc.).\n * @see https://tasty.style/docs\n */\n tasty(options?: GlazeTokenOptions): Record<string, string>;\n /** Export as a flat JSON map (no color name key). */\n json(options?: GlazeJsonOptions): Record<string, string>;\n /** Export as CSS custom property declarations grouped by scheme variant. */\n css(options: GlazeColorCssOptions): GlazeCssResult;\n /**\n * Export as W3C DTCG color tokens (one per scheme variant, no color name\n * key). Each entry is a full `{ $type: 'color', $value }` token.\n * @see https://www.designtokens.org/\n */\n dtcg(options?: GlazeDtcgOptions): GlazeColorDtcgResult;\n /**\n * Export as a single W3C DTCG Resolver-Module document for this color,\n * keyed by `name` across all scheme variants. `name` is required.\n * @see https://www.designtokens.org/\n */\n dtcgResolver(\n options: GlazeColorDtcgResolverOptions,\n ): GlazeDtcgResolverDocument;\n /**\n * Export as a Tailwind CSS v4 `@theme` block (light baseline) plus dark /\n * high-contrast overrides. Returns a single ready-to-paste CSS string.\n * `name` is required (forms `--color-<name>`).\n * @see https://tailwindcss.com/docs/theme\n */\n tailwind(options: GlazeColorTailwindOptions): string;\n /**\n * Serialize the token as a JSON-safe object. Captures the original\n * input value, overrides, and config so it can be rehydrated via\n * `glaze.colorFrom(...)`. `base` is recursively serialized.\n * Optional `override` is merged over the instance local at export time.\n */\n export(override?: GlazeConfigOverride): GlazeColorTokenExport;\n}\n\n/**\n * JSON-safe serialization of a `glaze.color()` token. Pass to\n * `glaze.colorFrom(...)` to rehydrate.\n */\nexport interface GlazeColorTokenExport {\n /** Snapshot kind. Always written by `token.export()`; optional on legacy snapshots. */\n kind?: 'color';\n /** Schema version. Always written by `token.export()`; optional on legacy snapshots. */\n version?: number;\n /**\n * Discriminator for the source overload that created the token.\n * - `'value'`: created via `glaze.color(value)` or `glaze.color({ from, ...overrides })`.\n * - `'structured'`: created via `glaze.color({ hue, saturation, ... })`.\n */\n form: 'value' | 'structured';\n /** Original input. For `form: 'value'` this is the raw `GlazeColorValue`; for `form: 'structured'` this is the structured input. */\n input: GlazeColorValue | GlazeColorInputExport;\n /**\n * Overrides recorded at creation time. `base` is recursively\n * serialized. Only present for `form: 'value'`.\n */\n overrides?: GlazeColorOverridesExport;\n /**\n * Effective config freeze from `.export()` — `getConfig() ∪ local ∪\n * exportArg` at call time. Used by `glaze.colorFrom()` to pin\n * deterministic behavior across later `configure()` calls.\n */\n config?: GlazeConfigOverride;\n}\n\n/**\n * JSON-safe serialization of a `glaze.palette()` composition.\n * Pass to `glaze.paletteFrom(...)` to rehydrate.\n */\nexport interface GlazePaletteExport {\n /** Snapshot kind. Always written by `palette.export()`. */\n kind?: 'palette';\n /** Schema version. Always written by `palette.export()`. */\n version?: number;\n /** Per-theme authoring snapshots keyed by theme name. */\n themes: Record<string, GlazeThemeExport>;\n /** Primary theme name, if set on the palette. */\n primary?: string;\n}\n\n/**\n * Serializable shape of a structured `glaze.color({...})` input.\n * Differs from `GlazeColorInput` only in that `base` is replaced by an\n * `export` instead of a token reference.\n */\nexport interface GlazeColorInputExport {\n hue: number;\n saturation: number;\n tone: HCPair<number | ExtremeValue>;\n saturationFactor?: number;\n mode?: AdaptationMode;\n autoFlip?: boolean;\n opacity?: number;\n base?: GlazeColorTokenExport | GlazeColorValue;\n contrast?: HCPair<ContrastSpec>;\n name?: string;\n pastel?: boolean;\n role?: RoleInput;\n}\n\n/**\n * Serializable shape of `GlazeColorOverrides`. `base` is replaced by\n * its export (or left as a `GlazeColorValue` if it was originally a value).\n */\nexport interface GlazeColorOverridesExport {\n hue?: number | RelativeValue;\n saturation?: number;\n tone?: HCPair<ToneValue>;\n saturationFactor?: number;\n mode?: AdaptationMode;\n autoFlip?: boolean;\n contrast?: HCPair<ContrastSpec>;\n base?: GlazeColorTokenExport | GlazeColorValue;\n opacity?: number;\n name?: string;\n pastel?: boolean;\n role?: RoleInput;\n}\n\n// ============================================================================\n// Theme API\n// ============================================================================\n\nexport interface GlazeTheme {\n /** The hue seed (0–360). */\n readonly hue: number;\n /** The saturation seed (0–100). */\n readonly saturation: number;\n /** The effective config for this theme. */\n getConfig(): GlazeConfigResolved;\n\n /** Add/replace colors (additive merge with existing definitions). */\n colors(defs: ColorMap): void;\n\n /** Get a color definition by name. */\n color(name: string): ColorDef | undefined;\n /** Set a single color definition. */\n color(name: string, def: ColorDef): void;\n\n /** Remove one or more color definitions. */\n remove(names: string | string[]): void;\n\n /** Check if a color is defined. */\n has(name: string): boolean;\n\n /** List all defined color names. */\n list(): string[];\n\n /** Clear all color definitions. */\n reset(): void;\n\n /** Export the theme configuration as a JSON-safe object. */\n export(override?: GlazeConfigOverride): GlazeThemeExport;\n\n /** Create a child theme inheriting all color definitions. */\n extend(options: GlazeExtendOptions): GlazeTheme;\n\n /** Resolve all colors and return the result map. */\n resolve(): Map<string, ResolvedColor>;\n\n /**\n * Export as a flat token map grouped by scheme variant.\n *\n * ```ts\n * theme.tokens()\n * // → { light: { surface: 'okhsl(...)' }, dark: { surface: 'okhsl(...)' } }\n * ```\n */\n tokens(options?: GlazeJsonOptions): Record<string, Record<string, string>>;\n\n /**\n * Export as tasty style-to-state bindings.\n * Uses `#name` color token keys and state aliases (`''`, `'@media(prefers-color-scheme: dark)'`, etc.).\n * Spread into component styles or register as a recipe via `configure({ recipes })`.\n * @see https://tasty.style/docs\n */\n tasty(options?: GlazeTokenOptions): Record<string, Record<string, string>>;\n\n /** Export as plain JSON. */\n json(options?: GlazeJsonOptions): Record<string, Record<string, string>>;\n\n /** Export as CSS custom property declarations. */\n css(options?: GlazeCssOptions): GlazeCssResult;\n\n /**\n * Export as W3C Design Tokens Format Module (2025.10) documents, one per\n * scheme variant. Consumable by Figma, Tokens Studio, Style Dictionary,\n * Terrazzo, and any DTCG-compatible tool.\n * @see https://www.designtokens.org/\n */\n dtcg(options?: GlazeDtcgOptions): GlazeDtcgResult;\n\n /**\n * Export as a single W3C DTCG Resolver-Module document describing every\n * scheme variant as one `sets` entry plus a single `scheme` modifier with a\n * context per variant. Consumable by resolver tools such as Dispersa.\n * @see https://www.designtokens.org/\n */\n dtcgResolver(options?: GlazeDtcgResolverOptions): GlazeDtcgResolverDocument;\n\n /**\n * Export as a Tailwind CSS v4 `@theme` block (light baseline) plus dark /\n * high-contrast overrides under configurable selectors. Returns a single\n * ready-to-paste CSS string.\n * @see https://tailwindcss.com/docs/theme\n */\n tailwind(options?: GlazeTailwindOptions): string;\n}\n\nexport interface GlazeExtendOptions {\n hue?: number;\n saturation?: number;\n colors?: ColorMap;\n /** Config override for the child theme. Merged with the parent's override. */\n config?: GlazeConfigOverride;\n}\n\n// ============================================================================\n// Palette API\n// ============================================================================\n\nexport interface GlazeTokenOptions {\n /** Prefix mode. `true` uses \"<themeName>-\", or provide a custom map. */\n prefix?: boolean | Record<string, string>;\n /** Override state aliases for this export. */\n states?: {\n dark?: string;\n highContrast?: string;\n };\n /** Override which scheme variants to include. */\n modes?: GlazeOutputModes;\n /** Output color format. Default: 'oklch'. */\n format?: GlazeColorFormat;\n /**\n * Emit hue as a separate custom property, referenced via `var()`.\n * Requires `format: 'oklch'` and every color to be pastel.\n */\n splitHue?: boolean;\n /**\n * Base name for the theme-level hue var (`--{name}-hue`). Default: `'theme'`.\n * Palette export auto-derives this from the theme name.\n */\n name?: string;\n}\n\nexport interface GlazeJsonOptions {\n /** Override which scheme variants to include. */\n modes?: GlazeOutputModes;\n /** Output color format. Default: 'oklch'. */\n format?: GlazeColorFormat;\n}\n\nexport interface GlazeCssOptions {\n /** Output color format. Default: 'oklch'. */\n format?: GlazeColorFormat;\n /** Suffix appended to each CSS custom property name. Default: '-color'. */\n suffix?: string;\n /**\n * Emit hue as a separate custom property, referenced via `var()`.\n * Requires `format: 'oklch'` and every color to be pastel.\n */\n splitHue?: boolean;\n /**\n * Base name for the theme-level hue var (`--{name}-hue`). Default: `'theme'`.\n * Palette export auto-derives this from the theme name.\n */\n name?: string;\n}\n\n/** CSS custom property declarations grouped by scheme variant. */\nexport interface GlazeCssResult {\n light: string;\n dark: string;\n lightContrast: string;\n darkContrast: string;\n}\n\n// ============================================================================\n// DTCG & Tailwind export types\n// ============================================================================\n\n/**\n * Color space used for DTCG `$value` color objects.\n * @see https://www.designtokens.org/\n */\nexport type DtcgColorSpace = 'srgb' | 'oklch';\n\n/**\n * A DTCG color `$value` in the sRGB color space: gamma sRGB components in\n * 0–1 plus a 6-digit `hex` hint. Universally understood by Figma, Tokens\n * Studio, Style Dictionary, and every DTCG reader.\n */\nexport interface DtcgSrgbColorValue {\n colorSpace: 'srgb';\n components: [number, number, number];\n hex: HexColor;\n /** Opacity 0–1. Omitted when fully opaque (alpha = 1). */\n alpha?: number;\n}\n\n/**\n * A DTCG color `$value` in the OKLCH color space: `[L, C, H]` components\n * (L/C: 0–1, H: degrees). Wide-gamut and Glaze-native; no `hex` is emitted.\n */\nexport interface DtcgOklchColorValue {\n colorSpace: 'oklch';\n components: [number, number, number];\n /** Opacity 0–1. Omitted when fully opaque (alpha = 1). */\n alpha?: number;\n}\n\n/** A DTCG `$value` for a color token, in either supported color space. */\nexport type DtcgColorValue = DtcgSrgbColorValue | DtcgOklchColorValue;\n\n/**\n * A single W3C DTCG color token: `{ $type: 'color', $value }`.\n * `$description` is optional and not populated by Glaze today.\n */\nexport interface DtcgColorToken {\n $type: 'color';\n $value: DtcgColorValue;\n $description?: string;\n}\n\n/**\n * A W3C Design Tokens Format Module (2025.10) token tree for one scheme.\n * Glaze emits one document per scheme variant — the most tool-compatible\n * convention (one file per Style Dictionary theme / Tokens Studio set /\n * Figma variable mode).\n */\nexport type DtcgDocument = Record<string, DtcgColorToken>;\n\n/** DTCG token documents grouped by scheme variant. Light is always present. */\nexport interface GlazeDtcgResult {\n light: DtcgDocument;\n dark?: DtcgDocument;\n lightContrast?: DtcgDocument;\n darkContrast?: DtcgDocument;\n}\n\n/** A single DTCG color token grouped by scheme variant (standalone tokens). */\nexport interface GlazeColorDtcgResult {\n light: DtcgColorToken;\n dark?: DtcgColorToken;\n lightContrast?: DtcgColorToken;\n darkContrast?: DtcgColorToken;\n}\n\n/** Options for `theme.dtcg()` / `palette.dtcg()`. */\nexport interface GlazeDtcgOptions {\n /** Override which scheme variants to include. */\n modes?: GlazeOutputModes;\n /**\n * DTCG color space. `'srgb'` (default) emits sRGB components plus a `hex`\n * hint — universally understood (Figma, Tokens Studio). `'oklch'` emits\n * OKLCH components with no hex — Glaze-native, wide-gamut.\n */\n colorSpace?: DtcgColorSpace;\n}\n\n// ============================================================================\n// DTCG Resolver-Module export types\n// (W3C Design Tokens Resolver Module — one document for all scheme variants)\n// ============================================================================\n\n/**\n * A node in a DTCG Resolver-Module token tree: either a leaf color token or a\n * nested group. A flat `DtcgDocument` (top-level color-name keys) is a valid\n * shallow tree, so Glaze's per-scheme documents slot directly into\n * `sets.<name>.sources` and `modifiers.<name>.contexts.<ctx>` entries.\n */\nexport interface DtcgTokenTree {\n [key: string]: DtcgColorToken | DtcgTokenTree;\n}\n\n/** A named set in a resolver document: a list of token-tree sources. */\nexport interface DtcgResolverSet {\n sources: DtcgTokenTree[];\n}\n\n/**\n * A named modifier (an axis such as `scheme`) in a resolver document.\n * `default` names the context applied when no override is selected; `contexts`\n * maps each context name to the token-tree overrides applied for it.\n */\nexport interface DtcgResolverModifier {\n default: string;\n contexts: Record<string, DtcgTokenTree[]>;\n}\n\n/** A JSON-pointer `$ref` entry in a resolver document's `resolutionOrder`. */\nexport interface DtcgResolverRef {\n $ref: string;\n}\n\n/**\n * A W3C DTCG Resolver-Module document. Describes every scheme variant in a\n * single file as `sets` (base token sources) plus `modifiers` (per-context\n * overrides) composed in `resolutionOrder`. Consumable by resolver tools such\n * as Dispersa.\n * @see https://www.designtokens.org/\n */\nexport interface GlazeDtcgResolverDocument {\n version: string;\n sets: Record<string, DtcgResolverSet>;\n modifiers: Record<string, DtcgResolverModifier>;\n resolutionOrder: DtcgResolverRef[];\n}\n\n/** Renaming of the four scheme variants as resolver-modifier context names. */\nexport interface GlazeDtcgResolverContextNames {\n light?: string;\n dark?: string;\n lightContrast?: string;\n darkContrast?: string;\n}\n\n/**\n * Options for `theme.dtcgResolver()` / `palette.dtcgResolver()`. Extends\n * `GlazeDtcgOptions` so `modes` + `colorSpace` pass through to the underlying\n * per-scheme `dtcg()` build.\n */\nexport interface GlazeDtcgResolverOptions extends GlazeDtcgOptions {\n /** Name of the single set holding the default (light) token tree. Default `'base'`. */\n setName?: string;\n /**\n * Name of the modifier describing the scheme axis. Default `'scheme'`\n * (Glaze's term for the light / dark / high-contrast axis).\n */\n modifierName?: string;\n /**\n * Override the four context names emitted on the modifier. Defaults to the\n * Glaze variant keys: `light` / `dark` / `lightContrast` / `darkContrast`.\n */\n contextNames?: GlazeDtcgResolverContextNames;\n /** Resolver document version. Default `'2025.10'`. */\n version?: string;\n}\n\n/** Options for `glaze.color().dtcgResolver()`. `name` is required. */\nexport interface GlazeColorDtcgResolverOptions extends GlazeDtcgResolverOptions {\n /** Token name keying the color within each token tree. Required. */\n name: string;\n}\n\n/** Options for `theme.tailwind()` / `palette.tailwind()`. */\nexport interface GlazeTailwindOptions {\n /** Override which scheme variants to include. */\n modes?: GlazeOutputModes;\n /** Output color format. Default: 'oklch'. */\n format?: GlazeColorFormat;\n /**\n * CSS custom property namespace, forming `--<namespace><name>`.\n * Default: `'color-'` → `--color-surface`. (Tailwind v4's `--color-*`\n * convention, which auto-generates `bg-*` / `text-*` / `border-*`.)\n *\n * Named `namespace` rather than `prefix` to avoid clashing with the\n * palette theme-prefix option on `palette.tailwind()`.\n */\n namespace?: string;\n /**\n * Selector wrapping the dark-scheme overrides. Default: `'.dark'`.\n * Pass a media query such as `'@media (prefers-color-scheme: dark)'` to\n * drive dark mode from the OS preference instead of a class.\n */\n darkSelector?: string;\n /**\n * Selector wrapping the light high-contrast overrides. Default:\n * `'.high-contrast'`. The combined dark + high-contrast overrides are\n * emitted under `${darkSelector}${highContrastSelector}` (e.g.\n * `.dark.high-contrast`).\n */\n highContrastSelector?: string;\n}\n\n/** Options for `glaze.color().tailwind()`. `name` is required. */\nexport interface GlazeColorTailwindOptions extends GlazeTailwindOptions {\n /** Custom property base name (without leading `--`). Required. */\n name: string;\n}\n\n/** Options for `glaze.palette()` creation. */\nexport interface GlazePaletteOptions {\n /**\n * Name of the primary theme. The primary theme's tokens are duplicated\n * without prefix in all exports, providing convenient short aliases\n * alongside the prefixed versions. Can be overridden per-export.\n *\n * @example\n * ```ts\n * const palette = glaze.palette({ brand, accent }, { primary: 'brand' });\n * palette.tokens()\n * // → { light: { 'brand-surface': '...', 'surface': '...', 'accent-surface': '...' } }\n * ```\n */\n primary?: string;\n}\n\n/** Options shared by palette `tokens()`, `tasty()`, and `css()` exports. */\nexport interface GlazePaletteExportOptions {\n /**\n * Prefix mode. `true` uses `\"<themeName>-\"`, or provide a custom map.\n * Defaults to `true` for palette export methods.\n * Set to `false` explicitly to disable prefixing. Colliding keys\n * produce a console.warn and the first-written value wins.\n */\n prefix?: boolean | Record<string, string>;\n /**\n * Override the palette-level primary theme for this export.\n * Pass a theme name to set/change the primary, or `false` to disable it.\n * When omitted, inherits the palette-level `primary`.\n */\n primary?: string | false;\n /**\n * Emit hue as a separate custom property, referenced via `var()`.\n * Requires `format: 'oklch'` and every color to be pastel.\n */\n splitHue?: boolean;\n}\n\nexport interface GlazePalette {\n /** Theme names in insertion order. */\n list(): string[];\n\n /** Primary theme name, if set at palette creation. */\n readonly primary: string | undefined;\n\n /** Get a theme by name. Returns the live instance held by the palette. */\n theme(name: string): GlazeTheme | undefined;\n\n /**\n * Shallow copy of the theme map (same instances the palette holds).\n * Mutating a returned theme affects subsequent palette exports.\n */\n themes(): Record<string, GlazeTheme>;\n\n /**\n * Export the palette authoring configuration as a JSON-safe object.\n * Restorable via `glaze.paletteFrom(...)`. Distinct from `json()`, which\n * emits resolved color strings. Optional `override` is forwarded to each\n * nested `theme.export(override)`.\n */\n export(override?: GlazeConfigOverride): GlazePaletteExport;\n\n /**\n * Export all themes as a flat token map grouped by scheme variant.\n * Prefix defaults to `true` — all tokens are prefixed with the theme name.\n * Inherits the palette-level `primary`; override per-call or pass `false` to disable.\n *\n * ```ts\n * const palette = glaze.palette({ brand, accent }, { primary: 'brand' });\n * palette.tokens()\n * // → { light: { 'brand-surface': '...', 'surface': '...', 'accent-surface': '...' } }\n * ```\n */\n tokens(\n options?: GlazeJsonOptions & GlazePaletteExportOptions,\n ): Record<string, Record<string, string>>;\n\n /**\n * Export all themes as tasty style-to-state bindings.\n * Uses `#name` color token keys and state aliases (`''`, `'@media(prefers-color-scheme: dark)'`, etc.).\n * Prefix defaults to `true`. Inherits the palette-level `primary`.\n * @see https://tasty.style/docs\n */\n tasty(\n options?: GlazeTokenOptions & GlazePaletteExportOptions,\n ): Record<string, Record<string, string>>;\n\n /** Export all themes as plain JSON grouped by theme name. */\n json(\n options?: GlazeJsonOptions & {\n prefix?: boolean | Record<string, string>;\n },\n ): Record<string, Record<string, Record<string, string>>>;\n\n /** Export all themes as CSS custom property declarations. */\n css(options?: GlazeCssOptions & GlazePaletteExportOptions): GlazeCssResult;\n\n /**\n * Export all themes as W3C DTCG documents, one per scheme variant.\n * Prefix defaults to `true`. Inherits the palette-level `primary`.\n * @see https://www.designtokens.org/\n */\n dtcg(options?: GlazeDtcgOptions & GlazePaletteExportOptions): GlazeDtcgResult;\n\n /**\n * Export all themes as a single W3C DTCG Resolver-Module document. Prefix\n * defaults to `true`. Inherits the palette-level `primary`.\n * @see https://www.designtokens.org/\n */\n dtcgResolver(\n options?: GlazeDtcgResolverOptions & GlazePaletteExportOptions,\n ): GlazeDtcgResolverDocument;\n\n /**\n * Export all themes as a Tailwind CSS v4 `@theme` block plus dark /\n * high-contrast overrides. Returns a single ready-to-paste CSS string.\n * Prefix defaults to `true`.\n * @see https://tailwindcss.com/docs/theme\n */\n tailwind(options?: GlazeTailwindOptions & GlazePaletteExportOptions): string;\n}\n","/**\n * Authoring-export helpers: schema version, type guards, and restore\n * validation shared by `themeFrom` / `colorFrom` / `paletteFrom`.\n */\n\nimport { GLAZE_EXPORT_VERSION } from './types';\nimport type {\n GlazeColorTokenExport,\n GlazeExportKind,\n GlazePaletteExport,\n GlazeThemeExport,\n} from './types';\n\nexport { GLAZE_EXPORT_VERSION };\n\nfunction isPlainObject(data: unknown): data is Record<string, unknown> {\n return typeof data === 'object' && data !== null && !Array.isArray(data);\n}\n\n/**\n * Reject unknown / invalid schema versions. Missing `version` is allowed\n * (legacy snapshots). Present versions must be an integer in\n * `1..=GLAZE_EXPORT_VERSION`.\n */\nexport function assertExportVersion(\n data: { version?: unknown },\n factory: string,\n): void {\n if (data.version === undefined) return;\n if (\n typeof data.version !== 'number' ||\n !Number.isInteger(data.version) ||\n data.version < 1\n ) {\n throw new Error(\n `${factory}: invalid \"version\" field — expected an integer >= 1 (got ${JSON.stringify(data.version)}).`,\n );\n }\n if (data.version > GLAZE_EXPORT_VERSION) {\n throw new Error(\n `${factory}: unsupported export version ${data.version} (this library supports version ${GLAZE_EXPORT_VERSION}). Upgrade @tenphi/glaze to load this snapshot.`,\n );\n }\n}\n\n/**\n * When `kind` is present, it must match the factory. Missing `kind` is\n * allowed for legacy snapshots.\n */\nexport function assertExportKind(\n data: { kind?: unknown },\n expected: GlazeExportKind,\n factory: string,\n): void {\n if (data.kind === undefined) return;\n if (data.kind !== expected) {\n throw new Error(\n `${factory}: expected kind \"${expected}\", got ${JSON.stringify(data.kind)}.`,\n );\n }\n}\n\nfunction hasThemeShape(data: Record<string, unknown>): boolean {\n return (\n typeof data.hue === 'number' &&\n typeof data.saturation === 'number' &&\n !('form' in data) &&\n !('themes' in data)\n );\n}\n\nfunction hasColorTokenShape(data: Record<string, unknown>): boolean {\n return data.form === 'value' || data.form === 'structured';\n}\n\nfunction hasPaletteShape(data: Record<string, unknown>): boolean {\n return (\n isPlainObject(data.themes) &&\n !('form' in data) &&\n typeof data.hue !== 'number'\n );\n}\n\n/** Type guard for theme authoring snapshots (prefers `kind`, falls back to shape). */\nexport function isThemeExport(data: unknown): data is GlazeThemeExport {\n if (!isPlainObject(data)) return false;\n if (data.kind === 'theme') return hasThemeShape(data);\n if (data.kind !== undefined) return false;\n return hasThemeShape(data);\n}\n\n/** Type guard for color-token authoring snapshots. */\nexport function isColorTokenExport(\n data: unknown,\n): data is GlazeColorTokenExport {\n if (!isPlainObject(data)) return false;\n if (data.kind === 'color') return hasColorTokenShape(data);\n if (data.kind !== undefined) return false;\n return hasColorTokenShape(data);\n}\n\n/** Type guard for palette authoring snapshots. */\nexport function isPaletteExport(data: unknown): data is GlazePaletteExport {\n if (!isPlainObject(data)) return false;\n if (data.kind === 'palette') return hasPaletteShape(data);\n if (data.kind !== undefined) return false;\n return hasPaletteShape(data);\n}\n","/**\n * Export-time guards for color format and channel-splitting prerequisites.\n */\n\nimport type {\n GlazeColorFormat,\n GlazeOutputModes,\n ResolvedColor,\n} from './types';\n\nconst NON_NATIVE_FORMATS = new Set<GlazeColorFormat>(['okhsl', 'okhst']);\n\n/**\n * Throw when a non-native Glaze color space is requested for an export that\n * emits raw CSS or non-Tasty token maps.\n */\nexport function assertNativeFormat(\n format: GlazeColorFormat | undefined,\n method: string,\n): void {\n if (format !== undefined && NON_NATIVE_FORMATS.has(format)) {\n throw new Error(\n `glaze: ${format} output is only supported by tasty() (not a native CSS color space). ` +\n `Use tasty({ format: '${format}' }) or pick a native format (oklch|hsl|rgb) for ${method}().`,\n );\n }\n}\n\ntype SchemeField = 'light' | 'dark' | 'lightContrast' | 'darkContrast';\n\nconst SCHEME_FIELDS: {\n field: SchemeField;\n modes: (modes: Required<GlazeOutputModes>) => boolean;\n}[] = [\n { field: 'light', modes: () => true },\n { field: 'dark', modes: (m) => m.dark },\n { field: 'lightContrast', modes: (m) => m.highContrast },\n {\n field: 'darkContrast',\n modes: (m) => m.dark && m.highContrast,\n },\n];\n\n/**\n * Throw when `splitHue` is enabled but any exported color is not pastel.\n * Hue rotation is only clip-free when chroma is bounded by the hue-independent\n * safe chroma (`computeSafeChromaOKLCH`).\n */\nexport function assertAllPastel(\n resolved: Map<string, ResolvedColor>,\n modes: Required<GlazeOutputModes>,\n): void {\n const nonPastel: string[] = [];\n\n for (const [name, color] of resolved) {\n for (const { field, modes: active } of SCHEME_FIELDS) {\n if (!active(modes)) continue;\n const variant = color[field];\n if (variant.pastel !== true) {\n if (!nonPastel.includes(name)) nonPastel.push(name);\n break;\n }\n }\n }\n\n if (nonPastel.length === 0) return;\n\n throw new Error(\n 'glaze: splitHue requires every color to be pastel (hue rotation is only ' +\n 'clip-free when chroma is bounded by the hue-independent safe chroma). ' +\n `Non-pastel: ${nonPastel.join(', ')}. ` +\n 'Set pastel: true (per-theme, per-token, or per-color) or drop splitHue.',\n );\n}\n","/**\n * Small shared helpers used across the resolver pipeline:\n * - HC-pair selection (`pairNormal` / `pairHC`)\n * - Absolute / relative / extreme tone discrimination\n * - Generic numeric helpers (`clamp`, hue resolution, relative-value parsing)\n */\n\nimport type { ExtremeValue, HCPair, RelativeValue, ToneValue } from './types';\n\nexport function pairNormal<T>(p: HCPair<T>): T {\n return Array.isArray(p) ? p[0] : p;\n}\n\nexport function pairHC<T>(p: HCPair<T>): T {\n return Array.isArray(p) ? p[1] : p;\n}\n\nexport function clamp(v: number, min: number, max: number): number {\n return Math.max(min, Math.min(max, v));\n}\n\n/** Whether a tone value is an extreme keyword (`'max'` / `'min'`). */\nexport function isExtremeTone(value: ToneValue): value is ExtremeValue {\n return value === 'max' || value === 'min';\n}\n\n/**\n * Parse a value that can be absolute (number) or relative (signed string).\n * Returns the numeric value and whether it's relative.\n */\nexport function parseRelativeOrAbsolute(value: number | RelativeValue): {\n value: number;\n relative: boolean;\n} {\n if (typeof value === 'number') {\n return { value, relative: false };\n }\n return { value: parseFloat(value), relative: true };\n}\n\n/**\n * Parse a tone value into a normalized shape.\n * - `'max'` / `'min'` → `{ kind: 'extreme', value: 100 | 0 }` (an absolute\n * author tone before scheme mapping — `'max'` is 100, `'min'` is 0).\n * - `'+N'` / `'-N'` → `{ kind: 'relative', value: ±N }`.\n * - number → `{ kind: 'absolute', value }`.\n */\nexport function parseToneValue(value: ToneValue): {\n kind: 'absolute' | 'relative' | 'extreme';\n value: number;\n} {\n if (value === 'max') return { kind: 'extreme', value: 100 };\n if (value === 'min') return { kind: 'extreme', value: 0 };\n if (typeof value === 'number') return { kind: 'absolute', value };\n return { kind: 'relative', value: parseFloat(value) };\n}\n\n/**\n * Compute the effective hue for a color, given the theme seed hue\n * and an optional per-color hue override.\n */\nexport function resolveEffectiveHue(\n seedHue: number,\n defHue: number | RelativeValue | undefined,\n): number {\n if (defHue === undefined) return seedHue;\n const parsed = parseRelativeOrAbsolute(defHue);\n if (parsed.relative) {\n return (((seedHue + parsed.value) % 360) + 360) % 360;\n }\n return ((parsed.value % 360) + 360) % 360;\n}\n\n/**\n * Check whether a tone value represents an absolute root definition\n * (i.e. a number, not a relative string). Extreme keywords (`'max'` /\n * `'min'`) also count — they need no base.\n */\nexport function isAbsoluteTone(tone: HCPair<ToneValue> | undefined): boolean {\n if (tone === undefined) return false;\n const normal = Array.isArray(tone) ? tone[0] : tone;\n return typeof normal === 'number' || isExtremeTone(normal);\n}\n","/**\n * OKHST — the contrast-uniform tone space.\n *\n * OKHST is OKHSL with its lightness axis replaced by a contrast-uniform\n * \"tone\" axis. It shares `h` / `s` with OKHSL verbatim and swaps `l` for\n * `t`. This module owns:\n *\n * - the closed-form tone transfers (`toTone` / `fromTone`) at a fixed\n * reference eps, plus the gray luminance helpers (`lToY` / `yToL`),\n * - the `{ h, s, t }` <-> `{ h, s, l }` color-space converters,\n * - the resolved-variant edge adapter (`variantToOkhsl`),\n * - the per-scheme tone mapping that replaced the Möbius dark curve\n * (`mapToneForScheme`), the dark desaturation reducer, and the solver's scheme\n * tone range.\n *\n * See `docs/okhst.md` for the full specification and the calibrated\n * default constants.\n */\n\nimport { clamp } from './hc-pair';\nimport { toe, toeInv } from './okhsl-color-math';\nimport type { AdaptationMode, GlazeConfigResolved, ToneWindow } from './types';\n\n/**\n * Reference eps for the OKHST color space. WCAG 2 contrast is\n * `(Y_hi + 0.05) / (Y_lo + 0.05)`, so an eps of `0.05` makes equal tone\n * steps yield equal WCAG contrast. This is the canonical eps used by\n * `okhst()` input, `{ h, s, t }` input, stored `ResolvedColorVariant.t`,\n * relative `tone` offsets, and the contrast solver.\n */\nexport const REF_EPS = 0.05;\n\n// ============================================================================\n// Gray luminance <-> OKHSL lightness (closed form)\n// ============================================================================\n\n/**\n * Gray luminance from OKHSL lightness. For an achromatic color the OKLab\n * lightness is `toeInv(l)` and luminance is its cube.\n */\nexport function lToY(l: number): number {\n const L = toeInv(l);\n return L * L * L;\n}\n\n/** OKHSL lightness from gray luminance — exact inverse of {@link lToY}. */\nexport function yToL(y: number): number {\n return toe(Math.cbrt(Math.max(0, y)));\n}\n\n// ============================================================================\n// Tone transfers (luminance domain)\n// ============================================================================\n\n/**\n * Map a luminance `Y` (0–1) to tone (0–100) at the given eps.\n * `toneFromY(0) === 0` and `toneFromY(1) === 100` for any eps.\n */\nexport function toneFromY(y: number, eps: number = REF_EPS): number {\n const num = Math.log(y + eps) - Math.log(eps);\n const den = Math.log(1 + eps) - Math.log(eps);\n return (num / den) * 100;\n}\n\n/** Map a tone (0–100) back to luminance (0–1). Inverse of {@link toneFromY}. */\nexport function yFromTone(t: number, eps: number = REF_EPS): number {\n const den = Math.log(1 + eps) - Math.log(eps);\n return Math.exp((t / 100) * den + Math.log(eps)) - eps;\n}\n\n// ============================================================================\n// Tone transfers (OKHSL lightness domain)\n// ============================================================================\n\n/** OKHSL lightness (0–1) -> tone (0–100). */\nexport function toTone(l: number, eps: number = REF_EPS): number {\n return toneFromY(lToY(l), eps);\n}\n\n/** Tone (0–100) -> OKHSL lightness (0–1). Inverse of {@link toTone}. */\nexport function fromTone(t: number, eps: number = REF_EPS): number {\n return yToL(yFromTone(t, eps));\n}\n\n// ============================================================================\n// Color-space converters\n// ============================================================================\n\n/** Convert OKHST `{ h, s, t }` (t in 0–1) to OKHSL `{ h, s, l }`. */\nexport function okhstToOkhsl(c: { h: number; s: number; t: number }): {\n h: number;\n s: number;\n l: number;\n} {\n return { h: c.h, s: c.s, l: clamp(fromTone(c.t * 100), 0, 1) };\n}\n\n/** Convert OKHSL `{ h, s, l }` to OKHST `{ h, s, t }` (t in 0–1). */\nexport function okhslToOkhst(c: { h: number; s: number; l: number }): {\n h: number;\n s: number;\n t: number;\n} {\n return { h: c.h, s: c.s, t: clamp(toTone(c.l) / 100, 0, 1) };\n}\n\n/**\n * Edge adapter: a resolved variant stores canonical tone `t` (0–1). Convert\n * it to the OKHSL `{ h, s, l }` the formatters and luminance pipeline expect.\n */\nexport function variantToOkhsl(v: { h: number; s: number; t: number }): {\n h: number;\n s: number;\n l: number;\n} {\n return { h: v.h, s: v.s, l: clamp(fromTone(v.t * 100), 0, 1) };\n}\n\n// ============================================================================\n// Scheme tone mapping (replaces the Möbius dark curve)\n// ============================================================================\n\n/**\n * Normalize any {@link ToneWindow} form to `{ lo, hi, eps }`.\n * - `false`: full range `[0, 100]` at the reference eps (boundaries removed,\n * curve preserved).\n * - `[lo, hi]`: endpoints at the reference eps (the common form).\n * - `{ lo, hi, eps }`: passed through (advanced eps tuning).\n */\nexport function normalizeToneWindow(win: ToneWindow): {\n lo: number;\n hi: number;\n eps: number;\n} {\n if (win === false) return { lo: 0, hi: 100, eps: REF_EPS };\n if (Array.isArray(win)) return { lo: win[0], hi: win[1], eps: REF_EPS };\n return { lo: win.lo, hi: win.hi, eps: win.eps };\n}\n\n/**\n * Resolve the active tone window for a scheme as OKHSL-lightness endpoints.\n * - HC variants always return the full range `[0, 100]` with the mode eps.\n * - `false` (= \"no clamping\") is treated as `[0, 100]` with the reference eps.\n */\nfunction activeWindow(\n isHighContrast: boolean,\n kind: 'light' | 'dark',\n config: GlazeConfigResolved,\n): { lo: number; hi: number; eps: number } {\n const win = normalizeToneWindow(\n kind === 'dark' ? config.darkTone : config.lightTone,\n );\n if (isHighContrast) return { lo: 0, hi: 100, eps: win.eps };\n return win;\n}\n\n/**\n * Remap an authored tone (0–100) into a scheme window and return the final\n * OKHSL lightness (0–100). The window endpoints are OKHSL lightnesses; the\n * author tone is positioned within the window's tone interval (using the\n * window's render eps), then converted back to lightness.\n */\nfunction remapToneToLightness(\n authorTone: number,\n win: { lo: number; hi: number; eps: number },\n): number {\n const loT = toTone(win.lo / 100, win.eps);\n const hiT = toTone(win.hi / 100, win.eps);\n const winTone = loT + (authorTone / 100) * (hiT - loT);\n return clamp(fromTone(winTone, win.eps) * 100, 0, 100);\n}\n\n/**\n * Map an authored tone for a scheme and return the canonical stored tone\n * (0–100, reference eps).\n *\n * - `static`: identity — the same tone renders in every scheme.\n * - `auto` + dark: invert (`100 - tone`) then remap into the dark window.\n * - `auto`/`fixed` + light, or `fixed` + dark: remap, no inversion.\n *\n * The window remap uses the mode's render eps to land a final OKHSL\n * lightness; that lightness is then re-expressed as canonical tone so\n * relative offsets and contrast stay comparable across schemes.\n */\nexport function mapToneForScheme(\n authorTone: number,\n mode: AdaptationMode,\n isDark: boolean,\n isHighContrast: boolean,\n config: GlazeConfigResolved,\n): number {\n if (mode === 'static') return clamp(authorTone, 0, 100);\n\n const kind = isDark ? 'dark' : 'light';\n const win = activeWindow(isHighContrast, kind, config);\n\n const inverted = isDark && mode === 'auto' ? 100 - authorTone : authorTone;\n const finalL = remapToneToLightness(clamp(inverted, 0, 100), win);\n return clamp(toTone(finalL / 100), 0, 100);\n}\n\n// ============================================================================\n// Saturation\n// ============================================================================\n\n/** Dark-scheme desaturation reducer (unchanged from the legacy pipeline). */\nexport function mapSaturationDark(\n s: number,\n mode: AdaptationMode,\n config: GlazeConfigResolved,\n): number {\n if (mode === 'static') return s;\n return s * (1 - config.darkDesaturation);\n}\n\n// ============================================================================\n// Solver support\n// ============================================================================\n\n/**\n * Tone search range (0–1) for the contrast solver in a given scheme.\n * `static` searches the full range; otherwise the scheme window's tone\n * endpoints (HC bypasses to full range).\n */\nexport function schemeToneRange(\n isDark: boolean,\n mode: AdaptationMode,\n isHighContrast: boolean,\n config: GlazeConfigResolved,\n): [number, number] {\n if (mode === 'static') return [0, 1];\n const win = activeWindow(isHighContrast, isDark ? 'dark' : 'light', config);\n return [\n clamp(toTone(win.lo / 100) / 100, 0, 1),\n clamp(toTone(win.hi / 100) / 100, 0, 1),\n ];\n}\n","/**\n * Contrast solver — operates in OKHST tone.\n *\n * Finds the tone closest to a preferred tone that satisfies a contrast\n * floor (WCAG 2 ratio or APCA Lc) against a base color. Because tone is\n * contrast-uniform, the WCAG branch gets a closed-form seed and the search\n * converges quickly.\n *\n * Public API: `findToneForContrast`, `findValueForMixContrast`,\n * `resolveMinContrast`, `resolveContrastForMode`, `apcaContrast`.\n */\n\nimport {\n okhslToLinearSrgb,\n contrastRatioFromLuminance,\n gamutClampedLuminance,\n apcaLuminanceFromLinearRgb,\n} from './okhsl-color-math';\nimport { REF_EPS, fromTone, toneFromY } from './okhst';\nimport { clamp } from './hc-pair';\nimport type { ContrastSpec, HCPair } from './types';\n\nexport type LinearRgb = [number, number, number];\n\nexport type ContrastMetric = 'wcag' | 'apca';\n\n/**\n * Luminance of a linear-sRGB color in the basis the metric expects: WCAG\n * relative luminance for `wcag`, APCA screen luminance (`Ys`) for `apca`.\n */\nexport function metricLuminance(\n metric: ContrastMetric,\n linearRgb: LinearRgb,\n): number {\n return metric === 'apca'\n ? apcaLuminanceFromLinearRgb(linearRgb)\n : gamutClampedLuminance(linearRgb);\n}\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport type ContrastPreset = 'AA' | 'AAA' | 'AA-large' | 'AAA-large';\nexport type MinContrast = number | ContrastPreset;\n\n/**\n * Named APCA Lc floor presets (APCA Bronze Simple Mode conformance levels),\n * independent of role. Use them anywhere an APCA target is accepted.\n *\n * | Preset | Lc | Use case |\n * | ------------- | --- | ---------------------------------------------------- |\n * | `'preferred'` | 90 | Preferred body / column text |\n * | `'body'` | 75 | Minimum body / column text |\n * | `'content'` | 60 | Readable non-body content (~WCAG AA 4.5:1) |\n * | `'large'` | 45 | Large/bold headlines; fine icons/outlines (~3:1) |\n * | `'non-text'` | 30 | Solid icons/controls; placeholder/disabled text |\n * | `'min'` | 15 | Dividers/decorative; APCA \"point of invisibility\" |\n */\nexport type ApcaPreset =\n | 'preferred'\n | 'body'\n | 'content'\n | 'large'\n | 'non-text'\n | 'min';\n\nexport const APCA_PRESETS: Record<ApcaPreset, number> = {\n preferred: 90,\n body: 75,\n content: 60,\n large: 45,\n 'non-text': 30,\n min: 15,\n};\n\n/**\n * APCA-W3 \"Enhanced Level\" delta added to a bare APCA target in high-contrast\n * mode when no explicit HC value is provided (analogous to WCAG AAA over AA).\n * Only applied when neither the outer `contrast` pair nor the inner `apca`\n * pair carries an explicit HC entry.\n */\nexport const APCA_HC_ENHANCEMENT = 15;\n\n/** Upper bound for an APCA Lc target after HC enhancement. */\nexport const APCA_MAX_LC = 106;\n\n/**\n * Resolve an APCA target — a raw Lc number (kept as-is) or an `ApcaPreset`\n * keyword mapped to its Lc value. The magnitude is forced non-negative.\n */\nexport function resolveApcaTarget(value: number | ApcaPreset): number {\n if (typeof value === 'number') return Math.abs(value);\n return APCA_PRESETS[value];\n}\n\n/** Metric + numeric target after resolving a `ContrastSpec` for a mode. */\nexport interface ResolvedContrast {\n metric: 'wcag' | 'apca';\n /** WCAG ratio (>= 1) or APCA Lc magnitude (0–106). */\n target: number;\n /**\n * APCA argument order: which side the resolved (candidate) color plays\n * against the base. `'fg'` (default) → `apcaContrast(yCandidate, yBase)`;\n * `'bg'` → `apcaContrast(yBase, yCandidate)`. Always `'fg'` for WCAG\n * (symmetric, ignored).\n */\n polarity?: 'fg' | 'bg';\n}\n\n// ============================================================================\n// Preset mapping + spec resolution\n// ============================================================================\n\nconst CONTRAST_PRESETS: Record<ContrastPreset, number> = {\n AA: 4.5,\n AAA: 7,\n 'AA-large': 3,\n 'AAA-large': 4.5,\n};\n\n/**\n * WCAG high-contrast auto-promotion (analog of APCA's Enhanced Level). A bare\n * AA / AA-large preset is promoted to its spec-defined \"Enhanced\" successor\n * (SC 1.4.3 → SC 1.4.6) in high-contrast mode. AAA / AAA-large are already\n * the top WCAG tier and are left unchanged. Bare numeric targets have no\n * defined successor tier and are also left unchanged. An explicit HC value\n * (outer or inner pair) always overrides.\n */\nconst WCAG_HC_PROMOTION: Partial<Record<ContrastPreset, ContrastPreset>> = {\n AA: 'AAA',\n 'AA-large': 'AAA-large',\n};\n\nexport function resolveMinContrast(value: MinContrast): number {\n if (typeof value === 'number') {\n return Math.max(1, value);\n }\n return CONTRAST_PRESETS[value];\n}\n\n/**\n * Resolve a WCAG target (number or preset) for a mode, applying the\n * high-contrast auto-promotion when `explicitHC` is false and the value is an\n * AA-family preset. Bare numbers and AAA-family presets pass through.\n */\nfunction resolveWcagTarget(\n value: number | ContrastPreset,\n isHighContrast: boolean,\n explicitHC: boolean,\n): number {\n if (typeof value === 'number') {\n return resolveMinContrast(value);\n }\n if (isHighContrast && !explicitHC) {\n const promoted = WCAG_HC_PROMOTION[value];\n if (promoted !== undefined) return resolveMinContrast(promoted);\n }\n return resolveMinContrast(value);\n}\n\nfunction pickPair<T>(p: HCPair<T>, isHighContrast: boolean): T {\n return Array.isArray(p) ? (isHighContrast ? p[1] : p[0]) : p;\n}\n\n/**\n * Resolve a `ContrastSpec` (already selected from any outer HC pair) for a\n * given mode into `{ metric, target }`. Handles the inner metric HC pair and\n * preset resolution. `polarity` is passed through to the result for the APCA\n * branch (it controls argument order in the solver); WCAG ignores it.\n *\n * `outerExplicitHC` indicates whether the caller selected this `spec` from an\n * explicit high-contrast entry of the outer `contrast` pair. Together with the\n * inner metric pair, it decides whether the HC auto-enhancement fires:\n * - APCA: +15 Lc \"Enhanced Level\" boost when neither level is explicit.\n * - WCAG: AA → AAA / AA-large → AAA-large promotion (SC 1.4.3 → 1.4.6) when\n * neither level is explicit. AAA-family presets and bare numbers are left\n * unchanged (AAA is the top WCAG tier).\n * Defaults to `false` (correct for direct callers, which pass a single\n * selected spec rather than an outer pair).\n */\nexport function resolveContrastForMode(\n spec: ContrastSpec,\n isHighContrast: boolean,\n polarity?: 'fg' | 'bg',\n outerExplicitHC?: boolean,\n): ResolvedContrast {\n if (typeof spec === 'number' || typeof spec === 'string') {\n // A bare string here is a WCAG preset ('AA' / 'AAA' / ...).\n return {\n metric: 'wcag',\n target: resolveWcagTarget(spec, isHighContrast, !!outerExplicitHC),\n };\n }\n if ('apca' in spec) {\n const baseTarget = resolveApcaTarget(pickPair(spec.apca, isHighContrast));\n const innerExplicitHC = Array.isArray(spec.apca);\n const enhanced =\n isHighContrast && !outerExplicitHC && !innerExplicitHC\n ? Math.min(baseTarget + APCA_HC_ENHANCEMENT, APCA_MAX_LC)\n : baseTarget;\n return {\n metric: 'apca',\n target: enhanced,\n polarity: polarity ?? 'fg',\n };\n }\n const innerExplicitHC = Array.isArray(spec.wcag);\n const picked = pickPair(spec.wcag, isHighContrast);\n return {\n metric: 'wcag',\n target: resolveWcagTarget(\n picked,\n isHighContrast,\n !!outerExplicitHC || innerExplicitHC,\n ),\n };\n}\n\n// ============================================================================\n// APCA (SAPC / APCA-W3 0.1.9 simplified)\n// ============================================================================\n\nconst APCA_EXPONENTS = {\n mainTRC: 2.4,\n normBG: 0.56,\n normTXT: 0.57,\n revTXT: 0.62,\n revBG: 0.65,\n};\nconst APCA_BLACK_THRESH = 0.022;\nconst APCA_BLACK_CLIP = 1.414;\nconst APCA_DELTA_Y_MIN = 0.0005;\nconst APCA_SCALE = 1.14;\nconst APCA_LO_OFFSET = 0.027;\n\nfunction apcaSoftClamp(y: number): number {\n const yc = Math.max(0, y);\n if (yc >= APCA_BLACK_THRESH) return yc;\n return yc + Math.pow(APCA_BLACK_THRESH - yc, APCA_BLACK_CLIP);\n}\n\n/**\n * APCA lightness contrast (Lc), signed: positive for dark text on light bg,\n * negative for light text on dark bg. Inputs are screen luminances (0–1).\n */\nexport function apcaContrast(yText: number, yBg: number): number {\n const txt = apcaSoftClamp(yText);\n const bg = apcaSoftClamp(yBg);\n\n if (Math.abs(bg - txt) < APCA_DELTA_Y_MIN) return 0;\n\n let sapc: number;\n if (bg > txt) {\n // Normal polarity: dark text on light bg.\n sapc =\n (Math.pow(bg, APCA_EXPONENTS.normBG) -\n Math.pow(txt, APCA_EXPONENTS.normTXT)) *\n APCA_SCALE;\n return sapc < 0.1 ? 0 : (sapc - APCA_LO_OFFSET) * 100;\n }\n // Reverse polarity: light text on dark bg.\n sapc =\n (Math.pow(bg, APCA_EXPONENTS.revBG) -\n Math.pow(txt, APCA_EXPONENTS.revTXT)) *\n APCA_SCALE;\n return sapc > -0.1 ? 0 : (sapc + APCA_LO_OFFSET) * 100;\n}\n\n// ============================================================================\n// Tone -> luminance (cached)\n// ============================================================================\n\nconst CACHE_SIZE = 512;\nconst luminanceCache = new Map<string, number>();\nconst cacheOrder: string[] = [];\n\n/**\n * Luminance of an OKHST color `(h, s, t)` with t in 0–1 (reference eps), in\n * the metric's luminance basis. The metric is part of the cache key because\n * WCAG and APCA derive different luminances from the same color.\n */\nfunction cachedLuminance(\n metric: ContrastMetric,\n h: number,\n s: number,\n t: number,\n pastel: boolean,\n): number {\n const tRounded = Math.round(t * 10000) / 10000;\n const key = `${metric}|${h}|${s}|${tRounded}|${pastel}`;\n\n const cached = luminanceCache.get(key);\n if (cached !== undefined) return cached;\n\n const l = fromTone(tRounded * 100, REF_EPS);\n const linearRgb = okhslToLinearSrgb(h, s, l, pastel);\n const y = metricLuminance(metric, linearRgb);\n\n if (luminanceCache.size >= CACHE_SIZE) {\n const evict = cacheOrder.shift()!;\n luminanceCache.delete(evict);\n }\n luminanceCache.set(key, y);\n cacheOrder.push(key);\n\n return y;\n}\n\n// ============================================================================\n// Metric evaluation\n// ============================================================================\n\n/**\n * Score a candidate luminance against the base for a metric. Returns a value\n * that is `>= target` exactly when the floor is met (WCAG ratio, or APCA Lc\n * magnitude). For APCA, `polarity` selects the argument order: `'fg'` (the\n * default) treats the candidate as the text against a background base\n * (`apcaContrast(yCandidate, yBase)`); `'bg'` treats the candidate as the\n * background (`apcaContrast(yBase, yCandidate)`). The magnitude is taken\n * either way. WCAG is symmetric, so polarity is ignored there.\n */\nfunction metricScore(\n metric: 'wcag' | 'apca',\n yCandidate: number,\n yBase: number,\n polarity?: 'fg' | 'bg',\n): number {\n if (metric === 'wcag') return contrastRatioFromLuminance(yCandidate, yBase);\n const lc =\n polarity === 'bg'\n ? apcaContrast(yBase, yCandidate)\n : apcaContrast(yCandidate, yBase);\n return Math.abs(lc);\n}\n\n// ============================================================================\n// Solver\n// ============================================================================\n\nexport interface FindToneForContrastOptions {\n /** Hue of the candidate color (0–360). */\n hue: number;\n /** Saturation of the candidate color (0–1). */\n saturation: number;\n /** Preferred tone of the candidate (0–1). */\n preferredTone: number;\n\n /** Base/reference color as linear sRGB. */\n baseLinearRgb: LinearRgb;\n\n /** Resolved contrast floor (metric + target). */\n contrast: ResolvedContrast;\n\n /** Search bounds for tone. Default: [0, 1]. */\n toneRange?: [number, number];\n /** Convergence threshold. Default: 1e-4. */\n epsilon?: number;\n /** Maximum binary-search iterations per branch. Default: 18. */\n maxIterations?: number;\n /** Preferred search direction before auto-flip is considered. */\n initialDirection?: 'lighter' | 'darker';\n /** Auto-flip tone direction when contrast can't be met. Default: false. */\n flip?: boolean;\n /** Use the hue-independent \"safe\" chroma boundary. Default: false. */\n pastel?: boolean;\n}\n\nexport interface FindToneForContrastResult {\n /** Chosen tone in 0–1. */\n tone: number;\n /** Achieved score (WCAG ratio or APCA Lc magnitude). */\n contrast: number;\n /** Whether the target was reached. */\n met: boolean;\n /** Which branch was selected. */\n branch: 'lighter' | 'darker' | 'preferred';\n /** Whether the result auto-flipped to the opposite direction. */\n flipped?: boolean;\n}\n\n/**\n * Result of a single one-dimensional branch search. `pos` is the chosen\n * coordinate (tone or mix value depending on the caller's domain).\n */\ninterface BranchResult {\n pos: number;\n contrast: number;\n met: boolean;\n}\n\n/**\n * Binary search one branch `[lo, hi]` for the position nearest to `anchor`\n * that meets `target`. The domain is whatever `lum` interprets (tone 0–1 or\n * mix parameter 0–1); the search is identical in both cases.\n */\nfunction searchBranch(\n lum: (x: number) => number,\n lo: number,\n hi: number,\n yBase: number,\n metric: 'wcag' | 'apca',\n target: number,\n epsilon: number,\n maxIter: number,\n anchor: number,\n polarity?: 'fg' | 'bg',\n): BranchResult {\n const scoreLo = metricScore(metric, lum(lo), yBase, polarity);\n const scoreHi = metricScore(metric, lum(hi), yBase, polarity);\n\n if (scoreLo < target && scoreHi < target) {\n return scoreLo >= scoreHi\n ? { pos: lo, contrast: scoreLo, met: false }\n : { pos: hi, contrast: scoreHi, met: false };\n }\n\n let low = lo;\n let high = hi;\n\n for (let i = 0; i < maxIter; i++) {\n if (high - low < epsilon) break;\n const mid = (low + high) / 2;\n const scoreMid = metricScore(metric, lum(mid), yBase, polarity);\n\n if (scoreMid >= target) {\n if (mid < anchor) low = mid;\n else high = mid;\n } else {\n if (mid < anchor) high = mid;\n else low = mid;\n }\n }\n\n const scoreLow = metricScore(metric, lum(low), yBase, polarity);\n const scoreHigh = metricScore(metric, lum(high), yBase, polarity);\n const lowPasses = scoreLow >= target;\n const highPasses = scoreHigh >= target;\n\n if (lowPasses && highPasses) {\n return Math.abs(low - anchor) <= Math.abs(high - anchor)\n ? { pos: low, contrast: scoreLow, met: true }\n : { pos: high, contrast: scoreHigh, met: true };\n }\n if (lowPasses) return { pos: low, contrast: scoreLow, met: true };\n if (highPasses) return { pos: high, contrast: scoreHigh, met: true };\n\n return scoreLow >= scoreHigh\n ? { pos: low, contrast: scoreLow, met: false }\n : { pos: high, contrast: scoreHigh, met: false };\n}\n\n/**\n * Closed-form WCAG tone seed: the gray tone whose luminance produces exactly\n * the target ratio against the base, on the requested side. Used to bias the\n * preferred tone before the search so chromatic refinement starts close.\n */\nfunction wcagToneSeed(yBase: number, target: number, darker: boolean): number {\n const yTarget = darker\n ? (yBase + 0.05) / target - 0.05\n : target * (yBase + 0.05) - 0.05;\n const yClamped = Math.max(0, Math.min(1, yTarget));\n return Math.max(0, Math.min(1, toneFromY(yClamped, REF_EPS) / 100));\n}\n\n/**\n * Shared \"find the nearest passing position\" core for both the tone and mix\n * solvers. Both pick an initial direction within `[lo, hi]`, binary-search\n * that branch, optionally flip to the opposite branch, and pin to the\n * initial extreme on failure — they only differ in their domain and how the\n * branch boundary / luminance closure are built.\n *\n * `searchAnchor` biases the branch boundary and the in-branch tiebreak (the\n * WCAG seed for the tone solver; `preferred` otherwise). `distanceAnchor`\n * is the position the flip step measures closeness against (the original\n * preferred position, before any seed bias).\n */\ninterface SolveCoreOptions {\n lum: (x: number) => number;\n yBase: number;\n metric: 'wcag' | 'apca';\n target: number;\n searchTarget: number;\n lo: number;\n hi: number;\n /** Branch-boundary + in-branch tiebreak anchor. */\n searchAnchor: number;\n /** Position the flip step minimizes distance to. */\n distanceAnchor: number;\n epsilon: number;\n maxIterations: number;\n flip: boolean;\n /** Force the first branch ('lower' searches `[lo, anchor]`). */\n initialIsLower: boolean;\n /** APCA argument order; ignored for WCAG. Default `'fg'`. */\n polarity?: 'fg' | 'bg';\n}\n\ninterface SolveCoreResult {\n pos: number;\n contrast: number;\n met: boolean;\n /** Which branch produced the result. */\n lower: boolean;\n flipped?: boolean;\n}\n\nfunction solveNearestContrast(opts: SolveCoreOptions): SolveCoreResult {\n const {\n lum,\n yBase,\n metric,\n target,\n searchTarget,\n lo,\n hi,\n searchAnchor,\n distanceAnchor,\n epsilon,\n maxIterations,\n flip,\n initialIsLower,\n polarity,\n } = opts;\n\n const runBranch = (lower: boolean): BranchResult =>\n lower\n ? searchBranch(\n lum,\n lo,\n searchAnchor,\n yBase,\n metric,\n searchTarget,\n epsilon,\n maxIterations,\n searchAnchor,\n polarity,\n )\n : searchBranch(\n lum,\n searchAnchor,\n hi,\n yBase,\n metric,\n searchTarget,\n epsilon,\n maxIterations,\n searchAnchor,\n polarity,\n );\n\n const initialResult = runBranch(initialIsLower);\n initialResult.met = initialResult.contrast >= target;\n\n if (initialResult.met && !flip) {\n return { ...initialResult, lower: initialIsLower };\n }\n\n if (flip) {\n // The opposite branch exists only when `distanceAnchor` is strictly\n // interior on that side (matches the legacy canDarker/canUpper guards).\n const canOpposite = initialIsLower\n ? distanceAnchor < hi\n : distanceAnchor > lo;\n const oppositeResult = canOpposite ? runBranch(!initialIsLower) : null;\n if (oppositeResult) oppositeResult.met = oppositeResult.contrast >= target;\n\n if (initialResult.met && oppositeResult?.met) {\n const initialDist = Math.abs(initialResult.pos - distanceAnchor);\n const oppositeDist = Math.abs(oppositeResult.pos - distanceAnchor);\n return initialDist <= oppositeDist\n ? { ...initialResult, lower: initialIsLower }\n : { ...oppositeResult, lower: !initialIsLower, flipped: true };\n }\n if (initialResult.met) return { ...initialResult, lower: initialIsLower };\n if (oppositeResult?.met) {\n return { ...oppositeResult, lower: !initialIsLower, flipped: true };\n }\n }\n\n // Failure: pin to the initial direction's extreme.\n const extreme = initialIsLower ? lo : hi;\n const scoreExtreme = metricScore(metric, lum(extreme), yBase, polarity);\n return {\n pos: extreme,\n contrast: scoreExtreme,\n met: false,\n lower: initialIsLower,\n };\n}\n\n/**\n * Find the tone that satisfies a contrast floor against a base color,\n * staying as close to `preferredTone` as possible.\n */\nexport function findToneForContrast(\n options: FindToneForContrastOptions,\n): FindToneForContrastResult {\n const {\n hue,\n saturation,\n preferredTone,\n baseLinearRgb,\n contrast,\n toneRange = [0, 1],\n epsilon = 1e-4,\n maxIterations = 18,\n pastel = false,\n } = options;\n\n const { metric, target, polarity } = contrast;\n // Overshoot absorbs rounding in the OKHSL/OKLCH formatting pipeline.\n const searchTarget = metric === 'wcag' ? target * 1.01 : target + 0.5;\n const yBase = metricLuminance(metric, baseLinearRgb);\n\n // Luminance of a candidate at tone `t`.\n const lum = (t: number): number =>\n cachedLuminance(metric, hue, saturation, t, pastel);\n\n const scorePref = metricScore(metric, lum(preferredTone), yBase, polarity);\n\n if (scorePref >= searchTarget) {\n return {\n tone: preferredTone,\n contrast: scorePref,\n met: true,\n branch: 'preferred',\n };\n }\n\n const [minT, maxT] = toneRange;\n const canDarker = preferredTone > minT;\n const canLighter = preferredTone < maxT;\n\n let initialIsDarker: boolean;\n if (options.initialDirection !== undefined) {\n initialIsDarker = options.initialDirection === 'darker';\n } else if (canDarker && !canLighter) {\n initialIsDarker = true;\n } else if (!canDarker && canLighter) {\n initialIsDarker = false;\n } else if (!canDarker && !canLighter) {\n return {\n tone: preferredTone,\n contrast: scorePref,\n met: false,\n branch: 'preferred',\n };\n } else {\n const scoreMin = metricScore(metric, lum(minT), yBase, polarity);\n const scoreMax = metricScore(metric, lum(maxT), yBase, polarity);\n initialIsDarker = scoreMin >= scoreMax;\n }\n\n // For WCAG, bias the search start toward the closed-form seed (darker =\n // the \"lower\" branch). The flip step still measures distance against the\n // original `preferredTone`, not the seed.\n const searchAnchor =\n metric === 'wcag'\n ? clamp(\n initialIsDarker\n ? Math.min(preferredTone, wcagToneSeed(yBase, target, true))\n : Math.max(preferredTone, wcagToneSeed(yBase, target, false)),\n minT,\n maxT,\n )\n : preferredTone;\n\n const solved = solveNearestContrast({\n lum,\n yBase,\n metric,\n target,\n searchTarget,\n lo: minT,\n hi: maxT,\n searchAnchor,\n distanceAnchor: preferredTone,\n epsilon,\n maxIterations,\n flip: options.flip ?? false,\n initialIsLower: initialIsDarker,\n polarity,\n });\n\n return {\n tone: solved.pos,\n contrast: solved.contrast,\n met: solved.met,\n branch: solved.lower ? 'darker' : 'lighter',\n ...(solved.flipped ? { flipped: true } : {}),\n };\n}\n\n// ============================================================================\n// Mix contrast solver\n// ============================================================================\n\nexport interface FindValueForMixContrastOptions {\n /** Preferred mix parameter (0–1). */\n preferredValue: number;\n /** Base color as linear sRGB. */\n baseLinearRgb: LinearRgb;\n /** Target color as linear sRGB. */\n targetLinearRgb: LinearRgb;\n /** Resolved contrast floor (metric + target). */\n contrast: ResolvedContrast;\n /** Compute the luminance of the mixed color at parameter t. */\n luminanceAtValue: (t: number) => number;\n /** Convergence threshold. Default: 1e-4. */\n epsilon?: number;\n /** Maximum binary-search iterations per branch. Default: 20. */\n maxIterations?: number;\n /** Auto-flip mix direction when contrast can't be met. Default: false. */\n flip?: boolean;\n}\n\nexport interface FindValueForMixContrastResult {\n value: number;\n contrast: number;\n met: boolean;\n flipped?: boolean;\n}\n\n/**\n * Find the mix parameter (ratio or opacity) that satisfies a contrast floor\n * against a base color, staying as close to `preferredValue` as possible.\n */\nexport function findValueForMixContrast(\n options: FindValueForMixContrastOptions,\n): FindValueForMixContrastResult {\n const {\n preferredValue,\n baseLinearRgb,\n contrast,\n luminanceAtValue,\n epsilon = 1e-4,\n maxIterations = 20,\n } = options;\n\n const { metric, target, polarity } = contrast;\n const searchTarget = metric === 'wcag' ? target * 1.01 : target + 0.5;\n const yBase = metricLuminance(metric, baseLinearRgb);\n\n const scorePref = metricScore(\n metric,\n luminanceAtValue(preferredValue),\n yBase,\n polarity,\n );\n if (scorePref >= searchTarget) {\n return { value: preferredValue, contrast: scorePref, met: true };\n }\n\n const canLower = preferredValue > 0;\n const canUpper = preferredValue < 1;\n let initialIsLower: boolean;\n if (canLower && !canUpper) {\n initialIsLower = true;\n } else if (!canLower && canUpper) {\n initialIsLower = false;\n } else if (!canLower && !canUpper) {\n return { value: preferredValue, contrast: scorePref, met: false };\n } else {\n const scoreLower = metricScore(\n metric,\n luminanceAtValue(0),\n yBase,\n polarity,\n );\n const scoreUpper = metricScore(\n metric,\n luminanceAtValue(1),\n yBase,\n polarity,\n );\n initialIsLower = scoreLower >= scoreUpper;\n }\n\n const solved = solveNearestContrast({\n lum: luminanceAtValue,\n yBase,\n metric,\n target,\n searchTarget,\n lo: 0,\n hi: 1,\n searchAnchor: preferredValue,\n distanceAnchor: preferredValue,\n epsilon,\n maxIterations,\n flip: options.flip ?? false,\n initialIsLower,\n polarity,\n });\n\n return {\n value: solved.pos,\n contrast: solved.contrast,\n met: solved.met,\n ...(solved.flipped ? { flipped: true } : {}),\n };\n}\n","/**\n * Semantic color role resolution.\n *\n * A `role` fixes APCA contrast polarity (which side is the foreground vs the\n * background). Roles are resolved per color via a four-step chain (see\n * `resolveRole`): explicit `def.role` → name inference → opposite of the\n * base's role → `'text'` foreground default.\n *\n * This module owns the alias keyword sets, name tokenization, and the\n * role → polarity / opposite-role mappings. It has no dependencies.\n */\n\nimport type { Role, RoleInput } from './types';\n\n// ============================================================================\n// Keyword sets\n// ============================================================================\n\nconst SURFACE_KEYWORDS = new Set([\n 'surface',\n 'bg',\n 'background',\n 'fill',\n 'canvas',\n 'paper',\n 'layer',\n]);\n\nconst TEXT_KEYWORDS = new Set([\n 'text',\n 'fg',\n 'foreground',\n 'content',\n 'ink',\n 'label',\n 'stroke',\n]);\n\nconst BORDER_KEYWORDS = new Set([\n 'border',\n 'divider',\n 'outline',\n 'separator',\n 'hairline',\n 'rule',\n]);\n\nconst ALIAS_TO_ROLE: Record<string, Role> = {\n // surface\n surface: 'surface',\n bg: 'surface',\n background: 'surface',\n fill: 'surface',\n canvas: 'surface',\n paper: 'surface',\n layer: 'surface',\n // text\n text: 'text',\n fg: 'text',\n foreground: 'text',\n content: 'text',\n ink: 'text',\n label: 'text',\n stroke: 'text',\n // border\n border: 'border',\n divider: 'border',\n outline: 'border',\n separator: 'border',\n hairline: 'border',\n rule: 'border',\n};\n\n// ============================================================================\n// Normalization\n// ============================================================================\n\n/**\n * Normalize a `RoleInput` (canonical value or alias) into a canonical `Role`.\n * Returns `undefined` for unrecognized strings so callers can fall through to\n * the next step of the resolution chain.\n */\nexport function normalizeRole(input: RoleInput | undefined): Role | undefined {\n if (input === undefined) return undefined;\n return ALIAS_TO_ROLE[input];\n}\n\n// ============================================================================\n// Name inference\n// ============================================================================\n\n/**\n * Tokenize a color name into lowercase keyword tokens, splitting on\n * non-alphanumeric boundaries and at camelCase boundaries. Examples:\n * - `'button-text'` → `['button', 'text']`\n * - `'inputBg'` → `['input', 'bg']`\n * - `'card_border-outline'` → `['card', 'border', 'outline']`\n */\nfunction tokenizeName(name: string): string[] {\n // Split on non-alphanumeric, then split camelCase within each piece.\n const pieces = name.split(/[^0-9a-zA-Z]+/).filter(Boolean);\n const tokens: string[] = [];\n for (const piece of pieces) {\n // Split at the boundary between a lowercase/digit run and an uppercase\n // letter (camelCase humps), e.g. \"inputBg\" → [\"input\", \"Bg\"].\n const sub = piece\n .replace(/([a-z0-9])([A-Z])/g, '$1 $2')\n .split(/\\s+/)\n .filter(Boolean);\n for (const s of sub) tokens.push(s.toLowerCase());\n }\n return tokens;\n}\n\n/**\n * Infer a `Role` from a color name by matching its tokens against the role\n * keyword sets. When multiple tokens match, the **last** recognized token\n * wins (so `button-text` → `text`, `input-bg` → `surface`, `card-border` →\n * `border`). Returns `undefined` when no token matches.\n */\nexport function inferRoleFromName(name: string): Role | undefined {\n const tokens = tokenizeName(name);\n let inferred: Role | undefined;\n for (const token of tokens) {\n if (SURFACE_KEYWORDS.has(token)) inferred = 'surface';\n else if (TEXT_KEYWORDS.has(token)) inferred = 'text';\n else if (BORDER_KEYWORDS.has(token)) inferred = 'border';\n }\n return inferred;\n}\n\n// ============================================================================\n// Polarity + opposites\n// ============================================================================\n\n/** APCA argument order: which side the resolved color plays. */\nexport type Polarity = 'fg' | 'bg';\n\n/**\n * Map a role to its APCA polarity. `text` and `border` are foreground spots\n * against their base (the candidate is the text argument); `surface` is the\n * background (the base is the text argument).\n */\nexport function roleToPolarity(role: Role): Polarity {\n return role === 'surface' ? 'bg' : 'fg';\n}\n\n/**\n * The opposite role of `role`, used when a color with no explicit role and no\n * inferable name depends on a base: the dependent color plays the opposite\n * role of its base. `surface` ↔ `text`; `border` is treated as a foreground\n * spot, so its opposite is `surface`.\n */\nexport function oppositeRole(role: Role): Role {\n if (role === 'surface') return 'text';\n return 'surface';\n}\n","/**\n * Shadow color computation.\n *\n * Owns the shadow / mix def predicates, default tuning constants, the\n * tuning merge, and the actual `computeShadow` math (hue blend,\n * saturation cap, lightness clamp, alpha curve). The resolver consumes\n * this module per scheme variant.\n */\n\nimport { clamp } from './hc-pair';\nimport type {\n ColorDef,\n MixColorDef,\n ShadowColorDef,\n ShadowTuning,\n} from './types';\n\n/**\n * OKHSL-lightness variant shape used by the shadow math. The resolver\n * converts the OKHST-stored variants to this shape at the shadow edge.\n */\nexport interface OkhslShadowVariant {\n h: number;\n s: number;\n l: number;\n alpha: number;\n}\n\nexport function isShadowDef(def: ColorDef): def is ShadowColorDef {\n return (def as ShadowColorDef).type === 'shadow';\n}\n\nexport function isMixDef(def: ColorDef): def is MixColorDef {\n return (def as MixColorDef).type === 'mix';\n}\n\nexport const DEFAULT_SHADOW_TUNING: Required<ShadowTuning> = {\n saturationFactor: 0.18,\n maxSaturation: 0.25,\n lightnessFactor: 0.25,\n lightnessBounds: [0.05, 0.2],\n minGapTarget: 0.05,\n alphaMax: 1.0,\n bgHueBlend: 0.2,\n};\n\nexport function resolveShadowTuning(\n perColor?: ShadowTuning,\n globalTuning?: ShadowTuning,\n): Required<ShadowTuning> {\n return {\n ...DEFAULT_SHADOW_TUNING,\n ...globalTuning,\n ...perColor,\n lightnessBounds:\n perColor?.lightnessBounds ??\n globalTuning?.lightnessBounds ??\n DEFAULT_SHADOW_TUNING.lightnessBounds,\n };\n}\n\nexport function circularLerp(a: number, b: number, t: number): number {\n let diff = b - a;\n if (diff > 180) diff -= 360;\n else if (diff < -180) diff += 360;\n return (((a + diff * t) % 360) + 360) % 360;\n}\n\n/**\n * Compute the canonical max-contrast reference t value for normalization.\n * Uses bg.l=1, fg.l=0, intensity=100 — the theoretical maximum.\n * This is a fixed constant per tuning configuration, ensuring uniform\n * scaling across all bg/fg pairs at low intensities.\n */\nfunction computeRefT(tuning: Required<ShadowTuning>): number {\n const EPSILON = 1e-6;\n let lShRef = clamp(\n tuning.lightnessFactor,\n tuning.lightnessBounds[0],\n tuning.lightnessBounds[1],\n );\n lShRef = Math.max(Math.min(lShRef, 1 - tuning.minGapTarget), 0);\n const gapRef = Math.max(1 - lShRef, EPSILON);\n return 1 / gapRef;\n}\n\nexport function computeShadow(\n bg: OkhslShadowVariant,\n fg: OkhslShadowVariant | undefined,\n intensity: number,\n tuning: Required<ShadowTuning>,\n): OkhslShadowVariant {\n const EPSILON = 1e-6;\n const clampedIntensity = clamp(intensity, 0, 100);\n const contrastWeight = fg ? Math.abs(bg.l - fg.l) : 1;\n const deltaL = (clampedIntensity / 100) * contrastWeight;\n\n const h = fg ? circularLerp(fg.h, bg.h, tuning.bgHueBlend) : bg.h;\n const s = fg\n ? Math.min(fg.s * tuning.saturationFactor, tuning.maxSaturation)\n : 0;\n\n let lSh = clamp(\n bg.l * tuning.lightnessFactor,\n tuning.lightnessBounds[0],\n tuning.lightnessBounds[1],\n );\n lSh = Math.max(Math.min(lSh, bg.l - tuning.minGapTarget), 0);\n\n const gap = Math.max(bg.l - lSh, EPSILON);\n const t = deltaL / gap;\n\n const tRef = computeRefT(tuning);\n const norm = Math.tanh(tRef / tuning.alphaMax);\n const alpha = Math.min(\n (tuning.alphaMax * Math.tanh(t / tuning.alphaMax)) / norm,\n tuning.alphaMax,\n );\n\n return { h, s, l: lSh, alpha };\n}\n","/**\n * Color graph validation and topological sort.\n *\n * `validateColorDefs` rejects bad references (missing / shadow-referencing /\n * base/contrast/tone mismatches) and detects cycles before the\n * resolver runs. `topoSort` orders defs so each color is processed after\n * its base / bg / fg / target dependencies.\n */\n\nimport { isAbsoluteTone } from './hc-pair';\nimport { isMixDef, isShadowDef } from './shadow';\nimport type { ColorMap, RegularColorDef, ResolvedColor } from './types';\n\nexport function validateColorDefs(\n defs: ColorMap,\n externalBases?: Map<string, ResolvedColor>,\n): void {\n const localNames = new Set(Object.keys(defs));\n const allNames = new Set([\n ...localNames,\n ...(externalBases ? externalBases.keys() : []),\n ]);\n\n for (const [name, def] of Object.entries(defs)) {\n if (isShadowDef(def)) {\n if (!allNames.has(def.bg)) {\n throw new Error(\n `glaze: shadow \"${name}\" references non-existent bg \"${def.bg}\".`,\n );\n }\n if (localNames.has(def.bg) && isShadowDef(defs[def.bg])) {\n throw new Error(\n `glaze: shadow \"${name}\" bg \"${def.bg}\" references another shadow color.`,\n );\n }\n if (def.fg !== undefined) {\n if (!allNames.has(def.fg)) {\n throw new Error(\n `glaze: shadow \"${name}\" references non-existent fg \"${def.fg}\".`,\n );\n }\n if (localNames.has(def.fg) && isShadowDef(defs[def.fg])) {\n throw new Error(\n `glaze: shadow \"${name}\" fg \"${def.fg}\" references another shadow color.`,\n );\n }\n }\n continue;\n }\n\n if (isMixDef(def)) {\n if (!allNames.has(def.base)) {\n throw new Error(\n `glaze: mix \"${name}\" references non-existent base \"${def.base}\".`,\n );\n }\n if (!allNames.has(def.target)) {\n throw new Error(\n `glaze: mix \"${name}\" references non-existent target \"${def.target}\".`,\n );\n }\n if (localNames.has(def.base) && isShadowDef(defs[def.base])) {\n throw new Error(\n `glaze: mix \"${name}\" base \"${def.base}\" references a shadow color.`,\n );\n }\n if (localNames.has(def.target) && isShadowDef(defs[def.target])) {\n throw new Error(\n `glaze: mix \"${name}\" target \"${def.target}\" references a shadow color.`,\n );\n }\n continue;\n }\n\n const regDef = def as RegularColorDef;\n\n if (regDef.contrast !== undefined && !regDef.base) {\n throw new Error(`glaze: color \"${name}\" has \"contrast\" without \"base\".`);\n }\n\n if (\n regDef.tone !== undefined &&\n !isAbsoluteTone(regDef.tone) &&\n !regDef.base\n ) {\n throw new Error(\n `glaze: color \"${name}\" has relative \"tone\" without \"base\".`,\n );\n }\n\n if (regDef.base && !allNames.has(regDef.base)) {\n throw new Error(\n `glaze: color \"${name}\" references non-existent base \"${regDef.base}\".`,\n );\n }\n\n if (\n regDef.base &&\n localNames.has(regDef.base) &&\n isShadowDef(defs[regDef.base])\n ) {\n throw new Error(\n `glaze: color \"${name}\" base \"${regDef.base}\" references a shadow color.`,\n );\n }\n\n if (!isAbsoluteTone(regDef.tone) && regDef.base === undefined) {\n throw new Error(\n `glaze: color \"${name}\" must have either absolute \"tone\" (root) or \"base\" (dependent).`,\n );\n }\n\n if (regDef.contrast !== undefined && regDef.opacity !== undefined) {\n console.warn(\n `glaze: color \"${name}\" has both \"contrast\" and \"opacity\". Opacity makes perceived tone unpredictable.`,\n );\n }\n }\n\n // Check for circular references (follows base, bg, fg edges).\n // External bases are leaves (no outgoing edges in `defs`), so they can't\n // form a cycle and we short-circuit there.\n const visited = new Set<string>();\n const inStack = new Set<string>();\n\n function dfs(name: string): void {\n if (!localNames.has(name)) return;\n if (inStack.has(name)) {\n throw new Error(\n `glaze: circular base reference detected involving \"${name}\".`,\n );\n }\n if (visited.has(name)) return;\n\n inStack.add(name);\n const def = defs[name];\n if (isShadowDef(def)) {\n dfs(def.bg);\n if (def.fg) dfs(def.fg);\n } else if (isMixDef(def)) {\n dfs(def.base);\n dfs(def.target);\n } else {\n const regDef = def as RegularColorDef;\n if (regDef.base) {\n dfs(regDef.base);\n }\n }\n inStack.delete(name);\n visited.add(name);\n }\n\n for (const name of localNames) {\n dfs(name);\n }\n}\n\nexport function topoSort(defs: ColorMap): string[] {\n const result: string[] = [];\n const visited = new Set<string>();\n\n function visit(name: string): void {\n if (visited.has(name)) return;\n visited.add(name);\n\n const def = defs[name];\n // External base references (not in `defs`) are leaves — they're already\n // pre-seeded into `ctx.resolved` and don't participate in the local sort.\n if (def === undefined) return;\n if (isShadowDef(def)) {\n visit(def.bg);\n if (def.fg) visit(def.fg);\n } else if (isMixDef(def)) {\n visit(def.base);\n visit(def.target);\n } else {\n const regDef = def as RegularColorDef;\n if (regDef.base) {\n visit(regDef.base);\n }\n }\n\n result.push(name);\n }\n\n for (const name of Object.keys(defs)) {\n visit(name);\n }\n\n return result;\n}\n","/**\n * Contrast-warning dispatcher.\n *\n * Tokens memoize their resolution, but a long-lived process (e.g. a dev\n * server with HMR) can re-resolve the same theme many times. The cache\n * here dedupes warnings within a session with a soft cap to keep noise\n * bounded.\n */\n\nimport { apcaContrast } from './contrast-solver';\nimport type { ResolvedContrast } from './contrast-solver';\nimport { contrastRatioFromLuminance } from './okhsl-color-math';\n\nconst CONTRAST_WARN_CACHE_LIMIT = 256;\nconst contrastWarnCache = new Set<string>();\n\n/**\n * Slack factor below the requested target before we emit a warning.\n * The contrast solver overshoots to absorb rounding noise, so an actual\n * value within ~2x that overshoot is effectively a pass.\n */\nconst CONTRAST_WARN_SLACK_WCAG = 0.98;\n/** APCA Lc is on a 0–106 scale; allow a small absolute slack. */\nconst CONTRAST_WARN_SLACK_APCA = 1.5;\n\nfunction schemeLabel(isDark: boolean, isHighContrast: boolean): string {\n if (isDark && isHighContrast) return 'darkContrast';\n if (isDark) return 'dark';\n if (isHighContrast) return 'lightContrast';\n return 'light';\n}\n\nfunction metricLabel(c: ResolvedContrast): string {\n return c.metric === 'apca'\n ? `APCA Lc ${c.target.toFixed(1)}`\n : `WCAG ${c.target.toFixed(2)}`;\n}\n\nfunction dedupe(key: string): boolean {\n if (contrastWarnCache.has(key)) return true;\n if (contrastWarnCache.size >= CONTRAST_WARN_CACHE_LIMIT) {\n contrastWarnCache.clear();\n }\n contrastWarnCache.add(key);\n return false;\n}\n\n/** Warn when the solver could not reach the requested contrast floor. */\nexport function warnContrastUnmet(\n name: string,\n isDark: boolean,\n isHighContrast: boolean,\n contrast: ResolvedContrast,\n actual: number,\n): void {\n const slack =\n contrast.metric === 'apca'\n ? contrast.target - CONTRAST_WARN_SLACK_APCA\n : contrast.target * CONTRAST_WARN_SLACK_WCAG;\n if (actual >= slack) return;\n\n const scheme = schemeLabel(isDark, isHighContrast);\n const key = `unmet|${name}|${scheme}|${contrast.metric}|${contrast.target.toFixed(\n 2,\n )}|${actual.toFixed(2)}`;\n if (dedupe(key)) return;\n\n console.warn(\n `glaze: color \"${name}\" cannot meet ${metricLabel(contrast)} in ` +\n `${scheme} scheme (got ${actual.toFixed(2)}). ` +\n `Try widening the tone window, lowering the contrast target, ` +\n `or picking a base color further from this color's tone.`,\n );\n}\n\n/**\n * Verification (§10): a chromatic swatch inherits the gray tone's\n * lightness but drifts in real luminance, so a contrast-floored color may\n * land slightly under the contrast its tone implies. Emit an advisory\n * warning when the actual measured contrast drifts below the target.\n */\nexport function warnContrastDrift(\n name: string,\n isDark: boolean,\n isHighContrast: boolean,\n contrast: ResolvedContrast,\n yColor: number,\n yBase: number,\n): void {\n const actual =\n contrast.metric === 'apca'\n ? Math.abs(\n contrast.polarity === 'bg'\n ? apcaContrast(yBase, yColor)\n : apcaContrast(yColor, yBase),\n )\n : contrastRatioFromLuminance(yColor, yBase);\n\n const slack =\n contrast.metric === 'apca'\n ? contrast.target - CONTRAST_WARN_SLACK_APCA\n : contrast.target * CONTRAST_WARN_SLACK_WCAG;\n if (actual >= slack) return;\n\n const scheme = schemeLabel(isDark, isHighContrast);\n const key = `drift|${name}|${scheme}|${contrast.metric}|${contrast.target.toFixed(\n 2,\n )}|${actual.toFixed(2)}`;\n if (dedupe(key)) return;\n\n console.warn(\n `glaze: color \"${name}\" drifts below ${metricLabel(contrast)} in ` +\n `${scheme} scheme (measured ${actual.toFixed(2)}). Chromatic luminance ` +\n `differs from the gray tone; nudge the tone or saturation if the floor matters.`,\n );\n}\n","/**\n * Color resolution engine.\n *\n * Runs the four-pass solver (light → light-HC → dark → dark-HC) that\n * turns a `ColorMap` into a fully resolved `ResolvedColor` per name.\n * Owns the per-scheme resolve helpers for regular, shadow, and mix\n * color defs.\n *\n * Variants are stored in OKHST: `h` / `s` are OKHSL hue/saturation and\n * `t` is the canonical contrast-uniform tone (0–1, reference eps). The\n * resolver works in tone for regular colors and converts to/from OKHSL\n * lightness only at the mix/shadow and luminance edges.\n *\n * Every function receives a single `GlazeConfigResolved` so the full\n * per-instance config (including overrides) is available without\n * re-reading the global singleton mid-resolve.\n */\n\nimport {\n okhslToLinearSrgb,\n sRGBLinearToGamma,\n srgbToOkhsl,\n} from './okhsl-color-math';\nimport {\n findToneForContrast,\n findValueForMixContrast,\n metricLuminance,\n resolveContrastForMode,\n} from './contrast-solver';\nimport type { LinearRgb, ResolvedContrast } from './contrast-solver';\nimport {\n clamp,\n isAbsoluteTone,\n pairHC,\n pairNormal,\n parseToneValue,\n resolveEffectiveHue,\n} from './hc-pair';\nimport {\n inferRoleFromName,\n normalizeRole,\n oppositeRole,\n roleToPolarity,\n} from './roles';\nimport {\n computeShadow,\n circularLerp,\n isMixDef,\n isShadowDef,\n resolveShadowTuning,\n} from './shadow';\nimport {\n fromTone,\n mapSaturationDark,\n mapToneForScheme,\n okhslToOkhst,\n schemeToneRange,\n toTone,\n variantToOkhsl,\n} from './okhst';\nimport { topoSort, validateColorDefs } from './validation';\nimport { warnContrastUnmet, warnContrastDrift } from './warnings';\nimport type {\n AdaptationMode,\n ColorDef,\n ColorMap,\n ContrastSpec,\n GlazeConfigResolved,\n HCPair,\n MixColorDef,\n RegularColorDef,\n ResolvedColor,\n ResolvedColorVariant,\n Role,\n ShadowColorDef,\n} from './types';\n\nexport interface ResolveContext {\n hue: number;\n saturation: number;\n defs: ColorMap;\n resolved: Map<string, ResolvedColor>;\n /** Fully-merged effective config for this resolve pass. */\n config: GlazeConfigResolved;\n /** Per-name role memo (filled lazily by `resolveRole`). */\n roles: Map<string, Role>;\n}\n\ntype ResolvedField = 'light' | 'dark' | 'lightContrast' | 'darkContrast';\n\n/** An OKHSL-lightness-shaped variant used at the mix/shadow edge. */\ninterface OkhslVariant {\n h: number;\n s: number;\n l: number;\n alpha: number;\n /** Carried from the resolved variant so edge conversions reuse the right gamut. */\n pastel?: boolean;\n}\n\nexport function getSchemeVariant(\n color: ResolvedColor,\n isDark: boolean,\n isHighContrast: boolean,\n): ResolvedColorVariant {\n if (isDark && isHighContrast) return color.darkContrast;\n if (isDark) return color.dark;\n if (isHighContrast) return color.lightContrast;\n return color.light;\n}\n\n/** Edge adapter: resolved variant (`t`) → OKHSL-lightness variant. */\nfunction toOkhslVariant(v: ResolvedColorVariant): OkhslVariant {\n const c = variantToOkhsl(v);\n return { h: c.h, s: c.s, l: c.l, alpha: v.alpha, pastel: v.pastel };\n}\n\n/** Edge adapter: OKHSL-lightness variant → resolved variant (`t`). */\nfunction toToneVariant(v: OkhslVariant): ResolvedColorVariant {\n const c = okhslToOkhst({ h: v.h, s: v.s, l: v.l });\n return { h: c.h, s: c.s, t: c.t, alpha: v.alpha };\n}\n\n// ============================================================================\n// Role resolution\n// ============================================================================\n\n/**\n * Resolve the role of a base color referenced by `baseName`, returning the\n * role the *dependent* color should take (the opposite of the base's role).\n * A base that lives in `defs` recursively resolves and is inverted via\n * `oppositeRole`; an external base (no local def, e.g. an injected standalone\n * token) is treated as a background, so the dependent defaults to foreground\n * (`'text'`).\n */\nfunction resolveBaseRoleInMap(\n baseName: string | undefined,\n defs: ColorMap,\n inferRole: boolean,\n roles: Map<string, Role>,\n): Role | undefined {\n if (!baseName) return undefined;\n const baseDef = defs[baseName];\n if (!baseDef) return 'text';\n return oppositeRole(\n resolveRoleInMap(baseName, baseDef, defs, inferRole, roles),\n );\n}\n\n/**\n * Role-resolution core that does not need a full `ResolveContext`. Shared by\n * the resolver (via `resolveRole`) and `verifyContrastDrift`.\n */\nfunction resolveRoleInMap(\n name: string,\n def: ColorDef,\n defs: ColorMap,\n inferRole: boolean,\n roles: Map<string, Role>,\n): Role {\n const cached = roles.get(name);\n if (cached) return cached;\n\n let role: Role | undefined;\n if (isShadowDef(def)) {\n role = 'surface';\n } else if (isMixDef(def)) {\n role =\n normalizeRole(def.role) ??\n (inferRole ? inferRoleFromName(name) : undefined) ??\n resolveBaseRoleInMap(def.base, defs, inferRole, roles) ??\n 'text';\n } else {\n const regDef = def as RegularColorDef;\n role =\n normalizeRole(regDef.role) ??\n (inferRole ? inferRoleFromName(name) : undefined) ??\n resolveBaseRoleInMap(regDef.base, defs, inferRole, roles) ??\n 'text';\n }\n\n const finalRole = role ?? 'text';\n roles.set(name, finalRole);\n return finalRole;\n}\n\n/**\n * Resolve a color's semantic `role` (text / surface / border) per the chain:\n * 1. explicit `def.role` (normalized)\n * 2. inferred from the color name when `config.inferRole` is on\n * 3. opposite of the base's role\n * 4. `'text'` (foreground) default\n *\n * Memoized on `ctx.roles` so the four scheme passes share one resolution.\n * Shadows have no contrast participation and default to `'surface'`.\n */\nfunction resolveRole(name: string, def: ColorDef, ctx: ResolveContext): Role {\n return resolveRoleInMap(name, def, ctx.defs, ctx.config.inferRole, ctx.roles);\n}\n\nfunction resolveContrastSpec(\n spec: HCPair<ContrastSpec>,\n isHighContrast: boolean,\n polarity?: 'fg' | 'bg',\n): ResolvedContrast {\n const outerExplicitHC = Array.isArray(spec);\n const outer = isHighContrast ? pairHC(spec) : pairNormal(spec);\n return resolveContrastForMode(\n outer,\n isHighContrast,\n polarity,\n outerExplicitHC,\n );\n}\n\n/**\n * Apply the relative-tone delta against a base, honoring `flip`.\n *\n * When `flip` is on and `base + delta` falls outside `[0, 100]`, mirror the\n * delta to the other side of the base (so an offset that would clamp instead\n * reflects back into range). When off, the caller clamps as usual.\n */\nfunction applyToneFlip(delta: number, baseTone: number, flip: boolean): number {\n if (!flip) return delta;\n const target = baseTone + delta;\n if (target >= 0 && target <= 100) return delta;\n return -delta;\n}\n\nfunction resolveRootColor(\n def: RegularColorDef,\n isHighContrast: boolean,\n): { authorTone: number; satFactor: number } {\n const rawT = def.tone!;\n const rawValue = isHighContrast ? pairHC(rawT) : pairNormal(rawT);\n // Root tone is absolute or extreme ('max' = 100, 'min' = 0); both flow\n // through mapToneForScheme (and invert in dark under mode 'auto').\n const parsed = parseToneValue(rawValue);\n const authorTone = clamp(parsed.value, 0, 100);\n const satFactor = clamp(def.saturation ?? 1, 0, 1);\n return { authorTone, satFactor };\n}\n\nfunction resolveDependentColor(\n name: string,\n def: RegularColorDef,\n ctx: ResolveContext,\n isHighContrast: boolean,\n isDark: boolean,\n effectiveHue: number,\n polarity: 'fg' | 'bg',\n effectivePastel: boolean,\n): { tone: number; satFactor: number } {\n const baseName = def.base!;\n const baseResolved = ctx.resolved.get(baseName);\n if (!baseResolved) {\n throw new Error(\n `glaze: base \"${baseName}\" not yet resolved for \"${name}\".`,\n );\n }\n\n const mode = def.mode ?? 'auto';\n const satFactor = clamp(def.saturation ?? 1, 0, 1);\n const flip = def.autoFlip ?? ctx.config.autoFlip;\n const pastel = effectivePastel;\n\n const baseVariant = getSchemeVariant(baseResolved, isDark, isHighContrast);\n const baseTone = baseVariant.t * 100;\n\n let preferredTone: number;\n const rawTone = def.tone;\n\n if (rawTone === undefined) {\n preferredTone = baseTone;\n } else {\n const rawValue = isHighContrast ? pairHC(rawTone) : pairNormal(rawTone);\n const parsed = parseToneValue(rawValue);\n\n if (parsed.kind === 'relative') {\n if (isDark && mode === 'auto') {\n const baseLightVariant = getSchemeVariant(\n baseResolved,\n false,\n isHighContrast,\n );\n const baseLightTone = baseLightVariant.t * 100;\n const absoluteLightTone = clamp(\n baseLightTone + applyToneFlip(parsed.value, baseLightTone, flip),\n 0,\n 100,\n );\n // Invert + remap the base-anchored light tone into the dark window,\n // exactly like an absolute author tone under `mode: 'auto'`.\n preferredTone = mapToneForScheme(\n absoluteLightTone,\n 'auto',\n true,\n isHighContrast,\n ctx.config,\n );\n } else {\n const delta = applyToneFlip(parsed.value, baseTone, flip);\n preferredTone = clamp(baseTone + delta, 0, 100);\n }\n } else {\n // Absolute or extreme ('max' = 100, 'min' = 0): map through the scheme.\n preferredTone = mapToneForScheme(\n parsed.value,\n mode,\n isDark,\n isHighContrast,\n ctx.config,\n );\n }\n }\n\n const rawContrast = def.contrast;\n if (rawContrast !== undefined) {\n const resolvedContrast = resolveContrastSpec(\n rawContrast,\n isHighContrast,\n polarity,\n );\n\n const effectiveSat = isDark\n ? mapSaturationDark((satFactor * ctx.saturation) / 100, mode, ctx.config)\n : (satFactor * ctx.saturation) / 100;\n\n const baseOkhsl = toOkhslVariant(baseVariant);\n const baseLinearRgb = okhslToLinearSrgb(\n baseOkhsl.h,\n baseOkhsl.s,\n baseOkhsl.l,\n baseVariant.pastel ?? ctx.config.pastel,\n );\n\n const toneRange = schemeToneRange(isDark, mode, isHighContrast, ctx.config);\n\n let initialDirection: 'lighter' | 'darker' | undefined;\n if (preferredTone < baseTone) {\n initialDirection = 'darker';\n } else if (preferredTone > baseTone) {\n initialDirection = 'lighter';\n }\n\n const result = findToneForContrast({\n hue: effectiveHue,\n saturation: effectiveSat,\n preferredTone: clamp(preferredTone / 100, toneRange[0], toneRange[1]),\n baseLinearRgb,\n contrast: resolvedContrast,\n toneRange: [0, 1],\n initialDirection,\n flip,\n pastel,\n });\n\n if (!result.met) {\n warnContrastUnmet(\n name,\n isDark,\n isHighContrast,\n resolvedContrast,\n result.contrast,\n );\n }\n\n return { tone: result.tone * 100, satFactor };\n }\n\n return { tone: clamp(preferredTone, 0, 100), satFactor };\n}\n\nfunction resolveColorForScheme(\n name: string,\n def: ColorDef,\n ctx: ResolveContext,\n isDark: boolean,\n isHighContrast: boolean,\n): ResolvedColorVariant {\n if (isShadowDef(def)) {\n return resolveShadowForScheme(def, ctx, isDark, isHighContrast);\n }\n\n if (isMixDef(def)) {\n return resolveMixForScheme(name, def, ctx, isDark, isHighContrast);\n }\n\n const regDef = def as RegularColorDef;\n const mode = regDef.mode ?? 'auto';\n const isRoot = isAbsoluteTone(regDef.tone) && !regDef.base;\n const effectiveHue = resolveEffectiveHue(ctx.hue, regDef.hue);\n const role = resolveRole(name, def, ctx);\n const polarity = roleToPolarity(role);\n const pastel = regDef.pastel ?? ctx.config.pastel;\n\n let finalTone: number;\n let satFactor: number;\n\n if (isRoot) {\n const root = resolveRootColor(regDef, isHighContrast);\n finalTone = mapToneForScheme(\n root.authorTone,\n mode,\n isDark,\n isHighContrast,\n ctx.config,\n );\n satFactor = root.satFactor;\n } else {\n const dep = resolveDependentColor(\n name,\n regDef,\n ctx,\n isHighContrast,\n isDark,\n effectiveHue,\n polarity,\n pastel,\n );\n finalTone = dep.tone;\n satFactor = dep.satFactor;\n }\n\n const baseSat = (satFactor * ctx.saturation) / 100;\n const finalSat = isDark\n ? mapSaturationDark(baseSat, mode, ctx.config)\n : baseSat;\n\n const toneFraction = clamp(finalTone / 100, 0, 1);\n\n return {\n h: effectiveHue,\n s: clamp(finalSat, 0, 1),\n t: toneFraction,\n alpha: regDef.opacity ?? 1,\n pastel,\n };\n}\n\nfunction resolveShadowForScheme(\n def: ShadowColorDef,\n ctx: ResolveContext,\n isDark: boolean,\n isHighContrast: boolean,\n): ResolvedColorVariant {\n const bgResolved = ctx.resolved.get(def.bg)!;\n const bgVariant = toOkhslVariant(\n getSchemeVariant(bgResolved, isDark, isHighContrast),\n );\n\n let fgVariant: OkhslVariant | undefined;\n if (def.fg) {\n const fgResolved = ctx.resolved.get(def.fg)!;\n fgVariant = toOkhslVariant(\n getSchemeVariant(fgResolved, isDark, isHighContrast),\n );\n }\n\n const intensity = isHighContrast\n ? pairHC(def.intensity)\n : pairNormal(def.intensity);\n\n const tuning = resolveShadowTuning(def.tuning, ctx.config.shadowTuning);\n return {\n ...toToneVariant(computeShadow(bgVariant, fgVariant, intensity, tuning)),\n pastel: def.pastel ?? ctx.config.pastel,\n };\n}\n\nfunction okhslVariantToLinearRgb(v: OkhslVariant, pastel: boolean): LinearRgb {\n return okhslToLinearSrgb(v.h, v.s, v.l, pastel);\n}\n\n/**\n * Resolve hue for OKHSL mixing, handling achromatic colors.\n * When one color has no saturation, its hue is meaningless —\n * use the hue from the color that has saturation (matches CSS\n * color-mix \"missing component\" behavior).\n */\nfunction mixHue(base: OkhslVariant, target: OkhslVariant, t: number): number {\n const SAT_EPSILON = 1e-6;\n const baseHasSat = base.s > SAT_EPSILON;\n const targetHasSat = target.s > SAT_EPSILON;\n\n if (baseHasSat && targetHasSat) return circularLerp(base.h, target.h, t);\n if (targetHasSat) return target.h;\n return base.h;\n}\n\nfunction linearSrgbLerp(\n base: LinearRgb,\n target: LinearRgb,\n t: number,\n): LinearRgb {\n return [\n base[0] + (target[0] - base[0]) * t,\n base[1] + (target[1] - base[1]) * t,\n base[2] + (target[2] - base[2]) * t,\n ];\n}\n\nfunction linearRgbToToneVariant(\n rgb: LinearRgb,\n pastel: boolean,\n): ResolvedColorVariant {\n const gamma: [number, number, number] = [\n Math.max(0, Math.min(1, sRGBLinearToGamma(rgb[0]))),\n Math.max(0, Math.min(1, sRGBLinearToGamma(rgb[1]))),\n Math.max(0, Math.min(1, sRGBLinearToGamma(rgb[2]))),\n ];\n const [h, s, l] = srgbToOkhsl(gamma, pastel);\n return toToneVariant({ h, s, l, alpha: 1 });\n}\n\nfunction resolveMixForScheme(\n name: string,\n def: MixColorDef,\n ctx: ResolveContext,\n isDark: boolean,\n isHighContrast: boolean,\n): ResolvedColorVariant {\n const baseResolved = ctx.resolved.get(def.base)!;\n const targetResolved = ctx.resolved.get(def.target)!;\n const baseVariant = toOkhslVariant(\n getSchemeVariant(baseResolved, isDark, isHighContrast),\n );\n const targetVariant = toOkhslVariant(\n getSchemeVariant(targetResolved, isDark, isHighContrast),\n );\n\n const rawValue = isHighContrast ? pairHC(def.value) : pairNormal(def.value);\n let t = clamp(rawValue, 0, 100) / 100;\n\n const blend = def.blend ?? 'opaque';\n const space = def.space ?? 'okhsl';\n const role = resolveRole(name, def, ctx);\n const polarity = roleToPolarity(role);\n const pastel = def.pastel ?? ctx.config.pastel;\n const baseLinear = okhslVariantToLinearRgb(\n baseVariant,\n baseVariant.pastel ?? ctx.config.pastel,\n );\n const targetLinear = okhslVariantToLinearRgb(\n targetVariant,\n targetVariant.pastel ?? ctx.config.pastel,\n );\n\n if (def.contrast !== undefined) {\n const resolvedContrast = resolveContrastSpec(\n def.contrast,\n isHighContrast,\n polarity,\n );\n const metric = resolvedContrast.metric;\n\n let luminanceAt: (v: number) => number;\n\n if (blend === 'transparent' || space === 'srgb') {\n luminanceAt = (v: number) =>\n metricLuminance(metric, linearSrgbLerp(baseLinear, targetLinear, v));\n } else {\n luminanceAt = (v: number) => {\n const h = mixHue(baseVariant, targetVariant, v);\n const s = baseVariant.s + (targetVariant.s - baseVariant.s) * v;\n const l = baseVariant.l + (targetVariant.l - baseVariant.l) * v;\n return metricLuminance(metric, okhslToLinearSrgb(h, s, l, pastel));\n };\n }\n\n const result = findValueForMixContrast({\n preferredValue: t,\n baseLinearRgb: baseLinear,\n targetLinearRgb: targetLinear,\n contrast: resolvedContrast,\n luminanceAtValue: luminanceAt,\n flip: ctx.config.autoFlip,\n });\n t = result.value;\n }\n\n if (blend === 'transparent') {\n return {\n ...toToneVariant({\n h: targetVariant.h,\n s: targetVariant.s,\n l: targetVariant.l,\n alpha: clamp(t, 0, 1),\n }),\n pastel,\n };\n }\n\n if (space === 'srgb') {\n const mixed = linearSrgbLerp(baseLinear, targetLinear, t);\n return { ...linearRgbToToneVariant(mixed, pastel), pastel };\n }\n\n return {\n ...toToneVariant({\n h: mixHue(baseVariant, targetVariant, t),\n s: clamp(baseVariant.s + (targetVariant.s - baseVariant.s) * t, 0, 1),\n l: clamp(baseVariant.l + (targetVariant.l - baseVariant.l) * t, 0, 1),\n alpha: 1,\n }),\n pastel,\n };\n}\n\nfunction defMode(def: ColorDef): AdaptationMode | undefined {\n if (isShadowDef(def) || isMixDef(def)) return undefined;\n return (def as RegularColorDef).mode ?? 'auto';\n}\n\n/**\n * Run a single resolve pass over all local names. Pass 1 lazily creates\n * each `ResolvedColor` (all four slots seeded with the just-resolved\n * variant) the first time it sees a name; later passes update the\n * `target` slot on the existing record.\n */\nfunction runPass(\n order: string[],\n defs: ColorMap,\n ctx: ResolveContext,\n isDark: boolean,\n isHighContrast: boolean,\n target: ResolvedField,\n): Map<string, ResolvedColorVariant> {\n const out = new Map<string, ResolvedColorVariant>();\n for (const name of order) {\n const variant = resolveColorForScheme(\n name,\n defs[name],\n ctx,\n isDark,\n isHighContrast,\n );\n out.set(name, variant);\n const existing = ctx.resolved.get(name);\n if (existing) {\n ctx.resolved.set(name, { ...existing, [target]: variant });\n } else {\n ctx.resolved.set(name, {\n name,\n light: variant,\n dark: variant,\n lightContrast: variant,\n darkContrast: variant,\n mode: defMode(defs[name]),\n });\n }\n }\n return out;\n}\n\n/**\n * Re-seed a single variant slot with a previously-resolved map so the\n * upcoming pass reads sensible fallbacks via `getSchemeVariant`.\n */\nfunction seedField(\n order: string[],\n ctx: ResolveContext,\n field: ResolvedField,\n source: Map<string, ResolvedColorVariant>,\n): void {\n for (const name of order) {\n const existing = ctx.resolved.get(name)!;\n ctx.resolved.set(name, { ...existing, [field]: source.get(name)! });\n }\n}\n\n/**\n * After the four passes, surface chromatic contrast drift (§10): a color\n * resolved with a `base` + `contrast` may land slightly under the contrast\n * its tone implies because chromatic luminance drifts from the gray tone.\n */\nfunction verifyContrastDrift(\n order: string[],\n defs: ColorMap,\n result: Map<string, ResolvedColor>,\n config: GlazeConfigResolved,\n): void {\n const roles = new Map<string, Role>();\n for (const name of order) {\n const def = defs[name];\n if (isShadowDef(def) || isMixDef(def)) continue;\n const regDef = def as RegularColorDef;\n if (regDef.contrast === undefined || !regDef.base) continue;\n const color = result.get(name);\n const base = result.get(regDef.base);\n if (!color || !base) continue;\n\n const role = resolveRoleInMap(name, def, defs, config.inferRole, roles);\n const polarity = roleToPolarity(role);\n\n const schemes: {\n isDark: boolean;\n isHighContrast: boolean;\n field: ResolvedField;\n }[] = [\n { isDark: false, isHighContrast: false, field: 'light' },\n { isDark: false, isHighContrast: true, field: 'lightContrast' },\n { isDark: true, isHighContrast: false, field: 'dark' },\n { isDark: true, isHighContrast: true, field: 'darkContrast' },\n ];\n\n for (const s of schemes) {\n const spec = resolveContrastSpec(\n regDef.contrast,\n s.isHighContrast,\n polarity,\n );\n const cVariant = color[s.field];\n const bVariant = base[s.field];\n const cOkhsl = toOkhslVariant(cVariant);\n const bOkhsl = toOkhslVariant(bVariant);\n // Measure in the spec's metric basis so the APCA warning compares APCA\n // luminances, not WCAG ones. Each variant carries its own effective\n // pastel flag so the gamut mapping matches what the resolver applied;\n // fall back to the config default for any variant without one.\n const cPastel = cVariant.pastel ?? config.pastel;\n const bPastel = bVariant.pastel ?? config.pastel;\n const yC = metricLuminance(\n spec.metric,\n okhslToLinearSrgb(cOkhsl.h, cOkhsl.s, cOkhsl.l, cPastel),\n );\n const yB = metricLuminance(\n spec.metric,\n okhslToLinearSrgb(bOkhsl.h, bOkhsl.s, bOkhsl.l, bPastel),\n );\n warnContrastDrift(name, s.isDark, s.isHighContrast, spec, yC, yB);\n }\n }\n}\n\nexport function resolveAllColors(\n hue: number,\n saturation: number,\n defs: ColorMap,\n config: GlazeConfigResolved,\n externalBases?: Map<string, ResolvedColor>,\n): Map<string, ResolvedColor> {\n validateColorDefs(defs, externalBases);\n const order = topoSort(defs);\n\n const ctx: ResolveContext = {\n hue,\n saturation,\n defs,\n resolved: new Map(),\n config,\n roles: new Map(),\n };\n\n // Pre-seed externally-resolved bases. The per-pass loops iterate only\n // `defs` keys (via `order`), so external entries persist across all\n // four passes and are read via `getSchemeVariant` per scheme.\n if (externalBases) {\n for (const [name, color] of externalBases) {\n ctx.resolved.set(name, color);\n }\n }\n\n // Pass 1: Light normal.\n const lightMap = runPass(order, defs, ctx, false, false, 'light');\n\n // Pass 2: Light high-contrast.\n seedField(order, ctx, 'lightContrast', lightMap);\n const lightHCMap = runPass(order, defs, ctx, false, true, 'lightContrast');\n\n // Pass 3: Dark normal.\n seedField(order, ctx, 'dark', lightMap);\n seedField(order, ctx, 'darkContrast', lightHCMap);\n const darkMap = runPass(order, defs, ctx, true, false, 'dark');\n\n // Pass 4: Dark high-contrast.\n seedField(order, ctx, 'darkContrast', darkMap);\n const darkHCMap = runPass(order, defs, ctx, true, true, 'darkContrast');\n\n const result = new Map<string, ResolvedColor>();\n for (const name of order) {\n result.set(name, {\n name,\n light: lightMap.get(name)!,\n dark: darkMap.get(name)!,\n lightContrast: lightHCMap.get(name)!,\n darkContrast: darkHCMap.get(name)!,\n mode: defMode(defs[name]),\n });\n }\n\n verifyContrastDrift(order, defs, result, config);\n\n return result;\n}\n\n// Re-export for callers that previously imported tone helpers from here.\nexport { fromTone, toTone };\n","/**\n * Hue channel planning for `splitHue` exports.\n *\n * Builds per-color hue var references and scheme-independent `--*-hue`\n * declarations for oklch CSS / Tasty output when every color is pastel.\n */\n\nimport { parseRelativeOrAbsolute } from './hc-pair';\nimport { isMixDef, isShadowDef } from './shadow';\nimport type {\n ColorDef,\n ColorMap,\n RegularColorDef,\n ResolvedColor,\n ResolvedColorVariant,\n} from './types';\n\nconst ACHROMATIC_EPSILON = 1e-6;\n\nexport interface HueDeclaration {\n prop: string;\n value: string;\n}\n\nexport interface HuePlan {\n /** CSS `var()` reference spliced into `oklch(L C <hueVar>)`. */\n hueVar: string;\n /** When true, emit a full inline color (shadow/mix/achromatic). */\n inline: boolean;\n /** Scheme-independent `--*-hue` declarations for this color. */\n declarations: HueDeclaration[];\n}\n\nexport interface ChannelCtx {\n seedHue: number;\n /** Theme-level hue var base name (without `--` / `-hue`). */\n baseName: string;\n /** Token / custom-property name prefix used for hue var naming (`brand-` etc.). */\n prefix: string;\n defs: ColorMap;\n mode: 'theme' | 'standalone';\n /** Standalone: resolved hue from the primary variant (scheme-independent). */\n resolvedHue?: number;\n /**\n * When false, hue declarations are not emitted (the pass only references\n * hue vars already declared by a sibling pass). Used by palette primary\n * unprefixed aliases so they reference the themed `--{themeName}-*-hue`\n * vars without re-declaring (and colliding with) other themes' base vars.\n * Defaults to true.\n */\n emitDeclarations?: boolean;\n}\n\nfunction cssProp(prefix: string, name: string, suffix: string): string {\n return `--${prefix}${name}${suffix}`;\n}\n\nfunction isAchromatic(v: ResolvedColorVariant): boolean {\n return v.s <= ACHROMATIC_EPSILON;\n}\n\nfunction themeHuePlan(\n name: string,\n def: ColorDef | undefined,\n variant: ResolvedColorVariant,\n ctx: ChannelCtx,\n): HuePlan {\n if (\n def === undefined ||\n isShadowDef(def) ||\n isMixDef(def) ||\n isAchromatic(variant)\n ) {\n return { hueVar: '', inline: true, declarations: [] };\n }\n\n const regDef = def as RegularColorDef;\n const baseHueVar = `var(--${ctx.baseName}-hue)`;\n\n if (regDef.hue === undefined) {\n return { hueVar: baseHueVar, inline: false, declarations: [] };\n }\n\n const parsed = parseRelativeOrAbsolute(regDef.hue);\n const prop = cssProp(ctx.prefix, name, '-hue');\n\n if (parsed.relative) {\n const sign = parsed.value >= 0 ? '+' : '-';\n const magnitude = Math.abs(parsed.value);\n const value = `calc(var(--${ctx.baseName}-hue) ${sign} ${magnitude})`;\n return {\n hueVar: `var(${prop})`,\n inline: false,\n declarations: [{ prop, value }],\n };\n }\n\n const absHue = ((parsed.value % 360) + 360) % 360;\n return {\n hueVar: `var(${prop})`,\n inline: false,\n declarations: [{ prop, value: String(absHue) }],\n };\n}\n\nfunction standaloneHuePlan(\n name: string,\n variant: ResolvedColorVariant,\n ctx: ChannelCtx,\n): HuePlan {\n if (isAchromatic(variant)) {\n return { hueVar: '', inline: true, declarations: [] };\n }\n\n const hue = ctx.resolvedHue ?? variant.h;\n const prop = cssProp(ctx.prefix, name, '-hue');\n return {\n hueVar: `var(${prop})`,\n inline: false,\n declarations: [{ prop, value: String(hue) }],\n };\n}\n\nexport function buildHuePlan(\n name: string,\n def: ColorDef | undefined,\n variant: ResolvedColorVariant,\n ctx: ChannelCtx,\n): HuePlan {\n if (ctx.mode === 'standalone') {\n return standaloneHuePlan(name, variant, ctx);\n }\n return themeHuePlan(name, def, variant, ctx);\n}\n\n/** Collect unique hue declarations across all colors (theme + per-color). */\nexport function collectHueDeclarations(\n resolved: Map<string, ResolvedColor>,\n ctx: ChannelCtx,\n): HueDeclaration[] {\n if (ctx.emitDeclarations === false) return [];\n\n const seen = new Set<string>();\n const out: HueDeclaration[] = [];\n\n const push = (decl: HueDeclaration): void => {\n if (seen.has(decl.prop)) return;\n seen.add(decl.prop);\n out.push(decl);\n };\n\n if (ctx.mode === 'theme') {\n push({\n prop: `--${ctx.baseName}-hue`,\n value: String(ctx.seedHue),\n });\n }\n\n for (const [name, color] of resolved) {\n const def = ctx.defs[name];\n const plan = buildHuePlan(name, def, color.light, ctx);\n for (const decl of plan.declarations) {\n push(decl);\n }\n }\n\n return out;\n}\n\nexport function buildHuePlans(\n resolved: Map<string, ResolvedColor>,\n ctx: ChannelCtx,\n): Map<string, HuePlan> {\n const plans = new Map<string, HuePlan>();\n for (const [name, color] of resolved) {\n plans.set(name, buildHuePlan(name, ctx.defs[name], color.light, ctx));\n }\n return plans;\n}\n","/**\n * Output formatting for resolved color maps.\n *\n * Owns the CSS-string formatter dispatch table (`okhsl` / `rgb` / `hsl` /\n * `oklch`) and the token-map shapes Glaze emits:\n * - `buildTokenMap` — Tasty style-to-state bindings (`#name` keys, state aliases).\n * - `buildFlatTokenMap` — `{ light, dark, ... }` per-variant maps.\n * - `buildJsonMap` — `{ name: { light, dark, ... } }` per-color JSON.\n * - `buildCssMap` — CSS custom property declaration strings per variant.\n * - `buildDtcgMap` — W3C DTCG (2025.10) token documents, one per scheme.\n * - `buildDtcgResolver` — W3C DTCG Resolver-Module document (one modifier, a context per scheme).\n * - `buildTailwindMap` — Tailwind v4 `@theme` block + dark/HC overrides.\n */\n\nimport {\n buildHuePlans,\n collectHueDeclarations,\n type ChannelCtx,\n type HuePlan,\n} from './channels';\nimport {\n formatHsl,\n formatOkhsl,\n formatOkhst,\n formatOklch,\n formatRgb,\n okhslToOklch,\n okhslToSrgb,\n srgbToHex,\n} from './okhsl-color-math';\nimport { variantToOkhsl } from './okhst';\nimport { getConfig } from './config';\nimport type {\n DtcgColorSpace,\n DtcgColorToken,\n DtcgColorValue,\n DtcgDocument,\n DtcgTokenTree,\n GlazeColorFormat,\n GlazeCssResult,\n GlazeDtcgResolverDocument,\n GlazeDtcgResolverOptions,\n GlazeDtcgResult,\n GlazeOutputModes,\n ResolvedColor,\n ResolvedColorVariant,\n} from './types';\n\nexport type { ChannelCtx } from './channels';\n\nconst formatters: Record<\n Exclude<GlazeColorFormat, 'okhst'>,\n (h: number, s: number, l: number, pastel: boolean) => string\n> = {\n okhsl: formatOkhsl,\n rgb: formatRgb,\n hsl: formatHsl,\n oklch: formatOklch,\n};\n\nfunction fmt(value: number, decimals: number): string {\n return parseFloat(value.toFixed(decimals)).toString();\n}\n\nexport function formatVariant(\n v: ResolvedColorVariant,\n format: GlazeColorFormat = 'oklch',\n pastel = false,\n): string {\n // Variants store canonical tone; convert to OKHSL lightness at the edge.\n // Per-variant `pastel` (set by the resolver from def or config fallback)\n // wins over the format-time fallback, so output matches resolution.\n const effectivePastel = v.pastel ?? pastel;\n\n let base: string;\n if (format === 'okhst') {\n base = formatOkhst(v.h, v.s * 100, v.t * 100, effectivePastel);\n } else {\n const { l } = variantToOkhsl(v);\n base = formatters[format](v.h, v.s * 100, l * 100, effectivePastel);\n }\n\n if (v.alpha >= 1) return base;\n const closing = base.lastIndexOf(')');\n return `${base.slice(0, closing)} / ${fmt(v.alpha, 4)})`;\n}\n\n/**\n * Format a resolved variant as `oklch(L C <hueVar>)`, splicing a CSS hue var\n * for `splitHue` exports. Falls back to inline when the plan is inline.\n */\nexport function formatVariantHue(\n v: ResolvedColorVariant,\n plan: HuePlan,\n pastel = false,\n): string {\n const effectivePastel = v.pastel ?? pastel;\n const { l } = variantToOkhsl(v);\n const [L, C] = okhslToOklch(v.h, v.s, l, effectivePastel);\n\n let base: string;\n if (plan.inline) {\n if (v.s <= 1e-6) {\n base = `oklch(${fmt(L, 4)} 0 0)`;\n } else {\n base = formatOklch(v.h, v.s * 100, l * 100, effectivePastel);\n }\n } else {\n base = `oklch(${fmt(L, 4)} ${fmt(C, 4)} ${plan.hueVar})`;\n }\n\n if (v.alpha >= 1) return base;\n const closing = base.lastIndexOf(')');\n return `${base.slice(0, closing)} / ${fmt(v.alpha, 4)})`;\n}\n\nfunction formatColorValue(\n v: ResolvedColorVariant,\n format: GlazeColorFormat,\n pastel: boolean,\n huePlan?: HuePlan,\n): string {\n if (format === 'oklch' && huePlan !== undefined) {\n return formatVariantHue(v, huePlan, pastel);\n }\n return formatVariant(v, format, pastel);\n}\n\nexport function resolveModes(\n override?: GlazeOutputModes,\n): Required<GlazeOutputModes> {\n const cfg = getConfig();\n return {\n dark: override?.dark ?? cfg.modes.dark,\n highContrast: override?.highContrast ?? cfg.modes.highContrast,\n };\n}\n\nexport function buildTokenMap(\n resolved: Map<string, ResolvedColor>,\n prefix: string,\n states: { dark: string; highContrast: string },\n modes: Required<GlazeOutputModes>,\n format: GlazeColorFormat = 'oklch',\n pastel = false,\n channelCtx?: ChannelCtx,\n): Record<string, Record<string, string>> {\n const tokens: Record<string, Record<string, string>> = {};\n const huePlans =\n channelCtx !== undefined && format === 'oklch'\n ? buildHuePlans(resolved, channelCtx)\n : undefined;\n\n if (huePlans !== undefined && channelCtx !== undefined) {\n const emitDecls = channelCtx.emitDeclarations !== false;\n if (emitDecls && channelCtx.mode === 'theme') {\n tokens[`$${channelCtx.baseName}-hue`] = {\n '': String(channelCtx.seedHue),\n };\n }\n for (const [name, color] of resolved) {\n const plan = huePlans.get(name)!;\n if (emitDecls) {\n for (const decl of plan.declarations) {\n const key = `$${decl.prop.slice(2)}`;\n if (!(key in tokens)) {\n tokens[key] = { '': decl.value };\n }\n }\n }\n const colorKey = `#${prefix}${name}`;\n const planForColor = huePlans.get(name);\n tokens[colorKey] = buildTokenEntry(\n color,\n states,\n modes,\n format,\n pastel,\n planForColor,\n );\n }\n return tokens;\n }\n\n for (const [name, color] of resolved) {\n const key = `#${prefix}${name}`;\n tokens[key] = buildTokenEntry(color, states, modes, format, pastel);\n }\n\n return tokens;\n}\n\nfunction buildTokenEntry(\n color: ResolvedColor,\n states: { dark: string; highContrast: string },\n modes: Required<GlazeOutputModes>,\n format: GlazeColorFormat,\n pastel: boolean,\n huePlan?: HuePlan,\n): Record<string, string> {\n const entry: Record<string, string> = {\n '': formatColorValue(color.light, format, pastel, huePlan),\n };\n\n if (modes.dark) {\n entry[states.dark] = formatColorValue(color.dark, format, pastel, huePlan);\n }\n if (modes.highContrast) {\n entry[states.highContrast] = formatColorValue(\n color.lightContrast,\n format,\n pastel,\n huePlan,\n );\n }\n if (modes.dark && modes.highContrast) {\n entry[`${states.dark} & ${states.highContrast}`] = formatColorValue(\n color.darkContrast,\n format,\n pastel,\n huePlan,\n );\n }\n\n return entry;\n}\n\nexport function buildFlatTokenMap(\n resolved: Map<string, ResolvedColor>,\n prefix: string,\n modes: Required<GlazeOutputModes>,\n format: GlazeColorFormat = 'oklch',\n pastel = false,\n): Record<string, Record<string, string>> {\n const result: Record<string, Record<string, string>> = {\n light: {},\n };\n\n if (modes.dark) {\n result.dark = {};\n }\n if (modes.highContrast) {\n result.lightContrast = {};\n }\n if (modes.dark && modes.highContrast) {\n result.darkContrast = {};\n }\n\n for (const [name, color] of resolved) {\n const key = `${prefix}${name}`;\n\n result.light[key] = formatVariant(color.light, format, pastel);\n\n if (modes.dark) {\n result.dark[key] = formatVariant(color.dark, format, pastel);\n }\n if (modes.highContrast) {\n result.lightContrast[key] = formatVariant(\n color.lightContrast,\n format,\n pastel,\n );\n }\n if (modes.dark && modes.highContrast) {\n result.darkContrast[key] = formatVariant(\n color.darkContrast,\n format,\n pastel,\n );\n }\n }\n\n return result;\n}\n\nexport function buildJsonMap(\n resolved: Map<string, ResolvedColor>,\n modes: Required<GlazeOutputModes>,\n format: GlazeColorFormat = 'oklch',\n pastel = false,\n): Record<string, Record<string, string>> {\n const result: Record<string, Record<string, string>> = {};\n\n for (const [name, color] of resolved) {\n const entry: Record<string, string> = {\n light: formatVariant(color.light, format, pastel),\n };\n\n if (modes.dark) {\n entry.dark = formatVariant(color.dark, format, pastel);\n }\n if (modes.highContrast) {\n entry.lightContrast = formatVariant(color.lightContrast, format, pastel);\n }\n if (modes.dark && modes.highContrast) {\n entry.darkContrast = formatVariant(color.darkContrast, format, pastel);\n }\n\n result[name] = entry;\n }\n\n return result;\n}\n\nexport function buildCssMap(\n resolved: Map<string, ResolvedColor>,\n prefix: string,\n suffix: string,\n format: GlazeColorFormat,\n pastel = false,\n channelCtx?: ChannelCtx,\n): GlazeCssResult {\n const lines: Record<keyof GlazeCssResult, string[]> = {\n light: [],\n dark: [],\n lightContrast: [],\n darkContrast: [],\n };\n\n const huePlans =\n channelCtx !== undefined && format === 'oklch'\n ? buildHuePlans(resolved, channelCtx)\n : undefined;\n\n if (huePlans !== undefined && channelCtx !== undefined) {\n for (const decl of collectHueDeclarations(resolved, channelCtx)) {\n lines.light.push(`${decl.prop}: ${decl.value};`);\n }\n }\n\n for (const [name, color] of resolved) {\n const prop = `--${prefix}${name}${suffix}`;\n const plan = huePlans?.get(name);\n lines.light.push(\n `${prop}: ${formatColorValue(color.light, format, pastel, plan)};`,\n );\n lines.dark.push(\n `${prop}: ${formatColorValue(color.dark, format, pastel, plan)};`,\n );\n lines.lightContrast.push(\n `${prop}: ${formatColorValue(color.lightContrast, format, pastel, plan)};`,\n );\n lines.darkContrast.push(\n `${prop}: ${formatColorValue(color.darkContrast, format, pastel, plan)};`,\n );\n }\n\n return {\n light: lines.light.join('\\n'),\n dark: lines.dark.join('\\n'),\n lightContrast: lines.lightContrast.join('\\n'),\n darkContrast: lines.darkContrast.join('\\n'),\n };\n}\n\n// ============================================================================\n// DTCG (W3C Design Tokens Format Module 2025.10)\n// ============================================================================\n\nfunction roundTo(value: number, decimals: number): number {\n return parseFloat(value.toFixed(decimals));\n}\n\n/**\n * Build a DTCG `$value` color object for a resolved variant.\n *\n * `srgb` (default) emits gamma sRGB components in 0–1 plus a 6-digit `hex`\n * hint — the most universally understood form (Figma, Tokens Studio, Style\n * Dictionary). `oklch` emits `[L, C, H]` components with no hex — Glaze-native\n * and wide-gamut. `alpha` is included only when below 1.\n */\nexport function dtcgColorValue(\n v: ResolvedColorVariant,\n colorSpace: DtcgColorSpace = 'srgb',\n pastel = false,\n): DtcgColorValue {\n const effectivePastel = v.pastel ?? pastel;\n const { l } = variantToOkhsl(v);\n const alpha = v.alpha < 1 ? roundTo(v.alpha, 6) : undefined;\n\n if (colorSpace === 'oklch') {\n const [L, C, H] = okhslToOklch(v.h, v.s, l, effectivePastel);\n const value: DtcgColorValue = {\n colorSpace: 'oklch',\n components: [roundTo(L, 6), roundTo(C, 6), roundTo(H, 4)],\n };\n if (alpha !== undefined) value.alpha = alpha;\n return value;\n }\n\n const [r, g, b] = okhslToSrgb(v.h, v.s, l, effectivePastel);\n const value: DtcgColorValue = {\n colorSpace: 'srgb',\n components: [roundTo(r, 6), roundTo(g, 6), roundTo(b, 6)],\n hex: srgbToHex([r, g, b]),\n };\n if (alpha !== undefined) value.alpha = alpha;\n return value;\n}\n\nfunction dtcgToken(\n v: ResolvedColorVariant,\n colorSpace: DtcgColorSpace,\n pastel: boolean,\n): DtcgColorToken {\n return { $type: 'color', $value: dtcgColorValue(v, colorSpace, pastel) };\n}\n\n/**\n * Build a `GlazeDtcgResult`: one spec-conformant DTCG token document per\n * scheme variant, gated by `modes`. Light is always present.\n */\nexport function buildDtcgMap(\n resolved: Map<string, ResolvedColor>,\n prefix: string,\n modes: Required<GlazeOutputModes>,\n colorSpace: DtcgColorSpace = 'srgb',\n pastel = false,\n): GlazeDtcgResult {\n const light: DtcgDocument = {};\n const dark: DtcgDocument | undefined = modes.dark ? {} : undefined;\n const lightContrast: DtcgDocument | undefined = modes.highContrast\n ? {}\n : undefined;\n const darkContrast: DtcgDocument | undefined =\n modes.dark && modes.highContrast ? {} : undefined;\n\n for (const [name, color] of resolved) {\n const key = `${prefix}${name}`;\n light[key] = dtcgToken(color.light, colorSpace, pastel);\n if (dark) dark[key] = dtcgToken(color.dark, colorSpace, pastel);\n if (lightContrast) {\n lightContrast[key] = dtcgToken(color.lightContrast, colorSpace, pastel);\n }\n if (darkContrast) {\n darkContrast[key] = dtcgToken(color.darkContrast, colorSpace, pastel);\n }\n }\n\n return { light, dark, lightContrast, darkContrast };\n}\n\n// ============================================================================\n// DTCG Resolver Module (single document for all scheme variants)\n// ============================================================================\n\n/**\n * Default context names emitted on the `scheme` modifier — the Glaze variant\n * keys, so the resolver document mirrors `GlazeDtcgResult` exactly.\n */\nconst DEFAULT_DTCG_CONTEXT_NAMES = {\n light: 'light',\n dark: 'dark',\n lightContrast: 'lightContrast',\n darkContrast: 'darkContrast',\n} as const;\n\n/**\n * Wrap a per-scheme `GlazeDtcgResult` into a single W3C DTCG Resolver-Module\n * document. The light document becomes `sets[setName].sources[0]` (the default\n * context); each other present variant becomes a `contexts[ctx]` override\n * array on a single `modifiers[modifierName]`. Absent variants (per the\n * `modes` already applied to `result`) are omitted — light is always present\n * and is the modifier `default`. Only the resolver-specific options are read;\n * `modes` / `colorSpace` were already consumed by the `buildDtcgMap` call that\n * produced `result`.\n */\nexport function buildDtcgResolver(\n result: GlazeDtcgResult,\n options?: GlazeDtcgResolverOptions,\n): GlazeDtcgResolverDocument {\n const setName = options?.setName ?? 'base';\n const modifierName = options?.modifierName ?? 'scheme';\n const ctx = {\n ...DEFAULT_DTCG_CONTEXT_NAMES,\n ...options?.contextNames,\n };\n const contexts: Record<string, DtcgTokenTree[]> = {\n [ctx.light]: [],\n };\n if (result.dark) contexts[ctx.dark] = [result.dark];\n if (result.lightContrast) {\n contexts[ctx.lightContrast] = [result.lightContrast];\n }\n if (result.darkContrast) contexts[ctx.darkContrast] = [result.darkContrast];\n\n return {\n version: options?.version ?? '2025.10',\n sets: {\n [setName]: { sources: [result.light] },\n },\n modifiers: {\n [modifierName]: {\n default: ctx.light,\n contexts,\n },\n },\n resolutionOrder: [\n { $ref: `#/sets/${setName}` },\n { $ref: `#/modifiers/${modifierName}` },\n ],\n };\n}\n\n// ============================================================================\n// Tailwind CSS v4 (@theme)\n// ============================================================================\n\n/** Per-scheme declaration lines (`--prop: value;`) accumulated for emission. */\nexport interface GlazeTailwindLines {\n light: string[];\n dark: string[];\n lightContrast: string[];\n darkContrast: string[];\n}\n\nfunction tailwindLinesFor(\n resolved: Map<string, ResolvedColor>,\n themePrefix: string,\n cssPrefix: string,\n format: GlazeColorFormat,\n pastel: boolean,\n): GlazeTailwindLines {\n const lines: GlazeTailwindLines = {\n light: [],\n dark: [],\n lightContrast: [],\n darkContrast: [],\n };\n for (const [name, color] of resolved) {\n const prop = `--${cssPrefix}${themePrefix}${name}`;\n lines.light.push(`${prop}: ${formatVariant(color.light, format, pastel)};`);\n lines.dark.push(`${prop}: ${formatVariant(color.dark, format, pastel)};`);\n lines.lightContrast.push(\n `${prop}: ${formatVariant(color.lightContrast, format, pastel)};`,\n );\n lines.darkContrast.push(\n `${prop}: ${formatVariant(color.darkContrast, format, pastel)};`,\n );\n }\n return lines;\n}\n\nfunction indentBlock(text: string, pad: string): string {\n return text\n .split('\\n')\n .map((line) => (line.length === 0 ? line : pad + line))\n .join('\\n');\n}\n\nfunction emitRule(selector: string, body: string): string {\n return `${selector} {\\n${indentBlock(body, ' ')}\\n}`;\n}\n\n/**\n * Emit a CSS block for a set of declarations scoped by one or more selectors\n * / at-rules. Class-like selectors concatenate (`.dark.high-contrast`);\n * at-rules (`@media …`) nest `:root` (or the chained selector) inside.\n */\nfunction emitScoped(\n scopes: string[],\n declarations: string[],\n): string | undefined {\n if (declarations.length === 0) return undefined;\n\n const atRules: string[] = [];\n let selectorChain = '';\n for (const scope of scopes) {\n if (scope.startsWith('@')) atRules.push(scope);\n else selectorChain += scope;\n }\n const selector = selectorChain || ':root';\n\n let css = emitRule(selector, declarations.join('\\n'));\n for (const rule of atRules) {\n css = emitRule(rule, css);\n }\n return css;\n}\n\n/**\n * Render accumulated per-scheme declaration lines as a Tailwind v4 CSS string:\n * an `@theme` block (light baseline) plus dark / high-contrast overrides under\n * the configured selectors. Empty blocks are skipped.\n */\nexport function emitTailwindCss(\n lines: GlazeTailwindLines,\n modes: Required<GlazeOutputModes>,\n darkSelector: string,\n highContrastSelector: string,\n): string {\n const blocks: string[] = [];\n\n if (lines.light.length > 0) {\n blocks.push(emitRule('@theme', lines.light.join('\\n')));\n }\n\n if (modes.dark) {\n const dark = emitScoped([darkSelector], lines.dark);\n if (dark) blocks.push(dark);\n }\n if (modes.highContrast) {\n const hc = emitScoped([highContrastSelector], lines.lightContrast);\n if (hc) blocks.push(hc);\n }\n if (modes.dark && modes.highContrast) {\n const dhc = emitScoped(\n [darkSelector, highContrastSelector],\n lines.darkContrast,\n );\n if (dhc) blocks.push(dhc);\n }\n\n return blocks.join('\\n\\n');\n}\n\n/**\n * Build per-scheme declaration lines for a single theme (used by\n * `theme.tailwind()` and as the palette `buildOne` step).\n */\nexport function buildTailwindLines(\n resolved: Map<string, ResolvedColor>,\n themePrefix: string,\n cssPrefix: string,\n format: GlazeColorFormat,\n pastel: boolean,\n): GlazeTailwindLines {\n return tailwindLinesFor(resolved, themePrefix, cssPrefix, format, pastel);\n}\n\n/**\n * Build a complete Tailwind v4 CSS string for a single theme.\n */\nexport function buildTailwindMap(\n resolved: Map<string, ResolvedColor>,\n themePrefix: string,\n cssPrefix: string,\n modes: Required<GlazeOutputModes>,\n format: GlazeColorFormat,\n darkSelector: string,\n highContrastSelector: string,\n pastel = false,\n): string {\n const lines = tailwindLinesFor(\n resolved,\n themePrefix,\n cssPrefix,\n format,\n pastel,\n );\n return emitTailwindCss(lines, modes, darkSelector, highContrastSelector);\n}\n","/**\n * Standalone single-color tokens (`glaze.color()` / `glaze.colorFrom()`).\n *\n * Owns the value-shorthand parser (hex, `rgb()` / `hsl()` / `okhsl()` /\n * `okhst()` / `oklch()`, `{ r, g, b }`, `{ h, s, l }`, `{ h, s, t }`,\n * `{ l, c, h }`), the structured-input validator, the two factory paths\n * (value vs structured), and the JSON-safe export / rehydration round-trip.\n *\n * Tokens store a sparse local config override only. Resolve merges the\n * live global config with that local override (invalidated on\n * `configure()`). Authoring `.export(override?)` freezes\n * `getConfig() ∪ local ∪ override` at call time.\n */\n\nimport {\n freezeConfigForExport,\n getConfig,\n getConfigVersion,\n mergeConfig,\n} from './config';\nimport {\n assertExportKind,\n assertExportVersion,\n GLAZE_EXPORT_VERSION,\n isColorTokenExport,\n} from './serialize';\nimport type { ChannelCtx } from './channels';\nimport { assertAllPastel, assertNativeFormat } from './format-guard';\nimport {\n hslToSrgb,\n oklabToOkhsl,\n parseHexAlpha,\n srgbToOkhsl,\n} from './okhsl-color-math';\nimport { okhstToOkhsl, toTone } from './okhst';\nimport { isAbsoluteTone, pairNormal } from './hc-pair';\nimport { resolveAllColors } from './resolver';\nimport {\n buildCssMap,\n buildDtcgMap,\n buildDtcgResolver,\n buildJsonMap,\n buildTailwindMap,\n buildTokenMap,\n resolveModes,\n} from './formatters';\nimport type {\n ColorMap,\n GlazeColorCssOptions,\n GlazeColorDtcgResolverOptions,\n GlazeColorDtcgResult,\n GlazeColorInput,\n GlazeColorInputExport,\n GlazeColorOverrides,\n GlazeColorOverridesExport,\n GlazeColorTailwindOptions,\n GlazeColorToken,\n GlazeColorTokenExport,\n GlazeColorValue,\n GlazeCssResult,\n GlazeConfigOverride,\n GlazeConfigResolved,\n GlazeDtcgOptions,\n GlazeDtcgResolverDocument,\n GlazeDtcgResult,\n GlazeJsonOptions,\n GlazeTokenOptions,\n OkhslColor,\n OkhstColor,\n OklchColor,\n RgbColor,\n RegularColorDef,\n ResolvedColor,\n} from './types';\n\n// ============================================================================\n// Standalone color constants\n// ============================================================================\n\n/** Internal name of the user-facing standalone color in the synthesized def map. */\nconst STANDALONE_VALUE = 'value';\n/** Internal name of the hidden static-anchor seed used for relative tone / contrast. */\nconst STANDALONE_SEED = 'seed';\n/** Internal name of an externally-resolved `GlazeColorToken` injected as a base reference. */\nconst STANDALONE_BASE = 'externalBase';\n\n/** Reserved internal names that user-supplied `name` must not collide with. */\nconst RESERVED_STANDALONE_NAMES = new Set([\n STANDALONE_VALUE,\n STANDALONE_SEED,\n STANDALONE_BASE,\n]);\n\n// ============================================================================\n// Sparse local config (no global freeze at create)\n// ============================================================================\n\n/**\n * Value-form local override: `lightTone` defaults to `false` (preserve\n * input tone). User override fields win.\n */\nfunction sparseValueFormLocal(\n userOverride?: GlazeConfigOverride,\n): GlazeConfigOverride {\n return {\n ...userOverride,\n lightTone:\n userOverride?.lightTone !== undefined ? userOverride.lightTone : false,\n };\n}\n\n// ============================================================================\n// Color string parsing\n// ============================================================================\n\n/**\n * Matches the CSS color functions Glaze itself emits (`rgb()`, `hsl()`,\n * `okhsl()`, `oklch()`) plus their legacy alpha aliases (`rgba()`, `hsla()`).\n *\n * Only bare numeric components are supported. Named colors (`red`),\n * relative-color syntax (`from <color> ...`), and angle units other\n * than bare degrees (`deg` is the only suffix tolerated by `parseFloat`)\n * are out of scope.\n */\nconst COLOR_FN_RE = /^(rgba?|hsla?|okhsl|okhst|oklch)\\(\\s*([^)]*)\\s*\\)$/i;\n\nfunction parseNumberOrPercent(raw: string, percentScale: number): number {\n if (raw.endsWith('%')) {\n return (parseFloat(raw) / 100) * percentScale;\n }\n return parseFloat(raw);\n}\n\n/**\n * Split the body of a CSS color function into its components and detect\n * whether an alpha channel was present.\n *\n * Handles both modern slash syntax (`R G B / A` or `R, G, B / A`) and\n * legacy comma syntax (`R, G, B, A`). The alpha value itself is discarded\n * by the caller — standalone Glaze colors have no opacity field.\n */\nfunction splitColorBody(body: string): {\n components: string[];\n hadAlpha: boolean;\n} {\n const slashIdx = body.indexOf('/');\n if (slashIdx !== -1) {\n const components = body\n .slice(0, slashIdx)\n .trim()\n .split(/[\\s,]+/)\n .filter(Boolean);\n const hadAlpha = body.slice(slashIdx + 1).trim().length > 0;\n return { components, hadAlpha };\n }\n\n const components = body.split(/[\\s,]+/).filter(Boolean);\n if (components.length === 4) {\n components.pop();\n return { components, hadAlpha: true };\n }\n return { components, hadAlpha: false };\n}\n\nfunction warnDroppedAlpha(input: string): void {\n console.warn(\n `glaze: alpha component dropped from \"${input}\" (standalone color has no opacity field).`,\n );\n}\n\nfunction parseColorString(input: string): OkhslColor {\n if (input.startsWith('#')) {\n const parsed = parseHexAlpha(input);\n if (!parsed) throw new Error(`glaze: invalid hex color \"${input}\".`);\n if (parsed.alpha !== undefined) warnDroppedAlpha(input);\n const [h, s, l] = srgbToOkhsl(parsed.rgb);\n return { h, s, l };\n }\n\n const m = input.match(COLOR_FN_RE);\n if (!m) {\n throw new Error(`glaze: unsupported color string \"${input}\".`);\n }\n\n const fn = m[1].toLowerCase();\n const { components, hadAlpha } = splitColorBody(m[2].trim());\n\n if (hadAlpha) warnDroppedAlpha(input);\n if (components.length !== 3) {\n throw new Error(`glaze: expected 3 components in \"${input}\".`);\n }\n\n switch (fn) {\n case 'rgb':\n case 'rgba': {\n const r = parseNumberOrPercent(components[0], 255) / 255;\n const g = parseNumberOrPercent(components[1], 255) / 255;\n const b = parseNumberOrPercent(components[2], 255) / 255;\n const [h, s, l] = srgbToOkhsl([r, g, b]);\n return { h, s, l };\n }\n case 'hsl':\n case 'hsla': {\n const h = parseFloat(components[0]);\n const s = parseNumberOrPercent(components[1], 1);\n const l = parseNumberOrPercent(components[2], 1);\n const [oh, os, ol] = srgbToOkhsl(hslToSrgb(h, s, l));\n return { h: oh, s: os, l: ol };\n }\n case 'okhsl': {\n const h = parseFloat(components[0]);\n const s = parseNumberOrPercent(components[1], 1);\n const l = parseNumberOrPercent(components[2], 1);\n return { h, s, l };\n }\n case 'okhst': {\n const h = parseFloat(components[0]);\n const s = parseNumberOrPercent(components[1], 1);\n const t = parseNumberOrPercent(components[2], 1);\n return okhstToOkhsl({ h, s, t });\n }\n case 'oklch': {\n const L = parseNumberOrPercent(components[0], 1);\n // Per CSS Color 4: chroma percent maps `100% → 0.4`.\n const C = parseNumberOrPercent(components[1], 0.4);\n const hDeg = parseFloat(components[2]);\n const hRad = (hDeg * Math.PI) / 180;\n const a = C * Math.cos(hRad);\n const b = C * Math.sin(hRad);\n const [h, s, l] = oklabToOkhsl([L, a, b]);\n return { h, s, l };\n }\n }\n throw new Error(`glaze: unsupported color function \"${fn}\".`);\n}\n\n// ============================================================================\n// Input validation\n// ============================================================================\n\n/**\n * Validate a user-supplied `OkhslColor`. Catches the common 0-100 vs 0-1\n * confusion (the structured form uses 0-100, OKHSL objects use 0-1).\n */\nfunction validateOkhslColor(value: OkhslColor): void {\n const { h, s, l } = value;\n if (!Number.isFinite(h) || !Number.isFinite(s) || !Number.isFinite(l)) {\n throw new Error('glaze.color: OkhslColor h/s/l must be finite numbers.');\n }\n if (s > 1.5 || l > 1.5) {\n throw new Error(\n 'glaze.color: OkhslColor s/l must be in 0–1 range. Did you mean the structured form { hue, saturation, tone } (which uses 0–100)?',\n );\n }\n}\n\n/** Validate a user-supplied `{ r, g, b }` object in 0–255. */\nfunction validateRgbColor(value: RgbColor): void {\n for (const key of ['r', 'g', 'b'] as const) {\n const n = value[key];\n if (!Number.isFinite(n) || n < 0 || n > 255) {\n throw new Error(\n `glaze.color: RgbColor ${key} must be a finite number in 0–255 (got ${n}).`,\n );\n }\n }\n}\n\n/** Validate a user-supplied `{ l, c, h }` OKLCh object. */\nfunction validateOklchColor(value: OklchColor): void {\n const { l, c, h } = value;\n if (!Number.isFinite(l) || !Number.isFinite(c) || !Number.isFinite(h)) {\n throw new Error('glaze.color: OklchColor l/c/h must be finite numbers.');\n }\n if (l > 1.5 || c > 1.5) {\n throw new Error(\n 'glaze.color: OklchColor l/c must be in 0–1 range (matching oklch() strings).',\n );\n }\n}\n\nfunction oklchComponentsToOkhsl(\n l: number,\n c: number,\n hDeg: number,\n): OkhslColor {\n const hRad = (hDeg * Math.PI) / 180;\n const a = c * Math.cos(hRad);\n const b = c * Math.sin(hRad);\n const [h, s, outL] = oklabToOkhsl([l, a, b]);\n return { h, s, l: outL };\n}\n\nfunction isRgbColorObject(value: object): value is RgbColor {\n return 'r' in value && 'g' in value && 'b' in value;\n}\n\nfunction isOklchColorObject(value: object): value is OklchColor {\n return 'c' in value && 'l' in value && 'h' in value;\n}\n\nfunction isOkhstColorObject(value: object): value is OkhstColor {\n return 't' in value && 'h' in value && 's' in value;\n}\n\n/** Validate a user-supplied `{ h, s, t }` OKHST object (s/t in 0–1). */\nfunction validateOkhstColor(value: OkhstColor): void {\n const { h, s, t } = value;\n if (!Number.isFinite(h) || !Number.isFinite(s) || !Number.isFinite(t)) {\n throw new Error('glaze.color: OkhstColor h/s/t must be finite numbers.');\n }\n if (s > 1.5 || t > 1.5) {\n throw new Error(\n 'glaze.color: OkhstColor s/t must be in 0–1 range. Did you mean the structured form { hue, saturation, tone } (which uses 0–100)?',\n );\n }\n}\n\n/**\n * Validate a user-supplied `opacity` override on `glaze.color()`.\n * Must be a finite number in `0..=1`.\n */\nfunction validateStandaloneOpacity(value: number): void {\n if (!Number.isFinite(value) || value < 0 || value > 1) {\n throw new Error(\n `glaze.color: opacity must be a finite number in 0–1 (got ${value}).`,\n );\n }\n}\n\n/**\n * Validate a structured `GlazeColorInput`. Range-checks the `hue` /\n * `saturation` / `tone` numerics (and any HC-pair second value)\n * before the resolver sees them so out-of-range or non-finite inputs\n * fail with a helpful, top-level error rather than producing a\n * NaN-laden token. `opacity` is checked here too so all input\n * validation lives in one place.\n */\nfunction validateStructuredInput(input: GlazeColorInput): void {\n if (!Number.isFinite(input.hue)) {\n throw new Error(\n `glaze.color: structured hue must be a finite number (got ${input.hue}).`,\n );\n }\n if (\n !Number.isFinite(input.saturation) ||\n input.saturation < 0 ||\n input.saturation > 100\n ) {\n throw new Error(\n `glaze.color: structured saturation must be a finite number in 0–100 (got ${input.saturation}).`,\n );\n }\n const checkTone = (value: number | string, label: string): void => {\n // 'max' / 'min' extreme keywords are always valid.\n if (value === 'max' || value === 'min') return;\n if (\n typeof value !== 'number' ||\n !Number.isFinite(value) ||\n value < 0 ||\n value > 100\n ) {\n throw new Error(\n `glaze.color: structured ${label} must be a finite number in 0–100 or 'max'/'min' (got ${String(value)}).`,\n );\n }\n };\n if (Array.isArray(input.tone)) {\n checkTone(input.tone[0], 'tone[normal]');\n checkTone(input.tone[1], 'tone[hc]');\n } else {\n checkTone(input.tone, 'tone');\n }\n if (input.saturationFactor !== undefined) {\n if (\n !Number.isFinite(input.saturationFactor) ||\n input.saturationFactor < 0 ||\n input.saturationFactor > 1\n ) {\n throw new Error(\n `glaze.color: structured saturationFactor must be a finite number in 0–1 (got ${input.saturationFactor}).`,\n );\n }\n }\n if (input.opacity !== undefined) validateStandaloneOpacity(input.opacity);\n}\n\n/**\n * Validate a user-supplied `name` override. Rejects empty / whitespace-only\n * strings and names colliding with `glaze`'s reserved internal sentinels.\n */\nfunction validateStandaloneName(name: string): void {\n if (typeof name !== 'string' || name.trim() === '') {\n throw new Error(\n 'glaze.color: name must be a non-empty string. ' +\n 'Omit `name` if you do not want to set a debug label.',\n );\n }\n if (RESERVED_STANDALONE_NAMES.has(name)) {\n const reserved = [...RESERVED_STANDALONE_NAMES]\n .map((n) => `\"${n}\"`)\n .join(', ');\n throw new Error(\n `glaze.color: name \"${name}\" is reserved (used internally). ` +\n `Reserved names are: ${reserved}. Pick a different name.`,\n );\n }\n}\n\n/**\n * Extract an OKHSL color from any `GlazeColorValue` form. Also used by\n * `glaze.shadow()` so all shadow inputs (hex, color functions, OKHSL,\n * literal objects) go through one parser.\n */\nexport function extractOkhslFromValue(value: GlazeColorValue): OkhslColor {\n if (typeof value === 'string') return parseColorString(value);\n if (Array.isArray(value)) {\n throw new Error(\n 'glaze.color: RGB tuple [r, g, b] is no longer supported — use { r, g, b } instead.',\n );\n }\n if (isRgbColorObject(value)) {\n validateRgbColor(value);\n const [h, s, l] = srgbToOkhsl([\n value.r / 255,\n value.g / 255,\n value.b / 255,\n ]);\n return { h, s, l };\n }\n if (isOklchColorObject(value)) {\n validateOklchColor(value);\n return oklchComponentsToOkhsl(value.l, value.c, value.h);\n }\n if (isOkhstColorObject(value)) {\n validateOkhstColor(value);\n return okhstToOkhsl(value);\n }\n validateOkhslColor(value);\n return value;\n}\n\n// ============================================================================\n// Factory: shared helpers\n// ============================================================================\n\ninterface ValueDefsResult {\n seedHue: number;\n seedSaturation: number;\n defs: ColorMap;\n primary: string;\n}\n\n/**\n * Build the `ColorMap` for a value-shorthand `glaze.color()` call.\n *\n * The user-facing color (`STANDALONE_VALUE`) defaults to `mode: 'auto'`\n * across every value-shorthand form.\n *\n * When the user requests `contrast` or relative `tone`, a hidden\n * `STANDALONE_SEED` def is synthesized at `mode: 'static'`. That keeps\n * the seed pinned to the literal user-provided color across all four\n * variants, so the contrast solver always anchors against it.\n */\nfunction buildStandaloneValueDefs(\n main: OkhslColor,\n options: GlazeColorOverrides | undefined,\n): ValueDefsResult {\n const seedHue = typeof options?.hue === 'number' ? options.hue : main.h;\n const seedSaturation = options?.saturation ?? main.s * 100;\n const relativeHue =\n typeof options?.hue === 'string' ? options.hue : undefined;\n\n const toneOption = options?.tone;\n const hasExternalBase = options?.base !== undefined;\n // Seed-anchor synthesis only kicks in when the user did NOT supply their\n // own base — in that case `contrast` and relative `tone` anchor to\n // the literal seed via the hidden `STANDALONE_SEED` def.\n const needsSeedAnchor =\n !hasExternalBase &&\n (options?.contrast !== undefined ||\n (toneOption !== undefined && !isAbsoluteTone(toneOption)));\n\n if (options?.opacity !== undefined)\n validateStandaloneOpacity(options.opacity);\n\n const userName = options?.name;\n if (userName !== undefined) validateStandaloneName(userName);\n const primary = userName ?? STANDALONE_VALUE;\n\n // The seed color is given in OKHSL lightness; express it as canonical tone.\n const seedTone = toTone(main.l);\n\n const valueDef: RegularColorDef = {\n hue: relativeHue,\n saturation: options?.saturationFactor,\n tone: toneOption ?? seedTone,\n contrast: options?.contrast,\n mode: options?.mode ?? 'auto',\n autoFlip: options?.autoFlip,\n opacity: options?.opacity,\n pastel: options?.pastel,\n role: options?.role,\n base: hasExternalBase\n ? STANDALONE_BASE\n : needsSeedAnchor\n ? STANDALONE_SEED\n : undefined,\n };\n\n const defs: ColorMap = { [primary]: valueDef };\n\n if (needsSeedAnchor) {\n defs[STANDALONE_SEED] = {\n hue: main.h,\n saturation: 1,\n tone: seedTone,\n mode: 'static',\n };\n }\n\n return {\n seedHue,\n seedSaturation,\n defs,\n primary,\n };\n}\n\nfunction createColorTokenFromDefs(\n seedHue: number,\n seedSaturation: number,\n defs: ColorMap,\n primary: string,\n configOverride: GlazeConfigOverride | undefined,\n baseToken: GlazeColorToken | undefined,\n buildExport: (override?: GlazeConfigOverride) => GlazeColorTokenExport,\n): GlazeColorToken {\n let cache: {\n map: Map<string, ResolvedColor> | null;\n version: number;\n effectiveConfig: GlazeConfigResolved;\n } | null = null;\n\n function getEffectiveConfig(): GlazeConfigResolved {\n const version = getConfigVersion();\n if (cache && cache.version === version) return cache.effectiveConfig;\n const effectiveConfig = mergeConfig(getConfig(), configOverride);\n cache = { map: null, version, effectiveConfig };\n return effectiveConfig;\n }\n\n const resolveOnce = (): Map<string, ResolvedColor> => {\n const version = getConfigVersion();\n if (cache && cache.version === version && cache.map) return cache.map;\n const effectiveConfig = getEffectiveConfig();\n const externalBases = baseToken\n ? new Map([[STANDALONE_BASE, baseToken.resolve()]])\n : undefined;\n const map = resolveAllColors(\n seedHue,\n seedSaturation,\n defs,\n effectiveConfig,\n externalBases,\n );\n cache = { map, version, effectiveConfig };\n return map;\n };\n\n const resolveStates = (options?: GlazeTokenOptions) => {\n const cfg = getConfig();\n return {\n dark: options?.states?.dark ?? cfg.states.dark,\n highContrast: options?.states?.highContrast ?? cfg.states.highContrast,\n };\n };\n\n const tokenLike = (options?: GlazeTokenOptions): Record<string, string> => {\n const tokenMap = buildTokenMap(\n resolveOnce(),\n '',\n resolveStates(options),\n resolveModes(options?.modes),\n options?.format ?? 'oklch',\n getEffectiveConfig().pastel,\n );\n return tokenMap[`#${primary}`];\n };\n\n return {\n resolve(): ResolvedColor {\n return resolveOnce().get(primary)!;\n },\n\n token: tokenLike,\n tasty: tokenLike,\n\n json(options?: GlazeJsonOptions): Record<string, string> {\n const format = options?.format ?? 'oklch';\n assertNativeFormat(format, 'json');\n const jsonMap = buildJsonMap(\n resolveOnce(),\n resolveModes(options?.modes),\n format,\n getEffectiveConfig().pastel,\n );\n return jsonMap[primary];\n },\n\n css(options: GlazeColorCssOptions): GlazeCssResult {\n const format = options.format ?? 'oklch';\n assertNativeFormat(format, 'css');\n const resolved = resolveOnce().get(primary)!;\n const renamed = new Map<string, ResolvedColor>([\n [options.name, resolved],\n ]);\n\n let channelCtx: ChannelCtx | undefined;\n if (options.splitHue && format === 'oklch') {\n const modes = resolveModes();\n assertAllPastel(renamed, modes);\n channelCtx = {\n seedHue,\n baseName: options.name,\n prefix: '',\n defs: { [options.name]: defs[primary] },\n mode: 'standalone',\n resolvedHue: resolved.light.h,\n };\n }\n\n return buildCssMap(\n renamed,\n '',\n options.suffix ?? '-color',\n format,\n getEffectiveConfig().pastel,\n channelCtx,\n );\n },\n\n dtcg(options?: GlazeDtcgOptions): GlazeColorDtcgResult {\n const modes = resolveModes(options?.modes);\n const doc = buildDtcgMap(\n resolveOnce(),\n '',\n modes,\n options?.colorSpace ?? 'srgb',\n getEffectiveConfig().pastel,\n );\n const result: GlazeColorDtcgResult = { light: doc.light[primary] };\n if (doc.dark) result.dark = doc.dark[primary];\n if (doc.lightContrast) {\n result.lightContrast = doc.lightContrast[primary];\n }\n if (doc.darkContrast) result.darkContrast = doc.darkContrast[primary];\n return result;\n },\n\n dtcgResolver(\n options: GlazeColorDtcgResolverOptions,\n ): GlazeDtcgResolverDocument {\n const doc = buildDtcgMap(\n resolveOnce(),\n '',\n resolveModes(options?.modes),\n options?.colorSpace ?? 'srgb',\n getEffectiveConfig().pastel,\n );\n const name = options.name;\n const result: GlazeDtcgResult = {\n light: { [name]: doc.light[primary] },\n };\n if (doc.dark) result.dark = { [name]: doc.dark[primary] };\n if (doc.lightContrast) {\n result.lightContrast = { [name]: doc.lightContrast[primary] };\n }\n if (doc.darkContrast) {\n result.darkContrast = { [name]: doc.darkContrast[primary] };\n }\n return buildDtcgResolver(result, options);\n },\n\n tailwind(options: GlazeColorTailwindOptions): string {\n const format = options.format ?? 'oklch';\n assertNativeFormat(format, 'tailwind');\n const renamed = new Map<string, ResolvedColor>([\n [options.name, resolveOnce().get(primary)!],\n ]);\n return buildTailwindMap(\n renamed,\n '',\n options.namespace ?? 'color-',\n resolveModes(options?.modes),\n format,\n options.darkSelector ?? '.dark',\n options.highContrastSelector ?? '.high-contrast',\n getEffectiveConfig().pastel,\n );\n },\n\n export(override?: GlazeConfigOverride): GlazeColorTokenExport {\n return buildExport(override);\n },\n };\n}\n\n/**\n * When a value/`from` color links to a base that was created via the\n * structured form (with explicit `hue`/`saturation`/`tone`), resolve\n * that base with `lightTone: false` for the linking math so the\n * contrast/tone anchor matches the input tone — not the\n * windowed output. The original base token's `.resolve()` is unaffected.\n */\nfunction toLinkingBase(\n base: GlazeColorToken | undefined,\n): GlazeColorToken | undefined {\n if (!base) return undefined;\n const exp = base.export();\n if (exp.form !== 'structured') return base;\n const linkingConfig: GlazeConfigOverride = {\n ...(exp.config ?? {}),\n lightTone: false,\n };\n return colorFromExport({ ...exp, config: linkingConfig });\n}\n\n/**\n * Resolve `base` (which may be a token reference or a raw color value)\n * into a `GlazeColorToken`. Raw values are auto-wrapped via\n * `createColorTokenFromValue` so they pick up the same auto-invert\n * defaults as an explicit wrap. Returns `undefined` when no base is provided.\n */\nfunction resolveBaseToken(\n base: GlazeColorToken | GlazeColorValue | undefined,\n): GlazeColorToken | undefined {\n if (base === undefined) return undefined;\n if (isGlazeColorToken(base)) return base;\n return createColorTokenFromValue(base, undefined, undefined);\n}\n\n/**\n * Discriminate a `GlazeColorToken` from a raw `GlazeColorValue`.\n */\nexport function isGlazeColorToken(\n candidate: GlazeColorToken | GlazeColorValue,\n): candidate is GlazeColorToken {\n return (\n typeof candidate === 'object' &&\n candidate !== null &&\n !Array.isArray(candidate) &&\n 'resolve' in candidate &&\n typeof (candidate as { resolve?: unknown }).resolve === 'function'\n );\n}\n\n// ============================================================================\n// Factory: structured input\n// ============================================================================\n\nexport function createColorToken(\n input: GlazeColorInput,\n configOverride?: GlazeConfigOverride,\n): GlazeColorToken {\n validateStructuredInput(input);\n\n const userName = input.name;\n if (userName !== undefined) validateStandaloneName(userName);\n const primary = userName ?? STANDALONE_VALUE;\n\n const baseToken = resolveBaseToken(input.base);\n const hasExternalBase = baseToken !== undefined;\n const needsSeedAnchor = !hasExternalBase && input.contrast !== undefined;\n\n const defs: ColorMap = {\n [primary]: {\n tone: input.tone,\n saturation: input.saturationFactor,\n mode: input.mode ?? 'auto',\n autoFlip: input.autoFlip,\n contrast: input.contrast,\n opacity: input.opacity,\n pastel: input.pastel,\n role: input.role,\n base: hasExternalBase\n ? STANDALONE_BASE\n : needsSeedAnchor\n ? STANDALONE_SEED\n : undefined,\n },\n };\n\n if (needsSeedAnchor) {\n const seedTone = pairNormal(input.tone);\n defs[STANDALONE_SEED] = {\n // The seed anchor must be a concrete tone; resolve 'max'/'min' to its\n // extreme so the static anchor is well-defined.\n tone: seedTone === 'max' ? 100 : seedTone === 'min' ? 0 : seedTone,\n saturation: 1,\n mode: 'static',\n };\n }\n\n const localOverride = configOverride;\n\n return createColorTokenFromDefs(\n input.hue,\n input.saturation,\n defs,\n primary,\n localOverride,\n baseToken,\n (exportArg) => ({\n kind: 'color',\n version: GLAZE_EXPORT_VERSION,\n form: 'structured',\n input: buildStructuredInputExport(input, exportArg),\n config: freezeConfigForExport(localOverride, exportArg),\n }),\n );\n}\n\n// ============================================================================\n// Factory: value-shorthand input\n// ============================================================================\n\nexport function createColorTokenFromValue(\n value: GlazeColorValue,\n options: GlazeColorOverrides | undefined,\n configOverride: GlazeConfigOverride | undefined,\n): GlazeColorToken {\n const main = extractOkhslFromValue(value);\n const rawBaseToken = resolveBaseToken(options?.base);\n // For linking math, structured bases are re-resolved at full range\n // (lightTone: false) so contrast/tone anchors use the\n // input tone, not the windowed output.\n const linkingBase = toLinkingBase(rawBaseToken);\n const { seedHue, seedSaturation, defs, primary } = buildStandaloneValueDefs(\n main,\n options,\n );\n\n const localOverride = sparseValueFormLocal(configOverride);\n\n return createColorTokenFromDefs(\n seedHue,\n seedSaturation,\n defs,\n primary,\n localOverride,\n linkingBase,\n (exportArg) => ({\n kind: 'color',\n version: GLAZE_EXPORT_VERSION,\n form: 'value',\n input: value,\n ...(options !== undefined\n ? { overrides: buildOverridesExport(options, exportArg) }\n : {}),\n config: freezeConfigForExport(localOverride, exportArg),\n }),\n );\n}\n\n// ============================================================================\n// Export / rehydrate\n// ============================================================================\n\n/**\n * Build a JSON-safe snapshot of `GlazeColorOverrides`. `base` is\n * recursively serialized when it was originally a token; raw values are\n * preserved as-is so `glaze.colorFrom(...)` round-trips them.\n */\nfunction buildOverridesExport(\n options: GlazeColorOverrides,\n exportArg?: GlazeConfigOverride,\n): GlazeColorOverridesExport {\n const out: GlazeColorOverridesExport = {};\n if (options.hue !== undefined) out.hue = options.hue;\n if (options.saturation !== undefined) out.saturation = options.saturation;\n if (options.tone !== undefined) out.tone = options.tone;\n if (options.saturationFactor !== undefined) {\n out.saturationFactor = options.saturationFactor;\n }\n if (options.mode !== undefined) out.mode = options.mode;\n if (options.autoFlip !== undefined) out.autoFlip = options.autoFlip;\n if (options.contrast !== undefined) out.contrast = options.contrast;\n if (options.opacity !== undefined) out.opacity = options.opacity;\n if (options.name !== undefined) out.name = options.name;\n if (options.pastel !== undefined) out.pastel = options.pastel;\n if (options.role !== undefined) out.role = options.role;\n if (options.base !== undefined) {\n out.base = isGlazeColorToken(options.base)\n ? options.base.export(exportArg)\n : options.base;\n }\n return out;\n}\n\nfunction buildStructuredInputExport(\n input: GlazeColorInput,\n exportArg?: GlazeConfigOverride,\n): GlazeColorInputExport {\n const out: GlazeColorInputExport = {\n hue: input.hue,\n saturation: input.saturation,\n tone: input.tone,\n };\n if (input.saturationFactor !== undefined) {\n out.saturationFactor = input.saturationFactor;\n }\n if (input.mode !== undefined) out.mode = input.mode;\n if (input.autoFlip !== undefined) out.autoFlip = input.autoFlip;\n if (input.opacity !== undefined) out.opacity = input.opacity;\n if (input.contrast !== undefined) out.contrast = input.contrast;\n if (input.name !== undefined) out.name = input.name;\n if (input.pastel !== undefined) out.pastel = input.pastel;\n if (input.role !== undefined) out.role = input.role;\n if (input.base !== undefined) {\n out.base = isGlazeColorToken(input.base)\n ? input.base.export(exportArg)\n : input.base;\n }\n return out;\n}\n\n/**\n * Discriminate a `GlazeColorTokenExport` from a raw `GlazeColorValue`.\n */\nfunction isExportedToken(\n candidate: GlazeColorTokenExport | GlazeColorValue,\n): candidate is GlazeColorTokenExport {\n return isColorTokenExport(candidate);\n}\n\nfunction rehydrateOverrides(\n data: GlazeColorOverridesExport,\n): GlazeColorOverrides {\n const out: GlazeColorOverrides = {};\n if (data.hue !== undefined) out.hue = data.hue;\n if (data.saturation !== undefined) out.saturation = data.saturation;\n if (data.tone !== undefined) out.tone = data.tone;\n if (data.saturationFactor !== undefined) {\n out.saturationFactor = data.saturationFactor;\n }\n if (data.mode !== undefined) out.mode = data.mode;\n if (data.autoFlip !== undefined) out.autoFlip = data.autoFlip;\n if (data.contrast !== undefined) out.contrast = data.contrast;\n if (data.opacity !== undefined) out.opacity = data.opacity;\n if (data.name !== undefined) out.name = data.name;\n if (data.pastel !== undefined) out.pastel = data.pastel;\n if (data.role !== undefined) out.role = data.role;\n if (data.base !== undefined) {\n out.base = isExportedToken(data.base)\n ? colorFromExport(data.base)\n : data.base;\n }\n return out;\n}\n\nfunction rehydrateStructuredInput(\n data: GlazeColorInputExport,\n): GlazeColorInput {\n const out: GlazeColorInput = {\n hue: data.hue,\n saturation: data.saturation,\n tone: data.tone,\n };\n if (data.saturationFactor !== undefined) {\n out.saturationFactor = data.saturationFactor;\n }\n if (data.mode !== undefined) out.mode = data.mode;\n if (data.autoFlip !== undefined) out.autoFlip = data.autoFlip;\n if (data.opacity !== undefined) out.opacity = data.opacity;\n if (data.contrast !== undefined) out.contrast = data.contrast;\n if (data.name !== undefined) out.name = data.name;\n if (data.pastel !== undefined) out.pastel = data.pastel;\n if (data.role !== undefined) out.role = data.role;\n if (data.base !== undefined) {\n out.base = isExportedToken(data.base)\n ? colorFromExport(data.base)\n : data.base;\n }\n return out;\n}\n\n/**\n * Rehydrate a token from its `.export()` snapshot. Recursively rebuilds\n * any base dependency. Inverse of `GlazeColorToken.export()`.\n *\n * The stored `config` field is the freeze from export time — passed as\n * the instance local override so the rehydrated token stays pinned\n * against later `glaze.configure()` calls.\n */\nexport function colorFromExport(data: GlazeColorTokenExport): GlazeColorToken {\n if (data === null || typeof data !== 'object') {\n throw new Error(\n `glaze.colorFrom: expected an object from token.export(), got ${data === null ? 'null' : typeof data}.`,\n );\n }\n assertExportKind(data, 'color', 'glaze.colorFrom');\n assertExportVersion(data, 'glaze.colorFrom');\n if (data.form !== 'value' && data.form !== 'structured') {\n throw new Error(\n `glaze.colorFrom: invalid \"form\" field — expected \"value\" or \"structured\" (got ${JSON.stringify((data as { form?: unknown }).form)}).`,\n );\n }\n if (data.input === undefined) {\n throw new Error(\n `glaze.colorFrom: missing \"input\" field — expected the original ${data.form === 'value' ? 'GlazeColorValue' : 'GlazeColorInput'}.`,\n );\n }\n\n if (data.form === 'value') {\n const value = data.input as GlazeColorValue;\n const overrides = data.overrides\n ? rehydrateOverrides(data.overrides)\n : undefined;\n return createColorTokenFromValue(value, overrides, data.config);\n }\n\n const input = rehydrateStructuredInput(data.input as GlazeColorInputExport);\n return createColorToken(input, data.config);\n}\n","/**\n * Theme factory.\n *\n * Wraps a hue/saturation seed, a mutable `ColorMap`, and an optional\n * per-theme `GlazeConfigOverride`. Exposes `tokens()` / `tasty()` /\n * `json()` / `css()` / `dtcg()` / `dtcgResolver()` / `tailwind()` / `resolve()` /\n * `export()` / `extend()`.\n *\n * The per-theme config override is **merged over the live global config at\n * resolve time** so the theme still reacts to later `configure()` calls\n * for fields it didn't override. The merged config is memoized by\n * `configVersion` to avoid rebuilding it on every export call.\n */\n\nimport type { ChannelCtx } from './channels';\nimport {\n freezeConfigForExport,\n getConfig,\n getConfigVersion,\n mergeConfig,\n} from './config';\nimport { assertAllPastel, assertNativeFormat } from './format-guard';\nimport {\n buildCssMap,\n buildDtcgMap,\n buildDtcgResolver,\n buildFlatTokenMap,\n buildJsonMap,\n buildTailwindMap,\n buildTokenMap,\n resolveModes,\n} from './formatters';\nimport { resolveAllColors } from './resolver';\nimport { GLAZE_EXPORT_VERSION } from './serialize';\nimport type {\n ColorDef,\n ColorMap,\n GlazeConfigOverride,\n GlazeConfigResolved,\n GlazeCssOptions,\n GlazeCssResult,\n GlazeDtcgOptions,\n GlazeDtcgResolverDocument,\n GlazeDtcgResolverOptions,\n GlazeDtcgResult,\n GlazeExtendOptions,\n GlazeJsonOptions,\n GlazeTailwindOptions,\n GlazeTheme,\n GlazeThemeExport,\n GlazeTokenOptions,\n ResolvedColor,\n} from './types';\n\nexport function createTheme(\n hue: number,\n saturation: number,\n initialColors?: ColorMap,\n configOverride?: GlazeConfigOverride,\n): GlazeTheme {\n let colorDefs: ColorMap = initialColors ? { ...initialColors } : {};\n\n let cache: {\n map: Map<string, ResolvedColor> | null;\n version: number;\n effectiveConfig: GlazeConfigResolved;\n } | null = null;\n\n function getEffectiveConfig(): GlazeConfigResolved {\n const version = getConfigVersion();\n if (cache && cache.version === version) return cache.effectiveConfig;\n const effectiveConfig = mergeConfig(getConfig(), configOverride);\n cache = { map: null, version, effectiveConfig };\n return effectiveConfig;\n }\n\n function resolveCached(): Map<string, ResolvedColor> {\n const version = getConfigVersion();\n if (cache && cache.version === version && cache.map) return cache.map;\n const effectiveConfig = getEffectiveConfig();\n const map = resolveAllColors(hue, saturation, colorDefs, effectiveConfig);\n cache = { map, version, effectiveConfig };\n return map;\n }\n\n function invalidate(): void {\n cache = null;\n }\n\n function channelCtxFor(\n options:\n | {\n splitHue?: boolean;\n name?: string;\n format?: GlazeCssOptions['format'];\n modes?: GlazeJsonOptions['modes'];\n }\n | undefined,\n formatDefault: 'rgb' | 'oklch' | 'okhsl',\n prefix: string,\n ): ChannelCtx | undefined {\n const format = options?.format ?? formatDefault;\n if (!options?.splitHue || format !== 'oklch') return undefined;\n const resolved = resolveCached();\n const modes = resolveModes(options?.modes);\n assertAllPastel(resolved, modes);\n return {\n seedHue: hue,\n baseName: options.name ?? 'theme',\n prefix,\n defs: colorDefs,\n mode: 'theme',\n };\n }\n\n const theme: GlazeTheme = {\n get hue() {\n return hue;\n },\n get saturation() {\n return saturation;\n },\n getConfig(): GlazeConfigResolved {\n return getEffectiveConfig();\n },\n\n colors(defs: ColorMap): void {\n colorDefs = { ...colorDefs, ...defs };\n invalidate();\n },\n\n color(name: string, def?: ColorDef): ColorDef | undefined | void {\n if (def === undefined) {\n return colorDefs[name];\n }\n colorDefs[name] = def;\n invalidate();\n },\n\n remove(names: string | string[]): void {\n const list = Array.isArray(names) ? names : [names];\n for (const name of list) {\n delete colorDefs[name];\n }\n invalidate();\n },\n\n has(name: string): boolean {\n return name in colorDefs;\n },\n\n list(): string[] {\n return Object.keys(colorDefs);\n },\n\n reset(): void {\n colorDefs = {};\n invalidate();\n },\n\n export(override?: GlazeConfigOverride): GlazeThemeExport {\n return {\n kind: 'theme',\n version: GLAZE_EXPORT_VERSION,\n hue,\n saturation,\n colors: structuredClone(colorDefs),\n config: freezeConfigForExport(configOverride, override),\n };\n },\n\n extend(options: GlazeExtendOptions): GlazeTheme {\n const newHue = options.hue ?? hue;\n const newSat = options.saturation ?? saturation;\n\n const inheritedColors: ColorMap = {};\n for (const [name, def] of Object.entries(colorDefs)) {\n if (def.inherit !== false) {\n inheritedColors[name] = def;\n }\n }\n\n const mergedColors = options.colors\n ? { ...inheritedColors, ...options.colors }\n : { ...inheritedColors };\n\n // Child inherits the parent override then merges in the per-extend override.\n const mergedConfigOverride: GlazeConfigOverride | undefined =\n configOverride || options.config\n ? { ...(configOverride ?? {}), ...(options.config ?? {}) }\n : undefined;\n\n return createTheme(newHue, newSat, mergedColors, mergedConfigOverride);\n },\n\n resolve(): Map<string, ResolvedColor> {\n // Defensive shallow clone: the cache holds the canonical Map for\n // internal exporters; callers that mutate the returned Map must\n // not corrupt subsequent cached reads.\n return new Map(resolveCached());\n },\n\n tokens(options?: GlazeJsonOptions): Record<string, Record<string, string>> {\n const format = options?.format ?? 'oklch';\n assertNativeFormat(format, 'tokens');\n const modes = resolveModes(options?.modes);\n return buildFlatTokenMap(\n resolveCached(),\n '',\n modes,\n format,\n getEffectiveConfig().pastel,\n );\n },\n\n tasty(options?: GlazeTokenOptions): Record<string, Record<string, string>> {\n const cfg = getEffectiveConfig();\n const states = {\n dark: options?.states?.dark ?? cfg.states.dark,\n highContrast: options?.states?.highContrast ?? cfg.states.highContrast,\n };\n const modes = resolveModes(options?.modes);\n const format = options?.format ?? 'oklch';\n const channelCtx = channelCtxFor(options, 'oklch', '');\n return buildTokenMap(\n resolveCached(),\n '',\n states,\n modes,\n format,\n cfg.pastel,\n channelCtx,\n );\n },\n\n json(options?: GlazeJsonOptions): Record<string, Record<string, string>> {\n const format = options?.format ?? 'oklch';\n assertNativeFormat(format, 'json');\n const modes = resolveModes(options?.modes);\n return buildJsonMap(\n resolveCached(),\n modes,\n format,\n getEffectiveConfig().pastel,\n );\n },\n\n css(options?: GlazeCssOptions): GlazeCssResult {\n const format = options?.format ?? 'oklch';\n assertNativeFormat(format, 'css');\n const channelCtx = channelCtxFor(options, 'oklch', '');\n return buildCssMap(\n resolveCached(),\n '',\n options?.suffix ?? '-color',\n format,\n getEffectiveConfig().pastel,\n channelCtx,\n );\n },\n\n dtcg(options?: GlazeDtcgOptions): GlazeDtcgResult {\n const modes = resolveModes(options?.modes);\n return buildDtcgMap(\n resolveCached(),\n '',\n modes,\n options?.colorSpace ?? 'srgb',\n getEffectiveConfig().pastel,\n );\n },\n\n dtcgResolver(\n options?: GlazeDtcgResolverOptions,\n ): GlazeDtcgResolverDocument {\n const result = buildDtcgMap(\n resolveCached(),\n '',\n resolveModes(options?.modes),\n options?.colorSpace ?? 'srgb',\n getEffectiveConfig().pastel,\n );\n return buildDtcgResolver(result, options);\n },\n\n tailwind(options?: GlazeTailwindOptions): string {\n const format = options?.format ?? 'oklch';\n assertNativeFormat(format, 'tailwind');\n const modes = resolveModes(options?.modes);\n return buildTailwindMap(\n resolveCached(),\n '',\n options?.namespace ?? 'color-',\n modes,\n format,\n options?.darkSelector ?? '.dark',\n options?.highContrastSelector ?? '.high-contrast',\n getEffectiveConfig().pastel,\n );\n },\n } as GlazeTheme;\n\n return theme;\n}\n","/**\n * Palette factory.\n *\n * Composes multiple themes into a single token namespace with optional\n * theme-name prefixes and a \"primary theme\" that also surfaces an\n * unprefixed copy of its tokens. All seven export methods (`tokens` /\n * `tasty` / `json` / `css` / `dtcg` / `dtcgResolver` / `tailwind`) share a\n * `buildPaletteOutput` driver that handles validation, per-theme iteration,\n * prefix resolution, collision filtering, and primary duplication.\n *\n * Authoring round-trip: `palette.export()` / `createPaletteFromExport()`\n * (wired as `glaze.paletteFrom`).\n */\n\nimport type { ChannelCtx } from './channels';\nimport { getConfig } from './config';\nimport { assertAllPastel, assertNativeFormat } from './format-guard';\nimport {\n buildCssMap,\n buildDtcgMap,\n buildDtcgResolver,\n buildFlatTokenMap,\n buildJsonMap,\n buildTailwindLines,\n buildTokenMap,\n emitTailwindCss,\n resolveModes,\n} from './formatters';\nimport {\n assertExportKind,\n assertExportVersion,\n GLAZE_EXPORT_VERSION,\n} from './serialize';\nimport { createTheme } from './theme';\nimport type {\n ColorMap,\n GlazeCssOptions,\n GlazeCssResult,\n GlazeConfigOverride,\n GlazeDtcgOptions,\n GlazeDtcgResolverDocument,\n GlazeDtcgResolverOptions,\n GlazeDtcgResult,\n GlazeJsonOptions,\n GlazePalette,\n GlazePaletteExport,\n GlazePaletteExportOptions,\n GlazePaletteOptions,\n GlazeTailwindOptions,\n GlazeTheme,\n GlazeThemeExport,\n GlazeTokenOptions,\n ResolvedColor,\n} from './types';\nimport type { GlazeTailwindLines } from './formatters';\n\ntype PaletteInput = Record<string, GlazeTheme>;\n\nfunction resolvePrefix(\n options: { prefix?: boolean | Record<string, string> } | undefined,\n themeName: string,\n defaultPrefix = false,\n): string {\n const prefix = options?.prefix ?? defaultPrefix;\n if (prefix === true) {\n return `${themeName}-`;\n }\n if (typeof prefix === 'object' && prefix !== null) {\n return prefix[themeName] ?? `${themeName}-`;\n }\n return '';\n}\n\nfunction validatePrimaryTheme(\n primary: string | undefined,\n themes: PaletteInput,\n): void {\n if (primary !== undefined && !(primary in themes)) {\n const available = Object.keys(themes).join(', ');\n throw new Error(\n `glaze: primary theme \"${primary}\" not found in palette. Available: ${available}.`,\n );\n }\n}\n\n/**\n * Resolve the effective primary for an export call.\n * `false` disables, a string overrides, `undefined` inherits from palette.\n */\nfunction resolveEffectivePrimary(\n exportPrimary: string | false | undefined,\n palettePrimary: string | undefined,\n): string | undefined {\n if (exportPrimary === false) return undefined;\n return exportPrimary ?? palettePrimary;\n}\n\n/**\n * Filter a resolved color map, skipping keys already in `seen`.\n * Warns on collision and keeps the first-written value (first-write-wins).\n * Returns a new map containing only non-colliding entries.\n */\nfunction filterCollisions(\n resolved: Map<string, ResolvedColor>,\n prefix: string,\n seen: Map<string, string>,\n themeName: string,\n isPrimary?: boolean,\n): Map<string, ResolvedColor> {\n const filtered = new Map<string, ResolvedColor>();\n const label = isPrimary ? `${themeName} (primary)` : themeName;\n\n for (const [name, color] of resolved) {\n const key = `${prefix}${name}`;\n if (seen.has(key)) {\n console.warn(\n `glaze: token \"${key}\" from theme \"${label}\" collides with theme \"${seen.get(key)}\" — skipping.`,\n );\n continue;\n }\n seen.set(key, label);\n filtered.set(name, color);\n }\n return filtered;\n}\n\nfunction colorMapFromTheme(theme: GlazeTheme): ColorMap {\n const defs: ColorMap = {};\n for (const name of theme.list()) {\n const def = theme.color(name);\n if (def !== undefined) defs[name] = def;\n }\n return defs;\n}\n\nfunction channelCtxForTheme(\n theme: GlazeTheme,\n themeName: string,\n passPrefix: string,\n themedPrefix: string,\n splitHue: boolean | undefined,\n format: string,\n modes: ReturnType<typeof resolveModes>,\n filtered: Map<string, ResolvedColor>,\n): ChannelCtx | undefined {\n if (!splitHue || format !== 'oklch') return undefined;\n assertAllPastel(filtered, modes);\n return {\n seedHue: theme.hue,\n baseName: themeName,\n // Hue var names always follow the themed prefix so the primary's\n // unprefixed alias references `--{themeName}-*-hue` rather than colliding\n // with other themes' base vars.\n prefix: themedPrefix,\n defs: colorMapFromTheme(theme),\n mode: 'theme',\n // Emit declarations only in the pass whose color-prop prefix matches the\n // themed prefix (the prefixed pass, or the single pass when prefix:false).\n emitDeclarations: passPrefix === themedPrefix,\n };\n}\n\n/**\n * Shared per-theme driver for `tokens` / `tasty` / `css`. `json` skips\n * this because it doesn't do collision filtering or primary duplication.\n */\nfunction buildPaletteOutput<T, R>(\n themes: PaletteInput,\n paletteOptions: GlazePaletteOptions | undefined,\n options:\n | {\n prefix?: boolean | Record<string, string>;\n primary?: string | false;\n }\n | undefined,\n buildOne: (\n resolved: Map<string, ResolvedColor>,\n prefix: string,\n pastel: boolean,\n themeName: string,\n theme: GlazeTheme,\n ) => T,\n merge: (acc: R, part: T) => void,\n empty: () => R,\n): R {\n const effectivePrimary = resolveEffectivePrimary(\n options?.primary,\n paletteOptions?.primary,\n );\n if (options?.primary !== undefined) {\n validatePrimaryTheme(effectivePrimary, themes);\n }\n\n const acc = empty();\n const seen = new Map<string, string>();\n\n for (const [themeName, theme] of Object.entries(themes)) {\n const resolved = theme.resolve();\n const pastel = theme.getConfig().pastel;\n const prefix = resolvePrefix(options, themeName, true);\n const filtered = filterCollisions(resolved, prefix, seen, themeName);\n merge(acc, buildOne(filtered, prefix, pastel, themeName, theme));\n\n if (themeName === effectivePrimary) {\n const primaryFiltered = filterCollisions(\n resolved,\n '',\n seen,\n themeName,\n true,\n );\n merge(acc, buildOne(primaryFiltered, '', pastel, themeName, theme));\n }\n }\n\n return acc;\n}\n\n/** Rebuild a theme from a `theme.export()` snapshot. */\nexport function createThemeFromExport(\n data: GlazeThemeExport,\n factory = 'glaze.themeFrom',\n): GlazeTheme {\n if (data === null || typeof data !== 'object') {\n throw new Error(\n `${factory}: expected an object from theme.export(), got ${data === null ? 'null' : typeof data}.`,\n );\n }\n assertExportKind(data, 'theme', factory);\n assertExportVersion(data, factory);\n if (typeof data.hue !== 'number' || typeof data.saturation !== 'number') {\n throw new Error(\n `${factory}: expected numeric \"hue\" and \"saturation\" fields.`,\n );\n }\n return createTheme(data.hue, data.saturation, data.colors, data.config);\n}\n\n/**\n * Rebuild a palette from a `palette.export()` snapshot.\n */\nexport function createPaletteFromExport(\n data: GlazePaletteExport,\n): GlazePalette {\n if (data === null || typeof data !== 'object') {\n throw new Error(\n `glaze.paletteFrom: expected an object from palette.export(), got ${data === null ? 'null' : typeof data}.`,\n );\n }\n assertExportKind(data, 'palette', 'glaze.paletteFrom');\n assertExportVersion(data, 'glaze.paletteFrom');\n if (data.themes === null || typeof data.themes !== 'object') {\n throw new Error(\n `glaze.paletteFrom: expected a \"themes\" object map of theme exports.`,\n );\n }\n\n const rebuilt: PaletteInput = {};\n for (const [name, themeExport] of Object.entries(data.themes)) {\n rebuilt[name] = createThemeFromExport(\n themeExport,\n `glaze.paletteFrom (theme \"${name}\")`,\n );\n }\n\n return createPalette(rebuilt, {\n primary: data.primary,\n });\n}\n\nexport function createPalette(\n themes: PaletteInput,\n paletteOptions?: GlazePaletteOptions,\n): GlazePalette {\n validatePrimaryTheme(paletteOptions?.primary, themes);\n\n const buildDtcgResult = (\n options?: GlazeDtcgOptions & GlazePaletteExportOptions,\n ): GlazeDtcgResult => {\n const modes = resolveModes(options?.modes);\n const colorSpace = options?.colorSpace ?? 'srgb';\n return buildPaletteOutput<GlazeDtcgResult, GlazeDtcgResult>(\n themes,\n paletteOptions,\n options,\n (filtered, prefix, pastel, _themeName, _theme) =>\n buildDtcgMap(filtered, prefix, modes, colorSpace, pastel),\n (acc, part) => {\n Object.assign(acc.light, part.light);\n if (part.dark) {\n acc.dark = Object.assign(acc.dark ?? {}, part.dark);\n }\n if (part.lightContrast) {\n acc.lightContrast = Object.assign(\n acc.lightContrast ?? {},\n part.lightContrast,\n );\n }\n if (part.darkContrast) {\n acc.darkContrast = Object.assign(\n acc.darkContrast ?? {},\n part.darkContrast,\n );\n }\n },\n () => ({ light: {} }),\n );\n };\n\n return {\n list(): string[] {\n return Object.keys(themes);\n },\n\n get primary(): string | undefined {\n return paletteOptions?.primary;\n },\n\n theme(name: string): GlazeTheme | undefined {\n return themes[name];\n },\n\n themes(): Record<string, GlazeTheme> {\n return { ...themes };\n },\n\n export(override?: GlazeConfigOverride): GlazePaletteExport {\n const themesExport: Record<string, GlazeThemeExport> = {};\n for (const [name, theme] of Object.entries(themes)) {\n themesExport[name] = theme.export(override);\n }\n const out: GlazePaletteExport = {\n kind: 'palette',\n version: GLAZE_EXPORT_VERSION,\n themes: themesExport,\n };\n if (paletteOptions?.primary !== undefined) {\n out.primary = paletteOptions.primary;\n }\n return out;\n },\n\n tokens(\n options?: GlazeJsonOptions & GlazePaletteExportOptions,\n ): Record<string, Record<string, string>> {\n const format = options?.format ?? 'oklch';\n assertNativeFormat(format, 'tokens');\n const modes = resolveModes(options?.modes);\n return buildPaletteOutput<\n Record<string, Record<string, string>>,\n Record<string, Record<string, string>>\n >(\n themes,\n paletteOptions,\n options,\n (filtered, prefix, pastel) =>\n buildFlatTokenMap(filtered, prefix, modes, format, pastel),\n (acc, part) => {\n for (const variant of Object.keys(part)) {\n if (!acc[variant]) {\n acc[variant] = {};\n }\n Object.assign(acc[variant], part[variant]);\n }\n },\n () => ({}),\n );\n },\n\n tasty(\n options?: GlazeTokenOptions & GlazePaletteExportOptions,\n ): Record<string, Record<string, string>> {\n const cfg = getConfig();\n const states = {\n dark: options?.states?.dark ?? cfg.states.dark,\n highContrast: options?.states?.highContrast ?? cfg.states.highContrast,\n };\n const modes = resolveModes(options?.modes);\n const format = options?.format ?? 'oklch';\n return buildPaletteOutput<\n Record<string, Record<string, string>>,\n Record<string, Record<string, string>>\n >(\n themes,\n paletteOptions,\n options,\n (filtered, prefix, pastel, themeName, theme) => {\n const themedPrefix = resolvePrefix(options, themeName, true);\n const channelCtx = channelCtxForTheme(\n theme,\n themeName,\n prefix,\n themedPrefix,\n options?.splitHue,\n format,\n modes,\n filtered,\n );\n return buildTokenMap(\n filtered,\n prefix,\n states,\n modes,\n format,\n pastel,\n channelCtx,\n );\n },\n (acc, part) => Object.assign(acc, part),\n () => ({}),\n );\n },\n\n json(\n options?: GlazeJsonOptions & {\n prefix?: boolean | Record<string, string>;\n },\n ): Record<string, Record<string, Record<string, string>>> {\n const format = options?.format ?? 'oklch';\n assertNativeFormat(format, 'json');\n const modes = resolveModes(options?.modes);\n const result: Record<string, Record<string, Record<string, string>>> = {};\n\n for (const [themeName, theme] of Object.entries(themes)) {\n const resolved = theme.resolve();\n result[themeName] = buildJsonMap(\n resolved,\n modes,\n format,\n theme.getConfig().pastel,\n );\n }\n\n return result;\n },\n\n css(options?: GlazeCssOptions & GlazePaletteExportOptions): GlazeCssResult {\n const suffix = options?.suffix ?? '-color';\n const format = options?.format ?? 'oklch';\n assertNativeFormat(format, 'css');\n const modes = resolveModes();\n\n const lines = buildPaletteOutput<\n GlazeCssResult,\n Record<keyof GlazeCssResult, string[]>\n >(\n themes,\n paletteOptions,\n options,\n (filtered, prefix, pastel, themeName, theme) => {\n const themedPrefix = resolvePrefix(options, themeName, true);\n const channelCtx = channelCtxForTheme(\n theme,\n themeName,\n prefix,\n themedPrefix,\n options?.splitHue,\n format,\n modes,\n filtered,\n );\n return buildCssMap(\n filtered,\n prefix,\n suffix,\n format,\n pastel,\n channelCtx,\n );\n },\n (acc, part) => {\n for (const key of [\n 'light',\n 'dark',\n 'lightContrast',\n 'darkContrast',\n ] as const) {\n if (part[key]) {\n acc[key].push(part[key]);\n }\n }\n },\n () => ({\n light: [],\n dark: [],\n lightContrast: [],\n darkContrast: [],\n }),\n );\n\n return {\n light: lines.light.join('\\n'),\n dark: lines.dark.join('\\n'),\n lightContrast: lines.lightContrast.join('\\n'),\n darkContrast: lines.darkContrast.join('\\n'),\n };\n },\n\n dtcg(\n options?: GlazeDtcgOptions & GlazePaletteExportOptions,\n ): GlazeDtcgResult {\n return buildDtcgResult(options);\n },\n\n dtcgResolver(\n options?: GlazeDtcgResolverOptions & GlazePaletteExportOptions,\n ): GlazeDtcgResolverDocument {\n return buildDtcgResolver(buildDtcgResult(options), options);\n },\n\n tailwind(\n options?: GlazeTailwindOptions & GlazePaletteExportOptions,\n ): string {\n const modes = resolveModes(options?.modes);\n const cssPrefix = options?.namespace ?? 'color-';\n const format = options?.format ?? 'oklch';\n assertNativeFormat(format, 'tailwind');\n const darkSelector = options?.darkSelector ?? '.dark';\n const highContrastSelector =\n options?.highContrastSelector ?? '.high-contrast';\n\n const lines = buildPaletteOutput<GlazeTailwindLines, GlazeTailwindLines>(\n themes,\n paletteOptions,\n options,\n (filtered, prefix, pastel, _themeName, _theme) =>\n buildTailwindLines(filtered, prefix, cssPrefix, format, pastel),\n (acc, part) => {\n for (const variant of [\n 'light',\n 'dark',\n 'lightContrast',\n 'darkContrast',\n ] as const) {\n acc[variant].push(...part[variant]);\n }\n },\n () => ({\n light: [],\n dark: [],\n lightContrast: [],\n darkContrast: [],\n }),\n );\n\n return emitTailwindCss(lines, modes, darkSelector, highContrastSelector);\n },\n };\n}\n","/**\n * Glaze — OKHST color theme generator.\n *\n * Public API entry. Wires `glaze()` and its attached static methods to\n * the focused modules in this folder:\n * - `theme.ts` — single-theme factory\n * - `palette.ts` — multi-theme composition\n * - `color-token.ts` — standalone single-color tokens (`glaze.color`)\n * - `shadow.ts` — standalone shadow factory (`glaze.shadow`)\n * - `formatters.ts` — variant → string (`glaze.format`)\n * - `config.ts` — global config singleton\n * - `serialize.ts` — authoring export type guards / version checks\n */\n\nimport { parseHex, srgbToOkhsl } from './okhsl-color-math';\nimport {\n configure as configureImpl,\n getConfig,\n resetConfig as resetConfigImpl,\n snapshotConfig,\n} from './config';\nimport {\n colorFromExport,\n createColorToken,\n createColorTokenFromValue,\n extractOkhslFromValue,\n} from './color-token';\nimport { formatVariant } from './formatters';\nimport { computeShadow, resolveShadowTuning } from './shadow';\nimport { okhslToOkhst } from './okhst';\nimport {\n createPalette,\n createPaletteFromExport,\n createThemeFromExport,\n} from './palette';\nimport {\n isColorTokenExport,\n isPaletteExport,\n isThemeExport,\n} from './serialize';\nimport { createTheme } from './theme';\nimport type {\n GlazeColorFormat,\n GlazeColorInput,\n GlazeColorToken,\n GlazeColorTokenExport,\n GlazeColorValue,\n GlazeConfig,\n GlazeConfigOverride,\n GlazeConfigResolved,\n GlazeFromInput,\n GlazePalette,\n GlazePaletteExport,\n GlazePaletteOptions,\n GlazeShadowInput,\n GlazeTheme,\n GlazeThemeExport,\n ResolvedColorVariant,\n} from './types';\n\ntype PaletteInput = Record<string, GlazeTheme>;\n\n/**\n * Create a single-hue glaze theme.\n *\n * An optional `config` override can be supplied to customize the resolve\n * behavior for this theme (tone windows, etc.). The\n * override is **merged over the live global config at resolve time** —\n * the theme still reacts to later `configure()` calls for fields it\n * didn't override.\n *\n * @example\n * ```ts\n * const primary = glaze(280, 80);\n * // or shorthand:\n * const primary = glaze({ hue: 280, saturation: 80 });\n * // with config override:\n * const raw = glaze(280, 80, { lightTone: false });\n * ```\n */\nexport function glaze(\n hueOrOptions: number | { hue: number; saturation: number },\n saturation?: number,\n config?: GlazeConfigOverride,\n): GlazeTheme {\n if (typeof hueOrOptions === 'number') {\n return createTheme(hueOrOptions, saturation ?? 100, undefined, config);\n }\n return createTheme(\n hueOrOptions.hue,\n hueOrOptions.saturation,\n undefined,\n config,\n );\n}\n\n/** Configure global glaze settings. */\nglaze.configure = function configure(config: GlazeConfig): void {\n configureImpl(config);\n};\n\n/** Compose multiple themes into a palette. */\nglaze.palette = function palette(\n themes: PaletteInput,\n options?: GlazePaletteOptions,\n): GlazePalette {\n return createPalette(themes, options);\n};\n\n/**\n * Create a theme from a serialized `theme.export()` snapshot.\n * Prefer this over the legacy `glaze.from` alias.\n */\nglaze.themeFrom = function themeFrom(data: GlazeThemeExport): GlazeTheme {\n return createThemeFromExport(data);\n};\n\n/** Compat alias for `glaze.themeFrom`. */\nglaze.from = glaze.themeFrom;\n\n/**\n * Create a standalone single-color token.\n *\n * **arg1 — the color** (four accepted shapes, discriminated by structure):\n *\n * | Shape | Example | Notes |\n * |---|---|---|\n * | Bare string | `'#26fcb2'`, `'rgb(38 252 178)'` | Hex or CSS color function (incl. `okhst()`) |\n * | Value object | `{ h: 152, s: 0.95, l: 0.74 }` | OKHSL, OKHST (`{h,s,t}`), `{r,g,b}`, `{l,c,h}` |\n * | `{ from, ...overrides }` | `{ from: '#fff', base: bg, contrast: 'AA' }` | Value + color overrides |\n * | Structured | `{ hue: 152, saturation: 95, tone: 74 }` | Full theme-style token |\n *\n * **arg2 — config override** (optional, all shapes):\n * Overrides the resolve-relevant global config fields for this token.\n * Fields that are omitted fall through to the live global config at\n * resolve time. Pass `false` for a tone window to disable clamping\n * entirely. `pastel` is instance-only (not set via `configure()`).\n *\n * ```ts\n * // Bare string — no overrides\n * glaze.color('#26fcb2')\n *\n * // From form — value + color overrides\n * glaze.color({ from: '#fff', base: bg, contrast: 'AA' })\n *\n * // Structured form — full theme-style token\n * glaze.color({ hue: 152, saturation: 95, tone: 74 })\n *\n * // Config override on any form\n * glaze.color('#26fcb2', { darkTone: false, autoFlip: false })\n * glaze.color({ from: '#fff', base: bg })\n * ```\n *\n * Defaults: every form defaults to `mode: 'auto'`. Value-shorthand forms\n * (bare strings and value objects) preserve light tone exactly\n * (`lightTone: false` locally). Structured form falls through to the live\n * global tone windows for omitted fields.\n *\n * Relative `tone: '+N'` and `contrast` anchor to the literal seed by\n * default; when `base` is set they anchor to the base's resolved variant\n * per scheme. Relative `hue: '+N'` always anchors to the seed, not the base.\n */\nglaze.color = function color(\n input: GlazeFromInput | GlazeColorInput | GlazeColorValue,\n config?: GlazeConfigOverride,\n): GlazeColorToken {\n if (typeof input === 'string') {\n return createColorTokenFromValue(input, undefined, config);\n }\n\n // Object inputs — discriminate by key presence\n const obj = input as object;\n\n if ('from' in obj) {\n const { from, ...overrides } = input as GlazeFromInput;\n return createColorTokenFromValue(from, overrides, config);\n }\n\n if ('hue' in obj) {\n return createColorToken(input as GlazeColorInput, config);\n }\n\n // Value-object: { h, s, l }, { r, g, b }, or { l, c, h }\n return createColorTokenFromValue(input as GlazeColorValue, undefined, config);\n};\n\n/**\n * Compute a shadow color from a bg/fg pair and intensity.\n *\n * Both `bg` and `fg` accept any `GlazeColorValue` form: hex (`#rgb` /\n * `#rrggbb` / `#rrggbbaa`), `rgb()` / `hsl()` / `okhsl()` / `oklch()`\n * strings, or `{ r, g, b }` / `{ h, s, l }` / `{ l, c, h }` objects.\n */\nglaze.shadow = function shadow(input: GlazeShadowInput): ResolvedColorVariant {\n const bg = extractOkhslFromValue(input.bg as GlazeColorValue);\n const fg = input.fg\n ? extractOkhslFromValue(input.fg as GlazeColorValue)\n : undefined;\n const cfg = getConfig();\n const tuning = resolveShadowTuning(input.tuning, cfg.shadowTuning);\n const result = computeShadow(\n { ...bg, alpha: 1 },\n fg ? { ...fg, alpha: 1 } : undefined,\n input.intensity,\n tuning,\n );\n const { h, s, t } = okhslToOkhst({\n h: result.h,\n s: result.s,\n l: result.l,\n });\n return { h, s, t, alpha: result.alpha };\n};\n\n/** Format a resolved color variant as a CSS string. */\nglaze.format = function format(\n variant: ResolvedColorVariant,\n colorFormat?: GlazeColorFormat,\n pastel?: boolean,\n): string {\n return formatVariant(variant, colorFormat, pastel);\n};\n\n/**\n * Create a theme from a hex color string.\n * Extracts hue and saturation from the color.\n */\nglaze.fromHex = function fromHex(hex: string): GlazeTheme {\n const rgb = parseHex(hex);\n if (!rgb) {\n throw new Error(`glaze: invalid hex color \"${hex}\".`);\n }\n const [h, s] = srgbToOkhsl(rgb);\n return createTheme(h, s * 100);\n};\n\n/**\n * Create a theme from RGB values (0–255).\n * Extracts hue and saturation from the color.\n */\nglaze.fromRgb = function fromRgb(r: number, g: number, b: number): GlazeTheme {\n const [h, s] = srgbToOkhsl([r / 255, g / 255, b / 255]);\n return createTheme(h, s * 100);\n};\n\n/**\n * Rehydrate a `glaze.color()` token from a `.export()` snapshot.\n *\n * The snapshot is a plain JSON-safe object containing the original\n * input value, overrides (with any `base` token recursively serialized),\n * and the effective config freeze from export time. The reconstructed\n * token pins that freeze as its local override.\n *\n * @example\n * ```ts\n * const text = glaze.color({ from: '#1a1a1a', contrast: 'AA' });\n * const data = text.export(); // JSON-safe\n * localStorage.setItem('text', JSON.stringify(data));\n * // ...later...\n * const restored = glaze.colorFrom(JSON.parse(localStorage.getItem('text')!));\n * ```\n */\nglaze.colorFrom = function colorFrom(\n data: GlazeColorTokenExport,\n): GlazeColorToken {\n return colorFromExport(data);\n};\n\n/**\n * Rehydrate a palette from a `palette.export()` snapshot.\n */\nglaze.paletteFrom = function paletteFrom(\n data: GlazePaletteExport,\n): GlazePalette {\n return createPaletteFromExport(data);\n};\n\n/** Type guard for theme authoring snapshots. */\nglaze.isThemeExport = isThemeExport;\n\n/** Type guard for color-token authoring snapshots. */\nglaze.isColorTokenExport = isColorTokenExport;\n\n/** Type guard for palette authoring snapshots. */\nglaze.isPaletteExport = isPaletteExport;\n\n/** Get the current global configuration (for testing/debugging). */\nglaze.getConfig = function getConfig(): GlazeConfigResolved {\n return snapshotConfig();\n};\n\n/** Reset global configuration to defaults. */\nglaze.resetConfig = function resetConfig(): void {\n resetConfigImpl();\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","names":["fmt","configure","resetConfig"],"sources":["../src/okhsl-color-math.ts","../src/config.ts","../src/types.ts","../src/serialize.ts","../src/format-guard.ts","../src/hc-pair.ts","../src/okhst.ts","../src/contrast-solver.ts","../src/roles.ts","../src/shadow.ts","../src/validation.ts","../src/warnings.ts","../src/resolver.ts","../src/channels.ts","../src/formatters.ts","../src/color-token.ts","../src/theme.ts","../src/palette.ts","../src/glaze.ts"],"sourcesContent":["/**\n * OKHSL color math primitives for the glaze theme generator.\n *\n * Provides bidirectional OKHSL ↔ sRGB conversion, luminance computation\n * for both contrast metrics (WCAG 2 relative luminance and APCA screen\n * luminance `Ys`), and multi-format output (okhsl, rgb, hsl, oklch).\n */\n\ntype Vec3 = [number, number, number];\n\n// ============================================================================\n// Matrices (from texel-color / Björn Ottosson's reference)\n// ============================================================================\n\nconst OKLab_to_LMS_M: Vec3[] = [\n [1.0, 0.3963377773761749, 0.2158037573099136],\n [1.0, -0.1055613458156586, -0.0638541728258133],\n [1.0, -0.0894841775298119, -1.2914855480194092],\n];\n\nconst LMS_to_linear_sRGB_M: Vec3[] = [\n [4.076741636075959, -3.307711539258062, 0.2309699031821041],\n [-1.2684379732850313, 2.6097573492876878, -0.3413193760026569],\n [-0.004196076138675526, -0.703418617935936, 1.7076146940746113],\n];\n\nconst linear_sRGB_to_LMS_M: Vec3[] = [\n [0.4122214708, 0.5363325363, 0.0514459929],\n [0.2119034982, 0.6806995451, 0.1073969566],\n [0.0883024619, 0.2817188376, 0.6299787005],\n];\n\nconst LMS_to_OKLab_M: Vec3[] = [\n [0.2104542553, 0.793617785, -0.0040720468],\n [1.9779984951, -2.428592205, 0.4505937099],\n [0.0259040371, 0.7827717662, -0.808675766],\n];\n\nconst OKLab_to_linear_sRGB_coefficients: [\n [[number, number], number[]],\n [[number, number], number[]],\n [[number, number], number[]],\n] = [\n [\n [-1.8817030993265873, -0.8093650129914302],\n [1.19086277, 1.76576728, 0.59662641, 0.75515197, 0.56771245],\n ],\n [\n [1.8144407988010998, -1.194452667805235],\n [0.73956515, -0.45954404, 0.08285427, 0.1254107, 0.14503204],\n ],\n [\n [0.13110757611180954, 1.813339709266608],\n [1.35733652, -0.00915799, -1.1513021, -0.50559606, 0.00692167],\n ],\n];\n\n// ============================================================================\n// Constants\n// ============================================================================\n\nconst TAU = 2 * Math.PI;\nconst K1 = 0.206;\nconst K2 = 0.03;\nconst K3 = (1.0 + K1) / (1.0 + K2);\nconst EPSILON = 1e-10;\n\n// ============================================================================\n// Helpers\n// ============================================================================\n\nconst constrainAngle = (angle: number): number => ((angle % 360) + 360) % 360;\n/**\n * OKHSL toe function: maps OKLab lightness L to perceptual lightness l.\n * Exported for the OKHST tone transfers in `okhst.ts`.\n */\nexport const toe = (x: number): number =>\n 0.5 *\n (K3 * x - K1 + Math.sqrt((K3 * x - K1) * (K3 * x - K1) + 4 * K2 * K3 * x));\n/** Inverse OKHSL toe: maps perceptual lightness l back to OKLab lightness L. */\nexport const toeInv = (x: number): number =>\n (x ** 2 + K1 * x) / (K3 * (x + K2));\nconst dot3 = (a: Vec3, b: Vec3): number =>\n a[0] * b[0] + a[1] * b[1] + a[2] * b[2];\nconst dotXY = (a: [number, number], b: [number, number]): number =>\n a[0] * b[0] + a[1] * b[1];\nconst transform = (input: Vec3, matrix: Vec3[]): Vec3 => [\n dot3(input, matrix[0]),\n dot3(input, matrix[1]),\n dot3(input, matrix[2]),\n];\nconst cubed3 = (lms: Vec3): Vec3 => [lms[0] ** 3, lms[1] ** 3, lms[2] ** 3];\nconst cbrt3 = (lms: Vec3): Vec3 => [\n Math.cbrt(lms[0]),\n Math.cbrt(lms[1]),\n Math.cbrt(lms[2]),\n];\nconst clampVal = (v: number, min: number, max: number): number =>\n Math.max(min, Math.min(max, v));\n\n// ============================================================================\n// Internal OKHSL pipeline\n// ============================================================================\n\nconst OKLabToLinearSRGB = (lab: Vec3): Vec3 => {\n const lms = transform(lab, OKLab_to_LMS_M);\n return transform(cubed3(lms), LMS_to_linear_sRGB_M);\n};\n\nconst computeMaxSaturationOKLC = (a: number, b: number): number => {\n const okCoeff = OKLab_to_linear_sRGB_coefficients;\n const lmsToRgb = LMS_to_linear_sRGB_M;\n const tmp2: [number, number] = [a, b];\n const tmp3: Vec3 = [0, a, b];\n\n let chnlCoeff: number[];\n let chnlLMS: Vec3;\n\n if (dotXY(okCoeff[0][0], tmp2) > 1) {\n chnlCoeff = okCoeff[0][1];\n chnlLMS = lmsToRgb[0];\n } else if (dotXY(okCoeff[1][0], tmp2) > 1) {\n chnlCoeff = okCoeff[1][1];\n chnlLMS = lmsToRgb[1];\n } else {\n chnlCoeff = okCoeff[2][1];\n chnlLMS = lmsToRgb[2];\n }\n\n const [k0, k1, k2, k3, k4] = chnlCoeff;\n const [wl, wm, ws] = chnlLMS;\n\n let sat = k0 + k1 * a + k2 * b + k3 * (a * a) + k4 * a * b;\n\n const dotYZ = (mat: Vec3, vec: Vec3): number =>\n mat[1] * vec[1] + mat[2] * vec[2];\n\n const kl = dotYZ(OKLab_to_LMS_M[0], tmp3);\n const km = dotYZ(OKLab_to_LMS_M[1], tmp3);\n const ks = dotYZ(OKLab_to_LMS_M[2], tmp3);\n\n const l_ = 1.0 + sat * kl;\n const m_ = 1.0 + sat * km;\n const s_ = 1.0 + sat * ks;\n\n const l = l_ ** 3;\n const m = m_ ** 3;\n const s = s_ ** 3;\n\n const lds = 3.0 * kl * l_ * l_;\n const mds = 3.0 * km * m_ * m_;\n const sds = 3.0 * ks * s_ * s_;\n\n const lds2 = 6.0 * kl * kl * l_;\n const mds2 = 6.0 * km * km * m_;\n const sds2 = 6.0 * ks * ks * s_;\n\n const f = wl * l + wm * m + ws * s;\n const f1 = wl * lds + wm * mds + ws * sds;\n const f2 = wl * lds2 + wm * mds2 + ws * sds2;\n\n sat = sat - (f * f1) / (f1 * f1 - 0.5 * f * f2);\n\n return sat;\n};\n\nconst findCuspOKLCH = (a: number, b: number): [number, number] => {\n const S_cusp = computeMaxSaturationOKLC(a, b);\n const lab: Vec3 = [1, S_cusp * a, S_cusp * b];\n const rgb_at_max = OKLabToLinearSRGB(lab);\n const L_cusp = Math.cbrt(\n 1 /\n Math.max(\n Math.max(rgb_at_max[0], rgb_at_max[1]),\n Math.max(rgb_at_max[2], 0.0),\n ),\n );\n return [L_cusp, L_cusp * S_cusp];\n};\n\nconst findGamutIntersectionOKLCH = (\n a: number,\n b: number,\n l1: number,\n c1: number,\n l0: number,\n cusp: [number, number],\n): number => {\n const lmsToRgb = LMS_to_linear_sRGB_M;\n const tmp3: Vec3 = [0, a, b];\n const floatMax = Number.MAX_VALUE;\n\n let t: number;\n\n const dotYZ = (mat: Vec3, vec: Vec3): number =>\n mat[1] * vec[1] + mat[2] * vec[2];\n const dotXYZ = (vec: Vec3, x: number, y: number, z: number): number =>\n vec[0] * x + vec[1] * y + vec[2] * z;\n\n if ((l1 - l0) * cusp[1] - (cusp[0] - l0) * c1 <= 0.0) {\n const denom = c1 * cusp[0] + cusp[1] * (l0 - l1);\n t = denom === 0 ? 0 : (cusp[1] * l0) / denom;\n } else {\n const denom = c1 * (cusp[0] - 1.0) + cusp[1] * (l0 - l1);\n t = denom === 0 ? 0 : (cusp[1] * (l0 - 1.0)) / denom;\n\n const dl = l1 - l0;\n const dc = c1;\n const kl = dotYZ(OKLab_to_LMS_M[0], tmp3);\n const km = dotYZ(OKLab_to_LMS_M[1], tmp3);\n const ks = dotYZ(OKLab_to_LMS_M[2], tmp3);\n\n const L = l0 * (1.0 - t) + t * l1;\n const C = t * c1;\n\n const l_ = L + C * kl;\n const m_ = L + C * km;\n const s_ = L + C * ks;\n\n const l = l_ ** 3;\n const m = m_ ** 3;\n const s = s_ ** 3;\n\n const ldt = 3 * (dl + dc * kl) * l_ * l_;\n const mdt = 3 * (dl + dc * km) * m_ * m_;\n const sdt = 3 * (dl + dc * ks) * s_ * s_;\n\n const ldt2 = 6 * (dl + dc * kl) ** 2 * l_;\n const mdt2 = 6 * (dl + dc * km) ** 2 * m_;\n const sdt2 = 6 * (dl + dc * ks) ** 2 * s_;\n\n const r_ = dotXYZ(lmsToRgb[0], l, m, s) - 1;\n const r1 = dotXYZ(lmsToRgb[0], ldt, mdt, sdt);\n const r2 = dotXYZ(lmsToRgb[0], ldt2, mdt2, sdt2);\n const ur = r1 / (r1 * r1 - 0.5 * r_ * r2);\n let tr = -r_ * ur;\n\n const g_ = dotXYZ(lmsToRgb[1], l, m, s) - 1;\n const g1 = dotXYZ(lmsToRgb[1], ldt, mdt, sdt);\n const g2 = dotXYZ(lmsToRgb[1], ldt2, mdt2, sdt2);\n const ug = g1 / (g1 * g1 - 0.5 * g_ * g2);\n let tg = -g_ * ug;\n\n const b_ = dotXYZ(lmsToRgb[2], l, m, s) - 1;\n const b1 = dotXYZ(lmsToRgb[2], ldt, mdt, sdt);\n const b2 = dotXYZ(lmsToRgb[2], ldt2, mdt2, sdt2);\n const ub = b1 / (b1 * b1 - 0.5 * b_ * b2);\n let tb = -b_ * ub;\n\n tr = ur >= 0.0 ? tr : floatMax;\n tg = ug >= 0.0 ? tg : floatMax;\n tb = ub >= 0.0 ? tb : floatMax;\n\n t += Math.min(tr, Math.min(tg, tb));\n }\n\n return t;\n};\n\nconst computeSt = (cusp: [number, number]): [number, number] => [\n cusp[1] / cusp[0],\n cusp[1] / (1 - cusp[0]),\n];\n\nconst computeStMid = (a: number, b: number): [number, number] => [\n 0.11516993 +\n 1.0 /\n (7.4477897 +\n 4.1590124 * b +\n a *\n (-2.19557347 +\n 1.75198401 * b +\n a *\n (-2.13704948 -\n 10.02301043 * b +\n a * (-4.24894561 + 5.38770819 * b + 4.69891013 * a)))),\n 0.11239642 +\n 1.0 /\n (1.6132032 -\n 0.68124379 * b +\n a *\n (0.40370612 +\n 0.90148123 * b +\n a *\n (-0.27087943 +\n 0.6122399 * b +\n a * (0.00299215 - 0.45399568 * b - 0.14661872 * a)))),\n];\n\nconst getCs = (\n L: number,\n a: number,\n b: number,\n cusp: [number, number],\n): [number, number, number] => {\n const cMax = findGamutIntersectionOKLCH(a, b, L, 1, L, cusp);\n const stMax = computeSt(cusp);\n const k = cMax / Math.min(L * stMax[0], (1 - L) * stMax[1]);\n const stMid = computeStMid(a, b);\n let ca = L * stMid[0];\n let cb = (1.0 - L) * stMid[1];\n const cMid =\n 0.9 * k * Math.sqrt(Math.sqrt(1.0 / (1.0 / ca ** 4 + 1.0 / cb ** 4)));\n ca = L * 0.4;\n cb = (1.0 - L) * 0.8;\n const c0 = Math.sqrt(1.0 / (1.0 / ca ** 2 + 1.0 / cb ** 2));\n return [c0, cMid, cMax];\n};\n\nconst CYAN_A = Math.cos((199.8 * Math.PI) / 180);\nconst CYAN_B = Math.sin((199.8 * Math.PI) / 180);\nconst BLUE_A = Math.cos((267.4 * Math.PI) / 180);\nconst BLUE_B = Math.sin((267.4 * Math.PI) / 180);\n\nlet cyanCusp: [number, number] | undefined;\nlet blueCusp: [number, number] | undefined;\n\n/**\n * Computes the maximum safe OKLCH chroma that fits inside the sRGB gamut\n * for all possible hues at a given OKLab lightness `L`.\n */\nexport function computeSafeChromaOKLCH(L: number): number {\n if (!cyanCusp) cyanCusp = findCuspOKLCH(CYAN_A, CYAN_B);\n if (!blueCusp) blueCusp = findCuspOKLCH(BLUE_A, BLUE_B);\n\n const c1 = findGamutIntersectionOKLCH(CYAN_A, CYAN_B, L, 1, L, cyanCusp);\n const c2 = findGamutIntersectionOKLCH(BLUE_A, BLUE_B, L, 1, L, blueCusp);\n return Math.min(c1, c2);\n}\n\n// ============================================================================\n// Public API\n// ============================================================================\n\n/** Per-hue cusp-lightness cache. The cusp is mode-independent, so keying on\n * a rounded hue is safe and keeps the cache small. */\nconst cuspLightnessCache = new Map<number, number>();\n\n/**\n * OKHSL lightness of the gamut cusp for a hue — the lightness where the\n * realizable chroma peaks. Reuses the same `find_cusp` OKHSL already runs for\n * its `s` normalization (no new color math); the OKLab cusp lightness is run\n * through the OKHSL `toe` and clamped to `[0.001, 0.999]` so divisions that\n * key off it stay safe. Cached per (rounded) hue.\n *\n * @param h Hue, 0–360.\n */\nexport function cuspLightness(h: number): number {\n const key = Math.round(constrainAngle(h) * 100) / 100;\n const cached = cuspLightnessCache.get(key);\n if (cached !== undefined) return cached;\n\n const hNorm = key / 360.0;\n const cusp = findCuspOKLCH(Math.cos(TAU * hNorm), Math.sin(TAU * hNorm));\n const lc = clampVal(toe(cusp[0]), 0.001, 0.999);\n cuspLightnessCache.set(key, lc);\n return lc;\n}\n\n/**\n * Convert OKHSL (h: 0–360, s: 0–1, l: 0–1) to OKLab [L, a, b].\n */\nexport function okhslToOklab(\n h: number,\n s: number,\n l: number,\n pastel = false,\n): [number, number, number] {\n const L = toeInv(l);\n let a = 0;\n let b = 0;\n\n const hNorm = constrainAngle(h) / 360.0;\n\n if (L !== 0.0 && L !== 1.0 && s !== 0) {\n const a_ = Math.cos(TAU * hNorm);\n const b_ = Math.sin(TAU * hNorm);\n\n if (pastel) {\n const c = s * computeSafeChromaOKLCH(L);\n a = c * a_;\n b = c * b_;\n } else {\n const cusp = findCuspOKLCH(a_, b_);\n const Cs = getCs(L, a_, b_, cusp);\n const [c0, cMid, cMax] = Cs;\n\n const mid = 0.8;\n const midInv = 1.25;\n let t: number, k0: number, k1: number, k2: number;\n\n if (s < mid) {\n t = midInv * s;\n k0 = 0.0;\n k1 = mid * c0;\n k2 = 1.0 - k1 / cMid;\n } else {\n t = 5 * (s - 0.8);\n k0 = cMid;\n k1 = (0.2 * cMid ** 2 * 1.25 ** 2) / c0;\n k2 = 1.0 - k1 / (cMax - cMid);\n }\n\n const c = k0 + (t * k1) / (1.0 - k2 * t);\n a = c * a_;\n b = c * b_;\n }\n }\n\n return [L, a, b];\n}\n\n/**\n * Convert OKHSL (h: 0–360, s: 0–1, l: 0–1) to linear sRGB.\n * Channels may exceed [0, 1] near gamut boundaries — caller must clamp if needed.\n */\nexport function okhslToLinearSrgb(\n h: number,\n s: number,\n l: number,\n pastel = false,\n): [number, number, number] {\n return OKLabToLinearSRGB(okhslToOklab(h, s, l, pastel));\n}\n\n/**\n * Compute relative luminance Y from linear sRGB channels.\n * Per WCAG 2: Y = 0.2126·R + 0.7152·G + 0.0722·B\n */\nexport function relativeLuminanceFromLinearRgb(\n rgb: [number, number, number],\n): number {\n return 0.2126 * rgb[0] + 0.7152 * rgb[1] + 0.0722 * rgb[2];\n}\n\n/**\n * WCAG 2 contrast ratio from two luminance values.\n */\nexport function contrastRatioFromLuminance(yA: number, yB: number): number {\n const lighter = Math.max(yA, yB);\n const darker = Math.min(yA, yB);\n return (lighter + 0.05) / (darker + 0.05);\n}\n\nexport const sRGBLinearToGamma = (val: number): number => {\n const sign = val < 0 ? -1 : 1;\n const abs = Math.abs(val);\n return abs > 0.0031308\n ? sign * (1.055 * Math.pow(abs, 1 / 2.4) - 0.055)\n : 12.92 * val;\n};\n\nexport const sRGBGammaToLinear = (val: number): number => {\n const sign = val < 0 ? -1 : 1;\n const abs = Math.abs(val);\n return abs <= 0.04045\n ? val / 12.92\n : sign * Math.pow((abs + 0.055) / 1.055, 2.4);\n};\n\n/**\n * Convert OKHSL to gamma-encoded sRGB (clamped to 0–1).\n */\nexport function okhslToSrgb(\n h: number,\n s: number,\n l: number,\n pastel = false,\n): [number, number, number] {\n const lin = okhslToLinearSrgb(h, s, l, pastel);\n return [\n Math.max(0, Math.min(1, sRGBLinearToGamma(lin[0]))),\n Math.max(0, Math.min(1, sRGBLinearToGamma(lin[1]))),\n Math.max(0, Math.min(1, sRGBLinearToGamma(lin[2]))),\n ];\n}\n\n/**\n * Compute WCAG 2 relative luminance from linear sRGB, matching the browser\n * rendering pipeline: gamma-encode, clamp to sRGB gamut [0,1], then linearize.\n * This avoids over/under-estimating luminance for out-of-gamut OKHSL colors.\n */\nexport function gamutClampedLuminance(\n linearRgb: [number, number, number],\n): number {\n const r = sRGBGammaToLinear(\n Math.max(0, Math.min(1, sRGBLinearToGamma(linearRgb[0]))),\n );\n const g = sRGBGammaToLinear(\n Math.max(0, Math.min(1, sRGBLinearToGamma(linearRgb[1]))),\n );\n const b = sRGBGammaToLinear(\n Math.max(0, Math.min(1, sRGBLinearToGamma(linearRgb[2]))),\n );\n return 0.2126 * r + 0.7152 * g + 0.0722 * b;\n}\n\n/**\n * Compute APCA screen luminance (`Ys`) from linear sRGB.\n *\n * APCA does not use the WCAG piecewise sRGB EOTF; it defines its own\n * luminance as `0.2126·R^2.4 + 0.7152·G^2.4 + 0.0722·B^2.4` over the\n * gamma-encoded (display) channels with a simple 2.4 exponent. The APCA\n * soft-clamp threshold in `apcaContrast` is calibrated against this basis,\n * so the solver must feed it `Ys`, not WCAG relative luminance. Channels\n * are gamut-clamped to [0, 1] first, matching `gamutClampedLuminance`.\n */\nexport function apcaLuminanceFromLinearRgb(\n linearRgb: [number, number, number],\n): number {\n const r = Math.max(0, Math.min(1, sRGBLinearToGamma(linearRgb[0])));\n const g = Math.max(0, Math.min(1, sRGBLinearToGamma(linearRgb[1])));\n const b = Math.max(0, Math.min(1, sRGBLinearToGamma(linearRgb[2])));\n return (\n 0.2126 * Math.pow(r, 2.4) +\n 0.7152 * Math.pow(g, 2.4) +\n 0.0722 * Math.pow(b, 2.4)\n );\n}\n\n// ============================================================================\n// Reverse pipeline: sRGB → OKHSL\n// ============================================================================\n\nconst linearSrgbToOklab = (rgb: Vec3): Vec3 => {\n const lms = transform(rgb, linear_sRGB_to_LMS_M);\n const lms_ = cbrt3(lms);\n return transform(lms_, LMS_to_OKLab_M);\n};\n\n/**\n * Convert OKLab to OKHSL.\n * Input: [L, a, b] where L: 0–1, a/b: roughly -0.5 to 0.5.\n * Returns [h, s, l] where h: 0–360, s: 0–1, l: 0–1.\n */\nexport const oklabToOkhsl = (lab: Vec3, pastel = false): Vec3 => {\n const L = lab[0];\n const a = lab[1];\n const b = lab[2];\n\n const C = Math.sqrt(a * a + b * b);\n\n if (C < EPSILON) {\n return [0, 0, toe(L)];\n }\n\n // Lightness-extreme achromatic guard.\n //\n // At L → 1 (white) and L → 0 (black) the in-gamut chroma collapses to\n // a single point: cMax, cMid, c0 all approach zero. Pure white is the\n // most visible failure case — `linearSrgbToOklab([1, 1, 1])` leaves\n // tiny floating-point residue in the a / b channels (`a ≈ 8e-11`,\n // `b ≈ 3.7e-8` → `C ≈ 3.7e-8`) that's well above `EPSILON` (`1e-10`),\n // so the chroma early-return above doesn't catch it. The chromatic\n // path then runs, the gamut at L ≈ 1 has nowhere to put any chroma,\n // and the saturation formula in `getCs` divides through ~zero values,\n // producing nonsense h/s for what is physically an achromatic color\n // (`#FFFFFF` → `okhsl(89.88 55.83% 100%)` instead of\n // `okhsl(0 0% 100%)`).\n //\n // The threshold (`1e-6`) is much wider than `EPSILON` because the fp\n // wobble in L for pure white lands at `1 - 6.5e-9` — `EPSILON = 1e-10`\n // misses it. `1e-6` is still well below any human-perceivable\n // difference in lightness (JNDs in OKHSL L are several orders of\n // magnitude larger), so we don't falsely flatten any in-gamut color.\n //\n // Treat both extremes as achromatic. The lightness window itself is\n // preserved through `toe(L)`.\n const L_EXTREME_EPSILON = 1e-6;\n if (L >= 1 - L_EXTREME_EPSILON || L <= L_EXTREME_EPSILON) {\n return [0, 0, toe(L)];\n }\n\n const a_ = a / C;\n const b_ = b / C;\n\n let h = Math.atan2(b, a) * (180 / Math.PI);\n h = constrainAngle(h);\n\n let s: number;\n\n if (pastel) {\n s = C / computeSafeChromaOKLCH(L);\n } else {\n const cusp = findCuspOKLCH(a_, b_);\n const Cs = getCs(L, a_, b_, cusp);\n const [c0, cMid, cMax] = Cs;\n\n const mid = 0.8;\n const midInv = 1.25;\n\n if (C < cMid) {\n const k1 = mid * c0;\n const k2 = 1.0 - k1 / cMid;\n const t = C / (k1 + C * k2);\n s = t / midInv;\n } else {\n const k0 = cMid;\n const k1 = (0.2 * cMid ** 2 * 1.25 ** 2) / c0;\n const k2 = 1.0 - k1 / (cMax - cMid);\n const cDiff = C - k0;\n const t = cDiff / (k1 + cDiff * k2);\n s = mid + t / 5;\n }\n }\n\n const l = toe(L);\n\n return [h, clampVal(s, 0, 1), clampVal(l, 0, 1)];\n};\n\n/**\n * Convert gamma-encoded sRGB (0–1 per channel) to OKHSL.\n * Returns [h, s, l] where h: 0–360, s: 0–1, l: 0–1.\n */\nexport function srgbToOkhsl(\n rgb: [number, number, number],\n pastel = false,\n): [number, number, number] {\n const linear: Vec3 = [\n sRGBGammaToLinear(rgb[0]),\n sRGBGammaToLinear(rgb[1]),\n sRGBGammaToLinear(rgb[2]),\n ];\n const oklab = linearSrgbToOklab(linear);\n return oklabToOkhsl(oklab, pastel) as [number, number, number];\n}\n\n/**\n * Convert CSS HSL (sRGB-based) to gamma-encoded sRGB [r, g, b] in 0–1 range.\n * h: 0–360, s: 0–1, l: 0–1.\n *\n * Note: CSS HSL is not the same as OKHSL — it's HSL in the sRGB color space.\n * Use this when parsing `hsl(...)` strings before passing to `srgbToOkhsl`.\n */\nexport function hslToSrgb(\n h: number,\n s: number,\n l: number,\n): [number, number, number] {\n const hh = (((h % 360) + 360) % 360) / 360;\n const ss = clampVal(s, 0, 1);\n const ll = clampVal(l, 0, 1);\n\n if (ss === 0) {\n return [ll, ll, ll];\n }\n\n const q = ll < 0.5 ? ll * (1 + ss) : ll + ss - ll * ss;\n const p = 2 * ll - q;\n\n const hueToChannel = (t: number): number => {\n let tt = t;\n if (tt < 0) tt += 1;\n if (tt > 1) tt -= 1;\n if (tt < 1 / 6) return p + (q - p) * 6 * tt;\n if (tt < 1 / 2) return q;\n if (tt < 2 / 3) return p + (q - p) * (2 / 3 - tt) * 6;\n return p;\n };\n\n return [hueToChannel(hh + 1 / 3), hueToChannel(hh), hueToChannel(hh - 1 / 3)];\n}\n\n/**\n * Parse a hex color string (#rgb or #rrggbb) to sRGB [r, g, b] in 0–1 range.\n * Returns null if the string is not a valid hex color.\n *\n * For 8-digit hex (`#rrggbbaa`) and 4-digit hex (`#rgba`) with alpha,\n * use {@link parseHexAlpha}.\n */\nexport function parseHex(hex: string): [number, number, number] | null {\n const result = parseHexAlpha(hex);\n if (!result || result.alpha !== undefined) return null;\n return result.rgb;\n}\n\n/**\n * Parse a hex color string (#rgb, #rrggbb, #rgba, or #rrggbbaa) to\n * sRGB [r, g, b] in 0–1 range plus an optional alpha (0–1).\n * Returns null if the string is not a valid hex color.\n */\nexport function parseHexAlpha(\n hex: string,\n): { rgb: [number, number, number]; alpha?: number } | null {\n const h = hex.startsWith('#') ? hex.slice(1) : hex;\n\n if (h.length === 3) {\n const r = parseInt(h[0] + h[0], 16);\n const g = parseInt(h[1] + h[1], 16);\n const b = parseInt(h[2] + h[2], 16);\n if (isNaN(r) || isNaN(g) || isNaN(b)) return null;\n return { rgb: [r / 255, g / 255, b / 255] };\n }\n\n if (h.length === 4) {\n const r = parseInt(h[0] + h[0], 16);\n const g = parseInt(h[1] + h[1], 16);\n const b = parseInt(h[2] + h[2], 16);\n const a = parseInt(h[3] + h[3], 16);\n if (isNaN(r) || isNaN(g) || isNaN(b) || isNaN(a)) return null;\n return { rgb: [r / 255, g / 255, b / 255], alpha: a / 255 };\n }\n\n if (h.length === 6) {\n const r = parseInt(h.slice(0, 2), 16);\n const g = parseInt(h.slice(2, 4), 16);\n const b = parseInt(h.slice(4, 6), 16);\n if (isNaN(r) || isNaN(g) || isNaN(b)) return null;\n return { rgb: [r / 255, g / 255, b / 255] };\n }\n\n if (h.length === 8) {\n const r = parseInt(h.slice(0, 2), 16);\n const g = parseInt(h.slice(2, 4), 16);\n const b = parseInt(h.slice(4, 6), 16);\n const a = parseInt(h.slice(6, 8), 16);\n if (isNaN(r) || isNaN(g) || isNaN(b) || isNaN(a)) return null;\n return { rgb: [r / 255, g / 255, b / 255], alpha: a / 255 };\n }\n\n return null;\n}\n\n// ============================================================================\n// Format functions\n// ============================================================================\n\nfunction fmt(value: number, decimals: number): string {\n return parseFloat(value.toFixed(decimals)).toString();\n}\n\n/**\n * Format OKHSL values as a CSS `okhsl(H S% L%)` string.\n * h: 0–360, s: 0–100, l: 0–100 (percentage scale for s and l).\n */\nexport function formatOkhsl(\n h: number,\n s: number,\n l: number,\n pastel = false,\n): string {\n let outS = s;\n if (pastel) {\n // If it's a pastel color, we need to find the equivalent normal OKHSL `s`\n // so it renders identically in external parsers that don't know about `pastel`.\n const oklab = okhslToOklab(h, s / 100, l / 100, true);\n const normalOkhsl = oklabToOkhsl(oklab, false);\n outS = normalOkhsl[1] * 100;\n }\n return `okhsl(${fmt(h, 2)} ${fmt(outS, 2)}% ${fmt(l, 2)}%)`;\n}\n\n/**\n * Format OKHST values as a CSS `okhst(H S% T%)` string.\n * h: 0–360, s: 0–100, t: 0–100 (percentage scale for s and t).\n *\n * Pastel recompute matches `formatOkhsl`: convert via OKLab so external\n * parsers that only understand non-pastel OKHST render identically.\n */\nexport function formatOkhst(\n h: number,\n s: number,\n t: number,\n pastel = false,\n): string {\n let outS = s;\n if (pastel) {\n const REF_EPS = 0.05;\n const den = Math.log(1 + REF_EPS) - Math.log(REF_EPS);\n const y = Math.exp((t / 100) * den + Math.log(REF_EPS)) - REF_EPS;\n const l = toe(Math.cbrt(Math.max(0, y)));\n const oklab = okhslToOklab(h, s / 100, l, true);\n const normalOkhsl = oklabToOkhsl(oklab, false);\n outS = normalOkhsl[1] * 100;\n }\n return `okhst(${fmt(h, 2)} ${fmt(outS, 2)}% ${fmt(t, 2)}%)`;\n}\n\n/**\n * Format OKHSL values as a CSS `rgb(R G B)` string.\n * Uses 2 decimal places to avoid 8-bit quantization contrast loss.\n * h: 0–360, s: 0–100, l: 0–100 (percentage scale for s and l).\n */\nexport function formatRgb(\n h: number,\n s: number,\n l: number,\n pastel = false,\n): string {\n const [r, g, b] = okhslToSrgb(h, s / 100, l / 100, pastel);\n return `rgb(${parseFloat((r * 255).toFixed(2))} ${parseFloat((g * 255).toFixed(2))} ${parseFloat((b * 255).toFixed(2))})`;\n}\n\n/**\n * Format OKHSL values as a CSS `hsl(H S% L%)` string.\n * h: 0–360, s: 0–100, l: 0–100 (percentage scale for s and l).\n */\nexport function formatHsl(\n h: number,\n s: number,\n l: number,\n pastel = false,\n): string {\n const [r, g, b] = okhslToSrgb(h, s / 100, l / 100, pastel);\n\n const max = Math.max(r, g, b);\n const min = Math.min(r, g, b);\n const delta = max - min;\n\n let hh = 0;\n let ss = 0;\n const ll = (max + min) / 2;\n\n if (delta > 0) {\n ss = ll > 0.5 ? delta / (2 - max - min) : delta / (max + min);\n\n if (max === r) {\n hh = ((g - b) / delta + (g < b ? 6 : 0)) * 60;\n } else if (max === g) {\n hh = ((b - r) / delta + 2) * 60;\n } else {\n hh = ((r - g) / delta + 4) * 60;\n }\n }\n\n return `hsl(${fmt(hh, 2)} ${fmt(ss * 100, 2)}% ${fmt(ll * 100, 2)}%)`;\n}\n\n/**\n * Format OKHSL values as a CSS `oklch(L C H)` string.\n * h: 0–360, s: 0–100, l: 0–100 (percentage scale for s and l).\n */\nexport function formatOklch(\n h: number,\n s: number,\n l: number,\n pastel = false,\n): string {\n const [L, C, hh] = okhslToOklch(h, s / 100, l / 100, pastel);\n return `oklch(${fmt(L, 4)} ${fmt(C, 4)} ${fmt(hh, 2)})`;\n}\n\n// ============================================================================\n// Structured (non-string) color accessors — used by the DTCG exporter.\n// ============================================================================\n\n/**\n * Convert gamma-encoded sRGB channels (0–1) to a 6-digit lowercase hex\n * string (`#rrggbb`). Channels are clamped to [0,1] and rounded to 8-bit.\n * Alpha is not encoded here — DTCG carries it as a separate `alpha` field.\n */\nexport function srgbToHex(rgb: [number, number, number]): `#${string}` {\n const toByte = (c: number): number =>\n Math.max(0, Math.min(255, Math.round(c * 255)));\n const r = toByte(rgb[0]);\n const g = toByte(rgb[1]);\n const b = toByte(rgb[2]);\n return `#${r.toString(16).padStart(2, '0')}${g.toString(16).padStart(2, '0')}${b.toString(16).padStart(2, '0')}`;\n}\n\n/**\n * Convert OKHSL (h: 0–360, s: 0–1, l: 0–1) to OKLCH components `[L, C, H]`.\n * L: 0–1, C: 0–~0.4 (chroma), H: 0–360 (hue). Shared by `formatOklch` and\n * the DTCG `oklch` colorSpace exporter so the two never drift apart.\n */\nexport function okhslToOklch(\n h: number,\n s: number,\n l: number,\n pastel = false,\n): [number, number, number] {\n const [L, a, b] = okhslToOklab(h, s, l, pastel);\n const C = Math.sqrt(a * a + b * b);\n const hh = constrainAngle(Math.atan2(b, a) * (180 / Math.PI));\n return [L, C, hh];\n}\n","/**\n * Glaze global configuration singleton.\n *\n * `configure()` mutates the singleton; every other module reads it via\n * `getConfig()` at call time so changes take effect for subsequent\n * resolves. Per-instance overrides (themes / color tokens) stay sparse —\n * omitted fields fall through to the live global at resolve time.\n * Authoring exports freeze the effective merge at export call time.\n *\n * `pastel` is instance-only (theme / token override or per-color def),\n * never set via `configure()`.\n */\n\nimport type {\n GlazeConfig,\n GlazeConfigOverride,\n GlazeConfigResolved,\n} from './types';\n\n/**\n * Build a fresh defaults object. Called from module init and from\n * `resetConfig()` so the two paths can't drift.\n *\n * `pastel: false` is a fixed instance default — not globally configurable.\n */\nexport function defaultConfig(): GlazeConfigResolved {\n return {\n lightTone: { lo: 10, hi: 100, eps: 0.05 },\n darkTone: { lo: 15, hi: 95, eps: 0.05 },\n darkDesaturation: 0.1,\n states: {\n dark: '@media(prefers-color-scheme: dark)',\n highContrast: '@media(prefers-contrast: more)',\n },\n modes: {\n dark: true,\n highContrast: false,\n },\n autoFlip: true,\n pastel: false,\n inferRole: true,\n };\n}\n\nlet globalConfig: GlazeConfigResolved = defaultConfig();\n\n/**\n * Monotonic counter incremented on every `configure()` / `resetConfig()`\n * call. Theme / palette caches read this to invalidate stale resolve\n * results when the config changes between exports.\n */\nlet configVersion = 0;\n\n/** Live reference to the current config. Mutated by `configure()` / `resetConfig()`. */\nexport function getConfig(): GlazeConfigResolved {\n return globalConfig;\n}\n\nexport function getConfigVersion(): number {\n return configVersion;\n}\n\n/**\n * Public-facing snapshot used by `glaze.getConfig()`. Returns a shallow\n * copy so callers can't mutate the live config.\n */\nexport function snapshotConfig(): GlazeConfigResolved {\n return { ...globalConfig };\n}\n\nexport function configure(config: GlazeConfig): void {\n configVersion++;\n globalConfig = {\n lightTone: config.lightTone ?? globalConfig.lightTone,\n darkTone: config.darkTone ?? globalConfig.darkTone,\n darkDesaturation: config.darkDesaturation ?? globalConfig.darkDesaturation,\n states: {\n dark: config.states?.dark ?? globalConfig.states.dark,\n highContrast:\n config.states?.highContrast ?? globalConfig.states.highContrast,\n },\n modes: {\n dark: config.modes?.dark ?? globalConfig.modes.dark,\n highContrast:\n config.modes?.highContrast ?? globalConfig.modes.highContrast,\n },\n shadowTuning: config.shadowTuning ?? globalConfig.shadowTuning,\n autoFlip: config.autoFlip ?? globalConfig.autoFlip,\n // Instance-only; never configurable globally.\n pastel: false,\n inferRole: config.inferRole ?? globalConfig.inferRole,\n };\n}\n\nexport function resetConfig(): void {\n configVersion++;\n globalConfig = defaultConfig();\n}\n\n/**\n * Merge a per-instance config override over a base resolved config.\n * Only fields present in `override` are replaced; others fall through\n * from `base`. `false` for tone windows passes through as-is\n * (treated as the full range by `activeWindow()` in okhst.ts).\n *\n * `pastel` is instance-only: `override.pastel ?? false`, never inherited\n * from the global base.\n */\nexport function mergeConfig(\n base: GlazeConfigResolved,\n override?: GlazeConfigOverride,\n): GlazeConfigResolved {\n if (!override) {\n return base.pastel === false ? base : { ...base, pastel: false };\n }\n return {\n lightTone:\n override.lightTone !== undefined ? override.lightTone : base.lightTone,\n darkTone:\n override.darkTone !== undefined ? override.darkTone : base.darkTone,\n darkDesaturation: override.darkDesaturation ?? base.darkDesaturation,\n states: base.states,\n modes: base.modes,\n shadowTuning: override.shadowTuning ?? base.shadowTuning,\n autoFlip: override.autoFlip ?? base.autoFlip,\n pastel: override.pastel ?? false,\n inferRole: override.inferRole ?? base.inferRole,\n };\n}\n\n/**\n * Freeze `getConfig() ∪ instanceLocal ∪ exportArg` as a plain, resolve-relevant\n * override for authoring export, so restored snapshots pin these fields. Later\n * wins; nested objects (`shadowTuning`) replace wholesale. The final\n * `structuredClone` detaches tone-window / shadow objects that `mergeConfig`\n * may still share with the live global config.\n */\nexport function freezeConfigForExport(\n instanceLocal?: GlazeConfigOverride,\n exportArg?: GlazeConfigOverride,\n): GlazeConfigOverride {\n const effective = mergeConfig(getConfig(), {\n ...instanceLocal,\n ...exportArg,\n });\n const out: GlazeConfigOverride = {\n lightTone: effective.lightTone,\n darkTone: effective.darkTone,\n darkDesaturation: effective.darkDesaturation,\n autoFlip: effective.autoFlip,\n pastel: effective.pastel,\n inferRole: effective.inferRole,\n };\n if (effective.shadowTuning !== undefined) {\n out.shadowTuning = effective.shadowTuning;\n }\n return structuredClone(out);\n}\n","/**\n * Glaze type definitions.\n */\n\nimport type { ApcaPreset, ContrastPreset } from './contrast-solver';\n\n// ============================================================================\n// Value types\n// ============================================================================\n\n/** A value or [normal, high-contrast] pair. */\nexport type HCPair<T> = T | [T, T];\n\n/** Bare WCAG contrast target: a ratio number or a named preset. */\nexport type MinContrast = number | ContrastPreset;\n\n/**\n * A contrast floor with a pluggable metric.\n *\n * - `number` / `ContrastPreset`: a WCAG ratio (bare form).\n * - `{ wcag }`: WCAG ratio or preset, optionally an HC pair.\n * - `{ apca }`: APCA Lc target (absolute value or preset), optionally an HC pair.\n *\n * The `[normal, highContrast]` pair may live at the outer level\n * (`[4.5, 7]`, `[{ wcag: 4.5 }, { wcag: 7 }]`) or inside the metric\n * (`{ wcag: [4.5, 7] }`, `{ apca: [45, 60] }`, `{ apca: ['content', 'body'] }`).\n */\nexport type ContrastSpec =\n | number\n | ContrastPreset\n | { wcag: HCPair<number | ContrastPreset> }\n | { apca: HCPair<number | ApcaPreset> };\n\n// ============================================================================\n// Color role\n// ============================================================================\n\n/**\n * The semantic role a color plays against its base, used to fix APCA contrast\n * polarity (which side is the foreground vs the background). WCAG is\n * symmetric, so role never changes WCAG results.\n */\nexport type Role = 'text' | 'surface' | 'border';\n\n/**\n * Any string accepted as a `role`. Canonical values plus aliases normalized by\n * `normalizeRole` (see `roles.ts`): `surface` (bg/background/fill/canvas/\n * paper/layer), `text` (fg/foreground/content/ink/label/stroke), `border`\n * (divider/outline/separator/hairline/rule).\n */\nexport type RoleInput =\n | Role\n | 'bg'\n | 'background'\n | 'fill'\n | 'canvas'\n | 'paper'\n | 'layer'\n | 'fg'\n | 'foreground'\n | 'content'\n | 'ink'\n | 'label'\n | 'stroke'\n | 'divider'\n | 'outline'\n | 'separator'\n | 'hairline'\n | 'rule';\n\nexport type AdaptationMode = 'auto' | 'fixed' | 'static';\n\n/** A signed relative offset string, e.g. '+20' or '-15.5'. */\nexport type RelativeValue = `+${number}` | `-${number}`;\n\n/**\n * Force a color to a tone extreme:\n * - `'max'`: the highest tone in the active scheme range/window.\n * - `'min'`: the lowest tone.\n *\n * Under `mode: 'auto'` the extreme inverts in the dark scheme (so `'max'`\n * tracks the inversion and becomes the darkest tone). No `base` required.\n */\nexport type ExtremeValue = 'max' | 'min';\n\n/**\n * A tone value as authored on a color.\n * - Number: absolute tone (0–100).\n * - `'+N'` / `'-N'`: relative to the base's tone (requires `base`).\n * - `'max'` / `'min'`: forced to the scheme's tone extreme (no base needed).\n */\nexport type ToneValue = number | RelativeValue | ExtremeValue;\n\n/** Color format for output. */\nexport type GlazeColorFormat = 'okhsl' | 'okhst' | 'rgb' | 'hsl' | 'oklch';\n\n/**\n * Controls which scheme variants are generated in the export.\n * Light is always included (it's the default).\n */\nexport interface GlazeOutputModes {\n /** Include dark scheme variants. Default: true. */\n dark?: boolean;\n /** Include high-contrast variants (both light-HC and dark-HC). Default: false. */\n highContrast?: boolean;\n}\n\n// ============================================================================\n// Color definitions\n// ============================================================================\n\n/** Hex color string for DX hints. Runtime validation in `parseHex()`. */\nexport type HexColor = `#${string}`;\n\n/** Direct OKHSL color input. */\nexport interface OkhslColor {\n h: number;\n s: number;\n l: number;\n}\n\n/**\n * Direct OKHST color input — OKHSL with the lightness axis replaced by the\n * contrast-uniform tone axis. `h`: 0–360, `s`: 0–1, `t`: 0–1 (tone).\n */\nexport interface OkhstColor {\n h: number;\n s: number;\n t: number;\n}\n\n/** sRGB components in 0–255 (value-shorthand object form). */\nexport interface RgbColor {\n r: number;\n g: number;\n b: number;\n}\n\n/** OKLCh components matching CSS `oklch(L C H)` (L/C: 0–1, H: degrees). */\nexport interface OklchColor {\n l: number;\n c: number;\n h: number;\n}\n\nexport interface RegularColorDef {\n /**\n * Tone value (0–100, contrast-uniform — see `docs/okhst.md`).\n * - Number: absolute tone.\n * - String ('+N' / '-N'): relative to base color's tone (requires `base`).\n * - `'max'` / `'min'`: force to the scheme's tone extreme (no base needed).\n */\n tone?: HCPair<ToneValue>;\n /** Saturation factor applied to the seed saturation (0–1, default: 1). */\n saturation?: number;\n /**\n * Hue override for this color.\n * - Number: absolute hue (0–360).\n * - String ('+N' / '-N'): relative to the theme seed hue.\n */\n hue?: number | RelativeValue;\n\n /** Name of another color in the same theme (dependent color). */\n base?: string;\n /**\n * Contrast floor against the base color. A bare number/preset is WCAG;\n * use `{ wcag }` / `{ apca }` to pick the metric. Accepts an HC pair.\n */\n contrast?: HCPair<ContrastSpec>;\n\n /** Adaptation mode. Default: 'auto'. */\n mode?: AdaptationMode;\n\n /**\n * Whether to flip out-of-bounds results to the opposite side instead of\n * clamping to the extreme. Affects both:\n * - relative `tone`: when `base ± delta` exceeds `[0, 100]`, mirror the\n * delta to the other side of the base. If the mirrored target is also\n * out of range, keep the original delta and clamp on the authored side.\n * - `contrast`: when the requested direction can't meet the floor, try the\n * opposite side (same as the global `autoFlip`).\n *\n * Defaults to the global `autoFlip` config (default `true`). Set `false`\n * to clamp instead.\n */\n autoFlip?: boolean;\n\n /**\n * Fixed opacity (0–1).\n * Output includes alpha in the CSS value.\n * Does not affect contrast resolution — a semi-transparent color\n * has no fixed perceived tone, so `contrast` and `opacity`\n * should not be combined (a console.warn is emitted).\n */\n opacity?: number;\n\n /**\n * Per-color override for the hue-independent \"safe\" chroma limit used in\n * OKHSL↔sRGB conversions (luminance, contrast solving, output formatting).\n * Falls through to the per-theme / per-token `pastel` override when omitted.\n * @see GlazeConfigOverride.pastel\n */\n pastel?: boolean;\n\n /**\n * Semantic role against `base`: how this color is used. Fixes APCA contrast\n * polarity (the argument order in `apcaContrast`). WCAG is symmetric so it\n * never affects WCAG results.\n *\n * Resolution: explicit `role` wins; else inferred from the color name when\n * `inferRole` is enabled (default); else the opposite of the base's role;\n * else defaults to `'text'` (foreground).\n */\n role?: RoleInput;\n\n /**\n * Whether this color is inherited by child themes created via `extend()`.\n * Default: true. Set to false to make this color local to the current theme.\n */\n inherit?: boolean;\n}\n\n/** Shadow tuning knobs. All values use the 0–1 scale (OKHSL). */\nexport interface ShadowTuning {\n /** Fraction of fg saturation kept in pigment (0-1). Default: 0.18. */\n saturationFactor?: number;\n /** Upper clamp on pigment saturation (0-1). Default: 0.25. */\n maxSaturation?: number;\n /** Multiplier for bg lightness → pigment lightness. Default: 0.25. */\n lightnessFactor?: number;\n /** [min, max] clamp for pigment lightness (0-1). Default: [0.05, 0.20]. */\n lightnessBounds?: [number, number];\n /**\n * Target minimum gap between pigment lightness and bg lightness (0-1).\n * Default: 0.05.\n */\n minGapTarget?: number;\n /** Max alpha (0-1). Reached at intensity=100 with max contrast. Default: 1.0. */\n alphaMax?: number;\n /**\n * Blend weight (0-1) pulling pigment hue toward bg hue.\n * 0 = pure fg hue, 1 = pure bg hue. Default: 0.2.\n */\n bgHueBlend?: number;\n}\n\nexport interface ShadowColorDef {\n type: 'shadow';\n /**\n * Background color name — the surface the shadow sits on.\n * Must reference a non-shadow color in the same theme.\n */\n bg: string;\n /**\n * Foreground color name for tinting and intensity modulation.\n * Must reference a non-shadow color in the same theme.\n * Omit for achromatic shadow at full user-specified intensity.\n */\n fg?: string;\n /**\n * Shadow intensity, 0-100.\n * Supports [normal, highContrast] pair.\n */\n intensity: HCPair<number>;\n /** Override default tuning. Merged field-by-field with global `shadowTuning`. */\n tuning?: ShadowTuning;\n\n /**\n * Per-color override for the hue-independent \"safe\" chroma limit used in\n * OKHSL↔sRGB conversions (luminance, contrast solving, output formatting).\n * Falls through to the per-theme / per-token `pastel` override when omitted.\n * @see GlazeConfigOverride.pastel\n */\n pastel?: boolean;\n\n /**\n * Whether this color is inherited by child themes created via `extend()`.\n * Default: true. Set to false to make this color local to the current theme.\n */\n inherit?: boolean;\n}\n\nexport interface MixColorDef {\n type: 'mix';\n /** Background/base color name — the \"from\" color. */\n base: string;\n /** Target color name — the \"to\" color to mix toward. */\n target: string;\n /**\n * Mix ratio 0–100 (0 = pure base, 100 = pure target).\n * In 'transparent' blend mode, this controls the opacity of the target.\n * Supports [normal, highContrast] pair.\n */\n value: HCPair<number>;\n /**\n * Blending mode. Default: 'opaque'.\n * - 'opaque': produces a solid color by interpolating base and target.\n * - 'transparent': produces the target color with alpha = value/100.\n */\n blend?: 'opaque' | 'transparent';\n /**\n * Interpolation color space for opaque blending. Default: 'okhsl'.\n * - 'okhsl': perceptually uniform, consistent with Glaze's internal model.\n * - 'srgb': linear sRGB interpolation, matches browser compositing.\n *\n * Ignored for 'transparent' blend (always composites in linear sRGB).\n */\n space?: 'okhsl' | 'srgb';\n /**\n * Minimum contrast between the base and the resulting color.\n * In 'opaque' mode, adjusts the mix ratio to meet contrast.\n * In 'transparent' mode, adjusts opacity to meet contrast against the composite.\n * A bare number/preset is WCAG; use `{ wcag }` / `{ apca }` to pick the\n * metric. Supports [normal, highContrast] pair.\n */\n contrast?: HCPair<ContrastSpec>;\n\n /**\n * Per-color override for the hue-independent \"safe\" chroma limit used in\n * OKHSL↔sRGB conversions (luminance, contrast solving, output formatting).\n * Falls through to the per-theme / per-token `pastel` override when omitted.\n * @see GlazeConfigOverride.pastel\n */\n pastel?: boolean;\n\n /**\n * Semantic role of the mixed result against `base`. Same semantics as\n * `RegularColorDef.role` (fixes APCA polarity). Resolution and defaults\n * are identical.\n */\n role?: RoleInput;\n\n /**\n * Whether this color is inherited by child themes created via `extend()`.\n * Default: true. Set to false to make this color local to the current theme.\n */\n inherit?: boolean;\n}\n\nexport type ColorDef = RegularColorDef | ShadowColorDef | MixColorDef;\n\nexport type ColorMap = Record<string, ColorDef>;\n\n// ============================================================================\n// Resolved internal types\n// ============================================================================\n\n/**\n * Resolved color for a single scheme variant.\n *\n * Stored in OKHST: `h` / `s` are OKHSL hue/saturation, `t` is the canonical\n * contrast-uniform tone (0–1, reference eps). Convert to OKHSL lightness via\n * `variantToOkhsl` at the rendering / luminance edges.\n */\nexport interface ResolvedColorVariant {\n /** OKHSL hue (0–360). */\n h: number;\n /** OKHSL saturation (0–1). */\n s: number;\n /** Canonical tone (0–1, reference eps). */\n t: number;\n /** Opacity (0–1). Default: 1. */\n alpha: number;\n /**\n * Effective `pastel` flag used while resolving this variant (author def or\n * config fallback). Carried on the variant so output formatting matches the\n * gamut mapping applied during resolution.\n */\n pastel?: boolean;\n}\n\n/** Fully resolved color across all scheme variants. */\nexport interface ResolvedColor {\n name: string;\n light: ResolvedColorVariant;\n dark: ResolvedColorVariant;\n lightContrast: ResolvedColorVariant;\n darkContrast: ResolvedColorVariant;\n /** Adaptation mode. Present only for regular colors, omitted for shadows. */\n mode?: AdaptationMode;\n}\n\n// ============================================================================\n// Configuration\n// ============================================================================\n\n/**\n * A scheme tone window.\n * - `[lo, hi]`: OKHSL-lightness endpoints (0–100) the authored tone is\n * remapped into, using the reference eps `0.05`. The common form.\n * - `{ lo, hi, eps }`: same, with an explicit render curvature `eps`\n * (advanced — most palettes never need this).\n * - `false`: disable clamping (full range `[0, 100]` at the reference eps).\n * This removes the *boundaries*, not the tone curve.\n */\nexport type ToneWindow =\n | false\n | [number, number]\n | { lo: number; hi: number; eps: number };\n\nexport interface GlazeConfig {\n /** Light scheme tone window — `[lo, hi]` (default `[10, 100]`), `{ lo, hi, eps }` for advanced eps tuning, or `false` to disable clamping. */\n lightTone?: ToneWindow;\n /** Dark scheme tone window — `[lo, hi]` (default `[15, 95]`), `{ lo, hi, eps }`, or `false` to disable clamping. */\n darkTone?: ToneWindow;\n /** Saturation reduction factor for dark scheme (0–1). Default: 0.1. */\n darkDesaturation?: number;\n /**\n * State alias names for Tasty token export. Default to media-query states\n * (`'@media(prefers-color-scheme: dark)'` / `'@media(prefers-contrast: more)'`)\n * so tokens react to the OS preference without registering custom states.\n */\n states?: {\n dark?: string;\n highContrast?: string;\n };\n /** Which scheme variants to include in exports. Default: both true. */\n modes?: GlazeOutputModes;\n /** Default tuning for all shadow colors. Per-color tuning merges field-by-field. */\n shadowTuning?: ShadowTuning;\n /**\n * Automatically flip tone direction when contrast can't be met.\n *\n * When enabled (default `true`), the solver searches the requested\n * tone direction first. If that direction can't reach the target,\n * it tries the opposite direction and uses it when it passes. If neither\n * side passes, the tone is pinned to the requested-direction\n * extreme and a warning is emitted.\n *\n * Set to `false` for strict \"no flip\" behavior. The opposite\n * direction is never considered: if the requested direction can't\n * meet the target, the tone is pinned to its extreme (never\n * falls back to the originally requested tone).\n */\n autoFlip?: boolean;\n /**\n * If true (default), infer a color's `role` from its name when no explicit\n * `role` is set. Set to `false` to opt out of name-based inference (the\n * base-opposite and default-foreground fallbacks still apply).\n * @default true\n */\n inferRole?: boolean;\n}\n\nexport interface GlazeConfigResolved {\n lightTone: ToneWindow;\n darkTone: ToneWindow;\n darkDesaturation: number;\n states: {\n dark: string;\n highContrast: string;\n };\n modes: Required<GlazeOutputModes>;\n shadowTuning?: ShadowTuning;\n autoFlip: boolean;\n /**\n * Instance-level pastel default (`def.pastel ?? config.pastel`).\n * Not set via `glaze.configure()` — only via per-theme / per-token\n * `GlazeConfigOverride` (default `false`).\n */\n pastel: boolean;\n inferRole: boolean;\n}\n\n/**\n * Per-instance config override for `glaze.color()` and `glaze()` themes.\n * Fields that are set take priority over the live global config. Fields\n * that are omitted fall through to the live global at resolve time\n * (`pastel` is instance-only and defaults to `false` when omitted).\n *\n * `false` for a tone window disables clamping (full range at reference eps).\n */\nexport interface GlazeConfigOverride {\n /** Light scheme tone window, or `false` to disable clamping. */\n lightTone?: ToneWindow;\n /** Dark scheme tone window, or `false` to disable clamping. */\n darkTone?: ToneWindow;\n /** Saturation reduction factor for dark scheme (0–1). */\n darkDesaturation?: number;\n /** Whether to auto-flip tone when contrast can't be met. */\n autoFlip?: boolean;\n /**\n * Instance-level pastel default for colors that omit per-color `pastel`.\n * Not available on `glaze.configure()` — set here or per-color.\n * @default false\n */\n pastel?: boolean;\n /**\n * If true, infer a color's `role` from its name when no explicit `role` is\n * set. Falls through to the live global at resolve time when omitted.\n */\n inferRole?: boolean;\n /**\n * Shadow tuning defaults. Only meaningful for themes; harmless on\n * standalone color tokens.\n */\n shadowTuning?: ShadowTuning;\n}\n\n// ============================================================================\n// Serialization\n// ============================================================================\n\n/**\n * Current authoring-export schema version. Bump when the export shape\n * changes in a non-compatible way. Written on every `.export()` snapshot.\n */\nexport const GLAZE_EXPORT_VERSION = 1 as const;\n\n/** Literal type of {@link GLAZE_EXPORT_VERSION}. */\nexport type GlazeExportVersion = typeof GLAZE_EXPORT_VERSION;\n\n/** Discriminator for authoring export snapshots. */\nexport type GlazeExportKind = 'theme' | 'color' | 'palette';\n\n/** Serialized theme configuration (no resolved values). */\nexport interface GlazeThemeExport {\n /** Snapshot kind. Always written by `theme.export()`; optional on legacy hand-written configs. */\n kind?: 'theme';\n /** Schema version. Always written by `theme.export()`; optional on legacy configs. */\n version?: number;\n hue: number;\n saturation: number;\n colors: ColorMap;\n /**\n * Effective config freeze from `.export()` —\n * `getConfig() ∪ instance local ∪ exportArg`. May be sparse on legacy\n * snapshots (omitted fields fall through to the live global at restore).\n */\n config?: GlazeConfigOverride;\n}\n\n// ============================================================================\n// Standalone shadow\n// ============================================================================\n\n/** Input for `glaze.shadow()` standalone factory. */\nexport interface GlazeShadowInput {\n /**\n * Background color — accepts any `GlazeColorValue` form: hex\n * (`#rgb` / `#rrggbb` / `#rrggbbaa`), `rgb()` / `hsl()` / `okhsl()`\n * / `oklch()` strings, or literal objects (`{ r, g, b }`, `{ h, s, l }`,\n * `{ l, c, h }`). Alpha components are dropped with a warning.\n */\n bg: GlazeColorValue;\n /**\n * Foreground color for tinting + intensity modulation. Accepts the\n * same forms as `bg`.\n */\n fg?: GlazeColorValue;\n /** Intensity 0-100. */\n intensity: number;\n tuning?: ShadowTuning;\n}\n\n// ============================================================================\n// Standalone color token\n// ============================================================================\n\n/** Input for the structured `glaze.color()` overload. */\nexport interface GlazeColorInput {\n hue: number;\n saturation: number;\n tone: HCPair<number | ExtremeValue>;\n saturationFactor?: number;\n mode?: AdaptationMode;\n /** Flip out-of-bounds results instead of clamping. Default: global `autoFlip`. */\n autoFlip?: boolean;\n /**\n * Fixed opacity (0–1). Output includes alpha in the CSS value.\n * Combining with `contrast` is not recommended (perceived tone\n * becomes unpredictable) — a `console.warn` is emitted in that case.\n */\n opacity?: number;\n /**\n * Optional dependency on another color. Same semantics as\n * `GlazeColorOverrides.base` — `contrast` and relative `tone`\n * anchor to the base per scheme.\n */\n base?: GlazeColorToken | GlazeColorValue;\n /**\n * Contrast floor against `base`. Requires `base` to be set. A bare\n * number/preset is WCAG; use `{ wcag }` / `{ apca }` to pick the metric.\n */\n contrast?: HCPair<ContrastSpec>;\n /**\n * Optional human-readable name for the token. Used in error and\n * warning messages (otherwise an internal name like `\"value\"` is\n * used). Does not affect output keys.\n */\n name?: string;\n\n /**\n * Per-color override for the hue-independent \"safe\" chroma limit used in\n * OKHSL↔sRGB conversions (luminance, contrast solving, output formatting).\n * Falls through to the per-theme / per-token `pastel` override when omitted.\n * @see GlazeConfigOverride.pastel\n */\n pastel?: boolean;\n\n /**\n * Semantic role against `base` / the literal seed: how this token is used.\n * Fixes APCA contrast polarity. Same resolution chain as\n * `RegularColorDef.role` (explicit → name inference → opposite of base →\n * `'text'`). For standalone tokens the name is internal, so set `role`\n * explicitly or rely on the base-opposite / foreground default.\n */\n role?: RoleInput;\n}\n\n/**\n * Any single-color input form accepted by the value-shorthand\n * overload of `glaze.color()`.\n *\n * Strings cover hex (`#rgb` / `#rrggbb` / `#rrggbbaa`, alpha dropped\n * with a warning) and the four CSS color functions Glaze itself emits:\n * `rgb()`, `hsl()`, `okhsl()`, `oklch()` (alpha components also dropped\n * with a warning).\n *\n * Literal object forms:\n * - `{ h, s, l }` — OKHSL (h: 0–360, s/l: 0–1). Passing 0–100 for `s`/`l`\n * throws with a hint to use the structured form.\n * - `{ h, s, t }` — OKHST (h: 0–360, s/t: 0–1). Tone in 0–1.\n * - `{ r, g, b }` — sRGB 0–255.\n * - `{ l, c, h }` — OKLCh (L/C: 0–1, H: degrees), same as `oklch()` strings.\n */\nexport type GlazeColorValue =\n | string\n | OkhslColor\n | OkhstColor\n | RgbColor\n | OklchColor;\n\n/** Color overrides for the `from` and value-shorthand inputs. */\nexport interface GlazeColorOverrides {\n /**\n * Override hue. Number is absolute (0–360); `'+N'`/`'-N'` is relative\n * to the extracted (or overridden) seed hue — same semantics as\n * `RegularColorDef.hue`.\n */\n hue?: number | RelativeValue;\n /** Override seed saturation (0–100). Default: extracted from value. */\n saturation?: number;\n /**\n * Override tone. Number is absolute (0–100, contrast-uniform); `'+N'`/`'-N'`\n * is relative to the literal seed (the value passed to `glaze.color()`);\n * `'max'` / `'min'` force to the scheme's tone extreme.\n * Supports HCPair for high-contrast.\n */\n tone?: HCPair<ToneValue>;\n /** Saturation multiplier on the seed (0–1). Default: 1. */\n saturationFactor?: number;\n /**\n * Adaptation mode. Defaults to `'auto'` for every input form, so\n * colors automatically adapt between light and dark like an ordinary\n * theme color. Value-shorthand inputs (strings and literal objects)\n * preserve light tone via a local `lightTone: false` default; other\n * omitted config fields fall through to the live global at resolve\n * time. Structured `{ hue, saturation, tone }` form also falls\n * through for both tone windows unless overridden.\n *\n * Pass `'fixed'` explicitly to opt back into the linear, non-\n * inverting mapping; pass `'static'` to pin the same tone\n * across every variant.\n */\n mode?: AdaptationMode;\n\n /**\n * Flip out-of-bounds results (relative `tone` overshoot / unmet\n * `contrast`) to the opposite side instead of clamping. Defaults to\n * the global `autoFlip`.\n */\n autoFlip?: boolean;\n\n /**\n * Contrast floor. By default solved against the literal seed\n * (the value itself); when `base` is set, solved against the base's\n * resolved variant per scheme. Same shape as `RegularColorDef.contrast`\n * (bare number/preset = WCAG; `{ wcag }` / `{ apca }` to pick the metric).\n */\n contrast?: HCPair<ContrastSpec>;\n\n /**\n * Optional dependency on another color. Accepts either a\n * `GlazeColorToken` (returned by another `glaze.color()`) or a raw\n * `GlazeColorValue` (hex / CSS strings / `{ r, g, b }` / `{ h, s, l }` / …),\n * which is automatically wrapped in `glaze.color(value)`.\n *\n * When set:\n * - `contrast` is solved against the base's resolved variant\n * per-scheme (light / dark / lightContrast / darkContrast).\n * - Relative `tone: '+N'` / `'-N'` is anchored to the base's\n * tone per-scheme (matches theme behavior for dependent colors).\n * - Relative `hue: '+N'` / `'-N'` still anchors to the seed (the\n * value passed to `glaze.color()`), not the base.\n * - When the base was created via the structured form (with explicit\n * `hue`/`saturation`/`tone`), it is resolved at full range\n * (`lightTone: false`) for the linking math — ensuring the\n * contrast/tone anchor matches the input tone, not the\n * windowed output. The base's own `.resolve()` output is unaffected.\n *\n * The base token's `.resolve()` is called lazily on first resolve and\n * its result is captured by reference; later mutations to the base's\n * defining call don't apply (matches existing token snapshot semantics).\n */\n base?: GlazeColorToken | GlazeColorValue;\n\n /**\n * Fixed opacity (0–1). Output includes alpha in the CSS value.\n * Combining with `contrast` is not recommended (perceived tone\n * becomes unpredictable) — a `console.warn` is emitted in that case.\n */\n opacity?: number;\n\n /**\n * Optional human-readable name for the token. Used in error and\n * warning messages (otherwise an internal name like `\"value\"` is\n * used). Does not affect output keys.\n */\n name?: string;\n\n /**\n * Per-color override for the hue-independent \"safe\" chroma limit used in\n * OKHSL↔sRGB conversions (luminance, contrast solving, output formatting).\n * Falls through to the per-theme / per-token `pastel` override when omitted.\n * @see GlazeConfigOverride.pastel\n */\n pastel?: boolean;\n\n /**\n * Semantic role against `base` / the literal seed: how this token is used.\n * Fixes APCA contrast polarity. Same resolution chain as\n * `RegularColorDef.role`.\n */\n role?: RoleInput;\n}\n\n/**\n * Object input for `glaze.color()` that carries a raw color value plus\n * optional color overrides in the same object.\n *\n * ```ts\n * glaze.color({ from: '#1a1a2e', base: bg, contrast: 'AA' })\n * glaze.color({ from: { r: 38, g: 252, b: 178 }, tone: '+10' })\n * ```\n */\nexport interface GlazeFromInput extends GlazeColorOverrides {\n /** The source color value. Accepts the same forms as a bare `GlazeColorValue`. */\n from: GlazeColorValue;\n}\n\n/** Options for `GlazeColorToken.css()`. */\nexport interface GlazeColorCssOptions {\n /**\n * Custom property base name (without leading `--`). Required.\n * Becomes the variable identifier in the output, e.g.\n * `name: 'brand'` → `--brand-color: …`.\n */\n name: string;\n /** Output color format. Default: 'oklch'. */\n format?: GlazeColorFormat;\n /**\n * Suffix appended to the name. Default: '-color' (matches\n * `theme.css` default).\n */\n suffix?: string;\n /**\n * Emit hue as a separate custom property, referenced via `var()`.\n * Requires `format: 'oklch'` and a pastel token. oklch + all-pastel only.\n */\n splitHue?: boolean;\n}\n\n/** Return type for `glaze.color()`. */\nexport interface GlazeColorToken {\n /** Resolve the color across all scheme variants. */\n resolve(): ResolvedColor;\n /** Export as a flat token map (no color name key). */\n token(options?: GlazeTokenOptions): Record<string, string>;\n /**\n * Export as a tasty style-to-state binding (no color name key).\n * Uses `#name` keys and state aliases (`''`, `'@media(prefers-color-scheme: dark)'`, etc.).\n * @see https://tasty.style/docs\n */\n tasty(options?: GlazeTokenOptions): Record<string, string>;\n /** Export as a flat JSON map (no color name key). */\n json(options?: GlazeJsonOptions): Record<string, string>;\n /** Export as CSS custom property declarations grouped by scheme variant. */\n css(options: GlazeColorCssOptions): GlazeCssResult;\n /**\n * Export as W3C DTCG color tokens (one per scheme variant, no color name\n * key). Each entry is a full `{ $type: 'color', $value }` token.\n * @see https://www.designtokens.org/\n */\n dtcg(options?: GlazeDtcgOptions): GlazeColorDtcgResult;\n /**\n * Export as a single W3C DTCG Resolver-Module document for this color,\n * keyed by `name` across all scheme variants. `name` is required.\n * @see https://www.designtokens.org/\n */\n dtcgResolver(\n options: GlazeColorDtcgResolverOptions,\n ): GlazeDtcgResolverDocument;\n /**\n * Export as a Tailwind CSS v4 `@theme` block (light baseline) plus dark /\n * high-contrast overrides. Returns a single ready-to-paste CSS string.\n * `name` is required (forms `--color-<name>`).\n * @see https://tailwindcss.com/docs/theme\n */\n tailwind(options: GlazeColorTailwindOptions): string;\n /**\n * Serialize the token as a JSON-safe object. Captures the original\n * input value, overrides, and config so it can be rehydrated via\n * `glaze.colorFrom(...)`. `base` is recursively serialized.\n * Optional `override` is merged over the instance local at export time.\n */\n export(override?: GlazeConfigOverride): GlazeColorTokenExport;\n}\n\n/**\n * JSON-safe serialization of a `glaze.color()` token. Pass to\n * `glaze.colorFrom(...)` to rehydrate.\n */\nexport interface GlazeColorTokenExport {\n /** Snapshot kind. Always written by `token.export()`; optional on legacy snapshots. */\n kind?: 'color';\n /** Schema version. Always written by `token.export()`; optional on legacy snapshots. */\n version?: number;\n /**\n * Discriminator for the source overload that created the token.\n * - `'value'`: created via `glaze.color(value)` or `glaze.color({ from, ...overrides })`.\n * - `'structured'`: created via `glaze.color({ hue, saturation, ... })`.\n */\n form: 'value' | 'structured';\n /** Original input. For `form: 'value'` this is the raw `GlazeColorValue`; for `form: 'structured'` this is the structured input. */\n input: GlazeColorValue | GlazeColorInputExport;\n /**\n * Overrides recorded at creation time. `base` is recursively\n * serialized. Only present for `form: 'value'`.\n */\n overrides?: GlazeColorOverridesExport;\n /**\n * Effective config freeze from `.export()` — `getConfig() ∪ local ∪\n * exportArg` at call time. Used by `glaze.colorFrom()` to pin\n * deterministic behavior across later `configure()` calls.\n */\n config?: GlazeConfigOverride;\n}\n\n/**\n * JSON-safe serialization of a `glaze.palette()` composition.\n * Pass to `glaze.paletteFrom(...)` to rehydrate.\n */\nexport interface GlazePaletteExport {\n /** Snapshot kind. Always written by `palette.export()`. */\n kind?: 'palette';\n /** Schema version. Always written by `palette.export()`. */\n version?: number;\n /** Per-theme authoring snapshots keyed by theme name. */\n themes: Record<string, GlazeThemeExport>;\n /** Primary theme name, if set on the palette. */\n primary?: string;\n}\n\n/**\n * Serializable shape of a structured `glaze.color({...})` input.\n * Differs from `GlazeColorInput` only in that `base` is replaced by an\n * `export` instead of a token reference.\n */\nexport interface GlazeColorInputExport {\n hue: number;\n saturation: number;\n tone: HCPair<number | ExtremeValue>;\n saturationFactor?: number;\n mode?: AdaptationMode;\n autoFlip?: boolean;\n opacity?: number;\n base?: GlazeColorTokenExport | GlazeColorValue;\n contrast?: HCPair<ContrastSpec>;\n name?: string;\n pastel?: boolean;\n role?: RoleInput;\n}\n\n/**\n * Serializable shape of `GlazeColorOverrides`. `base` is replaced by\n * its export (or left as a `GlazeColorValue` if it was originally a value).\n */\nexport interface GlazeColorOverridesExport {\n hue?: number | RelativeValue;\n saturation?: number;\n tone?: HCPair<ToneValue>;\n saturationFactor?: number;\n mode?: AdaptationMode;\n autoFlip?: boolean;\n contrast?: HCPair<ContrastSpec>;\n base?: GlazeColorTokenExport | GlazeColorValue;\n opacity?: number;\n name?: string;\n pastel?: boolean;\n role?: RoleInput;\n}\n\n// ============================================================================\n// Theme API\n// ============================================================================\n\nexport interface GlazeTheme {\n /** The hue seed (0–360). */\n readonly hue: number;\n /** The saturation seed (0–100). */\n readonly saturation: number;\n /** The effective config for this theme. */\n getConfig(): GlazeConfigResolved;\n\n /** Add/replace colors (additive merge with existing definitions). */\n colors(defs: ColorMap): void;\n\n /** Get a color definition by name. */\n color(name: string): ColorDef | undefined;\n /** Set a single color definition. */\n color(name: string, def: ColorDef): void;\n\n /** Remove one or more color definitions. */\n remove(names: string | string[]): void;\n\n /** Check if a color is defined. */\n has(name: string): boolean;\n\n /** List all defined color names. */\n list(): string[];\n\n /** Clear all color definitions. */\n reset(): void;\n\n /** Export the theme configuration as a JSON-safe object. */\n export(override?: GlazeConfigOverride): GlazeThemeExport;\n\n /** Create a child theme inheriting all color definitions. */\n extend(options: GlazeExtendOptions): GlazeTheme;\n\n /** Resolve all colors and return the result map. */\n resolve(): Map<string, ResolvedColor>;\n\n /**\n * Export as a flat token map grouped by scheme variant.\n *\n * ```ts\n * theme.tokens()\n * // → { light: { surface: 'okhsl(...)' }, dark: { surface: 'okhsl(...)' } }\n * ```\n */\n tokens(options?: GlazeJsonOptions): Record<string, Record<string, string>>;\n\n /**\n * Export as tasty style-to-state bindings.\n * Uses `#name` color token keys and state aliases (`''`, `'@media(prefers-color-scheme: dark)'`, etc.).\n * Spread into component styles or register as a recipe via `configure({ recipes })`.\n * @see https://tasty.style/docs\n */\n tasty(options?: GlazeTokenOptions): Record<string, Record<string, string>>;\n\n /** Export as plain JSON. */\n json(options?: GlazeJsonOptions): Record<string, Record<string, string>>;\n\n /** Export as CSS custom property declarations. */\n css(options?: GlazeCssOptions): GlazeCssResult;\n\n /**\n * Export as W3C Design Tokens Format Module (2025.10) documents, one per\n * scheme variant. Consumable by Figma, Tokens Studio, Style Dictionary,\n * Terrazzo, and any DTCG-compatible tool.\n * @see https://www.designtokens.org/\n */\n dtcg(options?: GlazeDtcgOptions): GlazeDtcgResult;\n\n /**\n * Export as a single W3C DTCG Resolver-Module document describing every\n * scheme variant as one `sets` entry plus a single `scheme` modifier with a\n * context per variant. Consumable by resolver tools such as Dispersa.\n * @see https://www.designtokens.org/\n */\n dtcgResolver(options?: GlazeDtcgResolverOptions): GlazeDtcgResolverDocument;\n\n /**\n * Export as a Tailwind CSS v4 `@theme` block (light baseline) plus dark /\n * high-contrast overrides under configurable selectors. Returns a single\n * ready-to-paste CSS string.\n * @see https://tailwindcss.com/docs/theme\n */\n tailwind(options?: GlazeTailwindOptions): string;\n}\n\nexport interface GlazeExtendOptions {\n hue?: number;\n saturation?: number;\n colors?: ColorMap;\n /** Config override for the child theme. Merged with the parent's override. */\n config?: GlazeConfigOverride;\n}\n\n// ============================================================================\n// Palette API\n// ============================================================================\n\nexport interface GlazeTokenOptions {\n /** Prefix mode. `true` uses \"<themeName>-\", or provide a custom map. */\n prefix?: boolean | Record<string, string>;\n /** Override state aliases for this export. */\n states?: {\n dark?: string;\n highContrast?: string;\n };\n /** Override which scheme variants to include. */\n modes?: GlazeOutputModes;\n /** Output color format. Default: 'oklch'. */\n format?: GlazeColorFormat;\n /**\n * Emit hue as a separate custom property, referenced via `var()`.\n * Requires `format: 'oklch'` and every color to be pastel.\n */\n splitHue?: boolean;\n /**\n * Base name for the theme-level hue var (`--{name}-hue`). Default: `'theme'`.\n * Palette export auto-derives this from the theme name.\n */\n name?: string;\n}\n\nexport interface GlazeJsonOptions {\n /** Override which scheme variants to include. */\n modes?: GlazeOutputModes;\n /** Output color format. Default: 'oklch'. */\n format?: GlazeColorFormat;\n}\n\nexport interface GlazeCssOptions {\n /** Output color format. Default: 'oklch'. */\n format?: GlazeColorFormat;\n /** Suffix appended to each CSS custom property name. Default: '-color'. */\n suffix?: string;\n /**\n * Emit hue as a separate custom property, referenced via `var()`.\n * Requires `format: 'oklch'` and every color to be pastel.\n */\n splitHue?: boolean;\n /**\n * Base name for the theme-level hue var (`--{name}-hue`). Default: `'theme'`.\n * Palette export auto-derives this from the theme name.\n */\n name?: string;\n}\n\n/** CSS custom property declarations grouped by scheme variant. */\nexport interface GlazeCssResult {\n light: string;\n dark: string;\n lightContrast: string;\n darkContrast: string;\n}\n\n// ============================================================================\n// DTCG & Tailwind export types\n// ============================================================================\n\n/**\n * Color space used for DTCG `$value` color objects.\n * @see https://www.designtokens.org/\n */\nexport type DtcgColorSpace = 'srgb' | 'oklch';\n\n/**\n * A DTCG color `$value` in the sRGB color space: gamma sRGB components in\n * 0–1 plus a 6-digit `hex` hint. Universally understood by Figma, Tokens\n * Studio, Style Dictionary, and every DTCG reader.\n */\nexport interface DtcgSrgbColorValue {\n colorSpace: 'srgb';\n components: [number, number, number];\n hex: HexColor;\n /** Opacity 0–1. Omitted when fully opaque (alpha = 1). */\n alpha?: number;\n}\n\n/**\n * A DTCG color `$value` in the OKLCH color space: `[L, C, H]` components\n * (L/C: 0–1, H: degrees). Wide-gamut and Glaze-native; no `hex` is emitted.\n */\nexport interface DtcgOklchColorValue {\n colorSpace: 'oklch';\n components: [number, number, number];\n /** Opacity 0–1. Omitted when fully opaque (alpha = 1). */\n alpha?: number;\n}\n\n/** A DTCG `$value` for a color token, in either supported color space. */\nexport type DtcgColorValue = DtcgSrgbColorValue | DtcgOklchColorValue;\n\n/**\n * A single W3C DTCG color token: `{ $type: 'color', $value }`.\n * `$description` is optional and not populated by Glaze today.\n */\nexport interface DtcgColorToken {\n $type: 'color';\n $value: DtcgColorValue;\n $description?: string;\n}\n\n/**\n * A W3C Design Tokens Format Module (2025.10) token tree for one scheme.\n * Glaze emits one document per scheme variant — the most tool-compatible\n * convention (one file per Style Dictionary theme / Tokens Studio set /\n * Figma variable mode).\n */\nexport type DtcgDocument = Record<string, DtcgColorToken>;\n\n/** DTCG token documents grouped by scheme variant. Light is always present. */\nexport interface GlazeDtcgResult {\n light: DtcgDocument;\n dark?: DtcgDocument;\n lightContrast?: DtcgDocument;\n darkContrast?: DtcgDocument;\n}\n\n/** A single DTCG color token grouped by scheme variant (standalone tokens). */\nexport interface GlazeColorDtcgResult {\n light: DtcgColorToken;\n dark?: DtcgColorToken;\n lightContrast?: DtcgColorToken;\n darkContrast?: DtcgColorToken;\n}\n\n/** Options for `theme.dtcg()` / `palette.dtcg()`. */\nexport interface GlazeDtcgOptions {\n /** Override which scheme variants to include. */\n modes?: GlazeOutputModes;\n /**\n * DTCG color space. `'srgb'` (default) emits sRGB components plus a `hex`\n * hint — universally understood (Figma, Tokens Studio). `'oklch'` emits\n * OKLCH components with no hex — Glaze-native, wide-gamut.\n */\n colorSpace?: DtcgColorSpace;\n}\n\n// ============================================================================\n// DTCG Resolver-Module export types\n// (W3C Design Tokens Resolver Module — one document for all scheme variants)\n// ============================================================================\n\n/**\n * A node in a DTCG Resolver-Module token tree: either a leaf color token or a\n * nested group. A flat `DtcgDocument` (top-level color-name keys) is a valid\n * shallow tree, so Glaze's per-scheme documents slot directly into\n * `sets.<name>.sources` and `modifiers.<name>.contexts.<ctx>` entries.\n */\nexport interface DtcgTokenTree {\n [key: string]: DtcgColorToken | DtcgTokenTree;\n}\n\n/** A named set in a resolver document: a list of token-tree sources. */\nexport interface DtcgResolverSet {\n sources: DtcgTokenTree[];\n}\n\n/**\n * A named modifier (an axis such as `scheme`) in a resolver document.\n * `default` names the context applied when no override is selected; `contexts`\n * maps each context name to the token-tree overrides applied for it.\n */\nexport interface DtcgResolverModifier {\n default: string;\n contexts: Record<string, DtcgTokenTree[]>;\n}\n\n/** A JSON-pointer `$ref` entry in a resolver document's `resolutionOrder`. */\nexport interface DtcgResolverRef {\n $ref: string;\n}\n\n/**\n * A W3C DTCG Resolver-Module document. Describes every scheme variant in a\n * single file as `sets` (base token sources) plus `modifiers` (per-context\n * overrides) composed in `resolutionOrder`. Consumable by resolver tools such\n * as Dispersa.\n * @see https://www.designtokens.org/\n */\nexport interface GlazeDtcgResolverDocument {\n version: string;\n sets: Record<string, DtcgResolverSet>;\n modifiers: Record<string, DtcgResolverModifier>;\n resolutionOrder: DtcgResolverRef[];\n}\n\n/** Renaming of the four scheme variants as resolver-modifier context names. */\nexport interface GlazeDtcgResolverContextNames {\n light?: string;\n dark?: string;\n lightContrast?: string;\n darkContrast?: string;\n}\n\n/**\n * Options for `theme.dtcgResolver()` / `palette.dtcgResolver()`. Extends\n * `GlazeDtcgOptions` so `modes` + `colorSpace` pass through to the underlying\n * per-scheme `dtcg()` build.\n */\nexport interface GlazeDtcgResolverOptions extends GlazeDtcgOptions {\n /** Name of the single set holding the default (light) token tree. Default `'base'`. */\n setName?: string;\n /**\n * Name of the modifier describing the scheme axis. Default `'scheme'`\n * (Glaze's term for the light / dark / high-contrast axis).\n */\n modifierName?: string;\n /**\n * Override the four context names emitted on the modifier. Defaults to the\n * Glaze variant keys: `light` / `dark` / `lightContrast` / `darkContrast`.\n */\n contextNames?: GlazeDtcgResolverContextNames;\n /** Resolver document version. Default `'2025.10'`. */\n version?: string;\n}\n\n/** Options for `glaze.color().dtcgResolver()`. `name` is required. */\nexport interface GlazeColorDtcgResolverOptions extends GlazeDtcgResolverOptions {\n /** Token name keying the color within each token tree. Required. */\n name: string;\n}\n\n/** Options for `theme.tailwind()` / `palette.tailwind()`. */\nexport interface GlazeTailwindOptions {\n /** Override which scheme variants to include. */\n modes?: GlazeOutputModes;\n /** Output color format. Default: 'oklch'. */\n format?: GlazeColorFormat;\n /**\n * CSS custom property namespace, forming `--<namespace><name>`.\n * Default: `'color-'` → `--color-surface`. (Tailwind v4's `--color-*`\n * convention, which auto-generates `bg-*` / `text-*` / `border-*`.)\n *\n * Named `namespace` rather than `prefix` to avoid clashing with the\n * palette theme-prefix option on `palette.tailwind()`.\n */\n namespace?: string;\n /**\n * Selector wrapping the dark-scheme overrides. Default: `'.dark'`.\n * Pass a media query such as `'@media (prefers-color-scheme: dark)'` to\n * drive dark mode from the OS preference instead of a class.\n */\n darkSelector?: string;\n /**\n * Selector wrapping the light high-contrast overrides. Default:\n * `'.high-contrast'`. The combined dark + high-contrast overrides are\n * emitted under `${darkSelector}${highContrastSelector}` (e.g.\n * `.dark.high-contrast`).\n */\n highContrastSelector?: string;\n}\n\n/** Options for `glaze.color().tailwind()`. `name` is required. */\nexport interface GlazeColorTailwindOptions extends GlazeTailwindOptions {\n /** Custom property base name (without leading `--`). Required. */\n name: string;\n}\n\n/** Options for `glaze.palette()` creation. */\nexport interface GlazePaletteOptions {\n /**\n * Name of the primary theme. The primary theme's tokens are duplicated\n * without prefix in all exports, providing convenient short aliases\n * alongside the prefixed versions. Can be overridden per-export.\n *\n * @example\n * ```ts\n * const palette = glaze.palette({ brand, accent }, { primary: 'brand' });\n * palette.tokens()\n * // → { light: { 'brand-surface': '...', 'surface': '...', 'accent-surface': '...' } }\n * ```\n */\n primary?: string;\n}\n\n/** Options shared by palette `tokens()`, `tasty()`, and `css()` exports. */\nexport interface GlazePaletteExportOptions {\n /**\n * Prefix mode. `true` uses `\"<themeName>-\"`, or provide a custom map.\n * Defaults to `true` for palette export methods.\n * Set to `false` explicitly to disable prefixing. Colliding keys\n * produce a console.warn and the first-written value wins.\n */\n prefix?: boolean | Record<string, string>;\n /**\n * Override the palette-level primary theme for this export.\n * Pass a theme name to set/change the primary, or `false` to disable it.\n * When omitted, inherits the palette-level `primary`.\n */\n primary?: string | false;\n /**\n * Emit hue as a separate custom property, referenced via `var()`.\n * Requires `format: 'oklch'` and every color to be pastel.\n */\n splitHue?: boolean;\n}\n\nexport interface GlazePalette {\n /** Theme names in insertion order. */\n list(): string[];\n\n /** Primary theme name, if set at palette creation. */\n readonly primary: string | undefined;\n\n /** Get a theme by name. Returns the live instance held by the palette. */\n theme(name: string): GlazeTheme | undefined;\n\n /**\n * Shallow copy of the theme map (same instances the palette holds).\n * Mutating a returned theme affects subsequent palette exports.\n */\n themes(): Record<string, GlazeTheme>;\n\n /**\n * Export the palette authoring configuration as a JSON-safe object.\n * Restorable via `glaze.paletteFrom(...)`. Distinct from `json()`, which\n * emits resolved color strings. Optional `override` is forwarded to each\n * nested `theme.export(override)`.\n */\n export(override?: GlazeConfigOverride): GlazePaletteExport;\n\n /**\n * Export all themes as a flat token map grouped by scheme variant.\n * Prefix defaults to `true` — all tokens are prefixed with the theme name.\n * Inherits the palette-level `primary`; override per-call or pass `false` to disable.\n *\n * ```ts\n * const palette = glaze.palette({ brand, accent }, { primary: 'brand' });\n * palette.tokens()\n * // → { light: { 'brand-surface': '...', 'surface': '...', 'accent-surface': '...' } }\n * ```\n */\n tokens(\n options?: GlazeJsonOptions & GlazePaletteExportOptions,\n ): Record<string, Record<string, string>>;\n\n /**\n * Export all themes as tasty style-to-state bindings.\n * Uses `#name` color token keys and state aliases (`''`, `'@media(prefers-color-scheme: dark)'`, etc.).\n * Prefix defaults to `true`. Inherits the palette-level `primary`.\n * @see https://tasty.style/docs\n */\n tasty(\n options?: GlazeTokenOptions & GlazePaletteExportOptions,\n ): Record<string, Record<string, string>>;\n\n /** Export all themes as plain JSON grouped by theme name. */\n json(\n options?: GlazeJsonOptions & {\n prefix?: boolean | Record<string, string>;\n },\n ): Record<string, Record<string, Record<string, string>>>;\n\n /** Export all themes as CSS custom property declarations. */\n css(options?: GlazeCssOptions & GlazePaletteExportOptions): GlazeCssResult;\n\n /**\n * Export all themes as W3C DTCG documents, one per scheme variant.\n * Prefix defaults to `true`. Inherits the palette-level `primary`.\n * @see https://www.designtokens.org/\n */\n dtcg(options?: GlazeDtcgOptions & GlazePaletteExportOptions): GlazeDtcgResult;\n\n /**\n * Export all themes as a single W3C DTCG Resolver-Module document. Prefix\n * defaults to `true`. Inherits the palette-level `primary`.\n * @see https://www.designtokens.org/\n */\n dtcgResolver(\n options?: GlazeDtcgResolverOptions & GlazePaletteExportOptions,\n ): GlazeDtcgResolverDocument;\n\n /**\n * Export all themes as a Tailwind CSS v4 `@theme` block plus dark /\n * high-contrast overrides. Returns a single ready-to-paste CSS string.\n * Prefix defaults to `true`.\n * @see https://tailwindcss.com/docs/theme\n */\n tailwind(options?: GlazeTailwindOptions & GlazePaletteExportOptions): string;\n}\n","/**\n * Authoring-export helpers: schema version, type guards, and restore\n * validation shared by `themeFrom` / `colorFrom` / `paletteFrom`.\n */\n\nimport { GLAZE_EXPORT_VERSION } from './types';\nimport type {\n GlazeColorTokenExport,\n GlazeExportKind,\n GlazePaletteExport,\n GlazeThemeExport,\n} from './types';\n\nexport { GLAZE_EXPORT_VERSION };\n\nfunction isPlainObject(data: unknown): data is Record<string, unknown> {\n return typeof data === 'object' && data !== null && !Array.isArray(data);\n}\n\n/**\n * Reject unknown / invalid schema versions. Missing `version` is allowed\n * (legacy snapshots). Present versions must be an integer in\n * `1..=GLAZE_EXPORT_VERSION`.\n */\nexport function assertExportVersion(\n data: { version?: unknown },\n factory: string,\n): void {\n if (data.version === undefined) return;\n if (\n typeof data.version !== 'number' ||\n !Number.isInteger(data.version) ||\n data.version < 1\n ) {\n throw new Error(\n `${factory}: invalid \"version\" field — expected an integer >= 1 (got ${JSON.stringify(data.version)}).`,\n );\n }\n if (data.version > GLAZE_EXPORT_VERSION) {\n throw new Error(\n `${factory}: unsupported export version ${data.version} (this library supports version ${GLAZE_EXPORT_VERSION}). Upgrade @tenphi/glaze to load this snapshot.`,\n );\n }\n}\n\n/**\n * When `kind` is present, it must match the factory. Missing `kind` is\n * allowed for legacy snapshots.\n */\nexport function assertExportKind(\n data: { kind?: unknown },\n expected: GlazeExportKind,\n factory: string,\n): void {\n if (data.kind === undefined) return;\n if (data.kind !== expected) {\n throw new Error(\n `${factory}: expected kind \"${expected}\", got ${JSON.stringify(data.kind)}.`,\n );\n }\n}\n\nfunction hasThemeShape(data: Record<string, unknown>): boolean {\n return (\n typeof data.hue === 'number' &&\n typeof data.saturation === 'number' &&\n !('form' in data) &&\n !('themes' in data)\n );\n}\n\nfunction hasColorTokenShape(data: Record<string, unknown>): boolean {\n return data.form === 'value' || data.form === 'structured';\n}\n\nfunction hasPaletteShape(data: Record<string, unknown>): boolean {\n return (\n isPlainObject(data.themes) &&\n !('form' in data) &&\n typeof data.hue !== 'number'\n );\n}\n\n/** Type guard for theme authoring snapshots (prefers `kind`, falls back to shape). */\nexport function isThemeExport(data: unknown): data is GlazeThemeExport {\n if (!isPlainObject(data)) return false;\n if (data.kind === 'theme') return hasThemeShape(data);\n if (data.kind !== undefined) return false;\n return hasThemeShape(data);\n}\n\n/** Type guard for color-token authoring snapshots. */\nexport function isColorTokenExport(\n data: unknown,\n): data is GlazeColorTokenExport {\n if (!isPlainObject(data)) return false;\n if (data.kind === 'color') return hasColorTokenShape(data);\n if (data.kind !== undefined) return false;\n return hasColorTokenShape(data);\n}\n\n/** Type guard for palette authoring snapshots. */\nexport function isPaletteExport(data: unknown): data is GlazePaletteExport {\n if (!isPlainObject(data)) return false;\n if (data.kind === 'palette') return hasPaletteShape(data);\n if (data.kind !== undefined) return false;\n return hasPaletteShape(data);\n}\n","/**\n * Export-time guards for color format and channel-splitting prerequisites.\n */\n\nimport type {\n GlazeColorFormat,\n GlazeOutputModes,\n ResolvedColor,\n} from './types';\n\nconst NON_NATIVE_FORMATS = new Set<GlazeColorFormat>(['okhsl', 'okhst']);\n\n/**\n * Throw when a non-native Glaze color space is requested for an export that\n * emits raw CSS or non-Tasty token maps.\n */\nexport function assertNativeFormat(\n format: GlazeColorFormat | undefined,\n method: string,\n): void {\n if (format !== undefined && NON_NATIVE_FORMATS.has(format)) {\n throw new Error(\n `glaze: ${format} output is only supported by tasty() (not a native CSS color space). ` +\n `Use tasty({ format: '${format}' }) or pick a native format (oklch|hsl|rgb) for ${method}().`,\n );\n }\n}\n\ntype SchemeField = 'light' | 'dark' | 'lightContrast' | 'darkContrast';\n\nconst SCHEME_FIELDS: {\n field: SchemeField;\n modes: (modes: Required<GlazeOutputModes>) => boolean;\n}[] = [\n { field: 'light', modes: () => true },\n { field: 'dark', modes: (m) => m.dark },\n { field: 'lightContrast', modes: (m) => m.highContrast },\n {\n field: 'darkContrast',\n modes: (m) => m.dark && m.highContrast,\n },\n];\n\n/**\n * Throw when `splitHue` is enabled but any exported color is not pastel.\n * Hue rotation is only clip-free when chroma is bounded by the hue-independent\n * safe chroma (`computeSafeChromaOKLCH`).\n */\nexport function assertAllPastel(\n resolved: Map<string, ResolvedColor>,\n modes: Required<GlazeOutputModes>,\n): void {\n const nonPastel: string[] = [];\n\n for (const [name, color] of resolved) {\n for (const { field, modes: active } of SCHEME_FIELDS) {\n if (!active(modes)) continue;\n const variant = color[field];\n if (variant.pastel !== true) {\n if (!nonPastel.includes(name)) nonPastel.push(name);\n break;\n }\n }\n }\n\n if (nonPastel.length === 0) return;\n\n throw new Error(\n 'glaze: splitHue requires every color to be pastel (hue rotation is only ' +\n 'clip-free when chroma is bounded by the hue-independent safe chroma). ' +\n `Non-pastel: ${nonPastel.join(', ')}. ` +\n 'Set pastel: true (per-theme, per-token, or per-color) or drop splitHue.',\n );\n}\n","/**\n * Small shared helpers used across the resolver pipeline:\n * - HC-pair selection (`pairNormal` / `pairHC`)\n * - Absolute / relative / extreme tone discrimination\n * - Generic numeric helpers (`clamp`, hue resolution, relative-value parsing)\n */\n\nimport type { ExtremeValue, HCPair, RelativeValue, ToneValue } from './types';\n\nexport function pairNormal<T>(p: HCPair<T>): T {\n return Array.isArray(p) ? p[0] : p;\n}\n\nexport function pairHC<T>(p: HCPair<T>): T {\n return Array.isArray(p) ? p[1] : p;\n}\n\nexport function clamp(v: number, min: number, max: number): number {\n return Math.max(min, Math.min(max, v));\n}\n\n/** Whether a tone value is an extreme keyword (`'max'` / `'min'`). */\nexport function isExtremeTone(value: ToneValue): value is ExtremeValue {\n return value === 'max' || value === 'min';\n}\n\n/**\n * Parse a value that can be absolute (number) or relative (signed string).\n * Returns the numeric value and whether it's relative.\n */\nexport function parseRelativeOrAbsolute(value: number | RelativeValue): {\n value: number;\n relative: boolean;\n} {\n if (typeof value === 'number') {\n return { value, relative: false };\n }\n return { value: parseFloat(value), relative: true };\n}\n\n/**\n * Parse a tone value into a normalized shape.\n * - `'max'` / `'min'` → `{ kind: 'extreme', value: 100 | 0 }` (an absolute\n * author tone before scheme mapping — `'max'` is 100, `'min'` is 0).\n * - `'+N'` / `'-N'` → `{ kind: 'relative', value: ±N }`.\n * - number → `{ kind: 'absolute', value }`.\n */\nexport function parseToneValue(value: ToneValue): {\n kind: 'absolute' | 'relative' | 'extreme';\n value: number;\n} {\n if (value === 'max') return { kind: 'extreme', value: 100 };\n if (value === 'min') return { kind: 'extreme', value: 0 };\n if (typeof value === 'number') return { kind: 'absolute', value };\n return { kind: 'relative', value: parseFloat(value) };\n}\n\n/**\n * Compute the effective hue for a color, given the theme seed hue\n * and an optional per-color hue override.\n */\nexport function resolveEffectiveHue(\n seedHue: number,\n defHue: number | RelativeValue | undefined,\n): number {\n if (defHue === undefined) return seedHue;\n const parsed = parseRelativeOrAbsolute(defHue);\n if (parsed.relative) {\n return (((seedHue + parsed.value) % 360) + 360) % 360;\n }\n return ((parsed.value % 360) + 360) % 360;\n}\n\n/**\n * Check whether a tone value represents an absolute root definition\n * (i.e. a number, not a relative string). Extreme keywords (`'max'` /\n * `'min'`) also count — they need no base.\n */\nexport function isAbsoluteTone(tone: HCPair<ToneValue> | undefined): boolean {\n if (tone === undefined) return false;\n const normal = Array.isArray(tone) ? tone[0] : tone;\n return typeof normal === 'number' || isExtremeTone(normal);\n}\n","/**\n * OKHST — the contrast-uniform tone space.\n *\n * OKHST is OKHSL with its lightness axis replaced by a contrast-uniform\n * \"tone\" axis. It shares `h` / `s` with OKHSL verbatim and swaps `l` for\n * `t`. This module owns:\n *\n * - the closed-form tone transfers (`toTone` / `fromTone`) at a fixed\n * reference eps, plus the gray luminance helpers (`lToY` / `yToL`),\n * - the `{ h, s, t }` <-> `{ h, s, l }` color-space converters,\n * - the resolved-variant edge adapter (`variantToOkhsl`),\n * - the per-scheme tone mapping that replaced the Möbius dark curve\n * (`mapToneForScheme`), the dark desaturation reducer, and the solver's scheme\n * tone range.\n *\n * See `docs/okhst.md` for the full specification and the calibrated\n * default constants.\n */\n\nimport { clamp } from './hc-pair';\nimport { toe, toeInv } from './okhsl-color-math';\nimport type { AdaptationMode, GlazeConfigResolved, ToneWindow } from './types';\n\n/**\n * Reference eps for the OKHST color space. WCAG 2 contrast is\n * `(Y_hi + 0.05) / (Y_lo + 0.05)`, so an eps of `0.05` makes equal tone\n * steps yield equal WCAG contrast. This is the canonical eps used by\n * `okhst()` input, `{ h, s, t }` input, stored `ResolvedColorVariant.t`,\n * relative `tone` offsets, and the contrast solver.\n */\nexport const REF_EPS = 0.05;\n\n// ============================================================================\n// Gray luminance <-> OKHSL lightness (closed form)\n// ============================================================================\n\n/**\n * Gray luminance from OKHSL lightness. For an achromatic color the OKLab\n * lightness is `toeInv(l)` and luminance is its cube.\n */\nexport function lToY(l: number): number {\n const L = toeInv(l);\n return L * L * L;\n}\n\n/** OKHSL lightness from gray luminance — exact inverse of {@link lToY}. */\nexport function yToL(y: number): number {\n return toe(Math.cbrt(Math.max(0, y)));\n}\n\n// ============================================================================\n// Tone transfers (luminance domain)\n// ============================================================================\n\n/**\n * Map a luminance `Y` (0–1) to tone (0–100) at the given eps.\n * `toneFromY(0) === 0` and `toneFromY(1) === 100` for any eps.\n */\nexport function toneFromY(y: number, eps: number = REF_EPS): number {\n const num = Math.log(y + eps) - Math.log(eps);\n const den = Math.log(1 + eps) - Math.log(eps);\n return (num / den) * 100;\n}\n\n/** Map a tone (0–100) back to luminance (0–1). Inverse of {@link toneFromY}. */\nexport function yFromTone(t: number, eps: number = REF_EPS): number {\n const den = Math.log(1 + eps) - Math.log(eps);\n return Math.exp((t / 100) * den + Math.log(eps)) - eps;\n}\n\n// ============================================================================\n// Tone transfers (OKHSL lightness domain)\n// ============================================================================\n\n/** OKHSL lightness (0–1) -> tone (0–100). */\nexport function toTone(l: number, eps: number = REF_EPS): number {\n return toneFromY(lToY(l), eps);\n}\n\n/** Tone (0–100) -> OKHSL lightness (0–1). Inverse of {@link toTone}. */\nexport function fromTone(t: number, eps: number = REF_EPS): number {\n return yToL(yFromTone(t, eps));\n}\n\n// ============================================================================\n// Color-space converters\n// ============================================================================\n\n/** Convert OKHST `{ h, s, t }` (t in 0–1) to OKHSL `{ h, s, l }`. */\nexport function okhstToOkhsl(c: { h: number; s: number; t: number }): {\n h: number;\n s: number;\n l: number;\n} {\n return { h: c.h, s: c.s, l: clamp(fromTone(c.t * 100), 0, 1) };\n}\n\n/** Convert OKHSL `{ h, s, l }` to OKHST `{ h, s, t }` (t in 0–1). */\nexport function okhslToOkhst(c: { h: number; s: number; l: number }): {\n h: number;\n s: number;\n t: number;\n} {\n return { h: c.h, s: c.s, t: clamp(toTone(c.l) / 100, 0, 1) };\n}\n\n/**\n * Edge adapter: a resolved variant stores canonical tone `t` (0–1). Convert\n * it to the OKHSL `{ h, s, l }` the formatters and luminance pipeline expect.\n */\nexport function variantToOkhsl(v: { h: number; s: number; t: number }): {\n h: number;\n s: number;\n l: number;\n} {\n return { h: v.h, s: v.s, l: clamp(fromTone(v.t * 100), 0, 1) };\n}\n\n// ============================================================================\n// Scheme tone mapping (replaces the Möbius dark curve)\n// ============================================================================\n\n/**\n * Normalize any {@link ToneWindow} form to `{ lo, hi, eps }`.\n * - `false`: full range `[0, 100]` at the reference eps (boundaries removed,\n * curve preserved).\n * - `[lo, hi]`: endpoints at the reference eps (the common form).\n * - `{ lo, hi, eps }`: passed through (advanced eps tuning).\n */\nexport function normalizeToneWindow(win: ToneWindow): {\n lo: number;\n hi: number;\n eps: number;\n} {\n if (win === false) return { lo: 0, hi: 100, eps: REF_EPS };\n if (Array.isArray(win)) return { lo: win[0], hi: win[1], eps: REF_EPS };\n return { lo: win.lo, hi: win.hi, eps: win.eps };\n}\n\n/**\n * Resolve the active tone window for a scheme as OKHSL-lightness endpoints.\n * - HC variants always return the full range `[0, 100]` with the mode eps.\n * - `false` (= \"no clamping\") is treated as `[0, 100]` with the reference eps.\n */\nfunction activeWindow(\n isHighContrast: boolean,\n kind: 'light' | 'dark',\n config: GlazeConfigResolved,\n): { lo: number; hi: number; eps: number } {\n const win = normalizeToneWindow(\n kind === 'dark' ? config.darkTone : config.lightTone,\n );\n if (isHighContrast) return { lo: 0, hi: 100, eps: win.eps };\n return win;\n}\n\n/**\n * Remap an authored tone (0–100) into a scheme window and return the final\n * OKHSL lightness (0–100). The window endpoints are OKHSL lightnesses; the\n * author tone is positioned within the window's tone interval (using the\n * window's render eps), then converted back to lightness.\n */\nfunction remapToneToLightness(\n authorTone: number,\n win: { lo: number; hi: number; eps: number },\n): number {\n const loT = toTone(win.lo / 100, win.eps);\n const hiT = toTone(win.hi / 100, win.eps);\n const winTone = loT + (authorTone / 100) * (hiT - loT);\n return clamp(fromTone(winTone, win.eps) * 100, 0, 100);\n}\n\n/**\n * Map an authored tone for a scheme and return the canonical stored tone\n * (0–100, reference eps).\n *\n * - `static`: identity — the same tone renders in every scheme.\n * - `auto` + dark: invert (`100 - tone`) then remap into the dark window.\n * - `auto`/`fixed` + light, or `fixed` + dark: remap, no inversion.\n *\n * The window remap uses the mode's render eps to land a final OKHSL\n * lightness; that lightness is then re-expressed as canonical tone so\n * relative offsets and contrast stay comparable across schemes.\n */\nexport function mapToneForScheme(\n authorTone: number,\n mode: AdaptationMode,\n isDark: boolean,\n isHighContrast: boolean,\n config: GlazeConfigResolved,\n): number {\n if (mode === 'static') return clamp(authorTone, 0, 100);\n\n const kind = isDark ? 'dark' : 'light';\n const win = activeWindow(isHighContrast, kind, config);\n\n const inverted = isDark && mode === 'auto' ? 100 - authorTone : authorTone;\n const finalL = remapToneToLightness(clamp(inverted, 0, 100), win);\n return clamp(toTone(finalL / 100), 0, 100);\n}\n\n// ============================================================================\n// Saturation\n// ============================================================================\n\n/** Dark-scheme desaturation reducer (unchanged from the legacy pipeline). */\nexport function mapSaturationDark(\n s: number,\n mode: AdaptationMode,\n config: GlazeConfigResolved,\n): number {\n if (mode === 'static') return s;\n return s * (1 - config.darkDesaturation);\n}\n\n// ============================================================================\n// Solver support\n// ============================================================================\n\n/**\n * Tone search range (0–1) for the contrast solver in a given scheme.\n * `static` searches the full range; otherwise the scheme window's tone\n * endpoints (HC bypasses to full range).\n */\nexport function schemeToneRange(\n isDark: boolean,\n mode: AdaptationMode,\n isHighContrast: boolean,\n config: GlazeConfigResolved,\n): [number, number] {\n if (mode === 'static') return [0, 1];\n const win = activeWindow(isHighContrast, isDark ? 'dark' : 'light', config);\n return [\n clamp(toTone(win.lo / 100) / 100, 0, 1),\n clamp(toTone(win.hi / 100) / 100, 0, 1),\n ];\n}\n","/**\n * Contrast solver — operates in OKHST tone.\n *\n * Finds the tone closest to a preferred tone that satisfies a contrast\n * floor (WCAG 2 ratio or APCA Lc) against a base color. Because tone is\n * contrast-uniform, the WCAG branch gets a closed-form seed and the search\n * converges quickly.\n *\n * Public API: `findToneForContrast`, `findValueForMixContrast`,\n * `resolveMinContrast`, `resolveContrastForMode`, `apcaContrast`.\n */\n\nimport {\n okhslToLinearSrgb,\n contrastRatioFromLuminance,\n gamutClampedLuminance,\n apcaLuminanceFromLinearRgb,\n} from './okhsl-color-math';\nimport { REF_EPS, fromTone, toneFromY } from './okhst';\nimport { clamp } from './hc-pair';\nimport type { ContrastSpec, HCPair } from './types';\n\nexport type LinearRgb = [number, number, number];\n\nexport type ContrastMetric = 'wcag' | 'apca';\n\n/**\n * Luminance of a linear-sRGB color in the basis the metric expects: WCAG\n * relative luminance for `wcag`, APCA screen luminance (`Ys`) for `apca`.\n */\nexport function metricLuminance(\n metric: ContrastMetric,\n linearRgb: LinearRgb,\n): number {\n return metric === 'apca'\n ? apcaLuminanceFromLinearRgb(linearRgb)\n : gamutClampedLuminance(linearRgb);\n}\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport type ContrastPreset = 'AA' | 'AAA' | 'AA-large' | 'AAA-large';\nexport type MinContrast = number | ContrastPreset;\n\n/**\n * Named APCA Lc floor presets (APCA Bronze Simple Mode conformance levels),\n * independent of role. Use them anywhere an APCA target is accepted.\n *\n * | Preset | Lc | Use case |\n * | ------------- | --- | ---------------------------------------------------- |\n * | `'preferred'` | 90 | Preferred body / column text |\n * | `'body'` | 75 | Minimum body / column text |\n * | `'content'` | 60 | Readable non-body content (~WCAG AA 4.5:1) |\n * | `'large'` | 45 | Large/bold headlines; fine icons/outlines (~3:1) |\n * | `'non-text'` | 30 | Solid icons/controls; placeholder/disabled text |\n * | `'min'` | 15 | Dividers/decorative; APCA \"point of invisibility\" |\n */\nexport type ApcaPreset =\n | 'preferred'\n | 'body'\n | 'content'\n | 'large'\n | 'non-text'\n | 'min';\n\nexport const APCA_PRESETS: Record<ApcaPreset, number> = {\n preferred: 90,\n body: 75,\n content: 60,\n large: 45,\n 'non-text': 30,\n min: 15,\n};\n\n/**\n * APCA-W3 \"Enhanced Level\" delta added to a bare APCA target in high-contrast\n * mode when no explicit HC value is provided (analogous to WCAG AAA over AA).\n * Only applied when neither the outer `contrast` pair nor the inner `apca`\n * pair carries an explicit HC entry.\n */\nexport const APCA_HC_ENHANCEMENT = 15;\n\n/** Upper bound for an APCA Lc target after HC enhancement. */\nexport const APCA_MAX_LC = 106;\n\n/**\n * Resolve an APCA target — a raw Lc number (kept as-is) or an `ApcaPreset`\n * keyword mapped to its Lc value. The magnitude is forced non-negative.\n */\nexport function resolveApcaTarget(value: number | ApcaPreset): number {\n if (typeof value === 'number') return Math.abs(value);\n return APCA_PRESETS[value];\n}\n\n/** Metric + numeric target after resolving a `ContrastSpec` for a mode. */\nexport interface ResolvedContrast {\n metric: 'wcag' | 'apca';\n /** WCAG ratio (>= 1) or APCA Lc magnitude (0–106). */\n target: number;\n /**\n * APCA argument order: which side the resolved (candidate) color plays\n * against the base. `'fg'` (default) → `apcaContrast(yCandidate, yBase)`;\n * `'bg'` → `apcaContrast(yBase, yCandidate)`. Always `'fg'` for WCAG\n * (symmetric, ignored).\n */\n polarity?: 'fg' | 'bg';\n}\n\n// ============================================================================\n// Preset mapping + spec resolution\n// ============================================================================\n\nconst CONTRAST_PRESETS: Record<ContrastPreset, number> = {\n AA: 4.5,\n AAA: 7,\n 'AA-large': 3,\n 'AAA-large': 4.5,\n};\n\n/**\n * WCAG high-contrast auto-promotion (analog of APCA's Enhanced Level). A bare\n * AA / AA-large preset is promoted to its spec-defined \"Enhanced\" successor\n * (SC 1.4.3 → SC 1.4.6) in high-contrast mode. AAA / AAA-large are already\n * the top WCAG tier and are left unchanged. Bare numeric targets have no\n * defined successor tier and are also left unchanged. An explicit HC value\n * (outer or inner pair) always overrides.\n */\nconst WCAG_HC_PROMOTION: Partial<Record<ContrastPreset, ContrastPreset>> = {\n AA: 'AAA',\n 'AA-large': 'AAA-large',\n};\n\nexport function resolveMinContrast(value: MinContrast): number {\n if (typeof value === 'number') {\n return Math.max(1, value);\n }\n return CONTRAST_PRESETS[value];\n}\n\n/**\n * Resolve a WCAG target (number or preset) for a mode, applying the\n * high-contrast auto-promotion when `explicitHC` is false and the value is an\n * AA-family preset. Bare numbers and AAA-family presets pass through.\n */\nfunction resolveWcagTarget(\n value: number | ContrastPreset,\n isHighContrast: boolean,\n explicitHC: boolean,\n): number {\n if (typeof value === 'number') {\n return resolveMinContrast(value);\n }\n if (isHighContrast && !explicitHC) {\n const promoted = WCAG_HC_PROMOTION[value];\n if (promoted !== undefined) return resolveMinContrast(promoted);\n }\n return resolveMinContrast(value);\n}\n\nfunction pickPair<T>(p: HCPair<T>, isHighContrast: boolean): T {\n return Array.isArray(p) ? (isHighContrast ? p[1] : p[0]) : p;\n}\n\n/**\n * Resolve a `ContrastSpec` (already selected from any outer HC pair) for a\n * given mode into `{ metric, target }`. Handles the inner metric HC pair and\n * preset resolution. `polarity` is passed through to the result for the APCA\n * branch (it controls argument order in the solver); WCAG ignores it.\n *\n * `outerExplicitHC` indicates whether the caller selected this `spec` from an\n * explicit high-contrast entry of the outer `contrast` pair. Together with the\n * inner metric pair, it decides whether the HC auto-enhancement fires:\n * - APCA: +15 Lc \"Enhanced Level\" boost when neither level is explicit.\n * - WCAG: AA → AAA / AA-large → AAA-large promotion (SC 1.4.3 → 1.4.6) when\n * neither level is explicit. AAA-family presets and bare numbers are left\n * unchanged (AAA is the top WCAG tier).\n * Defaults to `false` (correct for direct callers, which pass a single\n * selected spec rather than an outer pair).\n */\nexport function resolveContrastForMode(\n spec: ContrastSpec,\n isHighContrast: boolean,\n polarity?: 'fg' | 'bg',\n outerExplicitHC?: boolean,\n): ResolvedContrast {\n if (typeof spec === 'number' || typeof spec === 'string') {\n // A bare string here is a WCAG preset ('AA' / 'AAA' / ...).\n return {\n metric: 'wcag',\n target: resolveWcagTarget(spec, isHighContrast, !!outerExplicitHC),\n };\n }\n if ('apca' in spec) {\n const baseTarget = resolveApcaTarget(pickPair(spec.apca, isHighContrast));\n const innerExplicitHC = Array.isArray(spec.apca);\n const enhanced =\n isHighContrast && !outerExplicitHC && !innerExplicitHC\n ? Math.min(baseTarget + APCA_HC_ENHANCEMENT, APCA_MAX_LC)\n : baseTarget;\n return {\n metric: 'apca',\n target: enhanced,\n polarity: polarity ?? 'fg',\n };\n }\n const innerExplicitHC = Array.isArray(spec.wcag);\n const picked = pickPair(spec.wcag, isHighContrast);\n return {\n metric: 'wcag',\n target: resolveWcagTarget(\n picked,\n isHighContrast,\n !!outerExplicitHC || innerExplicitHC,\n ),\n };\n}\n\n// ============================================================================\n// APCA (SAPC / APCA-W3 0.1.9 simplified)\n// ============================================================================\n\nconst APCA_EXPONENTS = {\n mainTRC: 2.4,\n normBG: 0.56,\n normTXT: 0.57,\n revTXT: 0.62,\n revBG: 0.65,\n};\nconst APCA_BLACK_THRESH = 0.022;\nconst APCA_BLACK_CLIP = 1.414;\nconst APCA_DELTA_Y_MIN = 0.0005;\nconst APCA_SCALE = 1.14;\nconst APCA_LO_OFFSET = 0.027;\n\nfunction apcaSoftClamp(y: number): number {\n const yc = Math.max(0, y);\n if (yc >= APCA_BLACK_THRESH) return yc;\n return yc + Math.pow(APCA_BLACK_THRESH - yc, APCA_BLACK_CLIP);\n}\n\n/**\n * APCA lightness contrast (Lc), signed: positive for dark text on light bg,\n * negative for light text on dark bg. Inputs are screen luminances (0–1).\n */\nexport function apcaContrast(yText: number, yBg: number): number {\n const txt = apcaSoftClamp(yText);\n const bg = apcaSoftClamp(yBg);\n\n if (Math.abs(bg - txt) < APCA_DELTA_Y_MIN) return 0;\n\n let sapc: number;\n if (bg > txt) {\n // Normal polarity: dark text on light bg.\n sapc =\n (Math.pow(bg, APCA_EXPONENTS.normBG) -\n Math.pow(txt, APCA_EXPONENTS.normTXT)) *\n APCA_SCALE;\n return sapc < 0.1 ? 0 : (sapc - APCA_LO_OFFSET) * 100;\n }\n // Reverse polarity: light text on dark bg.\n sapc =\n (Math.pow(bg, APCA_EXPONENTS.revBG) -\n Math.pow(txt, APCA_EXPONENTS.revTXT)) *\n APCA_SCALE;\n return sapc > -0.1 ? 0 : (sapc + APCA_LO_OFFSET) * 100;\n}\n\n// ============================================================================\n// Tone -> luminance (cached)\n// ============================================================================\n\nconst CACHE_SIZE = 512;\nconst luminanceCache = new Map<string, number>();\nconst cacheOrder: string[] = [];\n\n/**\n * Luminance of an OKHST color `(h, s, t)` with t in 0–1 (reference eps), in\n * the metric's luminance basis. The metric is part of the cache key because\n * WCAG and APCA derive different luminances from the same color.\n */\nfunction cachedLuminance(\n metric: ContrastMetric,\n h: number,\n s: number,\n t: number,\n pastel: boolean,\n): number {\n const tRounded = Math.round(t * 10000) / 10000;\n const key = `${metric}|${h}|${s}|${tRounded}|${pastel}`;\n\n const cached = luminanceCache.get(key);\n if (cached !== undefined) return cached;\n\n const l = fromTone(tRounded * 100, REF_EPS);\n const linearRgb = okhslToLinearSrgb(h, s, l, pastel);\n const y = metricLuminance(metric, linearRgb);\n\n if (luminanceCache.size >= CACHE_SIZE) {\n const evict = cacheOrder.shift()!;\n luminanceCache.delete(evict);\n }\n luminanceCache.set(key, y);\n cacheOrder.push(key);\n\n return y;\n}\n\n// ============================================================================\n// Metric evaluation\n// ============================================================================\n\n/**\n * Score a candidate luminance against the base for a metric. Returns a value\n * that is `>= target` exactly when the floor is met (WCAG ratio, or APCA Lc\n * magnitude). For APCA, `polarity` selects the argument order: `'fg'` (the\n * default) treats the candidate as the text against a background base\n * (`apcaContrast(yCandidate, yBase)`); `'bg'` treats the candidate as the\n * background (`apcaContrast(yBase, yCandidate)`). The magnitude is taken\n * either way. WCAG is symmetric, so polarity is ignored there.\n */\nfunction metricScore(\n metric: 'wcag' | 'apca',\n yCandidate: number,\n yBase: number,\n polarity?: 'fg' | 'bg',\n): number {\n if (metric === 'wcag') return contrastRatioFromLuminance(yCandidate, yBase);\n const lc =\n polarity === 'bg'\n ? apcaContrast(yBase, yCandidate)\n : apcaContrast(yCandidate, yBase);\n return Math.abs(lc);\n}\n\n// ============================================================================\n// Solver\n// ============================================================================\n\nexport interface FindToneForContrastOptions {\n /** Hue of the candidate color (0–360). */\n hue: number;\n /** Saturation of the candidate color (0–1). */\n saturation: number;\n /** Preferred tone of the candidate (0–1). */\n preferredTone: number;\n\n /** Base/reference color as linear sRGB. */\n baseLinearRgb: LinearRgb;\n\n /** Resolved contrast floor (metric + target). */\n contrast: ResolvedContrast;\n\n /** Search bounds for tone. Default: [0, 1]. */\n toneRange?: [number, number];\n /** Convergence threshold. Default: 1e-4. */\n epsilon?: number;\n /** Maximum binary-search iterations per branch. Default: 18. */\n maxIterations?: number;\n /** Preferred search direction before auto-flip is considered. */\n initialDirection?: 'lighter' | 'darker';\n /** Auto-flip tone direction when contrast can't be met. Default: false. */\n flip?: boolean;\n /** Use the hue-independent \"safe\" chroma boundary. Default: false. */\n pastel?: boolean;\n}\n\nexport interface FindToneForContrastResult {\n /** Chosen tone in 0–1. */\n tone: number;\n /** Achieved score (WCAG ratio or APCA Lc magnitude). */\n contrast: number;\n /** Whether the target was reached. */\n met: boolean;\n /** Which branch was selected. */\n branch: 'lighter' | 'darker' | 'preferred';\n /** Whether the result auto-flipped to the opposite direction. */\n flipped?: boolean;\n}\n\n/**\n * Result of a single one-dimensional branch search. `pos` is the chosen\n * coordinate (tone or mix value depending on the caller's domain).\n */\ninterface BranchResult {\n pos: number;\n contrast: number;\n met: boolean;\n}\n\n/**\n * Binary search one branch `[lo, hi]` for the position nearest to `anchor`\n * that meets `target`. The domain is whatever `lum` interprets (tone 0–1 or\n * mix parameter 0–1); the search is identical in both cases.\n */\nfunction searchBranch(\n lum: (x: number) => number,\n lo: number,\n hi: number,\n yBase: number,\n metric: 'wcag' | 'apca',\n target: number,\n epsilon: number,\n maxIter: number,\n anchor: number,\n polarity?: 'fg' | 'bg',\n): BranchResult {\n const scoreLo = metricScore(metric, lum(lo), yBase, polarity);\n const scoreHi = metricScore(metric, lum(hi), yBase, polarity);\n\n if (scoreLo < target && scoreHi < target) {\n return scoreLo >= scoreHi\n ? { pos: lo, contrast: scoreLo, met: false }\n : { pos: hi, contrast: scoreHi, met: false };\n }\n\n let low = lo;\n let high = hi;\n\n for (let i = 0; i < maxIter; i++) {\n if (high - low < epsilon) break;\n const mid = (low + high) / 2;\n const scoreMid = metricScore(metric, lum(mid), yBase, polarity);\n\n if (scoreMid >= target) {\n if (mid < anchor) low = mid;\n else high = mid;\n } else {\n if (mid < anchor) high = mid;\n else low = mid;\n }\n }\n\n const scoreLow = metricScore(metric, lum(low), yBase, polarity);\n const scoreHigh = metricScore(metric, lum(high), yBase, polarity);\n const lowPasses = scoreLow >= target;\n const highPasses = scoreHigh >= target;\n\n if (lowPasses && highPasses) {\n return Math.abs(low - anchor) <= Math.abs(high - anchor)\n ? { pos: low, contrast: scoreLow, met: true }\n : { pos: high, contrast: scoreHigh, met: true };\n }\n if (lowPasses) return { pos: low, contrast: scoreLow, met: true };\n if (highPasses) return { pos: high, contrast: scoreHigh, met: true };\n\n return scoreLow >= scoreHigh\n ? { pos: low, contrast: scoreLow, met: false }\n : { pos: high, contrast: scoreHigh, met: false };\n}\n\n/**\n * Closed-form WCAG tone seed: the gray tone whose luminance produces exactly\n * the target ratio against the base, on the requested side. Used to bias the\n * preferred tone before the search so chromatic refinement starts close.\n */\nfunction wcagToneSeed(yBase: number, target: number, darker: boolean): number {\n const yTarget = darker\n ? (yBase + 0.05) / target - 0.05\n : target * (yBase + 0.05) - 0.05;\n const yClamped = Math.max(0, Math.min(1, yTarget));\n return Math.max(0, Math.min(1, toneFromY(yClamped, REF_EPS) / 100));\n}\n\n/**\n * Shared \"find the nearest passing position\" core for both the tone and mix\n * solvers. Both pick an initial direction within `[lo, hi]`, binary-search\n * that branch, optionally flip to the opposite branch, and pin to the\n * initial extreme on failure — they only differ in their domain and how the\n * branch boundary / luminance closure are built.\n *\n * `searchAnchor` biases the branch boundary and the in-branch tiebreak (the\n * WCAG seed for the tone solver; `preferred` otherwise). `distanceAnchor`\n * is the position the flip step measures closeness against (the original\n * preferred position, before any seed bias).\n */\ninterface SolveCoreOptions {\n lum: (x: number) => number;\n yBase: number;\n metric: 'wcag' | 'apca';\n target: number;\n searchTarget: number;\n lo: number;\n hi: number;\n /** Branch-boundary + in-branch tiebreak anchor. */\n searchAnchor: number;\n /** Position the flip step minimizes distance to. */\n distanceAnchor: number;\n epsilon: number;\n maxIterations: number;\n flip: boolean;\n /** Force the first branch ('lower' searches `[lo, anchor]`). */\n initialIsLower: boolean;\n /** APCA argument order; ignored for WCAG. Default `'fg'`. */\n polarity?: 'fg' | 'bg';\n}\n\ninterface SolveCoreResult {\n pos: number;\n contrast: number;\n met: boolean;\n /** Which branch produced the result. */\n lower: boolean;\n flipped?: boolean;\n}\n\nfunction solveNearestContrast(opts: SolveCoreOptions): SolveCoreResult {\n const {\n lum,\n yBase,\n metric,\n target,\n searchTarget,\n lo,\n hi,\n searchAnchor,\n distanceAnchor,\n epsilon,\n maxIterations,\n flip,\n initialIsLower,\n polarity,\n } = opts;\n\n const runBranch = (lower: boolean): BranchResult =>\n lower\n ? searchBranch(\n lum,\n lo,\n searchAnchor,\n yBase,\n metric,\n searchTarget,\n epsilon,\n maxIterations,\n searchAnchor,\n polarity,\n )\n : searchBranch(\n lum,\n searchAnchor,\n hi,\n yBase,\n metric,\n searchTarget,\n epsilon,\n maxIterations,\n searchAnchor,\n polarity,\n );\n\n const initialResult = runBranch(initialIsLower);\n initialResult.met = initialResult.contrast >= target;\n\n if (initialResult.met && !flip) {\n return { ...initialResult, lower: initialIsLower };\n }\n\n if (flip) {\n // The opposite branch exists only when `distanceAnchor` is strictly\n // interior on that side (matches the legacy canDarker/canUpper guards).\n const canOpposite = initialIsLower\n ? distanceAnchor < hi\n : distanceAnchor > lo;\n const oppositeResult = canOpposite ? runBranch(!initialIsLower) : null;\n if (oppositeResult) oppositeResult.met = oppositeResult.contrast >= target;\n\n if (initialResult.met && oppositeResult?.met) {\n const initialDist = Math.abs(initialResult.pos - distanceAnchor);\n const oppositeDist = Math.abs(oppositeResult.pos - distanceAnchor);\n return initialDist <= oppositeDist\n ? { ...initialResult, lower: initialIsLower }\n : { ...oppositeResult, lower: !initialIsLower, flipped: true };\n }\n if (initialResult.met) return { ...initialResult, lower: initialIsLower };\n if (oppositeResult?.met) {\n return { ...oppositeResult, lower: !initialIsLower, flipped: true };\n }\n }\n\n // Failure: pin to the initial direction's extreme.\n const extreme = initialIsLower ? lo : hi;\n const scoreExtreme = metricScore(metric, lum(extreme), yBase, polarity);\n return {\n pos: extreme,\n contrast: scoreExtreme,\n met: false,\n lower: initialIsLower,\n };\n}\n\n/**\n * Find the tone that satisfies a contrast floor against a base color,\n * staying as close to `preferredTone` as possible.\n */\nexport function findToneForContrast(\n options: FindToneForContrastOptions,\n): FindToneForContrastResult {\n const {\n hue,\n saturation,\n preferredTone,\n baseLinearRgb,\n contrast,\n toneRange = [0, 1],\n epsilon = 1e-4,\n maxIterations = 18,\n pastel = false,\n } = options;\n\n const { metric, target, polarity } = contrast;\n // Overshoot absorbs rounding in the OKHSL/OKLCH formatting pipeline.\n const searchTarget = metric === 'wcag' ? target * 1.01 : target + 0.5;\n const yBase = metricLuminance(metric, baseLinearRgb);\n\n // Luminance of a candidate at tone `t`.\n const lum = (t: number): number =>\n cachedLuminance(metric, hue, saturation, t, pastel);\n\n const scorePref = metricScore(metric, lum(preferredTone), yBase, polarity);\n\n if (scorePref >= searchTarget) {\n return {\n tone: preferredTone,\n contrast: scorePref,\n met: true,\n branch: 'preferred',\n };\n }\n\n const [minT, maxT] = toneRange;\n const canDarker = preferredTone > minT;\n const canLighter = preferredTone < maxT;\n\n let initialIsDarker: boolean;\n if (options.initialDirection !== undefined) {\n initialIsDarker = options.initialDirection === 'darker';\n } else if (canDarker && !canLighter) {\n initialIsDarker = true;\n } else if (!canDarker && canLighter) {\n initialIsDarker = false;\n } else if (!canDarker && !canLighter) {\n return {\n tone: preferredTone,\n contrast: scorePref,\n met: false,\n branch: 'preferred',\n };\n } else {\n const scoreMin = metricScore(metric, lum(minT), yBase, polarity);\n const scoreMax = metricScore(metric, lum(maxT), yBase, polarity);\n initialIsDarker = scoreMin >= scoreMax;\n }\n\n // For WCAG, bias the search start toward the closed-form seed (darker =\n // the \"lower\" branch). The flip step still measures distance against the\n // original `preferredTone`, not the seed.\n const searchAnchor =\n metric === 'wcag'\n ? clamp(\n initialIsDarker\n ? Math.min(preferredTone, wcagToneSeed(yBase, target, true))\n : Math.max(preferredTone, wcagToneSeed(yBase, target, false)),\n minT,\n maxT,\n )\n : preferredTone;\n\n const solved = solveNearestContrast({\n lum,\n yBase,\n metric,\n target,\n searchTarget,\n lo: minT,\n hi: maxT,\n searchAnchor,\n distanceAnchor: preferredTone,\n epsilon,\n maxIterations,\n flip: options.flip ?? false,\n initialIsLower: initialIsDarker,\n polarity,\n });\n\n return {\n tone: solved.pos,\n contrast: solved.contrast,\n met: solved.met,\n branch: solved.lower ? 'darker' : 'lighter',\n ...(solved.flipped ? { flipped: true } : {}),\n };\n}\n\n// ============================================================================\n// Mix contrast solver\n// ============================================================================\n\nexport interface FindValueForMixContrastOptions {\n /** Preferred mix parameter (0–1). */\n preferredValue: number;\n /** Base color as linear sRGB. */\n baseLinearRgb: LinearRgb;\n /** Target color as linear sRGB. */\n targetLinearRgb: LinearRgb;\n /** Resolved contrast floor (metric + target). */\n contrast: ResolvedContrast;\n /** Compute the luminance of the mixed color at parameter t. */\n luminanceAtValue: (t: number) => number;\n /** Convergence threshold. Default: 1e-4. */\n epsilon?: number;\n /** Maximum binary-search iterations per branch. Default: 20. */\n maxIterations?: number;\n /** Auto-flip mix direction when contrast can't be met. Default: false. */\n flip?: boolean;\n}\n\nexport interface FindValueForMixContrastResult {\n value: number;\n contrast: number;\n met: boolean;\n flipped?: boolean;\n}\n\n/**\n * Find the mix parameter (ratio or opacity) that satisfies a contrast floor\n * against a base color, staying as close to `preferredValue` as possible.\n */\nexport function findValueForMixContrast(\n options: FindValueForMixContrastOptions,\n): FindValueForMixContrastResult {\n const {\n preferredValue,\n baseLinearRgb,\n contrast,\n luminanceAtValue,\n epsilon = 1e-4,\n maxIterations = 20,\n } = options;\n\n const { metric, target, polarity } = contrast;\n const searchTarget = metric === 'wcag' ? target * 1.01 : target + 0.5;\n const yBase = metricLuminance(metric, baseLinearRgb);\n\n const scorePref = metricScore(\n metric,\n luminanceAtValue(preferredValue),\n yBase,\n polarity,\n );\n if (scorePref >= searchTarget) {\n return { value: preferredValue, contrast: scorePref, met: true };\n }\n\n const canLower = preferredValue > 0;\n const canUpper = preferredValue < 1;\n let initialIsLower: boolean;\n if (canLower && !canUpper) {\n initialIsLower = true;\n } else if (!canLower && canUpper) {\n initialIsLower = false;\n } else if (!canLower && !canUpper) {\n return { value: preferredValue, contrast: scorePref, met: false };\n } else {\n const scoreLower = metricScore(\n metric,\n luminanceAtValue(0),\n yBase,\n polarity,\n );\n const scoreUpper = metricScore(\n metric,\n luminanceAtValue(1),\n yBase,\n polarity,\n );\n initialIsLower = scoreLower >= scoreUpper;\n }\n\n const solved = solveNearestContrast({\n lum: luminanceAtValue,\n yBase,\n metric,\n target,\n searchTarget,\n lo: 0,\n hi: 1,\n searchAnchor: preferredValue,\n distanceAnchor: preferredValue,\n epsilon,\n maxIterations,\n flip: options.flip ?? false,\n initialIsLower,\n polarity,\n });\n\n return {\n value: solved.pos,\n contrast: solved.contrast,\n met: solved.met,\n ...(solved.flipped ? { flipped: true } : {}),\n };\n}\n","/**\n * Semantic color role resolution.\n *\n * A `role` fixes APCA contrast polarity (which side is the foreground vs the\n * background). Roles are resolved per color via a four-step chain (see\n * `resolveRole`): explicit `def.role` → name inference → opposite of the\n * base's role → `'text'` foreground default.\n *\n * This module owns the alias keyword sets, name tokenization, and the\n * role → polarity / opposite-role mappings. It has no dependencies.\n */\n\nimport type { Role, RoleInput } from './types';\n\n// ============================================================================\n// Keyword sets\n// ============================================================================\n\nconst SURFACE_KEYWORDS = new Set([\n 'surface',\n 'bg',\n 'background',\n 'fill',\n 'canvas',\n 'paper',\n 'layer',\n]);\n\nconst TEXT_KEYWORDS = new Set([\n 'text',\n 'fg',\n 'foreground',\n 'content',\n 'ink',\n 'label',\n 'stroke',\n]);\n\nconst BORDER_KEYWORDS = new Set([\n 'border',\n 'divider',\n 'outline',\n 'separator',\n 'hairline',\n 'rule',\n]);\n\nconst ALIAS_TO_ROLE: Record<string, Role> = {\n // surface\n surface: 'surface',\n bg: 'surface',\n background: 'surface',\n fill: 'surface',\n canvas: 'surface',\n paper: 'surface',\n layer: 'surface',\n // text\n text: 'text',\n fg: 'text',\n foreground: 'text',\n content: 'text',\n ink: 'text',\n label: 'text',\n stroke: 'text',\n // border\n border: 'border',\n divider: 'border',\n outline: 'border',\n separator: 'border',\n hairline: 'border',\n rule: 'border',\n};\n\n// ============================================================================\n// Normalization\n// ============================================================================\n\n/**\n * Normalize a `RoleInput` (canonical value or alias) into a canonical `Role`.\n * Returns `undefined` for unrecognized strings so callers can fall through to\n * the next step of the resolution chain.\n */\nexport function normalizeRole(input: RoleInput | undefined): Role | undefined {\n if (input === undefined) return undefined;\n return ALIAS_TO_ROLE[input];\n}\n\n// ============================================================================\n// Name inference\n// ============================================================================\n\n/**\n * Tokenize a color name into lowercase keyword tokens, splitting on\n * non-alphanumeric boundaries and at camelCase boundaries. Examples:\n * - `'button-text'` → `['button', 'text']`\n * - `'inputBg'` → `['input', 'bg']`\n * - `'card_border-outline'` → `['card', 'border', 'outline']`\n */\nfunction tokenizeName(name: string): string[] {\n // Split on non-alphanumeric, then split camelCase within each piece.\n const pieces = name.split(/[^0-9a-zA-Z]+/).filter(Boolean);\n const tokens: string[] = [];\n for (const piece of pieces) {\n // Split at the boundary between a lowercase/digit run and an uppercase\n // letter (camelCase humps), e.g. \"inputBg\" → [\"input\", \"Bg\"].\n const sub = piece\n .replace(/([a-z0-9])([A-Z])/g, '$1 $2')\n .split(/\\s+/)\n .filter(Boolean);\n for (const s of sub) tokens.push(s.toLowerCase());\n }\n return tokens;\n}\n\n/**\n * Infer a `Role` from a color name by matching its tokens against the role\n * keyword sets. When multiple tokens match, the **last** recognized token\n * wins (so `button-text` → `text`, `input-bg` → `surface`, `card-border` →\n * `border`). Returns `undefined` when no token matches.\n */\nexport function inferRoleFromName(name: string): Role | undefined {\n const tokens = tokenizeName(name);\n let inferred: Role | undefined;\n for (const token of tokens) {\n if (SURFACE_KEYWORDS.has(token)) inferred = 'surface';\n else if (TEXT_KEYWORDS.has(token)) inferred = 'text';\n else if (BORDER_KEYWORDS.has(token)) inferred = 'border';\n }\n return inferred;\n}\n\n// ============================================================================\n// Polarity + opposites\n// ============================================================================\n\n/** APCA argument order: which side the resolved color plays. */\nexport type Polarity = 'fg' | 'bg';\n\n/**\n * Map a role to its APCA polarity. `text` and `border` are foreground spots\n * against their base (the candidate is the text argument); `surface` is the\n * background (the base is the text argument).\n */\nexport function roleToPolarity(role: Role): Polarity {\n return role === 'surface' ? 'bg' : 'fg';\n}\n\n/**\n * The opposite role of `role`, used when a color with no explicit role and no\n * inferable name depends on a base: the dependent color plays the opposite\n * role of its base. `surface` ↔ `text`; `border` is treated as a foreground\n * spot, so its opposite is `surface`.\n */\nexport function oppositeRole(role: Role): Role {\n if (role === 'surface') return 'text';\n return 'surface';\n}\n","/**\n * Shadow color computation.\n *\n * Owns the shadow / mix def predicates, default tuning constants, the\n * tuning merge, and the actual `computeShadow` math (hue blend,\n * saturation cap, lightness clamp, alpha curve). The resolver consumes\n * this module per scheme variant.\n */\n\nimport { clamp } from './hc-pair';\nimport type {\n ColorDef,\n MixColorDef,\n ShadowColorDef,\n ShadowTuning,\n} from './types';\n\n/**\n * OKHSL-lightness variant shape used by the shadow math. The resolver\n * converts the OKHST-stored variants to this shape at the shadow edge.\n */\nexport interface OkhslShadowVariant {\n h: number;\n s: number;\n l: number;\n alpha: number;\n}\n\nexport function isShadowDef(def: ColorDef): def is ShadowColorDef {\n return (def as ShadowColorDef).type === 'shadow';\n}\n\nexport function isMixDef(def: ColorDef): def is MixColorDef {\n return (def as MixColorDef).type === 'mix';\n}\n\nexport const DEFAULT_SHADOW_TUNING: Required<ShadowTuning> = {\n saturationFactor: 0.18,\n maxSaturation: 0.25,\n lightnessFactor: 0.25,\n lightnessBounds: [0.05, 0.2],\n minGapTarget: 0.05,\n alphaMax: 1.0,\n bgHueBlend: 0.2,\n};\n\nexport function resolveShadowTuning(\n perColor?: ShadowTuning,\n globalTuning?: ShadowTuning,\n): Required<ShadowTuning> {\n return {\n ...DEFAULT_SHADOW_TUNING,\n ...globalTuning,\n ...perColor,\n lightnessBounds:\n perColor?.lightnessBounds ??\n globalTuning?.lightnessBounds ??\n DEFAULT_SHADOW_TUNING.lightnessBounds,\n };\n}\n\nexport function circularLerp(a: number, b: number, t: number): number {\n let diff = b - a;\n if (diff > 180) diff -= 360;\n else if (diff < -180) diff += 360;\n return (((a + diff * t) % 360) + 360) % 360;\n}\n\n/**\n * Compute the canonical max-contrast reference t value for normalization.\n * Uses bg.l=1, fg.l=0, intensity=100 — the theoretical maximum.\n * This is a fixed constant per tuning configuration, ensuring uniform\n * scaling across all bg/fg pairs at low intensities.\n */\nfunction computeRefT(tuning: Required<ShadowTuning>): number {\n const EPSILON = 1e-6;\n let lShRef = clamp(\n tuning.lightnessFactor,\n tuning.lightnessBounds[0],\n tuning.lightnessBounds[1],\n );\n lShRef = Math.max(Math.min(lShRef, 1 - tuning.minGapTarget), 0);\n const gapRef = Math.max(1 - lShRef, EPSILON);\n return 1 / gapRef;\n}\n\nexport function computeShadow(\n bg: OkhslShadowVariant,\n fg: OkhslShadowVariant | undefined,\n intensity: number,\n tuning: Required<ShadowTuning>,\n): OkhslShadowVariant {\n const EPSILON = 1e-6;\n const clampedIntensity = clamp(intensity, 0, 100);\n const contrastWeight = fg ? Math.abs(bg.l - fg.l) : 1;\n const deltaL = (clampedIntensity / 100) * contrastWeight;\n\n const h = fg ? circularLerp(fg.h, bg.h, tuning.bgHueBlend) : bg.h;\n const s = fg\n ? Math.min(fg.s * tuning.saturationFactor, tuning.maxSaturation)\n : 0;\n\n let lSh = clamp(\n bg.l * tuning.lightnessFactor,\n tuning.lightnessBounds[0],\n tuning.lightnessBounds[1],\n );\n lSh = Math.max(Math.min(lSh, bg.l - tuning.minGapTarget), 0);\n\n const gap = Math.max(bg.l - lSh, EPSILON);\n const t = deltaL / gap;\n\n const tRef = computeRefT(tuning);\n const norm = Math.tanh(tRef / tuning.alphaMax);\n const alpha = Math.min(\n (tuning.alphaMax * Math.tanh(t / tuning.alphaMax)) / norm,\n tuning.alphaMax,\n );\n\n return { h, s, l: lSh, alpha };\n}\n","/**\n * Color graph validation and topological sort.\n *\n * `validateColorDefs` rejects bad references (missing / shadow-referencing /\n * base/contrast/tone mismatches) and detects cycles before the\n * resolver runs. `topoSort` orders defs so each color is processed after\n * its base / bg / fg / target dependencies.\n */\n\nimport { isAbsoluteTone } from './hc-pair';\nimport { isMixDef, isShadowDef } from './shadow';\nimport type { ColorMap, RegularColorDef, ResolvedColor } from './types';\n\nexport function validateColorDefs(\n defs: ColorMap,\n externalBases?: Map<string, ResolvedColor>,\n): void {\n const localNames = new Set(Object.keys(defs));\n const allNames = new Set([\n ...localNames,\n ...(externalBases ? externalBases.keys() : []),\n ]);\n\n for (const [name, def] of Object.entries(defs)) {\n if (isShadowDef(def)) {\n if (!allNames.has(def.bg)) {\n throw new Error(\n `glaze: shadow \"${name}\" references non-existent bg \"${def.bg}\".`,\n );\n }\n if (localNames.has(def.bg) && isShadowDef(defs[def.bg])) {\n throw new Error(\n `glaze: shadow \"${name}\" bg \"${def.bg}\" references another shadow color.`,\n );\n }\n if (def.fg !== undefined) {\n if (!allNames.has(def.fg)) {\n throw new Error(\n `glaze: shadow \"${name}\" references non-existent fg \"${def.fg}\".`,\n );\n }\n if (localNames.has(def.fg) && isShadowDef(defs[def.fg])) {\n throw new Error(\n `glaze: shadow \"${name}\" fg \"${def.fg}\" references another shadow color.`,\n );\n }\n }\n continue;\n }\n\n if (isMixDef(def)) {\n if (!allNames.has(def.base)) {\n throw new Error(\n `glaze: mix \"${name}\" references non-existent base \"${def.base}\".`,\n );\n }\n if (!allNames.has(def.target)) {\n throw new Error(\n `glaze: mix \"${name}\" references non-existent target \"${def.target}\".`,\n );\n }\n if (localNames.has(def.base) && isShadowDef(defs[def.base])) {\n throw new Error(\n `glaze: mix \"${name}\" base \"${def.base}\" references a shadow color.`,\n );\n }\n if (localNames.has(def.target) && isShadowDef(defs[def.target])) {\n throw new Error(\n `glaze: mix \"${name}\" target \"${def.target}\" references a shadow color.`,\n );\n }\n continue;\n }\n\n const regDef = def as RegularColorDef;\n\n if (regDef.contrast !== undefined && !regDef.base) {\n throw new Error(`glaze: color \"${name}\" has \"contrast\" without \"base\".`);\n }\n\n if (\n regDef.tone !== undefined &&\n !isAbsoluteTone(regDef.tone) &&\n !regDef.base\n ) {\n throw new Error(\n `glaze: color \"${name}\" has relative \"tone\" without \"base\".`,\n );\n }\n\n if (regDef.base && !allNames.has(regDef.base)) {\n throw new Error(\n `glaze: color \"${name}\" references non-existent base \"${regDef.base}\".`,\n );\n }\n\n if (\n regDef.base &&\n localNames.has(regDef.base) &&\n isShadowDef(defs[regDef.base])\n ) {\n throw new Error(\n `glaze: color \"${name}\" base \"${regDef.base}\" references a shadow color.`,\n );\n }\n\n if (!isAbsoluteTone(regDef.tone) && regDef.base === undefined) {\n throw new Error(\n `glaze: color \"${name}\" must have either absolute \"tone\" (root) or \"base\" (dependent).`,\n );\n }\n\n if (regDef.contrast !== undefined && regDef.opacity !== undefined) {\n console.warn(\n `glaze: color \"${name}\" has both \"contrast\" and \"opacity\". Opacity makes perceived tone unpredictable.`,\n );\n }\n }\n\n // Check for circular references (follows base, bg, fg edges).\n // External bases are leaves (no outgoing edges in `defs`), so they can't\n // form a cycle and we short-circuit there.\n const visited = new Set<string>();\n const inStack = new Set<string>();\n\n function dfs(name: string): void {\n if (!localNames.has(name)) return;\n if (inStack.has(name)) {\n throw new Error(\n `glaze: circular base reference detected involving \"${name}\".`,\n );\n }\n if (visited.has(name)) return;\n\n inStack.add(name);\n const def = defs[name];\n if (isShadowDef(def)) {\n dfs(def.bg);\n if (def.fg) dfs(def.fg);\n } else if (isMixDef(def)) {\n dfs(def.base);\n dfs(def.target);\n } else {\n const regDef = def as RegularColorDef;\n if (regDef.base) {\n dfs(regDef.base);\n }\n }\n inStack.delete(name);\n visited.add(name);\n }\n\n for (const name of localNames) {\n dfs(name);\n }\n}\n\nexport function topoSort(defs: ColorMap): string[] {\n const result: string[] = [];\n const visited = new Set<string>();\n\n function visit(name: string): void {\n if (visited.has(name)) return;\n visited.add(name);\n\n const def = defs[name];\n // External base references (not in `defs`) are leaves — they're already\n // pre-seeded into `ctx.resolved` and don't participate in the local sort.\n if (def === undefined) return;\n if (isShadowDef(def)) {\n visit(def.bg);\n if (def.fg) visit(def.fg);\n } else if (isMixDef(def)) {\n visit(def.base);\n visit(def.target);\n } else {\n const regDef = def as RegularColorDef;\n if (regDef.base) {\n visit(regDef.base);\n }\n }\n\n result.push(name);\n }\n\n for (const name of Object.keys(defs)) {\n visit(name);\n }\n\n return result;\n}\n","/**\n * Contrast-warning dispatcher.\n *\n * Tokens memoize their resolution, but a long-lived process (e.g. a dev\n * server with HMR) can re-resolve the same theme many times. The cache\n * here dedupes warnings within a session with a soft cap to keep noise\n * bounded.\n */\n\nimport { apcaContrast } from './contrast-solver';\nimport type { ResolvedContrast } from './contrast-solver';\nimport { contrastRatioFromLuminance } from './okhsl-color-math';\n\nconst CONTRAST_WARN_CACHE_LIMIT = 256;\nconst contrastWarnCache = new Set<string>();\n\n/**\n * Slack factor below the requested target before we emit a warning.\n * The contrast solver overshoots to absorb rounding noise, so an actual\n * value within ~2x that overshoot is effectively a pass.\n */\nconst CONTRAST_WARN_SLACK_WCAG = 0.98;\n/** APCA Lc is on a 0–106 scale; allow a small absolute slack. */\nconst CONTRAST_WARN_SLACK_APCA = 1.5;\n\nfunction schemeLabel(isDark: boolean, isHighContrast: boolean): string {\n if (isDark && isHighContrast) return 'darkContrast';\n if (isDark) return 'dark';\n if (isHighContrast) return 'lightContrast';\n return 'light';\n}\n\nfunction metricLabel(c: ResolvedContrast): string {\n return c.metric === 'apca'\n ? `APCA Lc ${c.target.toFixed(1)}`\n : `WCAG ${c.target.toFixed(2)}`;\n}\n\nfunction dedupe(key: string): boolean {\n if (contrastWarnCache.has(key)) return true;\n if (contrastWarnCache.size >= CONTRAST_WARN_CACHE_LIMIT) {\n contrastWarnCache.clear();\n }\n contrastWarnCache.add(key);\n return false;\n}\n\n/** Warn when the solver could not reach the requested contrast floor. */\nexport function warnContrastUnmet(\n name: string,\n isDark: boolean,\n isHighContrast: boolean,\n contrast: ResolvedContrast,\n actual: number,\n): void {\n const slack =\n contrast.metric === 'apca'\n ? contrast.target - CONTRAST_WARN_SLACK_APCA\n : contrast.target * CONTRAST_WARN_SLACK_WCAG;\n if (actual >= slack) return;\n\n const scheme = schemeLabel(isDark, isHighContrast);\n const key = `unmet|${name}|${scheme}|${contrast.metric}|${contrast.target.toFixed(\n 2,\n )}|${actual.toFixed(2)}`;\n if (dedupe(key)) return;\n\n console.warn(\n `glaze: color \"${name}\" cannot meet ${metricLabel(contrast)} in ` +\n `${scheme} scheme (got ${actual.toFixed(2)}). ` +\n `Try widening the tone window, lowering the contrast target, ` +\n `or picking a base color further from this color's tone.`,\n );\n}\n\n/**\n * Verification (§10): a chromatic swatch inherits the gray tone's\n * lightness but drifts in real luminance, so a contrast-floored color may\n * land slightly under the contrast its tone implies. Emit an advisory\n * warning when the actual measured contrast drifts below the target.\n */\nexport function warnContrastDrift(\n name: string,\n isDark: boolean,\n isHighContrast: boolean,\n contrast: ResolvedContrast,\n yColor: number,\n yBase: number,\n): void {\n const actual =\n contrast.metric === 'apca'\n ? Math.abs(\n contrast.polarity === 'bg'\n ? apcaContrast(yBase, yColor)\n : apcaContrast(yColor, yBase),\n )\n : contrastRatioFromLuminance(yColor, yBase);\n\n const slack =\n contrast.metric === 'apca'\n ? contrast.target - CONTRAST_WARN_SLACK_APCA\n : contrast.target * CONTRAST_WARN_SLACK_WCAG;\n if (actual >= slack) return;\n\n const scheme = schemeLabel(isDark, isHighContrast);\n const key = `drift|${name}|${scheme}|${contrast.metric}|${contrast.target.toFixed(\n 2,\n )}|${actual.toFixed(2)}`;\n if (dedupe(key)) return;\n\n console.warn(\n `glaze: color \"${name}\" drifts below ${metricLabel(contrast)} in ` +\n `${scheme} scheme (measured ${actual.toFixed(2)}). Chromatic luminance ` +\n `differs from the gray tone; nudge the tone or saturation if the floor matters.`,\n );\n}\n","/**\n * Color resolution engine.\n *\n * Runs the four-pass solver (light → light-HC → dark → dark-HC) that\n * turns a `ColorMap` into a fully resolved `ResolvedColor` per name.\n * Owns the per-scheme resolve helpers for regular, shadow, and mix\n * color defs.\n *\n * Variants are stored in OKHST: `h` / `s` are OKHSL hue/saturation and\n * `t` is the canonical contrast-uniform tone (0–1, reference eps). The\n * resolver works in tone for regular colors and converts to/from OKHSL\n * lightness only at the mix/shadow and luminance edges.\n *\n * Every function receives a single `GlazeConfigResolved` so the full\n * per-instance config (including overrides) is available without\n * re-reading the global singleton mid-resolve.\n */\n\nimport {\n okhslToLinearSrgb,\n sRGBLinearToGamma,\n srgbToOkhsl,\n} from './okhsl-color-math';\nimport {\n findToneForContrast,\n findValueForMixContrast,\n metricLuminance,\n resolveContrastForMode,\n} from './contrast-solver';\nimport type { LinearRgb, ResolvedContrast } from './contrast-solver';\nimport {\n clamp,\n isAbsoluteTone,\n pairHC,\n pairNormal,\n parseToneValue,\n resolveEffectiveHue,\n} from './hc-pair';\nimport {\n inferRoleFromName,\n normalizeRole,\n oppositeRole,\n roleToPolarity,\n} from './roles';\nimport {\n computeShadow,\n circularLerp,\n isMixDef,\n isShadowDef,\n resolveShadowTuning,\n} from './shadow';\nimport {\n fromTone,\n mapSaturationDark,\n mapToneForScheme,\n okhslToOkhst,\n schemeToneRange,\n toTone,\n variantToOkhsl,\n} from './okhst';\nimport { topoSort, validateColorDefs } from './validation';\nimport { warnContrastUnmet, warnContrastDrift } from './warnings';\nimport type {\n AdaptationMode,\n ColorDef,\n ColorMap,\n ContrastSpec,\n GlazeConfigResolved,\n HCPair,\n MixColorDef,\n RegularColorDef,\n ResolvedColor,\n ResolvedColorVariant,\n Role,\n ShadowColorDef,\n} from './types';\n\nexport interface ResolveContext {\n hue: number;\n saturation: number;\n defs: ColorMap;\n resolved: Map<string, ResolvedColor>;\n /** Fully-merged effective config for this resolve pass. */\n config: GlazeConfigResolved;\n /** Per-name role memo (filled lazily by `resolveRole`). */\n roles: Map<string, Role>;\n}\n\ntype ResolvedField = 'light' | 'dark' | 'lightContrast' | 'darkContrast';\n\n/** An OKHSL-lightness-shaped variant used at the mix/shadow edge. */\ninterface OkhslVariant {\n h: number;\n s: number;\n l: number;\n alpha: number;\n /** Carried from the resolved variant so edge conversions reuse the right gamut. */\n pastel?: boolean;\n}\n\nexport function getSchemeVariant(\n color: ResolvedColor,\n isDark: boolean,\n isHighContrast: boolean,\n): ResolvedColorVariant {\n if (isDark && isHighContrast) return color.darkContrast;\n if (isDark) return color.dark;\n if (isHighContrast) return color.lightContrast;\n return color.light;\n}\n\n/** Edge adapter: resolved variant (`t`) → OKHSL-lightness variant. */\nfunction toOkhslVariant(v: ResolvedColorVariant): OkhslVariant {\n const c = variantToOkhsl(v);\n return { h: c.h, s: c.s, l: c.l, alpha: v.alpha, pastel: v.pastel };\n}\n\n/** Edge adapter: OKHSL-lightness variant → resolved variant (`t`). */\nfunction toToneVariant(v: OkhslVariant): ResolvedColorVariant {\n const c = okhslToOkhst({ h: v.h, s: v.s, l: v.l });\n return { h: c.h, s: c.s, t: c.t, alpha: v.alpha };\n}\n\n// ============================================================================\n// Role resolution\n// ============================================================================\n\n/**\n * Resolve the role of a base color referenced by `baseName`, returning the\n * role the *dependent* color should take (the opposite of the base's role).\n * A base that lives in `defs` recursively resolves and is inverted via\n * `oppositeRole`; an external base (no local def, e.g. an injected standalone\n * token) is treated as a background, so the dependent defaults to foreground\n * (`'text'`).\n */\nfunction resolveBaseRoleInMap(\n baseName: string | undefined,\n defs: ColorMap,\n inferRole: boolean,\n roles: Map<string, Role>,\n): Role | undefined {\n if (!baseName) return undefined;\n const baseDef = defs[baseName];\n if (!baseDef) return 'text';\n return oppositeRole(\n resolveRoleInMap(baseName, baseDef, defs, inferRole, roles),\n );\n}\n\n/**\n * Role-resolution core that does not need a full `ResolveContext`. Shared by\n * the resolver (via `resolveRole`) and `verifyContrastDrift`.\n */\nfunction resolveRoleInMap(\n name: string,\n def: ColorDef,\n defs: ColorMap,\n inferRole: boolean,\n roles: Map<string, Role>,\n): Role {\n const cached = roles.get(name);\n if (cached) return cached;\n\n let role: Role | undefined;\n if (isShadowDef(def)) {\n role = 'surface';\n } else if (isMixDef(def)) {\n role =\n normalizeRole(def.role) ??\n (inferRole ? inferRoleFromName(name) : undefined) ??\n resolveBaseRoleInMap(def.base, defs, inferRole, roles) ??\n 'text';\n } else {\n const regDef = def as RegularColorDef;\n role =\n normalizeRole(regDef.role) ??\n (inferRole ? inferRoleFromName(name) : undefined) ??\n resolveBaseRoleInMap(regDef.base, defs, inferRole, roles) ??\n 'text';\n }\n\n const finalRole = role ?? 'text';\n roles.set(name, finalRole);\n return finalRole;\n}\n\n/**\n * Resolve a color's semantic `role` (text / surface / border) per the chain:\n * 1. explicit `def.role` (normalized)\n * 2. inferred from the color name when `config.inferRole` is on\n * 3. opposite of the base's role\n * 4. `'text'` (foreground) default\n *\n * Memoized on `ctx.roles` so the four scheme passes share one resolution.\n * Shadows have no contrast participation and default to `'surface'`.\n */\nfunction resolveRole(name: string, def: ColorDef, ctx: ResolveContext): Role {\n return resolveRoleInMap(name, def, ctx.defs, ctx.config.inferRole, ctx.roles);\n}\n\nfunction resolveContrastSpec(\n spec: HCPair<ContrastSpec>,\n isHighContrast: boolean,\n polarity?: 'fg' | 'bg',\n): ResolvedContrast {\n const outerExplicitHC = Array.isArray(spec);\n const outer = isHighContrast ? pairHC(spec) : pairNormal(spec);\n return resolveContrastForMode(\n outer,\n isHighContrast,\n polarity,\n outerExplicitHC,\n );\n}\n\n/**\n * Apply the relative-tone delta against a base, honoring `flip`.\n *\n * When `flip` is on and `base + delta` falls outside `[0, 100]`, try mirroring\n * the delta to the other side of the base. If the mirrored target is also out\n * of range, keep the original delta so the caller clamps on the authored side.\n * When off, the caller clamps as usual.\n */\nfunction applyToneFlip(delta: number, baseTone: number, flip: boolean): number {\n if (!flip) return delta;\n const target = baseTone + delta;\n if (target >= 0 && target <= 100) return delta;\n const mirrored = baseTone - delta;\n if (mirrored >= 0 && mirrored <= 100) return -delta;\n return delta;\n}\n\nfunction resolveRootColor(\n def: RegularColorDef,\n isHighContrast: boolean,\n): { authorTone: number; satFactor: number } {\n const rawT = def.tone!;\n const rawValue = isHighContrast ? pairHC(rawT) : pairNormal(rawT);\n // Root tone is absolute or extreme ('max' = 100, 'min' = 0); both flow\n // through mapToneForScheme (and invert in dark under mode 'auto').\n const parsed = parseToneValue(rawValue);\n const authorTone = clamp(parsed.value, 0, 100);\n const satFactor = clamp(def.saturation ?? 1, 0, 1);\n return { authorTone, satFactor };\n}\n\nfunction resolveDependentColor(\n name: string,\n def: RegularColorDef,\n ctx: ResolveContext,\n isHighContrast: boolean,\n isDark: boolean,\n effectiveHue: number,\n polarity: 'fg' | 'bg',\n effectivePastel: boolean,\n): { tone: number; satFactor: number } {\n const baseName = def.base!;\n const baseResolved = ctx.resolved.get(baseName);\n if (!baseResolved) {\n throw new Error(\n `glaze: base \"${baseName}\" not yet resolved for \"${name}\".`,\n );\n }\n\n const mode = def.mode ?? 'auto';\n const satFactor = clamp(def.saturation ?? 1, 0, 1);\n const flip = def.autoFlip ?? ctx.config.autoFlip;\n const pastel = effectivePastel;\n\n const baseVariant = getSchemeVariant(baseResolved, isDark, isHighContrast);\n const baseTone = baseVariant.t * 100;\n\n let preferredTone: number;\n const rawTone = def.tone;\n\n if (rawTone === undefined) {\n preferredTone = baseTone;\n } else {\n const rawValue = isHighContrast ? pairHC(rawTone) : pairNormal(rawTone);\n const parsed = parseToneValue(rawValue);\n\n if (parsed.kind === 'relative') {\n if (isDark && mode === 'auto') {\n const baseLightVariant = getSchemeVariant(\n baseResolved,\n false,\n isHighContrast,\n );\n const baseLightTone = baseLightVariant.t * 100;\n const absoluteLightTone = clamp(\n baseLightTone + applyToneFlip(parsed.value, baseLightTone, flip),\n 0,\n 100,\n );\n // Invert + remap the base-anchored light tone into the dark window,\n // exactly like an absolute author tone under `mode: 'auto'`.\n preferredTone = mapToneForScheme(\n absoluteLightTone,\n 'auto',\n true,\n isHighContrast,\n ctx.config,\n );\n } else {\n const delta = applyToneFlip(parsed.value, baseTone, flip);\n preferredTone = clamp(baseTone + delta, 0, 100);\n }\n } else {\n // Absolute or extreme ('max' = 100, 'min' = 0): map through the scheme.\n preferredTone = mapToneForScheme(\n parsed.value,\n mode,\n isDark,\n isHighContrast,\n ctx.config,\n );\n }\n }\n\n const rawContrast = def.contrast;\n if (rawContrast !== undefined) {\n const resolvedContrast = resolveContrastSpec(\n rawContrast,\n isHighContrast,\n polarity,\n );\n\n const effectiveSat = isDark\n ? mapSaturationDark((satFactor * ctx.saturation) / 100, mode, ctx.config)\n : (satFactor * ctx.saturation) / 100;\n\n const baseOkhsl = toOkhslVariant(baseVariant);\n const baseLinearRgb = okhslToLinearSrgb(\n baseOkhsl.h,\n baseOkhsl.s,\n baseOkhsl.l,\n baseVariant.pastel ?? ctx.config.pastel,\n );\n\n const toneRange = schemeToneRange(isDark, mode, isHighContrast, ctx.config);\n\n let initialDirection: 'lighter' | 'darker' | undefined;\n if (preferredTone < baseTone) {\n initialDirection = 'darker';\n } else if (preferredTone > baseTone) {\n initialDirection = 'lighter';\n }\n\n const result = findToneForContrast({\n hue: effectiveHue,\n saturation: effectiveSat,\n preferredTone: clamp(preferredTone / 100, toneRange[0], toneRange[1]),\n baseLinearRgb,\n contrast: resolvedContrast,\n toneRange: [0, 1],\n initialDirection,\n flip,\n pastel,\n });\n\n if (!result.met) {\n warnContrastUnmet(\n name,\n isDark,\n isHighContrast,\n resolvedContrast,\n result.contrast,\n );\n }\n\n return { tone: result.tone * 100, satFactor };\n }\n\n return { tone: clamp(preferredTone, 0, 100), satFactor };\n}\n\nfunction resolveColorForScheme(\n name: string,\n def: ColorDef,\n ctx: ResolveContext,\n isDark: boolean,\n isHighContrast: boolean,\n): ResolvedColorVariant {\n if (isShadowDef(def)) {\n return resolveShadowForScheme(def, ctx, isDark, isHighContrast);\n }\n\n if (isMixDef(def)) {\n return resolveMixForScheme(name, def, ctx, isDark, isHighContrast);\n }\n\n const regDef = def as RegularColorDef;\n const mode = regDef.mode ?? 'auto';\n const isRoot = isAbsoluteTone(regDef.tone) && !regDef.base;\n const effectiveHue = resolveEffectiveHue(ctx.hue, regDef.hue);\n const role = resolveRole(name, def, ctx);\n const polarity = roleToPolarity(role);\n const pastel = regDef.pastel ?? ctx.config.pastel;\n\n let finalTone: number;\n let satFactor: number;\n\n if (isRoot) {\n const root = resolveRootColor(regDef, isHighContrast);\n finalTone = mapToneForScheme(\n root.authorTone,\n mode,\n isDark,\n isHighContrast,\n ctx.config,\n );\n satFactor = root.satFactor;\n } else {\n const dep = resolveDependentColor(\n name,\n regDef,\n ctx,\n isHighContrast,\n isDark,\n effectiveHue,\n polarity,\n pastel,\n );\n finalTone = dep.tone;\n satFactor = dep.satFactor;\n }\n\n const baseSat = (satFactor * ctx.saturation) / 100;\n const finalSat = isDark\n ? mapSaturationDark(baseSat, mode, ctx.config)\n : baseSat;\n\n const toneFraction = clamp(finalTone / 100, 0, 1);\n\n return {\n h: effectiveHue,\n s: clamp(finalSat, 0, 1),\n t: toneFraction,\n alpha: regDef.opacity ?? 1,\n pastel,\n };\n}\n\nfunction resolveShadowForScheme(\n def: ShadowColorDef,\n ctx: ResolveContext,\n isDark: boolean,\n isHighContrast: boolean,\n): ResolvedColorVariant {\n const bgResolved = ctx.resolved.get(def.bg)!;\n const bgVariant = toOkhslVariant(\n getSchemeVariant(bgResolved, isDark, isHighContrast),\n );\n\n let fgVariant: OkhslVariant | undefined;\n if (def.fg) {\n const fgResolved = ctx.resolved.get(def.fg)!;\n fgVariant = toOkhslVariant(\n getSchemeVariant(fgResolved, isDark, isHighContrast),\n );\n }\n\n const intensity = isHighContrast\n ? pairHC(def.intensity)\n : pairNormal(def.intensity);\n\n const tuning = resolveShadowTuning(def.tuning, ctx.config.shadowTuning);\n return {\n ...toToneVariant(computeShadow(bgVariant, fgVariant, intensity, tuning)),\n pastel: def.pastel ?? ctx.config.pastel,\n };\n}\n\nfunction okhslVariantToLinearRgb(v: OkhslVariant, pastel: boolean): LinearRgb {\n return okhslToLinearSrgb(v.h, v.s, v.l, pastel);\n}\n\n/**\n * Resolve hue for OKHSL mixing, handling achromatic colors.\n * When one color has no saturation, its hue is meaningless —\n * use the hue from the color that has saturation (matches CSS\n * color-mix \"missing component\" behavior).\n */\nfunction mixHue(base: OkhslVariant, target: OkhslVariant, t: number): number {\n const SAT_EPSILON = 1e-6;\n const baseHasSat = base.s > SAT_EPSILON;\n const targetHasSat = target.s > SAT_EPSILON;\n\n if (baseHasSat && targetHasSat) return circularLerp(base.h, target.h, t);\n if (targetHasSat) return target.h;\n return base.h;\n}\n\nfunction linearSrgbLerp(\n base: LinearRgb,\n target: LinearRgb,\n t: number,\n): LinearRgb {\n return [\n base[0] + (target[0] - base[0]) * t,\n base[1] + (target[1] - base[1]) * t,\n base[2] + (target[2] - base[2]) * t,\n ];\n}\n\nfunction linearRgbToToneVariant(\n rgb: LinearRgb,\n pastel: boolean,\n): ResolvedColorVariant {\n const gamma: [number, number, number] = [\n Math.max(0, Math.min(1, sRGBLinearToGamma(rgb[0]))),\n Math.max(0, Math.min(1, sRGBLinearToGamma(rgb[1]))),\n Math.max(0, Math.min(1, sRGBLinearToGamma(rgb[2]))),\n ];\n const [h, s, l] = srgbToOkhsl(gamma, pastel);\n return toToneVariant({ h, s, l, alpha: 1 });\n}\n\nfunction resolveMixForScheme(\n name: string,\n def: MixColorDef,\n ctx: ResolveContext,\n isDark: boolean,\n isHighContrast: boolean,\n): ResolvedColorVariant {\n const baseResolved = ctx.resolved.get(def.base)!;\n const targetResolved = ctx.resolved.get(def.target)!;\n const baseVariant = toOkhslVariant(\n getSchemeVariant(baseResolved, isDark, isHighContrast),\n );\n const targetVariant = toOkhslVariant(\n getSchemeVariant(targetResolved, isDark, isHighContrast),\n );\n\n const rawValue = isHighContrast ? pairHC(def.value) : pairNormal(def.value);\n let t = clamp(rawValue, 0, 100) / 100;\n\n const blend = def.blend ?? 'opaque';\n const space = def.space ?? 'okhsl';\n const role = resolveRole(name, def, ctx);\n const polarity = roleToPolarity(role);\n const pastel = def.pastel ?? ctx.config.pastel;\n const baseLinear = okhslVariantToLinearRgb(\n baseVariant,\n baseVariant.pastel ?? ctx.config.pastel,\n );\n const targetLinear = okhslVariantToLinearRgb(\n targetVariant,\n targetVariant.pastel ?? ctx.config.pastel,\n );\n\n if (def.contrast !== undefined) {\n const resolvedContrast = resolveContrastSpec(\n def.contrast,\n isHighContrast,\n polarity,\n );\n const metric = resolvedContrast.metric;\n\n let luminanceAt: (v: number) => number;\n\n if (blend === 'transparent' || space === 'srgb') {\n luminanceAt = (v: number) =>\n metricLuminance(metric, linearSrgbLerp(baseLinear, targetLinear, v));\n } else {\n luminanceAt = (v: number) => {\n const h = mixHue(baseVariant, targetVariant, v);\n const s = baseVariant.s + (targetVariant.s - baseVariant.s) * v;\n const l = baseVariant.l + (targetVariant.l - baseVariant.l) * v;\n return metricLuminance(metric, okhslToLinearSrgb(h, s, l, pastel));\n };\n }\n\n const result = findValueForMixContrast({\n preferredValue: t,\n baseLinearRgb: baseLinear,\n targetLinearRgb: targetLinear,\n contrast: resolvedContrast,\n luminanceAtValue: luminanceAt,\n flip: ctx.config.autoFlip,\n });\n t = result.value;\n }\n\n if (blend === 'transparent') {\n return {\n ...toToneVariant({\n h: targetVariant.h,\n s: targetVariant.s,\n l: targetVariant.l,\n alpha: clamp(t, 0, 1),\n }),\n pastel,\n };\n }\n\n if (space === 'srgb') {\n const mixed = linearSrgbLerp(baseLinear, targetLinear, t);\n return { ...linearRgbToToneVariant(mixed, pastel), pastel };\n }\n\n return {\n ...toToneVariant({\n h: mixHue(baseVariant, targetVariant, t),\n s: clamp(baseVariant.s + (targetVariant.s - baseVariant.s) * t, 0, 1),\n l: clamp(baseVariant.l + (targetVariant.l - baseVariant.l) * t, 0, 1),\n alpha: 1,\n }),\n pastel,\n };\n}\n\nfunction defMode(def: ColorDef): AdaptationMode | undefined {\n if (isShadowDef(def) || isMixDef(def)) return undefined;\n return (def as RegularColorDef).mode ?? 'auto';\n}\n\n/**\n * Run a single resolve pass over all local names. Pass 1 lazily creates\n * each `ResolvedColor` (all four slots seeded with the just-resolved\n * variant) the first time it sees a name; later passes update the\n * `target` slot on the existing record.\n */\nfunction runPass(\n order: string[],\n defs: ColorMap,\n ctx: ResolveContext,\n isDark: boolean,\n isHighContrast: boolean,\n target: ResolvedField,\n): Map<string, ResolvedColorVariant> {\n const out = new Map<string, ResolvedColorVariant>();\n for (const name of order) {\n const variant = resolveColorForScheme(\n name,\n defs[name],\n ctx,\n isDark,\n isHighContrast,\n );\n out.set(name, variant);\n const existing = ctx.resolved.get(name);\n if (existing) {\n ctx.resolved.set(name, { ...existing, [target]: variant });\n } else {\n ctx.resolved.set(name, {\n name,\n light: variant,\n dark: variant,\n lightContrast: variant,\n darkContrast: variant,\n mode: defMode(defs[name]),\n });\n }\n }\n return out;\n}\n\n/**\n * Re-seed a single variant slot with a previously-resolved map so the\n * upcoming pass reads sensible fallbacks via `getSchemeVariant`.\n */\nfunction seedField(\n order: string[],\n ctx: ResolveContext,\n field: ResolvedField,\n source: Map<string, ResolvedColorVariant>,\n): void {\n for (const name of order) {\n const existing = ctx.resolved.get(name)!;\n ctx.resolved.set(name, { ...existing, [field]: source.get(name)! });\n }\n}\n\n/**\n * After the four passes, surface chromatic contrast drift (§10): a color\n * resolved with a `base` + `contrast` may land slightly under the contrast\n * its tone implies because chromatic luminance drifts from the gray tone.\n */\nfunction verifyContrastDrift(\n order: string[],\n defs: ColorMap,\n result: Map<string, ResolvedColor>,\n config: GlazeConfigResolved,\n): void {\n const roles = new Map<string, Role>();\n for (const name of order) {\n const def = defs[name];\n if (isShadowDef(def) || isMixDef(def)) continue;\n const regDef = def as RegularColorDef;\n if (regDef.contrast === undefined || !regDef.base) continue;\n const color = result.get(name);\n const base = result.get(regDef.base);\n if (!color || !base) continue;\n\n const role = resolveRoleInMap(name, def, defs, config.inferRole, roles);\n const polarity = roleToPolarity(role);\n\n const schemes: {\n isDark: boolean;\n isHighContrast: boolean;\n field: ResolvedField;\n }[] = [\n { isDark: false, isHighContrast: false, field: 'light' },\n { isDark: false, isHighContrast: true, field: 'lightContrast' },\n { isDark: true, isHighContrast: false, field: 'dark' },\n { isDark: true, isHighContrast: true, field: 'darkContrast' },\n ];\n\n for (const s of schemes) {\n const spec = resolveContrastSpec(\n regDef.contrast,\n s.isHighContrast,\n polarity,\n );\n const cVariant = color[s.field];\n const bVariant = base[s.field];\n const cOkhsl = toOkhslVariant(cVariant);\n const bOkhsl = toOkhslVariant(bVariant);\n // Measure in the spec's metric basis so the APCA warning compares APCA\n // luminances, not WCAG ones. Each variant carries its own effective\n // pastel flag so the gamut mapping matches what the resolver applied;\n // fall back to the config default for any variant without one.\n const cPastel = cVariant.pastel ?? config.pastel;\n const bPastel = bVariant.pastel ?? config.pastel;\n const yC = metricLuminance(\n spec.metric,\n okhslToLinearSrgb(cOkhsl.h, cOkhsl.s, cOkhsl.l, cPastel),\n );\n const yB = metricLuminance(\n spec.metric,\n okhslToLinearSrgb(bOkhsl.h, bOkhsl.s, bOkhsl.l, bPastel),\n );\n warnContrastDrift(name, s.isDark, s.isHighContrast, spec, yC, yB);\n }\n }\n}\n\nexport function resolveAllColors(\n hue: number,\n saturation: number,\n defs: ColorMap,\n config: GlazeConfigResolved,\n externalBases?: Map<string, ResolvedColor>,\n): Map<string, ResolvedColor> {\n validateColorDefs(defs, externalBases);\n const order = topoSort(defs);\n\n const ctx: ResolveContext = {\n hue,\n saturation,\n defs,\n resolved: new Map(),\n config,\n roles: new Map(),\n };\n\n // Pre-seed externally-resolved bases. The per-pass loops iterate only\n // `defs` keys (via `order`), so external entries persist across all\n // four passes and are read via `getSchemeVariant` per scheme.\n if (externalBases) {\n for (const [name, color] of externalBases) {\n ctx.resolved.set(name, color);\n }\n }\n\n // Pass 1: Light normal.\n const lightMap = runPass(order, defs, ctx, false, false, 'light');\n\n // Pass 2: Light high-contrast.\n seedField(order, ctx, 'lightContrast', lightMap);\n const lightHCMap = runPass(order, defs, ctx, false, true, 'lightContrast');\n\n // Pass 3: Dark normal.\n seedField(order, ctx, 'dark', lightMap);\n seedField(order, ctx, 'darkContrast', lightHCMap);\n const darkMap = runPass(order, defs, ctx, true, false, 'dark');\n\n // Pass 4: Dark high-contrast.\n seedField(order, ctx, 'darkContrast', darkMap);\n const darkHCMap = runPass(order, defs, ctx, true, true, 'darkContrast');\n\n const result = new Map<string, ResolvedColor>();\n for (const name of order) {\n result.set(name, {\n name,\n light: lightMap.get(name)!,\n dark: darkMap.get(name)!,\n lightContrast: lightHCMap.get(name)!,\n darkContrast: darkHCMap.get(name)!,\n mode: defMode(defs[name]),\n });\n }\n\n verifyContrastDrift(order, defs, result, config);\n\n return result;\n}\n\n// Re-export for callers that previously imported tone helpers from here.\nexport { fromTone, toTone };\n","/**\n * Hue channel planning for `splitHue` exports.\n *\n * Builds per-color hue var references and scheme-independent `--*-hue`\n * declarations for oklch CSS / Tasty output when every color is pastel.\n */\n\nimport { parseRelativeOrAbsolute } from './hc-pair';\nimport { isMixDef, isShadowDef } from './shadow';\nimport type {\n ColorDef,\n ColorMap,\n RegularColorDef,\n ResolvedColor,\n ResolvedColorVariant,\n} from './types';\n\nconst ACHROMATIC_EPSILON = 1e-6;\n\nexport interface HueDeclaration {\n prop: string;\n value: string;\n}\n\nexport interface HuePlan {\n /** CSS `var()` reference spliced into `oklch(L C <hueVar>)`. */\n hueVar: string;\n /** When true, emit a full inline color (shadow/mix/achromatic). */\n inline: boolean;\n /** Scheme-independent `--*-hue` declarations for this color. */\n declarations: HueDeclaration[];\n}\n\nexport interface ChannelCtx {\n seedHue: number;\n /** Theme-level hue var base name (without `--` / `-hue`). */\n baseName: string;\n /** Token / custom-property name prefix used for hue var naming (`brand-` etc.). */\n prefix: string;\n defs: ColorMap;\n mode: 'theme' | 'standalone';\n /** Standalone: resolved hue from the primary variant (scheme-independent). */\n resolvedHue?: number;\n /**\n * When false, hue declarations are not emitted (the pass only references\n * hue vars already declared by a sibling pass). Used by palette primary\n * unprefixed aliases so they reference the themed `--{themeName}-*-hue`\n * vars without re-declaring (and colliding with) other themes' base vars.\n * Defaults to true.\n */\n emitDeclarations?: boolean;\n}\n\nfunction cssProp(prefix: string, name: string, suffix: string): string {\n return `--${prefix}${name}${suffix}`;\n}\n\nfunction isAchromatic(v: ResolvedColorVariant): boolean {\n return v.s <= ACHROMATIC_EPSILON;\n}\n\nfunction themeHuePlan(\n name: string,\n def: ColorDef | undefined,\n variant: ResolvedColorVariant,\n ctx: ChannelCtx,\n): HuePlan {\n if (\n def === undefined ||\n isShadowDef(def) ||\n isMixDef(def) ||\n isAchromatic(variant)\n ) {\n return { hueVar: '', inline: true, declarations: [] };\n }\n\n const regDef = def as RegularColorDef;\n const baseHueVar = `var(--${ctx.baseName}-hue)`;\n\n if (regDef.hue === undefined) {\n return { hueVar: baseHueVar, inline: false, declarations: [] };\n }\n\n const parsed = parseRelativeOrAbsolute(regDef.hue);\n const prop = cssProp(ctx.prefix, name, '-hue');\n\n if (parsed.relative) {\n const sign = parsed.value >= 0 ? '+' : '-';\n const magnitude = Math.abs(parsed.value);\n const value = `calc(var(--${ctx.baseName}-hue) ${sign} ${magnitude})`;\n return {\n hueVar: `var(${prop})`,\n inline: false,\n declarations: [{ prop, value }],\n };\n }\n\n const absHue = ((parsed.value % 360) + 360) % 360;\n return {\n hueVar: `var(${prop})`,\n inline: false,\n declarations: [{ prop, value: String(absHue) }],\n };\n}\n\nfunction standaloneHuePlan(\n name: string,\n variant: ResolvedColorVariant,\n ctx: ChannelCtx,\n): HuePlan {\n if (isAchromatic(variant)) {\n return { hueVar: '', inline: true, declarations: [] };\n }\n\n const hue = ctx.resolvedHue ?? variant.h;\n const prop = cssProp(ctx.prefix, name, '-hue');\n return {\n hueVar: `var(${prop})`,\n inline: false,\n declarations: [{ prop, value: String(hue) }],\n };\n}\n\nexport function buildHuePlan(\n name: string,\n def: ColorDef | undefined,\n variant: ResolvedColorVariant,\n ctx: ChannelCtx,\n): HuePlan {\n if (ctx.mode === 'standalone') {\n return standaloneHuePlan(name, variant, ctx);\n }\n return themeHuePlan(name, def, variant, ctx);\n}\n\n/** Collect unique hue declarations across all colors (theme + per-color). */\nexport function collectHueDeclarations(\n resolved: Map<string, ResolvedColor>,\n ctx: ChannelCtx,\n): HueDeclaration[] {\n if (ctx.emitDeclarations === false) return [];\n\n const seen = new Set<string>();\n const out: HueDeclaration[] = [];\n\n const push = (decl: HueDeclaration): void => {\n if (seen.has(decl.prop)) return;\n seen.add(decl.prop);\n out.push(decl);\n };\n\n if (ctx.mode === 'theme') {\n push({\n prop: `--${ctx.baseName}-hue`,\n value: String(ctx.seedHue),\n });\n }\n\n for (const [name, color] of resolved) {\n const def = ctx.defs[name];\n const plan = buildHuePlan(name, def, color.light, ctx);\n for (const decl of plan.declarations) {\n push(decl);\n }\n }\n\n return out;\n}\n\nexport function buildHuePlans(\n resolved: Map<string, ResolvedColor>,\n ctx: ChannelCtx,\n): Map<string, HuePlan> {\n const plans = new Map<string, HuePlan>();\n for (const [name, color] of resolved) {\n plans.set(name, buildHuePlan(name, ctx.defs[name], color.light, ctx));\n }\n return plans;\n}\n","/**\n * Output formatting for resolved color maps.\n *\n * Owns the CSS-string formatter dispatch table (`okhsl` / `rgb` / `hsl` /\n * `oklch`) and the token-map shapes Glaze emits:\n * - `buildTokenMap` — Tasty style-to-state bindings (`#name` keys, state aliases).\n * - `buildFlatTokenMap` — `{ light, dark, ... }` per-variant maps.\n * - `buildJsonMap` — `{ name: { light, dark, ... } }` per-color JSON.\n * - `buildCssMap` — CSS custom property declaration strings per variant.\n * - `buildDtcgMap` — W3C DTCG (2025.10) token documents, one per scheme.\n * - `buildDtcgResolver` — W3C DTCG Resolver-Module document (one modifier, a context per scheme).\n * - `buildTailwindMap` — Tailwind v4 `@theme` block + dark/HC overrides.\n */\n\nimport {\n buildHuePlans,\n collectHueDeclarations,\n type ChannelCtx,\n type HuePlan,\n} from './channels';\nimport {\n formatHsl,\n formatOkhsl,\n formatOkhst,\n formatOklch,\n formatRgb,\n okhslToOklch,\n okhslToSrgb,\n srgbToHex,\n} from './okhsl-color-math';\nimport { variantToOkhsl } from './okhst';\nimport { getConfig } from './config';\nimport type {\n DtcgColorSpace,\n DtcgColorToken,\n DtcgColorValue,\n DtcgDocument,\n DtcgTokenTree,\n GlazeColorFormat,\n GlazeCssResult,\n GlazeDtcgResolverDocument,\n GlazeDtcgResolverOptions,\n GlazeDtcgResult,\n GlazeOutputModes,\n ResolvedColor,\n ResolvedColorVariant,\n} from './types';\n\nexport type { ChannelCtx } from './channels';\n\nconst formatters: Record<\n Exclude<GlazeColorFormat, 'okhst'>,\n (h: number, s: number, l: number, pastel: boolean) => string\n> = {\n okhsl: formatOkhsl,\n rgb: formatRgb,\n hsl: formatHsl,\n oklch: formatOklch,\n};\n\nfunction fmt(value: number, decimals: number): string {\n return parseFloat(value.toFixed(decimals)).toString();\n}\n\nexport function formatVariant(\n v: ResolvedColorVariant,\n format: GlazeColorFormat = 'oklch',\n pastel = false,\n): string {\n // Variants store canonical tone; convert to OKHSL lightness at the edge.\n // Per-variant `pastel` (set by the resolver from def or config fallback)\n // wins over the format-time fallback, so output matches resolution.\n const effectivePastel = v.pastel ?? pastel;\n\n let base: string;\n if (format === 'okhst') {\n base = formatOkhst(v.h, v.s * 100, v.t * 100, effectivePastel);\n } else {\n const { l } = variantToOkhsl(v);\n base = formatters[format](v.h, v.s * 100, l * 100, effectivePastel);\n }\n\n if (v.alpha >= 1) return base;\n const closing = base.lastIndexOf(')');\n return `${base.slice(0, closing)} / ${fmt(v.alpha, 4)})`;\n}\n\n/**\n * Format a resolved variant as `oklch(L C <hueVar>)`, splicing a CSS hue var\n * for `splitHue` exports. Falls back to inline when the plan is inline.\n */\nexport function formatVariantHue(\n v: ResolvedColorVariant,\n plan: HuePlan,\n pastel = false,\n): string {\n const effectivePastel = v.pastel ?? pastel;\n const { l } = variantToOkhsl(v);\n const [L, C] = okhslToOklch(v.h, v.s, l, effectivePastel);\n\n let base: string;\n if (plan.inline) {\n if (v.s <= 1e-6) {\n base = `oklch(${fmt(L, 4)} 0 0)`;\n } else {\n base = formatOklch(v.h, v.s * 100, l * 100, effectivePastel);\n }\n } else {\n base = `oklch(${fmt(L, 4)} ${fmt(C, 4)} ${plan.hueVar})`;\n }\n\n if (v.alpha >= 1) return base;\n const closing = base.lastIndexOf(')');\n return `${base.slice(0, closing)} / ${fmt(v.alpha, 4)})`;\n}\n\nfunction formatColorValue(\n v: ResolvedColorVariant,\n format: GlazeColorFormat,\n pastel: boolean,\n huePlan?: HuePlan,\n): string {\n if (format === 'oklch' && huePlan !== undefined) {\n return formatVariantHue(v, huePlan, pastel);\n }\n return formatVariant(v, format, pastel);\n}\n\nexport function resolveModes(\n override?: GlazeOutputModes,\n): Required<GlazeOutputModes> {\n const cfg = getConfig();\n return {\n dark: override?.dark ?? cfg.modes.dark,\n highContrast: override?.highContrast ?? cfg.modes.highContrast,\n };\n}\n\nexport function buildTokenMap(\n resolved: Map<string, ResolvedColor>,\n prefix: string,\n states: { dark: string; highContrast: string },\n modes: Required<GlazeOutputModes>,\n format: GlazeColorFormat = 'oklch',\n pastel = false,\n channelCtx?: ChannelCtx,\n): Record<string, Record<string, string>> {\n const tokens: Record<string, Record<string, string>> = {};\n const huePlans =\n channelCtx !== undefined && format === 'oklch'\n ? buildHuePlans(resolved, channelCtx)\n : undefined;\n\n if (huePlans !== undefined && channelCtx !== undefined) {\n const emitDecls = channelCtx.emitDeclarations !== false;\n if (emitDecls && channelCtx.mode === 'theme') {\n tokens[`$${channelCtx.baseName}-hue`] = {\n '': String(channelCtx.seedHue),\n };\n }\n for (const [name, color] of resolved) {\n const plan = huePlans.get(name)!;\n if (emitDecls) {\n for (const decl of plan.declarations) {\n const key = `$${decl.prop.slice(2)}`;\n if (!(key in tokens)) {\n tokens[key] = { '': decl.value };\n }\n }\n }\n const colorKey = `#${prefix}${name}`;\n const planForColor = huePlans.get(name);\n tokens[colorKey] = buildTokenEntry(\n color,\n states,\n modes,\n format,\n pastel,\n planForColor,\n );\n }\n return tokens;\n }\n\n for (const [name, color] of resolved) {\n const key = `#${prefix}${name}`;\n tokens[key] = buildTokenEntry(color, states, modes, format, pastel);\n }\n\n return tokens;\n}\n\nfunction buildTokenEntry(\n color: ResolvedColor,\n states: { dark: string; highContrast: string },\n modes: Required<GlazeOutputModes>,\n format: GlazeColorFormat,\n pastel: boolean,\n huePlan?: HuePlan,\n): Record<string, string> {\n const entry: Record<string, string> = {\n '': formatColorValue(color.light, format, pastel, huePlan),\n };\n\n if (modes.dark) {\n entry[states.dark] = formatColorValue(color.dark, format, pastel, huePlan);\n }\n if (modes.highContrast) {\n entry[states.highContrast] = formatColorValue(\n color.lightContrast,\n format,\n pastel,\n huePlan,\n );\n }\n if (modes.dark && modes.highContrast) {\n entry[`${states.dark} & ${states.highContrast}`] = formatColorValue(\n color.darkContrast,\n format,\n pastel,\n huePlan,\n );\n }\n\n return entry;\n}\n\nexport function buildFlatTokenMap(\n resolved: Map<string, ResolvedColor>,\n prefix: string,\n modes: Required<GlazeOutputModes>,\n format: GlazeColorFormat = 'oklch',\n pastel = false,\n): Record<string, Record<string, string>> {\n const result: Record<string, Record<string, string>> = {\n light: {},\n };\n\n if (modes.dark) {\n result.dark = {};\n }\n if (modes.highContrast) {\n result.lightContrast = {};\n }\n if (modes.dark && modes.highContrast) {\n result.darkContrast = {};\n }\n\n for (const [name, color] of resolved) {\n const key = `${prefix}${name}`;\n\n result.light[key] = formatVariant(color.light, format, pastel);\n\n if (modes.dark) {\n result.dark[key] = formatVariant(color.dark, format, pastel);\n }\n if (modes.highContrast) {\n result.lightContrast[key] = formatVariant(\n color.lightContrast,\n format,\n pastel,\n );\n }\n if (modes.dark && modes.highContrast) {\n result.darkContrast[key] = formatVariant(\n color.darkContrast,\n format,\n pastel,\n );\n }\n }\n\n return result;\n}\n\nexport function buildJsonMap(\n resolved: Map<string, ResolvedColor>,\n modes: Required<GlazeOutputModes>,\n format: GlazeColorFormat = 'oklch',\n pastel = false,\n): Record<string, Record<string, string>> {\n const result: Record<string, Record<string, string>> = {};\n\n for (const [name, color] of resolved) {\n const entry: Record<string, string> = {\n light: formatVariant(color.light, format, pastel),\n };\n\n if (modes.dark) {\n entry.dark = formatVariant(color.dark, format, pastel);\n }\n if (modes.highContrast) {\n entry.lightContrast = formatVariant(color.lightContrast, format, pastel);\n }\n if (modes.dark && modes.highContrast) {\n entry.darkContrast = formatVariant(color.darkContrast, format, pastel);\n }\n\n result[name] = entry;\n }\n\n return result;\n}\n\nexport function buildCssMap(\n resolved: Map<string, ResolvedColor>,\n prefix: string,\n suffix: string,\n format: GlazeColorFormat,\n pastel = false,\n channelCtx?: ChannelCtx,\n): GlazeCssResult {\n const lines: Record<keyof GlazeCssResult, string[]> = {\n light: [],\n dark: [],\n lightContrast: [],\n darkContrast: [],\n };\n\n const huePlans =\n channelCtx !== undefined && format === 'oklch'\n ? buildHuePlans(resolved, channelCtx)\n : undefined;\n\n if (huePlans !== undefined && channelCtx !== undefined) {\n for (const decl of collectHueDeclarations(resolved, channelCtx)) {\n lines.light.push(`${decl.prop}: ${decl.value};`);\n }\n }\n\n for (const [name, color] of resolved) {\n const prop = `--${prefix}${name}${suffix}`;\n const plan = huePlans?.get(name);\n lines.light.push(\n `${prop}: ${formatColorValue(color.light, format, pastel, plan)};`,\n );\n lines.dark.push(\n `${prop}: ${formatColorValue(color.dark, format, pastel, plan)};`,\n );\n lines.lightContrast.push(\n `${prop}: ${formatColorValue(color.lightContrast, format, pastel, plan)};`,\n );\n lines.darkContrast.push(\n `${prop}: ${formatColorValue(color.darkContrast, format, pastel, plan)};`,\n );\n }\n\n return {\n light: lines.light.join('\\n'),\n dark: lines.dark.join('\\n'),\n lightContrast: lines.lightContrast.join('\\n'),\n darkContrast: lines.darkContrast.join('\\n'),\n };\n}\n\n// ============================================================================\n// DTCG (W3C Design Tokens Format Module 2025.10)\n// ============================================================================\n\nfunction roundTo(value: number, decimals: number): number {\n return parseFloat(value.toFixed(decimals));\n}\n\n/**\n * Build a DTCG `$value` color object for a resolved variant.\n *\n * `srgb` (default) emits gamma sRGB components in 0–1 plus a 6-digit `hex`\n * hint — the most universally understood form (Figma, Tokens Studio, Style\n * Dictionary). `oklch` emits `[L, C, H]` components with no hex — Glaze-native\n * and wide-gamut. `alpha` is included only when below 1.\n */\nexport function dtcgColorValue(\n v: ResolvedColorVariant,\n colorSpace: DtcgColorSpace = 'srgb',\n pastel = false,\n): DtcgColorValue {\n const effectivePastel = v.pastel ?? pastel;\n const { l } = variantToOkhsl(v);\n const alpha = v.alpha < 1 ? roundTo(v.alpha, 6) : undefined;\n\n if (colorSpace === 'oklch') {\n const [L, C, H] = okhslToOklch(v.h, v.s, l, effectivePastel);\n const value: DtcgColorValue = {\n colorSpace: 'oklch',\n components: [roundTo(L, 6), roundTo(C, 6), roundTo(H, 4)],\n };\n if (alpha !== undefined) value.alpha = alpha;\n return value;\n }\n\n const [r, g, b] = okhslToSrgb(v.h, v.s, l, effectivePastel);\n const value: DtcgColorValue = {\n colorSpace: 'srgb',\n components: [roundTo(r, 6), roundTo(g, 6), roundTo(b, 6)],\n hex: srgbToHex([r, g, b]),\n };\n if (alpha !== undefined) value.alpha = alpha;\n return value;\n}\n\nfunction dtcgToken(\n v: ResolvedColorVariant,\n colorSpace: DtcgColorSpace,\n pastel: boolean,\n): DtcgColorToken {\n return { $type: 'color', $value: dtcgColorValue(v, colorSpace, pastel) };\n}\n\n/**\n * Build a `GlazeDtcgResult`: one spec-conformant DTCG token document per\n * scheme variant, gated by `modes`. Light is always present.\n */\nexport function buildDtcgMap(\n resolved: Map<string, ResolvedColor>,\n prefix: string,\n modes: Required<GlazeOutputModes>,\n colorSpace: DtcgColorSpace = 'srgb',\n pastel = false,\n): GlazeDtcgResult {\n const light: DtcgDocument = {};\n const dark: DtcgDocument | undefined = modes.dark ? {} : undefined;\n const lightContrast: DtcgDocument | undefined = modes.highContrast\n ? {}\n : undefined;\n const darkContrast: DtcgDocument | undefined =\n modes.dark && modes.highContrast ? {} : undefined;\n\n for (const [name, color] of resolved) {\n const key = `${prefix}${name}`;\n light[key] = dtcgToken(color.light, colorSpace, pastel);\n if (dark) dark[key] = dtcgToken(color.dark, colorSpace, pastel);\n if (lightContrast) {\n lightContrast[key] = dtcgToken(color.lightContrast, colorSpace, pastel);\n }\n if (darkContrast) {\n darkContrast[key] = dtcgToken(color.darkContrast, colorSpace, pastel);\n }\n }\n\n return { light, dark, lightContrast, darkContrast };\n}\n\n// ============================================================================\n// DTCG Resolver Module (single document for all scheme variants)\n// ============================================================================\n\n/**\n * Default context names emitted on the `scheme` modifier — the Glaze variant\n * keys, so the resolver document mirrors `GlazeDtcgResult` exactly.\n */\nconst DEFAULT_DTCG_CONTEXT_NAMES = {\n light: 'light',\n dark: 'dark',\n lightContrast: 'lightContrast',\n darkContrast: 'darkContrast',\n} as const;\n\n/**\n * Wrap a per-scheme `GlazeDtcgResult` into a single W3C DTCG Resolver-Module\n * document. The light document becomes `sets[setName].sources[0]` (the default\n * context); each other present variant becomes a `contexts[ctx]` override\n * array on a single `modifiers[modifierName]`. Absent variants (per the\n * `modes` already applied to `result`) are omitted — light is always present\n * and is the modifier `default`. Only the resolver-specific options are read;\n * `modes` / `colorSpace` were already consumed by the `buildDtcgMap` call that\n * produced `result`.\n */\nexport function buildDtcgResolver(\n result: GlazeDtcgResult,\n options?: GlazeDtcgResolverOptions,\n): GlazeDtcgResolverDocument {\n const setName = options?.setName ?? 'base';\n const modifierName = options?.modifierName ?? 'scheme';\n const ctx = {\n ...DEFAULT_DTCG_CONTEXT_NAMES,\n ...options?.contextNames,\n };\n const contexts: Record<string, DtcgTokenTree[]> = {\n [ctx.light]: [],\n };\n if (result.dark) contexts[ctx.dark] = [result.dark];\n if (result.lightContrast) {\n contexts[ctx.lightContrast] = [result.lightContrast];\n }\n if (result.darkContrast) contexts[ctx.darkContrast] = [result.darkContrast];\n\n return {\n version: options?.version ?? '2025.10',\n sets: {\n [setName]: { sources: [result.light] },\n },\n modifiers: {\n [modifierName]: {\n default: ctx.light,\n contexts,\n },\n },\n resolutionOrder: [\n { $ref: `#/sets/${setName}` },\n { $ref: `#/modifiers/${modifierName}` },\n ],\n };\n}\n\n// ============================================================================\n// Tailwind CSS v4 (@theme)\n// ============================================================================\n\n/** Per-scheme declaration lines (`--prop: value;`) accumulated for emission. */\nexport interface GlazeTailwindLines {\n light: string[];\n dark: string[];\n lightContrast: string[];\n darkContrast: string[];\n}\n\nfunction tailwindLinesFor(\n resolved: Map<string, ResolvedColor>,\n themePrefix: string,\n cssPrefix: string,\n format: GlazeColorFormat,\n pastel: boolean,\n): GlazeTailwindLines {\n const lines: GlazeTailwindLines = {\n light: [],\n dark: [],\n lightContrast: [],\n darkContrast: [],\n };\n for (const [name, color] of resolved) {\n const prop = `--${cssPrefix}${themePrefix}${name}`;\n lines.light.push(`${prop}: ${formatVariant(color.light, format, pastel)};`);\n lines.dark.push(`${prop}: ${formatVariant(color.dark, format, pastel)};`);\n lines.lightContrast.push(\n `${prop}: ${formatVariant(color.lightContrast, format, pastel)};`,\n );\n lines.darkContrast.push(\n `${prop}: ${formatVariant(color.darkContrast, format, pastel)};`,\n );\n }\n return lines;\n}\n\nfunction indentBlock(text: string, pad: string): string {\n return text\n .split('\\n')\n .map((line) => (line.length === 0 ? line : pad + line))\n .join('\\n');\n}\n\nfunction emitRule(selector: string, body: string): string {\n return `${selector} {\\n${indentBlock(body, ' ')}\\n}`;\n}\n\n/**\n * Emit a CSS block for a set of declarations scoped by one or more selectors\n * / at-rules. Class-like selectors concatenate (`.dark.high-contrast`);\n * at-rules (`@media …`) nest `:root` (or the chained selector) inside.\n */\nfunction emitScoped(\n scopes: string[],\n declarations: string[],\n): string | undefined {\n if (declarations.length === 0) return undefined;\n\n const atRules: string[] = [];\n let selectorChain = '';\n for (const scope of scopes) {\n if (scope.startsWith('@')) atRules.push(scope);\n else selectorChain += scope;\n }\n const selector = selectorChain || ':root';\n\n let css = emitRule(selector, declarations.join('\\n'));\n for (const rule of atRules) {\n css = emitRule(rule, css);\n }\n return css;\n}\n\n/**\n * Render accumulated per-scheme declaration lines as a Tailwind v4 CSS string:\n * an `@theme` block (light baseline) plus dark / high-contrast overrides under\n * the configured selectors. Empty blocks are skipped.\n */\nexport function emitTailwindCss(\n lines: GlazeTailwindLines,\n modes: Required<GlazeOutputModes>,\n darkSelector: string,\n highContrastSelector: string,\n): string {\n const blocks: string[] = [];\n\n if (lines.light.length > 0) {\n blocks.push(emitRule('@theme', lines.light.join('\\n')));\n }\n\n if (modes.dark) {\n const dark = emitScoped([darkSelector], lines.dark);\n if (dark) blocks.push(dark);\n }\n if (modes.highContrast) {\n const hc = emitScoped([highContrastSelector], lines.lightContrast);\n if (hc) blocks.push(hc);\n }\n if (modes.dark && modes.highContrast) {\n const dhc = emitScoped(\n [darkSelector, highContrastSelector],\n lines.darkContrast,\n );\n if (dhc) blocks.push(dhc);\n }\n\n return blocks.join('\\n\\n');\n}\n\n/**\n * Build per-scheme declaration lines for a single theme (used by\n * `theme.tailwind()` and as the palette `buildOne` step).\n */\nexport function buildTailwindLines(\n resolved: Map<string, ResolvedColor>,\n themePrefix: string,\n cssPrefix: string,\n format: GlazeColorFormat,\n pastel: boolean,\n): GlazeTailwindLines {\n return tailwindLinesFor(resolved, themePrefix, cssPrefix, format, pastel);\n}\n\n/**\n * Build a complete Tailwind v4 CSS string for a single theme.\n */\nexport function buildTailwindMap(\n resolved: Map<string, ResolvedColor>,\n themePrefix: string,\n cssPrefix: string,\n modes: Required<GlazeOutputModes>,\n format: GlazeColorFormat,\n darkSelector: string,\n highContrastSelector: string,\n pastel = false,\n): string {\n const lines = tailwindLinesFor(\n resolved,\n themePrefix,\n cssPrefix,\n format,\n pastel,\n );\n return emitTailwindCss(lines, modes, darkSelector, highContrastSelector);\n}\n","/**\n * Standalone single-color tokens (`glaze.color()` / `glaze.colorFrom()`).\n *\n * Owns the value-shorthand parser (hex, `rgb()` / `hsl()` / `okhsl()` /\n * `okhst()` / `oklch()`, `{ r, g, b }`, `{ h, s, l }`, `{ h, s, t }`,\n * `{ l, c, h }`), the structured-input validator, the two factory paths\n * (value vs structured), and the JSON-safe export / rehydration round-trip.\n *\n * Tokens store a sparse local config override only. Resolve merges the\n * live global config with that local override (invalidated on\n * `configure()`). Authoring `.export(override?)` freezes\n * `getConfig() ∪ local ∪ override` at call time.\n */\n\nimport {\n freezeConfigForExport,\n getConfig,\n getConfigVersion,\n mergeConfig,\n} from './config';\nimport {\n assertExportKind,\n assertExportVersion,\n GLAZE_EXPORT_VERSION,\n isColorTokenExport,\n} from './serialize';\nimport type { ChannelCtx } from './channels';\nimport { assertAllPastel, assertNativeFormat } from './format-guard';\nimport {\n hslToSrgb,\n oklabToOkhsl,\n parseHexAlpha,\n srgbToOkhsl,\n} from './okhsl-color-math';\nimport { okhstToOkhsl, toTone } from './okhst';\nimport { isAbsoluteTone, pairNormal } from './hc-pair';\nimport { resolveAllColors } from './resolver';\nimport {\n buildCssMap,\n buildDtcgMap,\n buildDtcgResolver,\n buildJsonMap,\n buildTailwindMap,\n buildTokenMap,\n resolveModes,\n} from './formatters';\nimport type {\n ColorMap,\n GlazeColorCssOptions,\n GlazeColorDtcgResolverOptions,\n GlazeColorDtcgResult,\n GlazeColorInput,\n GlazeColorInputExport,\n GlazeColorOverrides,\n GlazeColorOverridesExport,\n GlazeColorTailwindOptions,\n GlazeColorToken,\n GlazeColorTokenExport,\n GlazeColorValue,\n GlazeCssResult,\n GlazeConfigOverride,\n GlazeConfigResolved,\n GlazeDtcgOptions,\n GlazeDtcgResolverDocument,\n GlazeDtcgResult,\n GlazeJsonOptions,\n GlazeTokenOptions,\n OkhslColor,\n OkhstColor,\n OklchColor,\n RgbColor,\n RegularColorDef,\n ResolvedColor,\n} from './types';\n\n// ============================================================================\n// Standalone color constants\n// ============================================================================\n\n/** Internal name of the user-facing standalone color in the synthesized def map. */\nconst STANDALONE_VALUE = 'value';\n/** Internal name of the hidden static-anchor seed used for relative tone / contrast. */\nconst STANDALONE_SEED = 'seed';\n/** Internal name of an externally-resolved `GlazeColorToken` injected as a base reference. */\nconst STANDALONE_BASE = 'externalBase';\n\n/** Reserved internal names that user-supplied `name` must not collide with. */\nconst RESERVED_STANDALONE_NAMES = new Set([\n STANDALONE_VALUE,\n STANDALONE_SEED,\n STANDALONE_BASE,\n]);\n\n// ============================================================================\n// Sparse local config (no global freeze at create)\n// ============================================================================\n\n/**\n * Value-form local override: `lightTone` defaults to `false` (preserve\n * input tone). User override fields win.\n */\nfunction sparseValueFormLocal(\n userOverride?: GlazeConfigOverride,\n): GlazeConfigOverride {\n return {\n ...userOverride,\n lightTone:\n userOverride?.lightTone !== undefined ? userOverride.lightTone : false,\n };\n}\n\n// ============================================================================\n// Color string parsing\n// ============================================================================\n\n/**\n * Matches the CSS color functions Glaze itself emits (`rgb()`, `hsl()`,\n * `okhsl()`, `oklch()`) plus their legacy alpha aliases (`rgba()`, `hsla()`).\n *\n * Only bare numeric components are supported. Named colors (`red`),\n * relative-color syntax (`from <color> ...`), and angle units other\n * than bare degrees (`deg` is the only suffix tolerated by `parseFloat`)\n * are out of scope.\n */\nconst COLOR_FN_RE = /^(rgba?|hsla?|okhsl|okhst|oklch)\\(\\s*([^)]*)\\s*\\)$/i;\n\nfunction parseNumberOrPercent(raw: string, percentScale: number): number {\n if (raw.endsWith('%')) {\n return (parseFloat(raw) / 100) * percentScale;\n }\n return parseFloat(raw);\n}\n\n/**\n * Split the body of a CSS color function into its components and detect\n * whether an alpha channel was present.\n *\n * Handles both modern slash syntax (`R G B / A` or `R, G, B / A`) and\n * legacy comma syntax (`R, G, B, A`). The alpha value itself is discarded\n * by the caller — standalone Glaze colors have no opacity field.\n */\nfunction splitColorBody(body: string): {\n components: string[];\n hadAlpha: boolean;\n} {\n const slashIdx = body.indexOf('/');\n if (slashIdx !== -1) {\n const components = body\n .slice(0, slashIdx)\n .trim()\n .split(/[\\s,]+/)\n .filter(Boolean);\n const hadAlpha = body.slice(slashIdx + 1).trim().length > 0;\n return { components, hadAlpha };\n }\n\n const components = body.split(/[\\s,]+/).filter(Boolean);\n if (components.length === 4) {\n components.pop();\n return { components, hadAlpha: true };\n }\n return { components, hadAlpha: false };\n}\n\nfunction warnDroppedAlpha(input: string): void {\n console.warn(\n `glaze: alpha component dropped from \"${input}\" (standalone color has no opacity field).`,\n );\n}\n\nfunction parseColorString(input: string): OkhslColor {\n if (input.startsWith('#')) {\n const parsed = parseHexAlpha(input);\n if (!parsed) throw new Error(`glaze: invalid hex color \"${input}\".`);\n if (parsed.alpha !== undefined) warnDroppedAlpha(input);\n const [h, s, l] = srgbToOkhsl(parsed.rgb);\n return { h, s, l };\n }\n\n const m = input.match(COLOR_FN_RE);\n if (!m) {\n throw new Error(`glaze: unsupported color string \"${input}\".`);\n }\n\n const fn = m[1].toLowerCase();\n const { components, hadAlpha } = splitColorBody(m[2].trim());\n\n if (hadAlpha) warnDroppedAlpha(input);\n if (components.length !== 3) {\n throw new Error(`glaze: expected 3 components in \"${input}\".`);\n }\n\n switch (fn) {\n case 'rgb':\n case 'rgba': {\n const r = parseNumberOrPercent(components[0], 255) / 255;\n const g = parseNumberOrPercent(components[1], 255) / 255;\n const b = parseNumberOrPercent(components[2], 255) / 255;\n const [h, s, l] = srgbToOkhsl([r, g, b]);\n return { h, s, l };\n }\n case 'hsl':\n case 'hsla': {\n const h = parseFloat(components[0]);\n const s = parseNumberOrPercent(components[1], 1);\n const l = parseNumberOrPercent(components[2], 1);\n const [oh, os, ol] = srgbToOkhsl(hslToSrgb(h, s, l));\n return { h: oh, s: os, l: ol };\n }\n case 'okhsl': {\n const h = parseFloat(components[0]);\n const s = parseNumberOrPercent(components[1], 1);\n const l = parseNumberOrPercent(components[2], 1);\n return { h, s, l };\n }\n case 'okhst': {\n const h = parseFloat(components[0]);\n const s = parseNumberOrPercent(components[1], 1);\n const t = parseNumberOrPercent(components[2], 1);\n return okhstToOkhsl({ h, s, t });\n }\n case 'oklch': {\n const L = parseNumberOrPercent(components[0], 1);\n // Per CSS Color 4: chroma percent maps `100% → 0.4`.\n const C = parseNumberOrPercent(components[1], 0.4);\n const hDeg = parseFloat(components[2]);\n const hRad = (hDeg * Math.PI) / 180;\n const a = C * Math.cos(hRad);\n const b = C * Math.sin(hRad);\n const [h, s, l] = oklabToOkhsl([L, a, b]);\n return { h, s, l };\n }\n }\n throw new Error(`glaze: unsupported color function \"${fn}\".`);\n}\n\n// ============================================================================\n// Input validation\n// ============================================================================\n\n/**\n * Validate a user-supplied `OkhslColor`. Catches the common 0-100 vs 0-1\n * confusion (the structured form uses 0-100, OKHSL objects use 0-1).\n */\nfunction validateOkhslColor(value: OkhslColor): void {\n const { h, s, l } = value;\n if (!Number.isFinite(h) || !Number.isFinite(s) || !Number.isFinite(l)) {\n throw new Error('glaze.color: OkhslColor h/s/l must be finite numbers.');\n }\n if (s > 1.5 || l > 1.5) {\n throw new Error(\n 'glaze.color: OkhslColor s/l must be in 0–1 range. Did you mean the structured form { hue, saturation, tone } (which uses 0–100)?',\n );\n }\n}\n\n/** Validate a user-supplied `{ r, g, b }` object in 0–255. */\nfunction validateRgbColor(value: RgbColor): void {\n for (const key of ['r', 'g', 'b'] as const) {\n const n = value[key];\n if (!Number.isFinite(n) || n < 0 || n > 255) {\n throw new Error(\n `glaze.color: RgbColor ${key} must be a finite number in 0–255 (got ${n}).`,\n );\n }\n }\n}\n\n/** Validate a user-supplied `{ l, c, h }` OKLCh object. */\nfunction validateOklchColor(value: OklchColor): void {\n const { l, c, h } = value;\n if (!Number.isFinite(l) || !Number.isFinite(c) || !Number.isFinite(h)) {\n throw new Error('glaze.color: OklchColor l/c/h must be finite numbers.');\n }\n if (l > 1.5 || c > 1.5) {\n throw new Error(\n 'glaze.color: OklchColor l/c must be in 0–1 range (matching oklch() strings).',\n );\n }\n}\n\nfunction oklchComponentsToOkhsl(\n l: number,\n c: number,\n hDeg: number,\n): OkhslColor {\n const hRad = (hDeg * Math.PI) / 180;\n const a = c * Math.cos(hRad);\n const b = c * Math.sin(hRad);\n const [h, s, outL] = oklabToOkhsl([l, a, b]);\n return { h, s, l: outL };\n}\n\nfunction isRgbColorObject(value: object): value is RgbColor {\n return 'r' in value && 'g' in value && 'b' in value;\n}\n\nfunction isOklchColorObject(value: object): value is OklchColor {\n return 'c' in value && 'l' in value && 'h' in value;\n}\n\nfunction isOkhstColorObject(value: object): value is OkhstColor {\n return 't' in value && 'h' in value && 's' in value;\n}\n\n/** Validate a user-supplied `{ h, s, t }` OKHST object (s/t in 0–1). */\nfunction validateOkhstColor(value: OkhstColor): void {\n const { h, s, t } = value;\n if (!Number.isFinite(h) || !Number.isFinite(s) || !Number.isFinite(t)) {\n throw new Error('glaze.color: OkhstColor h/s/t must be finite numbers.');\n }\n if (s > 1.5 || t > 1.5) {\n throw new Error(\n 'glaze.color: OkhstColor s/t must be in 0–1 range. Did you mean the structured form { hue, saturation, tone } (which uses 0–100)?',\n );\n }\n}\n\n/**\n * Validate a user-supplied `opacity` override on `glaze.color()`.\n * Must be a finite number in `0..=1`.\n */\nfunction validateStandaloneOpacity(value: number): void {\n if (!Number.isFinite(value) || value < 0 || value > 1) {\n throw new Error(\n `glaze.color: opacity must be a finite number in 0–1 (got ${value}).`,\n );\n }\n}\n\n/**\n * Validate a structured `GlazeColorInput`. Range-checks the `hue` /\n * `saturation` / `tone` numerics (and any HC-pair second value)\n * before the resolver sees them so out-of-range or non-finite inputs\n * fail with a helpful, top-level error rather than producing a\n * NaN-laden token. `opacity` is checked here too so all input\n * validation lives in one place.\n */\nfunction validateStructuredInput(input: GlazeColorInput): void {\n if (!Number.isFinite(input.hue)) {\n throw new Error(\n `glaze.color: structured hue must be a finite number (got ${input.hue}).`,\n );\n }\n if (\n !Number.isFinite(input.saturation) ||\n input.saturation < 0 ||\n input.saturation > 100\n ) {\n throw new Error(\n `glaze.color: structured saturation must be a finite number in 0–100 (got ${input.saturation}).`,\n );\n }\n const checkTone = (value: number | string, label: string): void => {\n // 'max' / 'min' extreme keywords are always valid.\n if (value === 'max' || value === 'min') return;\n if (\n typeof value !== 'number' ||\n !Number.isFinite(value) ||\n value < 0 ||\n value > 100\n ) {\n throw new Error(\n `glaze.color: structured ${label} must be a finite number in 0–100 or 'max'/'min' (got ${String(value)}).`,\n );\n }\n };\n if (Array.isArray(input.tone)) {\n checkTone(input.tone[0], 'tone[normal]');\n checkTone(input.tone[1], 'tone[hc]');\n } else {\n checkTone(input.tone, 'tone');\n }\n if (input.saturationFactor !== undefined) {\n if (\n !Number.isFinite(input.saturationFactor) ||\n input.saturationFactor < 0 ||\n input.saturationFactor > 1\n ) {\n throw new Error(\n `glaze.color: structured saturationFactor must be a finite number in 0–1 (got ${input.saturationFactor}).`,\n );\n }\n }\n if (input.opacity !== undefined) validateStandaloneOpacity(input.opacity);\n}\n\n/**\n * Validate a user-supplied `name` override. Rejects empty / whitespace-only\n * strings and names colliding with `glaze`'s reserved internal sentinels.\n */\nfunction validateStandaloneName(name: string): void {\n if (typeof name !== 'string' || name.trim() === '') {\n throw new Error(\n 'glaze.color: name must be a non-empty string. ' +\n 'Omit `name` if you do not want to set a debug label.',\n );\n }\n if (RESERVED_STANDALONE_NAMES.has(name)) {\n const reserved = [...RESERVED_STANDALONE_NAMES]\n .map((n) => `\"${n}\"`)\n .join(', ');\n throw new Error(\n `glaze.color: name \"${name}\" is reserved (used internally). ` +\n `Reserved names are: ${reserved}. Pick a different name.`,\n );\n }\n}\n\n/**\n * Extract an OKHSL color from any `GlazeColorValue` form. Also used by\n * `glaze.shadow()` so all shadow inputs (hex, color functions, OKHSL,\n * literal objects) go through one parser.\n */\nexport function extractOkhslFromValue(value: GlazeColorValue): OkhslColor {\n if (typeof value === 'string') return parseColorString(value);\n if (Array.isArray(value)) {\n throw new Error(\n 'glaze.color: RGB tuple [r, g, b] is no longer supported — use { r, g, b } instead.',\n );\n }\n if (isRgbColorObject(value)) {\n validateRgbColor(value);\n const [h, s, l] = srgbToOkhsl([\n value.r / 255,\n value.g / 255,\n value.b / 255,\n ]);\n return { h, s, l };\n }\n if (isOklchColorObject(value)) {\n validateOklchColor(value);\n return oklchComponentsToOkhsl(value.l, value.c, value.h);\n }\n if (isOkhstColorObject(value)) {\n validateOkhstColor(value);\n return okhstToOkhsl(value);\n }\n validateOkhslColor(value);\n return value;\n}\n\n// ============================================================================\n// Factory: shared helpers\n// ============================================================================\n\ninterface ValueDefsResult {\n seedHue: number;\n seedSaturation: number;\n defs: ColorMap;\n primary: string;\n}\n\n/**\n * Build the `ColorMap` for a value-shorthand `glaze.color()` call.\n *\n * The user-facing color (`STANDALONE_VALUE`) defaults to `mode: 'auto'`\n * across every value-shorthand form.\n *\n * When the user requests `contrast` or relative `tone`, a hidden\n * `STANDALONE_SEED` def is synthesized at `mode: 'static'`. That keeps\n * the seed pinned to the literal user-provided color across all four\n * variants, so the contrast solver always anchors against it.\n */\nfunction buildStandaloneValueDefs(\n main: OkhslColor,\n options: GlazeColorOverrides | undefined,\n): ValueDefsResult {\n const seedHue = typeof options?.hue === 'number' ? options.hue : main.h;\n const seedSaturation = options?.saturation ?? main.s * 100;\n const relativeHue =\n typeof options?.hue === 'string' ? options.hue : undefined;\n\n const toneOption = options?.tone;\n const hasExternalBase = options?.base !== undefined;\n // Seed-anchor synthesis only kicks in when the user did NOT supply their\n // own base — in that case `contrast` and relative `tone` anchor to\n // the literal seed via the hidden `STANDALONE_SEED` def.\n const needsSeedAnchor =\n !hasExternalBase &&\n (options?.contrast !== undefined ||\n (toneOption !== undefined && !isAbsoluteTone(toneOption)));\n\n if (options?.opacity !== undefined)\n validateStandaloneOpacity(options.opacity);\n\n const userName = options?.name;\n if (userName !== undefined) validateStandaloneName(userName);\n const primary = userName ?? STANDALONE_VALUE;\n\n // The seed color is given in OKHSL lightness; express it as canonical tone.\n const seedTone = toTone(main.l);\n\n const valueDef: RegularColorDef = {\n hue: relativeHue,\n saturation: options?.saturationFactor,\n tone: toneOption ?? seedTone,\n contrast: options?.contrast,\n mode: options?.mode ?? 'auto',\n autoFlip: options?.autoFlip,\n opacity: options?.opacity,\n pastel: options?.pastel,\n role: options?.role,\n base: hasExternalBase\n ? STANDALONE_BASE\n : needsSeedAnchor\n ? STANDALONE_SEED\n : undefined,\n };\n\n const defs: ColorMap = { [primary]: valueDef };\n\n if (needsSeedAnchor) {\n defs[STANDALONE_SEED] = {\n hue: main.h,\n saturation: 1,\n tone: seedTone,\n mode: 'static',\n };\n }\n\n return {\n seedHue,\n seedSaturation,\n defs,\n primary,\n };\n}\n\nfunction createColorTokenFromDefs(\n seedHue: number,\n seedSaturation: number,\n defs: ColorMap,\n primary: string,\n configOverride: GlazeConfigOverride | undefined,\n baseToken: GlazeColorToken | undefined,\n buildExport: (override?: GlazeConfigOverride) => GlazeColorTokenExport,\n): GlazeColorToken {\n let cache: {\n map: Map<string, ResolvedColor> | null;\n version: number;\n effectiveConfig: GlazeConfigResolved;\n } | null = null;\n\n function getEffectiveConfig(): GlazeConfigResolved {\n const version = getConfigVersion();\n if (cache && cache.version === version) return cache.effectiveConfig;\n const effectiveConfig = mergeConfig(getConfig(), configOverride);\n cache = { map: null, version, effectiveConfig };\n return effectiveConfig;\n }\n\n const resolveOnce = (): Map<string, ResolvedColor> => {\n const version = getConfigVersion();\n if (cache && cache.version === version && cache.map) return cache.map;\n const effectiveConfig = getEffectiveConfig();\n const externalBases = baseToken\n ? new Map([[STANDALONE_BASE, baseToken.resolve()]])\n : undefined;\n const map = resolveAllColors(\n seedHue,\n seedSaturation,\n defs,\n effectiveConfig,\n externalBases,\n );\n cache = { map, version, effectiveConfig };\n return map;\n };\n\n const resolveStates = (options?: GlazeTokenOptions) => {\n const cfg = getConfig();\n return {\n dark: options?.states?.dark ?? cfg.states.dark,\n highContrast: options?.states?.highContrast ?? cfg.states.highContrast,\n };\n };\n\n const tokenLike = (options?: GlazeTokenOptions): Record<string, string> => {\n const tokenMap = buildTokenMap(\n resolveOnce(),\n '',\n resolveStates(options),\n resolveModes(options?.modes),\n options?.format ?? 'oklch',\n getEffectiveConfig().pastel,\n );\n return tokenMap[`#${primary}`];\n };\n\n return {\n resolve(): ResolvedColor {\n return resolveOnce().get(primary)!;\n },\n\n token: tokenLike,\n tasty: tokenLike,\n\n json(options?: GlazeJsonOptions): Record<string, string> {\n const format = options?.format ?? 'oklch';\n assertNativeFormat(format, 'json');\n const jsonMap = buildJsonMap(\n resolveOnce(),\n resolveModes(options?.modes),\n format,\n getEffectiveConfig().pastel,\n );\n return jsonMap[primary];\n },\n\n css(options: GlazeColorCssOptions): GlazeCssResult {\n const format = options.format ?? 'oklch';\n assertNativeFormat(format, 'css');\n const resolved = resolveOnce().get(primary)!;\n const renamed = new Map<string, ResolvedColor>([\n [options.name, resolved],\n ]);\n\n let channelCtx: ChannelCtx | undefined;\n if (options.splitHue && format === 'oklch') {\n const modes = resolveModes();\n assertAllPastel(renamed, modes);\n channelCtx = {\n seedHue,\n baseName: options.name,\n prefix: '',\n defs: { [options.name]: defs[primary] },\n mode: 'standalone',\n resolvedHue: resolved.light.h,\n };\n }\n\n return buildCssMap(\n renamed,\n '',\n options.suffix ?? '-color',\n format,\n getEffectiveConfig().pastel,\n channelCtx,\n );\n },\n\n dtcg(options?: GlazeDtcgOptions): GlazeColorDtcgResult {\n const modes = resolveModes(options?.modes);\n const doc = buildDtcgMap(\n resolveOnce(),\n '',\n modes,\n options?.colorSpace ?? 'srgb',\n getEffectiveConfig().pastel,\n );\n const result: GlazeColorDtcgResult = { light: doc.light[primary] };\n if (doc.dark) result.dark = doc.dark[primary];\n if (doc.lightContrast) {\n result.lightContrast = doc.lightContrast[primary];\n }\n if (doc.darkContrast) result.darkContrast = doc.darkContrast[primary];\n return result;\n },\n\n dtcgResolver(\n options: GlazeColorDtcgResolverOptions,\n ): GlazeDtcgResolverDocument {\n const doc = buildDtcgMap(\n resolveOnce(),\n '',\n resolveModes(options?.modes),\n options?.colorSpace ?? 'srgb',\n getEffectiveConfig().pastel,\n );\n const name = options.name;\n const result: GlazeDtcgResult = {\n light: { [name]: doc.light[primary] },\n };\n if (doc.dark) result.dark = { [name]: doc.dark[primary] };\n if (doc.lightContrast) {\n result.lightContrast = { [name]: doc.lightContrast[primary] };\n }\n if (doc.darkContrast) {\n result.darkContrast = { [name]: doc.darkContrast[primary] };\n }\n return buildDtcgResolver(result, options);\n },\n\n tailwind(options: GlazeColorTailwindOptions): string {\n const format = options.format ?? 'oklch';\n assertNativeFormat(format, 'tailwind');\n const renamed = new Map<string, ResolvedColor>([\n [options.name, resolveOnce().get(primary)!],\n ]);\n return buildTailwindMap(\n renamed,\n '',\n options.namespace ?? 'color-',\n resolveModes(options?.modes),\n format,\n options.darkSelector ?? '.dark',\n options.highContrastSelector ?? '.high-contrast',\n getEffectiveConfig().pastel,\n );\n },\n\n export(override?: GlazeConfigOverride): GlazeColorTokenExport {\n return buildExport(override);\n },\n };\n}\n\n/**\n * When a value/`from` color links to a base that was created via the\n * structured form (with explicit `hue`/`saturation`/`tone`), resolve\n * that base with `lightTone: false` for the linking math so the\n * contrast/tone anchor matches the input tone — not the\n * windowed output. The original base token's `.resolve()` is unaffected.\n */\nfunction toLinkingBase(\n base: GlazeColorToken | undefined,\n): GlazeColorToken | undefined {\n if (!base) return undefined;\n const exp = base.export();\n if (exp.form !== 'structured') return base;\n const linkingConfig: GlazeConfigOverride = {\n ...(exp.config ?? {}),\n lightTone: false,\n };\n return colorFromExport({ ...exp, config: linkingConfig });\n}\n\n/**\n * Resolve `base` (which may be a token reference or a raw color value)\n * into a `GlazeColorToken`. Raw values are auto-wrapped via\n * `createColorTokenFromValue` so they pick up the same auto-invert\n * defaults as an explicit wrap. Returns `undefined` when no base is provided.\n */\nfunction resolveBaseToken(\n base: GlazeColorToken | GlazeColorValue | undefined,\n): GlazeColorToken | undefined {\n if (base === undefined) return undefined;\n if (isGlazeColorToken(base)) return base;\n return createColorTokenFromValue(base, undefined, undefined);\n}\n\n/**\n * Discriminate a `GlazeColorToken` from a raw `GlazeColorValue`.\n */\nexport function isGlazeColorToken(\n candidate: GlazeColorToken | GlazeColorValue,\n): candidate is GlazeColorToken {\n return (\n typeof candidate === 'object' &&\n candidate !== null &&\n !Array.isArray(candidate) &&\n 'resolve' in candidate &&\n typeof (candidate as { resolve?: unknown }).resolve === 'function'\n );\n}\n\n// ============================================================================\n// Factory: structured input\n// ============================================================================\n\nexport function createColorToken(\n input: GlazeColorInput,\n configOverride?: GlazeConfigOverride,\n): GlazeColorToken {\n validateStructuredInput(input);\n\n const userName = input.name;\n if (userName !== undefined) validateStandaloneName(userName);\n const primary = userName ?? STANDALONE_VALUE;\n\n const baseToken = resolveBaseToken(input.base);\n const hasExternalBase = baseToken !== undefined;\n const needsSeedAnchor = !hasExternalBase && input.contrast !== undefined;\n\n const defs: ColorMap = {\n [primary]: {\n tone: input.tone,\n saturation: input.saturationFactor,\n mode: input.mode ?? 'auto',\n autoFlip: input.autoFlip,\n contrast: input.contrast,\n opacity: input.opacity,\n pastel: input.pastel,\n role: input.role,\n base: hasExternalBase\n ? STANDALONE_BASE\n : needsSeedAnchor\n ? STANDALONE_SEED\n : undefined,\n },\n };\n\n if (needsSeedAnchor) {\n const seedTone = pairNormal(input.tone);\n defs[STANDALONE_SEED] = {\n // The seed anchor must be a concrete tone; resolve 'max'/'min' to its\n // extreme so the static anchor is well-defined.\n tone: seedTone === 'max' ? 100 : seedTone === 'min' ? 0 : seedTone,\n saturation: 1,\n mode: 'static',\n };\n }\n\n const localOverride = configOverride;\n\n return createColorTokenFromDefs(\n input.hue,\n input.saturation,\n defs,\n primary,\n localOverride,\n baseToken,\n (exportArg) => ({\n kind: 'color',\n version: GLAZE_EXPORT_VERSION,\n form: 'structured',\n input: buildStructuredInputExport(input, exportArg),\n config: freezeConfigForExport(localOverride, exportArg),\n }),\n );\n}\n\n// ============================================================================\n// Factory: value-shorthand input\n// ============================================================================\n\nexport function createColorTokenFromValue(\n value: GlazeColorValue,\n options: GlazeColorOverrides | undefined,\n configOverride: GlazeConfigOverride | undefined,\n): GlazeColorToken {\n const main = extractOkhslFromValue(value);\n const rawBaseToken = resolveBaseToken(options?.base);\n // For linking math, structured bases are re-resolved at full range\n // (lightTone: false) so contrast/tone anchors use the\n // input tone, not the windowed output.\n const linkingBase = toLinkingBase(rawBaseToken);\n const { seedHue, seedSaturation, defs, primary } = buildStandaloneValueDefs(\n main,\n options,\n );\n\n const localOverride = sparseValueFormLocal(configOverride);\n\n return createColorTokenFromDefs(\n seedHue,\n seedSaturation,\n defs,\n primary,\n localOverride,\n linkingBase,\n (exportArg) => ({\n kind: 'color',\n version: GLAZE_EXPORT_VERSION,\n form: 'value',\n input: value,\n ...(options !== undefined\n ? { overrides: buildOverridesExport(options, exportArg) }\n : {}),\n config: freezeConfigForExport(localOverride, exportArg),\n }),\n );\n}\n\n// ============================================================================\n// Export / rehydrate\n// ============================================================================\n\n/**\n * Build a JSON-safe snapshot of `GlazeColorOverrides`. `base` is\n * recursively serialized when it was originally a token; raw values are\n * preserved as-is so `glaze.colorFrom(...)` round-trips them.\n */\nfunction buildOverridesExport(\n options: GlazeColorOverrides,\n exportArg?: GlazeConfigOverride,\n): GlazeColorOverridesExport {\n const out: GlazeColorOverridesExport = {};\n if (options.hue !== undefined) out.hue = options.hue;\n if (options.saturation !== undefined) out.saturation = options.saturation;\n if (options.tone !== undefined) out.tone = options.tone;\n if (options.saturationFactor !== undefined) {\n out.saturationFactor = options.saturationFactor;\n }\n if (options.mode !== undefined) out.mode = options.mode;\n if (options.autoFlip !== undefined) out.autoFlip = options.autoFlip;\n if (options.contrast !== undefined) out.contrast = options.contrast;\n if (options.opacity !== undefined) out.opacity = options.opacity;\n if (options.name !== undefined) out.name = options.name;\n if (options.pastel !== undefined) out.pastel = options.pastel;\n if (options.role !== undefined) out.role = options.role;\n if (options.base !== undefined) {\n out.base = isGlazeColorToken(options.base)\n ? options.base.export(exportArg)\n : options.base;\n }\n return out;\n}\n\nfunction buildStructuredInputExport(\n input: GlazeColorInput,\n exportArg?: GlazeConfigOverride,\n): GlazeColorInputExport {\n const out: GlazeColorInputExport = {\n hue: input.hue,\n saturation: input.saturation,\n tone: input.tone,\n };\n if (input.saturationFactor !== undefined) {\n out.saturationFactor = input.saturationFactor;\n }\n if (input.mode !== undefined) out.mode = input.mode;\n if (input.autoFlip !== undefined) out.autoFlip = input.autoFlip;\n if (input.opacity !== undefined) out.opacity = input.opacity;\n if (input.contrast !== undefined) out.contrast = input.contrast;\n if (input.name !== undefined) out.name = input.name;\n if (input.pastel !== undefined) out.pastel = input.pastel;\n if (input.role !== undefined) out.role = input.role;\n if (input.base !== undefined) {\n out.base = isGlazeColorToken(input.base)\n ? input.base.export(exportArg)\n : input.base;\n }\n return out;\n}\n\n/**\n * Discriminate a `GlazeColorTokenExport` from a raw `GlazeColorValue`.\n */\nfunction isExportedToken(\n candidate: GlazeColorTokenExport | GlazeColorValue,\n): candidate is GlazeColorTokenExport {\n return isColorTokenExport(candidate);\n}\n\nfunction rehydrateOverrides(\n data: GlazeColorOverridesExport,\n): GlazeColorOverrides {\n const out: GlazeColorOverrides = {};\n if (data.hue !== undefined) out.hue = data.hue;\n if (data.saturation !== undefined) out.saturation = data.saturation;\n if (data.tone !== undefined) out.tone = data.tone;\n if (data.saturationFactor !== undefined) {\n out.saturationFactor = data.saturationFactor;\n }\n if (data.mode !== undefined) out.mode = data.mode;\n if (data.autoFlip !== undefined) out.autoFlip = data.autoFlip;\n if (data.contrast !== undefined) out.contrast = data.contrast;\n if (data.opacity !== undefined) out.opacity = data.opacity;\n if (data.name !== undefined) out.name = data.name;\n if (data.pastel !== undefined) out.pastel = data.pastel;\n if (data.role !== undefined) out.role = data.role;\n if (data.base !== undefined) {\n out.base = isExportedToken(data.base)\n ? colorFromExport(data.base)\n : data.base;\n }\n return out;\n}\n\nfunction rehydrateStructuredInput(\n data: GlazeColorInputExport,\n): GlazeColorInput {\n const out: GlazeColorInput = {\n hue: data.hue,\n saturation: data.saturation,\n tone: data.tone,\n };\n if (data.saturationFactor !== undefined) {\n out.saturationFactor = data.saturationFactor;\n }\n if (data.mode !== undefined) out.mode = data.mode;\n if (data.autoFlip !== undefined) out.autoFlip = data.autoFlip;\n if (data.opacity !== undefined) out.opacity = data.opacity;\n if (data.contrast !== undefined) out.contrast = data.contrast;\n if (data.name !== undefined) out.name = data.name;\n if (data.pastel !== undefined) out.pastel = data.pastel;\n if (data.role !== undefined) out.role = data.role;\n if (data.base !== undefined) {\n out.base = isExportedToken(data.base)\n ? colorFromExport(data.base)\n : data.base;\n }\n return out;\n}\n\n/**\n * Rehydrate a token from its `.export()` snapshot. Recursively rebuilds\n * any base dependency. Inverse of `GlazeColorToken.export()`.\n *\n * The stored `config` field is the freeze from export time — passed as\n * the instance local override so the rehydrated token stays pinned\n * against later `glaze.configure()` calls.\n */\nexport function colorFromExport(data: GlazeColorTokenExport): GlazeColorToken {\n if (data === null || typeof data !== 'object') {\n throw new Error(\n `glaze.colorFrom: expected an object from token.export(), got ${data === null ? 'null' : typeof data}.`,\n );\n }\n assertExportKind(data, 'color', 'glaze.colorFrom');\n assertExportVersion(data, 'glaze.colorFrom');\n if (data.form !== 'value' && data.form !== 'structured') {\n throw new Error(\n `glaze.colorFrom: invalid \"form\" field — expected \"value\" or \"structured\" (got ${JSON.stringify((data as { form?: unknown }).form)}).`,\n );\n }\n if (data.input === undefined) {\n throw new Error(\n `glaze.colorFrom: missing \"input\" field — expected the original ${data.form === 'value' ? 'GlazeColorValue' : 'GlazeColorInput'}.`,\n );\n }\n\n if (data.form === 'value') {\n const value = data.input as GlazeColorValue;\n const overrides = data.overrides\n ? rehydrateOverrides(data.overrides)\n : undefined;\n return createColorTokenFromValue(value, overrides, data.config);\n }\n\n const input = rehydrateStructuredInput(data.input as GlazeColorInputExport);\n return createColorToken(input, data.config);\n}\n","/**\n * Theme factory.\n *\n * Wraps a hue/saturation seed, a mutable `ColorMap`, and an optional\n * per-theme `GlazeConfigOverride`. Exposes `tokens()` / `tasty()` /\n * `json()` / `css()` / `dtcg()` / `dtcgResolver()` / `tailwind()` / `resolve()` /\n * `export()` / `extend()`.\n *\n * The per-theme config override is **merged over the live global config at\n * resolve time** so the theme still reacts to later `configure()` calls\n * for fields it didn't override. The merged config is memoized by\n * `configVersion` to avoid rebuilding it on every export call.\n */\n\nimport type { ChannelCtx } from './channels';\nimport {\n freezeConfigForExport,\n getConfig,\n getConfigVersion,\n mergeConfig,\n} from './config';\nimport { assertAllPastel, assertNativeFormat } from './format-guard';\nimport {\n buildCssMap,\n buildDtcgMap,\n buildDtcgResolver,\n buildFlatTokenMap,\n buildJsonMap,\n buildTailwindMap,\n buildTokenMap,\n resolveModes,\n} from './formatters';\nimport { resolveAllColors } from './resolver';\nimport { GLAZE_EXPORT_VERSION } from './serialize';\nimport type {\n ColorDef,\n ColorMap,\n GlazeConfigOverride,\n GlazeConfigResolved,\n GlazeCssOptions,\n GlazeCssResult,\n GlazeDtcgOptions,\n GlazeDtcgResolverDocument,\n GlazeDtcgResolverOptions,\n GlazeDtcgResult,\n GlazeExtendOptions,\n GlazeJsonOptions,\n GlazeTailwindOptions,\n GlazeTheme,\n GlazeThemeExport,\n GlazeTokenOptions,\n ResolvedColor,\n} from './types';\n\nexport function createTheme(\n hue: number,\n saturation: number,\n initialColors?: ColorMap,\n configOverride?: GlazeConfigOverride,\n): GlazeTheme {\n let colorDefs: ColorMap = initialColors ? { ...initialColors } : {};\n\n let cache: {\n map: Map<string, ResolvedColor> | null;\n version: number;\n effectiveConfig: GlazeConfigResolved;\n } | null = null;\n\n function getEffectiveConfig(): GlazeConfigResolved {\n const version = getConfigVersion();\n if (cache && cache.version === version) return cache.effectiveConfig;\n const effectiveConfig = mergeConfig(getConfig(), configOverride);\n cache = { map: null, version, effectiveConfig };\n return effectiveConfig;\n }\n\n function resolveCached(): Map<string, ResolvedColor> {\n const version = getConfigVersion();\n if (cache && cache.version === version && cache.map) return cache.map;\n const effectiveConfig = getEffectiveConfig();\n const map = resolveAllColors(hue, saturation, colorDefs, effectiveConfig);\n cache = { map, version, effectiveConfig };\n return map;\n }\n\n function invalidate(): void {\n cache = null;\n }\n\n function channelCtxFor(\n options:\n | {\n splitHue?: boolean;\n name?: string;\n format?: GlazeCssOptions['format'];\n modes?: GlazeJsonOptions['modes'];\n }\n | undefined,\n formatDefault: 'rgb' | 'oklch' | 'okhsl',\n prefix: string,\n ): ChannelCtx | undefined {\n const format = options?.format ?? formatDefault;\n if (!options?.splitHue || format !== 'oklch') return undefined;\n const resolved = resolveCached();\n const modes = resolveModes(options?.modes);\n assertAllPastel(resolved, modes);\n return {\n seedHue: hue,\n baseName: options.name ?? 'theme',\n prefix,\n defs: colorDefs,\n mode: 'theme',\n };\n }\n\n const theme: GlazeTheme = {\n get hue() {\n return hue;\n },\n get saturation() {\n return saturation;\n },\n getConfig(): GlazeConfigResolved {\n return getEffectiveConfig();\n },\n\n colors(defs: ColorMap): void {\n colorDefs = { ...colorDefs, ...defs };\n invalidate();\n },\n\n color(name: string, def?: ColorDef): ColorDef | undefined | void {\n if (def === undefined) {\n return colorDefs[name];\n }\n colorDefs[name] = def;\n invalidate();\n },\n\n remove(names: string | string[]): void {\n const list = Array.isArray(names) ? names : [names];\n for (const name of list) {\n delete colorDefs[name];\n }\n invalidate();\n },\n\n has(name: string): boolean {\n return name in colorDefs;\n },\n\n list(): string[] {\n return Object.keys(colorDefs);\n },\n\n reset(): void {\n colorDefs = {};\n invalidate();\n },\n\n export(override?: GlazeConfigOverride): GlazeThemeExport {\n return {\n kind: 'theme',\n version: GLAZE_EXPORT_VERSION,\n hue,\n saturation,\n colors: structuredClone(colorDefs),\n config: freezeConfigForExport(configOverride, override),\n };\n },\n\n extend(options: GlazeExtendOptions): GlazeTheme {\n const newHue = options.hue ?? hue;\n const newSat = options.saturation ?? saturation;\n\n const inheritedColors: ColorMap = {};\n for (const [name, def] of Object.entries(colorDefs)) {\n if (def.inherit !== false) {\n inheritedColors[name] = def;\n }\n }\n\n const mergedColors = options.colors\n ? { ...inheritedColors, ...options.colors }\n : { ...inheritedColors };\n\n // Child inherits the parent override then merges in the per-extend override.\n const mergedConfigOverride: GlazeConfigOverride | undefined =\n configOverride || options.config\n ? { ...(configOverride ?? {}), ...(options.config ?? {}) }\n : undefined;\n\n return createTheme(newHue, newSat, mergedColors, mergedConfigOverride);\n },\n\n resolve(): Map<string, ResolvedColor> {\n // Defensive shallow clone: the cache holds the canonical Map for\n // internal exporters; callers that mutate the returned Map must\n // not corrupt subsequent cached reads.\n return new Map(resolveCached());\n },\n\n tokens(options?: GlazeJsonOptions): Record<string, Record<string, string>> {\n const format = options?.format ?? 'oklch';\n assertNativeFormat(format, 'tokens');\n const modes = resolveModes(options?.modes);\n return buildFlatTokenMap(\n resolveCached(),\n '',\n modes,\n format,\n getEffectiveConfig().pastel,\n );\n },\n\n tasty(options?: GlazeTokenOptions): Record<string, Record<string, string>> {\n const cfg = getEffectiveConfig();\n const states = {\n dark: options?.states?.dark ?? cfg.states.dark,\n highContrast: options?.states?.highContrast ?? cfg.states.highContrast,\n };\n const modes = resolveModes(options?.modes);\n const format = options?.format ?? 'oklch';\n const channelCtx = channelCtxFor(options, 'oklch', '');\n return buildTokenMap(\n resolveCached(),\n '',\n states,\n modes,\n format,\n cfg.pastel,\n channelCtx,\n );\n },\n\n json(options?: GlazeJsonOptions): Record<string, Record<string, string>> {\n const format = options?.format ?? 'oklch';\n assertNativeFormat(format, 'json');\n const modes = resolveModes(options?.modes);\n return buildJsonMap(\n resolveCached(),\n modes,\n format,\n getEffectiveConfig().pastel,\n );\n },\n\n css(options?: GlazeCssOptions): GlazeCssResult {\n const format = options?.format ?? 'oklch';\n assertNativeFormat(format, 'css');\n const channelCtx = channelCtxFor(options, 'oklch', '');\n return buildCssMap(\n resolveCached(),\n '',\n options?.suffix ?? '-color',\n format,\n getEffectiveConfig().pastel,\n channelCtx,\n );\n },\n\n dtcg(options?: GlazeDtcgOptions): GlazeDtcgResult {\n const modes = resolveModes(options?.modes);\n return buildDtcgMap(\n resolveCached(),\n '',\n modes,\n options?.colorSpace ?? 'srgb',\n getEffectiveConfig().pastel,\n );\n },\n\n dtcgResolver(\n options?: GlazeDtcgResolverOptions,\n ): GlazeDtcgResolverDocument {\n const result = buildDtcgMap(\n resolveCached(),\n '',\n resolveModes(options?.modes),\n options?.colorSpace ?? 'srgb',\n getEffectiveConfig().pastel,\n );\n return buildDtcgResolver(result, options);\n },\n\n tailwind(options?: GlazeTailwindOptions): string {\n const format = options?.format ?? 'oklch';\n assertNativeFormat(format, 'tailwind');\n const modes = resolveModes(options?.modes);\n return buildTailwindMap(\n resolveCached(),\n '',\n options?.namespace ?? 'color-',\n modes,\n format,\n options?.darkSelector ?? '.dark',\n options?.highContrastSelector ?? '.high-contrast',\n getEffectiveConfig().pastel,\n );\n },\n } as GlazeTheme;\n\n return theme;\n}\n","/**\n * Palette factory.\n *\n * Composes multiple themes into a single token namespace with optional\n * theme-name prefixes and a \"primary theme\" that also surfaces an\n * unprefixed copy of its tokens. All seven export methods (`tokens` /\n * `tasty` / `json` / `css` / `dtcg` / `dtcgResolver` / `tailwind`) share a\n * `buildPaletteOutput` driver that handles validation, per-theme iteration,\n * prefix resolution, collision filtering, and primary duplication.\n *\n * Authoring round-trip: `palette.export()` / `createPaletteFromExport()`\n * (wired as `glaze.paletteFrom`).\n */\n\nimport type { ChannelCtx } from './channels';\nimport { getConfig } from './config';\nimport { assertAllPastel, assertNativeFormat } from './format-guard';\nimport {\n buildCssMap,\n buildDtcgMap,\n buildDtcgResolver,\n buildFlatTokenMap,\n buildJsonMap,\n buildTailwindLines,\n buildTokenMap,\n emitTailwindCss,\n resolveModes,\n} from './formatters';\nimport {\n assertExportKind,\n assertExportVersion,\n GLAZE_EXPORT_VERSION,\n} from './serialize';\nimport { createTheme } from './theme';\nimport type {\n ColorMap,\n GlazeCssOptions,\n GlazeCssResult,\n GlazeConfigOverride,\n GlazeDtcgOptions,\n GlazeDtcgResolverDocument,\n GlazeDtcgResolverOptions,\n GlazeDtcgResult,\n GlazeJsonOptions,\n GlazePalette,\n GlazePaletteExport,\n GlazePaletteExportOptions,\n GlazePaletteOptions,\n GlazeTailwindOptions,\n GlazeTheme,\n GlazeThemeExport,\n GlazeTokenOptions,\n ResolvedColor,\n} from './types';\nimport type { GlazeTailwindLines } from './formatters';\n\ntype PaletteInput = Record<string, GlazeTheme>;\n\nfunction resolvePrefix(\n options: { prefix?: boolean | Record<string, string> } | undefined,\n themeName: string,\n defaultPrefix = false,\n): string {\n const prefix = options?.prefix ?? defaultPrefix;\n if (prefix === true) {\n return `${themeName}-`;\n }\n if (typeof prefix === 'object' && prefix !== null) {\n return prefix[themeName] ?? `${themeName}-`;\n }\n return '';\n}\n\nfunction validatePrimaryTheme(\n primary: string | undefined,\n themes: PaletteInput,\n): void {\n if (primary !== undefined && !(primary in themes)) {\n const available = Object.keys(themes).join(', ');\n throw new Error(\n `glaze: primary theme \"${primary}\" not found in palette. Available: ${available}.`,\n );\n }\n}\n\n/**\n * Resolve the effective primary for an export call.\n * `false` disables, a string overrides, `undefined` inherits from palette.\n */\nfunction resolveEffectivePrimary(\n exportPrimary: string | false | undefined,\n palettePrimary: string | undefined,\n): string | undefined {\n if (exportPrimary === false) return undefined;\n return exportPrimary ?? palettePrimary;\n}\n\n/**\n * Filter a resolved color map, skipping keys already in `seen`.\n * Warns on collision and keeps the first-written value (first-write-wins).\n * Returns a new map containing only non-colliding entries.\n */\nfunction filterCollisions(\n resolved: Map<string, ResolvedColor>,\n prefix: string,\n seen: Map<string, string>,\n themeName: string,\n isPrimary?: boolean,\n): Map<string, ResolvedColor> {\n const filtered = new Map<string, ResolvedColor>();\n const label = isPrimary ? `${themeName} (primary)` : themeName;\n\n for (const [name, color] of resolved) {\n const key = `${prefix}${name}`;\n if (seen.has(key)) {\n console.warn(\n `glaze: token \"${key}\" from theme \"${label}\" collides with theme \"${seen.get(key)}\" — skipping.`,\n );\n continue;\n }\n seen.set(key, label);\n filtered.set(name, color);\n }\n return filtered;\n}\n\nfunction colorMapFromTheme(theme: GlazeTheme): ColorMap {\n const defs: ColorMap = {};\n for (const name of theme.list()) {\n const def = theme.color(name);\n if (def !== undefined) defs[name] = def;\n }\n return defs;\n}\n\nfunction channelCtxForTheme(\n theme: GlazeTheme,\n themeName: string,\n passPrefix: string,\n themedPrefix: string,\n splitHue: boolean | undefined,\n format: string,\n modes: ReturnType<typeof resolveModes>,\n filtered: Map<string, ResolvedColor>,\n): ChannelCtx | undefined {\n if (!splitHue || format !== 'oklch') return undefined;\n assertAllPastel(filtered, modes);\n return {\n seedHue: theme.hue,\n baseName: themeName,\n // Hue var names always follow the themed prefix so the primary's\n // unprefixed alias references `--{themeName}-*-hue` rather than colliding\n // with other themes' base vars.\n prefix: themedPrefix,\n defs: colorMapFromTheme(theme),\n mode: 'theme',\n // Emit declarations only in the pass whose color-prop prefix matches the\n // themed prefix (the prefixed pass, or the single pass when prefix:false).\n emitDeclarations: passPrefix === themedPrefix,\n };\n}\n\n/**\n * Shared per-theme driver for `tokens` / `tasty` / `css`. `json` skips\n * this because it doesn't do collision filtering or primary duplication.\n */\nfunction buildPaletteOutput<T, R>(\n themes: PaletteInput,\n paletteOptions: GlazePaletteOptions | undefined,\n options:\n | {\n prefix?: boolean | Record<string, string>;\n primary?: string | false;\n }\n | undefined,\n buildOne: (\n resolved: Map<string, ResolvedColor>,\n prefix: string,\n pastel: boolean,\n themeName: string,\n theme: GlazeTheme,\n ) => T,\n merge: (acc: R, part: T) => void,\n empty: () => R,\n): R {\n const effectivePrimary = resolveEffectivePrimary(\n options?.primary,\n paletteOptions?.primary,\n );\n if (options?.primary !== undefined) {\n validatePrimaryTheme(effectivePrimary, themes);\n }\n\n const acc = empty();\n const seen = new Map<string, string>();\n\n for (const [themeName, theme] of Object.entries(themes)) {\n const resolved = theme.resolve();\n const pastel = theme.getConfig().pastel;\n const prefix = resolvePrefix(options, themeName, true);\n const filtered = filterCollisions(resolved, prefix, seen, themeName);\n merge(acc, buildOne(filtered, prefix, pastel, themeName, theme));\n\n if (themeName === effectivePrimary) {\n const primaryFiltered = filterCollisions(\n resolved,\n '',\n seen,\n themeName,\n true,\n );\n merge(acc, buildOne(primaryFiltered, '', pastel, themeName, theme));\n }\n }\n\n return acc;\n}\n\n/** Rebuild a theme from a `theme.export()` snapshot. */\nexport function createThemeFromExport(\n data: GlazeThemeExport,\n factory = 'glaze.themeFrom',\n): GlazeTheme {\n if (data === null || typeof data !== 'object') {\n throw new Error(\n `${factory}: expected an object from theme.export(), got ${data === null ? 'null' : typeof data}.`,\n );\n }\n assertExportKind(data, 'theme', factory);\n assertExportVersion(data, factory);\n if (typeof data.hue !== 'number' || typeof data.saturation !== 'number') {\n throw new Error(\n `${factory}: expected numeric \"hue\" and \"saturation\" fields.`,\n );\n }\n return createTheme(data.hue, data.saturation, data.colors, data.config);\n}\n\n/**\n * Rebuild a palette from a `palette.export()` snapshot.\n */\nexport function createPaletteFromExport(\n data: GlazePaletteExport,\n): GlazePalette {\n if (data === null || typeof data !== 'object') {\n throw new Error(\n `glaze.paletteFrom: expected an object from palette.export(), got ${data === null ? 'null' : typeof data}.`,\n );\n }\n assertExportKind(data, 'palette', 'glaze.paletteFrom');\n assertExportVersion(data, 'glaze.paletteFrom');\n if (data.themes === null || typeof data.themes !== 'object') {\n throw new Error(\n `glaze.paletteFrom: expected a \"themes\" object map of theme exports.`,\n );\n }\n\n const rebuilt: PaletteInput = {};\n for (const [name, themeExport] of Object.entries(data.themes)) {\n rebuilt[name] = createThemeFromExport(\n themeExport,\n `glaze.paletteFrom (theme \"${name}\")`,\n );\n }\n\n return createPalette(rebuilt, {\n primary: data.primary,\n });\n}\n\nexport function createPalette(\n themes: PaletteInput,\n paletteOptions?: GlazePaletteOptions,\n): GlazePalette {\n validatePrimaryTheme(paletteOptions?.primary, themes);\n\n const buildDtcgResult = (\n options?: GlazeDtcgOptions & GlazePaletteExportOptions,\n ): GlazeDtcgResult => {\n const modes = resolveModes(options?.modes);\n const colorSpace = options?.colorSpace ?? 'srgb';\n return buildPaletteOutput<GlazeDtcgResult, GlazeDtcgResult>(\n themes,\n paletteOptions,\n options,\n (filtered, prefix, pastel, _themeName, _theme) =>\n buildDtcgMap(filtered, prefix, modes, colorSpace, pastel),\n (acc, part) => {\n Object.assign(acc.light, part.light);\n if (part.dark) {\n acc.dark = Object.assign(acc.dark ?? {}, part.dark);\n }\n if (part.lightContrast) {\n acc.lightContrast = Object.assign(\n acc.lightContrast ?? {},\n part.lightContrast,\n );\n }\n if (part.darkContrast) {\n acc.darkContrast = Object.assign(\n acc.darkContrast ?? {},\n part.darkContrast,\n );\n }\n },\n () => ({ light: {} }),\n );\n };\n\n return {\n list(): string[] {\n return Object.keys(themes);\n },\n\n get primary(): string | undefined {\n return paletteOptions?.primary;\n },\n\n theme(name: string): GlazeTheme | undefined {\n return themes[name];\n },\n\n themes(): Record<string, GlazeTheme> {\n return { ...themes };\n },\n\n export(override?: GlazeConfigOverride): GlazePaletteExport {\n const themesExport: Record<string, GlazeThemeExport> = {};\n for (const [name, theme] of Object.entries(themes)) {\n themesExport[name] = theme.export(override);\n }\n const out: GlazePaletteExport = {\n kind: 'palette',\n version: GLAZE_EXPORT_VERSION,\n themes: themesExport,\n };\n if (paletteOptions?.primary !== undefined) {\n out.primary = paletteOptions.primary;\n }\n return out;\n },\n\n tokens(\n options?: GlazeJsonOptions & GlazePaletteExportOptions,\n ): Record<string, Record<string, string>> {\n const format = options?.format ?? 'oklch';\n assertNativeFormat(format, 'tokens');\n const modes = resolveModes(options?.modes);\n return buildPaletteOutput<\n Record<string, Record<string, string>>,\n Record<string, Record<string, string>>\n >(\n themes,\n paletteOptions,\n options,\n (filtered, prefix, pastel) =>\n buildFlatTokenMap(filtered, prefix, modes, format, pastel),\n (acc, part) => {\n for (const variant of Object.keys(part)) {\n if (!acc[variant]) {\n acc[variant] = {};\n }\n Object.assign(acc[variant], part[variant]);\n }\n },\n () => ({}),\n );\n },\n\n tasty(\n options?: GlazeTokenOptions & GlazePaletteExportOptions,\n ): Record<string, Record<string, string>> {\n const cfg = getConfig();\n const states = {\n dark: options?.states?.dark ?? cfg.states.dark,\n highContrast: options?.states?.highContrast ?? cfg.states.highContrast,\n };\n const modes = resolveModes(options?.modes);\n const format = options?.format ?? 'oklch';\n return buildPaletteOutput<\n Record<string, Record<string, string>>,\n Record<string, Record<string, string>>\n >(\n themes,\n paletteOptions,\n options,\n (filtered, prefix, pastel, themeName, theme) => {\n const themedPrefix = resolvePrefix(options, themeName, true);\n const channelCtx = channelCtxForTheme(\n theme,\n themeName,\n prefix,\n themedPrefix,\n options?.splitHue,\n format,\n modes,\n filtered,\n );\n return buildTokenMap(\n filtered,\n prefix,\n states,\n modes,\n format,\n pastel,\n channelCtx,\n );\n },\n (acc, part) => Object.assign(acc, part),\n () => ({}),\n );\n },\n\n json(\n options?: GlazeJsonOptions & {\n prefix?: boolean | Record<string, string>;\n },\n ): Record<string, Record<string, Record<string, string>>> {\n const format = options?.format ?? 'oklch';\n assertNativeFormat(format, 'json');\n const modes = resolveModes(options?.modes);\n const result: Record<string, Record<string, Record<string, string>>> = {};\n\n for (const [themeName, theme] of Object.entries(themes)) {\n const resolved = theme.resolve();\n result[themeName] = buildJsonMap(\n resolved,\n modes,\n format,\n theme.getConfig().pastel,\n );\n }\n\n return result;\n },\n\n css(options?: GlazeCssOptions & GlazePaletteExportOptions): GlazeCssResult {\n const suffix = options?.suffix ?? '-color';\n const format = options?.format ?? 'oklch';\n assertNativeFormat(format, 'css');\n const modes = resolveModes();\n\n const lines = buildPaletteOutput<\n GlazeCssResult,\n Record<keyof GlazeCssResult, string[]>\n >(\n themes,\n paletteOptions,\n options,\n (filtered, prefix, pastel, themeName, theme) => {\n const themedPrefix = resolvePrefix(options, themeName, true);\n const channelCtx = channelCtxForTheme(\n theme,\n themeName,\n prefix,\n themedPrefix,\n options?.splitHue,\n format,\n modes,\n filtered,\n );\n return buildCssMap(\n filtered,\n prefix,\n suffix,\n format,\n pastel,\n channelCtx,\n );\n },\n (acc, part) => {\n for (const key of [\n 'light',\n 'dark',\n 'lightContrast',\n 'darkContrast',\n ] as const) {\n if (part[key]) {\n acc[key].push(part[key]);\n }\n }\n },\n () => ({\n light: [],\n dark: [],\n lightContrast: [],\n darkContrast: [],\n }),\n );\n\n return {\n light: lines.light.join('\\n'),\n dark: lines.dark.join('\\n'),\n lightContrast: lines.lightContrast.join('\\n'),\n darkContrast: lines.darkContrast.join('\\n'),\n };\n },\n\n dtcg(\n options?: GlazeDtcgOptions & GlazePaletteExportOptions,\n ): GlazeDtcgResult {\n return buildDtcgResult(options);\n },\n\n dtcgResolver(\n options?: GlazeDtcgResolverOptions & GlazePaletteExportOptions,\n ): GlazeDtcgResolverDocument {\n return buildDtcgResolver(buildDtcgResult(options), options);\n },\n\n tailwind(\n options?: GlazeTailwindOptions & GlazePaletteExportOptions,\n ): string {\n const modes = resolveModes(options?.modes);\n const cssPrefix = options?.namespace ?? 'color-';\n const format = options?.format ?? 'oklch';\n assertNativeFormat(format, 'tailwind');\n const darkSelector = options?.darkSelector ?? '.dark';\n const highContrastSelector =\n options?.highContrastSelector ?? '.high-contrast';\n\n const lines = buildPaletteOutput<GlazeTailwindLines, GlazeTailwindLines>(\n themes,\n paletteOptions,\n options,\n (filtered, prefix, pastel, _themeName, _theme) =>\n buildTailwindLines(filtered, prefix, cssPrefix, format, pastel),\n (acc, part) => {\n for (const variant of [\n 'light',\n 'dark',\n 'lightContrast',\n 'darkContrast',\n ] as const) {\n acc[variant].push(...part[variant]);\n }\n },\n () => ({\n light: [],\n dark: [],\n lightContrast: [],\n darkContrast: [],\n }),\n );\n\n return emitTailwindCss(lines, modes, darkSelector, highContrastSelector);\n },\n };\n}\n","/**\n * Glaze — OKHST color theme generator.\n *\n * Public API entry. Wires `glaze()` and its attached static methods to\n * the focused modules in this folder:\n * - `theme.ts` — single-theme factory\n * - `palette.ts` — multi-theme composition\n * - `color-token.ts` — standalone single-color tokens (`glaze.color`)\n * - `shadow.ts` — standalone shadow factory (`glaze.shadow`)\n * - `formatters.ts` — variant → string (`glaze.format`)\n * - `config.ts` — global config singleton\n * - `serialize.ts` — authoring export type guards / version checks\n */\n\nimport { parseHex, srgbToOkhsl } from './okhsl-color-math';\nimport {\n configure as configureImpl,\n getConfig,\n resetConfig as resetConfigImpl,\n snapshotConfig,\n} from './config';\nimport {\n colorFromExport,\n createColorToken,\n createColorTokenFromValue,\n extractOkhslFromValue,\n} from './color-token';\nimport { formatVariant } from './formatters';\nimport { computeShadow, resolveShadowTuning } from './shadow';\nimport { okhslToOkhst } from './okhst';\nimport {\n createPalette,\n createPaletteFromExport,\n createThemeFromExport,\n} from './palette';\nimport {\n isColorTokenExport,\n isPaletteExport,\n isThemeExport,\n} from './serialize';\nimport { createTheme } from './theme';\nimport type {\n GlazeColorFormat,\n GlazeColorInput,\n GlazeColorToken,\n GlazeColorTokenExport,\n GlazeColorValue,\n GlazeConfig,\n GlazeConfigOverride,\n GlazeConfigResolved,\n GlazeFromInput,\n GlazePalette,\n GlazePaletteExport,\n GlazePaletteOptions,\n GlazeShadowInput,\n GlazeTheme,\n GlazeThemeExport,\n ResolvedColorVariant,\n} from './types';\n\ntype PaletteInput = Record<string, GlazeTheme>;\n\n/**\n * Create a single-hue glaze theme.\n *\n * An optional `config` override can be supplied to customize the resolve\n * behavior for this theme (tone windows, etc.). The\n * override is **merged over the live global config at resolve time** —\n * the theme still reacts to later `configure()` calls for fields it\n * didn't override.\n *\n * @example\n * ```ts\n * const primary = glaze(280, 80);\n * // or shorthand:\n * const primary = glaze({ hue: 280, saturation: 80 });\n * // with config override:\n * const raw = glaze(280, 80, { lightTone: false });\n * ```\n */\nexport function glaze(\n hueOrOptions: number | { hue: number; saturation: number },\n saturation?: number,\n config?: GlazeConfigOverride,\n): GlazeTheme {\n if (typeof hueOrOptions === 'number') {\n return createTheme(hueOrOptions, saturation ?? 100, undefined, config);\n }\n return createTheme(\n hueOrOptions.hue,\n hueOrOptions.saturation,\n undefined,\n config,\n );\n}\n\n/** Configure global glaze settings. */\nglaze.configure = function configure(config: GlazeConfig): void {\n configureImpl(config);\n};\n\n/** Compose multiple themes into a palette. */\nglaze.palette = function palette(\n themes: PaletteInput,\n options?: GlazePaletteOptions,\n): GlazePalette {\n return createPalette(themes, options);\n};\n\n/**\n * Create a theme from a serialized `theme.export()` snapshot.\n * Prefer this over the legacy `glaze.from` alias.\n */\nglaze.themeFrom = function themeFrom(data: GlazeThemeExport): GlazeTheme {\n return createThemeFromExport(data);\n};\n\n/** Compat alias for `glaze.themeFrom`. */\nglaze.from = glaze.themeFrom;\n\n/**\n * Create a standalone single-color token.\n *\n * **arg1 — the color** (four accepted shapes, discriminated by structure):\n *\n * | Shape | Example | Notes |\n * |---|---|---|\n * | Bare string | `'#26fcb2'`, `'rgb(38 252 178)'` | Hex or CSS color function (incl. `okhst()`) |\n * | Value object | `{ h: 152, s: 0.95, l: 0.74 }` | OKHSL, OKHST (`{h,s,t}`), `{r,g,b}`, `{l,c,h}` |\n * | `{ from, ...overrides }` | `{ from: '#fff', base: bg, contrast: 'AA' }` | Value + color overrides |\n * | Structured | `{ hue: 152, saturation: 95, tone: 74 }` | Full theme-style token |\n *\n * **arg2 — config override** (optional, all shapes):\n * Overrides the resolve-relevant global config fields for this token.\n * Fields that are omitted fall through to the live global config at\n * resolve time. Pass `false` for a tone window to disable clamping\n * entirely. `pastel` is instance-only (not set via `configure()`).\n *\n * ```ts\n * // Bare string — no overrides\n * glaze.color('#26fcb2')\n *\n * // From form — value + color overrides\n * glaze.color({ from: '#fff', base: bg, contrast: 'AA' })\n *\n * // Structured form — full theme-style token\n * glaze.color({ hue: 152, saturation: 95, tone: 74 })\n *\n * // Config override on any form\n * glaze.color('#26fcb2', { darkTone: false, autoFlip: false })\n * glaze.color({ from: '#fff', base: bg })\n * ```\n *\n * Defaults: every form defaults to `mode: 'auto'`. Value-shorthand forms\n * (bare strings and value objects) preserve light tone exactly\n * (`lightTone: false` locally). Structured form falls through to the live\n * global tone windows for omitted fields.\n *\n * Relative `tone: '+N'` and `contrast` anchor to the literal seed by\n * default; when `base` is set they anchor to the base's resolved variant\n * per scheme. Relative `hue: '+N'` always anchors to the seed, not the base.\n */\nglaze.color = function color(\n input: GlazeFromInput | GlazeColorInput | GlazeColorValue,\n config?: GlazeConfigOverride,\n): GlazeColorToken {\n if (typeof input === 'string') {\n return createColorTokenFromValue(input, undefined, config);\n }\n\n // Object inputs — discriminate by key presence\n const obj = input as object;\n\n if ('from' in obj) {\n const { from, ...overrides } = input as GlazeFromInput;\n return createColorTokenFromValue(from, overrides, config);\n }\n\n if ('hue' in obj) {\n return createColorToken(input as GlazeColorInput, config);\n }\n\n // Value-object: { h, s, l }, { r, g, b }, or { l, c, h }\n return createColorTokenFromValue(input as GlazeColorValue, undefined, config);\n};\n\n/**\n * Compute a shadow color from a bg/fg pair and intensity.\n *\n * Both `bg` and `fg` accept any `GlazeColorValue` form: hex (`#rgb` /\n * `#rrggbb` / `#rrggbbaa`), `rgb()` / `hsl()` / `okhsl()` / `oklch()`\n * strings, or `{ r, g, b }` / `{ h, s, l }` / `{ l, c, h }` objects.\n */\nglaze.shadow = function shadow(input: GlazeShadowInput): ResolvedColorVariant {\n const bg = extractOkhslFromValue(input.bg as GlazeColorValue);\n const fg = input.fg\n ? extractOkhslFromValue(input.fg as GlazeColorValue)\n : undefined;\n const cfg = getConfig();\n const tuning = resolveShadowTuning(input.tuning, cfg.shadowTuning);\n const result = computeShadow(\n { ...bg, alpha: 1 },\n fg ? { ...fg, alpha: 1 } : undefined,\n input.intensity,\n tuning,\n );\n const { h, s, t } = okhslToOkhst({\n h: result.h,\n s: result.s,\n l: result.l,\n });\n return { h, s, t, alpha: result.alpha };\n};\n\n/** Format a resolved color variant as a CSS string. */\nglaze.format = function format(\n variant: ResolvedColorVariant,\n colorFormat?: GlazeColorFormat,\n pastel?: boolean,\n): string {\n return formatVariant(variant, colorFormat, pastel);\n};\n\n/**\n * Create a theme from a hex color string.\n * Extracts hue and saturation from the color.\n */\nglaze.fromHex = function fromHex(hex: string): GlazeTheme {\n const rgb = parseHex(hex);\n if (!rgb) {\n throw new Error(`glaze: invalid hex color \"${hex}\".`);\n }\n const [h, s] = srgbToOkhsl(rgb);\n return createTheme(h, s * 100);\n};\n\n/**\n * Create a theme from RGB values (0–255).\n * Extracts hue and saturation from the color.\n */\nglaze.fromRgb = function fromRgb(r: number, g: number, b: number): GlazeTheme {\n const [h, s] = srgbToOkhsl([r / 255, g / 255, b / 255]);\n return createTheme(h, s * 100);\n};\n\n/**\n * Rehydrate a `glaze.color()` token from a `.export()` snapshot.\n *\n * The snapshot is a plain JSON-safe object containing the original\n * input value, overrides (with any `base` token recursively serialized),\n * and the effective config freeze from export time. The reconstructed\n * token pins that freeze as its local override.\n *\n * @example\n * ```ts\n * const text = glaze.color({ from: '#1a1a1a', contrast: 'AA' });\n * const data = text.export(); // JSON-safe\n * localStorage.setItem('text', JSON.stringify(data));\n * // ...later...\n * const restored = glaze.colorFrom(JSON.parse(localStorage.getItem('text')!));\n * ```\n */\nglaze.colorFrom = function colorFrom(\n data: GlazeColorTokenExport,\n): GlazeColorToken {\n return colorFromExport(data);\n};\n\n/**\n * Rehydrate a palette from a `palette.export()` snapshot.\n */\nglaze.paletteFrom = function paletteFrom(\n data: GlazePaletteExport,\n): GlazePalette {\n return createPaletteFromExport(data);\n};\n\n/** Type guard for theme authoring snapshots. */\nglaze.isThemeExport = isThemeExport;\n\n/** Type guard for color-token authoring snapshots. */\nglaze.isColorTokenExport = isColorTokenExport;\n\n/** Type guard for palette authoring snapshots. */\nglaze.isPaletteExport = isPaletteExport;\n\n/** Get the current global configuration (for testing/debugging). */\nglaze.getConfig = function getConfig(): GlazeConfigResolved {\n return snapshotConfig();\n};\n\n/** Reset global configuration to defaults. */\nglaze.resetConfig = function resetConfig(): void {\n resetConfigImpl();\n};\n"],"mappings":"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"}