fashionable 0.2.0 → 0.4.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.
Files changed (67) hide show
  1. package/dist/calc/index.d.mts +1 -1
  2. package/dist/calc/index.mjs +1 -1
  3. package/dist/data/index.d.mts +2 -208
  4. package/dist/data/index.mjs +73 -54
  5. package/dist/data/index.mjs.map +1 -1
  6. package/dist/declaration/index.d.mts +1 -1
  7. package/dist/declaration/index.mjs +9 -28
  8. package/dist/declaration/index.mjs.map +1 -1
  9. package/dist/fontFace/index.d.mts +1 -1
  10. package/dist/property/index.d.mts +1 -1
  11. package/dist/property/index.mjs +1 -1
  12. package/dist/property/index.mjs.map +1 -1
  13. package/dist/query/index.d.mts +1 -1
  14. package/dist/query/index.mjs +137 -3
  15. package/dist/query/index.mjs.map +1 -1
  16. package/dist/rule/index.d.mts +1 -1
  17. package/dist/rule/index.mjs +45 -33
  18. package/dist/rule/index.mjs.map +1 -1
  19. package/dist/selector/index.d.mts +1 -1
  20. package/dist/selector/index.mjs +117 -21
  21. package/dist/selector/index.mjs.map +1 -1
  22. package/dist/shared/{calc-Cih4o2r7.mjs → calc-Uwbxd7CS.mjs} +233 -165
  23. package/dist/shared/calc-Uwbxd7CS.mjs.map +1 -0
  24. package/dist/shared/{color.internal-Dts5ycTm.mjs → color.internal-CxjlaRqR.mjs} +48 -13
  25. package/dist/shared/color.internal-CxjlaRqR.mjs.map +1 -0
  26. package/dist/shared/declaration-CqRm38oZ.d.mts +264 -0
  27. package/dist/shared/declaration.internal-bHzvbanA.mjs +121 -0
  28. package/dist/shared/declaration.internal-bHzvbanA.mjs.map +1 -0
  29. package/dist/shared/{fontFaceRule-C7nYgH6X.d.mts → fontFaceRule-BOgUM4PF.d.mts} +3 -3
  30. package/dist/shared/index-D-hVWDgZ.d.mts +2289 -0
  31. package/dist/shared/mediaQuery-VDIAHnM1.d.mts +333 -0
  32. package/dist/shared/{mediaQuery.internal-B6iuMd75.mjs → mediaQuery.internal-CKTmLVxL.mjs} +70 -6
  33. package/dist/shared/mediaQuery.internal-CKTmLVxL.mjs.map +1 -0
  34. package/dist/shared/{mediaRule-BDB4WCYy.d.mts → mediaRule-2K7Ggwe4.d.mts} +169 -105
  35. package/dist/shared/{propertyRule-BbkFh9b9.d.mts → propertyRule-B9ii0mv4.d.mts} +56 -21
  36. package/dist/shared/{propertyRule.internal-Bc_HrfcL.mjs → propertyRule.internal-ncYCWUar.mjs} +31 -4
  37. package/dist/shared/propertyRule.internal-ncYCWUar.mjs.map +1 -0
  38. package/dist/shared/{ruleSet.internal-DodzVMUU.mjs → ruleSet.internal-Cj4yIYFI.mjs} +31 -18
  39. package/dist/shared/ruleSet.internal-Cj4yIYFI.mjs.map +1 -0
  40. package/dist/shared/selector-BkxnzX_6.d.mts +615 -0
  41. package/dist/shared/{selector.internal-ESe9s0IH.mjs → selector.internal-B3iu_RpX.mjs} +144 -30
  42. package/dist/shared/selector.internal-B3iu_RpX.mjs.map +1 -0
  43. package/dist/shared/{utils-BKm298I-.d.mts → utils-DpN6qr94.d.mts} +4 -4
  44. package/dist/shared/var.internal-DSxAzEFN.mjs +119 -0
  45. package/dist/shared/var.internal-DSxAzEFN.mjs.map +1 -0
  46. package/dist/stylesheet/index.d.mts +93 -60
  47. package/dist/stylesheet/index.mjs +111 -35
  48. package/dist/stylesheet/index.mjs.map +1 -1
  49. package/dist/utils.d.mts +1 -1
  50. package/dist/utils.mjs.map +1 -1
  51. package/dist/var/index.d.mts +2 -0
  52. package/dist/var/index.mjs +177 -0
  53. package/dist/var/index.mjs.map +1 -0
  54. package/package.json +8 -2
  55. package/dist/shared/calc-Cih4o2r7.mjs.map +0 -1
  56. package/dist/shared/color-BvNJ2YqL.d.mts +0 -590
  57. package/dist/shared/color.internal-Dts5ycTm.mjs.map +0 -1
  58. package/dist/shared/declaration-1DlO_ltT.d.mts +0 -166
  59. package/dist/shared/declaration.internal-wLB4ssxC.mjs +0 -73
  60. package/dist/shared/declaration.internal-wLB4ssxC.mjs.map +0 -1
  61. package/dist/shared/index-BvtwY4FQ.d.mts +0 -841
  62. package/dist/shared/mediaQuery-BYR1z-iD.d.mts +0 -145
  63. package/dist/shared/mediaQuery.internal-B6iuMd75.mjs.map +0 -1
  64. package/dist/shared/propertyRule.internal-Bc_HrfcL.mjs.map +0 -1
  65. package/dist/shared/ruleSet.internal-DodzVMUU.mjs.map +0 -1
  66. package/dist/shared/selector-HZY-W6l6.d.mts +0 -346
  67. package/dist/shared/selector.internal-ESe9s0IH.mjs.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"calc-Uwbxd7CS.mjs","names":["Equal.hashString","Equal.combine","Equal.hashNumber","Equal.EqualTypeId","isCalc","Equal.HashTypeId","#hash","of","varNameOf","add","min","max","subtract","multiply","mod","divide","pow","signedPow","abs","sign","sin","cos","tan","acos","atan2","clamp","lerp","bind","solve","serialize","idents","units","equals","Equal.equals","internal.isCalc","internal.of","internal.ref","internal.add","internal.subtract","internal.mod","internal.multiply","internal.divide","internal.pow","internal.signedPow","internal.min","internal.max","internal.clamp","internal.lerp","internal.abs","internal.sign","internal.sin","internal.cos","internal.tan","internal.acos","internal.atan2","internal.bind","internal.solve","internal.serialize","internal.refs","internal.idents","internal.units","internal.equals","internal.isPrecision","internal.decimals","internal.significant"],"sources":["../../src/calc/calc.internal.ts","../../src/calc/calc.ts","../../src/calc/precision.ts"],"sourcesContent":["import type { Unit } from '#data'\nimport * as Equal from '#internal/equal'\nimport {\n DEFAULT_FORMAT,\n type FormatSpec,\n formatWith,\n specEquals,\n specFidelity,\n} from '#internal/format'\nimport { EMPTY_REFS, RefsTypeId } from '#internal/refs'\nimport { dual, invariant, Pipeable } from '#util'\nimport type { Name as VarName } from '#var/var'\nimport {\n type AnyVar,\n declaredTypeOf,\n fallbackOf,\n isVar,\n nameOf as varNameOf,\n refsOfVar,\n} from '#var/var.internal'\nimport type { Bindings, Calc, Input, Kind, SerializeOptions, Top } from './calc.ts'\nimport { toSpec } from './precision.internal.ts'\nimport type { Precision } from './precision.ts'\n\nexport const CalcTypeId = Symbol.for('fashionable/calc')\nexport type CalcTypeId = typeof CalcTypeId\n\n// ---------------------------------------------------------------------------\n// node ADT\n// ---------------------------------------------------------------------------\n\n/** @internal */\nexport interface ConstantNode {\n readonly _tag: 'Constant'\n readonly value: number\n readonly precision: FormatSpec | undefined\n /** The CSS unit token (`'px'`, `'rad'`), or `undefined` for a plain number. */\n readonly unit: string | undefined\n /** The CSS dimension, supplied by the constructing data module. */\n readonly kind: Kind\n}\n\n/**\n * A custom-property read. `fallback`, when present, is the read's rendered\n * second argument — a whole calc tree, with nested reads lowered to nested\n * `Ref` nodes. It participates in the vars set and in `bind` substitution,\n * but never in `units`/`idents` collection (those mirror `Requires`, and a\n * fallback is unreachable in every projection that consumes requirements)\n * and never in evaluation (`solve` substitutes the mandatory binding, which\n * discards it).\n *\n * @internal\n */\nexport interface RefNode {\n readonly _tag: 'Ref'\n readonly name: string\n readonly fallback?: CalcNode\n}\n\n/**\n * A bare CSS identifier leaf — an unquoted token resolved from its surrounding\n * context, not the custom-property channel. Serializes as its name (`l`, not\n * `var(--l)`) and contributes no variables; `bind` passes it through untouched.\n * It carries a leaf brand (`Calc.Ident`), so `solve` demands a value for it by\n * name through the `idents` section of its options, the way a viewport unit\n * demands a ratio through `units`. Today the relative-color channel keywords\n * (`Channel.L`, `Channel.C`, ...) are its only source.\n *\n * @internal\n */\nexport interface IdentNode {\n readonly _tag: 'Ident'\n readonly name: string\n}\n\n/** @internal */\nexport type CalcNode =\n | ConstantNode\n | RefNode\n | IdentNode\n | { readonly _tag: 'Add'; readonly terms: ReadonlyArray<CalcNode> }\n | { readonly _tag: 'Subtract'; readonly left: CalcNode; readonly right: CalcNode }\n | { readonly _tag: 'Multiply'; readonly left: CalcNode; readonly right: CalcNode }\n | { readonly _tag: 'Divide'; readonly left: CalcNode; readonly right: CalcNode }\n | { readonly _tag: 'Mod'; readonly left: CalcNode; readonly right: CalcNode }\n | { readonly _tag: 'Pow'; readonly base: CalcNode; readonly exponent: CalcNode }\n | { readonly _tag: 'SignedPow'; readonly base: CalcNode; readonly exponent: CalcNode }\n | { readonly _tag: 'Min'; readonly args: ReadonlyArray<CalcNode> }\n | { readonly _tag: 'Max'; readonly args: ReadonlyArray<CalcNode> }\n | {\n readonly _tag: 'Clamp'\n readonly minimum: CalcNode\n readonly value: CalcNode\n readonly maximum: CalcNode\n }\n | { readonly _tag: 'Abs'; readonly argument: CalcNode }\n | { readonly _tag: 'Sign'; readonly argument: CalcNode }\n | { readonly _tag: 'Sin'; readonly argument: CalcNode }\n | { readonly _tag: 'Cos'; readonly argument: CalcNode }\n | { readonly _tag: 'Tan'; readonly argument: CalcNode }\n | { readonly _tag: 'Acos'; readonly argument: CalcNode }\n | { readonly _tag: 'Atan2'; readonly y: CalcNode; readonly x: CalcNode }\n\nconst isConstant = (node: CalcNode): node is ConstantNode => node._tag === 'Constant'\n\n// ---------------------------------------------------------------------------\n// smart node constructors: eager constant folding + precision propagation\n// ---------------------------------------------------------------------------\n\nconst constantNode = (\n value: number,\n precision: FormatSpec | undefined,\n unit: string | undefined = undefined,\n kind: Kind = 'number',\n): ConstantNode => {\n invariant(Number.isFinite(value), `Constant value must be a finite number, got ${value}`)\n return { _tag: 'Constant', value, precision, unit, kind }\n}\n\n/**\n * The shared (unit, kind) of a run of constants, or `undefined` when they mix\n * units and so cannot fold to a single constant (`10px + 5vw` stays symbolic).\n */\nconst commonDimension = (\n nodes: ReadonlyArray<ConstantNode>,\n): { readonly unit: string | undefined; readonly kind: Kind } | undefined => {\n const first = nodes[0]\n if (first === undefined) {\n return { unit: undefined, kind: 'number' }\n }\n for (const node of nodes) {\n if (node.unit !== first.unit) {\n return undefined\n }\n }\n return { unit: first.unit, kind: first.kind }\n}\n\nconst bestPrecision = (nodes: ReadonlyArray<ConstantNode>): FormatSpec | undefined => {\n let best: FormatSpec | undefined\n for (const node of nodes) {\n if (specFidelity(node.precision) > specFidelity(best)) {\n best = node.precision\n }\n }\n return best\n}\n\nconst addNode = (terms: ReadonlyArray<CalcNode>): CalcNode => {\n if (terms.every(isConstant)) {\n const dim = commonDimension(terms)\n if (dim !== undefined) {\n return constantNode(\n terms.reduce((total, term) => total + term.value, 0),\n bestPrecision(terms),\n dim.unit,\n dim.kind,\n )\n }\n }\n return { _tag: 'Add', terms }\n}\n\nconst subtractNode = (left: CalcNode, right: CalcNode): CalcNode => {\n if (isConstant(left) && isConstant(right) && left.unit === right.unit) {\n return constantNode(\n left.value - right.value,\n bestPrecision([left, right]),\n left.unit,\n left.kind,\n )\n }\n return { _tag: 'Subtract', left, right }\n}\n\nconst multiplyNode = (left: CalcNode, right: CalcNode): CalcNode => {\n if (isConstant(left) && isConstant(right)) {\n // A dimensioned factor rides through a number factor; two dimensioned\n // factors are invalid CSS (rejected at the type level) and stay symbolic.\n if (left.unit === undefined) {\n return constantNode(\n left.value * right.value,\n bestPrecision([left, right]),\n right.unit,\n right.kind,\n )\n }\n if (right.unit === undefined) {\n return constantNode(\n left.value * right.value,\n bestPrecision([left, right]),\n left.unit,\n left.kind,\n )\n }\n }\n return { _tag: 'Multiply', left, right }\n}\n\nconst divideNode = (left: CalcNode, right: CalcNode): CalcNode => {\n if (isConstant(left) && isConstant(right)) {\n if (left.unit === right.unit) {\n // same unit (or both unit-free) -> the ratio is a unit-free number\n return constantNode(left.value / right.value, bestPrecision([left, right]))\n }\n if (right.unit === undefined) {\n return constantNode(\n left.value / right.value,\n bestPrecision([left, right]),\n left.unit,\n left.kind,\n )\n }\n // number / dimensioned, or two differing dimensioned units: no context-free\n // value, so stay symbolic (the browser resolves the units)\n }\n return { _tag: 'Divide', left, right }\n}\n\n// CSS mod(): the result takes the sign of the divisor, so it is the floored\n// modulo. Folds only when both operands share a unit (or are unit-free).\nconst modNode = (left: CalcNode, right: CalcNode): CalcNode => {\n if (isConstant(left) && isConstant(right) && left.unit === right.unit) {\n return constantNode(\n left.value - right.value * Math.floor(left.value / right.value),\n bestPrecision([left, right]),\n left.unit,\n left.kind,\n )\n }\n return { _tag: 'Mod', left, right }\n}\n\nconst powNode = (base: CalcNode, exponent: CalcNode): CalcNode => {\n if (isConstant(base) && isConstant(exponent)) {\n return constantNode(base.value ** exponent.value, bestPrecision([base, exponent]))\n }\n return { _tag: 'Pow', base, exponent }\n}\n\nconst signedPowNode = (base: CalcNode, exponent: CalcNode): CalcNode => {\n if (isConstant(base) && isConstant(exponent)) {\n return constantNode(\n Math.abs(base.value) ** exponent.value * Math.sign(base.value),\n bestPrecision([base, exponent]),\n )\n }\n return { _tag: 'SignedPow', base, exponent }\n}\n\nconst naryNode =\n (tag: 'Min' | 'Max', compute: (values: ReadonlyArray<number>) => number) =>\n (args: ReadonlyArray<CalcNode>): CalcNode => {\n if (args.every(isConstant)) {\n const dim = commonDimension(args)\n if (dim !== undefined) {\n return constantNode(\n compute(args.map((arg) => arg.value)),\n bestPrecision(args),\n dim.unit,\n dim.kind,\n )\n }\n }\n return { _tag: tag, args }\n }\n\nconst minNode = naryNode('Min', (values) => Math.min(...values))\nconst maxNode = naryNode('Max', (values) => Math.max(...values))\n\nconst clampNode = (minimum: CalcNode, value: CalcNode, maximum: CalcNode): CalcNode => {\n if (isConstant(minimum) && isConstant(value) && isConstant(maximum)) {\n const dim = commonDimension([minimum, value, maximum])\n if (dim !== undefined) {\n return constantNode(\n Math.max(minimum.value, Math.min(value.value, maximum.value)),\n bestPrecision([minimum, value, maximum]),\n dim.unit,\n dim.kind,\n )\n }\n }\n return { _tag: 'Clamp', minimum, value, maximum }\n}\n\ntype UnaryTag = 'Abs' | 'Sign' | 'Sin' | 'Cos' | 'Tan' | 'Acos'\n\n/**\n * Per-function data for the unary math nodes — the single source of truth the\n * fold constructor, the evaluator, and the serializer all read:\n *\n * - `fn` both folds a constant operand and lowers the node under `solve`, so the\n * construction-time and solve-time numerics can never drift.\n * - `css` is the math-function name serialization emits.\n * - `result` is the folded constant's dimension: `sign`/`sin`/`cos`/`tan`\n * produce a plain `number`; `abs` preserves the operand's; `acos` returns\n * radians, so its constant composes with `Angle.rad` terms and stays valid CSS\n * with no plain-number-beside-angle hack.\n */\nconst UNARY: Record<\n UnaryTag,\n {\n readonly fn: (x: number) => number\n readonly css: string\n readonly result: 'number' | 'preserve' | 'rad'\n }\n> = {\n Abs: { fn: Math.abs, css: 'abs', result: 'preserve' },\n Sign: { fn: Math.sign, css: 'sign', result: 'number' },\n Sin: { fn: Math.sin, css: 'sin', result: 'number' },\n Cos: { fn: Math.cos, css: 'cos', result: 'number' },\n Tan: { fn: Math.tan, css: 'tan', result: 'number' },\n Acos: { fn: Math.acos, css: 'acos', result: 'rad' },\n}\n\nconst foldUnary = (tag: UnaryTag, argument: CalcNode): CalcNode => {\n if (!isConstant(argument)) {\n return { _tag: tag, argument }\n }\n const { fn, result } = UNARY[tag]\n const value = fn(argument.value)\n // No `default`: a new `result` variant becomes a missing-return type error here,\n // the same exhaustiveness the node walkers rely on.\n switch (result) {\n case 'number':\n return constantNode(value, argument.precision)\n case 'preserve':\n return constantNode(value, argument.precision, argument.unit, argument.kind)\n case 'rad':\n return constantNode(value, argument.precision, 'rad', 'angle')\n }\n}\n\n// atan2(y, x) returns an <angle>. It also divides same-kind dimensions to a\n// number via tan(atan2(a, b)): a length ratio that works where `a / b` does not\n// (Firefox does not yet support <length> / <length> in calc). Folds only when\n// both operands share a unit, so the ratio is unit-free (like divide).\nconst atan2Node = (y: CalcNode, x: CalcNode): CalcNode => {\n if (isConstant(y) && isConstant(x) && y.unit === x.unit) {\n return constantNode(Math.atan2(y.value, x.value), bestPrecision([y, x]), 'rad', 'angle')\n }\n return { _tag: 'Atan2', y, x }\n}\n\n// ---------------------------------------------------------------------------\n// walkers\n// ---------------------------------------------------------------------------\n\n/** @internal */\nexport const substituteNode = (node: CalcNode, bindings: Record<string, CalcNode>): CalcNode => {\n switch (node._tag) {\n case 'Constant':\n return node\n case 'Ref': {\n const bound = bindings[node.name]\n if (bound !== undefined) {\n // author substitution wins over cascade defaulting: the whole read\n // is replaced and the fallback discarded\n return bound\n }\n if (node.fallback === undefined) {\n return node\n }\n const fallback = substituteNode(node.fallback, bindings)\n return fallback === node.fallback ? node : { _tag: 'Ref', name: node.name, fallback }\n }\n case 'Ident':\n return node\n case 'Add':\n return addNode(node.terms.map((term) => substituteNode(term, bindings)))\n case 'Subtract':\n return subtractNode(substituteNode(node.left, bindings), substituteNode(node.right, bindings))\n case 'Multiply':\n return multiplyNode(substituteNode(node.left, bindings), substituteNode(node.right, bindings))\n case 'Divide':\n return divideNode(substituteNode(node.left, bindings), substituteNode(node.right, bindings))\n case 'Mod':\n return modNode(substituteNode(node.left, bindings), substituteNode(node.right, bindings))\n case 'Pow':\n return powNode(substituteNode(node.base, bindings), substituteNode(node.exponent, bindings))\n case 'SignedPow':\n return signedPowNode(\n substituteNode(node.base, bindings),\n substituteNode(node.exponent, bindings),\n )\n case 'Min':\n return minNode(node.args.map((arg) => substituteNode(arg, bindings)))\n case 'Max':\n return maxNode(node.args.map((arg) => substituteNode(arg, bindings)))\n case 'Clamp':\n return clampNode(\n substituteNode(node.minimum, bindings),\n substituteNode(node.value, bindings),\n substituteNode(node.maximum, bindings),\n )\n case 'Abs':\n case 'Sign':\n case 'Sin':\n case 'Cos':\n case 'Tan':\n case 'Acos':\n return foldUnary(node._tag, substituteNode(node.argument, bindings))\n case 'Atan2':\n return atan2Node(substituteNode(node.y, bindings), substituteNode(node.x, bindings))\n }\n}\n\n/**\n * The units that lower with no caller-supplied ratio: `px` is the pixel base\n * (`1`), a radian is already the numeric measure of its angle (`1`), and a\n * degree is a fixed `pi / 180` of one. Every other unit is context-dependent\n * and must appear in the `units` section of the solve options.\n *\n * @internal\n */\nexport const DEFAULT_RATIOS: Record<string, number> = { px: 1, rad: 1, deg: Math.PI / 180 }\n\n/** @internal */\nexport const evaluateNode = (\n node: CalcNode,\n unitRatios: Record<string, number>,\n identValues: Record<string, number>,\n): number => {\n switch (node._tag) {\n case 'Constant': {\n if (node.unit === undefined) {\n return node.value\n }\n const ratio = unitRatios[node.unit] ?? DEFAULT_RATIOS[node.unit]\n invariant(\n ratio !== undefined,\n `Cannot evaluate ${node.value}${node.unit}: no ratio for '${node.unit}' in the units section`,\n )\n return node.value * ratio\n }\n case 'Ref':\n throw new Error(`Cannot evaluate unbound variable: ${node.name}`)\n case 'Ident': {\n const value = identValues[node.name]\n invariant(\n value !== undefined,\n `Cannot evaluate '${node.name}': no value for it in the idents section`,\n )\n return value\n }\n case 'Add':\n return node.terms.reduce(\n (total, term) => total + evaluateNode(term, unitRatios, identValues),\n 0,\n )\n case 'Subtract':\n return (\n evaluateNode(node.left, unitRatios, identValues) -\n evaluateNode(node.right, unitRatios, identValues)\n )\n case 'Multiply':\n return (\n evaluateNode(node.left, unitRatios, identValues) *\n evaluateNode(node.right, unitRatios, identValues)\n )\n case 'Divide':\n return (\n evaluateNode(node.left, unitRatios, identValues) /\n evaluateNode(node.right, unitRatios, identValues)\n )\n case 'Mod': {\n const dividend = evaluateNode(node.left, unitRatios, identValues)\n const divisor = evaluateNode(node.right, unitRatios, identValues)\n return dividend - divisor * Math.floor(dividend / divisor)\n }\n case 'Pow':\n return (\n evaluateNode(node.base, unitRatios, identValues) **\n evaluateNode(node.exponent, unitRatios, identValues)\n )\n case 'SignedPow': {\n const base = evaluateNode(node.base, unitRatios, identValues)\n return (\n Math.abs(base) ** evaluateNode(node.exponent, unitRatios, identValues) * Math.sign(base)\n )\n }\n case 'Min':\n return Math.min(...node.args.map((arg) => evaluateNode(arg, unitRatios, identValues)))\n case 'Max':\n return Math.max(...node.args.map((arg) => evaluateNode(arg, unitRatios, identValues)))\n case 'Clamp':\n return Math.max(\n evaluateNode(node.minimum, unitRatios, identValues),\n Math.min(\n evaluateNode(node.value, unitRatios, identValues),\n evaluateNode(node.maximum, unitRatios, identValues),\n ),\n )\n case 'Abs':\n case 'Sign':\n case 'Sin':\n case 'Cos':\n case 'Tan':\n case 'Acos':\n return UNARY[node._tag].fn(evaluateNode(node.argument, unitRatios, identValues))\n case 'Atan2':\n return Math.atan2(\n evaluateNode(node.y, unitRatios, identValues),\n evaluateNode(node.x, unitRatios, identValues),\n )\n }\n}\n\n/**\n * True for the arithmetic forms that need a `calc()` wrapper when they\n * stand alone; function forms and leaves never do.\n *\n * @internal\n */\nexport const needsCalcWrap = (node: CalcNode): boolean =>\n node._tag === 'Add' ||\n node._tag === 'Subtract' ||\n node._tag === 'Multiply' ||\n node._tag === 'Divide' ||\n node._tag === 'SignedPow'\n\n// ---------------------------------------------------------------------------\n// serialization\n// ---------------------------------------------------------------------------\n\ninterface SerializeContext {\n readonly precision: FormatSpec\n}\n\nconst PI_TOLERANCE = 1e-10\n\nconst formatConstant = (\n node: ConstantNode,\n insideMath: boolean,\n context: SerializeContext,\n): string => {\n if (node.unit === undefined && insideMath && Math.abs(node.value - Math.PI) < PI_TOLERANCE) {\n return 'pi'\n }\n const text = formatWith(node.value, node.precision ?? context.precision)\n return node.unit !== undefined ? `${text}${node.unit}` : text\n}\n\nconst wrapOperand = (node: CalcNode, serialized: string): string =>\n node._tag === 'Add' || node._tag === 'Subtract' ? `(${serialized})` : serialized\n\n/**\n * A fallback renders under the normal top-level rules — `var()`\n * substitution is token-level, so an arithmetic fallback carries its own\n * nested `calc()` wrapper rather than leaning on the surrounding context.\n */\nconst serializeFallback = (node: CalcNode, context: SerializeContext): string => {\n const wrap = needsCalcWrap(node)\n const body = serializeNode(node, wrap, context)\n return wrap ? `calc(${body})` : body\n}\n\nconst hasNegativeCoefficient = (node: CalcNode): boolean => {\n if (isConstant(node)) {\n return node.value < 0\n }\n if (node._tag === 'Multiply' || node._tag === 'Divide') {\n return isConstant(node.left) && node.left.value < 0\n }\n return false\n}\n\n/**\n * Serializes the negation of a term whose leading coefficient is a\n * negative constant, so `a + (-k * x)` renders as `a - k * x`.\n */\nconst serializeNegated = (\n node: CalcNode,\n insideMath: boolean,\n context: SerializeContext,\n): string => {\n if (isConstant(node)) {\n return formatConstant(\n constantNode(-node.value, node.precision, node.unit, node.kind),\n insideMath,\n context,\n )\n }\n const binary = node as Extract<CalcNode, { _tag: 'Multiply' | 'Divide' }>\n const left = binary.left as ConstantNode\n const negated: CalcNode = {\n _tag: binary._tag,\n left: constantNode(-left.value, left.precision, left.unit, left.kind),\n right: binary.right,\n }\n return serializeNode(negated, insideMath, context)\n}\n\n/** @internal */\nexport const serializeNode = (\n node: CalcNode,\n insideMath: boolean,\n context: SerializeContext,\n): string => {\n switch (node._tag) {\n case 'Constant':\n return formatConstant(node, insideMath, context)\n case 'Ref':\n return node.fallback === undefined\n ? `var(--${node.name})`\n : `var(--${node.name}, ${serializeFallback(node.fallback, context)})`\n case 'Ident':\n return node.name\n case 'Add': {\n let out = ''\n for (const [index, term] of node.terms.entries()) {\n if (index === 0) {\n out = serializeNode(term, insideMath, context)\n } else if (hasNegativeCoefficient(term)) {\n out += ` - ${serializeNegated(term, insideMath, context)}`\n } else {\n out += ` + ${serializeNode(term, insideMath, context)}`\n }\n }\n return out\n }\n case 'Subtract': {\n const left = serializeNode(node.left, insideMath, context)\n if (hasNegativeCoefficient(node.right)) {\n return `${left} + ${serializeNegated(node.right, insideMath, context)}`\n }\n return `${left} - ${serializeNode(node.right, insideMath, context)}`\n }\n case 'Multiply': {\n const left = wrapOperand(node.left, serializeNode(node.left, insideMath, context))\n const right = wrapOperand(node.right, serializeNode(node.right, insideMath, context))\n return `${left} * ${right}`\n }\n case 'Divide': {\n const left = wrapOperand(node.left, serializeNode(node.left, insideMath, context))\n const right = wrapOperand(node.right, serializeNode(node.right, insideMath, context))\n return `${left} / ${right}`\n }\n case 'Mod':\n return `mod(${serializeNode(node.left, true, context)}, ${serializeNode(node.right, true, context)})`\n case 'Pow':\n return `pow(${serializeNode(node.base, true, context)}, ${serializeNode(node.exponent, true, context)})`\n case 'SignedPow': {\n const base = serializeNode(node.base, true, context)\n const exponent = serializeNode(node.exponent, true, context)\n return `pow(abs(${base}), ${exponent}) * sign(${base})`\n }\n case 'Min':\n return `min(${node.args.map((arg) => serializeNode(arg, true, context)).join(', ')})`\n case 'Max':\n return `max(${node.args.map((arg) => serializeNode(arg, true, context)).join(', ')})`\n case 'Clamp':\n return `clamp(${serializeNode(node.minimum, true, context)}, ${serializeNode(node.value, true, context)}, ${serializeNode(node.maximum, true, context)})`\n case 'Abs':\n case 'Sign':\n case 'Sin':\n case 'Cos':\n case 'Tan':\n case 'Acos':\n return `${UNARY[node._tag].css}(${serializeNode(node.argument, true, context)})`\n case 'Atan2':\n return `atan2(${serializeNode(node.y, true, context)}, ${serializeNode(node.x, true, context)})`\n }\n}\n\n/** @internal */\nexport const serializeTop = (node: CalcNode, precision: FormatSpec): string => {\n const wrap = needsCalcWrap(node)\n const body = serializeNode(node, wrap, { precision })\n return wrap ? `calc(${body})` : body\n}\n\n// ---------------------------------------------------------------------------\n// structural equality\n// ---------------------------------------------------------------------------\n\nconst nodeArrayEquals = (a: ReadonlyArray<CalcNode>, b: ReadonlyArray<CalcNode>): boolean =>\n a.length === b.length && a.every((node, index) => nodeEquals(node, b[index] as CalcNode))\n\n/** @internal */\nexport const nodeEquals = (a: CalcNode, b: CalcNode): boolean => {\n if (a === b) {\n return true\n }\n if (a._tag !== b._tag) {\n return false\n }\n switch (a._tag) {\n case 'Constant': {\n const other = b as ConstantNode\n return (\n a.value === other.value && a.unit === other.unit && specEquals(a.precision, other.precision)\n )\n }\n case 'Ref': {\n const other = b as RefNode\n if (a.name !== other.name) {\n return false\n }\n return a.fallback === undefined || other.fallback === undefined\n ? a.fallback === other.fallback\n : nodeEquals(a.fallback, other.fallback)\n }\n case 'Ident':\n return a.name === (b as IdentNode).name\n case 'Add':\n return nodeArrayEquals(a.terms, (b as typeof a).terms)\n case 'Subtract':\n case 'Multiply':\n case 'Divide':\n case 'Mod': {\n const other = b as typeof a\n return nodeEquals(a.left, other.left) && nodeEquals(a.right, other.right)\n }\n case 'Pow':\n case 'SignedPow': {\n const other = b as typeof a\n return nodeEquals(a.base, other.base) && nodeEquals(a.exponent, other.exponent)\n }\n case 'Min':\n case 'Max':\n return nodeArrayEquals(a.args, (b as typeof a).args)\n case 'Clamp': {\n const other = b as typeof a\n return (\n nodeEquals(a.minimum, other.minimum) &&\n nodeEquals(a.value, other.value) &&\n nodeEquals(a.maximum, other.maximum)\n )\n }\n case 'Abs':\n case 'Sign':\n case 'Sin':\n case 'Cos':\n case 'Tan':\n case 'Acos':\n return nodeEquals(a.argument, (b as typeof a).argument)\n case 'Atan2': {\n const other = b as typeof a\n return nodeEquals(a.y, other.y) && nodeEquals(a.x, other.x)\n }\n }\n}\n\nconst hashNodeArray = (tag: string, nodes: ReadonlyArray<CalcNode>): number => {\n let h = Equal.hashString(tag)\n for (const node of nodes) {\n h = Equal.combine(h, nodeHash(node))\n }\n return h\n}\n\n/** @internal */\nexport const nodeHash = (node: CalcNode): number => {\n switch (node._tag) {\n case 'Constant': {\n const precision =\n node.precision === undefined\n ? 0\n : Equal.combine(Equal.hashString(node.precision.mode), node.precision.digits | 0)\n const unit = node.unit === undefined ? 0 : Equal.hashString(node.unit)\n return Equal.combine(\n Equal.hashString('Constant'),\n Equal.combine(Equal.combine(Equal.hashNumber(node.value), precision), unit),\n )\n }\n case 'Ref':\n return Equal.combine(\n Equal.combine(Equal.hashString('Ref'), Equal.hashString(node.name)),\n node.fallback === undefined ? 0 : nodeHash(node.fallback),\n )\n case 'Ident':\n return Equal.combine(Equal.hashString('Ident'), Equal.hashString(node.name))\n case 'Add':\n return hashNodeArray('Add', node.terms)\n case 'Subtract':\n case 'Multiply':\n case 'Divide':\n case 'Mod':\n return hashNodeArray(node._tag, [node.left, node.right])\n case 'Pow':\n case 'SignedPow':\n return hashNodeArray(node._tag, [node.base, node.exponent])\n case 'Min':\n case 'Max':\n return hashNodeArray(node._tag, node.args)\n case 'Clamp':\n return hashNodeArray('Clamp', [node.minimum, node.value, node.maximum])\n case 'Abs':\n case 'Sign':\n case 'Sin':\n case 'Cos':\n case 'Tan':\n case 'Acos':\n return hashNodeArray(node._tag, [node.argument])\n case 'Atan2':\n return hashNodeArray('Atan2', [node.y, node.x])\n }\n}\n\n// ---------------------------------------------------------------------------\n// the public value\n// ---------------------------------------------------------------------------\n\nclass CalcImpl extends Pipeable implements Calc<AnyVar>, Equal.Equal {\n readonly [CalcTypeId]: CalcTypeId = CalcTypeId\n\n readonly node: CalcNode\n readonly refSet: ReadonlySet<string>\n #hash: number | undefined\n\n constructor(node: CalcNode, refSet: ReadonlySet<string>) {\n super()\n this.node = node\n this.refSet = refSet\n }\n\n get [RefsTypeId](): ReadonlySet<string> {\n return this.refSet\n }\n\n [Equal.EqualTypeId](that: unknown): boolean {\n return isCalc(that) && nodeEquals(this.node, nodeOf(that))\n }\n\n [Equal.HashTypeId](): number {\n this.#hash ??= Equal.combine(Equal.hashString('fashionable/calc'), nodeHash(this.node))\n return this.#hash\n }\n\n get [Symbol.toStringTag]() {\n return `Calc(${serializeTop(this.node, DEFAULT_FORMAT)})`\n }\n\n get [Symbol.for('nodejs.util.inspect.custom')]() {\n return this[Symbol.toStringTag]\n }\n}\n\n/** @internal */\nexport const isCalc = (u: unknown): u is Calc<AnyVar, Unit.Any, unknown> =>\n typeof u === 'object' && u !== null && CalcTypeId in u\n\n/** @internal */\nexport const nodeOf = (expr: Top): CalcNode => (expr as CalcImpl).node\n\n/** @internal */\nexport const refsOf = (expr: Top): ReadonlySet<string> => (expr as unknown as CalcImpl).refSet\n\n// Neither leaf token kind is tracked in the ref set (they are not custom\n// properties), so both are gathered by walking the tree on demand — the\n// runtime counterpart to the `Requires`-level typing, one pass collecting into\n// whichever sets are supplied.\nconst collectTokens = (\n node: CalcNode,\n intoUnits: Set<string> | undefined,\n intoIdents: Set<string> | undefined,\n): void => {\n switch (node._tag) {\n case 'Ident':\n intoIdents?.add(node.name)\n return\n case 'Constant':\n if (node.unit !== undefined) {\n intoUnits?.add(node.unit)\n }\n return\n case 'Ref':\n return\n case 'Add':\n for (const term of node.terms) {\n collectTokens(term, intoUnits, intoIdents)\n }\n return\n case 'Min':\n case 'Max':\n for (const arg of node.args) {\n collectTokens(arg, intoUnits, intoIdents)\n }\n return\n case 'Subtract':\n case 'Multiply':\n case 'Divide':\n case 'Mod':\n collectTokens(node.left, intoUnits, intoIdents)\n collectTokens(node.right, intoUnits, intoIdents)\n return\n case 'Pow':\n case 'SignedPow':\n collectTokens(node.base, intoUnits, intoIdents)\n collectTokens(node.exponent, intoUnits, intoIdents)\n return\n case 'Clamp':\n collectTokens(node.minimum, intoUnits, intoIdents)\n collectTokens(node.value, intoUnits, intoIdents)\n collectTokens(node.maximum, intoUnits, intoIdents)\n return\n case 'Abs':\n case 'Sign':\n case 'Sin':\n case 'Cos':\n case 'Tan':\n case 'Acos':\n collectTokens(node.argument, intoUnits, intoIdents)\n return\n case 'Atan2':\n collectTokens(node.y, intoUnits, intoIdents)\n collectTokens(node.x, intoUnits, intoIdents)\n return\n }\n}\n\n/** @internal */\nexport const identsOf = (node: CalcNode): ReadonlySet<string> => {\n const set = new Set<string>()\n collectTokens(node, undefined, set)\n return set\n}\n\n/** @internal */\nexport const unitsOf = (node: CalcNode): ReadonlySet<string> => {\n const set = new Set<string>()\n collectTokens(node, set, undefined)\n return set\n}\n\nconst makeCalc = (node: CalcNode, refSet: ReadonlySet<string>): Calc<AnyVar> =>\n new CalcImpl(node, refSet)\n\n/**\n * Any operand the runtime combinators accept: an expression of any kind, or a\n * bare number. The precise per-combinator kind/leaf types live in `calc.ts`;\n * the runtime works on the erased tree.\n *\n * @internal\n */\nexport type AnyInput = Top | number\n\n/**\n * The bottom `Calc` — assignable to every precise combinator return in\n * `calc.ts`. The loosely-typed runtime impls return this; the public signatures\n * carry the real kind/leaf types.\n *\n * @internal\n */\nexport type Bottom = Calc<never, never, never>\n\n/** @internal */\nexport const toCalc = (input: AnyInput): Calc<AnyVar> =>\n typeof input === 'number' ? of(input) : (input as Calc<AnyVar>)\n\nconst mergeRefs = (exprs: ReadonlyArray<Calc<AnyVar>>): ReadonlySet<string> => {\n const merged = new Set<string>()\n for (const expr of exprs) {\n for (const name of refsOf(expr)) {\n merged.add(name)\n }\n }\n return merged\n}\n\n// ---------------------------------------------------------------------------\n// constructors\n// ---------------------------------------------------------------------------\n\n/** @internal */\nexport function of(value: number, precision?: Precision): Calc<never> {\n return makeCalc(\n constantNode(value, precision === undefined ? undefined : toSpec(precision)),\n EMPTY_REFS,\n ) as Calc<never>\n}\n\n/**\n * Builds a dimensioned constant. The `data` module's `Length`/`Angle`\n * constructors call this and cast the result to the precise leaf-branded type;\n * the calc core stays unit-agnostic, carrying `unit` and `kind` as given.\n *\n * @internal\n */\nexport function dimension(value: number, unit: string, kind: Kind, precision?: Precision): Bottom {\n return makeCalc(\n constantNode(value, precision === undefined ? undefined : toSpec(precision), unit, kind),\n EMPTY_REFS,\n ) as Bottom\n}\n\nconst refCache = new Map<string, Bottom>()\n\n// Lowers a read's fallback into calc's node vocabulary: numbers become\n// unannotated constants, nested reads become nested `Ref` nodes, and a\n// `Calc` hands over its tree. The rejection is structural — anything else\n// (a `Color`, say) fails the invariant without this module naming it.\nconst lowerFallback = (fb: unknown): CalcNode => {\n if (typeof fb === 'number') {\n return constantNode(fb, undefined)\n }\n if (isVar(fb)) {\n return lowerRead(fb)\n }\n invariant(isCalc(fb), 'Calc var fallback must be a number, a Calc expression, or a Var read')\n return nodeOf(fb)\n}\n\nconst lowerRead = (read: AnyVar): RefNode => {\n invariant(\n declaredTypeOf(read) !== 'color',\n 'A color-declared read cannot lift into calc; use Color.var',\n )\n const fb = fallbackOf(read)\n return fb === undefined\n ? { _tag: 'Ref', name: varNameOf(read) }\n : { _tag: 'Ref', name: varNameOf(read), fallback: lowerFallback(fb) }\n}\n\n/** @internal */\nexport function ref(read: string | AnyVar): Bottom {\n if (typeof read !== 'string') {\n invariant(\n declaredTypeOf(read) !== 'color',\n 'A color-declared read cannot lift into calc; use Color.var',\n )\n if (fallbackOf(read) === undefined) {\n return ref(varNameOf(read))\n }\n return makeCalc(lowerRead(read), refsOfVar(read)) as Bottom\n }\n const cached = refCache.get(read)\n if (cached) {\n return cached\n }\n invariant(read.length > 0, 'Reference name must be a non-empty string')\n const expr = makeCalc({ _tag: 'Ref', name: read }, new Set([read])) as Bottom\n refCache.set(read, expr)\n return expr\n}\n\n/**\n * Builds a bare-identifier constant — a leaf serializing as `name`, carrying no\n * references. The `data` module's `Channel` keywords call this; the identifier\n * text is opaque to the calc core, resolved by whatever CSS context surrounds\n * it (a relative-color function today).\n *\n * @internal\n */\nexport function ident(name: string): Calc<never> {\n invariant(name.length > 0, 'Identifier name must be a non-empty string')\n return makeCalc({ _tag: 'Ident', name }, EMPTY_REFS) as Calc<never>\n}\n\n// ---------------------------------------------------------------------------\n// combinators\n// ---------------------------------------------------------------------------\n\nconst liftNary =\n (construct: (nodes: ReadonlyArray<CalcNode>) => CalcNode) =>\n (args: ReadonlyArray<Input>): Calc<AnyVar> => {\n const exprs = args.map(toCalc)\n return makeCalc(construct(exprs.map(nodeOf)), mergeRefs(exprs))\n }\n\nconst addImpl = liftNary(addNode)\nconst minImpl = liftNary(minNode)\nconst maxImpl = liftNary(maxNode)\n\n/**\n * The shared shape of the variadic same-kind combinators (`add`, `min`, `max`):\n * fixed 2/3/4-ary overloads that union the operands' references, then a variadic\n * tail. The precise kind/leaf algebra rides on the public re-exports in\n * `calc.ts`; these internal arms track only references.\n */\ninterface NaryCombinator {\n <A extends AnyVar = never, B extends AnyVar = never>(a: Input<A>, b: Input<B>): Calc<A | B>\n <A extends AnyVar = never, B extends AnyVar = never, C extends AnyVar = never>(\n a: Input<A>,\n b: Input<B>,\n c: Input<C>,\n ): Calc<A | B | C>\n <\n A extends AnyVar = never,\n B extends AnyVar = never,\n C extends AnyVar = never,\n D extends AnyVar = never,\n >(\n a: Input<A>,\n b: Input<B>,\n c: Input<C>,\n d: Input<D>,\n ): Calc<A | B | C | D>\n (...args: readonly [Input, Input, ...ReadonlyArray<Input>]): Calc<AnyVar>\n}\n\n// The precise arms widen the loose runtime impl (every arity returns\n// `Calc<string>`); the function-overload form these three replace hid the same\n// widening behind lenient overload checking, so the cast loses no safety.\nconst naryCombinator = (impl: (args: ReadonlyArray<Input>) => Calc<AnyVar>): NaryCombinator =>\n ((...args: ReadonlyArray<Input>) => impl(args)) as NaryCombinator\n\n/** @internal */\nexport const add: NaryCombinator = naryCombinator(addImpl)\n\n/** @internal */\nexport const min: NaryCombinator = naryCombinator(minImpl)\n\n/** @internal */\nexport const max: NaryCombinator = naryCombinator(maxImpl)\n\nconst liftBinary =\n (construct: (left: CalcNode, right: CalcNode) => CalcNode) =>\n (left: AnyInput, right: AnyInput): Calc<AnyVar> => {\n const l = toCalc(left)\n const r = toCalc(right)\n return makeCalc(construct(nodeOf(l), nodeOf(r)), mergeRefs([l, r]))\n }\n\nconst subtractImpl = liftBinary(subtractNode)\nconst multiplyImpl = liftBinary(multiplyNode)\nconst divideImpl = liftBinary(divideNode)\nconst modImpl = liftBinary(modNode)\nconst powImpl = liftBinary(powNode)\nconst signedPowImpl = liftBinary(signedPowNode)\nconst atan2Impl = liftBinary(atan2Node)\n\n/** @internal */\nexport function subtract(left: AnyInput, right: AnyInput): Bottom {\n return subtractImpl(left, right) as Bottom\n}\n\n/** @internal */\nexport function multiply(left: AnyInput, right: AnyInput): Bottom {\n return multiplyImpl(left, right) as Bottom\n}\n\n/** @internal */\nexport function mod(left: AnyInput, right: AnyInput): Bottom {\n return modImpl(left, right) as Bottom\n}\n\n/** @internal */\nexport function divide<A extends AnyVar = never, B extends AnyVar = never>(\n left: Input<A>,\n right: Input<B>,\n): Calc<A | B> {\n return divideImpl(left, right) as Calc<A | B>\n}\n\n/** @internal */\nexport function pow(base: AnyInput, exponent: AnyInput): Bottom {\n return powImpl(base, exponent) as Bottom\n}\n\n/** @internal */\nexport function signedPow(base: AnyInput, exponent: AnyInput): Bottom {\n return signedPowImpl(base, exponent) as Bottom\n}\n\nconst liftUnary =\n (construct: (argument: CalcNode) => CalcNode) =>\n (argument: AnyInput): Calc<AnyVar> => {\n const arg = toCalc(argument)\n return makeCalc(construct(nodeOf(arg)), refsOf(arg))\n }\n\nconst absImpl = liftUnary((argument) => foldUnary('Abs', argument))\nconst signImpl = liftUnary((argument) => foldUnary('Sign', argument))\nconst sinImpl = liftUnary((argument) => foldUnary('Sin', argument))\nconst cosImpl = liftUnary((argument) => foldUnary('Cos', argument))\nconst tanImpl = liftUnary((argument) => foldUnary('Tan', argument))\nconst acosImpl = liftUnary((argument) => foldUnary('Acos', argument))\n\n/** @internal */\nexport function abs(argument: AnyInput): Bottom {\n return absImpl(argument) as Bottom\n}\n\n/** @internal */\nexport function sign(argument: AnyInput): Bottom {\n return signImpl(argument) as Bottom\n}\n\n/** @internal */\nexport function sin(argument: AnyInput): Bottom {\n return sinImpl(argument) as Bottom\n}\n\n/** @internal */\nexport function cos(argument: AnyInput): Bottom {\n return cosImpl(argument) as Bottom\n}\n\n/** @internal */\nexport function tan(argument: AnyInput): Bottom {\n return tanImpl(argument) as Bottom\n}\n\n/** @internal */\nexport function acos(argument: AnyInput): Bottom {\n return acosImpl(argument) as Bottom\n}\n\n/** @internal */\nexport function atan2(y: AnyInput, x: AnyInput): Bottom {\n return atan2Impl(y, x) as Bottom\n}\n\n/** @internal */\nexport function clamp(minimum: AnyInput, value: AnyInput, maximum: AnyInput): Bottom {\n const lo = toCalc(minimum)\n const mid = toCalc(value)\n const hi = toCalc(maximum)\n return makeCalc(\n clampNode(nodeOf(lo), nodeOf(mid), nodeOf(hi)),\n mergeRefs([lo, mid, hi]),\n ) as Bottom\n}\n\n/** @internal */\nexport function lerp(a: AnyInput, b: AnyInput, t: AnyInput): Bottom {\n return add(multiply(subtract(1, t), a), multiply(t, b)) as Bottom\n}\n\n// ---------------------------------------------------------------------------\n// binding and projections\n// ---------------------------------------------------------------------------\n\n/** @internal */\nexport const collectBindings = (\n refSet: ReadonlySet<string>,\n bindings: Record<string, Input | undefined>,\n): { readonly nodeBindings: Record<string, CalcNode>; readonly refSet: Set<string> } => {\n const nodeBindings: Record<string, CalcNode> = {}\n const newRefs = new Set<string>(refSet)\n for (const [key, value] of Object.entries(bindings)) {\n if (value === undefined || !refSet.has(key)) {\n continue\n }\n const expr = toCalc(value)\n nodeBindings[key] = nodeOf(expr)\n newRefs.delete(key)\n for (const name of refsOf(expr)) {\n newRefs.add(name)\n }\n }\n return { nodeBindings, refSet: newRefs }\n}\n\n/** @internal */\nexport const bind: {\n <const B extends Bindings>(bindings: B): (expr: Top) => Bottom\n (expr: Top, bindings: Bindings): Bottom\n} = dual(2, (expr: Top, bindings: Record<string, Input>): Bottom => {\n const collected = collectBindings(refsOf(expr), bindings)\n return makeCalc(substituteNode(nodeOf(expr), collected.nodeBindings), collected.refSet) as Bottom\n})\n\n/**\n * The erased solve options: each section optional, keys untyped. The precise\n * per-section requiredness (`SolveOptions`) rides the public signature.\n *\n * @internal\n */\nexport interface AnySolveOptions {\n readonly bindings?: Record<string, Input | undefined>\n readonly units?: Record<string, number>\n readonly idents?: Record<string, number>\n}\n\n/** @internal */\nexport function solve(expr: Top, options?: AnySolveOptions): number {\n let node = nodeOf(expr)\n let remaining: ReadonlySet<string> = refsOf(expr)\n if (options?.bindings !== undefined) {\n const collected = collectBindings(remaining, options.bindings)\n node = substituteNode(node, collected.nodeBindings)\n remaining = collected.refSet\n }\n invariant(remaining.size === 0, 'Cannot convert expression to number: unbound variables remain')\n return evaluateNode(node, options?.units ?? {}, options?.idents ?? {})\n}\n\n/** @internal */\nexport function serialize<Vars extends AnyVar>(\n expr: Calc<Vars, Unit.Any, unknown>,\n options?: SerializeOptions<Vars>,\n): string {\n let node = nodeOf(expr)\n if (options?.bindings !== undefined) {\n const collected = collectBindings(\n refsOf(expr),\n options.bindings as Record<string, Input | undefined>,\n )\n node = substituteNode(node, collected.nodeBindings)\n }\n const precision = options?.precision === undefined ? DEFAULT_FORMAT : toSpec(options.precision)\n return serializeTop(node, precision)\n}\n\n/** @internal */\nexport function refs<Vars extends AnyVar>(\n expr: Calc<Vars, Unit.Any, unknown>,\n): ReadonlySet<VarName<Vars>> {\n return refsOf(expr) as ReadonlySet<VarName<Vars>>\n}\n\n/** @internal */\nexport function idents(expr: Top): ReadonlySet<string> {\n return identsOf(nodeOf(expr))\n}\n\n/** @internal */\nexport function units(expr: Top): ReadonlySet<string> {\n return unitsOf(nodeOf(expr))\n}\n\n/** @internal */\nexport const equals = dual<\n (that: Top) => (self: Top) => boolean,\n (self: Top, that: Top) => boolean\n>(2, (self: Top, that: Top): boolean => Equal.equals(self, that))\n","import type { Unit } from '#data'\nimport type { Pipeable } from '#util'\nimport type { Var } from '#var'\nimport type { CalcTypeId } from './calc.internal.ts'\nimport * as internal from './calc.internal.ts'\nimport type { Precision } from './precision.ts'\n\ndeclare const CalcVariance: unique symbol\ndeclare const IdentId: unique symbol\n\n/**\n * The CSS dimension vocabulary: `<number>`, `<length>`, `<angle>`, or\n * `<percentage>`. The algebra itself runs on `Result` unit brands compared by\n * `Unit.Family` — CSS type-checks `calc()` at this dimension level, and the\n * family comparison implements exactly that — so `Kind` remains as the prose\n * and runtime vocabulary: dimensioned constants carry it, and the docs speak\n * it. A `<percentage>` is its own dimension, not a length: it adds only to\n * another percentage — unless the expression is anchored on a\n * `<length-percentage>` value (a `Var.lengthPercentage` read, or\n * `LengthPercentage.of`), which admits both families (see `docs/design.md`).\n *\n * @since 0.2.0\n */\nexport type Kind = 'number' | 'length' | 'angle' | 'percentage'\n\n/**\n * The leaf brand of a bare CSS identifier — a token like a relative color's\n * `l` that serializes as itself and is resolved by the CSS construct around\n * it, not read from the cascade. It rides the `Requires` parameter of `Calc`,\n * so `solve` demands a value for the token through the `idents` section of\n * its options, the way a relative unit demands a ratio through `units`.\n *\n * Constructs that introduce identifiers refine this brand: the `Channel`\n * keywords (`Channel.L`, ...) carry a subtype scoped to their color space,\n * and `Color.from` admits them by that subtype. Generic machinery — the\n * solve options, `idents` — keys on this base, so every identifier source\n * is covered without new plumbing.\n *\n * @since 0.2.0\n */\nexport interface Ident<Name extends string = string> {\n readonly [IdentId]: Name\n}\n\n/**\n * A CSS value expression: a tree of constants, unbound variables, and math\n * operations that can be solved to a number, serialized to CSS `calc()`\n * text, or partially bound and passed along.\n *\n * Three type parameters track the expression structurally:\n *\n * - `Vars` — the identities of the custom-property reads still unbound,\n * as `Var` values from `fashionable/var`: `var('u')` is a\n * `Calc<Var<'u'>>`. Combining expressions unions their reads; `bind`\n * subtracts the names it binds. A fully bound (or constant) expression\n * is a `Calc<never>`. Names stay the value-level currency — binding\n * records are keyed by bare name, and `vars` reports names — while the\n * phantom carries the identities.\n * - `Result` — what the expression produces, as a set of `Unit` brands:\n * `Unit.Px` for a pure pixel length, `Unit.Px | Unit.Vw` for a mixed sum\n * (a composition, not an uncertainty), `Unit.None` for a `<number>`. The\n * algebra enforces the CSS dimension rules through it — same-family\n * addition, family-merging multiplication, same-family division producing\n * `Unit.None` — so a `<length>` plus a `<number>` is a type error.\n * - `Requires` — what stands between the expression and a number: the unit\n * ratios and identifier values the matching sections of `solve`'s options\n * must supply (`never` when nothing is needed). Absolute units ride it\n * with default supplies — `px`, `rad`, and `deg` demand no entry.\n *\n * Values are immutable and structurally comparable via `equals`.\n * Construction folds constant subtrees eagerly: `add(1, 2)` is the\n * constant `3`, and binding every variable of a tree collapses it to a\n * constant.\n *\n * An unbound variable serializes as `var(--name)` — the read side of a CSS\n * custom property.\n *\n * Construct via `of`, `var`, the `Length`/`Angle` constructors in\n * `fashionable/data`, and the math combinators.\n *\n * @since 0.1.0\n */\nexport interface Calc<\n out Vars extends Var.Any = Var.Any,\n out Result = Unit.None,\n out Requires = never,\n> extends Pipeable {\n readonly [CalcTypeId]: CalcTypeId\n readonly [CalcVariance]?: {\n readonly vars: Vars\n readonly result: Result\n readonly requires: Requires\n }\n}\n\n/**\n * The widest `Calc` — the supertype every expression extends, used to\n * constrain a combinator operand before its facets are extracted.\n *\n * @since 0.2.0\n */\nexport type Top = Calc<Var.Any, Unit.Any, unknown>\n\n// ---------------------------------------------------------------------------\n// combinator type machinery (internal): facet extractors and the family/\n// requirement algebra the combinator signatures below are built from.\n// Validated by the Result spike recorded in docs/result-calc.md.\n// ---------------------------------------------------------------------------\n\n/** Any operand a combinator accepts: an expression of any dimension, or a bare number. */\ntype In = Top | number\n\ntype VarsOf<A> = A extends Calc<infer X, Unit.Any, unknown> ? X : never\ntype ResultOf<A> = A extends Calc<Var.Any, infer R, unknown> ? R : Unit.None\ntype RequiresOf<A> = A extends Calc<Var.Any, Unit.Any, infer Q> ? Q : never\n\n/** An operand constrained to number-result (or a bare number). */\ntype NumberIn = number | Calc<Var.Any, Unit.None, unknown>\n\n/** An operand accepted by `sin`/`cos`: a plain number (radians) or an angle. */\ntype NumberOrAngleIn = number | Calc<Var.Any, Unit.None | Unit.Angle, unknown>\n\n/**\n * An operand constrained to `A`'s dimension family — a bare number only when\n * `A` is number-result, so `add(length, 1)` is rejected while\n * `add(length, length)` holds.\n */\ntype SameKindIn<A> =\n | Calc<Var.Any, Unit.Family<ResultOf<A>>, unknown>\n | (Unit.Family<ResultOf<A>> extends Unit.None ? number : never)\n\ntype VarsOfAll<T extends ReadonlyArray<unknown>> = { [K in keyof T]: VarsOf<T[K]> }[number]\ntype ResultOfAll<T extends ReadonlyArray<unknown>> = { [K in keyof T]: ResultOf<T[K]> }[number]\ntype RequiresOfAll<T extends ReadonlyArray<unknown>> = {\n [K in keyof T]: RequiresOf<T[K]>\n}[number]\n\n// Requirement discharge under division. Cancellation is sound only where eager\n// folding guarantees the division folds once bound: same-single-unit constants\n// always do, ident leaves never do (an `Ident` is not a constant), and a\n// number-result divisor can itself carry requirements (`divide(vw, px)` is a\n// number), so its requirements always survive. The Result side needs none of\n// this: same-family division is `Unit.None` unconditionally.\ntype IsUnion<T, U = T> = [T] extends [never]\n ? false\n : T extends T\n ? [U] extends [T]\n ? false\n : true\n : never\ntype Singleton<T> = [T] extends [never] ? false : IsUnion<T> extends true ? false : true\ntype LeafFn<X> = <T>() => T extends X ? 1 : 2\ntype LeafEqual<A, B> = LeafFn<A> extends LeafFn<B> ? true : false\ntype SameSingleton<A, B> = LeafEqual<A, B> extends true ? Singleton<A> : false\ntype DivRequires<A, B> =\n Unit.Family<ResultOf<B>> extends Unit.None\n ? RequiresOf<A> | RequiresOf<B>\n : SameSingleton<RequiresOf<A>, RequiresOf<B>> extends true\n ? [Extract<RequiresOf<A>, Ident<string>>] extends [never]\n ? never\n : RequiresOf<A> | RequiresOf<B>\n : RequiresOf<A> | RequiresOf<B>\n\n/**\n * A value accepted where an expression is expected: an existing `Calc` or\n * a bare number, which is coerced to an unannotated constant.\n *\n * @since 0.1.0\n */\nexport type Input<Vars extends Var.Any = Var.Any> = Calc<Vars> | number\n\n/**\n * The declared type of the read named `N` in `Vars` — the identity's\n * `Type` slot, recovered per name. `unknown` while the name is undeclared;\n * a union when a name is declared twice (a violation of the one-name,\n * one-type contract, met leniently).\n *\n * @since 0.4.0\n */\nexport type DeclaredType<Vars extends Var.Any, N extends string> = Var.Type<\n Extract<Vars, Var.Var<N, unknown, unknown>>\n>\n\n// The values a binding may supply for a name: the declared type is\n// directly the domain — the slot holds the value type — plus the\n// bare-number sugar when the family is number. Undeclared names keep the\n// unconstrained Input, and so do color-declared ones (a color read is\n// never substitutable by bind; see the Color.var docs).\ntype BindingValue<T> = [unknown] extends [T]\n ? Input\n : T extends Calc<Var.Any, infer R, unknown>\n ?\n | Calc<Var.Any, Unit.Family<R>, unknown>\n | ([Unit.Family<R>] extends [Unit.None] ? number : never)\n : Input\n\n/**\n * A bindings record: bare variable names to the values that replace them.\n * A value may itself be an expression, whose own reads join the result.\n *\n * Keys are names, not `Var` values — names are the value-level currency\n * of the variables channel; the identities live in the `Vars` phantom the\n * record is derived from (mapped over `Var.Name<Vars>`). A declared name\n * types its value: a `Var.length` read binds only to length-family\n * expressions, while undeclared names accept any `Input`.\n *\n * @since 0.1.0\n */\nexport type Bindings<Vars extends Var.Any = Var.Any> = {\n readonly [N in Var.Name<Vars>]: BindingValue<DeclaredType<Vars, N>>\n}\n\ntype ValueVars<V> = V extends Calc<infer R> ? R : never\n\ntype BindingVars<T> = T extends Record<string, infer V> ? ValueVars<V> : never\n\n/**\n * The read identities remaining after applying the bindings `B` to an\n * expression with reads `Vars`: identities whose names are bound are\n * removed, and the reads of any expression-valued bindings are added.\n *\n * @since 0.1.0\n */\nexport type ApplyBindings<Vars extends Var.Any, B> =\n | (Vars extends unknown ? (Var.Name<Vars> extends keyof B ? never : Vars) : never)\n | BindingVars<Pick<B, Extract<keyof B, Var.Name<Vars>>>>\n\ntype ValueRequires<V> = V extends Calc<Var.Any, Unit.Any, infer Q> ? Q : never\ntype RecordRequires<T> = T extends Record<string, infer V> ? ValueRequires<V> : never\n\n/**\n * What `bind` accepts for an expression with reads `Vars`: `Bindings`\n * with every name optional (binding may be partial), intersected with a\n * wide index signature so a record sharing no names with the expression\n * stays legal — unread names are ignored, and without the index signature\n * the all-optional record would be a weak type that rejects exactly the\n * spread-a-wider-object usage the contract promises. Present names still\n * check against their declared types through the `Bindings` half.\n *\n * @since 0.4.0\n */\nexport type PartialBindings<Vars extends Var.Any> = Partial<Bindings<Vars>> & {\n readonly [name: string]: Calc<Var.Any, Unit.Any, unknown> | number | undefined\n}\n\n/**\n * The requirements the bindings `B` contribute to an expression with reads\n * `Vars`: the union of the bound values' own `Requires`, over the names\n * the expression actually reads. This is `bind`'s side of the split with\n * `solve` — `bind` is partial evaluation, so a bound `Length.vw(2)` may\n * carry its `vw` requirement into the result, where `solve` is total and\n * accepts only pre-satisfied values (see `docs/vars.md`).\n *\n * @since 0.4.0\n */\nexport type BindingRequires<Vars extends Var.Any, B> = RecordRequires<\n Pick<B, Extract<keyof B, Var.Name<Vars>>>\n>\n\n/**\n * Options for `serialize`.\n *\n * @since 0.1.0\n */\nexport interface SerializeOptions<Vars extends Var.Any = Var.Any> {\n /**\n * Bindings applied before rendering. May be partial: variables left\n * unbound render as `var(--name)`.\n */\n readonly bindings?: Partial<Bindings<Vars>>\n /**\n * The precision for constants that carry no annotation of their own.\n * Defaults to `Precision.decimals(5)`.\n */\n readonly precision?: Precision\n}\n\ntype IdentName<I> = I extends Ident<infer Name> ? Name : never\n\n/**\n * The `idents` section of `SolveOptions`: a numeric value for each\n * bare-identifier token in the requirements `R`. The value is the token's\n * own — read directly, not multiplied as a ratio — so `{ l: 0.62 }` supplies\n * the relative-color `l` keyword.\n *\n * @since 0.4.0\n */\nexport type IdentValues<R> = {\n readonly [K in IdentName<Extract<R, Ident<string>>> & string]: number\n}\n\n/**\n * Options for `solve`: the environments that satisfy an expression's\n * dependency channels. Each section is required exactly when the\n * expression's type demands it — `bindings` while unbound variables remain,\n * `units` while a relative unit or percentage is present, `idents` while a\n * bare identifier is — and optional otherwise.\n *\n * - `bindings` — a closed value (a number or a `Calc<never>`) for every\n * unbound variable. Substitution, as in `bind`, but total: a value\n * carrying its own unbound variables is a type error here, since nothing\n * later could close it.\n * - `units` — a pixels-per-unit ratio for every context-dependent unit:\n * `vw` is `sampleWidth / 100`, `%` is `basis / 100`. Absolute lengths\n * default (`px` is `1`) unless overridden; angles never appear (radians\n * and degrees lower on their own).\n * - `idents` — the value each bare-identifier token stands for\n * (`{ l: 0.62 }`).\n *\n * @since 0.4.0\n */\n// A solve binding is total: closed (no reads of its own) and pre-satisfied\n// (only `px`/`rad`/`deg` requirements), because `SolveOptions` cannot\n// demand ratios for units the bindings introduce — the `units` section's\n// type is fixed by the expression's `R` before the bindings beside it are\n// seen. Bind first to accumulate requirements, then solve.\ntype SolveBindingValue<T> = [unknown] extends [T]\n ? Input<never>\n : T extends Calc<Var.Any, infer R, unknown>\n ?\n | Calc<never, Unit.Family<R>, Unit.ContextFree>\n | ([Unit.Family<R>] extends [Unit.None] ? number : never)\n : Input<never>\n\nexport type SolveOptions<Vars extends Var.Any, R> = ([Vars] extends [never]\n ? { readonly bindings?: Record<string, Input<never>> }\n : {\n readonly bindings: {\n readonly [N in Var.Name<Vars>]: SolveBindingValue<DeclaredType<Vars, N>>\n }\n }) &\n ([Exclude<R, Unit.ContextFree | Ident<string>>] extends [never]\n ? { readonly units?: Unit.UnitContext<R> }\n : { readonly units: Unit.UnitContext<R> }) &\n ([Extract<R, Ident<string>>] extends [never]\n ? { readonly idents?: IdentValues<R> }\n : { readonly idents: IdentValues<R> })\n\n/**\n * Checks if a value is a `Calc`.\n *\n * True only for values built by this module's constructors, which carry\n * the brand.\n *\n * @param u - The value to check.\n * @returns `true` if the value is a `Calc`, `false` otherwise.\n * @since 0.1.0\n */\nexport const isCalc: (u: unknown) => u is Calc<Var.Any, Unit.Any, unknown> = internal.isCalc\n\n/**\n * Creates a constant expression, optionally annotated with a serialization\n * precision that overrides the context default wherever the constant lands\n * — including in constants produced by folding it with others (the\n * highest-fidelity operand annotation wins).\n *\n * Bare numbers passed to combinators become unannotated constants; `of`\n * exists to name a value or pin its precision.\n *\n * @param value - The constant value. Must be finite.\n * @param precision - Optional precision annotation.\n * @returns A constant `Calc<never>`.\n * @throws `Error` when `value` is not finite.\n * @example\n * ```ts\n * const k = Calc.of(0.8377580409572781, Precision.significant(10))\n * Calc.serialize(Calc.multiply(k, Calc.var('t'))) // 'calc(0.837758041 * var(--t))'\n * ```\n * @since 0.1.0\n */\nexport const of: (value: number, precision?: Precision) => Calc<never> = internal.of\n\n/**\n * The Result a lifted read produces: its declared type's Result when the\n * declaration is calc-shaped — the trait is the `Result` parameter itself,\n * read structurally — and `Unit.None` while the read is undeclared.\n *\n * @since 0.4.0\n */\nexport type ReadResult<T> = T extends Calc<Var.Any, infer R, unknown> ? R : Unit.None\n\n// The identities a read contributes to the phantom, flattened: the read's\n// own name-and-type pair, then its fallback chain's — a Calc fallback hands\n// over its Vars, a nested read recurses, a number contributes nothing.\ntype ReadVars<V> =\n V extends Var.Var<infer N, infer T, infer F> ? Var.Var<N, T> | ReadFallbackVars<F> : never\ntype ReadFallbackVars<F> =\n F extends Calc<infer W, Unit.Any, unknown> ? W : F extends Var.Any ? ReadVars<F> : never\n\n// The lift's admission rules, as a guard the read parameter intersects:\n// `unknown` (a no-op) for a valid read, a string-literal error type\n// otherwise, so the compile error names the rule that failed. A constraint\n// cannot carry these rules — the `Type` slot's top is `unknown`, so every\n// declared read is assignable wherever an undeclared one is (that\n// covariance is the typed-handle forward-compat), and admission must be\n// checked, not bounded. `docs/vars.md` section 8 records the derivation.\ntype ReadGuard<V> =\n V extends Var.Var<string, infer T, infer F>\n ? [unknown] extends [T]\n ? FallbackGuard<F, Unit.None>\n : T extends Calc<Var.Any, Unit.Any, unknown>\n ? FallbackGuard<F, Unit.Family<ReadResult<T>>>\n : 'this read is declared outside calc: a color-typed read lifts with Color.var'\n : never\n\n// A fallback must land in the read's family: it substitutes where the read\n// does, so a differently-dimensioned fallback would hand the surrounding\n// tree a value the algebra rejected everywhere else.\ntype FallbackGuard<F, Fam> = [F] extends [undefined]\n ? unknown\n : F extends number\n ? [Fam] extends [Unit.None]\n ? unknown\n : 'a bare-number fallback fits only a number-result read'\n : F extends Calc<Var.Any, infer R, unknown>\n ? [Unit.Family<R>] extends [Fam]\n ? unknown\n : \"this fallback's family does not match the read's declared type\"\n : F extends Var.Var<string, infer T2, infer F2>\n ? [unknown] extends [T2]\n ? [Unit.None] extends [Fam]\n ? FallbackGuard<F2, Fam>\n : \"an undeclared nested read is number-result; declare it to match the outer read's family\"\n : T2 extends Calc<Var.Any, Unit.Any, unknown>\n ? [Unit.Family<ReadResult<T2>>] extends [Fam]\n ? FallbackGuard<F2, Fam>\n : \"a nested read's declared family must match the outer read's\"\n : 'a color-typed read cannot fall back inside calc'\n : 'a calc fallback is a number, a Calc expression, or a Var read'\n\nconst _var: {\n /**\n * Creates a read of a CSS variable (custom property): `var('width')`\n * serializes as `var(--width)`. Variables are the substitutable\n * dependency channel — `bind` replaces them with values or other\n * expressions, and an expression's `Vars` parameter tracks the reads\n * still unbound. Exported as `var` (`Calc.var('width')`) because `var`\n * is reserved in declaration position.\n *\n * Sugar for the read overload: `Calc.var('width')` is\n * `Calc.var(Var.of('width'))`. Repeated calls with the same name return\n * the same instance.\n *\n * @param name - The variable name, without the `--` prefix. Must be non-empty.\n * @returns A `Calc` reading `name`, its one unbound variable.\n * @throws `Error` when `name` is empty.\n * @example\n * ```ts\n * Calc.serialize(Calc.var('width')) // 'var(--width)'\n * ```\n * @since 0.1.0\n */\n <Name extends string>(name: Name): Calc<Var.Var<Name>>\n /**\n * Lifts a `Var` read into an expression. The read's declared type sets\n * the expression's Result: a `Var.length` read is a length-family\n * expression that composes through the ordinary dimension algebra, an\n * undeclared read is a `<number>` as before, and a color-typed read is\n * rejected — it lifts with `Color.var`.\n *\n * A fallback-carrying read renders its fallback (`var(--gap, 8)`),\n * which must land in the read's family: a bare number only under a\n * number-result read, a `Calc` of the declared family (rendered under\n * the normal rules, so arithmetic gets a nested `calc()` wrapper), or\n * another read of the same family, recursively. Anything else is a type\n * error at this lift, backed by a runtime check on the world (family\n * fidelity within calc is the type level's job alone, as everywhere\n * else in the algebra).\n *\n * The returned expression's `Vars` unions the read's identity with its\n * fallback chain's, flattened — `var(--x, var(--y))` is a\n * `Calc<Var<'x'> | Var<'y'>>`, and both names join the dependency\n * report. Binding the read's own name replaces the whole read and\n * discards the fallback; a fallback never reduces what `solve`\n * requires (see `docs/vars.md`).\n *\n * @param read - The read to lift, from `Var.of` or a typed constructor (optionally through `Var.fallback`).\n * @returns A `Calc` of the read's declared family, with its fallback chain's reads unioned in.\n * @throws `Error` when the read is color-declared, or its fallback chain holds anything but numbers, `Calc` expressions, and reads.\n * @example\n * ```ts\n * const gap = Var.length('gap')\n * Calc.serialize(Calc.add(Calc.var(gap), Length.px(4))) // 'calc(var(--gap) + 4px)'\n * ```\n * @since 0.4.0\n */\n <V extends Var.Any>(read: V & ReadGuard<V>): Calc<ReadVars<V>, ReadResult<Var.Type<V>>, never>\n} = internal.ref\nexport { _var as var }\n\n/**\n * Adds expressions. Constant operands fold at construction.\n *\n * Serializes as `a + b + ...` inside a `calc()` wrapper; negative constant\n * terms (and products led by a negative constant) render subtractively:\n * `a + (-2)` serializes as `a - 2`.\n *\n * @param a - The first operand.\n * @param b - The second operand, sharing `a`'s dimension.\n * @returns The sum, with the operands' variables, results, and requirements unioned.\n * @example\n * ```ts\n * Calc.serialize(Calc.add(Calc.var('x'), 10)) // 'calc(var(--x) + 10)'\n * ```\n * @since 0.1.0\n */\nexport const add: <\n A extends In,\n B extends SameKindIn<A>,\n Rest extends ReadonlyArray<SameKindIn<A>>,\n>(\n a: A,\n b: B,\n ...rest: Rest\n) => Calc<\n VarsOf<A> | VarsOf<B> | VarsOfAll<Rest>,\n ResultOf<A> | ResultOf<B> | ResultOfAll<Rest>,\n RequiresOf<A> | RequiresOf<B> | RequiresOfAll<Rest>\n> = internal.add\n\n/**\n * Subtracts `right` from `left`. Constant operands fold at construction.\n *\n * @param left - The minuend.\n * @param right - The subtrahend, sharing `left`'s dimension.\n * @returns The difference, with the operands' variables, results, and requirements unioned.\n * @since 0.1.0\n */\nexport const subtract: <A extends In, B extends SameKindIn<A>>(\n left: A,\n right: B,\n) => Calc<VarsOf<A> | VarsOf<B>, ResultOf<A> | ResultOf<B>, RequiresOf<A> | RequiresOf<B>> =\n internal.subtract\n\n/**\n * The CSS `mod()` of `dividend` and `divisor` — the remainder that takes the\n * sign of the divisor (the floored modulo), so `mod(x, 360)` lands in\n * `[0, 360)` for a positive divisor. Same-dimension operands, as `subtract`;\n * constant operands fold at construction.\n *\n * @param dividend - The value to reduce.\n * @param divisor - The modulus, sharing `dividend`'s dimension.\n * @returns The modulo, with the operands' variables, results, and requirements unioned.\n * @example\n * ```ts\n * Calc.serialize(Calc.mod(Calc.var('h'), 360)) // 'mod(var(--h), 360)'\n * ```\n * @since 0.2.0\n */\nexport const mod: <A extends In, B extends SameKindIn<A>>(\n dividend: A,\n divisor: B,\n) => Calc<VarsOf<A> | VarsOf<B>, ResultOf<A> | ResultOf<B>, RequiresOf<A> | RequiresOf<B>> =\n internal.mod\n\n/**\n * Multiplies expressions. One factor must be a `<number>`; the dimensioned\n * factor's result rides through. Constant operands fold at construction.\n *\n * Addition and subtraction operands are parenthesized when serialized\n * under a product: `(a + b) * c`.\n *\n * @param left - The first factor.\n * @param right - The second factor.\n * @returns The product, carrying the dimensioned factor's result and both operands' variables and requirements.\n * @since 0.1.0\n */\nexport const multiply: {\n <A extends NumberIn, B extends In>(\n left: A,\n right: B,\n ): Calc<VarsOf<A> | VarsOf<B>, ResultOf<B>, RequiresOf<A> | RequiresOf<B>>\n <A extends In, B extends NumberIn>(\n left: A,\n right: B,\n ): Calc<VarsOf<A> | VarsOf<B>, ResultOf<A>, RequiresOf<A> | RequiresOf<B>>\n} = internal.multiply\n\n/**\n * Divides `left` by `right`. Constant operands fold at construction.\n *\n * Dividing by a `<number>` keeps the dividend's result; dividing two\n * same-dimension expressions produces a `<number>` (`Unit.None`) — the\n * units cancel. The requirements discharge only where folding guarantees\n * they can: a same-single-unit division always folds once bound, so its\n * requirement drops; anything mixed keeps both operands'.\n *\n * @param left - The dividend.\n * @param right - The divisor: a number, or an expression sharing `left`'s dimension.\n * @returns The quotient, with the operands' variables unioned.\n * @since 0.1.0\n */\nexport const divide: {\n <A extends In, B extends NumberIn>(\n left: A,\n right: B,\n ): Calc<VarsOf<A> | VarsOf<B>, ResultOf<A>, DivRequires<A, B>>\n <A extends In, B extends SameKindIn<A>>(\n left: A,\n right: B,\n ): Calc<VarsOf<A> | VarsOf<B>, Unit.None, DivRequires<A, B>>\n} = internal.divide\n\n/**\n * Raises `base` to `exponent`. Serializes as the CSS `pow()` function,\n * whose operands are `<number>`s — so both take number-result expressions,\n * which may carry identifier requirements (`pow(l, 2.2)` gamma-adjusts a\n * relative-color channel).\n *\n * @param base - The base.\n * @param exponent - The exponent.\n * @returns The power, a `<number>`, with the operands' variables and requirements unioned.\n * @since 0.1.0\n */\nexport const pow: <A extends NumberIn, B extends NumberIn>(\n base: A,\n exponent: B,\n) => Calc<VarsOf<A> | VarsOf<B>, Unit.None, RequiresOf<A> | RequiresOf<B>> = internal.pow\n\n/**\n * Sign-preserving power: `abs(base) ^ exponent * sign(base)`. Unlike\n * `pow`, well-defined for negative bases with fractional exponents.\n * Serializes as `pow(abs(base), exponent) * sign(base)`.\n *\n * @param base - The base.\n * @param exponent - The exponent.\n * @returns The signed power, a `<number>`, with the operands' variables and requirements unioned.\n * @since 0.1.0\n */\nexport const signedPow: <A extends NumberIn, B extends NumberIn>(\n base: A,\n exponent: B,\n) => Calc<VarsOf<A> | VarsOf<B>, Unit.None, RequiresOf<A> | RequiresOf<B>> = internal.signedPow\n\n/**\n * The minimum of the operands. Serializes as the CSS `min()` function.\n *\n * @param a - The first operand.\n * @param b - The second operand, sharing `a`'s dimension.\n * @returns The minimum, with the operands' variables, results, and requirements unioned.\n * @since 0.1.0\n */\nexport const min: <\n A extends In,\n B extends SameKindIn<A>,\n Rest extends ReadonlyArray<SameKindIn<A>>,\n>(\n a: A,\n b: B,\n ...rest: Rest\n) => Calc<\n VarsOf<A> | VarsOf<B> | VarsOfAll<Rest>,\n ResultOf<A> | ResultOf<B> | ResultOfAll<Rest>,\n RequiresOf<A> | RequiresOf<B> | RequiresOfAll<Rest>\n> = internal.min\n\n/**\n * The maximum of the operands. Serializes as the CSS `max()` function.\n *\n * @param a - The first operand.\n * @param b - The second operand, sharing `a`'s dimension.\n * @returns The maximum, with the operands' variables, results, and requirements unioned.\n * @since 0.1.0\n */\nexport const max: <\n A extends In,\n B extends SameKindIn<A>,\n Rest extends ReadonlyArray<SameKindIn<A>>,\n>(\n a: A,\n b: B,\n ...rest: Rest\n) => Calc<\n VarsOf<A> | VarsOf<B> | VarsOfAll<Rest>,\n ResultOf<A> | ResultOf<B> | ResultOfAll<Rest>,\n RequiresOf<A> | RequiresOf<B> | RequiresOfAll<Rest>\n> = internal.max\n\n/**\n * Clamps `value` between `minimum` and `maximum`. Serializes as the CSS\n * `clamp()` function, with the CSS argument order `(min, value, max)`.\n *\n * @param minimum - The lower bound.\n * @param value - The value to clamp, sharing `minimum`'s dimension.\n * @param maximum - The upper bound, likewise.\n * @returns The clamped expression, with the operands' variables, results, and requirements unioned.\n * @example\n * ```ts\n * Calc.serialize(Calc.clamp(-1, Calc.var('u'), 1)) // 'clamp(-1, var(--u), 1)'\n * ```\n * @since 0.1.0\n */\nexport const clamp: <A extends In, B extends SameKindIn<A>, C extends SameKindIn<A>>(\n minimum: A,\n value: B,\n maximum: C,\n) => Calc<\n VarsOf<A> | VarsOf<B> | VarsOf<C>,\n ResultOf<A> | ResultOf<B> | ResultOf<C>,\n RequiresOf<A> | RequiresOf<B> | RequiresOf<C>\n> = internal.clamp\n\n/**\n * Linear interpolation from `a` to `b` by `t`. This is sugar, not a node:\n * it desugars to `(1 - t) * a + t * b`, and serializes as that expanded\n * form. `t` contributes its variables and requirements but never the\n * result — the endpoints alone fix the dimension.\n *\n * @param a - The value at `t = 0`.\n * @param b - The value at `t = 1`, sharing `a`'s dimension.\n * @param t - The interpolation parameter, a `<number>`.\n * @returns The interpolated expression, with the operands' variables unioned.\n * @since 0.1.0\n */\nexport const lerp: {\n <A extends In, B extends SameKindIn<A>, T extends NumberIn>(\n a: A,\n b: B,\n t: T,\n ): Calc<\n VarsOf<A> | VarsOf<B> | VarsOf<T>,\n ResultOf<A> | ResultOf<B>,\n RequiresOf<A> | RequiresOf<B> | RequiresOf<T>\n >\n} = internal.lerp\n\n/**\n * The absolute value. Serializes as the CSS `abs()` function.\n *\n * @param argument - The operand.\n * @returns The absolute value expression, preserving the operand's result.\n * @since 0.1.0\n */\nexport const abs: {\n <A extends In>(argument: A): Calc<VarsOf<A>, ResultOf<A>, RequiresOf<A>>\n} = internal.abs\n\n/**\n * The sign (`-1`, `0`, or `1`). Serializes as the CSS `sign()` function,\n * which accepts a calculation of any dimension and returns a `<number>` —\n * so any operand is accepted here.\n *\n * @param argument - The operand, of any dimension.\n * @returns The sign, a `<number>`, carrying the operand's requirements.\n * @since 0.1.0\n */\nexport const sign: {\n <A extends In>(argument: A): Calc<VarsOf<A>, Unit.None, RequiresOf<A>>\n} = internal.sign\n\n/**\n * The sine of its argument. Serializes as the CSS `sin()` function, which\n * accepts an `<angle>` or a plain number treated as radians — so this takes\n * either an angle expression or a number, and returns a number.\n *\n * @param argument - An angle, or a plain number in radians.\n * @returns The sine, a `<number>`, carrying the argument's requirements.\n * @since 0.1.0\n */\nexport const sin: {\n <A extends NumberOrAngleIn>(argument: A): Calc<VarsOf<A>, Unit.None, RequiresOf<A>>\n} = internal.sin\n\n/**\n * The cosine of its argument. Serializes as the CSS `cos()` function, which\n * accepts an `<angle>` or a plain number treated as radians — so this takes\n * either an angle expression or a number, and returns a number.\n *\n * @param argument - An angle, or a plain number in radians.\n * @returns The cosine, a `<number>`, carrying the argument's requirements.\n * @since 0.1.0\n */\nexport const cos: {\n <A extends NumberOrAngleIn>(argument: A): Calc<VarsOf<A>, Unit.None, RequiresOf<A>>\n} = internal.cos\n\n/**\n * The tangent of its argument. Serializes as the CSS `tan()` function, which\n * accepts an `<angle>` or a plain number treated as radians. Paired with\n * `atan2`, `tan(atan2(a, b))` divides two same-dimension expressions to a\n * `<number>` — the length ratio that works where `a / b` does not, since\n * Firefox does not yet support `<length> / <length>` in `calc()`.\n *\n * @param argument - An angle, or a plain number in radians.\n * @returns The tangent, a `<number>`, carrying the argument's requirements.\n * @since 0.2.0\n */\nexport const tan: {\n <A extends NumberOrAngleIn>(argument: A): Calc<VarsOf<A>, Unit.None, RequiresOf<A>>\n} = internal.tan\n\n/**\n * The arccosine of a value in `[-1, 1]`, an `<angle>` in radians — the\n * result is `Unit.Rad`, matching what solving evaluates (`Math.acos`) and\n * what constant folding emits (`rad` constants); CSS's `acos()` returns an\n * `<angle>` and serialization is unchanged.\n *\n * Because the result is an angle, it composes only with other angles: divide\n * or scale it by a number, and add or subtract an `Angle.rad(...)` phase. A\n * plain number added to it is a type error — supply the phase as an angle.\n *\n * @param argument - The cosine value, in `[-1, 1]`.\n * @returns The arccosine in radians, carrying the argument's requirements.\n * @example\n * ```ts\n * const phase = Angle.rad(2.0943951)\n * Calc.serialize(Calc.cos(Calc.subtract(Calc.divide(Calc.acos(Calc.var('u')), 3), phase)))\n * // 'cos(acos(var(--u)) / 3 - 2.0944rad)'\n * ```\n * @since 0.1.0\n */\nexport const acos: {\n <A extends NumberIn>(argument: A): Calc<VarsOf<A>, Unit.Rad, RequiresOf<A>>\n} = internal.acos\n\n/**\n * The angle, in radians, of the vector from the origin to `(x, y)` — CSS's\n * `atan2()`, which returns an `<angle>`; the result is `Unit.Rad`, as\n * `acos`. The operands must share a dimension (two numbers, two lengths,\n * two angles); their units cancel in the ratio, so `tan(atan2(a, b))`\n * recovers `a / b` as a `<number>` and is the portable way to divide two\n * `<length>`s.\n *\n * @param y - The vertical component.\n * @param x - The horizontal component, sharing `y`'s dimension.\n * @returns The angle in radians, with the operands' variables and requirements unioned.\n * @example\n * ```ts\n * const ratio = Calc.tan(Calc.atan2(Calc.subtract(Length.vw(100), Length.px(320)), Length.px(160)))\n * Calc.serialize(ratio) // 'tan(atan2(100vw - 320px, 160px))'\n * ```\n * @since 0.2.0\n */\nexport const atan2: {\n <A extends In, B extends SameKindIn<A>>(\n y: A,\n x: B,\n ): Calc<VarsOf<A> | VarsOf<B>, Unit.Rad, RequiresOf<A> | RequiresOf<B>>\n} = internal.atan2\n\nexport const bind: {\n /**\n * Returns a function that binds the given names in an expression.\n *\n * The data-last form cannot see its eventual expression, so the\n * per-name declared-type checking rides the data-first overload only;\n * requirement threading works in both.\n *\n * @param bindings - Variable names to values or expressions. Names the expression does not read are ignored, as are `undefined` values.\n * @returns A function replacing bound variables in its argument, preserving its result and joining the bound values' requirements to its own.\n * @since 0.1.0\n */\n <const B extends Bindings>(\n bindings: B,\n ): <A extends Top>(\n expr: A,\n ) => Calc<ApplyBindings<VarsOf<A>, B>, ResultOf<A>, RequiresOf<A> | BindingRequires<VarsOf<A>, B>>\n /**\n * Replaces variables with values or other expressions. Binding is\n * partial evaluation: substituted subtrees re-fold, so binding every\n * variable collapses the tree to a constant. The expression's result is\n * preserved — binding touches only the variable channel — and the bound\n * values' own requirements join the expression's, so a `Length.vw(2)`\n * binding carries its `vw` ratio demand into the result for `solve` to\n * collect later.\n *\n * A declared name types its value: binding a `Var.length` read to a\n * bare number (or any non-length) is a type error, the check the\n * declaration exists for. Undeclared names accept any `Input`.\n *\n * Names the expression does not read are ignored (spreading a wider\n * bindings object is fine), as are `undefined` values. Binding a\n * variable to another expression composes trees; the bound expression's\n * own variables join the result, tracked in the return type by\n * `ApplyBindings`.\n *\n * @param expr - The expression to bind.\n * @param bindings - Variable names to values or expressions, typed per name by its declared type. May be partial: unbound names stay in the result.\n * @returns The bound expression.\n * @example\n * ```ts\n * const half = Calc.bind(Calc.divide(Calc.var('x'), 2), { x: Calc.var('width') })\n * Calc.serialize(half) // 'calc(var(--width) / 2)'\n * Calc.solve(Calc.bind(half, { width: 100 })) // 50\n * ```\n * @since 0.1.0\n */\n <A extends Top, const B extends PartialBindings<VarsOf<A>>>(\n expr: A,\n bindings: B,\n ): Calc<ApplyBindings<VarsOf<A>, B>, ResultOf<A>, RequiresOf<A> | BindingRequires<VarsOf<A>, B>>\n} = internal.bind\n\nexport const solve: {\n /**\n * Evaluates a closed expression to a number. Absolute lengths (`px`) and\n * angles (radians and degrees) lower with no options; an unbound\n * variable, a relative unit, a percentage, or a bare identifier needs the\n * options overload.\n *\n * @param expr - The expression. No unbound variables, only pre-satisfied requirements.\n * @returns The numeric value.\n * @throws `Error` when unbound variables or unresolvable requirements remain at runtime.\n * @since 0.1.0\n */\n (expr: Calc<never, Unit.Any, Unit.ContextFree>): number\n /**\n * Applies bindings, lowers each unit and identifier through the matching\n * options section, then evaluates to a number. `SolveOptions` requires\n * each section exactly when the expression's type demands it: `bindings`\n * while variables are unbound, `units` while a relative unit or\n * percentage is present, `idents` while a bare identifier is.\n *\n * @param expr - The expression to evaluate.\n * @param options - The bindings, unit ratios, and identifier values the expression needs.\n * @returns The numeric value.\n * @throws `Error` when unbound variables remain after binding, or a unit or identifier has no entry at runtime.\n * @example\n * ```ts\n * Calc.solve(Calc.lerp(Calc.var('a'), Calc.var('b'), 0.5), { bindings: { a: 0, b: 10 } }) // 5\n * const position = Calc.divide(Calc.subtract(Length.vw(100), Length.px(320)), Length.px(160))\n * Calc.solve(position, { units: { vw: 1280 / 100 } }) // 6\n * Calc.solve(Calc.multiply(Channel.L, 0.8), { idents: { l: 0.62 } }) // 0.496\n * ```\n * @since 0.1.0\n */\n <Vars extends Var.Any, R>(expr: Calc<Vars, Unit.Any, R>, options: SolveOptions<Vars, R>): number\n} = internal.solve\n\n/**\n * Renders an expression as CSS text. Arithmetic gets a `calc()` wrapper;\n * function forms (`min`, `clamp`, `sin`, ...) and leaves stand alone.\n * Variables render as `var(--name)`.\n *\n * Bindings in `options` are applied first and may be partial — this is\n * the serialize half of the solve/serialize duality, and unbound\n * variables are the values left for the browser. Constants render with\n * their annotated precision, or the context `precision` option (default\n * `Precision.decimals(5)`). Constants equal to pi render as the CSS\n * constant `pi` where a math function surrounds them.\n *\n * @param expr - The expression to render.\n * @param options - Optional bindings and precision context.\n * @returns Deterministic CSS text.\n * @example\n * ```ts\n * const fluid = Calc.add(10, Calc.var('runtime'))\n * Calc.serialize(fluid) // 'calc(10 + var(--runtime))'\n * Calc.serialize(fluid, { bindings: { runtime: 4 } }) // '14'\n * ```\n * @since 0.1.0\n */\nexport const serialize: <Vars extends Var.Any>(\n expr: Calc<Vars, Unit.Any, unknown>,\n options?: SerializeOptions<Vars>,\n) => string = internal.serialize\n\n/**\n * The expression's unbound variable names — bare names, the value-level\n * mirror of the read identities in `Vars`. A fallback chain's names are\n * included: `var(--x, var(--y))` reads both.\n *\n * @param expr - The expression to inspect.\n * @returns The set of unbound variable names.\n * @since 0.1.0\n */\nexport const vars: <Vars extends Var.Any>(\n expr: Calc<Vars, Unit.Any, unknown>,\n) => ReadonlySet<Var.Name<Vars>> = internal.refs\n\n/**\n * The bare-identifier tokens the expression reads — leaves that serialize\n * as themselves (`l`, not `var(--l)`) and are resolved by the CSS construct\n * around them, the `Channel` keywords being the only source today. Empty\n * for an expression with none.\n *\n * The runtime mirror of the `Ident` brands in `Requires`: it reports which\n * values the `idents` section of `solve`'s options must supply, exactly as\n * `vars` reports what `bindings` must — and, unlike the type parameter, it\n * survives on a `Calc<Vars, Unit.Any, unknown>` whose requirements have\n * been erased. Identifiers are not variables, so `vars` never lists them\n * and they never reach a `Stylesheet`'s dependency report.\n *\n * @param expr - The expression to inspect.\n * @returns The set of bare-identifier tokens the expression reads.\n * @example\n * ```ts\n * Calc.idents(Calc.multiply(Channel.L, 0.8)) // Set { 'l' }\n * Calc.idents(Calc.var('x')) // Set {}\n * ```\n * @since 0.2.0\n */\nexport const idents: (expr: Calc<Var.Any, Unit.Any, unknown>) => ReadonlySet<string> =\n internal.idents\n\n/**\n * The unit tokens the expression's dimensioned constants carry (`'vw'`,\n * `'px'`, `'%'`). Empty for a unit-free expression.\n *\n * The runtime mirror of the `Unit` brands in `Requires`: it reports which\n * ratios the `units` section of `solve`'s options may need to supply, and —\n * unlike the type parameter — it survives on a `Calc<Vars, Unit.Any, unknown>`\n * whose requirements have been erased. Pre-satisfied units (`px`, `rad`,\n * `deg`) are reported too; they lower with no entry.\n *\n * @param expr - The expression to inspect.\n * @returns The set of unit tokens the expression's constants carry.\n * @example\n * ```ts\n * Calc.units(Calc.subtract(Length.vw(100), Length.px(320))) // Set { 'vw', 'px' }\n * ```\n * @since 0.4.0\n */\nexport const units: (expr: Calc<Var.Any, Unit.Any, unknown>) => ReadonlySet<string> = internal.units\n\nexport const equals: {\n /**\n * Returns a function that checks structural equality against `that`.\n *\n * @param that - The expression to compare against.\n * @returns A function testing its argument for structural equality with `that`.\n * @since 0.1.0\n */\n (that: Calc<Var.Any, Unit.Any, unknown>): (self: Calc<Var.Any, Unit.Any, unknown>) => boolean\n /**\n * Structural equality over expression trees. Two expressions are equal\n * when their trees match node for node — including constant units and\n * precision annotations, which affect serialization. Expression trees are\n * ordered syntax: `add(a, b)` and `add(b, a)` are not equal.\n *\n * @param self - The first expression.\n * @param that - The second expression.\n * @returns `true` if the expressions are structurally equal.\n * @since 0.1.0\n */\n (self: Calc<Var.Any, Unit.Any, unknown>, that: Calc<Var.Any, Unit.Any, unknown>): boolean\n} = internal.equals\n","import type { Pipeable } from '#util'\nimport type { PrecisionTypeId } from './precision.internal.ts'\nimport * as internal from './precision.internal.ts'\n\n/**\n * A number-formatting precision, attached to constants at construction\n * (`Calc.of`) or supplied as a serialization context default\n * (`Calc.serialize`'s `precision` option).\n *\n * Two modes exist. `decimals` fixes the count of digits after the decimal\n * point (`toFixed` semantics); `significant` fixes the count of significant\n * digits (`toPrecision` semantics). Both render plain decimal text with\n * trailing zeros trimmed — CSS never accepts exponent notation.\n *\n * A precision annotated on a constant overrides the serialization context.\n * When constant folding combines annotated constants, the result carries\n * the highest-fidelity annotation among the operands: any `significant`\n * outranks any `decimals`, and more digits outrank fewer.\n *\n * @since 0.1.0\n */\nexport interface Precision extends Pipeable {\n readonly [PrecisionTypeId]: PrecisionTypeId\n /**\n * The formatting mode: digits after the decimal point (`decimals`) or\n * significant digits (`significant`).\n */\n readonly mode: 'decimals' | 'significant'\n /**\n * The digit count the mode fixes.\n */\n readonly digits: number\n}\n\n/**\n * Checks if a value is a `Precision`.\n *\n * True only for values built by `decimals` or `significant`, which carry\n * the brand.\n *\n * @param u - The value to check.\n * @returns `true` if the value is a `Precision`, `false` otherwise.\n * @since 0.1.0\n */\nexport const isPrecision: (u: unknown) => u is Precision = internal.isPrecision\n\n/**\n * Creates a `Precision` fixing the count of digits after the decimal\n * point. The library default for unannotated constants is `decimals(5)`.\n *\n * @param digits - Digits after the decimal point. Must be an integer in `[0, 100]`.\n * @returns A `Precision` in `decimals` mode.\n * @throws `Error` when `digits` is not an integer in `[0, 100]`.\n * @example\n * ```ts\n * Calc.serialize(Calc.of(1 / 3), { precision: Precision.decimals(2) }) // '0.33'\n * ```\n * @since 0.1.0\n */\nexport const decimals: (digits: number) => Precision = internal.decimals\n\n/**\n * Creates a `Precision` fixing the count of significant digits. Use it for\n * unit-free constants whose error is amplified downstream — solved curve\n * coefficients, for example — where fixed decimal places would truncate.\n *\n * @param digits - Significant digits. Must be an integer in `[1, 100]`.\n * @returns A `Precision` in `significant` mode.\n * @throws `Error` when `digits` is not an integer in `[1, 100]`.\n * @example\n * ```ts\n * const k = Calc.of(0.8377580409572781, Precision.significant(10))\n * Calc.serialize(k) // '0.837758041'\n * ```\n * @since 0.1.0\n */\nexport const significant: (digits: number) => Precision = internal.significant\n"],"mappings":"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"}
