@tenphi/glaze 0.12.0 → 0.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +12 -10
- package/dist/index.cjs +980 -574
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +323 -193
- package/dist/index.d.mts +323 -193
- package/dist/index.mjs +970 -574
- package/dist/index.mjs.map +1 -1
- package/docs/api.md +300 -165
- package/docs/methodology.md +64 -54
- package/docs/migration.md +81 -10
- package/docs/okhst.md +224 -0
- package/package.json +1 -1
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":["fmt","configure","resetConfig"],"sources":["../src/okhsl-color-math.ts","../src/config.ts","../src/hc-pair.ts","../src/contrast-solver.ts","../src/shadow.ts","../src/scheme-mapping.ts","../src/validation.ts","../src/warnings.ts","../src/resolver.ts","../src/formatters.ts","../src/color-token.ts","../src/palette.ts","../src/theme.ts","../src/glaze.ts"],"sourcesContent":["/**\n * OKHSL color math primitives for the glaze theme generator.\n *\n * Provides bidirectional OKHSL ↔ sRGB conversion, relative luminance\n * computation for WCAG 2 contrast calculations, and multi-format output\n * (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;\nconst toe = (x: number): number =>\n 0.5 *\n (K3 * x - K1 + Math.sqrt((K3 * x - K1) * (K3 * x - K1) + 4 * K2 * K3 * x));\nconst toeInv = (x: number): number => (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\n// ============================================================================\n// Public API\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): [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 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 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): [number, number, number] {\n return OKLabToLinearSRGB(okhslToOklab(h, s, l));\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): [number, number, number] {\n const lin = okhslToLinearSrgb(h, s, l);\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// 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): 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 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 let s: number;\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 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): [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) 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(h: number, s: number, l: number): string {\n return `okhsl(${fmt(h, 2)} ${fmt(s, 2)}% ${fmt(l, 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(h: number, s: number, l: number): string {\n const [r, g, b] = okhslToSrgb(h, s / 100, l / 100);\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(h: number, s: number, l: number): string {\n const [r, g, b] = okhslToSrgb(h, s / 100, l / 100);\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(h: number, s: number, l: number): string {\n const [L, a, b] = okhslToOklab(h, s / 100, l / 100);\n const C = Math.sqrt(a * a + b * b);\n let hh = Math.atan2(b, a) * (180 / Math.PI);\n hh = constrainAngle(hh);\n\n return `oklch(${fmt(L, 4)} ${fmt(C, 4)} ${fmt(hh, 2)})`;\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. Standalone color tokens snapshot the relevant fields at\n * create time (see `color-token.ts`), so already-created tokens keep\n * their original behavior across later `configure()` calls.\n */\n\nimport type { GlazeConfig, GlazeConfigResolved } 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 */\nexport function defaultConfig(): GlazeConfigResolved {\n return {\n lightLightness: [10, 100],\n darkLightness: [15, 95],\n darkDesaturation: 0.1,\n darkCurve: 0.5,\n states: {\n dark: '@dark',\n highContrast: '@high-contrast',\n },\n modes: {\n dark: true,\n highContrast: false,\n },\n autoFlip: 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 lightLightness: config.lightLightness ?? globalConfig.lightLightness,\n darkLightness: config.darkLightness ?? globalConfig.darkLightness,\n darkDesaturation: config.darkDesaturation ?? globalConfig.darkDesaturation,\n darkCurve: config.darkCurve ?? globalConfig.darkCurve,\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 };\n}\n\nexport function resetConfig(): void {\n configVersion++;\n globalConfig = defaultConfig();\n}\n","/**\n * Small shared helpers used across the resolver pipeline:\n * - HC-pair selection (`pairNormal` / `pairHC`)\n * - Absolute / relative lightness discrimination\n * - Generic numeric helpers (`clamp`, hue resolution, relative-value parsing)\n */\n\nimport type { HCPair, RelativeValue } 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/**\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 * 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 lightness value represents an absolute root definition\n * (i.e. a number, not a relative string).\n */\nexport function isAbsoluteLightness(\n lightness: HCPair<number | RelativeValue> | undefined,\n): boolean {\n if (lightness === undefined) return false;\n const normal = Array.isArray(lightness) ? lightness[0] : lightness;\n return typeof normal === 'number';\n}\n","/**\n * OKHSL Contrast Solver\n *\n * Finds the closest OKHSL lightness that satisfies a WCAG 2 contrast target\n * against a base color. Used by glaze when resolving dependent colors\n * with `contrast`.\n */\n\nimport {\n okhslToLinearSrgb,\n contrastRatioFromLuminance,\n gamutClampedLuminance,\n} from './okhsl-color-math';\n\nexport type LinearRgb = [number, number, number];\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport type ContrastPreset = 'AA' | 'AAA' | 'AA-large' | 'AAA-large';\nexport type MinContrast = number | ContrastPreset;\n\nexport interface FindLightnessForContrastOptions {\n /** Hue of the candidate color (0–360). */\n hue: number;\n /** Saturation of the candidate color (0–1). */\n saturation: number;\n /** Preferred lightness of the candidate (0–1). */\n preferredLightness: number;\n\n /** Base/reference color as linear sRGB (channels may be outside 0–1 before clamp). */\n baseLinearRgb: [number, number, number];\n\n /** WCAG contrast ratio target floor. */\n contrast: MinContrast;\n\n /** Search bounds for lightness. Default: [0, 1]. */\n lightnessRange?: [number, number];\n /** Convergence threshold. Default: 1e-4. */\n epsilon?: number;\n /** Maximum binary-search iterations per branch. Default: 14. */\n maxIterations?: number;\n /**\n * Preferred search direction before auto-flip is considered.\n *\n * Theme resolution sets this from the requested lightness relative to\n * the base color so `autoFlip: false` preserves the authored direction.\n * When omitted, the solver falls back to the side whose extreme has\n * higher contrast against the base.\n */\n initialDirection?: 'lighter' | 'darker';\n /**\n * Auto-flip lightness direction when contrast can't be met.\n *\n * When `true`, the solver searches the initial direction first. If that side\n * doesn't reach the target, it tries the opposite direction and\n * uses it when it passes. If neither side passes, it returns the\n * extreme lightness of the initial direction.\n *\n * When `false`, only the initial direction is considered. If it\n * doesn't reach the target, the result is pinned to the initial\n * direction's extreme — never to the original preferred lightness.\n *\n * Default: false.\n */\n flip?: boolean;\n}\n\nexport interface FindLightnessForContrastResult {\n /** Chosen lightness in 0–1. */\n lightness: number;\n /** Achieved WCAG contrast ratio. */\n contrast: number;\n /** Whether the target was reached. */\n met: boolean;\n /** Which branch was selected. */\n branch: 'lighter' | 'darker' | 'preferred';\n /**\n * Whether the result was auto-flipped to the opposite direction.\n * Only set when the initial direction failed and the opposite\n * direction satisfied the target.\n */\n flipped?: boolean;\n}\n\n// ============================================================================\n// Preset mapping\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\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// LRU luminance cache\n// ============================================================================\n\nconst CACHE_SIZE = 512;\nconst luminanceCache = new Map<string, number>();\nconst cacheOrder: string[] = [];\n\nfunction cachedLuminance(h: number, s: number, l: number): number {\n const lRounded = Math.round(l * 10000) / 10000;\n const key = `${h}|${s}|${lRounded}`;\n\n const cached = luminanceCache.get(key);\n if (cached !== undefined) return cached;\n\n const linearRgb = okhslToLinearSrgb(h, s, lRounded);\n const y = gamutClampedLuminance(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// Solver\n// ============================================================================\n\ninterface BranchResult {\n lightness: number;\n contrast: number;\n met: boolean;\n}\n\n/**\n * Binary search one branch [lo, hi] for the nearest passing lightness to `preferred`.\n */\nfunction searchBranch(\n h: number,\n s: number,\n lo: number,\n hi: number,\n yBase: number,\n target: number,\n epsilon: number,\n maxIter: number,\n preferred: number,\n): BranchResult {\n const yLo = cachedLuminance(h, s, lo);\n const yHi = cachedLuminance(h, s, hi);\n const crLo = contrastRatioFromLuminance(yLo, yBase);\n const crHi = contrastRatioFromLuminance(yHi, yBase);\n\n if (crLo < target && crHi < target) {\n if (crLo >= crHi) {\n return { lightness: lo, contrast: crLo, met: false };\n }\n return { lightness: hi, contrast: crHi, 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\n const mid = (low + high) / 2;\n const yMid = cachedLuminance(h, s, mid);\n const crMid = contrastRatioFromLuminance(yMid, yBase);\n\n if (crMid >= target) {\n if (mid < preferred) {\n low = mid;\n } else {\n high = mid;\n }\n } else {\n if (mid < preferred) {\n high = mid;\n } else {\n low = mid;\n }\n }\n }\n\n const yLow = cachedLuminance(h, s, low);\n const yHigh = cachedLuminance(h, s, high);\n const crLow = contrastRatioFromLuminance(yLow, yBase);\n const crHigh = contrastRatioFromLuminance(yHigh, yBase);\n\n const lowPasses = crLow >= target;\n const highPasses = crHigh >= target;\n\n if (lowPasses && highPasses) {\n if (Math.abs(low - preferred) <= Math.abs(high - preferred)) {\n return { lightness: low, contrast: crLow, met: true };\n }\n return { lightness: high, contrast: crHigh, met: true };\n }\n if (lowPasses) return { lightness: low, contrast: crLow, met: true };\n if (highPasses) return { lightness: high, contrast: crHigh, met: true };\n\n return coarseScan(h, s, lo, hi, yBase, target, epsilon, maxIter);\n}\n\n/**\n * Fallback coarse scan when binary search is unstable near gamut edges.\n */\nfunction coarseScan(\n h: number,\n s: number,\n lo: number,\n hi: number,\n yBase: number,\n target: number,\n epsilon: number,\n maxIter: number,\n): BranchResult {\n const STEPS = 64;\n const step = (hi - lo) / STEPS;\n let bestL = lo;\n let bestCr = 0;\n let bestMet = false;\n\n for (let i = 0; i <= STEPS; i++) {\n const l = lo + step * i;\n const y = cachedLuminance(h, s, l);\n const cr = contrastRatioFromLuminance(y, yBase);\n\n if (cr >= target && !bestMet) {\n bestL = l;\n bestCr = cr;\n bestMet = true;\n } else if (cr >= target && bestMet) {\n bestL = l;\n bestCr = cr;\n } else if (!bestMet && cr > bestCr) {\n bestL = l;\n bestCr = cr;\n }\n }\n\n if (bestMet && bestL > lo + step) {\n let rLo = bestL - step;\n let rHi = bestL;\n for (let i = 0; i < maxIter; i++) {\n if (rHi - rLo < epsilon) break;\n const mid = (rLo + rHi) / 2;\n const y = cachedLuminance(h, s, mid);\n const cr = contrastRatioFromLuminance(y, yBase);\n if (cr >= target) {\n rHi = mid;\n bestL = mid;\n bestCr = cr;\n } else {\n rLo = mid;\n }\n }\n }\n\n return { lightness: bestL, contrast: bestCr, met: bestMet };\n}\n\n/**\n * Find the OKHSL lightness that satisfies a WCAG 2 contrast target\n * against a base color, staying as close to `preferredLightness` as possible.\n */\nexport function findLightnessForContrast(\n options: FindLightnessForContrastOptions,\n): FindLightnessForContrastResult {\n const {\n hue,\n saturation,\n preferredLightness,\n baseLinearRgb,\n contrast: contrastInput,\n lightnessRange = [0, 1],\n epsilon = 1e-4,\n maxIterations = 14,\n } = options;\n\n const target = resolveMinContrast(contrastInput);\n // Overshoot absorbs rounding in the OKHSL pipeline and OKLCH formatting\n const searchTarget = target * 1.01;\n const yBase = gamutClampedLuminance(baseLinearRgb);\n\n const yPref = cachedLuminance(hue, saturation, preferredLightness);\n const crPref = contrastRatioFromLuminance(yPref, yBase);\n\n if (crPref >= searchTarget) {\n return {\n lightness: preferredLightness,\n contrast: crPref,\n met: true,\n branch: 'preferred',\n };\n }\n\n const [minL, maxL] = lightnessRange;\n\n // Initial direction: caller-provided when the authored lightness hint\n // matters, otherwise the side whose extreme has higher contrast against\n // the base. The opposite direction is only considered when `flip` is\n // enabled; the fallback extreme also lives on the initial side.\n const canDarker = preferredLightness > minL;\n const canLighter = preferredLightness < maxL;\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 // Degenerate range — preferred == minL == maxL. Nothing to search.\n return {\n lightness: preferredLightness,\n contrast: crPref,\n met: false,\n branch: 'preferred',\n };\n } else {\n const yMinExt = cachedLuminance(hue, saturation, minL);\n const yMaxExt = cachedLuminance(hue, saturation, maxL);\n const crMinExt = contrastRatioFromLuminance(yMinExt, yBase);\n const crMaxExt = contrastRatioFromLuminance(yMaxExt, yBase);\n initialIsDarker = crMinExt >= crMaxExt;\n }\n\n const searchInitial = () =>\n initialIsDarker\n ? searchBranch(\n hue,\n saturation,\n minL,\n preferredLightness,\n yBase,\n searchTarget,\n epsilon,\n maxIterations,\n preferredLightness,\n )\n : searchBranch(\n hue,\n saturation,\n preferredLightness,\n maxL,\n yBase,\n searchTarget,\n epsilon,\n maxIterations,\n preferredLightness,\n );\n\n const searchOpposite = () =>\n initialIsDarker\n ? searchBranch(\n hue,\n saturation,\n preferredLightness,\n maxL,\n yBase,\n searchTarget,\n epsilon,\n maxIterations,\n preferredLightness,\n )\n : searchBranch(\n hue,\n saturation,\n minL,\n preferredLightness,\n yBase,\n searchTarget,\n epsilon,\n maxIterations,\n preferredLightness,\n );\n\n const initialBranchName: 'darker' | 'lighter' = initialIsDarker\n ? 'darker'\n : 'lighter';\n const oppositeBranchName: 'darker' | 'lighter' = initialIsDarker\n ? 'lighter'\n : 'darker';\n\n const initialResult = searchInitial();\n initialResult.met = initialResult.contrast >= target;\n\n // Initial direction passes — use it (closest passing point in that\n // direction). When auto-flip is enabled we also consider the opposite\n // direction in case it produces a result closer to `preferredLightness`.\n if (initialResult.met && !options.flip) {\n return { ...initialResult, branch: initialBranchName };\n }\n\n if (options.flip) {\n const canOpposite = initialIsDarker ? canLighter : canDarker;\n const oppositeResult = canOpposite ? searchOpposite() : null;\n if (oppositeResult) oppositeResult.met = oppositeResult.contrast >= target;\n\n if (initialResult.met && oppositeResult?.met) {\n const initialDist = Math.abs(\n initialResult.lightness - preferredLightness,\n );\n const oppositeDist = Math.abs(\n oppositeResult.lightness - preferredLightness,\n );\n if (initialDist <= oppositeDist) {\n return { ...initialResult, branch: initialBranchName };\n }\n return {\n ...oppositeResult,\n branch: oppositeBranchName,\n flipped: true,\n };\n }\n\n if (initialResult.met) {\n return { ...initialResult, branch: initialBranchName };\n }\n\n if (oppositeResult?.met) {\n return {\n ...oppositeResult,\n branch: oppositeBranchName,\n flipped: true,\n };\n }\n }\n\n // Failure: pin to the initial direction's extreme.\n const extreme = initialIsDarker ? minL : maxL;\n const yExtreme = cachedLuminance(hue, saturation, extreme);\n const crExtreme = contrastRatioFromLuminance(yExtreme, yBase);\n return {\n lightness: extreme,\n contrast: crExtreme,\n met: false,\n branch: initialBranchName,\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 /** WCAG contrast target. */\n contrast: MinContrast;\n /**\n * Compute the luminance of the mixed color at parameter t.\n * For opaque: luminance of OKHSL-interpolated color.\n * For transparent: luminance of alpha-composited color over base.\n */\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 /**\n * Auto-flip mix direction when contrast can't be met.\n *\n * When `true`, the solver searches the initial direction first\n * (the side whose extreme has higher contrast against the base).\n * If that side doesn't reach the target, it tries the opposite\n * direction and uses it when it passes. If neither side passes,\n * it returns the extreme mix value of the initial direction.\n *\n * When `false`, only the initial direction is considered. If it\n * doesn't reach the target, the result is pinned to the initial\n * direction's extreme — never to the original preferred value.\n *\n * Default: false.\n */\n flip?: boolean;\n}\n\nexport interface FindValueForMixContrastResult {\n /** Chosen mix parameter (0–1). */\n value: number;\n /** Achieved WCAG contrast ratio. */\n contrast: number;\n /** Whether the target was reached. */\n met: boolean;\n /**\n * Whether the result was auto-flipped to the opposite direction.\n * Only set when the initial direction failed and the opposite\n * direction satisfied the target.\n */\n flipped?: boolean;\n}\n\n/**\n * Binary-search one branch [lo, hi] for the nearest passing mix value\n * to `preferred`.\n */\nfunction searchMixBranch(\n lo: number,\n hi: number,\n yBase: number,\n target: number,\n epsilon: number,\n maxIter: number,\n preferred: number,\n luminanceAt: (t: number) => number,\n): BranchResult {\n const crLo = contrastRatioFromLuminance(luminanceAt(lo), yBase);\n const crHi = contrastRatioFromLuminance(luminanceAt(hi), yBase);\n\n if (crLo < target && crHi < target) {\n if (crLo >= crHi) {\n return { lightness: lo, contrast: crLo, met: false };\n }\n return { lightness: hi, contrast: crHi, 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\n const mid = (low + high) / 2;\n const crMid = contrastRatioFromLuminance(luminanceAt(mid), yBase);\n\n if (crMid >= target) {\n if (mid < preferred) low = mid;\n else high = mid;\n } else {\n if (mid < preferred) high = mid;\n else low = mid;\n }\n }\n\n const crLow = contrastRatioFromLuminance(luminanceAt(low), yBase);\n const crHigh = contrastRatioFromLuminance(luminanceAt(high), yBase);\n\n const lowPasses = crLow >= target;\n const highPasses = crHigh >= target;\n\n if (lowPasses && highPasses) {\n if (Math.abs(low - preferred) <= Math.abs(high - preferred)) {\n return { lightness: low, contrast: crLow, met: true };\n }\n return { lightness: high, contrast: crHigh, met: true };\n }\n if (lowPasses) return { lightness: low, contrast: crLow, met: true };\n if (highPasses) return { lightness: high, contrast: crHigh, met: true };\n\n return crLow >= crHigh\n ? { lightness: low, contrast: crLow, met: false }\n : { lightness: high, contrast: crHigh, met: false };\n}\n\n/**\n * Find the mix parameter (ratio or opacity) that satisfies a WCAG 2 contrast\n * target 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: contrastInput,\n luminanceAtValue,\n epsilon = 1e-4,\n maxIterations = 20,\n } = options;\n\n const target = resolveMinContrast(contrastInput);\n const searchTarget = target * 1.01;\n const yBase = gamutClampedLuminance(baseLinearRgb);\n\n const yPref = luminanceAtValue(preferredValue);\n const crPref = contrastRatioFromLuminance(yPref, yBase);\n\n if (crPref >= searchTarget) {\n return { value: preferredValue, contrast: crPref, met: true };\n }\n\n // Initial direction: the side whose extreme has higher contrast\n // against the base. Auto-flip considers the opposite side only when\n // this side fails; the fallback extreme also lives on this side.\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: crPref, met: false };\n } else {\n const crLowerExt = contrastRatioFromLuminance(luminanceAtValue(0), yBase);\n const crUpperExt = contrastRatioFromLuminance(luminanceAtValue(1), yBase);\n initialIsLower = crLowerExt >= crUpperExt;\n }\n\n const searchInitial = () =>\n initialIsLower\n ? searchMixBranch(\n 0,\n preferredValue,\n yBase,\n searchTarget,\n epsilon,\n maxIterations,\n preferredValue,\n luminanceAtValue,\n )\n : searchMixBranch(\n preferredValue,\n 1,\n yBase,\n searchTarget,\n epsilon,\n maxIterations,\n preferredValue,\n luminanceAtValue,\n );\n\n const searchOpposite = () =>\n initialIsLower\n ? searchMixBranch(\n preferredValue,\n 1,\n yBase,\n searchTarget,\n epsilon,\n maxIterations,\n preferredValue,\n luminanceAtValue,\n )\n : searchMixBranch(\n 0,\n preferredValue,\n yBase,\n searchTarget,\n epsilon,\n maxIterations,\n preferredValue,\n luminanceAtValue,\n );\n\n const initialResult = searchInitial();\n initialResult.met = initialResult.contrast >= target;\n\n if (initialResult.met && !options.flip) {\n return {\n value: initialResult.lightness,\n contrast: initialResult.contrast,\n met: true,\n };\n }\n\n if (options.flip) {\n const canOpposite = initialIsLower ? canUpper : canLower;\n const oppositeResult = canOpposite ? searchOpposite() : null;\n if (oppositeResult) oppositeResult.met = oppositeResult.contrast >= target;\n\n if (initialResult.met && oppositeResult?.met) {\n const initialDist = Math.abs(initialResult.lightness - preferredValue);\n const oppositeDist = Math.abs(oppositeResult.lightness - preferredValue);\n if (initialDist <= oppositeDist) {\n return {\n value: initialResult.lightness,\n contrast: initialResult.contrast,\n met: true,\n };\n }\n return {\n value: oppositeResult.lightness,\n contrast: oppositeResult.contrast,\n met: true,\n flipped: true,\n };\n }\n\n if (initialResult.met) {\n return {\n value: initialResult.lightness,\n contrast: initialResult.contrast,\n met: true,\n };\n }\n\n if (oppositeResult?.met) {\n return {\n value: oppositeResult.lightness,\n contrast: oppositeResult.contrast,\n met: true,\n flipped: true,\n };\n }\n }\n\n // Failure: pin to the initial direction's extreme.\n const extreme = initialIsLower ? 0 : 1;\n const crExtreme = contrastRatioFromLuminance(\n luminanceAtValue(extreme),\n yBase,\n );\n return {\n value: extreme,\n contrast: crExtreme,\n met: false,\n };\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 { getConfig } from './config';\nimport type {\n ColorDef,\n MixColorDef,\n ResolvedColorVariant,\n ShadowColorDef,\n ShadowTuning,\n} from './types';\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): Required<ShadowTuning> {\n const globalTuning = getConfig().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: ResolvedColorVariant,\n fg: ResolvedColorVariant | undefined,\n intensity: number,\n tuning: Required<ShadowTuning>,\n): ResolvedColorVariant {\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 * Light / dark scheme lightness mappings.\n *\n * Owns the active lightness window selection (with per-call scaling\n * overrides and high-contrast handling), the Möbius curve used by the\n * `'auto'` dark adaptation, and the saturation-desaturation reducer\n * for dark mode.\n */\n\nimport { clamp, pairHC, pairNormal } from './hc-pair';\nimport { getConfig } from './config';\nimport type { AdaptationMode, GlazeColorScaling } from './types';\n\n/**\n * Resolve the active lightness window for a scheme.\n * - HC variants always return `[0, 100]` (existing behavior, predates per-call overrides).\n * - Otherwise, per-call `scaling` (e.g. from `glaze.color()`'s third arg) wins;\n * `false` is interpreted as `[0, 100]` (no remap). Falls back to `globalConfig.*Lightness`.\n */\nexport function lightnessWindow(\n isHighContrast: boolean,\n kind: 'light' | 'dark',\n scaling?: GlazeColorScaling,\n): [number, number] {\n if (isHighContrast) return [0, 100];\n if (scaling) {\n const override =\n kind === 'dark' ? scaling.darkLightness : scaling.lightLightness;\n if (override === false) return [0, 100];\n if (override !== undefined) return override;\n }\n const cfg = getConfig();\n return kind === 'dark' ? cfg.darkLightness : cfg.lightLightness;\n}\n\nexport function mapLightnessLight(\n l: number,\n mode: AdaptationMode,\n isHighContrast: boolean,\n scaling?: GlazeColorScaling,\n): number {\n if (mode === 'static') return l;\n const [lo, hi] = lightnessWindow(isHighContrast, 'light', scaling);\n return (l * (hi - lo)) / 100 + lo;\n}\n\nfunction mobiusCurve(t: number, beta: number): number {\n if (beta >= 1) return t;\n return t / (t + beta * (1 - t));\n}\n\nexport function mapLightnessDark(\n l: number,\n mode: AdaptationMode,\n isHighContrast: boolean,\n scaling?: GlazeColorScaling,\n): number {\n if (mode === 'static') return l;\n\n const cfg = getConfig();\n const beta = isHighContrast\n ? pairHC(cfg.darkCurve)\n : pairNormal(cfg.darkCurve);\n const [darkLo, darkHi] = lightnessWindow(isHighContrast, 'dark', scaling);\n\n if (mode === 'fixed') {\n return (l * (darkHi - darkLo)) / 100 + darkLo;\n }\n\n const [lightLo, lightHi] = lightnessWindow(isHighContrast, 'light', scaling);\n const lightL = (l * (lightHi - lightLo)) / 100 + lightLo;\n const t = (lightHi - lightL) / (lightHi - lightLo);\n return darkLo + (darkHi - darkLo) * mobiusCurve(t, beta);\n}\n\nexport function lightMappedToDark(\n lightL: number,\n isHighContrast: boolean,\n scaling?: GlazeColorScaling,\n): number {\n const cfg = getConfig();\n const beta = isHighContrast\n ? pairHC(cfg.darkCurve)\n : pairNormal(cfg.darkCurve);\n const [lightLo, lightHi] = lightnessWindow(isHighContrast, 'light', scaling);\n const [darkLo, darkHi] = lightnessWindow(isHighContrast, 'dark', scaling);\n const clamped = clamp(lightL, lightLo, lightHi);\n const t = (lightHi - clamped) / (lightHi - lightLo);\n return darkLo + (darkHi - darkLo) * mobiusCurve(t, beta);\n}\n\nexport function mapSaturationDark(s: number, mode: AdaptationMode): number {\n if (mode === 'static') return s;\n return s * (1 - getConfig().darkDesaturation);\n}\n\nexport function schemeLightnessRange(\n isDark: boolean,\n mode: AdaptationMode,\n isHighContrast: boolean,\n scaling?: GlazeColorScaling,\n): [number, number] {\n if (mode === 'static') return [0, 1];\n const [lo, hi] = lightnessWindow(\n isHighContrast,\n isDark ? 'dark' : 'light',\n scaling,\n );\n return [lo / 100, hi / 100];\n}\n","/**\n * Color graph validation and topological sort.\n *\n * `validateColorDefs` rejects bad references (missing / shadow-referencing /\n * base/contrast/lightness 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 { isAbsoluteLightness } 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.lightness !== undefined &&\n !isAbsoluteLightness(regDef.lightness) &&\n !regDef.base\n ) {\n throw new Error(\n `glaze: color \"${name}\" has relative \"lightness\" 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 (!isAbsoluteLightness(regDef.lightness) && regDef.base === undefined) {\n throw new Error(\n `glaze: color \"${name}\" must have either absolute \"lightness\" (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 lightness 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 { resolveMinContrast } from './contrast-solver';\nimport type { MinContrast } from './contrast-solver';\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 already overshoots by `OVERSHOOT` (currently 1%)\n * to absorb rounding noise (`see findLightnessForContrast` in\n * `contrast-solver.ts`), so an `actual` ratio within ~2x that overshoot\n * is effectively a pass and not worth nagging the user about.\n */\nconst CONTRAST_WARN_SLACK = 0.98;\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 formatContrastTarget(input: MinContrast, ratio: number): string {\n return typeof input === 'string'\n ? `\"${input}\" (${ratio.toFixed(2)})`\n : ratio.toFixed(2);\n}\n\nexport function warnContrastUnmet(\n name: string,\n isDark: boolean,\n isHighContrast: boolean,\n target: MinContrast,\n actual: number,\n): void {\n const targetRatio = resolveMinContrast(target);\n if (actual >= targetRatio * CONTRAST_WARN_SLACK) return;\n\n const scheme = schemeLabel(isDark, isHighContrast);\n const key = `${name}|${scheme}|${targetRatio.toFixed(3)}|${actual.toFixed(2)}`;\n if (contrastWarnCache.has(key)) return;\n\n if (contrastWarnCache.size >= CONTRAST_WARN_CACHE_LIMIT) {\n contrastWarnCache.clear();\n }\n contrastWarnCache.add(key);\n\n console.warn(\n `glaze: color \"${name}\" cannot meet contrast ${formatContrastTarget(\n target,\n targetRatio,\n )} in ${scheme} scheme (got ${actual.toFixed(2)}). ` +\n `Try widening the lightness window, lowering the contrast target, ` +\n `or picking a base color further from this color's lightness.`,\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\nimport {\n okhslToLinearSrgb,\n sRGBLinearToGamma,\n gamutClampedLuminance,\n srgbToOkhsl,\n} from './okhsl-color-math';\nimport {\n findLightnessForContrast,\n findValueForMixContrast,\n} from './contrast-solver';\nimport type { LinearRgb } from './contrast-solver';\nimport {\n clamp,\n isAbsoluteLightness,\n pairHC,\n pairNormal,\n parseRelativeOrAbsolute,\n resolveEffectiveHue,\n} from './hc-pair';\nimport { getConfig } from './config';\nimport {\n computeShadow,\n circularLerp,\n isMixDef,\n isShadowDef,\n resolveShadowTuning,\n} from './shadow';\nimport {\n lightMappedToDark,\n mapLightnessDark,\n mapLightnessLight,\n mapSaturationDark,\n schemeLightnessRange,\n} from './scheme-mapping';\nimport { topoSort, validateColorDefs } from './validation';\nimport { warnContrastUnmet } from './warnings';\nimport type {\n AdaptationMode,\n ColorDef,\n ColorMap,\n GlazeColorScaling,\n MixColorDef,\n RegularColorDef,\n ResolvedColor,\n ResolvedColorVariant,\n ShadowColorDef,\n} from './types';\n\nexport interface ResolveContext {\n hue: number;\n saturation: number;\n defs: ColorMap;\n resolved: Map<string, ResolvedColor>;\n /**\n * Optional per-resolve scaling overrides for the lightness windows.\n * Used by `glaze.color()` to preserve light input by default while\n * still adapting dark to `globalConfig.darkLightness`.\n */\n scaling?: GlazeColorScaling;\n /**\n * Whether to auto-flip lightness direction when contrast can't be met.\n * Read from global config at resolve time; overridable per-call via\n * the context for standalone tokens that snapshot it at creation.\n */\n autoFlip?: boolean;\n}\n\ntype ResolvedField = 'light' | 'dark' | 'lightContrast' | 'darkContrast';\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\nfunction resolveRootColor(\n _name: string,\n def: RegularColorDef,\n _ctx: ResolveContext,\n isHighContrast: boolean,\n): { lightL: number; satFactor: number } {\n const rawL = def.lightness!;\n const rawValue = isHighContrast ? pairHC(rawL) : pairNormal(rawL);\n const parsed = parseRelativeOrAbsolute(rawValue);\n const lightL = clamp(parsed.value, 0, 100);\n const satFactor = clamp(def.saturation ?? 1, 0, 1);\n return { lightL, satFactor };\n}\n\nfunction resolveDependentColor(\n name: string,\n def: RegularColorDef,\n ctx: ResolveContext,\n isHighContrast: boolean,\n isDark: boolean,\n effectiveHue: number,\n): { l: 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\n const baseVariant = getSchemeVariant(baseResolved, isDark, isHighContrast);\n const baseL = baseVariant.l * 100;\n\n let preferredL: number;\n const rawLightness = def.lightness;\n\n if (rawLightness === undefined) {\n preferredL = baseL;\n } else {\n const rawValue = isHighContrast\n ? pairHC(rawLightness)\n : pairNormal(rawLightness);\n const parsed = parseRelativeOrAbsolute(rawValue);\n\n if (parsed.relative) {\n const delta = parsed.value;\n if (isDark && mode === 'auto') {\n const baseLightVariant = getSchemeVariant(\n baseResolved,\n false,\n isHighContrast,\n );\n const absoluteLightL = clamp(baseLightVariant.l * 100 + delta, 0, 100);\n preferredL = lightMappedToDark(\n absoluteLightL,\n isHighContrast,\n ctx.scaling,\n );\n } else {\n preferredL = clamp(baseL + delta, 0, 100);\n }\n } else {\n if (isDark) {\n preferredL = mapLightnessDark(\n parsed.value,\n mode,\n isHighContrast,\n ctx.scaling,\n );\n } else {\n preferredL = mapLightnessLight(\n parsed.value,\n mode,\n isHighContrast,\n ctx.scaling,\n );\n }\n }\n }\n\n const rawContrast = def.contrast;\n if (rawContrast !== undefined) {\n const minCr = isHighContrast\n ? pairHC(rawContrast)\n : pairNormal(rawContrast);\n\n const effectiveSat = isDark\n ? mapSaturationDark((satFactor * ctx.saturation) / 100, mode)\n : (satFactor * ctx.saturation) / 100;\n\n const baseLinearRgb = okhslToLinearSrgb(\n baseVariant.h,\n baseVariant.s,\n baseVariant.l,\n );\n\n const windowRange = schemeLightnessRange(\n isDark,\n mode,\n isHighContrast,\n ctx.scaling,\n );\n\n const autoFlip = ctx.autoFlip ?? getConfig().autoFlip;\n let initialDirection: 'lighter' | 'darker' | undefined;\n if (preferredL < baseL) {\n initialDirection = 'darker';\n } else if (preferredL > baseL) {\n initialDirection = 'lighter';\n }\n\n const result = findLightnessForContrast({\n hue: effectiveHue,\n saturation: effectiveSat,\n preferredLightness: clamp(\n preferredL / 100,\n windowRange[0],\n windowRange[1],\n ),\n baseLinearRgb,\n contrast: minCr,\n lightnessRange: [0, 1],\n initialDirection,\n flip: autoFlip,\n });\n\n if (!result.met) {\n warnContrastUnmet(name, isDark, isHighContrast, minCr, result.contrast);\n }\n\n return { l: result.lightness * 100, satFactor };\n }\n\n return { l: clamp(preferredL, 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(def, ctx, isDark, isHighContrast);\n }\n\n const regDef = def as RegularColorDef;\n const mode = regDef.mode ?? 'auto';\n const isRoot = isAbsoluteLightness(regDef.lightness) && !regDef.base;\n const effectiveHue = resolveEffectiveHue(ctx.hue, regDef.hue);\n\n let lightL: number;\n let satFactor: number;\n\n if (isRoot) {\n const root = resolveRootColor(name, regDef, ctx, isHighContrast);\n lightL = root.lightL;\n satFactor = root.satFactor;\n } else {\n const dep = resolveDependentColor(\n name,\n regDef,\n ctx,\n isHighContrast,\n isDark,\n effectiveHue,\n );\n lightL = dep.l;\n satFactor = dep.satFactor;\n }\n\n let finalL: number;\n let finalSat: number;\n\n if (isDark && isRoot) {\n finalL = mapLightnessDark(lightL, mode, isHighContrast, ctx.scaling);\n finalSat = mapSaturationDark((satFactor * ctx.saturation) / 100, mode);\n } else if (isDark && !isRoot) {\n finalL = lightL;\n finalSat = mapSaturationDark((satFactor * ctx.saturation) / 100, mode);\n } else if (isRoot) {\n finalL = mapLightnessLight(lightL, mode, isHighContrast, ctx.scaling);\n finalSat = (satFactor * ctx.saturation) / 100;\n } else {\n finalL = lightL;\n finalSat = (satFactor * ctx.saturation) / 100;\n }\n\n return {\n h: effectiveHue,\n s: clamp(finalSat, 0, 1),\n l: clamp(finalL / 100, 0, 1),\n alpha: regDef.opacity ?? 1,\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 = getSchemeVariant(bgResolved, isDark, isHighContrast);\n\n let fgVariant: ResolvedColorVariant | undefined;\n if (def.fg) {\n const fgResolved = ctx.resolved.get(def.fg)!;\n fgVariant = getSchemeVariant(fgResolved, isDark, isHighContrast);\n }\n\n const intensity = isHighContrast\n ? pairHC(def.intensity)\n : pairNormal(def.intensity);\n\n const tuning = resolveShadowTuning(def.tuning);\n return computeShadow(bgVariant, fgVariant, intensity, tuning);\n}\n\nfunction variantToLinearRgb(v: ResolvedColorVariant): LinearRgb {\n return okhslToLinearSrgb(v.h, v.s, v.l);\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(\n base: ResolvedColorVariant,\n target: ResolvedColorVariant,\n t: number,\n): 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 linearRgbToVariant(rgb: LinearRgb): 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);\n return { h, s, l, alpha: 1 };\n}\n\nfunction resolveMixForScheme(\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 = getSchemeVariant(baseResolved, isDark, isHighContrast);\n const targetVariant = getSchemeVariant(\n targetResolved,\n isDark,\n 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 baseLinear = variantToLinearRgb(baseVariant);\n const targetLinear = variantToLinearRgb(targetVariant);\n\n if (def.contrast !== undefined) {\n const minCr = isHighContrast\n ? pairHC(def.contrast)\n : pairNormal(def.contrast);\n\n let luminanceAt: (v: number) => number;\n\n if (blend === 'transparent') {\n luminanceAt = (v: number) =>\n gamutClampedLuminance(linearSrgbLerp(baseLinear, targetLinear, v));\n } else if (space === 'srgb') {\n luminanceAt = (v: number) =>\n gamutClampedLuminance(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 gamutClampedLuminance(okhslToLinearSrgb(h, s, l));\n };\n }\n\n const autoFlip = ctx.autoFlip ?? getConfig().autoFlip;\n\n const result = findValueForMixContrast({\n preferredValue: t,\n baseLinearRgb: baseLinear,\n targetLinearRgb: targetLinear,\n contrast: minCr,\n luminanceAtValue: luminanceAt,\n flip: autoFlip,\n });\n t = result.value;\n }\n\n if (blend === 'transparent') {\n return {\n h: targetVariant.h,\n s: targetVariant.s,\n l: targetVariant.l,\n alpha: clamp(t, 0, 1),\n };\n }\n\n if (space === 'srgb') {\n const mixed = linearSrgbLerp(baseLinear, targetLinear, t);\n return linearRgbToVariant(mixed);\n }\n\n return {\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}\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\nexport function resolveAllColors(\n hue: number,\n saturation: number,\n defs: ColorMap,\n scaling?: GlazeColorScaling,\n externalBases?: Map<string, ResolvedColor>,\n overrideAutoFlip?: boolean,\n): Map<string, ResolvedColor> {\n validateColorDefs(defs, externalBases);\n const order = topoSort(defs);\n\n const cfg = getConfig();\n const ctx: ResolveContext = {\n hue,\n saturation,\n defs,\n resolved: new Map(),\n scaling,\n autoFlip: overrideAutoFlip ?? cfg.autoFlip,\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. `runPass` initializes each local ResolvedColor\n // with all four slots seeded with the just-computed light variant.\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. Seed dark/darkContrast from the light passes\n // so HC-dependent and base lookups have sensible starting points.\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 return result;\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 four 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 */\n\nimport {\n formatHsl,\n formatOkhsl,\n formatOklch,\n formatRgb,\n} from './okhsl-color-math';\nimport { getConfig } from './config';\nimport type {\n GlazeColorFormat,\n GlazeCssResult,\n GlazeOutputModes,\n ResolvedColor,\n ResolvedColorVariant,\n} from './types';\n\nconst formatters: Record<\n GlazeColorFormat,\n (h: number, s: number, l: number) => 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 = 'okhsl',\n): string {\n const base = formatters[format](v.h, v.s * 100, v.l * 100);\n if (v.alpha >= 1) return base;\n const closing = base.lastIndexOf(')');\n return `${base.slice(0, closing)} / ${fmt(v.alpha, 4)})`;\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 = 'okhsl',\n): Record<string, Record<string, string>> {\n const tokens: Record<string, Record<string, string>> = {};\n\n for (const [name, color] of resolved) {\n const key = `#${prefix}${name}`;\n const entry: Record<string, string> = {\n '': formatVariant(color.light, format),\n };\n\n if (modes.dark) {\n entry[states.dark] = formatVariant(color.dark, format);\n }\n if (modes.highContrast) {\n entry[states.highContrast] = formatVariant(color.lightContrast, format);\n }\n if (modes.dark && modes.highContrast) {\n entry[`${states.dark} & ${states.highContrast}`] = formatVariant(\n color.darkContrast,\n format,\n );\n }\n\n tokens[key] = entry;\n }\n\n return tokens;\n}\n\nexport function buildFlatTokenMap(\n resolved: Map<string, ResolvedColor>,\n prefix: string,\n modes: Required<GlazeOutputModes>,\n format: GlazeColorFormat = 'okhsl',\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);\n\n if (modes.dark) {\n result.dark[key] = formatVariant(color.dark, format);\n }\n if (modes.highContrast) {\n result.lightContrast[key] = formatVariant(color.lightContrast, format);\n }\n if (modes.dark && modes.highContrast) {\n result.darkContrast[key] = formatVariant(color.darkContrast, format);\n }\n }\n\n return result;\n}\n\nexport function buildJsonMap(\n resolved: Map<string, ResolvedColor>,\n modes: Required<GlazeOutputModes>,\n format: GlazeColorFormat = 'okhsl',\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),\n };\n\n if (modes.dark) {\n entry.dark = formatVariant(color.dark, format);\n }\n if (modes.highContrast) {\n entry.lightContrast = formatVariant(color.lightContrast, format);\n }\n if (modes.dark && modes.highContrast) {\n entry.darkContrast = formatVariant(color.darkContrast, format);\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): GlazeCssResult {\n const lines: Record<keyof GlazeCssResult, string[]> = {\n light: [],\n dark: [],\n lightContrast: [],\n darkContrast: [],\n };\n\n for (const [name, color] of resolved) {\n const prop = `--${prefix}${name}${suffix}`;\n lines.light.push(`${prop}: ${formatVariant(color.light, format)};`);\n lines.dark.push(`${prop}: ${formatVariant(color.dark, format)};`);\n lines.lightContrast.push(\n `${prop}: ${formatVariant(color.lightContrast, format)};`,\n );\n lines.darkContrast.push(\n `${prop}: ${formatVariant(color.darkContrast, format)};`,\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 * Standalone single-color tokens (`glaze.color()` / `glaze.colorFrom()`).\n *\n * Owns the value-shorthand parser (hex, `rgb()` / `hsl()` / `okhsl()` /\n * `oklch()`, `{ r, g, b }`, `{ h, s, l }`, `{ l, c, h }`), the structured-input\n * validator, the two factory paths (value vs structured), and the\n * JSON-safe export / rehydration round-trip.\n *\n * Standalone tokens snapshot the relevant `globalConfig` fields at\n * create time so later `configure()` calls do not retroactively change\n * exported tokens — the snapshot is captured eagerly in\n * `defaultStandaloneScaling()`. The token's resolved variants are then\n * memoized on first `.resolve()` / `.token()` / ... call.\n */\n\nimport { getConfig } from './config';\nimport {\n hslToSrgb,\n oklabToOkhsl,\n parseHexAlpha,\n srgbToOkhsl,\n} from './okhsl-color-math';\nimport { isAbsoluteLightness, pairNormal } from './hc-pair';\nimport { resolveAllColors } from './resolver';\nimport {\n buildCssMap,\n buildJsonMap,\n buildTokenMap,\n resolveModes,\n} from './formatters';\nimport type {\n ColorMap,\n GlazeColorCssOptions,\n GlazeColorInput,\n GlazeColorInputExport,\n GlazeColorOverrides,\n GlazeColorOverridesExport,\n GlazeColorScaling,\n GlazeColorToken,\n GlazeColorTokenExport,\n GlazeColorValue,\n GlazeCssResult,\n GlazeJsonOptions,\n GlazeTokenOptions,\n OkhslColor,\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 lightness / 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 * Create-time scaling for all value-shorthand `glaze.color()` inputs.\n * Light lightness is preserved (`lightLightness: false`); dark uses the\n * theme window from `globalConfig.darkLightness`, snapshotted at create\n * time so later `configure()` does not retroactively change tokens.\n */\nfunction defaultValueShorthandScaling(): GlazeColorScaling {\n const cfg = getConfig();\n return {\n lightLightness: false,\n darkLightness: cfg.darkLightness,\n };\n}\n\n/**\n * Create-time scaling for structured `glaze.color({ hue, saturation,\n * lightness, ... })`. Both windows come from `globalConfig` so the\n * token behaves like an ordinary theme color on light and dark sides.\n */\nfunction defaultStructuredScaling(): GlazeColorScaling {\n const cfg = getConfig();\n return {\n lightLightness: cfg.lightLightness,\n darkLightness: cfg.darkLightness,\n };\n}\n\n/**\n * Discriminate a `GlazeColorToken` from a raw `GlazeColorValue`.\n * Used to widen `base?` so it accepts either a token reference or a\n * raw value (auto-wrapped into `glaze.color(value)`).\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\nexport function isStructuredColorInput(\n input: GlazeColorInput | GlazeColorValue,\n): input is GlazeColorInput {\n return (\n typeof input === 'object' &&\n input !== null &&\n !Array.isArray(input) &&\n 'hue' in input &&\n 'lightness' in input\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|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 '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, lightness } (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\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` / `lightness` 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 checkLightness = (value: number, label: string): void => {\n if (!Number.isFinite(value) || value < 0 || value > 100) {\n throw new Error(\n `glaze.color: structured ${label} must be a finite number in 0–100 (got ${value}).`,\n );\n }\n };\n if (Array.isArray(input.lightness)) {\n checkLightness(input.lightness[0], 'lightness[normal]');\n checkLightness(input.lightness[1], 'lightness[hc]');\n } else {\n checkLightness(input.lightness, 'lightness');\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 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, using the snapshotted\n * `globalConfig.darkLightness` window (light lightness preserved via\n * `lightLightness: false`).\n *\n * When the user requests `contrast` or relative `lightness`, 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 lightnessOption = options?.lightness;\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 `lightness` anchor to\n // the literal seed via the hidden `STANDALONE_SEED` def.\n const needsSeedAnchor =\n !hasExternalBase &&\n (options?.contrast !== undefined ||\n (lightnessOption !== undefined && !isAbsoluteLightness(lightnessOption)));\n\n if (options?.opacity !== undefined)\n validateStandaloneOpacity(options.opacity);\n\n // User-supplied `name` becomes the def key (and surfaces in error / warn\n // messages). It must not collide with internal reserved names; we throw\n // a clear error rather than silently shadowing them.\n const userName = options?.name;\n if (userName !== undefined) validateStandaloneName(userName);\n const primary = userName ?? STANDALONE_VALUE;\n\n const valueDef: RegularColorDef = {\n hue: relativeHue,\n saturation: options?.saturationFactor,\n lightness: lightnessOption ?? main.l * 100,\n contrast: options?.contrast,\n mode: options?.mode ?? 'auto',\n opacity: options?.opacity,\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 // `saturation: 1` is the default factor; combined with seedSaturation\n // = main.s * 100, the seed renders at exactly the user-provided color.\n defs[STANDALONE_SEED] = {\n hue: main.h,\n saturation: 1,\n lightness: main.l * 100,\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 effectiveScaling: GlazeColorScaling,\n baseToken: GlazeColorToken | undefined,\n exportData: () => GlazeColorTokenExport,\n autoFlip: boolean,\n): GlazeColorToken {\n // Cache the resolve result across token / tasty / json / css / resolve calls.\n // The base token's `.resolve()` is called lazily on first resolve and the\n // result is captured by reference, so subsequent base mutations don't apply\n // (matches the existing snapshot semantics for `scaling.darkLightness`).\n let cached: Map<string, ResolvedColor> | undefined;\n const resolveOnce = (): Map<string, ResolvedColor> => {\n if (cached) return cached;\n const externalBases = baseToken\n ? new Map([[STANDALONE_BASE, baseToken.resolve()]])\n : undefined;\n cached = resolveAllColors(\n seedHue,\n seedSaturation,\n defs,\n effectiveScaling,\n externalBases,\n autoFlip,\n );\n return cached;\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,\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 jsonMap = buildJsonMap(\n resolveOnce(),\n resolveModes(options?.modes),\n options?.format,\n );\n return jsonMap[primary];\n },\n\n css(options: GlazeColorCssOptions): GlazeCssResult {\n const renamed = new Map<string, ResolvedColor>([\n [options.name, resolveOnce().get(primary)!],\n ]);\n return buildCssMap(\n renamed,\n '',\n options.suffix ?? '-color',\n options.format ?? 'rgb',\n );\n },\n\n export: exportData,\n };\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 * `glaze.color(value)` so they pick up the same auto-invert defaults as\n * 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// Factory: structured input\n// ============================================================================\n\nexport function createColorToken(\n input: GlazeColorInput,\n scaling: GlazeColorScaling | undefined,\n overrideAutoFlip?: boolean,\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 // Mirror value-form behavior: when `contrast` is provided without an\n // external base, synthesize a hidden static seed so contrast anchors\n // against the input's own normal-mode lightness.\n const needsSeedAnchor = !hasExternalBase && input.contrast !== undefined;\n\n const defs: ColorMap = {\n [primary]: {\n lightness: input.lightness,\n saturation: input.saturationFactor,\n mode: input.mode ?? 'auto',\n contrast: input.contrast,\n opacity: input.opacity,\n base: hasExternalBase\n ? STANDALONE_BASE\n : needsSeedAnchor\n ? STANDALONE_SEED\n : undefined,\n },\n };\n\n if (needsSeedAnchor) {\n defs[STANDALONE_SEED] = {\n lightness: pairNormal(input.lightness),\n saturation: 1,\n mode: 'static',\n };\n }\n\n // Structured form snapshots both lightness windows from `globalConfig`\n // at create time. With the default `mode: 'auto'` this matches an\n // ordinary theme color (Möbius-inverted in dark).\n const effectiveScaling: GlazeColorScaling =\n scaling ?? defaultStructuredScaling();\n\n const autoFlip = overrideAutoFlip ?? getConfig().autoFlip;\n\n const exportData = (): GlazeColorTokenExport => ({\n form: 'structured',\n input: buildStructuredInputExport(input),\n scaling: effectiveScaling,\n autoFlip,\n });\n\n return createColorTokenFromDefs(\n input.hue,\n input.saturation,\n defs,\n primary,\n effectiveScaling,\n baseToken,\n exportData,\n autoFlip,\n );\n}\n\n// ============================================================================\n// Factory: value-shorthand input\n// ============================================================================\n\nexport function createColorTokenFromValue(\n value: GlazeColorValue,\n options: GlazeColorOverrides | undefined,\n scaling: GlazeColorScaling | undefined,\n overrideAutoFlip?: boolean,\n): GlazeColorToken {\n const main = extractOkhslFromValue(value);\n const baseToken = resolveBaseToken(options?.base);\n const { seedHue, seedSaturation, defs, primary } = buildStandaloneValueDefs(\n main,\n options,\n );\n const effectiveScaling: GlazeColorScaling =\n scaling ?? defaultValueShorthandScaling();\n\n const autoFlip = overrideAutoFlip ?? getConfig().autoFlip;\n\n const exportData = (): GlazeColorTokenExport => ({\n form: 'value',\n input: value,\n ...(options !== undefined\n ? { overrides: buildOverridesExport(options) }\n : {}),\n scaling: effectiveScaling,\n autoFlip,\n });\n\n return createColorTokenFromDefs(\n seedHue,\n seedSaturation,\n defs,\n primary,\n effectiveScaling,\n baseToken,\n exportData,\n autoFlip,\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): 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.lightness !== undefined) out.lightness = options.lightness;\n if (options.saturationFactor !== undefined) {\n out.saturationFactor = options.saturationFactor;\n }\n if (options.mode !== undefined) out.mode = options.mode;\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.base !== undefined) {\n out.base = isGlazeColorToken(options.base)\n ? options.base.export()\n : options.base;\n }\n return out;\n}\n\nfunction buildStructuredInputExport(\n input: GlazeColorInput,\n): GlazeColorInputExport {\n const out: GlazeColorInputExport = {\n hue: input.hue,\n saturation: input.saturation,\n lightness: input.lightness,\n };\n if (input.saturationFactor !== undefined) {\n out.saturationFactor = input.saturationFactor;\n }\n if (input.mode !== undefined) out.mode = input.mode;\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.base !== undefined) {\n out.base = isGlazeColorToken(input.base) ? input.base.export() : input.base;\n }\n return out;\n}\n\n/**\n * Discriminate a `GlazeColorTokenExport` from a raw `GlazeColorValue`.\n * `GlazeColorTokenExport` always has a `form` field set to either\n * `'value'` or `'structured'`; raw values never do.\n */\nfunction isExportedToken(\n candidate: GlazeColorTokenExport | GlazeColorValue,\n): candidate is GlazeColorTokenExport {\n return (\n typeof candidate === 'object' &&\n candidate !== null &&\n !Array.isArray(candidate) &&\n 'form' in candidate &&\n ((candidate as GlazeColorTokenExport).form === 'value' ||\n (candidate as GlazeColorTokenExport).form === 'structured')\n );\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.lightness !== undefined) out.lightness = data.lightness;\n if (data.saturationFactor !== undefined) {\n out.saturationFactor = data.saturationFactor;\n }\n if (data.mode !== undefined) out.mode = data.mode;\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.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 lightness: data.lightness,\n };\n if (data.saturationFactor !== undefined) {\n out.saturationFactor = data.saturationFactor;\n }\n if (data.mode !== undefined) out.mode = data.mode;\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.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 */\nexport function colorFromExport(data: GlazeColorTokenExport): GlazeColorToken {\n // Shape guard: rehydration takes untrusted JSON (localStorage, URL,\n // remote API), so a corrupted blob shouldn't blow up deep inside the\n // resolver with confusing errors.\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 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 // Snapshot autoFlip at rehydration time so the exported token\n // preserves its original behavior regardless of globalConfig changes.\n const cfg = getConfig();\n const effectiveAutoFlip = data.autoFlip ?? cfg.autoFlip;\n return createColorTokenFromValue(\n value,\n overrides,\n data.scaling,\n effectiveAutoFlip,\n );\n }\n const input = rehydrateStructuredInput(data.input as GlazeColorInputExport);\n // Same snapshot semantics for structured inputs.\n const cfg = getConfig();\n const effectiveAutoFlip = data.autoFlip ?? cfg.autoFlip;\n return createColorToken(input, data.scaling, effectiveAutoFlip);\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 four export methods (`tokens` /\n * `tasty` / `json` / `css`) share a `buildPaletteOutput` driver that\n * handles validation, per-theme iteration, prefix resolution, collision\n * filtering, and primary duplication.\n */\n\nimport { getConfig } from './config';\nimport {\n buildCssMap,\n buildFlatTokenMap,\n buildJsonMap,\n buildTokenMap,\n resolveModes,\n} from './formatters';\nimport type {\n GlazeCssOptions,\n GlazeCssResult,\n GlazeJsonOptions,\n GlazePalette,\n GlazePaletteExportOptions,\n GlazePaletteOptions,\n GlazeTheme,\n GlazeTokenOptions,\n ResolvedColor,\n} from './types';\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\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: (resolved: Map<string, ResolvedColor>, prefix: string) => 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 prefix = resolvePrefix(options, themeName, true);\n const filtered = filterCollisions(resolved, prefix, seen, themeName);\n merge(acc, buildOne(filtered, prefix));\n\n if (themeName === effectivePrimary) {\n const primaryFiltered = filterCollisions(\n resolved,\n '',\n seen,\n themeName,\n true,\n );\n merge(acc, buildOne(primaryFiltered, ''));\n }\n }\n\n return acc;\n}\n\nexport function createPalette(\n themes: PaletteInput,\n paletteOptions?: GlazePaletteOptions,\n): GlazePalette {\n validatePrimaryTheme(paletteOptions?.primary, themes);\n\n return {\n tokens(\n options?: GlazeJsonOptions & GlazePaletteExportOptions,\n ): Record<string, Record<string, string>> {\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) =>\n buildFlatTokenMap(filtered, prefix, modes, options?.format),\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 return buildPaletteOutput<\n Record<string, Record<string, string>>,\n Record<string, Record<string, string>>\n >(\n themes,\n paletteOptions,\n options,\n (filtered, prefix) =>\n buildTokenMap(filtered, prefix, states, modes, options?.format),\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 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(resolved, modes, options?.format);\n }\n\n return result;\n },\n\n css(options?: GlazeCssOptions & GlazePaletteExportOptions): GlazeCssResult {\n const suffix = options?.suffix ?? '-color';\n const format = options?.format ?? 'rgb';\n\n const lines = buildPaletteOutput<\n GlazeCssResult,\n Record<keyof GlazeCssResult, string[]>\n >(\n themes,\n paletteOptions,\n options,\n (filtered, prefix) => buildCssMap(filtered, prefix, suffix, format),\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}\n","/**\n * Theme factory.\n *\n * Wraps a hue/saturation seed and a mutable `ColorMap`, and exposes\n * `tokens()` / `tasty()` / `json()` / `css()` / `resolve()` / `export()`\n * / `extend()`. Caches the last resolve result so successive exports\n * with the same defs and config don't re-run the four-pass resolver.\n */\n\nimport { getConfig, getConfigVersion } from './config';\nimport {\n buildCssMap,\n buildFlatTokenMap,\n buildJsonMap,\n buildTokenMap,\n resolveModes,\n} from './formatters';\nimport { resolveAllColors } from './resolver';\nimport type {\n ColorDef,\n ColorMap,\n GlazeCssOptions,\n GlazeCssResult,\n GlazeExtendOptions,\n GlazeJsonOptions,\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): GlazeTheme {\n let colorDefs: ColorMap = initialColors ? { ...initialColors } : {};\n\n let cache: {\n map: Map<string, ResolvedColor>;\n version: number;\n } | null = null;\n\n function resolveCached(): Map<string, ResolvedColor> {\n const version = getConfigVersion();\n if (cache && cache.version === version) return cache.map;\n const map = resolveAllColors(hue, saturation, colorDefs);\n cache = { map, version };\n return map;\n }\n\n function invalidate(): void {\n cache = null;\n }\n\n const theme: GlazeTheme = {\n get hue() {\n return hue;\n },\n get saturation() {\n return saturation;\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(): GlazeThemeExport {\n return {\n hue,\n saturation,\n colors: { ...colorDefs },\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 return createTheme(newHue, newSat, mergedColors);\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 modes = resolveModes(options?.modes);\n return buildFlatTokenMap(resolveCached(), '', modes, options?.format);\n },\n\n tasty(options?: GlazeTokenOptions): 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 return buildTokenMap(resolveCached(), '', states, modes, options?.format);\n },\n\n json(options?: GlazeJsonOptions): Record<string, Record<string, string>> {\n const modes = resolveModes(options?.modes);\n return buildJsonMap(resolveCached(), modes, options?.format);\n },\n\n css(options?: GlazeCssOptions): GlazeCssResult {\n return buildCssMap(\n resolveCached(),\n '',\n options?.suffix ?? '-color',\n options?.format ?? 'rgb',\n );\n },\n } as GlazeTheme;\n\n return theme;\n}\n","/**\n * Glaze — OKHSL-based 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 */\n\nimport { parseHex, srgbToOkhsl } from './okhsl-color-math';\nimport {\n configure as configureImpl,\n resetConfig as resetConfigImpl,\n snapshotConfig,\n} from './config';\nimport {\n colorFromExport,\n createColorToken,\n createColorTokenFromValue,\n extractOkhslFromValue,\n isStructuredColorInput,\n} from './color-token';\nimport { formatVariant } from './formatters';\nimport { computeShadow, resolveShadowTuning } from './shadow';\nimport { createPalette } from './palette';\nimport { createTheme } from './theme';\nimport type {\n GlazeColorFormat,\n GlazeColorInput,\n GlazeColorOverrides,\n GlazeColorScaling,\n GlazeColorToken,\n GlazeColorTokenExport,\n GlazeColorValue,\n GlazeConfig,\n GlazeConfigResolved,\n GlazePalette,\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 * @example\n * ```ts\n * const primary = glaze({ hue: 280, saturation: 80 });\n * // or shorthand:\n * const primary = glaze(280, 80);\n * ```\n */\nexport function glaze(\n hueOrOptions: number | { hue: number; saturation: number },\n saturation?: number,\n): GlazeTheme {\n if (typeof hueOrOptions === 'number') {\n return createTheme(hueOrOptions, saturation ?? 100);\n }\n return createTheme(hueOrOptions.hue, hueOrOptions.saturation);\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/** Create a theme from a serialized export. */\nglaze.from = function from(data: GlazeThemeExport): GlazeTheme {\n return createTheme(data.hue, data.saturation, data.colors);\n};\n\n/**\n * Create a standalone single-color token.\n *\n * Two overloads:\n * - `glaze.color(input, scaling?)` — structured form:\n * `{ hue, saturation, lightness, ... }` plus an optional per-call\n * lightness-window override.\n * - `glaze.color(value, overrides?, scaling?)` — value-shorthand: a hex\n * string (3/6/8 digits), one of the CSS color functions Glaze itself\n * emits (`rgb()`, `hsl()`, `okhsl()`, `oklch()`), or literal objects\n * `{ r, g, b }` (0–255), `{ h, s, l }` (OKHSL 0–1), `{ l, c, h }`\n * (OKLCh, matching `oklch()` strings).\n *\n * Defaults: every input form defaults to `mode: 'auto'`. Value-shorthand\n * (strings and literal objects) snapshots `{ lightLightness: false,\n * darkLightness: globalConfig.darkLightness }` — light preserves the\n * input; dark uses the theme window. Structured `{ hue, saturation,\n * lightness, ... }` snapshots both `globalConfig` windows like a theme\n * color.\n *\n * Pass `{ mode: 'fixed' }` to opt back into the legacy linear, non-\n * inverting mapping, or `{ mode: 'static' }` to pin the same lightness\n * across every variant.\n *\n * Relative `lightness: '+N'` and `contrast: <ratio>` are anchored to\n * the literal seed (the value passed in) by default, pinned at\n * `mode: 'static'` across all four variants. Pass `overrides.base` (a\n * `GlazeColorToken`) to anchor `contrast` and relative `lightness`\n * against another color's resolved variant per scheme instead. Relative\n * `hue: '+N'` always anchors to the seed.\n *\n * Alpha components in `rgba()` / `hsla()` / slash-alpha syntax and\n * 8-digit hex are parsed but dropped with a `console.warn`.\n */\nglaze.color = function color(\n input: GlazeColorInput | GlazeColorValue,\n arg2?: GlazeColorOverrides | GlazeColorScaling,\n arg3?: GlazeColorScaling,\n): GlazeColorToken {\n if (isStructuredColorInput(input)) {\n return createColorToken(input, arg2 as GlazeColorScaling | undefined);\n }\n return createColorTokenFromValue(\n input,\n arg2 as GlazeColorOverrides | undefined,\n arg3,\n );\n} as {\n (input: GlazeColorInput, scaling?: GlazeColorScaling): GlazeColorToken;\n (\n value: GlazeColorValue,\n overrides?: GlazeColorOverrides,\n scaling?: GlazeColorScaling,\n ): GlazeColorToken;\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 tuning = resolveShadowTuning(input.tuning);\n return computeShadow(\n { ...bg, alpha: 1 },\n fg ? { ...fg, alpha: 1 } : undefined,\n input.intensity,\n tuning,\n );\n};\n\n/** Format a resolved color variant as a CSS string. */\nglaze.format = function format(\n variant: ResolvedColorVariant,\n colorFormat?: GlazeColorFormat,\n): string {\n return formatVariant(variant, colorFormat);\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 captured scaling. The reconstructed token is identical in\n * behavior to the original at the time of export.\n *\n * @example\n * ```ts\n * const text = glaze.color('#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/** 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/hc-pair.ts","../src/okhst.ts","../src/contrast-solver.ts","../src/shadow.ts","../src/validation.ts","../src/warnings.ts","../src/resolver.ts","../src/formatters.ts","../src/color-token.ts","../src/palette.ts","../src/theme.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\n// ============================================================================\n// Public API\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): [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 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 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): [number, number, number] {\n return OKLabToLinearSRGB(okhslToOklab(h, s, l));\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): [number, number, number] {\n const lin = okhslToLinearSrgb(h, s, l);\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): 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 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 let s: number;\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 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): [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) 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(h: number, s: number, l: number): string {\n return `okhsl(${fmt(h, 2)} ${fmt(s, 2)}% ${fmt(l, 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(h: number, s: number, l: number): string {\n const [r, g, b] = okhslToSrgb(h, s / 100, l / 100);\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(h: number, s: number, l: number): string {\n const [r, g, b] = okhslToSrgb(h, s / 100, l / 100);\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(h: number, s: number, l: number): string {\n const [L, a, b] = okhslToOklab(h, s / 100, l / 100);\n const C = Math.sqrt(a * a + b * b);\n let hh = Math.atan2(b, a) * (180 / Math.PI);\n hh = constrainAngle(hh);\n\n return `oklch(${fmt(L, 4)} ${fmt(C, 4)} ${fmt(hh, 2)})`;\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. Standalone color tokens snapshot the relevant fields at\n * create time (see `color-token.ts`), so already-created tokens keep\n * their original behavior across later `configure()` calls.\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 */\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 saturationTaper: 0.15,\n states: {\n dark: '@dark',\n highContrast: '@high-contrast',\n },\n modes: {\n dark: true,\n highContrast: false,\n },\n autoFlip: 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 saturationTaper: config.saturationTaper ?? globalConfig.saturationTaper,\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 };\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 */\nexport function mergeConfig(\n base: GlazeConfigResolved,\n override?: GlazeConfigOverride,\n): GlazeConfigResolved {\n if (!override) return base;\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 saturationTaper: override.saturationTaper ?? base.saturationTaper,\n states: base.states,\n modes: base.modes,\n shadowTuning: override.shadowTuning ?? base.shadowTuning,\n autoFlip: override.autoFlip ?? base.autoFlip,\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 saturation reducers, and the solver's\n * scheme 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/** Smoothstep `0..1`. */\nfunction smoothstep(x: number): number {\n const t = clamp(x, 0, 1);\n return t * t * (3 - 2 * t);\n}\n\n/** Fraction of the tone range over which the taper ramps in, per end. */\nconst TAPER_REGION = 0.15;\n\n/**\n * Gently taper saturation toward the tone extremes, where in-gamut chroma\n * collapses and high saturation reads as noise. `taper` is the *strength*\n * (0–1): the maximum fraction of saturation removed at the very edges. The\n * rolloff ramps in smoothly over the outer {@link TAPER_REGION} of tone on\n * each end, so mid-tones are untouched and high-tone surfaces keep most of\n * their color. `taper = 0` disables the effect.\n *\n * @param s Saturation (0–1).\n * @param toneFinal Stored canonical tone (0–1).\n * @param taper Strength (0–1); default config is a gentle 0.15.\n */\nexport function saturationEnvelope(\n s: number,\n toneFinal: number,\n taper: number,\n): number {\n if (taper <= 0) return s;\n const t = clamp(toneFinal, 0, 1);\n const strength = clamp(taper, 0, 1);\n const edge = Math.min(t, 1 - t);\n if (edge >= TAPER_REGION) return s;\n // ramp: 0 at the region boundary, 1 at the extreme.\n const ramp = 1 - smoothstep(edge / TAPER_REGION);\n return s * (1 - strength * ramp);\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, saturationEnvelope, 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/** 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\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\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\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.\n */\nexport function resolveContrastForMode(\n spec: ContrastSpec,\n isHighContrast: boolean,\n): ResolvedContrast {\n if (typeof spec === 'number' || typeof spec === 'string') {\n return { metric: 'wcag', target: resolveMinContrast(spec) };\n }\n if ('apca' in spec) {\n return {\n metric: 'apca',\n target: Math.abs(pickPair(spec.apca, isHighContrast)),\n };\n }\n return {\n metric: 'wcag',\n target: resolveMinContrast(pickPair(spec.wcag, isHighContrast)),\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): number {\n const tRounded = Math.round(t * 10000) / 10000;\n const key = `${metric}|${h}|${s}|${tRounded}`;\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);\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).\n */\nfunction metricScore(\n metric: 'wcag' | 'apca',\n yCandidate: number,\n yBase: number,\n): number {\n if (metric === 'wcag') return contrastRatioFromLuminance(yCandidate, yBase);\n return Math.abs(apcaContrast(yCandidate, yBase));\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 /**\n * Saturation taper strength (0–1). When set, candidate saturation is rolled\n * off toward the tone extremes via the same envelope the renderer applies,\n * so the solved tone meets the floor with its *rendered* saturation. Default\n * `0` (no taper) for direct/advanced callers.\n */\n saturationTaper?: number;\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): BranchResult {\n const scoreLo = metricScore(metric, lum(lo), yBase);\n const scoreHi = metricScore(metric, lum(hi), yBase);\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);\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);\n const scoreHigh = metricScore(metric, lum(high), yBase);\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}\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 } = 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 )\n : searchBranch(\n lum,\n searchAnchor,\n hi,\n yBase,\n metric,\n searchTarget,\n epsilon,\n maxIterations,\n searchAnchor,\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);\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 } = options;\n\n const { metric, target } = 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 const taper = options.saturationTaper ?? 0;\n // Luminance of a candidate at tone `t`. With a taper, saturation rolls off\n // toward the extremes exactly as the renderer does, so the solved tone\n // meets the floor with its *rendered* saturation; the (h, s, t) cache only\n // applies when saturation is tone-independent (no taper).\n const lum =\n taper > 0\n ? (t: number): number => {\n const s = saturationEnvelope(saturation, t, taper);\n const l = fromTone(t * 100, REF_EPS);\n return metricLuminance(metric, okhslToLinearSrgb(hue, s, l));\n }\n : (t: number): number => cachedLuminance(metric, hue, saturation, t);\n\n const scorePref = metricScore(metric, lum(preferredTone), yBase);\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);\n const scoreMax = metricScore(metric, lum(maxT), yBase);\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 });\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 } = 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 );\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(metric, luminanceAtValue(0), yBase);\n const scoreUpper = metricScore(metric, luminanceAtValue(1), yBase);\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 });\n\n return {\n value: solved.pos,\n contrast: solved.contrast,\n met: solved.met,\n ...(solved.flipped ? { flipped: true } : {}),\n };\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(apcaContrast(yColor, yBase))\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 computeShadow,\n circularLerp,\n isMixDef,\n isShadowDef,\n resolveShadowTuning,\n} from './shadow';\nimport {\n fromTone,\n mapSaturationDark,\n mapToneForScheme,\n okhslToOkhst,\n saturationEnvelope,\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 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}\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}\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 };\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\nfunction resolveContrastSpec(\n spec: HCPair<ContrastSpec>,\n isHighContrast: boolean,\n): ResolvedContrast {\n const outer = isHighContrast ? pairHC(spec) : pairNormal(spec);\n return resolveContrastForMode(outer, isHighContrast);\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): { 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.flip ?? ctx.config.autoFlip;\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(rawContrast, isHighContrast);\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 );\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 // Search with the same edge taper the renderer applies, so the solved\n // tone meets the floor at its rendered saturation.\n saturationTaper: ctx.config.saturationTaper,\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(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\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 );\n finalTone = dep.tone;\n satFactor = dep.satFactor;\n }\n\n const baseSat = (satFactor * ctx.saturation) / 100;\n let finalSat = isDark\n ? mapSaturationDark(baseSat, mode, ctx.config)\n : baseSat;\n\n const toneFraction = clamp(finalTone / 100, 0, 1);\n finalSat = saturationEnvelope(\n finalSat,\n toneFraction,\n ctx.config.saturationTaper,\n );\n\n return {\n h: effectiveHue,\n s: clamp(finalSat, 0, 1),\n t: toneFraction,\n alpha: regDef.opacity ?? 1,\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 toToneVariant(computeShadow(bgVariant, fgVariant, intensity, tuning));\n}\n\nfunction okhslVariantToLinearRgb(v: OkhslVariant): LinearRgb {\n return okhslToLinearSrgb(v.h, v.s, v.l);\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(rgb: LinearRgb): 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);\n return toToneVariant({ h, s, l, alpha: 1 });\n}\n\nfunction resolveMixForScheme(\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 baseLinear = okhslVariantToLinearRgb(baseVariant);\n const targetLinear = okhslVariantToLinearRgb(targetVariant);\n\n if (def.contrast !== undefined) {\n const resolvedContrast = resolveContrastSpec(def.contrast, isHighContrast);\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));\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 toToneVariant({\n h: targetVariant.h,\n s: targetVariant.s,\n l: targetVariant.l,\n alpha: clamp(t, 0, 1),\n });\n }\n\n if (space === 'srgb') {\n const mixed = linearSrgbLerp(baseLinear, targetLinear, t);\n return linearRgbToToneVariant(mixed);\n }\n\n return 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}\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): void {\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 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(regDef.contrast, s.isHighContrast);\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.\n const yC = metricLuminance(\n spec.metric,\n okhslToLinearSrgb(cOkhsl.h, cOkhsl.s, cOkhsl.l),\n );\n const yB = metricLuminance(\n spec.metric,\n okhslToLinearSrgb(bOkhsl.h, bOkhsl.s, bOkhsl.l),\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 };\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);\n\n return result;\n}\n\n// Re-export for callers that previously imported tone helpers from here.\nexport { fromTone, toTone };\n","/**\n * Output formatting for resolved color maps.\n *\n * Owns the CSS-string formatter dispatch table (`okhsl` / `rgb` / `hsl` /\n * `oklch`) and the four 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 */\n\nimport {\n formatHsl,\n formatOkhsl,\n formatOklch,\n formatRgb,\n} from './okhsl-color-math';\nimport { variantToOkhsl } from './okhst';\nimport { getConfig } from './config';\nimport type {\n GlazeColorFormat,\n GlazeCssResult,\n GlazeOutputModes,\n ResolvedColor,\n ResolvedColorVariant,\n} from './types';\n\nconst formatters: Record<\n GlazeColorFormat,\n (h: number, s: number, l: number) => 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 = 'okhsl',\n): string {\n // Variants store canonical tone; convert to OKHSL lightness at the edge.\n const { l } = variantToOkhsl(v);\n const base = formatters[format](v.h, v.s * 100, l * 100);\n if (v.alpha >= 1) return base;\n const closing = base.lastIndexOf(')');\n return `${base.slice(0, closing)} / ${fmt(v.alpha, 4)})`;\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 = 'okhsl',\n): Record<string, Record<string, string>> {\n const tokens: Record<string, Record<string, string>> = {};\n\n for (const [name, color] of resolved) {\n const key = `#${prefix}${name}`;\n const entry: Record<string, string> = {\n '': formatVariant(color.light, format),\n };\n\n if (modes.dark) {\n entry[states.dark] = formatVariant(color.dark, format);\n }\n if (modes.highContrast) {\n entry[states.highContrast] = formatVariant(color.lightContrast, format);\n }\n if (modes.dark && modes.highContrast) {\n entry[`${states.dark} & ${states.highContrast}`] = formatVariant(\n color.darkContrast,\n format,\n );\n }\n\n tokens[key] = entry;\n }\n\n return tokens;\n}\n\nexport function buildFlatTokenMap(\n resolved: Map<string, ResolvedColor>,\n prefix: string,\n modes: Required<GlazeOutputModes>,\n format: GlazeColorFormat = 'okhsl',\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);\n\n if (modes.dark) {\n result.dark[key] = formatVariant(color.dark, format);\n }\n if (modes.highContrast) {\n result.lightContrast[key] = formatVariant(color.lightContrast, format);\n }\n if (modes.dark && modes.highContrast) {\n result.darkContrast[key] = formatVariant(color.darkContrast, format);\n }\n }\n\n return result;\n}\n\nexport function buildJsonMap(\n resolved: Map<string, ResolvedColor>,\n modes: Required<GlazeOutputModes>,\n format: GlazeColorFormat = 'okhsl',\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),\n };\n\n if (modes.dark) {\n entry.dark = formatVariant(color.dark, format);\n }\n if (modes.highContrast) {\n entry.lightContrast = formatVariant(color.lightContrast, format);\n }\n if (modes.dark && modes.highContrast) {\n entry.darkContrast = formatVariant(color.darkContrast, format);\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): GlazeCssResult {\n const lines: Record<keyof GlazeCssResult, string[]> = {\n light: [],\n dark: [],\n lightContrast: [],\n darkContrast: [],\n };\n\n for (const [name, color] of resolved) {\n const prop = `--${prefix}${name}${suffix}`;\n lines.light.push(`${prop}: ${formatVariant(color.light, format)};`);\n lines.dark.push(`${prop}: ${formatVariant(color.dark, format)};`);\n lines.lightContrast.push(\n `${prop}: ${formatVariant(color.lightContrast, format)};`,\n );\n lines.darkContrast.push(\n `${prop}: ${formatVariant(color.darkContrast, format)};`,\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 * 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 * Standalone tokens snapshot the full effective config at create time\n * so later `configure()` calls do not retroactively change exported\n * tokens. The snapshot is built eagerly in\n * `buildValueFormConfigOverride()` / `buildStructuredConfigOverride()`.\n * The token's resolved variants are then memoized on first\n * `.resolve()` / `.token()` / ... call.\n */\n\nimport { defaultConfig, getConfig, mergeConfig } from './config';\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 buildJsonMap,\n buildTokenMap,\n resolveModes,\n} from './formatters';\nimport type {\n ColorMap,\n GlazeColorCssOptions,\n GlazeColorInput,\n GlazeColorInputExport,\n GlazeColorOverrides,\n GlazeColorOverridesExport,\n GlazeColorToken,\n GlazeColorTokenExport,\n GlazeColorValue,\n GlazeCssResult,\n GlazeConfigOverride,\n GlazeConfigResolved,\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// Effective config snapshots\n// ============================================================================\n\n/**\n * Build the per-token effective config override for a value-form color.\n *\n * Light window defaults to `false` (preserve input tone exactly).\n * All other fields snapshot from global at create time. User override\n * fields win over all defaults.\n */\nfunction buildValueFormConfigOverride(\n userOverride?: GlazeConfigOverride,\n): GlazeConfigOverride {\n const cfg = getConfig();\n return {\n lightTone:\n userOverride?.lightTone !== undefined ? userOverride.lightTone : false,\n darkTone:\n userOverride?.darkTone !== undefined\n ? userOverride.darkTone\n : cfg.darkTone,\n darkDesaturation: userOverride?.darkDesaturation ?? cfg.darkDesaturation,\n saturationTaper: userOverride?.saturationTaper ?? cfg.saturationTaper,\n autoFlip: userOverride?.autoFlip ?? cfg.autoFlip,\n shadowTuning: userOverride?.shadowTuning ?? cfg.shadowTuning,\n };\n}\n\n/**\n * Build the per-token effective config override for a structured-form color.\n *\n * Both light and dark windows snapshot from global at create time.\n * User override fields win.\n */\nfunction buildStructuredConfigOverride(\n userOverride?: GlazeConfigOverride,\n): GlazeConfigOverride {\n const cfg = getConfig();\n return {\n lightTone:\n userOverride?.lightTone !== undefined\n ? userOverride.lightTone\n : cfg.lightTone,\n darkTone:\n userOverride?.darkTone !== undefined\n ? userOverride.darkTone\n : cfg.darkTone,\n darkDesaturation: userOverride?.darkDesaturation ?? cfg.darkDesaturation,\n saturationTaper: userOverride?.saturationTaper ?? cfg.saturationTaper,\n autoFlip: userOverride?.autoFlip ?? cfg.autoFlip,\n shadowTuning: userOverride?.shadowTuning ?? cfg.shadowTuning,\n };\n}\n\n/**\n * Build the `GlazeConfigResolved` to pass to `resolveAllColors` from a\n * snapshot override. Uses `defaultConfig()` as the base so all required\n * fields are present; the snapshot fields win.\n */\nfunction resolvedConfigFromOverride(\n override: GlazeConfigOverride,\n): GlazeConfigResolved {\n return mergeConfig(defaultConfig(), override);\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 flip: options?.flip,\n opacity: options?.opacity,\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 effectiveConfig: GlazeConfigResolved,\n baseToken: GlazeColorToken | undefined,\n exportData: () => GlazeColorTokenExport,\n): GlazeColorToken {\n // Cache the resolve result across token / tasty / json / css / resolve calls.\n let cached: Map<string, ResolvedColor> | undefined;\n const resolveOnce = (): Map<string, ResolvedColor> => {\n if (cached) return cached;\n const externalBases = baseToken\n ? new Map([[STANDALONE_BASE, baseToken.resolve()]])\n : undefined;\n cached = resolveAllColors(\n seedHue,\n seedSaturation,\n defs,\n effectiveConfig,\n externalBases,\n );\n return cached;\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,\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 jsonMap = buildJsonMap(\n resolveOnce(),\n resolveModes(options?.modes),\n options?.format,\n );\n return jsonMap[primary];\n },\n\n css(options: GlazeColorCssOptions): GlazeCssResult {\n const renamed = new Map<string, ResolvedColor>([\n [options.name, resolveOnce().get(primary)!],\n ]);\n return buildCssMap(\n renamed,\n '',\n options.suffix ?? '-color',\n options.format ?? 'rgb',\n );\n },\n\n export: exportData,\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 flip: input.flip,\n contrast: input.contrast,\n opacity: input.opacity,\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 effectiveConfigOverride = buildStructuredConfigOverride(configOverride);\n const effectiveConfig = resolvedConfigFromOverride(effectiveConfigOverride);\n\n const exportData = (): GlazeColorTokenExport => ({\n form: 'structured',\n input: buildStructuredInputExport(input),\n config: effectiveConfigOverride,\n });\n\n return createColorTokenFromDefs(\n input.hue,\n input.saturation,\n defs,\n primary,\n effectiveConfig,\n baseToken,\n exportData,\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 effectiveConfigOverride = buildValueFormConfigOverride(configOverride);\n const effectiveConfig = resolvedConfigFromOverride(effectiveConfigOverride);\n\n const exportData = (): GlazeColorTokenExport => ({\n form: 'value',\n input: value,\n ...(options !== undefined\n ? { overrides: buildOverridesExport(options) }\n : {}),\n config: effectiveConfigOverride,\n });\n\n return createColorTokenFromDefs(\n seedHue,\n seedSaturation,\n defs,\n primary,\n effectiveConfig,\n linkingBase,\n exportData,\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): 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.flip !== undefined) out.flip = options.flip;\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.base !== undefined) {\n out.base = isGlazeColorToken(options.base)\n ? options.base.export()\n : options.base;\n }\n return out;\n}\n\nfunction buildStructuredInputExport(\n input: GlazeColorInput,\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.flip !== undefined) out.flip = input.flip;\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.base !== undefined) {\n out.base = isGlazeColorToken(input.base) ? input.base.export() : 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 (\n typeof candidate === 'object' &&\n candidate !== null &&\n !Array.isArray(candidate) &&\n 'form' in candidate &&\n ((candidate as GlazeColorTokenExport).form === 'value' ||\n (candidate as GlazeColorTokenExport).form === 'structured')\n );\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.flip !== undefined) out.flip = data.flip;\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.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.flip !== undefined) out.flip = data.flip;\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.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 contains the full effective config override\n * snapshotted at creation time, so the rehydrated token is deterministic\n * regardless of subsequent `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 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 // The stored `config` contains the full effective snapshot — pass it\n // directly so the rehydrated token reproduces identical behavior.\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 * 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 four export methods (`tokens` /\n * `tasty` / `json` / `css`) share a `buildPaletteOutput` driver that\n * handles validation, per-theme iteration, prefix resolution, collision\n * filtering, and primary duplication.\n */\n\nimport { getConfig } from './config';\nimport {\n buildCssMap,\n buildFlatTokenMap,\n buildJsonMap,\n buildTokenMap,\n resolveModes,\n} from './formatters';\nimport type {\n GlazeCssOptions,\n GlazeCssResult,\n GlazeJsonOptions,\n GlazePalette,\n GlazePaletteExportOptions,\n GlazePaletteOptions,\n GlazeTheme,\n GlazeTokenOptions,\n ResolvedColor,\n} from './types';\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\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: (resolved: Map<string, ResolvedColor>, prefix: string) => 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 prefix = resolvePrefix(options, themeName, true);\n const filtered = filterCollisions(resolved, prefix, seen, themeName);\n merge(acc, buildOne(filtered, prefix));\n\n if (themeName === effectivePrimary) {\n const primaryFiltered = filterCollisions(\n resolved,\n '',\n seen,\n themeName,\n true,\n );\n merge(acc, buildOne(primaryFiltered, ''));\n }\n }\n\n return acc;\n}\n\nexport function createPalette(\n themes: PaletteInput,\n paletteOptions?: GlazePaletteOptions,\n): GlazePalette {\n validatePrimaryTheme(paletteOptions?.primary, themes);\n\n return {\n tokens(\n options?: GlazeJsonOptions & GlazePaletteExportOptions,\n ): Record<string, Record<string, string>> {\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) =>\n buildFlatTokenMap(filtered, prefix, modes, options?.format),\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 return buildPaletteOutput<\n Record<string, Record<string, string>>,\n Record<string, Record<string, string>>\n >(\n themes,\n paletteOptions,\n options,\n (filtered, prefix) =>\n buildTokenMap(filtered, prefix, states, modes, options?.format),\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 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(resolved, modes, options?.format);\n }\n\n return result;\n },\n\n css(options?: GlazeCssOptions & GlazePaletteExportOptions): GlazeCssResult {\n const suffix = options?.suffix ?? '-color';\n const format = options?.format ?? 'rgb';\n\n const lines = buildPaletteOutput<\n GlazeCssResult,\n Record<keyof GlazeCssResult, string[]>\n >(\n themes,\n paletteOptions,\n options,\n (filtered, prefix) => buildCssMap(filtered, prefix, suffix, format),\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}\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()` / `resolve()` / `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 { getConfig, getConfigVersion, mergeConfig } from './config';\nimport {\n buildCssMap,\n buildFlatTokenMap,\n buildJsonMap,\n buildTokenMap,\n resolveModes,\n} from './formatters';\nimport { resolveAllColors } from './resolver';\nimport type {\n ColorDef,\n ColorMap,\n GlazeCssOptions,\n GlazeCssResult,\n GlazeConfigOverride,\n GlazeConfigResolved,\n GlazeExtendOptions,\n GlazeJsonOptions,\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>;\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 return mergeConfig(getConfig(), configOverride);\n }\n\n function resolveCached(): Map<string, ResolvedColor> {\n const version = getConfigVersion();\n if (cache && cache.version === version) return cache.map;\n const effectiveConfig = mergeConfig(getConfig(), configOverride);\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 const theme: GlazeTheme = {\n get hue() {\n return hue;\n },\n get saturation() {\n return saturation;\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(): GlazeThemeExport {\n const out: GlazeThemeExport = {\n hue,\n saturation,\n colors: { ...colorDefs },\n };\n if (configOverride !== undefined) out.config = configOverride;\n return out;\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 modes = resolveModes(options?.modes);\n return buildFlatTokenMap(resolveCached(), '', modes, options?.format);\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 return buildTokenMap(resolveCached(), '', states, modes, options?.format);\n },\n\n json(options?: GlazeJsonOptions): Record<string, Record<string, string>> {\n const modes = resolveModes(options?.modes);\n return buildJsonMap(resolveCached(), modes, options?.format);\n },\n\n css(options?: GlazeCssOptions): GlazeCssResult {\n return buildCssMap(\n resolveCached(),\n '',\n options?.suffix ?? '-color',\n options?.format ?? 'rgb',\n );\n },\n } as GlazeTheme;\n\n return theme;\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 */\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 { createPalette } from './palette';\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 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, saturation taper, 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/** Create a theme from a serialized export. */\nglaze.from = function from(data: GlazeThemeExport): GlazeTheme {\n return createTheme(data.hue, data.saturation, data.colors, data.config);\n};\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 * create time (and are snapshotted). Pass `false` for a tone window\n * to disable clamping entirely.\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 }, { saturationTaper: 0 })\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` internally). Structured form snapshots both\n * tone windows from `globalConfig` at create time.\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): string {\n return formatVariant(variant, colorFormat);\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 snapshot. The reconstructed token is identical\n * in behavior to the original at the time of export.\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/** 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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"}
|