@@ -1,14 +1,15 @@
1
1
  import { Pipeable, dual, invariant } from "../utils.mjs";
2
2
  import { i as equals$1, n as HashTypeId, r as combine, s as hashString, t as EqualTypeId } from "./equal-U9G5LhtL.mjs";
3
3
  import { t as DEFAULT_FORMAT } from "./format-B9jsmCER.mjs";
4
- import { C as EMPTY_REFS, S as toCalc, _ as nodeOf, a as multiply, b as serializeNode, f as identsOf, g as nodeHash, h as nodeEquals, i as mod, l as collectBindings, m as needsCalcWrap, n as add, o as sign, s as subtract, u as dimension, v as refsOf$1, w as unionRefs, x as substituteNode } from "./calc-Cih4o2r7.mjs";
4
+ import { _ as RefsTypeId, g as EMPTY_REFS, h as refsOfVar, o as fallbackOf, r as declaredTypeOf, s as isVar, u as nameOf, y as unionRefs } from "./var.internal-DSxAzEFN.mjs";
5
5
  import { i as toSpec } from "./precision.internal-0lv1nEpF.mjs";
6
+ import { S as toCalc, _ as nodeOf, a as multiply, b as serializeNode, f as identsOf, g as nodeHash, h as nodeEquals, i as mod, l as collectBindings, m as needsCalcWrap, n as add, o as sign, s as subtract, u as dimension, v as refsOf$1, x as substituteNode } from "./calc-Uwbxd7CS.mjs";
6
7
  //#region src/data/colorSpace.internal.ts
7
8
  const ColorSpaceTypeId = Symbol.for("fashionable/data/colorSpace");
8
9
  var ColorSpaceImpl = class {
10
+ [ColorSpaceTypeId] = ColorSpaceTypeId;
9
11
  token;
10
12
  wrap;
11
- [ColorSpaceTypeId] = ColorSpaceTypeId;
12
13
  constructor(token, wrap) {
13
14
  this.token = token;
14
15
  this.wrap = wrap;
@@ -56,8 +57,8 @@ const dataOf = (space) => space;
56
57
  //#region src/data/hueInterpolation.internal.ts
57
58
  const HueInterpolationTypeId = Symbol.for("fashionable/data/hueInterpolation");
58
59
  var HueInterpolationImpl = class {
59
- strategy;
60
60
  [HueInterpolationTypeId] = HueInterpolationTypeId;
61
+ strategy;
61
62
  constructor(strategy) {
62
63
  this.strategy = strategy;
63
64
  }
@@ -159,7 +160,11 @@ const mapColorNode = (node, f) => {
159
160
  ],
160
161
  alpha: node.alpha === void 0 ? void 0 : mapChannel(node.alpha, f)
161
162
  };
162
- case "ColorRef":
163
+ case "ColorRef": return node.fallback === void 0 ? node : {
164
+ _tag: "ColorRef",
165
+ name: node.name,
166
+ fallback: mapColorNode(node.fallback, f)
167
+ };
163
168
  case "Named": return node;
164
169
  }
165
170
  };
@@ -178,7 +183,7 @@ const serializeColorNode = (node, precision) => {
178
183
  if (node._tag === "Named") return node.name;
179
184
  if (node._tag === "LightDark") return `light-dark(${serializeColorNode(node.light, precision)}, ${serializeColorNode(node.dark, precision)})`;
180
185
  if (node._tag === "ColorMix") return `color-mix(${serializeMethod(node.method)}, ${serializeMixArm(node.color1, node.percentage1, precision)}, ${serializeMixArm(node.color2, node.percentage2, precision)})`;
181
- if (node._tag === "ColorRef") return `var(--${node.name})`;
186
+ if (node._tag === "ColorRef") return node.fallback === void 0 ? `var(--${node.name})` : `var(--${node.name}, ${serializeColorNode(node.fallback, precision)})`;
182
187
  if (node._tag === "Relative") {
183
188
  const origin = serializeColorNode(node.origin, precision);
184
189
  const rendered = node.channels.map((channel) => serializeChannel(channel, precision)).join(" ");
@@ -205,7 +210,11 @@ const colorNodeEquals = (a, b) => {
205
210
  const other = b;
206
211
  return a.method.colorspace === other.method.colorspace && a.method.hue === other.method.hue && colorNodeEquals(a.color1, other.color1) && percentageEquals(a.percentage1, other.percentage1) && colorNodeEquals(a.color2, other.color2) && percentageEquals(a.percentage2, other.percentage2);
207
212
  }
208
- if (a._tag === "ColorRef") return a.name === b.name;
213
+ if (a._tag === "ColorRef") {
214
+ const other = b;
215
+ if (a.name !== other.name) return false;
216
+ return a.fallback === void 0 || other.fallback === void 0 ? a.fallback === other.fallback : colorNodeEquals(a.fallback, other.fallback);
217
+ }
209
218
  if (a._tag === "Relative") {
210
219
  const other = b;
211
220
  return a.token === other.token && a.wrap === other.wrap && colorNodeEquals(a.origin, other.origin) && a.channels.every((channel, index) => channelEquals(channel, other.channels[index])) && alphaEquals(a.alpha, other.alpha);
@@ -217,7 +226,10 @@ const hashChannel = (channel) => isNoneChannel(channel) ? hashString("none") : n
217
226
  const colorNodeHash = (node) => {
218
227
  let h = hashString(node._tag);
219
228
  if (node._tag === "Named") return combine(h, hashString(node.name));
220
- if (node._tag === "ColorRef") return combine(h, hashString(node.name));
229
+ if (node._tag === "ColorRef") {
230
+ h = combine(h, hashString(node.name));
231
+ return combine(h, node.fallback === void 0 ? 0 : colorNodeHash(node.fallback));
232
+ }
221
233
  if (node._tag === "LightDark") {
222
234
  h = combine(h, colorNodeHash(node.light));
223
235
  return combine(h, colorNodeHash(node.dark));
@@ -250,6 +262,9 @@ var ColorImpl = class extends Pipeable {
250
262
  this.node = node;
251
263
  this.refSet = refSet;
252
264
  }
265
+ get [RefsTypeId]() {
266
+ return this.refSet;
267
+ }
253
268
  [EqualTypeId](that) {
254
269
  return isColor(that) && colorNodeEquals(this.node, nodeOfColor(that));
255
270
  }
@@ -324,13 +339,33 @@ const named = (name) => {
324
339
  };
325
340
  /** @internal */
326
341
  const transparent = named("transparent");
342
+ const lowerFallback = (fb) => {
343
+ if (typeof fb === "string") return nodeOfColor(named(fb));
344
+ if (isVar(fb)) return lowerRead(fb);
345
+ invariant(isColor(fb), "Color var fallback must be a Color, color text, or a Var read");
346
+ return nodeOfColor(fb);
347
+ };
348
+ const lowerRead = (read) => {
349
+ const declared = declaredTypeOf(read);
350
+ invariant(declared === void 0 || declared === "color", "A calc-declared read cannot lift into a color; use Calc.var");
351
+ const fb = fallbackOf(read);
352
+ return fb === void 0 ? {
353
+ _tag: "ColorRef",
354
+ name: nameOf(read)
355
+ } : {
356
+ _tag: "ColorRef",
357
+ name: nameOf(read),
358
+ fallback: lowerFallback(fb)
359
+ };
360
+ };
327
361
  /** @internal */
328
- const ref = (name) => {
329
- invariant(name.length > 0, "Color reference name must be a non-empty string");
362
+ const ref = (read) => {
363
+ if (typeof read !== "string") return new ColorImpl(lowerRead(read), refsOfVar(read));
364
+ invariant(read.length > 0, "Color reference name must be a non-empty string");
330
365
  return new ColorImpl({
331
366
  _tag: "ColorRef",
332
- name
333
- }, /* @__PURE__ */ new Set([name]));
367
+ name: read
368
+ }, /* @__PURE__ */ new Set([read]));
334
369
  };
335
370
  /** @internal */
336
371
  function lightDark(light, dark) {
@@ -397,7 +432,7 @@ function from(origin, space, channel1, channel2, channel3, alpha) {
397
432
  }
398
433
  const colorRefNames = (node) => {
399
434
  switch (node._tag) {
400
- case "ColorRef": return /* @__PURE__ */ new Set([node.name]);
435
+ case "ColorRef": return node.fallback === void 0 ? /* @__PURE__ */ new Set([node.name]) : unionRefs(/* @__PURE__ */ new Set([node.name]), colorRefNames(node.fallback));
401
436
  case "LightDark": return unionRefs(colorRefNames(node.light), colorRefNames(node.dark));
402
437
  case "ColorMix": return unionRefs(colorRefNames(node.color1), colorRefNames(node.color2));
403
438
  case "Relative": return colorRefNames(node.origin);
@@ -447,4 +482,4 @@ const equals = dual(2, (self, that) => equals$1(self, that));
447
482
  //#endregion
448
483
  export { oklab as A, shorter as C, hwb as D, hsl as E, srgbLinear as F, xyz as I, xyzD50 as L, prophotoRgb as M, rec2020 as N, lab as O, srgb$1 as P, xyzD65 as R, longer as S, displayP3 as T, isNone as _, isColor as a, increasing as b, named as c, refs as d, refsOf as f, of as g, transparent as h, from as i, oklch$1 as j, lch as k, oklch as l, srgb as m, channels as n, lightDark as o, serialize as p, equals as r, mix as s, bind as t, ref as u, none as v, a98Rgb as w, interpolate as x, decreasing as y };
449
484
 
450
- //# sourceMappingURL=color.internal-Dts5ycTm.mjs.map
485
+ //# sourceMappingURL=color.internal-CxjlaRqR.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"color.internal-CxjlaRqR.mjs","names":["srgb","oklch","Calc.subtract","Calc.mod","Calc.add","Calc.multiply","Calc.sign","Equal.hashString","Equal.combine","Equal.EqualTypeId","Equal.HashTypeId","#hash","calcRefsOf","varNameOf","percentageOf","spaceDataOf","Equal.equals"],"sources":["../../src/data/colorSpace.internal.ts","../../src/data/hueInterpolation.internal.ts","../../src/data/keywords.internal.ts","../../src/data/percentage.internal.ts","../../src/data/color.internal.ts"],"sourcesContent":["import type { ColorSpace } from './colorSpace.ts'\n\nexport const ColorSpaceTypeId = Symbol.for('fashionable/data/colorSpace')\nexport type ColorSpaceTypeId = typeof ColorSpaceTypeId\n\n/**\n * Phantom key holding a `ColorSpace`'s `Trait` parameter. The runtime value\n * never has a value here — traits are type-level brands, so a space is\n * identical at runtime whatever its traits (the curvy trait pattern).\n *\n * @internal\n */\nexport const ColorSpaceTraits: unique symbol = Symbol.for('fashionable/data/colorSpace/traits')\nexport type ColorSpaceTraits = typeof ColorSpaceTraits\n\n/**\n * How a relative color built in this space serializes: a named color function\n * (`oklch(from ...)`) or the `color()` wrapper with a colorspace token\n * (`color(from ... srgb ...)`).\n *\n * @internal\n */\nexport type Wrap = 'function' | 'color'\n\n/**\n * The erased runtime of a color space: the token that names it (`in <token>`\n * for `mix`, the destination for `from`) and how a `from` wraps. Polar-ness is\n * a type-level trait, so it carries no runtime data.\n *\n * @internal\n */\nexport interface ColorSpaceData {\n readonly token: string\n readonly wrap: Wrap\n}\n\nclass ColorSpaceImpl {\n readonly [ColorSpaceTypeId]: ColorSpaceTypeId = ColorSpaceTypeId\n readonly token: string\n readonly wrap: Wrap\n\n constructor(token: string, wrap: Wrap) {\n this.token = token\n this.wrap = wrap\n }\n\n get [Symbol.toStringTag]() {\n return `ColorSpace(${this.token})`\n }\n\n get [Symbol.for('nodejs.util.inspect.custom')]() {\n return this[Symbol.toStringTag]\n }\n}\n\n/** @internal */\nexport const srgb = new ColorSpaceImpl('srgb', 'color')\n/** @internal */\nexport const srgbLinear = new ColorSpaceImpl('srgb-linear', 'color')\n/** @internal */\nexport const displayP3 = new ColorSpaceImpl('display-p3', 'color')\n/** @internal */\nexport const a98Rgb = new ColorSpaceImpl('a98-rgb', 'color')\n/** @internal */\nexport const prophotoRgb = new ColorSpaceImpl('prophoto-rgb', 'color')\n/** @internal */\nexport const rec2020 = new ColorSpaceImpl('rec2020', 'color')\n/** @internal */\nexport const lab = new ColorSpaceImpl('lab', 'function')\n/** @internal */\nexport const oklab = new ColorSpaceImpl('oklab', 'function')\n/** @internal */\nexport const xyz = new ColorSpaceImpl('xyz', 'color')\n/** @internal */\nexport const xyzD50 = new ColorSpaceImpl('xyz-d50', 'color')\n/** @internal */\nexport const xyzD65 = new ColorSpaceImpl('xyz-d65', 'color')\n/** @internal */\nexport const hsl = new ColorSpaceImpl('hsl', 'function')\n/** @internal */\nexport const hwb = new ColorSpaceImpl('hwb', 'function')\n/** @internal */\nexport const lch = new ColorSpaceImpl('lch', 'function')\n/** @internal */\nexport const oklch = new ColorSpaceImpl('oklch', 'function')\n\n/** @internal */\nexport const dataOf = (space: ColorSpace<unknown>): ColorSpaceData =>\n space as unknown as ColorSpaceData\n","import { Calc } from '#calc'\nimport type { Input } from '#calc/calc'\nimport type { HueInterpolation } from './hueInterpolation.ts'\n\nexport const HueInterpolationTypeId = Symbol.for('fashionable/data/hueInterpolation')\nexport type HueInterpolationTypeId = typeof HueInterpolationTypeId\n\nclass HueInterpolationImpl {\n readonly [HueInterpolationTypeId]: HueInterpolationTypeId = HueInterpolationTypeId\n readonly strategy: string\n\n constructor(strategy: string) {\n this.strategy = strategy\n }\n\n get [Symbol.toStringTag]() {\n return `HueInterpolation(${this.strategy})`\n }\n\n get [Symbol.for('nodejs.util.inspect.custom')]() {\n return this[Symbol.toStringTag]\n }\n}\n\n/** @internal */\nexport const shorter = new HueInterpolationImpl('shorter')\n\n/** @internal */\nexport const longer = new HueInterpolationImpl('longer')\n\n/** @internal */\nexport const increasing = new HueInterpolationImpl('increasing')\n\n/** @internal */\nexport const decreasing = new HueInterpolationImpl('decreasing')\n\n/** @internal */\nexport const strategyOf = (hue: HueInterpolation<string>): string =>\n (hue as unknown as HueInterpolationImpl).strategy\n\n/** @internal */\nexport const interpolate = (\n strategy: HueInterpolation<string>,\n from: Input,\n to: Input,\n t: Input,\n): Calc.Calc<never> => {\n // CSS Color 4 hue fixup, branchless in degree-space (`mod` handles the\n // normalization): each strategy is a signed delta the browser adds to `from`\n // as `t` runs 0 to 1. `shorter` and `longer` are complementary arcs;\n // `increasing`/`decreasing` force the direction.\n const delta = Calc.subtract(to, from)\n const shortest = Calc.subtract(Calc.mod(Calc.add(delta, 180), 360), 180)\n const strat = strategyOf(strategy)\n const step =\n strat === 'increasing'\n ? Calc.mod(delta, 360)\n : strat === 'decreasing'\n ? Calc.subtract(Calc.mod(delta, 360), 360)\n : strat === 'longer'\n ? Calc.subtract(shortest, Calc.multiply(360, Calc.sign(shortest)))\n : shortest\n return Calc.add(from, Calc.multiply(step, t)) as unknown as Calc.Calc<never>\n}\n","import { Pipeable } from '#util'\nimport type { None } from './keywords.ts'\n\nexport const NoneTypeId = Symbol.for('fashionable/data/keywords/none')\nexport type NoneTypeId = typeof NoneTypeId\n\nclass NoneImpl extends Pipeable implements None {\n readonly [NoneTypeId]: NoneTypeId = NoneTypeId\n\n get [Symbol.toStringTag]() {\n return 'Keyword(none)'\n }\n\n get [Symbol.for('nodejs.util.inspect.custom')]() {\n return this[Symbol.toStringTag]\n }\n}\n\n/** @internal */\nexport const none: None = new NoneImpl()\n\n/** @internal */\nexport const isNone = (u: unknown): u is None =>\n typeof u === 'object' && u !== null && NoneTypeId in u\n","import type { Calc } from '#calc/calc'\nimport { dimension } from '#calc/calc.internal'\nimport type { Precision } from '#calc/precision'\nimport type * as Unit from './unit.ts'\n\n/** @internal */\nexport const of = (value: number, precision?: Precision): Calc<never, Unit.Percent, Unit.Percent> =>\n dimension(value, '%', 'percentage', precision)\n","import type { ApplyBindings, Bindings, Calc, Input, SerializeOptions } from '#calc/calc'\nimport {\n type CalcNode,\n collectBindings,\n identsOf,\n needsCalcWrap,\n nodeEquals,\n nodeHash,\n nodeOf,\n refsOf as calcRefsOf,\n serializeNode,\n substituteNode,\n toCalc,\n} from '#calc/calc.internal'\nimport { toSpec } from '#calc/precision.internal'\nimport * as Equal from '#internal/equal'\nimport { DEFAULT_FORMAT, type FormatSpec } from '#internal/format'\nimport { EMPTY_REFS, RefsTypeId, unionRefs } from '#internal/refs'\nimport { dual, invariant, Pipeable } from '#util'\nimport type { Name as VarName } from '#var/var'\nimport {\n type AnyVar,\n declaredTypeOf,\n fallbackOf,\n isVar,\n nameOf as varNameOf,\n refsOfVar,\n} from '#var/var.internal'\nimport type { ChannelIdent } from './channels.ts'\nimport type { Color, RelativeChannel } from './color.ts'\nimport { dataOf as spaceDataOf, type Wrap } from './colorSpace.internal.ts'\nimport type { ColorSpace } from './colorSpace.ts'\nimport { strategyOf } from './hueInterpolation.internal.ts'\nimport type { HueInterpolation } from './hueInterpolation.ts'\nimport { isNone } from './keywords.internal.ts'\nimport type { None } from './keywords.ts'\nimport { of as percentageOf } from './percentage.internal.ts'\nimport type * as Unit from './unit.ts'\n\nexport const ColorTypeId = Symbol.for('fashionable/color')\nexport type ColorTypeId = typeof ColorTypeId\n\n/**\n * A channel slot: a number expression, or CSS's missing-component\n * keyword. The `none` marker is a singleton, so channel operations\n * discriminate by reference.\n *\n * @internal\n */\nexport type ChannelNode = CalcNode | NoneChannel\n\ninterface NoneChannel {\n readonly _tag: 'NoneKeyword'\n}\n\nconst NONE_CHANNEL: NoneChannel = { _tag: 'NoneKeyword' }\n\nconst isNoneChannel = (channel: ChannelNode): channel is NoneChannel => channel === NONE_CHANNEL\n\n/** @internal */\nexport interface OklchNode {\n readonly _tag: 'Oklch'\n readonly lightness: ChannelNode\n readonly chroma: ChannelNode\n readonly hue: ChannelNode\n}\n\n/** @internal */\nexport interface SrgbNode {\n readonly _tag: 'Srgb'\n readonly red: ChannelNode\n readonly green: ChannelNode\n readonly blue: ChannelNode\n}\n\n/**\n * A named color (`transparent`, `rebeccapurple`): the name is the whole\n * value, so the node has no channels and nothing to bind.\n *\n * @internal\n */\nexport interface NamedColorNode {\n readonly _tag: 'Named'\n readonly name: string\n}\n\n/**\n * A scheme-conditional color: `light-dark(light, dark)`. Arms are whole\n * color nodes — positional, not commutative (the first slot is the\n * light scheme) — so the node operations recurse where the channel\n * functions stay flat.\n *\n * @internal\n */\nexport interface LightDarkNode {\n readonly _tag: 'LightDark'\n readonly light: ColorNode\n readonly dark: ColorNode\n}\n\n/**\n * The normalized interpolation method of a `color-mix()`: a colorspace\n * token plus, for polar spaces, an optional hue-interpolation strategy.\n * The type-level polar/rectangular split lives in `color.ts`; the node\n * carries the erased strings.\n *\n * @internal\n */\nexport interface MethodNode {\n readonly colorspace: string\n readonly hue: string | undefined\n}\n\n/**\n * A `color-mix(in method, c1 p1?, c2 p2?)`. The two arms are whole color\n * nodes, each with an optional percentage — a percentage-kind `CalcNode`,\n * never `none`, `undefined` when omitted. Arms are positional (they carry\n * their own percentages), so the node operations recurse, as `LightDark`\n * does.\n *\n * @internal\n */\nexport interface ColorMixNode {\n readonly _tag: 'ColorMix'\n readonly method: MethodNode\n readonly color1: ColorNode\n readonly percentage1: CalcNode | undefined\n readonly color2: ColorNode\n readonly percentage2: CalcNode | undefined\n}\n\n/**\n * A relative color: `oklch(from origin l c h [/ a])` or\n * `color(from origin srgb r g b [/ a])`. `token` names the destination space\n * and `wrap` selects its serialized form — a named function or the `color()`\n * wrapper — both read off the `ColorSpace` argument. `origin` is a whole color\n * node (recursed, as `LightDark` arms are). The three `channels` and the\n * optional `alpha` are calc slots whose expressions may read the origin's\n * channels through the `Channel` keywords — bare-identifier leaves that stay\n * put under bind and contribute no refs.\n *\n * @internal\n */\nexport interface RelativeNode {\n readonly _tag: 'Relative'\n readonly token: string\n readonly wrap: Wrap\n readonly origin: ColorNode\n readonly channels: readonly [ChannelNode, ChannelNode, ChannelNode]\n readonly alpha: ChannelNode | undefined\n}\n\n/**\n * A color-valued custom-property reference: `var(--name)` used as a whole\n * color. The reference is the whole value, so — like a `Named` — it has no\n * channels to descend into; it serializes `var(--name)` and reports `name` as\n * a ref. The channel-binding path cannot substitute a color into it, so its\n * ref rides through `bind` (restored structurally), the browser being the one\n * to resolve it.\n *\n * @internal\n */\nexport interface ColorRefNode {\n readonly _tag: 'ColorRef'\n readonly name: string\n readonly fallback?: ColorNode\n}\n\n/** @internal */\nexport type ColorNode =\n | OklchNode\n | SrgbNode\n | LightDarkNode\n | NamedColorNode\n | ColorMixNode\n | RelativeNode\n | ColorRefNode\n\ntype ChannelFunctionNode = OklchNode | SrgbNode\n\nconst channelsOf = (node: ChannelFunctionNode): ReadonlyArray<ChannelNode> =>\n node._tag === 'Oklch'\n ? [node.lightness, node.chroma, node.hue]\n : [node.red, node.green, node.blue]\n\nconst mapChannel = (channel: ChannelNode, f: (channel: CalcNode) => CalcNode): ChannelNode =>\n isNoneChannel(channel) ? channel : f(channel)\n\nconst mapColorNode = (node: ColorNode, f: (channel: CalcNode) => CalcNode): ColorNode => {\n switch (node._tag) {\n case 'Oklch':\n return {\n _tag: 'Oklch',\n lightness: mapChannel(node.lightness, f),\n chroma: mapChannel(node.chroma, f),\n hue: mapChannel(node.hue, f),\n }\n case 'Srgb':\n return {\n _tag: 'Srgb',\n red: mapChannel(node.red, f),\n green: mapChannel(node.green, f),\n blue: mapChannel(node.blue, f),\n }\n case 'LightDark':\n return {\n _tag: 'LightDark',\n light: mapColorNode(node.light, f),\n dark: mapColorNode(node.dark, f),\n }\n case 'ColorMix':\n return {\n _tag: 'ColorMix',\n method: node.method,\n color1: mapColorNode(node.color1, f),\n percentage1: node.percentage1 === undefined ? undefined : f(node.percentage1),\n color2: mapColorNode(node.color2, f),\n percentage2: node.percentage2 === undefined ? undefined : f(node.percentage2),\n }\n case 'Relative':\n return {\n _tag: 'Relative',\n token: node.token,\n wrap: node.wrap,\n origin: mapColorNode(node.origin, f),\n channels: [\n mapChannel(node.channels[0], f),\n mapChannel(node.channels[1], f),\n mapChannel(node.channels[2], f),\n ],\n alpha: node.alpha === undefined ? undefined : mapChannel(node.alpha, f),\n }\n case 'ColorRef':\n return node.fallback === undefined\n ? node\n : { _tag: 'ColorRef', name: node.name, fallback: mapColorNode(node.fallback, f) }\n case 'Named':\n return node\n }\n}\n\n// A single calc-expression slot — a channel or a percentage — wrapped in\n// `calc()` only when it is arithmetic; function forms and leaves stand alone.\nconst serializeCalcNode = (node: CalcNode, precision: FormatSpec): string => {\n const wrap = needsCalcWrap(node)\n const body = serializeNode(node, wrap, { precision })\n return wrap ? `calc(${body})` : body\n}\n\nconst serializeChannel = (channel: ChannelNode, precision: FormatSpec): string =>\n isNoneChannel(channel) ? 'none' : serializeCalcNode(channel, precision)\n\nconst serializeMethod = (method: MethodNode): string =>\n method.hue === undefined ? `in ${method.colorspace}` : `in ${method.colorspace} ${method.hue} hue`\n\nconst serializeMixArm = (\n color: ColorNode,\n percentage: CalcNode | undefined,\n precision: FormatSpec,\n): string => {\n const rendered = serializeColorNode(color, precision)\n return percentage === undefined\n ? rendered\n : `${rendered} ${serializeCalcNode(percentage, precision)}`\n}\n\nconst serializeColorNode = (node: ColorNode, precision: FormatSpec): string => {\n if (node._tag === 'Named') {\n return node.name\n }\n if (node._tag === 'LightDark') {\n return `light-dark(${serializeColorNode(node.light, precision)}, ${serializeColorNode(node.dark, precision)})`\n }\n if (node._tag === 'ColorMix') {\n return `color-mix(${serializeMethod(node.method)}, ${serializeMixArm(node.color1, node.percentage1, precision)}, ${serializeMixArm(node.color2, node.percentage2, precision)})`\n }\n if (node._tag === 'ColorRef') {\n return node.fallback === undefined\n ? `var(--${node.name})`\n : `var(--${node.name}, ${serializeColorNode(node.fallback, precision)})`\n }\n if (node._tag === 'Relative') {\n const origin = serializeColorNode(node.origin, precision)\n const rendered = node.channels.map((channel) => serializeChannel(channel, precision)).join(' ')\n const alpha = node.alpha === undefined ? '' : ` / ${serializeChannel(node.alpha, precision)}`\n return node.wrap === 'function'\n ? `${node.token}(from ${origin} ${rendered}${alpha})`\n : `color(from ${origin} ${node.token} ${rendered}${alpha})`\n }\n const rendered = channelsOf(node)\n .map((channel) => serializeChannel(channel, precision))\n .join(' ')\n return node._tag === 'Oklch' ? `oklch(${rendered})` : `color(srgb ${rendered})`\n}\n\nconst channelEquals = (a: ChannelNode, b: ChannelNode): boolean => {\n if (isNoneChannel(a) || isNoneChannel(b)) {\n return a === b\n }\n return nodeEquals(a, b)\n}\n\nconst percentageEquals = (a: CalcNode | undefined, b: CalcNode | undefined): boolean =>\n a === undefined || b === undefined ? a === b : nodeEquals(a, b)\n\n// An optional channel — a relative color's alpha — where an omitted slot only\n// equals another omitted slot, never a present `none` or expression.\nconst alphaEquals = (a: ChannelNode | undefined, b: ChannelNode | undefined): boolean =>\n a === undefined || b === undefined ? a === b : channelEquals(a, b)\n\nconst colorNodeEquals = (a: ColorNode, b: ColorNode): boolean => {\n if (a._tag !== b._tag) {\n return false\n }\n if (a._tag === 'Named') {\n return a.name === (b as NamedColorNode).name\n }\n if (a._tag === 'LightDark') {\n const other = b as LightDarkNode\n return colorNodeEquals(a.light, other.light) && colorNodeEquals(a.dark, other.dark)\n }\n if (a._tag === 'ColorMix') {\n const other = b as ColorMixNode\n return (\n a.method.colorspace === other.method.colorspace &&\n a.method.hue === other.method.hue &&\n colorNodeEquals(a.color1, other.color1) &&\n percentageEquals(a.percentage1, other.percentage1) &&\n colorNodeEquals(a.color2, other.color2) &&\n percentageEquals(a.percentage2, other.percentage2)\n )\n }\n if (a._tag === 'ColorRef') {\n const other = b as ColorRefNode\n if (a.name !== other.name) {\n return false\n }\n return a.fallback === undefined || other.fallback === undefined\n ? a.fallback === other.fallback\n : colorNodeEquals(a.fallback, other.fallback)\n }\n if (a._tag === 'Relative') {\n const other = b as RelativeNode\n return (\n a.token === other.token &&\n a.wrap === other.wrap &&\n colorNodeEquals(a.origin, other.origin) &&\n a.channels.every((channel, index) =>\n channelEquals(channel, other.channels[index] as ChannelNode),\n ) &&\n alphaEquals(a.alpha, other.alpha)\n )\n }\n const others = channelsOf(b as ChannelFunctionNode)\n return channelsOf(a).every((channel, index) =>\n channelEquals(channel, others[index] as ChannelNode),\n )\n}\n\nconst hashChannel = (channel: ChannelNode): number =>\n isNoneChannel(channel) ? Equal.hashString('none') : nodeHash(channel)\n\nconst colorNodeHash = (node: ColorNode): number => {\n let h = Equal.hashString(node._tag)\n if (node._tag === 'Named') {\n return Equal.combine(h, Equal.hashString(node.name))\n }\n if (node._tag === 'ColorRef') {\n h = Equal.combine(h, Equal.hashString(node.name))\n return Equal.combine(h, node.fallback === undefined ? 0 : colorNodeHash(node.fallback))\n }\n if (node._tag === 'LightDark') {\n h = Equal.combine(h, colorNodeHash(node.light))\n return Equal.combine(h, colorNodeHash(node.dark))\n }\n if (node._tag === 'ColorMix') {\n h = Equal.combine(h, Equal.hashString(node.method.colorspace))\n h = Equal.combine(h, node.method.hue === undefined ? 0 : Equal.hashString(node.method.hue))\n h = Equal.combine(h, colorNodeHash(node.color1))\n h = Equal.combine(h, node.percentage1 === undefined ? 0 : nodeHash(node.percentage1))\n h = Equal.combine(h, colorNodeHash(node.color2))\n return Equal.combine(h, node.percentage2 === undefined ? 0 : nodeHash(node.percentage2))\n }\n if (node._tag === 'Relative') {\n h = Equal.combine(h, Equal.hashString(node.token))\n h = Equal.combine(h, Equal.hashString(node.wrap))\n h = Equal.combine(h, colorNodeHash(node.origin))\n for (const channel of node.channels) {\n h = Equal.combine(h, hashChannel(channel))\n }\n return Equal.combine(h, node.alpha === undefined ? 0 : hashChannel(node.alpha))\n }\n for (const channel of channelsOf(node)) {\n h = Equal.combine(h, hashChannel(channel))\n }\n return h\n}\n\nclass ColorImpl extends Pipeable implements Color<AnyVar>, Equal.Equal {\n readonly [ColorTypeId]: ColorTypeId = ColorTypeId\n\n readonly node: ColorNode\n readonly refSet: ReadonlySet<string>\n #hash: number | undefined\n\n constructor(node: ColorNode, refSet: ReadonlySet<string>) {\n super()\n this.node = node\n this.refSet = refSet\n }\n\n get [RefsTypeId](): ReadonlySet<string> {\n return this.refSet\n }\n\n [Equal.EqualTypeId](that: unknown): boolean {\n return isColor(that) && colorNodeEquals(this.node, nodeOfColor(that))\n }\n\n [Equal.HashTypeId](): number {\n this.#hash ??= Equal.combine(Equal.hashString('fashionable/color'), colorNodeHash(this.node))\n return this.#hash\n }\n\n get [Symbol.toStringTag]() {\n return `Color(${serializeColorNode(this.node, DEFAULT_FORMAT)})`\n }\n\n get [Symbol.for('nodejs.util.inspect.custom')]() {\n return this[Symbol.toStringTag]\n }\n}\n\n/** @internal */\nexport const isColor = (u: unknown): u is Color<AnyVar> =>\n typeof u === 'object' && u !== null && ColorTypeId in u\n\n/** @internal */\nexport const nodeOfColor = (color: Color<AnyVar>): ColorNode => (color as ColorImpl).node\n\n/** @internal */\nexport const refsOf = (color: Color<AnyVar>): ReadonlySet<string> =>\n (color as unknown as ColorImpl).refSet\n\ninterface ResolvedChannel {\n readonly node: ChannelNode\n readonly refs: ReadonlySet<string>\n}\n\n// The erased channel input the constructors funnel through `toChannel`: a\n// number, `none`, or any number-kind expression — including one branded with a\n// relative-color channel keyword. The public signatures pin the precise vars\n// and scope the keywords to the space; this stays wide enough to accept all.\ntype RelativeChannelInput = RelativeChannel<AnyVar, ChannelIdent<string>>\n\nconst toChannel = (input: RelativeChannelInput): ResolvedChannel => {\n if (isNone(input)) {\n return { node: NONE_CHANNEL, refs: EMPTY_REFS }\n }\n const calc = toCalc(input)\n return { node: nodeOf(calc), refs: calcRefsOf(calc) }\n}\n\n/** @internal */\nexport function oklch<L extends AnyVar = never, C extends AnyVar = never, H extends AnyVar = never>(\n lightness: Input<L> | None,\n chroma: Input<C> | None,\n hue: Input<H> | None,\n): Color<L | C | H> {\n const l = toChannel(lightness)\n const c = toChannel(chroma)\n const h = toChannel(hue)\n return new ColorImpl(\n { _tag: 'Oklch', lightness: l.node, chroma: c.node, hue: h.node },\n unionRefs(l.refs, c.refs, h.refs),\n ) as Color<L | C | H>\n}\n\n/** @internal */\nexport function srgb<R extends AnyVar = never, G extends AnyVar = never, B extends AnyVar = never>(\n red: Input<R> | None,\n green: Input<G> | None,\n blue: Input<B> | None,\n): Color<R | G | B> {\n const r = toChannel(red)\n const g = toChannel(green)\n const b = toChannel(blue)\n return new ColorImpl(\n { _tag: 'Srgb', red: r.node, green: g.node, blue: b.node },\n unionRefs(r.refs, g.refs, b.refs),\n ) as Color<R | G | B>\n}\n\n// The CSS-wide keywords are whole-declaration values, not colors —\n// `light-dark(inherit, …)` is invalid CSS — so `named` rejects them\n// (the `PropertySyntax.keyword` posture).\nconst CSS_WIDE_KEYWORDS = new Set([\n 'inherit',\n 'initial',\n 'unset',\n 'revert',\n 'revert-layer',\n 'default',\n])\n\n/** @internal */\nexport const named = (name: string): Color<never> => {\n invariant(name.length > 0, 'Named color must be a non-empty string')\n invariant(\n !CSS_WIDE_KEYWORDS.has(name.toLowerCase()),\n `Named color must not be a CSS-wide keyword, got '${name}'`,\n )\n return new ColorImpl({ _tag: 'Named', name }, EMPTY_REFS) as Color<never>\n}\n\n/** @internal */\nexport const transparent: Color<never> = named('transparent')\n\n// Lowers a read's fallback into color's node vocabulary: literal text is\n// coerced through `named` (so its guards apply), nested reads become nested\n// `ColorRef` nodes, and a `Color` hands over its node. The rejection is\n// structural — a `Calc`, say, fails the invariant without naming it here.\nconst lowerFallback = (fb: unknown): ColorNode => {\n if (typeof fb === 'string') {\n return nodeOfColor(named(fb))\n }\n if (isVar(fb)) {\n return lowerRead(fb)\n }\n invariant(isColor(fb), 'Color var fallback must be a Color, color text, or a Var read')\n return nodeOfColor(fb)\n}\n\nconst lowerRead = (read: AnyVar): ColorRefNode => {\n const declared = declaredTypeOf(read)\n invariant(\n declared === undefined || declared === 'color',\n 'A calc-declared read cannot lift into a color; use Calc.var',\n )\n const fb = fallbackOf(read)\n return fb === undefined\n ? { _tag: 'ColorRef', name: varNameOf(read) }\n : { _tag: 'ColorRef', name: varNameOf(read), fallback: lowerFallback(fb) }\n}\n\n/** @internal */\nexport const ref = (read: string | AnyVar): Color<never> => {\n if (typeof read !== 'string') {\n return new ColorImpl(lowerRead(read), refsOfVar(read)) as Color<never>\n }\n invariant(read.length > 0, 'Color reference name must be a non-empty string')\n return new ColorImpl({ _tag: 'ColorRef', name: read }, new Set([read])) as Color<never>\n}\n\n/** @internal */\nexport function lightDark<A extends AnyVar = never, B extends AnyVar = never>(\n light: Color<A>,\n dark: Color<B>,\n): Color<A | B> {\n return new ColorImpl(\n { _tag: 'LightDark', light: nodeOfColor(light), dark: nodeOfColor(dark) },\n unionRefs(refsOf(light), refsOf(dark)),\n ) as Color<A | B>\n}\n\n// The erased mix arm: a whole color, or a [color, weight] tuple whose weight is\n// a percentage-kind expression (a bare number reads as a percent).\ntype MixArmInput =\n | Color<AnyVar>\n | readonly [Color<AnyVar>, number | Calc<AnyVar, Unit.Percentage, unknown>]\n\ninterface ResolvedArm {\n readonly color: ColorNode\n readonly percentage: CalcNode | undefined\n readonly refs: ReadonlySet<string>\n}\n\nconst toArm = (arm: MixArmInput): ResolvedArm => {\n if (isColor(arm)) {\n return { color: nodeOfColor(arm), percentage: undefined, refs: refsOf(arm) }\n }\n const [color, percentage] = arm\n const pct = typeof percentage === 'number' ? percentageOf(percentage) : percentage\n return {\n color: nodeOfColor(color),\n percentage: nodeOf(pct),\n refs: unionRefs(refsOf(color), calcRefsOf(pct)),\n }\n}\n\n/** @internal */\nexport function mix(\n space: ColorSpace<unknown>,\n arg2: HueInterpolation<string> | MixArmInput,\n arg3: MixArmInput,\n arg4?: MixArmInput,\n): Color<never> {\n // (space, color1, color2), or (space, hue, color1, color2) — the hue form is\n // the one with a fourth argument\n const hasHue = arg4 !== undefined\n const hue = hasHue ? strategyOf(arg2 as HueInterpolation<string>) : undefined\n const a1 = toArm((hasHue ? arg3 : arg2) as MixArmInput)\n const a2 = toArm((hasHue ? arg4 : arg3) as MixArmInput)\n return new ColorImpl(\n {\n _tag: 'ColorMix',\n method: { colorspace: spaceDataOf(space).token, hue },\n color1: a1.color,\n percentage1: a1.percentage,\n color2: a2.color,\n percentage2: a2.percentage,\n },\n unionRefs(a1.refs, a2.refs),\n ) as Color<never>\n}\n\nconst relative = (\n token: string,\n wrap: Wrap,\n origin: Color<AnyVar>,\n channel1: RelativeChannelInput,\n channel2: RelativeChannelInput,\n channel3: RelativeChannelInput,\n alpha: RelativeChannelInput | undefined,\n): Color<AnyVar> => {\n const c1 = toChannel(channel1)\n const c2 = toChannel(channel2)\n const c3 = toChannel(channel3)\n const a = alpha === undefined ? undefined : toChannel(alpha)\n return new ColorImpl(\n {\n _tag: 'Relative',\n token,\n wrap,\n origin: nodeOfColor(origin),\n channels: [c1.node, c2.node, c3.node],\n alpha: a === undefined ? undefined : a.node,\n },\n unionRefs(refsOf(origin), c1.refs, c2.refs, c3.refs, a === undefined ? EMPTY_REFS : a.refs),\n )\n}\n\n/** @internal */\nexport function from(\n origin: Color<AnyVar>,\n space: ColorSpace<unknown>,\n channel1: RelativeChannelInput,\n channel2: RelativeChannelInput,\n channel3: RelativeChannelInput,\n alpha?: RelativeChannelInput,\n): Color<never> {\n const { token, wrap } = spaceDataOf(space)\n return relative(token, wrap, origin, channel1, channel2, channel3, alpha) as Color<never>\n}\n\n// The color-valued reference names in a node — the `ColorRef` origins the\n// channel-binding path cannot substitute, so `bind` restores them structurally\n// rather than trust `collectBindings` to have kept them (it strips any bound\n// key, including a color-ref name a caller passed a value for).\nconst colorRefNames = (node: ColorNode): ReadonlySet<string> => {\n switch (node._tag) {\n case 'ColorRef':\n return node.fallback === undefined\n ? new Set([node.name])\n : unionRefs(new Set([node.name]), colorRefNames(node.fallback))\n case 'LightDark':\n return unionRefs(colorRefNames(node.light), colorRefNames(node.dark))\n case 'ColorMix':\n return unionRefs(colorRefNames(node.color1), colorRefNames(node.color2))\n case 'Relative':\n return colorRefNames(node.origin)\n case 'Oklch':\n case 'Srgb':\n case 'Named':\n return EMPTY_REFS\n }\n}\n\nconst identsOfChannel = (channel: ChannelNode): ReadonlySet<string> =>\n isNoneChannel(channel) ? EMPTY_REFS : identsOf(channel)\n\n// The channel-keyword tokens a color reads — each channel slot's calc tree\n// walked and sub-colors recursed, the `Color` counterpart to `Calc.channels`.\n// Only relative colors introduce keywords; other nodes carry them solely\n// through a nested relative origin or arm.\nconst colorChannels = (node: ColorNode): ReadonlySet<string> => {\n switch (node._tag) {\n case 'Named':\n case 'ColorRef':\n return EMPTY_REFS\n case 'Oklch':\n return unionRefs(\n identsOfChannel(node.lightness),\n identsOfChannel(node.chroma),\n identsOfChannel(node.hue),\n )\n case 'Srgb':\n return unionRefs(\n identsOfChannel(node.red),\n identsOfChannel(node.green),\n identsOfChannel(node.blue),\n )\n case 'LightDark':\n return unionRefs(colorChannels(node.light), colorChannels(node.dark))\n case 'ColorMix':\n return unionRefs(\n colorChannels(node.color1),\n node.percentage1 === undefined ? EMPTY_REFS : identsOf(node.percentage1),\n colorChannels(node.color2),\n node.percentage2 === undefined ? EMPTY_REFS : identsOf(node.percentage2),\n )\n case 'Relative':\n return unionRefs(\n colorChannels(node.origin),\n identsOfChannel(node.channels[0]),\n identsOfChannel(node.channels[1]),\n identsOfChannel(node.channels[2]),\n node.alpha === undefined ? EMPTY_REFS : identsOfChannel(node.alpha),\n )\n }\n}\n\n/** @internal */\nexport const bind: {\n <const B extends Bindings>(\n bindings: B,\n ): <Vars extends AnyVar>(color: Color<Vars>) => Color<ApplyBindings<Vars, B>>\n <Vars extends AnyVar, const B extends Bindings>(\n color: Color<Vars>,\n bindings: B,\n ): Color<ApplyBindings<Vars, B>>\n} = dual(2, (color: Color<AnyVar>, bindings: Record<string, Input>): Color<AnyVar> => {\n const collected = collectBindings(refsOf(color), bindings)\n const node = mapColorNode(nodeOfColor(color), (channel) =>\n substituteNode(channel, collected.nodeBindings),\n )\n return new ColorImpl(node, unionRefs(collected.refSet, colorRefNames(node)))\n})\n\n/** @internal */\nexport function serialize<Vars extends AnyVar>(\n color: Color<Vars>,\n options?: SerializeOptions<Vars>,\n): string {\n let node = nodeOfColor(color)\n if (options?.bindings !== undefined) {\n const collected = collectBindings(\n refsOf(color),\n options.bindings as Record<string, Input | undefined>,\n )\n node = mapColorNode(node, (channel) => substituteNode(channel, collected.nodeBindings))\n }\n const precision = options?.precision === undefined ? DEFAULT_FORMAT : toSpec(options.precision)\n return serializeColorNode(node, precision)\n}\n\n/** @internal */\nexport function refs<Vars extends AnyVar>(color: Color<Vars>): ReadonlySet<VarName<Vars>> {\n return refsOf(color) as ReadonlySet<VarName<Vars>>\n}\n\n/** @internal */\nexport function channels(color: Color<AnyVar>): ReadonlySet<string> {\n return colorChannels(nodeOfColor(color))\n}\n\n/** @internal */\nexport const equals = dual<\n (that: Color<AnyVar>) => (self: Color<AnyVar>) => boolean,\n (self: Color<AnyVar>, that: Color<AnyVar>) => boolean\n>(2, (self: Color<AnyVar>, that: Color<AnyVar>): boolean => Equal.equals(self, that))\n"],"mappings":"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"}