@tenphi/tasty 3.1.0 → 3.3.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 (54) hide show
  1. package/README.md +1 -0
  2. package/dist/{babel-R2qT7yLN.d.ts → babel-BUQGeOXA.d.ts} +2 -2
  3. package/dist/{collector-D7yzmG5G.js → collector-BNQJyxFh.js} +3 -3
  4. package/dist/{collector-D7yzmG5G.js.map → collector-BNQJyxFh.js.map} +1 -1
  5. package/dist/{collector-D8o4Wdq-.d.ts → collector-DUaHCcTS.d.ts} +2 -2
  6. package/dist/{config-De8L9NWM.d.ts → config-YsxGv4tq.d.ts} +101 -10
  7. package/dist/{config-CwQ-fAsp.js → config-zkrtb424.js} +739 -960
  8. package/dist/config-zkrtb424.js.map +1 -0
  9. package/dist/core/index.d.ts +5 -5
  10. package/dist/core/index.js +6 -6
  11. package/dist/{core-CqSh853z.js → core-Bf48Z1I-.js} +57 -41
  12. package/dist/core-Bf48Z1I-.js.map +1 -0
  13. package/dist/{css-writer-dS1srTkS.js → css-writer-B-SvwNbq.js} +3 -3
  14. package/dist/{css-writer-dS1srTkS.js.map → css-writer-B-SvwNbq.js.map} +1 -1
  15. package/dist/{format-rules-CaW4lJGg.js → format-rules-Co21uwA3.js} +5 -20
  16. package/dist/format-rules-Co21uwA3.js.map +1 -0
  17. package/dist/{hydrate-uFv9kx7G.js → hydrate-D38TyhAG.js} +2 -2
  18. package/dist/{hydrate-uFv9kx7G.js.map → hydrate-D38TyhAG.js.map} +1 -1
  19. package/dist/{index-KUYya3x7.d.ts → index-Cd45t5NM.d.ts} +108 -3
  20. package/dist/{index-DzGxoeyN.d.ts → index-DhhUI0yi.d.ts} +63 -12
  21. package/dist/index.d.ts +5 -5
  22. package/dist/index.js +62 -8
  23. package/dist/index.js.map +1 -1
  24. package/dist/{keyframes-DaZhjqkd.js → keyframes-mDAB6pLf.js} +2 -2
  25. package/dist/{keyframes-DaZhjqkd.js.map → keyframes-mDAB6pLf.js.map} +1 -1
  26. package/dist/{merge-styles-H8LFJ5HY.js → merge-styles-CFwtEHzv.js} +2 -2
  27. package/dist/{merge-styles-H8LFJ5HY.js.map → merge-styles-CFwtEHzv.js.map} +1 -1
  28. package/dist/{merge-styles-DLm4wdnb.d.ts → merge-styles-CU7JbEwg.d.ts} +2 -2
  29. package/dist/{resolve-recipes-aN94fjqS.js → resolve-recipes-B8pIVinB.js} +3 -3
  30. package/dist/{resolve-recipes-aN94fjqS.js.map → resolve-recipes-B8pIVinB.js.map} +1 -1
  31. package/dist/ssr/astro-client.js +1 -1
  32. package/dist/ssr/astro.js +3 -3
  33. package/dist/ssr/index.d.ts +1 -1
  34. package/dist/ssr/index.js +3 -3
  35. package/dist/ssr/next.d.ts +1 -1
  36. package/dist/ssr/next.js +4 -4
  37. package/dist/static/index.d.ts +2 -2
  38. package/dist/static/index.js +1 -1
  39. package/dist/zero/babel.d.ts +1 -1
  40. package/dist/zero/babel.js +4 -4
  41. package/dist/zero/index.d.ts +1 -1
  42. package/dist/zero/index.js +1 -1
  43. package/dist/zero/next.d.ts +1 -1
  44. package/docs/configuration.md +195 -15
  45. package/docs/dsl.md +28 -6
  46. package/docs/injector.md +11 -0
  47. package/docs/methodology.md +1 -1
  48. package/docs/pipeline.md +1 -4
  49. package/docs/react-api.md +1 -1
  50. package/docs/styles.md +6 -1
  51. package/package.json +7 -6
  52. package/dist/config-CwQ-fAsp.js.map +0 -1
  53. package/dist/core-CqSh853z.js.map +0 -1
  54. package/dist/format-rules-CaW4lJGg.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-zkrtb424.js","names":["clamp","emittedWarnings","GTKEY","globalStore","processGroup","dimension","devMode","STYLE_HANDLER_MAP","emittedWarnings","devMode","warnOnce"],"sources":["../src/parser/const.ts","../src/utils/string.ts","../src/utils/color-math.ts","../src/utils/color-space.ts","../src/parser/types.ts","../src/parser/classify.ts","../src/parser/lru.ts","../src/parser/tokenizer.ts","../src/parser/parser.ts","../src/utils/is-dev-env.ts","../src/styles/shared.ts","../src/plugins/color-func.ts","../src/plugins/okhsl-plugin.ts","../src/plugins/okhst-plugin.ts","../src/plugins/defaults.ts","../src/utils/styles.ts","../src/functions/index.ts","../src/chunks/style-chunk-map.ts","../src/prop-handlers.ts","../src/properties/index.ts","../src/utils/hash.ts","../src/utils/name-prefix.ts","../src/utils/warnings.ts","../src/injector/batch.ts","../src/properties/property-type-resolver.ts","../src/styles/const.ts","../src/styles/border.ts","../src/styles/color.ts","../src/styles/createStyle.ts","../src/styles/display.ts","../src/styles/fade.ts","../src/styles/fill.ts","../src/styles/flow.ts","../src/styles/gap.ts","../src/styles/dimension.ts","../src/styles/height.ts","../src/styles/directional.ts","../src/styles/inset.ts","../src/styles/margin.ts","../src/styles/outline.ts","../src/styles/padding.ts","../src/styles/placement.ts","../src/styles/preset.ts","../src/styles/radius.ts","../src/styles/scrollMargin.ts","../src/styles/scrollbar.ts","../src/styles/shadow.ts","../src/styles/transition.ts","../src/styles/width.ts","../src/styles/predefined.ts","../src/styles/define-handler.ts","../src/styles/index.ts","../src/injector/sheet-manager.ts","../src/font-face/index.ts","../src/counter-style/index.ts","../src/injector/injector.ts","../src/states/index.ts","../src/pipeline/conditions.ts","../src/pipeline/simplify.ts","../src/pipeline/materialize-contradictions.ts","../src/pipeline/materialize.ts","../src/pipeline/warnings.ts","../src/pipeline/exclusive.ts","../src/utils/case-converter.ts","../src/utils/selector-transform.ts","../src/pipeline/parseStateKey.ts","../src/pipeline/index.ts","../src/styles/list.ts","../src/styles/base-props.ts","../src/utils/typography.ts","../src/config.ts"],"sourcesContent":["export const VALUE_KEYWORDS = new Set([\n 'auto',\n 'max-content',\n 'min-content',\n 'fit-content',\n 'stretch',\n 'initial',\n 'inherit',\n 'revert',\n 'unset',\n 'revert-layer',\n]);\n\nexport const CSS_WIDE_KEYWORDS = new Set([\n 'initial',\n 'inherit',\n 'revert',\n 'unset',\n 'revert-layer',\n]);\n\n/**\n * Color functions that *derive* a color from other colors. They take no alpha\n * channel, so opacity has to wrap the whole call in `color-mix()` instead of\n * being appended after a slash.\n */\nconst DERIVED_COLOR_FUNCS_LIST = [\n 'color-mix',\n 'color-contrast',\n 'contrast-color',\n 'light-dark',\n];\n\nexport const DERIVED_COLOR_FUNCS = new Set(DERIVED_COLOR_FUNCS_LIST);\n\n/**\n * Every color function the parser recognizes. The ones outside\n * `DERIVED_COLOR_FUNCS` take channels as arguments, optionally followed by\n * `/ <alpha>` — which is where an opacity suffix writes.\n */\nexport const COLOR_FUNCS = new Set([\n 'rgb',\n 'rgba',\n 'hsl',\n 'hsla',\n 'hwb',\n 'lab',\n 'lch',\n 'oklab',\n 'oklch',\n 'color',\n 'device-cmyk',\n 'gray',\n ...DERIVED_COLOR_FUNCS_LIST,\n]);\n\n/**\n * The one color function CSS also allows to carry non-color values, so its\n * bucket depends on the arguments: `light-dark(#dark, #light)` is a color, while\n * `light-dark(1x, 2x)` is a plain value and has to stay out of the color slot.\n */\nexport const POLYMORPHIC_COLOR_FUNC = 'light-dark';\n\n/** A value that is a single `name(args)` call: captures the name and the args. */\nexport const RE_FUNC_CALL = /^([a-z][a-z0-9-]*)\\((.+)\\)$/i;\n\nexport const RE_UNIT_NUM = /^[+-]?(?:\\d*\\.\\d+|\\d+)([a-z][a-z0-9]*)$/;\nexport const RE_NUMBER = /^[+-]?(?:\\d*\\.\\d+|\\d+)$/;\nexport const RE_HEX = /^(?:[0-9a-f]{3,4}|[0-9a-f]{6}(?:[0-9a-f]{2})?)$/;\n// Matches raw CSS unit values like \"8px\", \"1rem\", \"0.5em\" - captures number and unit separately\nexport const RE_RAW_UNIT = /^([+-]?(?:\\d*\\.\\d+|\\d+))([a-z%]+)$/;\n\nconst CANONICAL_FUNC_CASE = new Map([\n ['translatex', 'translateX'],\n ['translatey', 'translateY'],\n ['translatez', 'translateZ'],\n ['scalex', 'scaleX'],\n ['scaley', 'scaleY'],\n ['scalez', 'scaleZ'],\n ['rotatex', 'rotateX'],\n ['rotatey', 'rotateY'],\n ['rotatez', 'rotateZ'],\n ['skewx', 'skewX'],\n ['skewy', 'skewY'],\n]);\n\nexport function canonicalFuncName(lowered: string): string {\n return CANONICAL_FUNC_CASE.get(lowered) ?? lowered;\n}\n","import { RE_HEX } from '../parser/const';\n\nexport function toSnakeCase(str: string): string {\n return str.replace(/[A-Z]/g, (s) => `-${s.toLowerCase()}`);\n}\n\n/**\n * Normalize a DSL identifier to the CSS custom-property name it emits.\n *\n * CSS custom-property names are case-sensitive, so `$myVar` has to keep its\n * inner case to reference `--myVar`. A leading capital is the one exception:\n * `$Foo` is not a supported way to name a property, so the first character is\n * folded rather than kebab-cased (`--foo`, not `---foo`) and every later\n * character is left alone.\n *\n * Every place that turns a `$name` / `#name` identifier into a CSS name goes\n * through this, so authoring a token and referencing it always agree.\n */\nexport function normalizeDslName(name: string): string {\n if (!name) return name;\n\n const first = name[0];\n const lower = first.toLowerCase();\n\n return lower === first ? name : lower + name.slice(1);\n}\n\n/** A DSL identifier: `$name`, `$$name`, `#name` or `##name`. */\nconst RE_DSL_IDENTIFIER = /(\\$\\$?|##?)([a-zA-Z_][a-zA-Z0-9_-]*)/g;\n\n/**\n * Case-fold a DSL string for parsing, preserving the case of custom-property\n * names.\n *\n * Everything the parser matches on — keywords, units, modifiers, function names,\n * color-token names — is compared lowercase, so the whole string used to be\n * lowercased up front. That also folded custom-property names, which are\n * case-sensitive in CSS: `$myVar` referenced `var(--myvar)` while the token\n * definition emitted `--myVar`, so the two could never meet.\n *\n * Identifier bodies now keep their case (their first character still folds, see\n * {@link normalizeDslName}); everything else is lowercased exactly as before.\n * Hex literals are excluded — `#FF0000` is a color, not a name, and must fold to\n * match {@link RE_HEX}.\n */\nexport function foldDslCase(src: string): string {\n const folded = src.toLowerCase();\n\n // Fast paths, in the order they pay off: an input that was already lowercase\n // has no case to protect, and one without a sigil has no identifier to protect.\n // Both reduce to the single fold this replaced, so only mixed-case values that\n // actually name a custom property reach the scan below.\n if (folded === src || (!src.includes('$') && !src.includes('#'))) {\n return folded;\n }\n\n RE_DSL_IDENTIFIER.lastIndex = 0;\n\n let out = '';\n let last = 0;\n let match: RegExpExecArray | null;\n\n while ((match = RE_DSL_IDENTIFIER.exec(src))) {\n const [whole, prefix, body] = match;\n\n out += src.slice(last, match.index).toLowerCase();\n out +=\n prefix +\n (prefix[0] === '#' && RE_HEX.test(body.toLowerCase())\n ? body.toLowerCase()\n : normalizeDslName(body));\n last = match.index + whole.length;\n }\n\n return out + src.slice(last).toLowerCase();\n}\n","/**\n * Consolidated color conversion math.\n *\n * Single source of truth for all color space conversions used across the\n * library: sRGB gamma, HSL, OKLab, OKLCH, OKHSL, hex parsing, named\n * colors, and CSS string converters.\n *\n * This module has zero internal imports — it is a leaf dependency.\n *\n * Reference: https://bottosson.github.io/posts/oklab/\n */\n\n// ============================================================================\n// Types\n// ============================================================================\n\ntype Vec3 = [number, number, number];\n\n// ============================================================================\n// Conversion Matrices\n// ============================================================================\n\nconst OKLab_to_LMS_M: Vec3[] = [\n [1.0, 0.3963377773761749, 0.2158037573099136],\n [1.0, -0.1055613458156586, -0.0638541728258133],\n [1.0, -0.0894841775298119, -1.2914855480194092],\n];\n\nconst LMS_to_linear_sRGB_M: Vec3[] = [\n [4.076741636075959, -3.307711539258062, 0.2309699031821041],\n [-1.2684379732850313, 2.6097573492876878, -0.3413193760026569],\n [-0.004196076138675526, -0.703418617935936, 1.7076146940746113],\n];\n\nconst OKLab_to_linear_sRGB_coefficients: [\n [[number, number], number[]],\n [[number, number], number[]],\n [[number, number], number[]],\n] = [\n [\n [-1.8817030993265873, -0.8093650129914302],\n [1.19086277, 1.76576728, 0.59662641, 0.75515197, 0.56771245],\n ],\n [\n [1.8144407988010998, -1.194452667805235],\n [0.73956515, -0.45954404, 0.08285427, 0.1254107, 0.14503204],\n ],\n [\n [0.13110757611180954, 1.813339709266608],\n [1.35733652, -0.00915799, -1.1513021, -0.50559606, 0.00692167],\n ],\n];\n\n// ============================================================================\n// Linear Algebra Helpers\n// ============================================================================\n\nconst dotXY = (a: [number, number], b: [number, number]): number =>\n a[0] * b[0] + a[1] * b[1];\n\n// ============================================================================\n// sRGB Gamma <-> Linear\n// ============================================================================\n\n/**\n * sRGB gamma to linear. Only the sRGB-to-OKLab direction needs it, so this is\n * test-only for the same reason as {@link srgbToOkhsl} — the forward path goes\n * through {@link srgbLinearToGamma} instead.\n */\nexport function srgbToLinear(c: number): number {\n return c <= 0.04045 ? c / 12.92 : ((c + 0.055) / 1.055) ** 2.4;\n}\n\nconst INV_GAMMA = 1 / 2.4;\n\nexport function srgbLinearToGamma(val: number): number {\n const sign = val < 0 ? -1 : 1;\n const abs = Math.abs(val);\n return abs > 0.0031308\n ? sign * (1.055 * abs ** INV_GAMMA - 0.055)\n : 12.92 * val;\n}\n\n// ============================================================================\n// OKHSL Constants & Helpers\n// ============================================================================\n\nconst TAU = 2 * Math.PI;\nconst K1 = 0.206;\nconst K2 = 0.03;\nconst K3 = (1.0 + K1) / (1.0 + K2);\nconst EPSILON = 1e-10;\n\nconst clamp = (value: number, min: number, max: number): number =>\n Math.max(Math.min(value, max), min);\n\nconst constrainAngle = (angle: number): number => ((angle % 360) + 360) % 360;\n\nconst toe = (x: number): number =>\n 0.5 *\n (K3 * x - K1 + Math.sqrt((K3 * x - K1) * (K3 * x - K1) + 4 * K2 * K3 * x));\n\nconst toeInv = (x: number): number => (x ** 2 + K1 * x) / (K3 * (x + K2));\n\n// ============================================================================\n// OKHST Tone Transfers\n// ============================================================================\n\nconst OKHST_REF_EPS = 0.05;\n\nfunction lToY(l: number): number {\n const L = toeInv(l);\n return L * L * L;\n}\n\nfunction yToL(y: number): number {\n return toe(Math.cbrt(Math.max(0, y)));\n}\n\nfunction toneFromY(y: number, eps: number = OKHST_REF_EPS): number {\n const num = Math.log(y + eps) - Math.log(eps);\n const den = Math.log(1 + eps) - Math.log(eps);\n return (num / den) * 100;\n}\n\nfunction yFromTone(t: number, eps: number = OKHST_REF_EPS): number {\n const den = Math.log(1 + eps) - Math.log(eps);\n return Math.exp((t / 100) * den + Math.log(eps)) - eps;\n}\n\n/**\n * Lightness to OKHST tone — the reverse of {@link fromTone}, which is the\n * direction `okhst()` uses. Kept for the same reason as {@link srgbToOkhsl},\n * and kept out of the build the same way: it lets the forward transfer be\n * round-tripped in tests, and `scripts/check-test-only-code.mjs` verifies it\n * never reaches an emitted file.\n */\nexport function toTone(l: number, eps: number = OKHST_REF_EPS): number {\n return toneFromY(lToY(l), eps);\n}\n\nexport function fromTone(t: number, eps: number = OKHST_REF_EPS): number {\n return yToL(yFromTone(t, eps));\n}\n\n// ============================================================================\n// OKLab <-> Linear sRGB\n// ============================================================================\n\nconst oklabToLinearSrgb = (lab: Vec3): Vec3 => {\n const L = lab[0];\n const a = lab[1];\n const b = lab[2];\n\n // OKLab -> LMS (inlined OKLab_to_LMS_M multiply)\n const l_ = L + 0.3963377773761749 * a + 0.2158037573099136 * b;\n const m_ = L - 0.1055613458156586 * a - 0.0638541728258133 * b;\n const s_ = L - 0.0894841775298119 * a - 1.2914855480194092 * b;\n\n // Cube\n const l = l_ * l_ * l_;\n const m = m_ * m_ * m_;\n const s = s_ * s_ * s_;\n\n // LMS -> linear sRGB (inlined LMS_to_linear_sRGB_M multiply)\n return [\n 4.076741636075959 * l - 3.307711539258062 * m + 0.2309699031821041 * s,\n -1.2684379732850313 * l + 2.6097573492876878 * m - 0.3413193760026569 * s,\n -0.004196076138675526 * l - 0.703418617935936 * m + 1.7076146940746113 * s,\n ];\n};\n\nconst linearSrgbToOklab = (rgb: Vec3): Vec3 => {\n const r = rgb[0];\n const g = rgb[1];\n const b = rgb[2];\n\n // linear sRGB -> LMS (inlined linear_sRGB_to_LMS_M multiply)\n const l = 0.4122214708 * r + 0.5363325363 * g + 0.0514459929 * b;\n const m = 0.2119034982 * r + 0.6806995451 * g + 0.1073969566 * b;\n const s = 0.0883024619 * r + 0.2817188376 * g + 0.6299787005 * b;\n\n // Cube root\n const l_ = Math.cbrt(l);\n const m_ = Math.cbrt(m);\n const s_ = Math.cbrt(s);\n\n // LMS -> OKLab (inlined LMS_to_OKLab_M multiply)\n return [\n 0.2104542553 * l_ + 0.793617785 * m_ - 0.0040720468 * s_,\n 1.9779984951 * l_ - 2.428592205 * m_ + 0.4505937099 * s_,\n 0.0259040371 * l_ + 0.7827717662 * m_ - 0.808675766 * s_,\n ];\n};\n\n// ============================================================================\n// OKHSL Gamut-Mapping Internals\n// ============================================================================\n\nconst computeMaxSaturationOKLC = (a: number, b: number): number => {\n const okCoeff = OKLab_to_linear_sRGB_coefficients;\n const lmsToRgb = LMS_to_linear_sRGB_M;\n const tmp2: [number, number] = [a, b];\n const tmp3: Vec3 = [0, a, b];\n\n let chnlCoeff: number[];\n let chnlLMS: Vec3;\n\n if (dotXY(okCoeff[0][0], tmp2) > 1) {\n chnlCoeff = okCoeff[0][1];\n chnlLMS = lmsToRgb[0];\n } else if (dotXY(okCoeff[1][0], tmp2) > 1) {\n chnlCoeff = okCoeff[1][1];\n chnlLMS = lmsToRgb[1];\n } else {\n chnlCoeff = okCoeff[2][1];\n chnlLMS = lmsToRgb[2];\n }\n\n const [k0, k1, k2, k3, k4] = chnlCoeff;\n const [wl, wm, ws] = chnlLMS;\n\n let sat = k0 + k1 * a + k2 * b + k3 * (a * a) + k4 * a * b;\n\n const dotYZ = (mat: Vec3, vec: Vec3): number =>\n mat[1] * vec[1] + mat[2] * vec[2];\n\n const kl = dotYZ(OKLab_to_LMS_M[0], tmp3);\n const km = dotYZ(OKLab_to_LMS_M[1], tmp3);\n const ks = dotYZ(OKLab_to_LMS_M[2], tmp3);\n\n const l_ = 1.0 + sat * kl;\n const m_ = 1.0 + sat * km;\n const s_ = 1.0 + sat * ks;\n\n const l = l_ ** 3;\n const m = m_ ** 3;\n const s = s_ ** 3;\n\n const lds = 3.0 * kl * (l_ * l_);\n const mds = 3.0 * km * (m_ * m_);\n const sds = 3.0 * ks * (s_ * s_);\n\n const lds2 = 6.0 * (kl * kl) * l_;\n const mds2 = 6.0 * (km * km) * m_;\n const sds2 = 6.0 * (ks * ks) * s_;\n\n const f = wl * l + wm * m + ws * s;\n const f1 = wl * lds + wm * mds + ws * sds;\n const f2 = wl * lds2 + wm * mds2 + ws * sds2;\n\n sat = sat - (f * f1) / (f1 * f1 - 0.5 * f * f2);\n\n return sat;\n};\n\nconst findCuspOKLCH = (a: number, b: number): [number, number] => {\n const S_cusp = computeMaxSaturationOKLC(a, b);\n const lab: Vec3 = [1, S_cusp * a, S_cusp * b];\n const rgb_at_max = oklabToLinearSrgb(lab);\n const L_cusp = Math.cbrt(\n 1 /\n Math.max(\n Math.max(rgb_at_max[0], rgb_at_max[1]),\n Math.max(rgb_at_max[2], 0.0),\n ),\n );\n return [L_cusp, L_cusp * S_cusp];\n};\n\nconst findGamutIntersectionOKLCH = (\n a: number,\n b: number,\n l1: number,\n c1: number,\n l0: number,\n cusp: [number, number],\n): number => {\n const lmsToRgb = LMS_to_linear_sRGB_M;\n const tmp3: Vec3 = [0, a, b];\n const floatMax = Number.MAX_VALUE;\n\n let t: number;\n\n const dotYZ = (mat: Vec3, vec: Vec3): number =>\n mat[1] * vec[1] + mat[2] * vec[2];\n const dotXYZ = (vec: Vec3, x: number, y: number, z: number): number =>\n vec[0] * x + vec[1] * y + vec[2] * z;\n\n if ((l1 - l0) * cusp[1] - (cusp[0] - l0) * c1 <= 0.0) {\n const denom = c1 * cusp[0] + cusp[1] * (l0 - l1);\n t = denom === 0 ? 0 : (cusp[1] * l0) / denom;\n } else {\n const denom = c1 * (cusp[0] - 1.0) + cusp[1] * (l0 - l1);\n t = denom === 0 ? 0 : (cusp[1] * (l0 - 1.0)) / denom;\n\n const dl = l1 - l0;\n const dc = c1;\n\n const kl = dotYZ(OKLab_to_LMS_M[0], tmp3);\n const km = dotYZ(OKLab_to_LMS_M[1], tmp3);\n const ks = dotYZ(OKLab_to_LMS_M[2], tmp3);\n\n const ldt_ = dl + dc * kl;\n const mdt_ = dl + dc * km;\n const sdt_ = dl + dc * ks;\n\n const L = l0 * (1.0 - t) + t * l1;\n const C = t * c1;\n\n const l_ = L + C * kl;\n const m_ = L + C * km;\n const s_ = L + C * ks;\n\n const l = l_ ** 3;\n const m = m_ ** 3;\n const s = s_ ** 3;\n\n const ldt = 3 * ldt_ * l_ * l_;\n const mdt = 3 * mdt_ * m_ * m_;\n const sdt = 3 * sdt_ * s_ * s_;\n\n const ldt2 = 6 * ldt_ * ldt_ * l_;\n const mdt2 = 6 * mdt_ * mdt_ * m_;\n const sdt2 = 6 * sdt_ * sdt_ * s_;\n\n const r_ = dotXYZ(lmsToRgb[0], l, m, s) - 1;\n const r1 = dotXYZ(lmsToRgb[0], ldt, mdt, sdt);\n const r2 = dotXYZ(lmsToRgb[0], ldt2, mdt2, sdt2);\n\n const ur = r1 / (r1 * r1 - 0.5 * r_ * r2);\n let tr = -r_ * ur;\n\n const g_ = dotXYZ(lmsToRgb[1], l, m, s) - 1;\n const g1 = dotXYZ(lmsToRgb[1], ldt, mdt, sdt);\n const g2 = dotXYZ(lmsToRgb[1], ldt2, mdt2, sdt2);\n\n const ug = g1 / (g1 * g1 - 0.5 * g_ * g2);\n let tg = -g_ * ug;\n\n const b_ = dotXYZ(lmsToRgb[2], l, m, s) - 1;\n const b1 = dotXYZ(lmsToRgb[2], ldt, mdt, sdt);\n const b2 = dotXYZ(lmsToRgb[2], ldt2, mdt2, sdt2);\n\n const ub = b1 / (b1 * b1 - 0.5 * b_ * b2);\n let tb = -b_ * ub;\n\n tr = ur >= 0.0 ? tr : floatMax;\n tg = ug >= 0.0 ? tg : floatMax;\n tb = ub >= 0.0 ? tb : floatMax;\n\n t += Math.min(tr, Math.min(tg, tb));\n }\n\n return t;\n};\n\nconst computeSt = (cusp: [number, number]): [number, number] => [\n cusp[1] / cusp[0],\n cusp[1] / (1 - cusp[0]),\n];\n\nconst computeStMid = (a: number, b: number): [number, number] => [\n 0.11516993 +\n 1.0 /\n (7.4477897 +\n 4.1590124 * b +\n a *\n (-2.19557347 +\n 1.75198401 * b +\n a *\n (-2.13704948 -\n 10.02301043 * b +\n a * (-4.24894561 + 5.38770819 * b + 4.69891013 * a)))),\n 0.11239642 +\n 1.0 /\n (1.6132032 -\n 0.68124379 * b +\n a *\n (0.40370612 +\n 0.90148123 * b +\n a *\n (-0.27087943 +\n 0.6122399 * b +\n a * (0.00299215 - 0.45399568 * b - 0.14661872 * a)))),\n];\n\nconst getCs = (\n L: number,\n a: number,\n b: number,\n cusp: [number, number],\n): [number, number, number] => {\n const cMax = findGamutIntersectionOKLCH(a, b, L, 1, L, cusp);\n const stMax = computeSt(cusp);\n const k = cMax / Math.min(L * stMax[0], (1 - L) * stMax[1]);\n const stMid = computeStMid(a, b);\n let ca = L * stMid[0];\n let cb = (1.0 - L) * stMid[1];\n const cMid =\n 0.9 * k * Math.sqrt(Math.sqrt(1.0 / (1.0 / ca ** 4 + 1.0 / cb ** 4)));\n ca = L * 0.4;\n cb = (1.0 - L) * 0.8;\n const c0 = Math.sqrt(1.0 / (1.0 / ca ** 2 + 1.0 / cb ** 2));\n return [c0, cMid, cMax];\n};\n\nconst okhslToOklab = (hsl: Vec3): Vec3 => {\n let h = hsl[0];\n const s = hsl[1];\n const l = hsl[2];\n\n const L = toeInv(l);\n let a = 0;\n let b = 0;\n\n h = constrainAngle(h) / 360.0;\n\n if (L !== 0.0 && L !== 1.0 && s !== 0) {\n const a_ = Math.cos(TAU * h);\n const b_ = Math.sin(TAU * h);\n\n const cusp = findCuspOKLCH(a_, b_);\n const Cs = getCs(L, a_, b_, cusp);\n const [c0, cMid, cMax] = Cs;\n\n const mid = 0.8;\n const midInv = 1.25;\n let t: number, k0: number, k1: number, k2: number;\n\n if (s < mid) {\n t = midInv * s;\n k0 = 0.0;\n k1 = mid * c0;\n k2 = 1.0 - k1 / cMid;\n } else {\n t = 5 * (s - 0.8);\n k0 = cMid;\n k1 = (0.2 * cMid ** 2 * 1.25 ** 2) / c0;\n k2 = 1.0 - k1 / (cMax - cMid);\n }\n\n const c = k0 + (t * k1) / (1.0 - k2 * t);\n a = c * a_;\n b = c * b_;\n }\n\n return [L, a, b];\n};\n\nconst oklabToOkhsl = (lab: Vec3): Vec3 => {\n const L = lab[0];\n const a = lab[1];\n const b = lab[2];\n\n const C = Math.sqrt(a * a + b * b);\n\n if (C < EPSILON) {\n return [0, 0, toe(L)];\n }\n\n const a_ = a / C;\n const b_ = b / C;\n\n let h = Math.atan2(b, a) * (180 / Math.PI);\n h = constrainAngle(h);\n\n const cusp = findCuspOKLCH(a_, b_);\n const Cs = getCs(L, a_, b_, cusp);\n const [c0, cMid, cMax] = Cs;\n\n const mid = 0.8;\n const midInv = 1.25;\n\n let s: number;\n\n if (C < cMid) {\n const k1 = mid * c0;\n const k2 = 1.0 - k1 / cMid;\n const t = C / (k1 + C * k2);\n s = t / midInv;\n } else {\n const k0 = cMid;\n const k1 = (0.2 * cMid ** 2 * 1.25 ** 2) / c0;\n const k2 = 1.0 - k1 / (cMax - cMid);\n const cDiff = C - k0;\n const t = cDiff / (k1 + cDiff * k2);\n s = mid + t / 5;\n }\n\n const l = toe(L);\n\n return [h, clamp(s, 0, 1), clamp(l, 0, 1)];\n};\n\n// ============================================================================\n// Public Conversions — Pure Math (Vec3 in / Vec3 out)\n// ============================================================================\n\n/**\n * HSL to RGB.\n * Algorithm from CSS Color 4 spec.\n *\n * @param h - Hue in degrees (0-360)\n * @param s - Saturation (0-1)\n * @param l - Lightness (0-1)\n * @returns RGB values in 0-255 range (may have fractional values)\n */\nexport function hslToRgbValues(h: number, s: number, l: number): Vec3 {\n const a = s * Math.min(l, 1 - l);\n\n const f = (n: number): number => {\n const k = (n + h / 30) % 12;\n return l - a * Math.max(-1, Math.min(k - 3, 9 - k, 1));\n };\n\n return [f(0) * 255, f(8) * 255, f(4) * 255];\n}\n\n/**\n * OKHSL to sRGB (0-1 range).\n * @param h - Hue in degrees (0-360)\n * @param s - Saturation (0-1)\n * @param l - Lightness (0-1)\n * @returns sRGB values in 0-1 range, clamped to gamut\n */\nexport function okhslToSrgb(h: number, s: number, l: number): Vec3 {\n const oklab = okhslToOklab([h, s, l]);\n const linearRGB = oklabToLinearSrgb(oklab);\n\n return [\n clamp(srgbLinearToGamma(linearRGB[0]), 0, 1),\n clamp(srgbLinearToGamma(linearRGB[1]), 0, 1),\n clamp(srgbLinearToGamma(linearRGB[2]), 0, 1),\n ];\n}\n\n/**\n * OKHST to sRGB (0-1 range).\n * @param h - Hue in degrees (0-360)\n * @param s - Saturation (0-1)\n * @param t - Tone (0-1)\n * @returns sRGB values in 0-1 range, clamped to gamut\n */\nexport function okhstToSrgb(h: number, s: number, t: number): Vec3 {\n return okhslToSrgb(h, clamp(s, 0, 1), clamp(fromTone(t * 100), 0, 1));\n}\n\n/**\n * OKLCH to sRGB (0-255 range).\n * @param L - Lightness (0-1)\n * @param C - Chroma (typically 0-0.4)\n * @param H - Hue in degrees (0-360)\n * @returns RGB values in 0-255 range, clamped to gamut\n */\nexport function oklchToRgbValues(L: number, C: number, H: number): Vec3 {\n const hRad = (H * Math.PI) / 180;\n const a = C * Math.cos(hRad);\n const b = C * Math.sin(hRad);\n const linear = oklabToLinearSrgb([L, a, b]);\n\n return [\n clamp(srgbLinearToGamma(linear[0]), 0, 1) * 255,\n clamp(srgbLinearToGamma(linear[1]), 0, 1) * 255,\n clamp(srgbLinearToGamma(linear[2]), 0, 1) * 255,\n ];\n}\n\n/**\n * sRGB (0-1 range) to OKHSL.\n *\n * The reverse of {@link okhslToSrgb}, which is the direction the `okhsl()`\n * plugin uses. Nothing in the engine calls this — it exists so the forward\n * conversion can be round-tripped in tests, which checks its accuracy without\n * depending on hand-written fixtures.\n *\n * Test-only, and kept out of the build by not being reachable from any package\n * entry point. `scripts/check-test-only-code.mjs` fails the build if that ever\n * stops being true.\n *\n * @returns [H (0-360), S (0-1), L (0-1)]\n */\nexport function srgbToOkhsl(rgb: Vec3): Vec3 {\n const linear: Vec3 = [\n srgbToLinear(rgb[0]),\n srgbToLinear(rgb[1]),\n srgbToLinear(rgb[2]),\n ];\n const oklab = linearSrgbToOklab(linear);\n return oklabToOkhsl(oklab);\n}\n\n// ============================================================================\n// Named CSS Colors\n// ============================================================================\n\nlet _namedColorHex: Map<string, string> | null = null;\n\nexport function getNamedColorHex(): Map<string, string> {\n if (_namedColorHex) return _namedColorHex;\n _namedColorHex = new Map([\n ['aliceblue', '#f0f8ff'],\n ['antiquewhite', '#faebd7'],\n ['aqua', '#00ffff'],\n ['aquamarine', '#7fffd4'],\n ['azure', '#f0ffff'],\n ['beige', '#f5f5dc'],\n ['bisque', '#ffe4c4'],\n ['black', '#000000'],\n ['blanchedalmond', '#ffebcd'],\n ['blue', '#0000ff'],\n ['blueviolet', '#8a2be2'],\n ['brown', '#a52a2a'],\n ['burlywood', '#deb887'],\n ['cadetblue', '#5f9ea0'],\n ['chartreuse', '#7fff00'],\n ['chocolate', '#d2691e'],\n ['coral', '#ff7f50'],\n ['cornflowerblue', '#6495ed'],\n ['cornsilk', '#fff8dc'],\n ['crimson', '#dc143c'],\n ['cyan', '#00ffff'],\n ['darkblue', '#00008b'],\n ['darkcyan', '#008b8b'],\n ['darkgoldenrod', '#b8860b'],\n ['darkgray', '#a9a9a9'],\n ['darkgreen', '#006400'],\n ['darkgrey', '#a9a9a9'],\n ['darkkhaki', '#bdb76b'],\n ['darkmagenta', '#8b008b'],\n ['darkolivegreen', '#556b2f'],\n ['darkorange', '#ff8c00'],\n ['darkorchid', '#9932cc'],\n ['darkred', '#8b0000'],\n ['darksalmon', '#e9967a'],\n ['darkseagreen', '#8fbc8f'],\n ['darkslateblue', '#483d8b'],\n ['darkslategray', '#2f4f4f'],\n ['darkslategrey', '#2f4f4f'],\n ['darkturquoise', '#00ced1'],\n ['darkviolet', '#9400d3'],\n ['deeppink', '#ff1493'],\n ['deepskyblue', '#00bfff'],\n ['dimgray', '#696969'],\n ['dimgrey', '#696969'],\n ['dodgerblue', '#1e90ff'],\n ['firebrick', '#b22222'],\n ['floralwhite', '#fffaf0'],\n ['forestgreen', '#228b22'],\n ['fuchsia', '#ff00ff'],\n ['gainsboro', '#dcdcdc'],\n ['ghostwhite', '#f8f8ff'],\n ['gold', '#ffd700'],\n ['goldenrod', '#daa520'],\n ['gray', '#808080'],\n ['green', '#008000'],\n ['greenyellow', '#adff2f'],\n ['grey', '#808080'],\n ['honeydew', '#f0fff0'],\n ['hotpink', '#ff69b4'],\n ['indianred', '#cd5c5c'],\n ['indigo', '#4b0082'],\n ['ivory', '#fffff0'],\n ['khaki', '#f0e68c'],\n ['lavender', '#e6e6fa'],\n ['lavenderblush', '#fff0f5'],\n ['lawngreen', '#7cfc00'],\n ['lemonchiffon', '#fffacd'],\n ['lightblue', '#add8e6'],\n ['lightcoral', '#f08080'],\n ['lightcyan', '#e0ffff'],\n ['lightgoldenrodyellow', '#fafad2'],\n ['lightgray', '#d3d3d3'],\n ['lightgreen', '#90ee90'],\n ['lightgrey', '#d3d3d3'],\n ['lightpink', '#ffb6c1'],\n ['lightsalmon', '#ffa07a'],\n ['lightseagreen', '#20b2aa'],\n ['lightskyblue', '#87cefa'],\n ['lightslategray', '#778899'],\n ['lightslategrey', '#778899'],\n ['lightsteelblue', '#b0c4de'],\n ['lightyellow', '#ffffe0'],\n ['lime', '#00ff00'],\n ['limegreen', '#32cd32'],\n ['linen', '#faf0e6'],\n ['magenta', '#ff00ff'],\n ['maroon', '#800000'],\n ['mediumaquamarine', '#66cdaa'],\n ['mediumblue', '#0000cd'],\n ['mediumorchid', '#ba55d3'],\n ['mediumpurple', '#9370db'],\n ['mediumseagreen', '#3cb371'],\n ['mediumslateblue', '#7b68ee'],\n ['mediumspringgreen', '#00fa9a'],\n ['mediumturquoise', '#48d1cc'],\n ['mediumvioletred', '#c71585'],\n ['midnightblue', '#191970'],\n ['mintcream', '#f5fffa'],\n ['mistyrose', '#ffe4e1'],\n ['moccasin', '#ffe4b5'],\n ['navajowhite', '#ffdead'],\n ['navy', '#000080'],\n ['oldlace', '#fdf5e6'],\n ['olive', '#808000'],\n ['olivedrab', '#6b8e23'],\n ['orange', '#ffa500'],\n ['orangered', '#ff4500'],\n ['orchid', '#da70d6'],\n ['palegoldenrod', '#eee8aa'],\n ['palegreen', '#98fb98'],\n ['paleturquoise', '#afeeee'],\n ['palevioletred', '#db7093'],\n ['papayawhip', '#ffefd5'],\n ['peachpuff', '#ffdab9'],\n ['peru', '#cd853f'],\n ['pink', '#ffc0cb'],\n ['plum', '#dda0dd'],\n ['powderblue', '#b0e0e6'],\n ['purple', '#800080'],\n ['rebeccapurple', '#663399'],\n ['red', '#ff0000'],\n ['rosybrown', '#bc8f8f'],\n ['royalblue', '#4169e1'],\n ['saddlebrown', '#8b4513'],\n ['salmon', '#fa8072'],\n ['sandybrown', '#f4a460'],\n ['seagreen', '#2e8b57'],\n ['seashell', '#fff5ee'],\n ['sienna', '#a0522d'],\n ['silver', '#c0c0c0'],\n ['skyblue', '#87ceeb'],\n ['slateblue', '#6a5acd'],\n ['slategray', '#708090'],\n ['slategrey', '#708090'],\n ['snow', '#fffafa'],\n ['springgreen', '#00ff7f'],\n ['steelblue', '#4682b4'],\n ['tan', '#d2b48c'],\n ['teal', '#008080'],\n ['thistle', '#d8bfd8'],\n ['tomato', '#ff6347'],\n ['turquoise', '#40e0d0'],\n ['violet', '#ee82ee'],\n ['wheat', '#f5deb3'],\n ['white', '#ffffff'],\n ['whitesmoke', '#f5f5f5'],\n ['yellow', '#ffff00'],\n ['yellowgreen', '#9acd32'],\n ]);\n return _namedColorHex;\n}\n\n// ============================================================================\n// String Converters\n// ============================================================================\n\n/**\n * Convert hex color string to `rgb()` CSS string.\n * Supports 3, 4, 6, and 8 character hex values (with or without `#`).\n */\nexport function hexToRgb(hex: string): string | null {\n const matched = hex\n .replace(\n /^#?([a-f\\d])([a-f\\d])([a-f\\d])$/i,\n (_m: string, r: string, g: string, b: string) =>\n '#' + r + r + g + g + b + b,\n )\n .substring(1)\n .match(/.{2}/g);\n\n if (!matched) return null;\n\n const rgba = matched.map(\n (x: string, i: number) => parseInt(x, 16) * (i === 3 ? 1 / 255 : 1),\n );\n\n if (rgba.some((v) => Number.isNaN(v))) {\n return null;\n }\n\n if (rgba.length >= 3) {\n return `rgb(${rgba.slice(0, 3).join(' ')}${rgba.length > 3 ? ` / ${rgba[3]}` : ''})`;\n }\n\n return null;\n}\n\n/**\n * Extract RGB values from an `rgb()`/`rgba()` string.\n * Supports comma-separated, space-separated, fractional, percentage,\n * and slash alpha notation.\n *\n * @returns Array of RGB values (0-255 range), converting percentages as needed.\n */\nexport function getRgbValuesFromRgbaString(str: string): number[] {\n const match = str.match(/rgba?\\(([^)]+)\\)/i);\n if (!match) return [];\n\n const inner = match[1].trim();\n const [colorPart] = inner.split('/');\n const parts = colorPart\n .trim()\n .split(/[,\\s]+/)\n .filter(Boolean);\n\n return parts.slice(0, 3).map((part) => {\n part = part.trim();\n if (part.endsWith('%')) {\n return (parseFloat(part) / 100) * 255;\n }\n return parseFloat(part);\n });\n}\n\n/**\n * Convert any recognized color string to an `rgb()` CSS string.\n * Handles hex, `okhsl()`, `okhst()`, `hsl()`/`hsla()`, named CSS colors,\n * and `rgb()`/`rgba()` pass-through.\n */\nexport function strToRgb(\n color: string,\n _ignoreAlpha = false,\n): string | null | undefined {\n if (!color) return undefined;\n\n if (color.startsWith('rgb')) return color;\n if (color.startsWith('#')) return hexToRgb(color);\n if (color.startsWith('oklch(')) return oklchStringToRgb(color);\n if (color.startsWith('hsl')) return hslStringToRgb(color);\n\n const namedHex = getNamedColorHex().get(color.toLowerCase());\n if (namedHex) return hexToRgb(namedHex);\n\n return null;\n}\n\n/**\n * Convert an HSL/HSLA color string to an `rgb()`/`rgba()` CSS string.\n * Supports modern space-separated and legacy comma-separated syntax,\n * deg/turn/rad hue units, and slash alpha notation.\n */\nexport function hslStringToRgb(hslStr: string): string | null {\n const match = hslStr.match(/hsla?\\(([^)]+)\\)/i);\n if (!match) return null;\n\n const inner = match[1].trim();\n const [colorPart, slashAlpha] = inner.split('/');\n const parts = colorPart\n .trim()\n .split(/[,\\s]+/)\n .filter(Boolean);\n\n if (parts.length < 3) return null;\n\n const alphaPart = slashAlpha?.trim() || (parts.length >= 4 ? parts[3] : null);\n\n let h = parseFloat(parts[0]);\n const hueStr = parts[0].toLowerCase();\n if (hueStr.endsWith('turn')) h = parseFloat(hueStr) * 360;\n else if (hueStr.endsWith('rad')) h = (parseFloat(hueStr) * 180) / Math.PI;\n h = ((h % 360) + 360) % 360;\n\n const parsePercent = (val: string): number => {\n const num = parseFloat(val);\n return val.includes('%') ? num / 100 : num;\n };\n const s = Math.max(0, Math.min(1, parsePercent(parts[1])));\n const l = Math.max(0, Math.min(1, parsePercent(parts[2])));\n\n const [r, g, b] = hslToRgbValues(h, s, l);\n\n if (alphaPart) {\n const alpha = parseFloat(alphaPart.trim());\n return `rgba(${Math.round(r)}, ${Math.round(g)}, ${Math.round(b)}, ${alpha})`;\n }\n\n return `rgb(${Math.round(r)} ${Math.round(g)} ${Math.round(b)})`;\n}\n\n/**\n * Convert an `oklch()` color string to an `rgb()`/`rgba()` CSS string.\n * Supports deg/turn/rad hue units and percentage lightness.\n */\nexport function oklchStringToRgb(oklchStr: string): string | null {\n const match = oklchStr.match(/oklch\\(([^)]+)\\)/i);\n if (!match) return null;\n\n const inner = match[1].trim();\n const [colorPart, alphaPart] = inner.split('/');\n const parts = colorPart\n .trim()\n .split(/[,\\s]+/)\n .filter(Boolean);\n\n if (parts.length < 3) return null;\n\n const parsePercent = (val: string): number => {\n const num = parseFloat(val);\n return val.includes('%') ? num / 100 : num;\n };\n const L = Math.max(0, Math.min(1, parsePercent(parts[0])));\n const C = Math.max(0, parseFloat(parts[1]));\n\n let H = parseFloat(parts[2]);\n const hueStr = parts[2].toLowerCase();\n if (hueStr.endsWith('turn')) H = parseFloat(hueStr) * 360;\n else if (hueStr.endsWith('rad')) H = (parseFloat(hueStr) * 180) / Math.PI;\n else if (hueStr.endsWith('deg')) H = parseFloat(hueStr);\n\n const [r, g, b] = oklchToRgbValues(L, C, H);\n\n if (alphaPart) {\n const alpha = parseFloat(alphaPart.trim());\n return `rgba(${Math.round(r)}, ${Math.round(g)}, ${Math.round(b)}, ${alpha})`;\n }\n\n return `rgb(${Math.round(r)} ${Math.round(g)} ${Math.round(b)})`;\n}\n","/**\n * Color handling that survives into the emitted CSS.\n *\n * Tasty does not rewrite a color into a particular color space: opacity is\n * applied with CSS relative color syntax, which reads the channels off whatever\n * the browser resolves a value to, so a color is emitted exactly as authored.\n * What is left here is how an alpha gets applied, and the one distinction that\n * matters — replacing a token's alpha versus composing onto an inherited one.\n */\n\n/**\n * The color space a `#name` token's value used to be rewritten into.\n *\n * @deprecated Kept for the `colorSpace` config option, which no longer has any\n * effect. Colors are emitted as authored and opacity is always applied in\n * `oklch` through relative color syntax.\n */\nexport type ColorSpace = 'rgb' | 'hsl' | 'oklch';\n\n/**\n * Set the alpha of a whole color, replacing any it already carries.\n *\n * CSS relative color syntax is how opacity is applied to every color Tasty\n * emits. `oklch(from <color> l c h / <alpha>)` copies the channels over and\n * writes the alpha slot, which needs nothing from the color except that it *is*\n * a color: a `color-mix()`, a `light-dark()`, a `currentcolor`, a\n * `--name-color` written by hand-authored CSS that Tasty never defined — all of\n * them work, where writing into a channel slot directly would require channels\n * the engine has no way to compute.\n *\n * Alpha is *replaced*, not composed. A token holding `rgb(255 0 0 / .8)` faded\n * to `.5` is alpha `.5`. `color-mix()` against `transparent` cannot do this —\n * it would multiply the two to `.4`.\n *\n * The alpha slot takes a `<number>` or a `<percentage>`, so an opacity custom\n * property passes straight through in whichever form the author declared it.\n *\n * The space is always `oklch`, regardless of the configured {@link ColorSpace}:\n * it is unbounded, so a wide-gamut color survives the round trip that a\n * gamut-limited space would clamp, and it is the space the computed value used\n * to be reported in. Channels are copied rather than interpolated, so the polar\n * form costs nothing even for an achromatic color, whose hue is carried through\n * untouched.\n */\nexport function overrideColorAlpha(color: string, alpha: string): string {\n return `oklch(from ${color} l c h / ${alpha})`;\n}\n\n/**\n * Compose an alpha onto a color, multiplying with any it already carries.\n *\n * This is the counterpart to {@link overrideColorAlpha}, and the difference is\n * the point. A design token names a color, so fading it *sets* its alpha. But\n * `currentcolor` is the color an element **inherits**, which an ancestor may\n * already have faded — `#current.4` there means \"40% of what reaches me\", and a\n * nested `#current.18` under it composes to `.072`. Design systems build ramps\n * out of exactly that, so `#current` composes and a token replaces.\n *\n * `color-mix()` against `transparent` is what composes: mixing premultiplied\n * leaves the channels alone and multiplies the alphas. Its percentage slot takes\n * no `<number>`, so a `$prop` alpha has to be scaled — which is why an opacity\n * property used as `#current.$prop` has to hold a unitless number, where a token\n * accepts either form.\n */\nexport function mixColorAlpha(color: string, percentage: string): string {\n return `color-mix(in oklab, ${color} ${percentage}, transparent)`;\n}\n\n/**\n * Matches what {@link overrideColorAlpha} builds. The first group is greedy so a\n * nested override splits on its outermost layer.\n */\nconst RE_ALPHA_OVERRIDE = /^oklch\\(from (.+) l c h \\/ (.+)\\)$/;\n\n/**\n * Split what {@link overrideColorAlpha} builds back into the color it faded and\n * the alpha, or `null` when the value is not one of those.\n */\nexport function parseAlphaOverride(\n value: string,\n): { color: string; alpha: string } | null {\n const match = value.match(RE_ALPHA_OVERRIDE);\n\n return match ? { color: match[1], alpha: match[2] } : null;\n}\n","export enum Bucket {\n Color,\n Value,\n Mod,\n /**\n * A custom-property reference whose name ends with `-color`, e.g.\n * `$brand-color`. The suffix is the only hint the parser has, so the reference\n * is filed as a color *and* as a value: a color slot finds it, and so does a\n * handler reading `values` — otherwise `padding: '$brand-color'` would find no\n * value and silently emit its default instead.\n */\n ColorValue,\n}\n\n/**\n * A part within a group, representing a slash-separated segment.\n * For example, in `'2px solid #red / 4px'`, there are two parts:\n * - Part 0: `2px solid #red`\n * - Part 1: `4px`\n */\nexport interface StyleDetailsPart {\n mods: string[];\n values: string[];\n colors: string[];\n all: string[];\n output: string;\n}\n\n/**\n * A group of style details, representing a comma-separated segment.\n * Contains aggregated values from all parts for backward compatibility,\n * plus the structured `parts` array for handlers that need slash separation.\n */\nexport interface StyleDetails {\n input: string;\n output: string;\n /** Aggregated mods from all parts (backward compatible) */\n mods: string[];\n /** Aggregated values from all parts (backward compatible) */\n values: string[];\n /** Aggregated colors from all parts (backward compatible) */\n colors: string[];\n /** Aggregated all tokens from all parts (backward compatible) */\n all: string[];\n /** Slash-separated parts within this group */\n parts: StyleDetailsPart[];\n}\n\nexport interface ProcessedStyle {\n output: string;\n groups: StyleDetails[];\n}\n\nexport type UnitHandler = (scalar: number) => string;\n\nexport interface ParserOptions {\n functions?: Record<string, (parsed: StyleDetails[]) => string>;\n units?: Record<string, string | UnitHandler>;\n cacheSize?: number;\n}\n\nexport const makeEmptyPart = (): StyleDetailsPart => ({\n mods: [],\n values: [],\n colors: [],\n all: [],\n output: '',\n});\n\nexport const makeEmptyDetails = (): StyleDetails => ({\n input: '',\n output: '',\n mods: [],\n values: [],\n colors: [],\n all: [],\n parts: [],\n});\n\nexport const finalizePart = (p: StyleDetailsPart): StyleDetailsPart => {\n p.output = p.all.join(' ');\n return p;\n};\n\n/**\n * Aggregate parts into a StyleDetails group.\n * Combines all parts' arrays into group-level arrays for backward compatibility.\n */\nexport const finalizeGroup = (\n d: StyleDetails,\n parts: StyleDetailsPart[],\n): StyleDetails => {\n // Store parts\n d.parts = parts;\n\n // Aggregate all parts into group-level arrays\n for (const part of parts) {\n d.mods.push(...part.mods);\n d.values.push(...part.values);\n d.colors.push(...part.colors);\n d.all.push(...part.all);\n }\n\n // Join parts' outputs with ' / ' for the group output\n d.output = parts.map((p) => p.output).join(' / ');\n\n return d;\n};\n","import { getNamedColorHex } from '../utils/color-math';\nimport { mixColorAlpha, overrideColorAlpha } from '../utils/color-space';\nimport { getGlobalPredefinedTokens } from '../utils/styles';\nimport { foldDslCase } from '../utils/string';\n\nimport {\n COLOR_FUNCS,\n DERIVED_COLOR_FUNCS,\n POLYMORPHIC_COLOR_FUNC,\n RE_FUNC_CALL,\n RE_HEX,\n RE_NUMBER,\n RE_RAW_UNIT,\n RE_UNIT_NUM,\n VALUE_KEYWORDS,\n canonicalFuncName,\n} from './const';\nimport { StyleParser } from './parser';\nimport type { ParserOptions, ProcessedStyle } from './types';\nimport { Bucket } from './types';\n\n/**\n * Convert an opacity suffix to the alpha value it denotes.\n *\n * The authored digits are kept verbatim — `.07` stays `.07` rather than being\n * multiplied into `7.000000000000001%` — and a `$prop` suffix passes the\n * reference straight through, so it works whether the property holds a\n * `<number>` or a `<percentage>`. Both are what the alpha slot accepts.\n */\nfunction alphaSuffixToAlpha(rawAlpha: string): string {\n // Custom property: $disabled -> var(--disabled)\n if (rawAlpha.startsWith('$')) return `var(--${rawAlpha.slice(1)})`;\n if (rawAlpha === '0') return '0';\n\n return `.${rawAlpha}`;\n}\n\n/** Apply an opacity suffix to a color, replacing any alpha it already carries. */\nfunction fadeColor(color: string, rawAlpha: string): string {\n return overrideColorAlpha(color, alphaSuffixToAlpha(rawAlpha));\n}\n\n/**\n * Convert an opacity suffix to the percentage `color-mix()` needs, by shifting\n * the decimal point rather than multiplying: `.07` is `7%`, not the\n * `7.000000000000001%` that `parseFloat('.07') * 100` produces.\n */\nfunction alphaSuffixToPercentage(rawAlpha: string): string {\n if (rawAlpha.startsWith('$')) {\n // A mix percentage cannot be a `<number>`, so the reference has to be scaled.\n return `calc(var(--${rawAlpha.slice(1)}) * 100%)`;\n }\n if (rawAlpha === '0') return '0%';\n\n const digits = rawAlpha.length === 1 ? `${rawAlpha}0` : rawAlpha;\n const whole = String(Number(digits.slice(0, 2)));\n const fraction = digits.slice(2);\n\n return `${fraction ? `${whole}.${fraction}` : whole}%`;\n}\n\n/**\n * Apply an opacity suffix to `currentcolor`, composing with any alpha an\n * ancestor already applied. See {@link mixColorAlpha} for why this differs from\n * how a token is faded.\n */\nfunction fadeCurrentColor(rawAlpha: string): string {\n return mixColorAlpha('currentcolor', alphaSuffixToPercentage(rawAlpha));\n}\n\n/**\n * Whether parsed function arguments hold a color. Colors reach either the color\n * bucket (`#token`, a nested color function, `transparent`) or — for the CSS\n * named colors, which the parser has no token syntax for — the modifier bucket.\n */\nfunction hasColorArgs(parsed: ProcessedStyle): boolean {\n const namedColors = getNamedColorHex();\n\n return parsed.groups.some(\n (group) =>\n group.colors.length > 0 || group.mods.some((mod) => namedColors.has(mod)),\n );\n}\n\n/**\n * Re-parses a value through the parser until it stabilizes (no changes)\n * or max iterations reached. This allows units to reference other units.\n * Example: { x: '8px', y: '2x' } -> '1y' resolves to '16px'\n */\nfunction resolveUntilStable(\n value: string,\n opts: ParserOptions,\n recurse: (str: string) => ProcessedStyle,\n maxIterations = 10,\n): string {\n let current = value;\n for (let i = 0; i < maxIterations; i++) {\n // Check if the current value contains a custom unit that needs resolution\n const unitMatch = current.match(RE_UNIT_NUM);\n if (!unitMatch) break; // Not a unit number, no resolution needed\n\n const unitName = unitMatch[1];\n // Only recurse if the unit is a custom unit we know about\n // Any unit not in opts.units is assumed to be a native CSS unit\n if (!opts.units || !(unitName in opts.units)) break;\n\n const result = recurse(current);\n if (result.output === current) break; // Stable\n current = result.output;\n }\n return current;\n}\n\nexport function classify(\n raw: string,\n opts: ParserOptions,\n recurse: (str: string) => ProcessedStyle,\n): { bucket: Bucket; processed: string } {\n const token = raw.trim();\n if (!token) return { bucket: Bucket.Mod, processed: '' };\n\n // Early-out: if the token contains unmatched parentheses treat it as invalid\n // and skip it. This avoids cases like `drop-shadow(` that are missing a\n // closing parenthesis (e.g., a user-typo in CSS). We count paren depth while\n // ignoring everything inside string literals to avoid false positives.\n {\n let depth = 0;\n let inQuote: string | 0 = 0;\n for (let i = 0; i < token.length; i++) {\n const ch = token[i];\n\n // track quote context so parentheses inside quotes are ignored\n if (inQuote) {\n if (ch === inQuote && token[i - 1] !== '\\\\') inQuote = 0;\n continue;\n }\n if (ch === '\"' || ch === \"'\") {\n inQuote = ch;\n continue;\n }\n\n if (ch === '(') depth++;\n else if (ch === ')') depth = Math.max(0, depth - 1);\n }\n\n if (depth !== 0) {\n // Unbalanced parens → treat as invalid token (skipped).\n if (process.env.NODE_ENV !== 'production') {\n console.warn(\n '[Tasty] skipped invalid function token with unmatched parentheses:',\n token,\n );\n }\n return { bucket: Bucket.Mod, processed: '' };\n }\n }\n\n // Quoted string literals should be treated as value tokens (e.g., \"\" for content)\n if (\n (token.startsWith('\"') && token.endsWith('\"')) ||\n (token.startsWith(\"'\") && token.endsWith(\"'\"))\n ) {\n return { bucket: Bucket.Value, processed: token };\n }\n\n // 0. Double prefix for literal CSS property names ($$name -> --name, ##name -> --name-color)\n // Used in transitions and animations to reference the property name itself, not its value.\n // Also supports custom @function invocation: $$name(args) -> --name(processed args).\n if (token.startsWith('$$')) {\n const rest = token.slice(2);\n const openIdx = rest.indexOf('(');\n if (openIdx > 0 && rest.endsWith(')')) {\n const fname = rest.slice(0, openIdx);\n if (/^[a-z_][a-z0-9-_]*$/i.test(fname)) {\n const inner = rest.slice(openIdx + 1, -1).trim();\n const cssName = `--${fname}`;\n // @function polyfill: when a compiled closure is registered for this\n // function, inline the call into plain CSS instead of emitting the\n // (limited-support) native `--name(...)` call.\n if (opts.functions && cssName in opts.functions) {\n const groups = inner\n ? new StyleParser(opts).process(inner).groups\n : [];\n const funcResult = opts.functions[cssName](groups);\n // Empty result signals a recursion-cycle bail: leave the call as-is.\n if (funcResult !== '') {\n return classify(\n funcResult,\n { ...opts, functions: undefined },\n recurse,\n );\n }\n }\n const args = inner ? recurse(inner).output : '';\n return { bucket: Bucket.Value, processed: `--${fname}(${args})` };\n }\n }\n if (/^[a-z_][a-z0-9-_]*$/i.test(rest)) {\n return { bucket: Bucket.Value, processed: `--${rest}` };\n }\n }\n if (token.startsWith('##')) {\n const rest = token.slice(2);\n const openIdx = rest.indexOf('(');\n if (openIdx > 0 && rest.endsWith(')')) {\n const fname = rest.slice(0, openIdx);\n if (/^[a-z_][a-z0-9-_]*$/i.test(fname)) {\n const inner = rest.slice(openIdx + 1, -1).trim();\n const args = inner ? recurse(inner).output : '';\n return { bucket: Bucket.Value, processed: `--${fname}-color(${args})` };\n }\n }\n if (/^[a-z_][a-z0-9-_]*$/i.test(rest)) {\n return { bucket: Bucket.Value, processed: `--${rest}-color` };\n }\n }\n\n // 0b. Special handling for #current (reserved keyword, cannot be overridden by\n // predefined tokens).\n //\n // `#current` resolves through `--current-color` rather than to the\n // `currentcolor` keyword directly. The variable is registered with\n // `initial-value: currentcolor`, so where nothing publishes it the two are\n // indistinguishable — it resolves per element exactly as the keyword does.\n // Where a `color` style *has* published it, the variable holds a concrete\n // color, and that is the difference that matters: a token defined as\n // `#current` can then be faded, because `oklch(from <concrete> l c h / a)`\n // works from Safari 16.4 while `oklch(from currentcolor …)` needs Safari 18.\n if (token === '#current') {\n return { bucket: Bucket.Color, processed: 'var(--current-color)' };\n }\n\n // #current with opacity: #current.5 or #current.$opacity\n //\n // Deliberately keeps the `currentcolor` keyword rather than the variable.\n // `color-mix()` *composes*, so a nested fade has to read the already-faded\n // color that reaches it — `#current.4` with `#current.18` under it lands at\n // `.072`. The keyword resolves to that faded color at each element; the\n // variable would carry the outer fade's own operand and mix it a second time.\n // `color-mix()` with `currentcolor` has worked since Safari 16.2 regardless.\n const currentAlphaMatch = token.match(\n /^#current\\.(\\$[a-z_][a-z0-9-_]*|[0-9]+)$/i,\n );\n if (currentAlphaMatch) {\n return {\n bucket: Bucket.Color,\n processed: fadeCurrentColor(currentAlphaMatch[1]),\n };\n }\n\n // 0c. Check for predefined tokens (configured via configure({ replaceTokens: {...} }))\n // Must happen before default $ and # handling to allow overriding\n if (token[0] === '$' || token[0] === '#') {\n const predefinedTokens = getGlobalPredefinedTokens();\n if (predefinedTokens) {\n // Exact match. Keys are stored lowercase, and token names are matched\n // case-insensitively even though the name they *emit* keeps its case.\n const lookupKey = token.toLowerCase();\n if (lookupKey in predefinedTokens) {\n const tokenValue = predefinedTokens[lookupKey];\n // Fold the token value the same way the parser folds its input.\n return classify(foldDslCase(tokenValue), opts, recurse);\n }\n // Check for color token with alpha suffix: #token.alpha or #token.$prop\n if (token[0] === '#') {\n const alphaMatch = token.match(\n /^(#[a-z0-9-]+)\\.(\\$[a-z_][a-z0-9-_]*|[0-9]+)$/i,\n );\n if (alphaMatch) {\n const [, baseToken, rawAlpha] = alphaMatch;\n const baseKey = baseToken.toLowerCase();\n if (baseKey in predefinedTokens) {\n const resolvedValue = predefinedTokens[baseKey];\n\n // If resolved value starts with # (color token), use standard alpha syntax\n if (resolvedValue.startsWith('#')) {\n // Fold to match parser behavior\n return classify(\n `${foldDslCase(resolvedValue)}.${rawAlpha}`,\n opts,\n recurse,\n );\n }\n\n // For color functions like rgb(), rgba(), hsl(), hwb(), etc., inject alpha.\n // This covers all standard CSS color functions plus any custom color\n // function registered as a parse function (e.g. okhsl/okhst via plugins),\n // so no function name is hardcoded here.\n const funcMatch = resolvedValue.match(RE_FUNC_CALL);\n if (funcMatch) {\n const [, funcName, args] = funcMatch;\n const lowerFunc = funcName.toLowerCase();\n\n // A derived color function (color-mix, light-dark, …) has no alpha\n // channel to write into, so opacity is applied to the whole call\n // the same way `#current.5` is.\n if (DERIVED_COLOR_FUNCS.has(lowerFunc)) {\n const resolved = classify(\n foldDslCase(resolvedValue),\n opts,\n recurse,\n );\n\n return {\n bucket: Bucket.Color,\n processed: fadeColor(resolved.processed, rawAlpha),\n };\n }\n const isCustomFunc = !!(\n opts.functions &&\n lowerFunc in opts.functions &&\n !COLOR_FUNCS.has(lowerFunc) &&\n !COLOR_FUNCS.has(funcName.replace(/a$/i, '').toLowerCase())\n );\n // Native color function name with the legacy 'a' suffix dropped\n // (rgba->rgb, hsla->hsl). Custom functions keep their original name.\n const normalizedFunc = isCustomFunc\n ? lowerFunc\n : funcName.replace(/a$/i, '').toLowerCase();\n // Only treat as a color function if it is a native CSS color\n // function or a registered custom parse function. Otherwise the\n // resolved value is some other function call and alpha injection\n // does not apply.\n const isColorFunc =\n COLOR_FUNCS.has(normalizedFunc) ||\n COLOR_FUNCS.has(lowerFunc) ||\n isCustomFunc;\n if (!isColorFunc) {\n return classify(`${resolvedValue}.${rawAlpha}`, opts, recurse);\n }\n // Handle $prop syntax for custom property alpha\n let alpha: string;\n if (rawAlpha.startsWith('$')) {\n const propName = rawAlpha.slice(1);\n alpha = `var(--${propName})`;\n } else {\n alpha = rawAlpha === '0' ? '0' : `.${rawAlpha}`;\n }\n // Normalize to modern syntax: replace top-level commas with spaces\n // Preserves commas inside nested functions like min(), max(), clamp()\n const normalizeArgs = (a: string) => {\n let result = '';\n let depth = 0;\n for (let i = 0; i < a.length; i++) {\n const c = a[i];\n if (c === '(') {\n depth++;\n result += c;\n } else if (c === ')') {\n depth = Math.max(0, depth - 1);\n result += c;\n } else if (c === ',' && depth === 0) {\n // Skip comma and any following whitespace at top level\n while (i + 1 < a.length && /\\s/.test(a[i + 1])) i++;\n result += ' ';\n } else {\n result += c;\n }\n }\n return result;\n };\n // Helper: find last top-level occurrence of a character (ignores parentheses)\n const findLastTopLevel = (str: string, ch: string) => {\n let depth = 0;\n for (let i = str.length - 1; i >= 0; i--) {\n const c = str[i];\n if (c === ')') depth++;\n else if (c === '(') depth = Math.max(0, depth - 1);\n else if (c === ch && depth === 0) return i;\n }\n return -1;\n };\n\n // Check if already has alpha:\n // - Modern syntax: has `/` separator at top level (works with dynamic alpha like var()/calc())\n // - Legacy syntax: function ends with 'a' (rgba, hsla) and has exactly 4 top-level comma-separated values\n const slashIdx = findLastTopLevel(args, '/');\n const hasModernAlpha = slashIdx !== -1;\n\n // Count top-level commas to avoid commas inside nested functions\n let topLevelCommaCount = 0;\n let lastTopLevelComma = -1;\n {\n let depth = 0;\n for (let i = 0; i < args.length; i++) {\n const c = args[i];\n if (c === '(') depth++;\n else if (c === ')') depth = Math.max(0, depth - 1);\n else if (c === ',' && depth === 0) {\n topLevelCommaCount++;\n lastTopLevelComma = i;\n }\n }\n }\n\n const hasLegacyAlpha =\n !hasModernAlpha &&\n /a$/i.test(funcName) &&\n topLevelCommaCount === 3;\n\n const colorArgs =\n hasModernAlpha || hasLegacyAlpha\n ? normalizeArgs(\n hasModernAlpha\n ? args.slice(0, slashIdx).trim()\n : args.slice(0, lastTopLevelComma).trim(),\n )\n : normalizeArgs(args);\n\n const constructed = `${normalizedFunc}(${colorArgs} / ${alpha})`;\n\n // Custom functions (not native CSS) must be re-classified\n // so the function handler can convert them to valid CSS\n if (\n !COLOR_FUNCS.has(normalizedFunc) &&\n opts.functions &&\n normalizedFunc in opts.functions\n ) {\n return classify(constructed, opts, recurse);\n }\n\n return { bucket: Bucket.Color, processed: constructed };\n }\n\n // Fallback: try appending .alpha (may not work for all cases)\n return classify(`${resolvedValue}.${rawAlpha}`, opts, recurse);\n }\n }\n }\n }\n }\n\n // 0. Direct var(--*-color) token\n const varColorMatch = token.match(/^var\\(--([a-zA-Z0-9-]+)-color\\)$/);\n if (varColorMatch) {\n return { bucket: Bucket.Color, processed: token };\n }\n\n // 1. URL\n if (token.startsWith('url(')) {\n return { bucket: Bucket.Value, processed: token };\n }\n\n // 2. Custom property\n if (token[0] === '$') {\n const identMatch = token.match(/^\\$([a-z_][a-zA-Z0-9-_]*)$/);\n if (identMatch) {\n const name = identMatch[1];\n const processed = `var(--${name})`;\n const bucketType = name.endsWith('-color')\n ? Bucket.ColorValue\n : Bucket.Value;\n return {\n bucket: bucketType,\n processed,\n };\n }\n // invalid custom property → modifier\n }\n\n // 3. Hash colors (with optional alpha suffix e.g., #purple.5 or #purple.$disabled)\n if (token[0] === '#' && token.length > 1) {\n // alpha form: #name.alpha or #name.$prop\n const alphaMatch = token.match(\n /^#([a-z0-9-]+)\\.(\\$[a-z_][a-z0-9-_]*|[0-9]+)$/i,\n );\n if (alphaMatch) {\n const [, base, rawAlpha] = alphaMatch;\n\n // Opacity applies to the color variable as a whole. The token may hold\n // anything a `<color>` can be — including a `color-mix()` or a\n // `light-dark()` with no channels to decompose, or a value written\n // straight into `--name-color` by hand-authored CSS that Tasty never\n // defined — and relative color syntax fades all of them.\n return {\n bucket: Bucket.Color,\n processed: fadeColor(`var(--${base}-color)`, rawAlpha),\n };\n }\n\n // hyphenated names like #dark-05 should keep full name\n\n const name = token.slice(1);\n // valid hex → treat as hex literal with fallback\n if (RE_HEX.test(name)) {\n return {\n bucket: Bucket.Color,\n processed: `var(--${name}-color, #${name})`,\n };\n }\n // simple color name token → css variable lookup with rgb fallback\n return { bucket: Bucket.Color, processed: `var(--${name}-color)` };\n }\n\n // 4 & 5. Functions\n const openIdx = token.indexOf('(');\n if (openIdx > 0 && token.endsWith(')')) {\n const fname = token.slice(0, openIdx);\n const inner = token.slice(openIdx + 1, -1); // without ()\n\n if (COLOR_FUNCS.has(fname)) {\n // Process inner to expand nested colors or units.\n const parsedInner = recurse(inner);\n const argProcessed = parsedInner.output.replace(/,\\s+/g, ','); // color funcs expect no spaces after commas\n const processed = `${canonicalFuncName(fname)}(${argProcessed})`;\n // `light-dark()` is not color-only — CSS lets it pick between values of\n // any type — so bucket it by what it actually holds. Otherwise\n // `padding: 'light-dark(1x, 2x)'` would land in the color slot and the\n // padding handler would emit its default instead.\n const bucket =\n fname === POLYMORPHIC_COLOR_FUNC && !hasColorArgs(parsedInner)\n ? Bucket.Value\n : Bucket.Color;\n\n return { bucket, processed };\n }\n\n // user function (provided via opts)\n if (opts.functions && fname in opts.functions) {\n // split by top-level commas within inner\n const tmp = new StyleParser(opts).process(inner); // fresh parser w/ same opts but no cache share issues\n const funcResult = opts.functions[fname](tmp.groups);\n // Re-classify the result to determine proper bucket (e.g., if it returns a color)\n // Pass functions: undefined to prevent infinite recursion if result matches a function pattern\n return classify(funcResult, { ...opts, functions: undefined }, recurse);\n }\n\n // generic: process inner and rebuild\n const argProcessed = recurse(inner).output;\n return {\n bucket: Bucket.Value,\n processed: `${canonicalFuncName(fname)}(${argProcessed})`,\n };\n }\n\n // 6. Color fallback syntax: (#name, fallback)\n if (token.startsWith('(') && token.endsWith(')')) {\n const inner = token.slice(1, -1);\n const colorMatch = inner.match(/^#([a-z0-9-]+)\\s*,\\s*(.*)$/i);\n if (colorMatch) {\n const [, name, fallback] = colorMatch;\n const processedFallback = recurse(fallback).output;\n return {\n bucket: Bucket.Color,\n processed: `var(--${name}-color, ${processedFallback})`,\n };\n }\n }\n\n // 7. Custom property with fallback syntax: ($prop, fallback)\n if (token.startsWith('(') && token.endsWith(')')) {\n const inner = token.slice(1, -1);\n const match = inner.match(/^\\$([a-z_][a-zA-Z0-9-_]*)\\s*,\\s*(.*)$/);\n if (match) {\n const [, name, fallback] = match;\n const processedFallback = recurse(fallback).output;\n const bucketType = name.endsWith('-color')\n ? Bucket.ColorValue\n : Bucket.Value;\n return {\n bucket: bucketType,\n processed: `var(--${name}, ${processedFallback})`,\n };\n }\n }\n\n // 8. Auto-calc group\n if (token[0] === '(' && token[token.length - 1] === ')') {\n const inner = token.slice(1, -1);\n const innerProcessed = recurse(inner).output;\n return { bucket: Bucket.Value, processed: `calc(${innerProcessed})` };\n }\n\n // 9. Unit number\n const um = token.match(RE_UNIT_NUM);\n if (um) {\n const unit = um[1];\n const numericPart = parseFloat(token.slice(0, -unit.length));\n const handler = opts.units && opts.units[unit];\n if (handler) {\n if (typeof handler === 'string') {\n // Check if this is a raw CSS unit (e.g., \"8px\", \"1rem\")\n const rawMatch = handler.match(RE_RAW_UNIT);\n if (rawMatch) {\n // Raw unit: calculate directly instead of using calc()\n const [, baseNum, cssUnit] = rawMatch;\n const result = numericPart * parseFloat(baseNum);\n const processed = `${result}${cssUnit}`;\n // Re-parse to resolve any nested units (e.g., units referencing other units)\n const resolved = resolveUntilStable(processed, opts, recurse);\n return { bucket: Bucket.Value, processed: resolved };\n }\n\n // Non-raw handler (e.g., \"var(--gap)\", \"calc(...)\"): use calc() wrapping\n const base = handler;\n if (numericPart === 1) {\n return { bucket: Bucket.Value, processed: base };\n }\n return {\n bucket: Bucket.Value,\n processed: `calc(${numericPart} * ${base})`,\n };\n } else {\n // Function units return complete CSS expressions, no wrapping needed\n const inner = handler(numericPart);\n return {\n bucket: Bucket.Value,\n processed: inner,\n };\n }\n }\n }\n\n // 9b. Unknown numeric+unit → treat as literal value (e.g., 1fr)\n if (/^[+-]?(?:\\d*\\.\\d+|\\d+)[a-z%]+$/.test(token)) {\n return { bucket: Bucket.Value, processed: token };\n }\n\n // 9c. Plain unit-less numbers should be treated as value tokens (e.g.,\n // numeric arguments in custom style handlers).\n if (RE_NUMBER.test(token)) {\n return { bucket: Bucket.Value, processed: token };\n }\n\n // 10. Literal value keywords\n if (VALUE_KEYWORDS.has(token)) {\n return { bucket: Bucket.Value, processed: token };\n }\n\n // 10b. Special keyword colors\n if (token === 'transparent' || token === 'currentcolor') {\n return { bucket: Bucket.Color, processed: token };\n }\n\n // 11. Fallback modifier\n return { bucket: Bucket.Mod, processed: token };\n}\n","export class Lru<K, V> {\n private map = new Map<K, { prev: K | null; next: K | null; value: V }>();\n private head: K | null = null;\n private tail: K | null = null;\n private onEvict?: (key: K, value: V) => void;\n\n constructor(\n private limit = 1000,\n onEvict?: (key: K, value: V) => void,\n ) {\n // Normalize limit; fall back to sensible default (1000) to keep caching enabled\n let normalized = Number.isFinite(this.limit)\n ? Math.floor(this.limit)\n : 1000;\n if (normalized <= 0) normalized = 1000;\n this.limit = normalized;\n this.onEvict = onEvict;\n }\n\n setOnEvict(fn?: (key: K, value: V) => void) {\n this.onEvict = fn;\n }\n\n get(key: K): V | undefined {\n const node = this.map.get(key);\n if (!node) return undefined;\n this.touch(key, node);\n return node.value;\n }\n\n set(key: K, value: V) {\n let node = this.map.get(key);\n if (node) {\n node.value = value;\n this.touch(key, node);\n return;\n }\n node = { prev: null, next: this.head, value };\n if (this.head) {\n const headNode = this.map.get(this.head);\n if (headNode) headNode.prev = key;\n }\n this.head = key;\n if (!this.tail) this.tail = key;\n this.map.set(key, node);\n if (this.map.size > this.limit) this.evict();\n }\n\n delete(key: K) {\n const node = this.map.get(key);\n if (!node) return;\n if (node.prev) {\n const prevNode = this.map.get(node.prev);\n if (prevNode) prevNode.next = node.next;\n }\n if (node.next) {\n const nextNode = this.map.get(node.next);\n if (nextNode) nextNode.prev = node.prev;\n }\n if (this.head === key) this.head = node.next;\n if (this.tail === key) this.tail = node.prev;\n this.map.delete(key);\n }\n\n keys(): IterableIterator<K> {\n return this.map.keys();\n }\n\n private touch(key: K, node: { prev: K | null; next: K | null; value: V }) {\n if (this.head === key) return; // already MRU\n\n // detach\n if (node.prev) {\n const prevNode = this.map.get(node.prev);\n if (prevNode) prevNode.next = node.next;\n }\n if (node.next) {\n const nextNode = this.map.get(node.next);\n if (nextNode) nextNode.prev = node.prev;\n }\n if (this.tail === key) this.tail = node.prev;\n\n // move to head\n node.prev = null;\n node.next = this.head;\n if (this.head) {\n const headNode = this.map.get(this.head);\n if (headNode) headNode.prev = key;\n }\n this.head = key;\n }\n\n private evict() {\n const old = this.tail;\n if (!old) return;\n const node = this.map.get(old);\n if (!node) {\n // Tail pointer is stale; reset pointers conservatively\n if (this.head === old) this.head = null;\n this.tail = null;\n return;\n }\n if (node.prev) {\n const prevNode = this.map.get(node.prev);\n if (prevNode) prevNode.next = null;\n }\n this.tail = node.prev;\n if (this.head === old) this.head = null;\n this.map.delete(old);\n\n if (this.onEvict) {\n try {\n this.onEvict(old, node.value);\n } catch {\n // ignore user callback errors\n }\n }\n }\n\n clear() {\n this.map.clear();\n this.head = this.tail = null;\n }\n}\n","type TokenCallback = (\n token: string,\n isComma: boolean,\n isSlash: boolean,\n precedingChar: string | null,\n) => void;\n\nconst isWhitespace = (ch: string | undefined): boolean =>\n ch === ' ' || ch === '\\n' || ch === '\\t' || ch === '\\r' || ch === '\\f';\n\nexport function scan(src: string, cb: TokenCallback) {\n let depth = 0;\n let inUrl = false;\n let inQuote: string | 0 = 0;\n let start = 0;\n let i = 0;\n // Track if we just saw a standalone slash separator (whitespace before, whitespace after)\n let pendingSlash = false;\n\n const flush = (isComma: boolean, isSlash: boolean) => {\n // If we have a pending slash, emit the part break\n const actualSlash = isSlash || pendingSlash;\n pendingSlash = false;\n\n if (start < i) {\n const prevChar = start > 0 ? src[start - 1] : null;\n cb(src.slice(start, i), isComma, actualSlash, prevChar);\n } else if (isComma) {\n cb('', true, false, null); // empty token followed by comma => group break.\n } else if (actualSlash) {\n cb('', false, true, null); // empty token followed by slash => part break.\n }\n start = i + 1;\n };\n\n for (; i < src.length; i++) {\n const ch = src[i];\n\n // quote mode\n if (inQuote) {\n if (ch === inQuote && src[i - 1] !== '\\\\') inQuote = 0;\n continue;\n }\n if (ch === '\"' || ch === \"'\") {\n inQuote = ch;\n continue;\n }\n\n // paren & url tracking (not inside quotes)\n if (ch === '(') {\n // detect url(\n if (!depth) {\n const maybe = src.slice(Math.max(0, i - 3), i + 1);\n if (maybe === 'url(') inUrl = true;\n }\n depth++;\n continue;\n }\n if (ch === ')') {\n depth = Math.max(0, depth - 1);\n if (inUrl && depth === 0) inUrl = false;\n continue;\n }\n\n if (inUrl) continue; // inside url(...) treat everything as part of token\n\n if (!depth) {\n if (ch === ',') {\n flush(true, false);\n continue;\n }\n // Slash is only a separator when surrounded by whitespace (e.g., \"a / b\")\n // This preserves CSS patterns like \"center/cover\" as single tokens\n if (ch === '/') {\n const prevIsWhitespace = isWhitespace(src[i - 1]);\n const nextIsWhitespace = isWhitespace(src[i + 1]);\n if (prevIsWhitespace && nextIsWhitespace) {\n // Already flushed by whitespace before, mark pending slash\n pendingSlash = true;\n start = i + 1; // skip the slash character\n continue;\n }\n // Not surrounded by whitespace - treat as part of token\n continue;\n }\n if (isWhitespace(ch)) {\n flush(false, false);\n continue;\n }\n }\n }\n flush(false, false); // tail\n}\n","import { foldDslCase } from '../utils/string';\n\nimport { classify } from './classify';\nimport { Lru } from './lru';\nimport { scan } from './tokenizer';\nimport type {\n ParserOptions,\n ProcessedStyle,\n StyleDetails,\n StyleDetailsPart,\n} from './types';\nimport {\n Bucket,\n finalizeGroup,\n finalizePart,\n makeEmptyDetails,\n makeEmptyPart,\n} from './types';\n\nexport class StyleParser {\n private cache: Lru<string, ProcessedStyle>;\n constructor(private opts: ParserOptions = {}) {\n this.cache = new Lru<string, ProcessedStyle>(this.opts.cacheSize ?? 1000);\n }\n\n /* ---------------- Public API ---------------- */\n process(src: string): ProcessedStyle {\n const key = String(src);\n const hit = this.cache.get(key);\n if (hit) return hit;\n\n // strip comments, then case-fold everything except custom-property names\n const stripped = foldDslCase(\n src.replace(/\\/\\*[^*]*\\*+(?:[^/*][^*]*\\*+)*\\//g, ''),\n );\n\n const groups: StyleDetails[] = [];\n let currentGroup = makeEmptyDetails();\n let currentPart = makeEmptyPart();\n let parts: StyleDetailsPart[] = [];\n\n const pushToken = (bucket: Bucket, processed: string) => {\n if (!processed) return;\n\n // If the previous token was a url(...) value, merge this token into it so that\n // background layer segments like \"url(img) no-repeat center/cover\" are kept\n // as a single value entry.\n const mergeIntoPrevUrl = () => {\n const lastIdx = currentPart.values.length - 1;\n currentPart.values[lastIdx] += ` ${processed}`;\n const lastAllIdx = currentPart.all.length - 1;\n currentPart.all[lastAllIdx] += ` ${processed}`;\n };\n\n const prevIsUrlValue =\n currentPart.values.length > 0 &&\n currentPart.values[currentPart.values.length - 1].startsWith('url(');\n\n if (prevIsUrlValue) {\n // Extend the existing url(...) value regardless of current bucket.\n mergeIntoPrevUrl();\n // Additionally, for non-value buckets we need to remove their own storage.\n // So early return.\n return;\n }\n\n switch (bucket) {\n case Bucket.Color:\n currentPart.colors.push(processed);\n break;\n case Bucket.Value:\n currentPart.values.push(processed);\n break;\n case Bucket.Mod:\n currentPart.mods.push(processed);\n break;\n case Bucket.ColorValue:\n // Untyped reference: readable from either bucket, listed once in `all`.\n currentPart.colors.push(processed);\n currentPart.values.push(processed);\n break;\n }\n currentPart.all.push(processed);\n };\n\n const endPart = () => {\n // Only add non-empty parts\n if (currentPart.all.length > 0) {\n finalizePart(currentPart);\n parts.push(currentPart);\n }\n currentPart = makeEmptyPart();\n };\n\n const endGroup = () => {\n endPart(); // finalize last part\n\n // Ensure at least one part exists (even if empty) for backward compat\n if (parts.length === 0) {\n parts.push(makeEmptyPart());\n finalizePart(parts[0]);\n }\n\n finalizeGroup(currentGroup, parts);\n groups.push(currentGroup);\n\n // Reset for next group\n currentGroup = makeEmptyDetails();\n parts = [];\n currentPart = makeEmptyPart();\n };\n\n scan(stripped, (tok, isComma, isSlash, _prevChar) => {\n if (tok) {\n // Accumulate raw token into currentGroup.input\n if (currentGroup.input) {\n currentGroup.input += ` ${tok}`;\n } else {\n currentGroup.input = tok;\n }\n\n const { bucket, processed } = classify(tok, this.opts, (sub) =>\n this.process(sub),\n );\n pushToken(bucket, processed);\n }\n if (isSlash) endPart();\n if (isComma) endGroup();\n });\n\n // push final group if not already\n if (currentPart.all.length || parts.length || !groups.length) endGroup();\n\n const output = groups.map((g) => g.output).join(', ');\n const result: ProcessedStyle = { output, groups };\n Object.freeze(result);\n this.cache.set(key, result);\n return result;\n }\n\n setFunctions(functions: Required<ParserOptions>['functions']): void {\n this.opts.functions = functions;\n this.cache.clear();\n }\n\n setUnits(units: Required<ParserOptions>['units']): void {\n this.opts.units = units;\n this.cache.clear();\n }\n\n updateOptions(patch: Partial<ParserOptions>): void {\n Object.assign(this.opts, patch);\n if (patch.cacheSize)\n this.cache = new Lru<string, ProcessedStyle>(patch.cacheSize);\n else this.cache.clear();\n }\n\n /**\n * Clear the parser cache.\n * Call this when external state that affects parsing results has changed\n * (e.g., predefined tokens).\n */\n clearCache(): void {\n this.cache.clear();\n }\n\n /**\n * Get the current units configuration.\n */\n getUnits(): ParserOptions['units'] {\n return this.opts.units;\n }\n}\n","/**\n * Check if we're in a development environment at runtime\n * Uses bracket notation to avoid bundler compilation\n * Also checks for TASTY_DEBUG localStorage setting\n */\nexport function isDevEnv(): boolean {\n // Check localStorage for DEBUG_TASTY setting (browser environment)\n if (typeof window !== 'undefined' && window.localStorage) {\n try {\n const forceTastyDebug = window.localStorage.getItem('TASTY_DEBUG');\n if (\n forceTastyDebug !== null &&\n forceTastyDebug.toLowerCase() === 'true'\n ) {\n return true;\n }\n } catch {\n // localStorage might not be available (private browsing, etc.)\n // Continue with other checks\n }\n }\n\n // Check NODE_ENV for Node.js environments\n if (typeof process === 'undefined') return false;\n\n // Use bracket notation to avoid bundler replacement\n const nodeEnv = process.env?.['NODE_ENV'];\n return nodeEnv !== 'test' && nodeEnv !== 'production';\n}\n","import { CSS_WIDE_KEYWORDS } from '../parser/const';\nimport type { StyleDetails } from '../parser/types';\nimport { isDevEnv } from '../utils/is-dev-env';\n\n/**\n * If the group contains exactly one value that is a CSS-wide keyword\n * and no colors, return the keyword. Otherwise null.\n *\n * Direction mods (top/right/bottom/left) may coexist with the keyword\n * for directional application like `padding=\"inherit top\"`.\n */\nexport function extractCSSWideKeyword(group: StyleDetails): string | null {\n if (group.values.length !== 1 || group.colors.length > 0) return null;\n return CSS_WIDE_KEYWORDS.has(group.values[0]) ? group.values[0] : null;\n}\n\n/** A resolved custom-property reference, i.e. `var(--name)` or `var(--name, …)`. */\nconst RE_VAR_REFERENCE = /^var\\(/;\n\n/**\n * Assign custom-property references to the style and color slots of a\n * `<line-width> <line-style> <line-color>` shorthand (`border`, `outline`).\n *\n * The parser cannot type a reference, so it buckets `$name` as a plain value and\n * the handler has to place it. A reference fills the first slot still free, in\n * shorthand order: the width takes `values[0]`, then the style, then the color.\n * The style would otherwise arrive as a keyword (`solid`, `dashed`, …) that a\n * reference has no way to match, and the color as `#name` — the `$name-color`\n * form the parser buckets as a color exists to reference a raw CSS custom\n * property, not as the way colors are written, so a reference should not reach\n * for the color slot until the style slot is taken.\n *\n * Lengths are left alone: a second length is not valid in these shorthands, and\n * promoting one would emit an invalid declaration instead of ignoring an extra\n * value. Callers supply their own slot defaults.\n */\nexport function assignLineSlots(\n values: string[],\n styleKeyword: string | undefined,\n colorToken: string | undefined,\n): { style: string | undefined; color: string | undefined } {\n if (styleKeyword && colorToken) {\n return { style: styleKeyword, color: colorToken };\n }\n\n // A `$name-color` reference is filed under both buckets (`Bucket.ColorValue`),\n // so skip the one the color slot already claimed rather than placing it twice.\n const spare = values\n .slice(1)\n .filter((value) => RE_VAR_REFERENCE.test(value) && value !== colorToken);\n\n return {\n style: styleKeyword || spare.shift(),\n color: colorToken || spare.shift(),\n };\n}\n\n/** Warning keys already emitted, so each distinct offending value warns once. */\nconst emittedWarnings = new Set<string>();\n\n/** A resolved custom-property reference anywhere in a token. */\nconst RE_HAS_VAR_REFERENCE = /var\\(/;\n\n/**\n * Reject a custom-property reference used where a *token name* is expected.\n *\n * `preset` and `transition` take the name of a design token (`t3`, `fill`) and\n * interpolate it into a CSS custom property — `var(--t3-font-size)`. A reference\n * substituted into that position builds `var(--var(--x)-font-size)`, which is not\n * a valid custom-property name, so the browser drops the declaration and the\n * style silently does nothing. The DSL has no way to indirect a token name\n * through a custom property: the name is needed at build time, and a reference\n * only resolves in the browser.\n *\n * Returns true (warning once per value in dev) so the caller can fall back\n * instead of emitting a declaration that cannot work.\n */\nexport function isTokenNameReference(property: string, name: string): boolean {\n if (!RE_HAS_VAR_REFERENCE.test(name)) return false;\n\n warnOnceDev(\n `token-name-reference:${property}:${name}`,\n `${property}=\"${name}\": a custom property cannot name a token. The name is ` +\n `interpolated into a CSS custom property at build time, so a reference ` +\n `would build an unusable name. It is ignored.`,\n );\n\n return true;\n}\n\n/**\n * Emit a style-level warning at most once per `key`. No-op outside dev mode.\n *\n * Style handlers run once per state combination and their results are cached,\n * but the same value can arrive from many components, so dedupe is required.\n *\n * `isDevEnv()` is called lazily rather than captured at module load (the pattern\n * used in `config.ts` and `states/index.ts`) so that tests can enable it with\n * `vi.stubEnv('NODE_ENV', 'development')` — `isDevEnv()` returns `false` for\n * `NODE_ENV=test`, which is why every module-load-gated warning in this repo is\n * currently untestable. The key is registered *before* the dev check, so\n * production pays at most one `isDevEnv()` call per distinct offending value and\n * never touches the console.\n */\nexport function warnOnceDev(key: string, message: string): void {\n if (emittedWarnings.has(key)) return;\n emittedWarnings.add(key);\n\n if (!isDevEnv()) return;\n\n console.warn(`[Tasty] ${message}`);\n}\n\n/** Forget emitted style warnings. Called by `resetConfig()`; test isolation. */\nexport function resetStyleWarnings(): void {\n emittedWarnings.clear();\n}\n\n/**\n * Report a comma group that names direction modifiers together with more values\n * than the group can use.\n *\n * The parser buckets values and modifiers into separate arrays per comma group,\n * so `padding: '2x 4x top right'`, `padding: '2x top 4x right'` and\n * `padding: 'top 2x right 4x'` all reach a handler identically — the pairing a\n * reader infers from source order does not survive parsing. Such a group\n * therefore carries a single value, applied to every direction it names.\n *\n * `maxValues` is 2 only for a span modifier (`inset: '2x 4x bottom dock'`),\n * where the second value insets the sides the dock spans.\n *\n * Callers must guard on the count themselves so the valid path costs one integer\n * comparison; everything expensive happens here, on the misuse path only.\n */\nexport function warnExtraGroupValues(\n property: string,\n input: string,\n maxValues: 1 | 2,\n): void {\n const message =\n maxValues === 2\n ? `${property}=\"${input}\": with a span modifier a group takes at most two ` +\n `values — one for the named edge and one for the spanned sides. ` +\n `The extra values are ignored.`\n : `${property}=\"${input}\": a group that names directions takes a single ` +\n `value, applied to every direction it names. The extra values are ` +\n `ignored — use comma-separated groups instead, ` +\n `e.g. ${property}=\"2x top, 4x right\".`;\n\n warnOnceDev(`extra-values:${property}:${input}`, message);\n}\n","import { Lru } from '../parser/lru';\nimport { warnOnceDev } from '../styles/shared';\nimport { isDevEnv } from '../utils/is-dev-env';\nimport type { StyleDetails } from '../parser/types';\n\nconst clamp = (value: number, min: number, max: number): number =>\n Math.max(Math.min(value, max), min);\n\n/**\n * Parse an angle value with optional unit.\n * Supports: deg, turn, rad, or unitless (treated as degrees).\n */\nconst parseAngle = (value: string): number => {\n const match = value.match(/^([+-]?\\d*\\.?\\d+)(deg|turn|rad)?$/);\n if (!match) return 0;\n\n const num = parseFloat(match[1]);\n const unit = match[2];\n\n switch (unit) {\n case 'turn':\n return num * 360;\n case 'rad':\n return (num * 180) / Math.PI;\n case 'deg':\n default:\n return num;\n }\n};\n\n/**\n * Parse a percentage value (e.g., \"50%\") to a 0-1 range. A unitless number is\n * read as the factor it already looks like, so `okhsl(280 .8 .52)` and\n * `okhsl(280 80% 52%)` are the same color.\n */\nconst parsePercentage = (value: string): number => {\n const match = value.match(/^([+-]?\\d*\\.?\\d+)%?$/);\n if (!match) return 0;\n\n const num = parseFloat(match[1]);\n return value.includes('%') ? num / 100 : num;\n};\n\n/**\n * Creates a color function handler for the tasty parser.\n *\n * A color function is a custom `functions` entry that converts its arguments\n * to an `rgb(...)` string (an already-supported color), so it needs no special\n * core integration — registering it as a parse function is enough.\n *\n * @param name The name of the color function (e.g., 'okhsl', 'okhst')\n * @param convert Converts the parsed first three channel values (after angle/\n * percent normalization) to sRGB `[r, g, b]` in the 0-1 range\n * @param label Optional diagnostic label shown in dev warnings when the wrong\n * number of arguments is supplied (e.g., 'H S L'). Has no effect on parsing\n * or output.\n */\nexport function createColorFunc(\n name: string,\n convert: (h: number, c2: number, c3: number) => [number, number, number],\n label?: string,\n): (groups: StyleDetails[]) => string {\n const conversionCache = new Lru<string, string>(500);\n const expected = label ? ` (${label})` : '';\n\n return (groups: StyleDetails[]): string => {\n if (groups.length === 0 || groups[0].all.length < 3) {\n if (isDevEnv()) {\n console.warn(\n `[Tasty] ${name}(): expected 3 values${expected}, got:`,\n groups,\n );\n }\n\n return 'rgb(0% 0% 0%)';\n }\n\n const group = groups[0];\n const tokens = group.all;\n\n const alpha =\n group.parts.length > 1 && group.parts[1].all.length > 0\n ? group.parts[1].output\n : undefined;\n\n const cacheKey =\n tokens.slice(0, 3).join(' ') + (alpha ? ` / ${alpha}` : '');\n const cached = conversionCache.get(cacheKey);\n if (cached) return cached;\n\n const h = parseAngle(tokens[0]);\n const c2 = parsePercentage(tokens[1]);\n const c3 = parsePercentage(tokens[2]);\n\n // A *unitless* channel above 1 cannot be a factor, so it is a missing `%`.\n // Clamping it quietly is the worst outcome: `okhsl(280 80 52)` renders as\n // white, which looks like a color rather than like a mistake.\n //\n // The raw token decides, not the parsed number: `150%` parses to `1.5`,\n // which is over-saturation that legitimately clamps, and warning about it\n // would also burn the dedup slot and silence a real `80` later. `1` itself\n // is a legitimate factor, so the comparison is strict.\n const misscaled = [tokens[1], tokens[2]].filter(\n (raw, i) => !raw.includes('%') && (i === 0 ? c2 : c3) > 1,\n );\n\n if (misscaled.length) {\n warnOnceDev(\n `${name}:percent-scale`,\n `${name}(): channels are factors (0-1) or percentages, so ` +\n `${misscaled.map((v) => `\"${v}\"`).join(' and ')} ` +\n `${misscaled.length > 1 ? 'clamp' : 'clamps'} to 1 — add the ` +\n `missing '%', or write the value as a 0-1 number.`,\n );\n }\n\n const [r, g, b] = convert(h, clamp(c2, 0, 1), clamp(c3, 0, 1));\n\n const format = (n: number): string => {\n const pct = n * 100;\n return parseFloat(pct.toFixed(1)).toString() + '%';\n };\n\n const result = alpha\n ? `rgb(${format(r)} ${format(g)} ${format(b)} / ${alpha})`\n : `rgb(${format(r)} ${format(g)} ${format(b)})`;\n\n conversionCache.set(cacheKey, result);\n return result;\n };\n}\n","/**\n * OKHSL Plugin for Tasty\n *\n * Converts OKHSL color syntax to RGB notation.\n * Supports angle units: deg, turn, rad, or unitless (degrees).\n *\n * Examples:\n * okhsl(240.5 50% 50%)\n * okhsl(240.5deg 50% 50%)\n * okhsl(0.25turn 50% 50%)\n * okhsl(1.57rad 50% 50%)\n */\n\nimport { okhslToSrgb } from '../utils/color-math';\n\nimport { createColorFunc } from './color-func';\n\nimport type { TastyPlugin, TastyPluginFactory } from './types';\n\n/**\n * The okhsl function handler for tasty parser.\n * Receives parsed style groups and returns an RGB color string.\n */\nconst okhslFunction = createColorFunc('okhsl', okhslToSrgb, 'H S L');\n\n/**\n * OKHSL Plugin for Tasty.\n *\n * Adds support for the `okhsl()` color function in tasty styles.\n *\n * @example\n * ```ts\n * import { configure } from '@tenphi/tasty';\n * import { okhslPlugin } from '@tenphi/tasty';\n *\n * configure({\n * plugins: [okhslPlugin()],\n * });\n *\n * // Now you can use okhsl in styles:\n * const Box = tasty({\n * styles: {\n * fill: 'okhsl(240 50% 50%)',\n * },\n * });\n * ```\n */\nexport const okhslPlugin: TastyPluginFactory = (): TastyPlugin => ({\n name: 'okhsl',\n functions: {\n okhsl: okhslFunction,\n },\n});\n\nexport { okhslFunction };\n","/**\n * OKHST Plugin for Tasty\n *\n * Converts OKHST color syntax to RGB notation.\n * OKHST is OKHSL with the lightness axis replaced by a contrast-uniform tone axis.\n * Supports angle units: deg, turn, rad, or unitless (degrees).\n *\n * Examples:\n * okhst(240.5 50% 50%)\n * okhst(240.5deg 50% 50%)\n * okhst(0.25turn 50% 50%)\n * okhst(1.57rad 50% 50%)\n */\n\nimport { okhstToSrgb } from '../utils/color-math';\n\nimport { createColorFunc } from './color-func';\n\nimport type { TastyPlugin, TastyPluginFactory } from './types';\n\n/**\n * The okhst function handler for tasty parser.\n * Receives parsed style groups and returns an RGB color string.\n */\nconst okhstFunction = createColorFunc('okhst', okhstToSrgb, 'H S T');\n\n/**\n * OKHST Plugin for Tasty.\n *\n * Adds support for the `okhst()` color function in tasty styles.\n *\n * @example\n * ```ts\n * import { configure } from '@tenphi/tasty';\n * import { okhstPlugin } from '@tenphi/tasty';\n *\n * configure({\n * plugins: [okhstPlugin()],\n * });\n *\n * // Now you can use okhst in styles:\n * const Box = tasty({\n * styles: {\n * fill: 'okhst(240 50% 50%)',\n * },\n * });\n * ```\n */\nexport const okhstPlugin: TastyPluginFactory = (): TastyPlugin => ({\n name: 'okhst',\n functions: {\n okhst: okhstFunction,\n },\n});\n\nexport { okhstFunction };\n","import { customFunction } from '../utils/styles';\n\nimport { okhslFunction } from './okhsl-plugin';\nimport { okhstFunction } from './okhst-plugin';\n\n/**\n * Register the default color functions (okhsl, okhst) with the global parser.\n *\n * They are ordinary `functions` entries — the same mechanism any third-party\n * color plugin uses — so they need no special-casing in core.\n *\n * Idempotent and safe to call from the lazy parser initializer so that\n * zero-config usage keeps working. `resetGlobalParseFunctions()` re-invokes it\n * after clearing user-registered functions so the defaults survive a config reset.\n *\n * @internal\n */\nexport function registerDefaultFunctions(): void {\n customFunction('okhsl', okhslFunction);\n customFunction('okhst', okhstFunction);\n}\n","import { StyleParser } from '../parser/parser';\nimport { registerDefaultFunctions } from '../plugins/defaults';\n\nimport type { ProcessedStyle, StyleDetails } from '../parser/types';\n\nimport { getNamedColorHex } from './color-math';\nimport { parseAlphaOverride } from './color-space';\n\nexport {\n getNamedColorHex,\n getRgbValuesFromRgbaString,\n hexToRgb,\n strToRgb,\n} from './color-math';\n\nexport type StyleValue<T = string> = T | boolean | number | null | undefined;\n\n/**\n * Normalize a color token value.\n * - Boolean `true` is converted to `'transparent'`\n * - Boolean `false` returns `null` (signals the token should be skipped)\n * - Other values are returned as-is\n *\n * @param value - The raw token value\n * @returns Normalized value or null if the token should be skipped\n */\nexport function normalizeColorTokenValue<T>(\n value: T | boolean,\n): T | 'transparent' | null {\n if (value === true) {\n return 'transparent';\n }\n if (value === false) {\n return null;\n }\n return value as T;\n}\n\nexport type StyleValueStateMap<T = string> = Record<\n string,\n StyleValue<T> | '@inherit'\n>;\n\n/**\n * Combined type for style values that can be either a direct value or a state map.\n * Use this for component props that accept style values.\n */\nexport type StylePropValue<T = string> = StyleValue<T> | StyleValueStateMap<T>;\n\n/**\n * One dependency value as a style handler receives it: already resolved for a\n * single state, but still the **raw authored DSL string** (`'2x'`, `'#purple.5'`).\n * Handlers parse it themselves via {@link parseStyle} / {@link parseColor}.\n */\nexport type ResolvedStyleValue = StyleValue<string>;\n\n/**\n * The dependency map a handler receives — one resolved value per style name in\n * its `__lookupStyles`.\n */\nexport type StyleHandlerProps<TDeps extends string = string> = Partial<\n Record<TDeps, ResolvedStyleValue>\n>;\n\n/**\n * One set of CSS declarations returned by a style handler.\n *\n * Keys are **kebab-case** CSS property names (`'background-color'`, not\n * `backgroundColor`) or `--custom-property` names. Values are stringified, so\n * numbers are accepted. `$` is reserved as a selector suffix.\n */\nexport type CSSMap = {\n /** Selector suffix (or suffixes) these declarations apply to, e.g. `'& > *'`. */\n $?: string | string[];\n} & Record<string, string | number | (string | number)[] | undefined>;\n\nexport type StyleHandlerResult = CSSMap | CSSMap[] | null | void;\n\nexport type RawStyleHandler<TProps extends object = StyleHandlerProps> = (\n props: TProps,\n) => StyleHandlerResult;\n\nexport type StyleHandler<TProps extends object = StyleHandlerProps> =\n RawStyleHandler<TProps> & {\n __lookupStyles: string[];\n };\n\n/**\n * The handler type used by the registry (`STYLE_HANDLER_MAP`), with parameter\n * variance erased.\n *\n * Handlers declare narrow, hand-written dependency types — `({ fill }: { fill?:\n * string }) => …` — which under `strictFunctionTypes` are not assignable to a\n * wider parameter type. The registry stores handlers of many different dependency\n * shapes together, so it needs the erased form. Prefer {@link StyleHandler} (or\n * {@link defineHandler}) when writing a handler; this type is for code that\n * inspects the registry.\n */\nexport type AnyStyleHandler = ((\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n props: any,\n) => StyleHandlerResult) & {\n __lookupStyles: string[];\n};\n\n/**\n * Handler definition forms for configure() and plugins.\n * - Function only: lookup styles inferred from key name\n * - Single property tuple: ['styleName', handler]\n * - Multi-property tuple: [['style1', 'style2'], handler]\n *\n * Use {@link defineHandler} to have the dependency names inferred into the\n * handler's parameter type instead of annotating it by hand.\n */\nexport type StyleHandlerDefinition<TDeps extends string = string> =\n | RawStyleHandler<StyleHandlerProps<TDeps>>\n | [TDeps, RawStyleHandler<StyleHandlerProps<TDeps>>]\n | [readonly TDeps[], RawStyleHandler<StyleHandlerProps<TDeps>>];\n\nexport interface ParsedColor {\n color?: string;\n name?: string;\n opacity?: number;\n}\n\nexport type StyleMap = Record<string, StyleValue | StyleValueStateMap>;\n\nconst devMode = process.env.NODE_ENV !== 'production';\n\n// Precompiled regex patterns for parseColor optimization\n// Match var(--name-color...) and extract the name, regardless of fallbacks.\n// Anchored: a reference inside a color function is an *argument* of that color,\n// not the color's own name — `color-mix(in oklab, var(--purple-color) 50%, …)`\n// is not named `purple`.\nconst COLOR_VAR_PATTERN = /^var\\(--([a-z0-9-]+)-color[,)]/;\nconst RGB_ALPHA_PATTERN = /\\/\\s*([0-9.]+)\\)/;\nconst RE_HEX_COLOR = /^#[0-9a-fA-F]{3,8}$/;\nconst RE_VAR_COLOR = /^var\\(--[a-z0-9-]+-color/;\n\nfunction isSimpleColorFast(val: string): boolean {\n const c0 = val.charCodeAt(0);\n\n // Cheap first-character dispatch for the shapes that have one. A miss must\n // fall through rather than answer `false`: the CSS named colors start with\n // every letter these cases claim — `red`, `hotpink`, `lime`, `orange`,\n // `violet`, `coral`, `teal` — and each one is a color too.\n switch (c0) {\n case 35: // '#'\n return RE_HEX_COLOR.test(val);\n case 114: // 'r'\n if (val.charCodeAt(1) === 103 && val.charCodeAt(2) === 98) return true; // 'rgb'\n break;\n case 104: // 'h'\n if (val.charCodeAt(1) === 115 && val.charCodeAt(2) === 108) return true; // 'hsl'\n break;\n case 108: // 'l'\n if (val.charCodeAt(1) === 99 && val.charCodeAt(2) === 104) return true; // 'lch'\n break;\n case 111: // 'o'\n if (val.startsWith('oklch(')) return true;\n break;\n case 118: // 'v'\n if (RE_VAR_COLOR.test(val)) return true;\n break;\n case 99: // 'c'\n if (val === 'currentColor' || val === 'currentcolor') return true;\n break;\n case 116: // 't'\n if (val === 'transparent') return true;\n break;\n }\n\n return getNamedColorHex().has(val.toLowerCase());\n}\n\n// Rate limiting for dev warnings to avoid spam\nlet colorWarningCount = 0;\nconst MAX_COLOR_WARNINGS = 10;\n\nexport const CUSTOM_UNITS = {\n r: '6px',\n cr: '10px',\n bw: '1px',\n ow: '3px',\n x: '8px',\n sf: function sf(num: number) {\n return `minmax(0, ${num}fr)`;\n },\n};\n\nexport const DIRECTIONS = ['top', 'right', 'bottom', 'left'];\n\n// Lazy-initialized to break the circular dependency:\n// parser.ts → classify.ts → utils/styles.ts → parser.ts\nlet __tastyParser: StyleParser | null = null;\n\nfunction getOrCreateParser(): StyleParser {\n if (!__tastyParser) {\n __tastyParser = new StyleParser({ units: CUSTOM_UNITS });\n __tastyParser.setFunctions(__tastyParseFunctions);\n // Register built-in color functions (okhsl/okhst) as ordinary parse\n // functions. Done lazily here so zero-config usage works regardless of\n // module initialization order or tree-shaking.\n registerDefaultFunctions();\n }\n return __tastyParser;\n}\n\n// Registry for user-provided custom functions that the parser can call.\n// It is updated through the `customFunc` helper exported below and through\n// `configure()`. Built-in color functions (okhsl/okhst) are registered lazily\n// by `registerDefaultFunctions()` rather than seeded here, so they go through\n// the exact same path as any third-party plugin.\nconst __tastyParseFunctions: Record<\n string,\n (groups: StyleDetails[]) => string\n> = {};\n\n/**\n * Register a parse-time function.\n *\n * @internal Use `configure({ functions })`. This bypasses the configuration lock\n * and is kept only for the lazy default-function bootstrap and the `@function`\n * polyfill, both of which must register after `configure()` has run.\n */\nexport function customFunction(\n name: string,\n fn: (groups: StyleDetails[]) => string,\n) {\n __tastyParseFunctions[name] = fn;\n getOrCreateParser().setFunctions(__tastyParseFunctions);\n}\n\n/**\n * Reset parse functions back to the built-in set (okhsl/okhst).\n *\n * @internal Called by `resetConfig()`.\n */\nexport function resetGlobalParseFunctions(): void {\n for (const key of Object.keys(__tastyParseFunctions)) {\n delete __tastyParseFunctions[key];\n }\n // Re-register the default color functions so they survive a config reset.\n registerDefaultFunctions();\n getOrCreateParser().setFunctions(__tastyParseFunctions);\n}\n\n/**\n * Get the global StyleParser instance.\n * Used by configure() to apply parser configuration.\n */\nexport function getGlobalParser(): StyleParser {\n return getOrCreateParser();\n}\n\n/**\n * Get the current custom functions registry.\n * Used by configure() to merge with new functions.\n */\n/**\n * The live parse-function registry.\n *\n * @internal Returns the mutable internal map; writing to it bypasses the\n * parser's cache invalidation, so the write silently does not take effect.\n * Read-only, internal use.\n */\nexport function getGlobalParseFunctions(): Record<\n string,\n (groups: StyleDetails[]) => string\n> {\n return __tastyParseFunctions;\n}\n\n// ============================================================================\n// Global Predefined Tokens\n// ============================================================================\n\n/**\n * Storage for predefined tokens that are replaced during style parsing.\n * Keys are token names (with $ or # prefix), values are pre-processed CSS values.\n */\nlet __globalPredefinedTokens: Record<string, string> | null = null;\n\n/**\n * Set global predefined tokens.\n * Called from configure() after processing token values.\n * Merges with existing tokens (new tokens override existing ones with same key).\n * Keys are normalized to lowercase (parser lowercases input before classification).\n * @internal\n */\nexport function setGlobalPredefinedTokens(\n tokens: Record<string, string>,\n): void {\n // Normalize keys to lowercase for case-insensitive matching\n const normalizedTokens: Record<string, string> = {};\n for (const [key, value] of Object.entries(tokens)) {\n const lowerKey = key.toLowerCase();\n const lowerValue = value.toLowerCase();\n\n // Warn if trying to use bare #current to define other color tokens\n // #current represents currentcolor which cannot be used as a base for recursive token resolution\n // Note: #current.5 (with opacity) is allowed since it resolves to a concrete color-mix value\n if (lowerKey.startsWith('#') && lowerValue === '#current') {\n if (process.env.NODE_ENV !== 'production') {\n console.warn(\n `[Tasty] Using #current to define color token \"${key}\" is not supported. ` +\n `The #current token represents currentcolor which cannot be used as a base for other tokens.`,\n );\n }\n continue; // Skip this token\n }\n\n normalizedTokens[lowerKey] = value;\n }\n // Merge with existing tokens (consistent with how states, units, and parse functions are handled)\n __globalPredefinedTokens = __globalPredefinedTokens\n ? { ...__globalPredefinedTokens, ...normalizedTokens }\n : normalizedTokens;\n // Clear parser cache since token values affect parsing\n getOrCreateParser().clearCache();\n}\n\n/**\n * Get the current global predefined tokens.\n * Returns null if no tokens are configured.\n */\nexport function getGlobalPredefinedTokens(): Record<string, string> | null {\n return __globalPredefinedTokens;\n}\n\n/**\n * Reset global predefined tokens.\n * Used for testing.\n * @internal\n */\nexport function resetGlobalPredefinedTokens(): void {\n __globalPredefinedTokens = null;\n // Clear parser cache since token availability affects parsing\n getOrCreateParser().clearCache();\n}\n\n/**\n *\n * @param {String} value\n * @param {Number} mode\n * @returns {Object<String,String|Array>}\n */\nexport function parseStyle(value: StyleValue): ProcessedStyle {\n let str: string;\n\n if (typeof value === 'string') {\n str = value;\n } else if (typeof value === 'number') {\n str = String(value);\n } else {\n // boolean, null, undefined, objects etc. → empty string\n str = '';\n }\n\n return getOrCreateParser().process(str);\n}\n\n/** A `$`-prefixed custom-property reference — the only DSL syntax that starts with `$`. */\nconst RE_CUSTOM_PROPERTY_REF = /\\$[a-zA-Z_$]/;\n\n/**\n * Substitute custom-property references (`$ident` → `var(--ident)`) inside a\n * value a handler would otherwise emit to CSS verbatim.\n *\n * Handlers for keyword-valued properties (`display`, `align`, `text-transform`,\n * `overflow`, …) pass their input straight through, since there are no units or\n * color tokens to resolve. That leaked the raw DSL into the stylesheet:\n * `display: '$my-display'` emitted `display: $my-display`, which the browser\n * drops as invalid. The same applies to color props whose value the parser could\n * not classify as a color — `$ident` is a color only when the name ends with\n * `-color`, so `fill: '$my-fill'` fell back to the unparsed input.\n *\n * Values without a `$` skip the parser entirely, so pass-through behaviour (and\n * the parser's case folding) is unchanged for every value that was already\n * valid CSS.\n */\nexport function resolveCustomProperties(value: string): string {\n if (!RE_CUSTOM_PROPERTY_REF.test(value)) return value;\n\n return parseStyle(value).output || value;\n}\n\n/**\n * Parse color. Find it value, name and opacity.\n * Optimized to avoid heavy parseStyle calls for simple color patterns.\n */\nexport function parseColor(val: string, ignoreError = false): ParsedColor {\n // Early return for non-strings or empty values\n if (typeof val !== 'string') {\n val = String(val ?? '');\n }\n\n val = val.trim();\n if (!val) return {};\n\n // Fast path: Check if it's a simple color pattern that doesn't need full parsing\n const isSimpleColor = isSimpleColorFast(val);\n\n let firstColor: string;\n if (isSimpleColor) {\n // For simple colors, use the value directly without parsing\n firstColor = val;\n } else {\n const processed = parseStyle(val);\n const extractedColor = processed.groups.find((g) => g.colors.length)\n ?.colors[0];\n\n if (!extractedColor) {\n // Rate-limited warning to avoid spam\n if (!ignoreError && devMode && colorWarningCount < MAX_COLOR_WARNINGS) {\n console.warn('[Tasty] unable to parse color:', val);\n colorWarningCount++;\n if (colorWarningCount === MAX_COLOR_WARNINGS) {\n console.warn(\n '[Tasty] color parsing warnings will be suppressed from now on',\n );\n }\n }\n return {};\n }\n\n firstColor = extractedColor;\n }\n\n // `#name.alpha` fades the color with relative color syntax, so the name and the\n // opacity are read off the parts rather than the whole.\n const faded = parseAlphaOverride(firstColor);\n const baseColor = faded ? faded.color : firstColor;\n\n // Extract color name (if present) from variable pattern using precompiled regex\n const nameMatch = baseColor.match(COLOR_VAR_PATTERN);\n\n let opacity: number | undefined;\n if (faded) {\n // A `var()` alpha has no number to report.\n const { alpha } = faded;\n const v = parseFloat(alpha);\n if (!isNaN(v)) opacity = alpha.endsWith('%') ? v : v * 100;\n } else if (\n baseColor.startsWith('rgb') ||\n baseColor.startsWith('hsl') ||\n baseColor.startsWith('lch') ||\n baseColor.startsWith('oklch')\n ) {\n const alphaMatch = baseColor.match(RGB_ALPHA_PATTERN);\n if (alphaMatch) {\n const v = parseFloat(alphaMatch[1]);\n if (!isNaN(v)) opacity = v * 100;\n }\n }\n\n return {\n color: firstColor,\n name: nameMatch ? nameMatch[1] : undefined,\n opacity,\n };\n}\n\nexport function filterMods(mods: string[], allowedMods: string[]): string[] {\n return mods.filter((mod) => allowedMods.includes(mod));\n}\n\n// ============================================================================\n// Style Stringification\n// ============================================================================\n\nconst _innerCache = new WeakMap();\nconst _topLevelCache = new WeakMap<object, string>();\n\nexport function stringifyStyles(styles: unknown): string {\n if (styles == null || typeof styles !== 'object') return '';\n\n const cached = _topLevelCache.get(styles as object);\n if (cached !== undefined) return cached;\n\n const obj = styles as Record<string, unknown>;\n const keys = Object.keys(obj).sort();\n const parts: string[] = [];\n for (const k of keys) {\n const v = obj[k];\n if (v === undefined || typeof v === 'function' || typeof v === 'symbol')\n continue;\n\n const c0 = k.charCodeAt(0);\n const needsInnerSort =\n ((c0 >= 65 && c0 <= 90) || c0 === 38) &&\n v &&\n typeof v === 'object' &&\n !Array.isArray(v);\n\n let sv: string;\n if (needsInnerSort) {\n sv = _innerCache.get(v);\n if (sv === undefined) {\n const innerObj = v as Record<string, unknown>;\n const innerKeys = Object.keys(innerObj).sort();\n const innerParts: string[] = [];\n for (const ik of innerKeys) {\n const ivs = JSON.stringify(innerObj[ik]);\n if (ivs !== undefined)\n innerParts.push(JSON.stringify(ik) + ':' + ivs);\n }\n sv = '{' + innerParts.join(',') + '}';\n _innerCache.set(v, sv);\n }\n } else {\n sv = JSON.stringify(v);\n }\n parts.push(JSON.stringify(k) + ':' + sv);\n }\n const result = '{' + parts.join(',') + '}';\n _topLevelCache.set(styles as object, result);\n return result;\n}\n","/**\n * Function Utilities\n *\n * Utilities for extracting and processing CSS @function definitions in styles.\n * Custom functions are permanent once injected and do not need cleanup.\n *\n * Token syntax:\n * - Function name keys use `$$name` (the literal callable `--name`), matching\n * the call site `$$name(...)`. `$name` and `--name` are also accepted.\n * - Parameters and local variables use `$name` (declared/referenced as a custom\n * property), exactly like a normal styles object.\n * - `result`, local-variable values, and parameter defaults flow through the\n * Tasty DSL parser, so units, color tokens, auto-calc, and fallbacks all work.\n */\n\nimport type { FunctionDefinition, FunctionParameter } from '../injector/types';\nimport type { StyleDetails } from '../parser/types';\nimport type { Styles } from '../styles/types';\nimport { customFunction, parseStyle } from '../utils/styles';\n\n// ============================================================================\n// Constants\n// ============================================================================\n\nconst FUNCTION_KEY = '@function';\n\n/** Descriptor keys that are not local-variable declarations. */\nconst RESERVED_KEYS = new Set(['args', 'returns', 'result']);\n\n/**\n * A parse-time function: receives the parsed (comma-separated) argument groups\n * and returns a CSS value string. This is the JS flavor of the unified\n * `functions` config (bare-name keys), distinct from declarative `@function`\n * definitions (`$$`-prefixed keys).\n */\nexport type ParseFunction = (groups: StyleDetails[]) => string;\n\n/**\n * The unified `functions` map: keys are either bare names (parse functions,\n * value is a function) or `$$name`/`$name`/`--name` (declarative CSS functions,\n * value is a {@link FunctionDefinition} object).\n */\nexport type FunctionsConfig = Record<\n string,\n FunctionDefinition | ParseFunction\n>;\n\n// ============================================================================\n// Extraction Functions\n// ============================================================================\n\n/**\n * Check if styles object has a local @function definition.\n */\nexport function hasLocalFunctions(styles: Styles): boolean {\n return FUNCTION_KEY in styles;\n}\n\n/**\n * Extract local @function definitions from a styles object.\n * Returns null if none (fast path).\n */\nexport function extractLocalFunctions(\n styles: Styles,\n): Record<string, FunctionDefinition> | null {\n const functions = styles[FUNCTION_KEY];\n if (!functions || typeof functions !== 'object') {\n return null;\n }\n return functions as Record<string, FunctionDefinition>;\n}\n\n// ============================================================================\n// Token Parsing\n// ============================================================================\n\n/**\n * Parse a function name token into its CSS custom name.\n * Accepts `$$name`, `$name`, `--name`, or bare `name` → `--name`.\n */\nexport function parseFunctionName(token: string): string {\n if (token.startsWith('$$')) return `--${token.slice(2)}`;\n if (token.startsWith('$')) return `--${token.slice(1)}`;\n if (token.startsWith('--')) return token;\n return `--${token}`;\n}\n\n/**\n * Parse a parameter / local-variable name token into its CSS custom name.\n * Accepts `$name`, `--name`, or bare `name` → `--name`.\n */\nexport function parseParamName(token: string): string {\n if (token.startsWith('$')) return `--${token.slice(1)}`;\n if (token.startsWith('--')) return token;\n return `--${token}`;\n}\n\n// ============================================================================\n// CSS Formatting\n// ============================================================================\n\n/**\n * Format a single parameter (`--name <type>: default`).\n */\nfunction formatParameter(token: string, param: FunctionParameter): string {\n const name = parseParamName(token);\n\n if (param === true) {\n return name;\n }\n\n if (typeof param === 'string') {\n return param ? `${name} ${param}` : name;\n }\n\n let out = name;\n if (param.syntax) {\n out += ` ${param.syntax}`;\n }\n if (param.default !== undefined) {\n out += `: ${parseStyle(param.default).output}`;\n }\n return out;\n}\n\n/**\n * Format the function prelude: `@function --name(params) returns <type>`.\n */\nexport function formatFunctionPrelude(\n name: string,\n args: FunctionDefinition['args'],\n returns?: string,\n): string {\n const cssName = parseFunctionName(name);\n\n let params = '';\n if (Array.isArray(args)) {\n params = args.map((token) => formatParameter(token, true)).join(', ');\n } else if (args) {\n params = Object.entries(args)\n .map(([token, param]) => formatParameter(token, param))\n .join(', ');\n }\n\n const returnsPart = returns ? ` returns ${returns}` : '';\n\n return `@function ${cssName}(${params})${returnsPart}`;\n}\n\n/**\n * Format the inner declarations of a @function rule (local variables + result).\n */\nexport function formatFunctionDeclarations(def: FunctionDefinition): string {\n const parts: string[] = [];\n\n for (const key of Object.keys(def)) {\n if (RESERVED_KEYS.has(key) || !key.startsWith('$')) continue;\n const value = def[key as `$${string}`];\n if (value === undefined) continue;\n parts.push(`${parseParamName(key)}: ${parseStyle(value).output};`);\n }\n\n parts.push(`result: ${parseStyle(def.result).output};`);\n\n return parts.join(' ');\n}\n\n/**\n * Format a complete @function rule as CSS.\n */\nexport function formatFunctionRule(\n name: string,\n def: FunctionDefinition,\n): string {\n const prelude = formatFunctionPrelude(name, def.args, def.returns);\n return `${prelude} { ${formatFunctionDeclarations(def)} }`;\n}\n\n// ============================================================================\n// Unified `functions` config: value-type split\n// ============================================================================\n\n/** A key is a CSS-function key when it carries the `$`/`--` prefix. */\nfunction isCssFunctionKey(key: string): boolean {\n return key.startsWith('$') || key.startsWith('--');\n}\n\n/** Discriminate a unified `functions` entry by its value type. */\nfunction isParseFunction(\n value: FunctionDefinition | ParseFunction,\n): value is ParseFunction {\n return typeof value === 'function';\n}\n\nexport type FunctionMismatch =\n | 'expected-definition' // function value under a `$$` key\n | 'expected-parse-function'; // object value under a bare key\n\n/**\n * Split the unified `functions` map into the two internal registries:\n * - `parseFuncs`: JS parse functions (bare keys).\n * - `functionDefs`: declarative CSS `@function` definitions (`$$` keys).\n *\n * Entries whose key prefix does not match the value type are reported via\n * `onMismatch` and skipped.\n */\nexport function splitFunctions(\n map: FunctionsConfig,\n onMismatch?: (key: string, kind: FunctionMismatch) => void,\n): {\n parseFuncs: Record<string, ParseFunction>;\n functionDefs: Record<string, FunctionDefinition>;\n} {\n const parseFuncs: Record<string, ParseFunction> = {};\n const functionDefs: Record<string, FunctionDefinition> = {};\n\n for (const [key, value] of Object.entries(map)) {\n const cssKey = isCssFunctionKey(key);\n if (isParseFunction(value)) {\n if (cssKey) {\n onMismatch?.(key, 'expected-definition');\n continue;\n }\n parseFuncs[key] = value;\n } else {\n if (!cssKey) {\n onMismatch?.(key, 'expected-parse-function');\n continue;\n }\n functionDefs[key] = value;\n }\n }\n\n return { parseFuncs, functionDefs };\n}\n\n// ============================================================================\n// Polyfill: compile a declarative @function into a parse-function closure\n// ============================================================================\n\nfunction escapeRegExp(str: string): string {\n return str.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n}\n\nconst paramBareName = (token: string): string => parseParamName(token).slice(2);\n\n/**\n * Rewrite `var(--name)` references for declared parameter/local names to a\n * collision-resistant, function-scoped prefix. This guarantees that later\n * value substitution only ever targets the function's own variables and can\n * never accidentally match a real element-level `var(--name)` introduced by an\n * argument value (e.g. the `--gap` used by Tasty units). Blanket prefix — no\n * exact-collision detection.\n */\nfunction prefixDeclaredVars(\n template: string,\n declared: string[],\n prefixOf: (bare: string) => string,\n): string {\n let out = template;\n for (const bare of declared) {\n const re = new RegExp(`var\\\\(\\\\s*--${escapeRegExp(bare)}(?![\\\\w-])`, 'g');\n out = out.replace(re, `var(--${prefixOf(bare)}`);\n }\n return out;\n}\n\n/**\n * Replace the prefixed `var(--<prefixed>)` / `var(--<prefixed>, fallback)`\n * references with their mapped values, iterating so that local variables that\n * reference parameters (or other locals) resolve fully.\n */\nfunction substituteVars(\n template: string,\n valueMap: Map<string, string>,\n): string {\n let out = template;\n for (let iter = 0; iter < 30; iter++) {\n let changed = false;\n for (const [name, value] of valueMap) {\n const re = new RegExp(\n `var\\\\(\\\\s*--${escapeRegExp(name)}\\\\s*(?:,[^)]*)?\\\\)`,\n 'g',\n );\n const next = out.replace(re, () => {\n changed = true;\n return value;\n });\n out = next;\n }\n if (!changed) break;\n }\n return out;\n}\n\n/** Function names currently being expanded, to guard against recursion cycles. */\nconst inProgress = new Set<string>();\n\n/**\n * Compile a declarative `@function` definition into a parse-function closure\n * that fully inlines the call into plain CSS (the `@function` polyfill).\n *\n * Parameters and local variables are substituted directly with their values,\n * so no function-internal custom properties are emitted (collisions are\n * structurally impossible). Self/mutually-recursive functions are not expanded:\n * the cycle guard bails and the call is left untouched.\n */\nexport function compileFunctionClosure(\n name: string,\n def: FunctionDefinition,\n): ParseFunction {\n const cssName = parseFunctionName(name);\n // Function-scoped, collision-resistant prefix for this function's variables.\n const prefixOf = (bare: string): string => `tf-${cssName.slice(2)}-${bare}`;\n\n const params: { prefixed: string; default?: string }[] = [];\n if (Array.isArray(def.args)) {\n for (const token of def.args) {\n params.push({ prefixed: prefixOf(paramBareName(token)) });\n }\n } else if (def.args) {\n for (const [token, param] of Object.entries(def.args)) {\n let dflt: string | undefined;\n if (param && typeof param === 'object' && param.default !== undefined) {\n dflt = parseStyle(param.default).output;\n }\n params.push({ prefixed: prefixOf(paramBareName(token)), default: dflt });\n }\n }\n\n const localKeys = Object.keys(def).filter(\n (key) => !RESERVED_KEYS.has(key) && key.startsWith('$'),\n );\n\n const declared = [\n ...(Array.isArray(def.args)\n ? def.args.map(paramBareName)\n : def.args\n ? Object.keys(def.args).map(paramBareName)\n : []),\n ...localKeys.map(paramBareName),\n ];\n\n // Built lazily on first call so that nested function calls referenced by the\n // result are resolved against the fully-populated registry.\n let built = false;\n let resultTemplate = '';\n const localTemplates: { prefixed: string; value: string }[] = [];\n\n const build = () => {\n built = true;\n resultTemplate = prefixDeclaredVars(\n parseStyle(def.result).output,\n declared,\n prefixOf,\n );\n for (const key of localKeys) {\n const value = def[key as `$${string}`];\n if (value === undefined) continue;\n localTemplates.push({\n prefixed: prefixOf(paramBareName(key)),\n value: prefixDeclaredVars(parseStyle(value).output, declared, prefixOf),\n });\n }\n };\n\n return (groups: StyleDetails[]): string => {\n if (inProgress.has(cssName)) return '';\n inProgress.add(cssName);\n try {\n if (!built) build();\n\n const valueMap = new Map<string, string>();\n params.forEach((param, index) => {\n const arg = groups[index]?.output?.trim();\n valueMap.set(param.prefixed, arg || param.default || '');\n });\n for (const local of localTemplates) {\n valueMap.set(local.prefixed, local.value);\n }\n\n return substituteVars(resultTemplate, valueMap);\n } finally {\n inProgress.delete(cssName);\n }\n };\n}\n\n/** CSS function name -> serialized definition, to dedupe polyfill registration. */\nconst registeredFunctionDefs = new Map<string, string>();\n\n/**\n * Register a declarative `@function` as a parse-function closure so the parser\n * inlines its call sites. Deduplicated by name + definition; a later, different\n * definition of the same name overrides the previous one (local wins).\n */\nexport function registerFunctionPolyfill(\n name: string,\n definition: FunctionDefinition,\n): void {\n const cssName = parseFunctionName(name);\n const serialized = JSON.stringify(definition);\n if (registeredFunctionDefs.get(cssName) === serialized) return;\n registeredFunctionDefs.set(cssName, serialized);\n customFunction(cssName, compileFunctionClosure(name, definition));\n}\n\n/** Register all local `@function` definitions from a styles object (polyfill). */\nexport function registerLocalFunctionPolyfills(styles: Styles): void {\n const local = extractLocalFunctions(styles);\n if (!local) return;\n for (const [name, definition] of Object.entries(local)) {\n registerFunctionPolyfill(name, definition);\n }\n}\n\n/** Clear polyfill registration bookkeeping (used by resetConfig in tests). */\nexport function resetFunctionPolyfills(): void {\n registeredFunctionDefs.clear();\n}\n","/**\n * Chunk names, the built-in chunk style lists, and the style→chunk lookup.\n *\n * This is a **leaf module with no imports**. It exists separately from\n * `definitions.ts` for two reasons:\n *\n * 1. The style handler registry (`styles/predefined.ts`) needs to assign chunk\n * membership for custom handlers. Reaching for `definitions.ts` would create an\n * import cycle (`definitions` -> `pipeline` -> `styles` -> `predefined`).\n * 2. `STYLE_TO_CHUNK` is populated as a side effect of module load, so it must be\n * populated by the module that *owns* it. Otherwise an importer that only pulls\n * in this module would see an empty map and misclassify every style as `misc`.\n *\n * `definitions.ts` re-exports everything here, so existing import paths and the\n * public API surface are unchanged.\n */\n\nexport const CHUNK_NAMES = {\n /** Special chunk for styles that cannot be split */\n COMBINED: 'combined',\n SUBCOMPONENTS: 'subcomponents',\n APPEARANCE: 'appearance',\n FONT: 'font',\n DIMENSION: 'dimension',\n DISPLAY: 'display',\n LAYOUT: 'layout',\n POSITION: 'position',\n MISC: 'misc',\n} as const;\n\nexport type ChunkName = (typeof CHUNK_NAMES)[keyof typeof CHUNK_NAMES];\n\n// ============================================================================\n// Built-in Chunk Style Lists\n// ============================================================================\n\n/**\n * Appearance chunk - visual styling with independent handlers\n *\n * @public\n */\nexport const APPEARANCE_CHUNK_STYLES = [\n 'fill', // fillStyle (independent)\n 'color', // colorStyle (independent)\n 'opacity', // independent\n 'border', // borderStyle (independent)\n 'radius', // radiusStyle (independent)\n 'outline', // outlineStyle: outline ↔ outlineOffset\n 'outlineOffset', // outlineStyle: outline ↔ outlineOffset\n 'shadow', // shadowStyle (independent)\n 'fade', // fadeStyle (independent)\n] as const;\n\n/**\n * Font chunk - typography styles\n *\n * Handler dependencies (all styles in each handler MUST stay in this chunk):\n * ⚠️ presetStyle: preset, fontSize, lineHeight, letterSpacing, textTransform,\n * fontWeight, fontStyle, font\n */\n/** @public */\nexport const FONT_CHUNK_STYLES = [\n // All from presetStyle handler - MUST stay together\n 'preset',\n 'font',\n 'fontWeight',\n 'fontStyle',\n 'fontSize',\n 'lineHeight',\n 'letterSpacing',\n 'textTransform',\n // Independent text styles grouped for cohesion\n 'fontFamily', // independent alias (logical grouping with font styles)\n 'textAlign',\n 'textDecoration',\n 'wordBreak',\n 'wordWrap',\n 'boldFontWeight',\n] as const;\n\n/**\n * Dimension chunk - sizing and spacing\n *\n * Handler dependencies (all styles in each handler MUST stay in this chunk):\n * ⚠️ paddingStyle: padding, paddingTop/Right/Bottom/Left, paddingBlock/Inline\n * ⚠️ marginStyle: margin, marginTop/Right/Bottom/Left, marginBlock/Inline\n * ⚠️ widthStyle: width, minWidth, maxWidth\n * ⚠️ heightStyle: height, minHeight, maxHeight\n */\n/** @public */\nexport const DIMENSION_CHUNK_STYLES = [\n // All from paddingStyle handler - MUST stay together\n 'padding',\n 'paddingTop',\n 'paddingRight',\n 'paddingBottom',\n 'paddingLeft',\n 'paddingBlock',\n 'paddingInline',\n // All from marginStyle handler - MUST stay together\n 'margin',\n 'marginTop',\n 'marginRight',\n 'marginBottom',\n 'marginLeft',\n 'marginBlock',\n 'marginInline',\n // widthStyle handler - MUST stay together\n 'width',\n 'minWidth',\n 'maxWidth',\n // heightStyle handler - MUST stay together\n 'height',\n 'minHeight',\n 'maxHeight',\n 'flexBasis',\n 'flexGrow',\n 'flexShrink',\n 'flex',\n] as const;\n\n/**\n * Display chunk - display mode, layout flow, text overflow, and scrollbar\n *\n * Handler dependencies (all styles in each handler MUST stay in this chunk):\n * ⚠️ displayStyle: display, hide, textOverflow, overflow, whiteSpace\n * ⚠️ flowStyle: display, flow\n * ⚠️ gapStyle: display, flow, gap\n * ⚠️ scrollbarStyle: scrollbar, overflow\n */\n/** @public */\nexport const DISPLAY_CHUNK_STYLES = [\n // displayStyle handler\n 'display',\n 'hide',\n 'textOverflow',\n 'overflow', // also used by scrollbarStyle\n 'whiteSpace',\n // flowStyle handler (requires display)\n 'flow',\n // gapStyle handler (requires display, flow)\n 'gap',\n // scrollbarStyle handler (requires overflow)\n 'scrollbar',\n] as const;\n\n/**\n * Layout chunk - flex/grid alignment and grid templates\n *\n * Note: flow and gap are in DISPLAY chunk due to handler dependencies\n * (flowStyle and gapStyle both require 'display' prop).\n */\n/** @public */\nexport const LAYOUT_CHUNK_STYLES = [\n // Alignment styles (all independent handlers)\n 'placeItems',\n 'placeContent',\n 'alignItems',\n 'alignContent',\n 'justifyItems',\n 'justifyContent',\n 'align', // placementStyle\n 'justify', // placementStyle\n 'place', // placementStyle\n 'columnGap',\n 'rowGap',\n // Grid template styles\n 'gridColumns',\n 'gridRows',\n 'gridTemplate',\n 'gridAreas',\n 'gridAutoFlow',\n 'gridAutoColumns',\n 'gridAutoRows',\n] as const;\n\n/**\n * Position chunk - element positioning\n *\n * Handler dependencies (all styles in each handler MUST stay in this chunk):\n * ⚠️ insetStyle: inset, insetBlock, insetInline, top, right, bottom, left\n */\n/** @public */\nexport const POSITION_CHUNK_STYLES = [\n 'position',\n // All from insetStyle handler - MUST stay together\n 'inset',\n 'insetBlock',\n 'insetInline',\n 'top',\n 'right',\n 'bottom',\n 'left',\n 'zIndex',\n 'gridArea',\n 'gridColumn',\n 'gridRow',\n 'order',\n 'placeSelf',\n 'alignSelf',\n 'justifySelf',\n 'transform',\n 'transition',\n 'animation',\n] as const;\n\n// ============================================================================\n// Style-to-Chunk Lookup Map (O(1) categorization)\n// ============================================================================\n\n/**\n * Map for O(1) style-to-chunk lookup. Seeded with the built-in lists above and\n * extended by {@link assignStyleChunk} when a custom handler declares style names\n * the built-in lists don't know.\n */\nexport const STYLE_TO_CHUNK = new Map<string, ChunkName>();\n\n/** Built-in assignments, captured so `resetStyleChunks()` can restore them. */\nlet builtinSnapshot: Map<string, ChunkName> | null = null;\n\nfunction populateStyleToChunkMap(): void {\n for (const style of APPEARANCE_CHUNK_STYLES) {\n STYLE_TO_CHUNK.set(style, CHUNK_NAMES.APPEARANCE);\n }\n for (const style of FONT_CHUNK_STYLES) {\n STYLE_TO_CHUNK.set(style, CHUNK_NAMES.FONT);\n }\n for (const style of DIMENSION_CHUNK_STYLES) {\n STYLE_TO_CHUNK.set(style, CHUNK_NAMES.DIMENSION);\n }\n for (const style of DISPLAY_CHUNK_STYLES) {\n STYLE_TO_CHUNK.set(style, CHUNK_NAMES.DISPLAY);\n }\n for (const style of LAYOUT_CHUNK_STYLES) {\n STYLE_TO_CHUNK.set(style, CHUNK_NAMES.LAYOUT);\n }\n for (const style of POSITION_CHUNK_STYLES) {\n STYLE_TO_CHUNK.set(style, CHUNK_NAMES.POSITION);\n }\n}\n\n// Populate at module load and record the result as the baseline that\n// resetStyleChunks() restores.\npopulateStyleToChunkMap();\nbuiltinSnapshot = new Map(STYLE_TO_CHUNK);\n\n/**\n * Assign a style name to a chunk.\n *\n * Used to keep a custom handler's dependencies in one chunk: chunks are rendered\n * and cached independently, and a chunk's cache key covers only its own style\n * values, so a handler whose `__lookupStyles` straddle two chunks is invoked once\n * per chunk with a subset of its inputs and can emit stale CSS.\n */\nexport function assignStyleChunk(styleName: string, chunk: ChunkName): void {\n STYLE_TO_CHUNK.set(styleName, chunk);\n}\n\n/**\n * Drop custom chunk assignments and restore the built-in baseline.\n *\n * Called by `resetConfig()`. Without this, a custom handler's chunk assignments\n * would leak across tests the same way custom handlers themselves did before\n * `resetHandlers()` existed.\n *\n * @internal\n */\nexport function resetStyleChunks(): void {\n if (!builtinSnapshot) return;\n\n STYLE_TO_CHUNK.clear();\n\n for (const [style, chunk] of builtinSnapshot) {\n STYLE_TO_CHUNK.set(style, chunk);\n }\n}\n","/**\n * Props middleware for tasty components.\n *\n * A prop handler receives a component's props and returns them, changed or not.\n * That makes it the extension point for props that are *not* style properties:\n * it can read a custom prop, strip it so it never reaches the DOM, and fold its\n * meaning into `styles`, `mods`, `tokens`, `variant`, or `as`.\n *\n * ```ts\n * configure({\n * propHandlers: {\n * glaze: (props) => {\n * const { glaze, ...rest } = props;\n * if (!glaze) return rest;\n * return { ...rest, styles: mergeStyles(glazeStyles(glaze), rest.styles) };\n * },\n * },\n * });\n * ```\n *\n * Handlers run on every render of every tasty component, so the registry is a\n * pre-composed chain that is `null` while nothing is registered — the cost when\n * unused is one property load and one branch.\n */\n\nimport { isDevEnv } from './utils/is-dev-env';\n\n/** Props object handed to a prop handler. Deliberately untyped: handlers see everything. */\nexport type PropHandlerProps = Record<string, unknown>;\n\n/**\n * Props middleware: props in, props out. Returning nothing means \"unchanged\".\n *\n * Must be a **pure function** and must not mutate its input. Style values are\n * cached by object identity, so mutating a value object in place produces a stale\n * class name and stale CSS. Return fresh (ideally frozen, ideally memoized)\n * objects instead.\n */\nexport type PropHandler = (\n props: PropHandlerProps,\n) => PropHandlerProps | void | null;\n\n/**\n * How a prop handler is declared. The map key is both its name and, by default,\n * the prop that triggers it.\n *\n * - `fn` — triggered when a prop matching the key is present\n * - `['glaze', fn]` — triggered by the named prop\n * - `[['glaze', 'tone'], fn]` — triggered by any of them\n * - `['*', fn]` — unconditional; runs on every render of every component\n */\nexport type PropHandlerDefinition =\n | PropHandler\n | [string, PropHandler]\n | [string[], PropHandler];\n\ninterface NormalizedPropHandler {\n key: string;\n /** Props that trigger this handler, or `null` for unconditional. */\n triggers: string[] | null;\n fn: PropHandler;\n source: string;\n}\n\ntype PropHandlerChain = (props: PropHandlerProps) => PropHandlerProps;\n\ninterface PropHandlerRegistry {\n /** Pre-composed chain, or `null` while nothing is registered. */\n apply: PropHandlerChain | null;\n list: NormalizedPropHandler[];\n}\n\n// Held on globalThis so a duplicated module graph (Astro's server/client split)\n// shares one registry, matching how the rest of the global config is stored.\nconst GTKEY = '__tasty_prop_handlers__';\n\nconst globalStore = globalThis as unknown as Record<string, unknown>;\n\nexport const propHandlerRegistry: PropHandlerRegistry =\n (globalStore[GTKEY] as PropHandlerRegistry | undefined) ??\n ((globalStore[GTKEY] = { apply: null, list: [] }) as PropHandlerRegistry);\n\nexport interface RegisterPropHandlerOptions {\n /** Where the handler came from — a plugin name, or `'configure()'`. */\n source?: string;\n}\n\nfunction normalize(\n key: string,\n definition: PropHandlerDefinition,\n options?: RegisterPropHandlerOptions,\n): NormalizedPropHandler {\n const source = options?.source ?? 'configure()';\n\n if (typeof definition === 'function') {\n return { key, triggers: [key], fn: definition, source };\n }\n\n if (Array.isArray(definition)) {\n const [first, fn] = definition;\n\n if (typeof fn !== 'function') {\n throw new Error(\n `[Tasty] Invalid prop handler definition for \"${key}\". ` +\n 'Tuple must have a function as the second element: [string, function] or [string[], function].',\n );\n }\n\n if (first === '*') {\n return { key, triggers: null, fn, source };\n }\n\n if (typeof first === 'string') {\n return { key, triggers: [first], fn, source };\n }\n\n if (Array.isArray(first)) {\n return {\n key,\n triggers: first.includes('*') ? null : first,\n fn,\n source,\n };\n }\n\n throw new Error(\n `[Tasty] Invalid prop handler definition for \"${key}\". ` +\n 'First element must be a string or string array.',\n );\n }\n\n throw new Error(\n `[Tasty] Invalid prop handler definition for \"${key}\". ` +\n 'Expected function, [string, function], or [string[], function].',\n );\n}\n\n/**\n * Run one handler, treating a nothing/non-object return as \"unchanged\".\n *\n * `isDevEnv()` is called lazily rather than captured at module load so the\n * warnings are assertable in tests; it is only reached on the misuse path.\n */\nfunction runOne(\n handler: NormalizedPropHandler,\n props: PropHandlerProps,\n): PropHandlerProps {\n const next = handler.fn(props);\n\n if (next != null && typeof next === 'object' && !Array.isArray(next)) {\n return next;\n }\n\n if (isDevEnv()) {\n console.warn(\n next == null\n ? `[Tasty] propHandlers[\"${handler.key}\"] (from ${handler.source}) returned ` +\n `${String(next)}. Props are treated as unchanged — did you forget to ` +\n `\\`return props\\`?`\n : `[Tasty] propHandlers[\"${handler.key}\"] (from ${handler.source}) returned ` +\n `${Array.isArray(next) ? 'an array' : typeof next}. A prop handler must ` +\n `return a props object. The result was ignored.`,\n );\n }\n\n return props;\n}\n\nfunction compose(list: NormalizedPropHandler[]): PropHandlerChain | null {\n if (list.length === 0) return null;\n\n // Specialize the overwhelmingly common single-handler case.\n if (list.length === 1) {\n const only = list[0];\n\n if (only.triggers === null) {\n return (props) => runOne(only, props);\n }\n\n if (only.triggers.length === 1) {\n const trigger = only.triggers[0];\n\n return (props) => (trigger in props ? runOne(only, props) : props);\n }\n }\n\n return (props) => {\n for (const handler of list) {\n const triggers = handler.triggers;\n\n if (triggers !== null) {\n let triggered = false;\n\n for (const trigger of triggers) {\n if (trigger in props) {\n triggered = true;\n break;\n }\n }\n\n if (!triggered) continue;\n }\n\n props = runOne(handler, props);\n }\n\n return props;\n };\n}\n\n/**\n * Register a props middleware under `key`, replacing any handler already\n * registered under the same key while keeping its position in the chain.\n */\nexport function registerPropHandler(\n key: string,\n definition: PropHandlerDefinition,\n options?: RegisterPropHandlerOptions,\n): void {\n const normalized = normalize(key, definition, options);\n const { list } = propHandlerRegistry;\n const existing = list.findIndex((handler) => handler.key === key);\n\n if (existing === -1) {\n list.push(normalized);\n } else {\n list[existing] = normalized;\n }\n\n propHandlerRegistry.apply = compose(list);\n}\n\n/** Drop every registered props middleware. Called by `resetConfig()`. */\nexport function resetPropHandlers(): void {\n if (propHandlerRegistry.list.length === 0) return;\n\n // Mutate the holder rather than replacing it: other modules captured this\n // object reference at import time.\n propHandlerRegistry.list.length = 0;\n propHandlerRegistry.apply = null;\n}\n","/**\n * Properties Utilities\n *\n * Utilities for extracting and processing CSS @property definitions in styles.\n * Unlike keyframes, properties are permanent once registered and don't need cleanup.\n *\n * Property names use tasty token syntax:\n * - `$name` for regular properties → `--name`\n * - `#name` for color properties → `--name-color` (auto-sets syntax: '<color>')\n */\n\nimport type { PropertyDefinition } from '../injector/types';\nimport { RE_NUMBER, RE_RAW_UNIT } from '../parser/const';\nimport type { Styles } from '../styles/types';\n\n// ============================================================================\n// Constants\n// ============================================================================\n\nconst PROPERTIES_KEY = '@property';\n\n/**\n * Valid CSS custom property name pattern (after the -- prefix).\n * Must start with a letter or underscore, followed by letters, digits, hyphens, or underscores.\n */\nconst VALID_PROPERTY_NAME_PATTERN = /^[a-z_][a-z0-9-_]*$/i;\n\n// ============================================================================\n// Validation Functions\n// ============================================================================\n\n/**\n * Validate a CSS custom property name (the part after --).\n * Returns true if the name is valid for use as a CSS custom property.\n */\nexport function isValidPropertyName(name: string): boolean {\n return VALID_PROPERTY_NAME_PATTERN.test(name);\n}\n\n/**\n * Result of parsing a property token.\n */\ninterface ParsedPropertyToken {\n /** The CSS custom property name (e.g., '--my-prop') */\n cssName: string;\n /** Whether this is a color property */\n isColor: boolean;\n /** Whether the token was valid */\n isValid: boolean;\n /** Error message if invalid */\n error?: string;\n}\n\n// ============================================================================\n// Extraction Functions\n// ============================================================================\n\n/**\n * Check if styles object has local @property definition.\n * Fast path: single property lookup.\n */\nexport function hasLocalProperties(styles: Styles): boolean {\n return PROPERTIES_KEY in styles;\n}\n\n/**\n * Extract local @property from styles object.\n * Returns null if no local properties (fast path).\n */\nexport function extractLocalProperties(\n styles: Styles,\n): Record<string, PropertyDefinition> | null {\n const properties = styles[PROPERTIES_KEY];\n if (!properties || typeof properties !== 'object') {\n return null;\n }\n return properties as Record<string, PropertyDefinition>;\n}\n\n// ============================================================================\n// Token Parsing Functions\n// ============================================================================\n\n/**\n * Parse a property token name and return the CSS property name and whether it's a color.\n * Supports tasty token syntax and validates the property name.\n *\n * Token formats:\n * - `$name` → { cssName: '--name', isColor: false }\n * - `#name` → { cssName: '--name-color', isColor: true }\n * - `--name` → { cssName: '--name', isColor: false } (legacy, auto-detect color by suffix)\n * - `name` → { cssName: '--name', isColor: false } (legacy)\n *\n * @param token - The property token to parse\n * @returns Parsed result with cssName, isColor, isValid, and optional error\n */\nexport function parsePropertyToken(token: string): ParsedPropertyToken {\n if (!token || typeof token !== 'string') {\n return {\n cssName: '',\n isColor: false,\n isValid: false,\n error: 'Property token must be a non-empty string',\n };\n }\n\n let name: string;\n let isColor: boolean;\n\n if (token.startsWith('$')) {\n // Regular property token: $name → --name\n name = token.slice(1);\n isColor = false;\n } else if (token.startsWith('#')) {\n // Color property token: #name → --name-color\n name = token.slice(1);\n isColor = true;\n } else if (token.startsWith('--')) {\n // Legacy format with -- prefix\n name = token.slice(2);\n isColor = token.endsWith('-color');\n } else {\n // Legacy format without prefix\n name = token;\n isColor = token.endsWith('-color');\n }\n\n // Validate the name\n if (!name) {\n return {\n cssName: '',\n isColor,\n isValid: false,\n error: 'Property name cannot be empty',\n };\n }\n\n if (!isValidPropertyName(name)) {\n return {\n cssName: '',\n isColor,\n isValid: false,\n error: `Invalid property name \"${name}\". Must start with a letter or underscore, followed by letters, digits, hyphens, or underscores.`,\n };\n }\n\n // Build the CSS custom property name\n // For #name tokens, we add -color suffix\n // For legacy formats (--name-color or name-color), the name already includes -color\n let cssName: string;\n if (token.startsWith('#')) {\n // Color token: #name → --name-color\n cssName = `--${name}-color`;\n } else {\n // All other formats: just add -- prefix\n cssName = `--${name}`;\n }\n\n return {\n cssName,\n isColor,\n isValid: true,\n };\n}\n\n// ============================================================================\n// Normalization Functions\n// ============================================================================\n\n/**\n * Normalize a property name to the CSS custom property format.\n *\n * @deprecated Use parsePropertyToken instead for proper token handling\n */\nexport function normalizePropertyName(name: string): string {\n const result = parsePropertyToken(name);\n return result.isValid ? result.cssName : `--${name}`;\n}\n\n/**\n * Normalize a property definition to a consistent string representation.\n * Used for comparing definitions to detect type conflicts.\n *\n * Only `syntax` and `inherits` are compared — `initialValue` is intentionally\n * excluded because different components may set different defaults for the\n * same typed property (e.g. auto-inferred `0px` vs explicit `6px`).\n *\n * Keys are sorted alphabetically to ensure consistent comparison:\n * { inherits: true, syntax: '<color>' } === { syntax: '<color>', inherits: true }\n */\nexport function normalizePropertyDefinition(def: PropertyDefinition): string {\n const normalized: Record<string, unknown> = {};\n\n if (def.inherits !== undefined) {\n normalized.inherits = def.inherits;\n }\n if (def.syntax !== undefined) {\n normalized.syntax = def.syntax;\n }\n\n return JSON.stringify(normalized);\n}\n\n/**\n * Result of getEffectiveDefinition.\n */\ninterface EffectiveDefinitionResult {\n /** The CSS custom property name */\n cssName: string;\n /** The effective property definition */\n definition: PropertyDefinition;\n /** Whether the token was valid */\n isValid: boolean;\n /** Error message if invalid */\n error?: string;\n}\n\n/**\n * Get the effective property definition for a token.\n * For color tokens (#name), auto-sets syntax to '<color>' and defaults initialValue to 'transparent'.\n *\n * @param token - Property token ($name, #name, --name, or plain name)\n * @param userDefinition - User-provided definition options\n * @returns Effective definition with cssName, definition, isValid, and optional error\n */\nexport function getEffectiveDefinition(\n token: string,\n userDefinition: PropertyDefinition,\n): EffectiveDefinitionResult {\n const parsed = parsePropertyToken(token);\n\n if (!parsed.isValid) {\n return {\n cssName: '',\n definition: userDefinition,\n isValid: false,\n error: parsed.error,\n };\n }\n\n if (parsed.isColor) {\n // Color properties have fixed syntax and default initialValue\n return {\n cssName: parsed.cssName,\n definition: {\n syntax: '<color>', // Always '<color>' for color tokens, cannot be overridden\n inherits: userDefinition.inherits, // Allow inherits to be customized\n initialValue: userDefinition.initialValue ?? 'transparent', // Default to transparent\n },\n isValid: true,\n };\n }\n\n // Regular properties use the definition as-is\n return {\n cssName: parsed.cssName,\n definition: userDefinition,\n isValid: true,\n };\n}\n\n// ============================================================================\n// Value Type Inference\n// ============================================================================\n\n/**\n * Result of inferring a CSS @property syntax from a value.\n */\ninterface InferredSyntax {\n syntax: string;\n initialValue: string;\n}\n\nconst UNIT_TO_SYNTAX: Record<string, InferredSyntax> = {};\n\nconst LENGTH_UNITS = [\n 'px',\n 'em',\n 'rem',\n 'vw',\n 'vh',\n 'vmin',\n 'vmax',\n 'ch',\n 'ex',\n 'cap',\n 'ic',\n 'lh',\n 'rlh',\n 'svw',\n 'svh',\n 'lvw',\n 'lvh',\n 'dvw',\n 'dvh',\n 'cqw',\n 'cqh',\n 'cqi',\n 'cqb',\n 'cqmin',\n 'cqmax',\n];\n\nconst ANGLE_UNITS = ['deg', 'rad', 'grad', 'turn'];\nconst TIME_UNITS = ['ms', 's'];\n\nfor (const u of LENGTH_UNITS) {\n UNIT_TO_SYNTAX[u] = { syntax: '<length-percentage>', initialValue: '0px' };\n}\nUNIT_TO_SYNTAX['%'] = { syntax: '<length-percentage>', initialValue: '0px' };\nfor (const u of ANGLE_UNITS) {\n UNIT_TO_SYNTAX[u] = { syntax: '<angle>', initialValue: '0deg' };\n}\nfor (const u of TIME_UNITS) {\n UNIT_TO_SYNTAX[u] = { syntax: '<time>', initialValue: '0s' };\n}\n\n/**\n * Infer CSS @property syntax from a concrete value.\n * Detects numeric types: \\<number\\>, \\<length-percentage\\>, \\<angle\\>, \\<time\\>.\n * Length and percentage values both map to \\<length-percentage\\> for maximum flexibility.\n * Color properties are handled separately via the #name token convention\n * (--name-color gets \\<color\\> syntax automatically in getEffectiveDefinition).\n *\n * @param value - The CSS value to infer from (e.g. '10px', '1', '45deg')\n * @returns Inferred syntax and initial value, or null if not inferable\n */\nexport function inferSyntaxFromValue(value: string): InferredSyntax | null {\n if (!value || typeof value !== 'string') return null;\n\n const trimmed = value.trim();\n if (!trimmed) return null;\n\n if (RE_NUMBER.test(trimmed)) {\n // Bare zero is ambiguous (could be <length>, <angle>, <percentage>, etc.)\n if (parseFloat(trimmed) === 0) return null;\n return { syntax: '<number>', initialValue: '0' };\n }\n\n const unitMatch = trimmed.match(RE_RAW_UNIT);\n if (unitMatch) {\n const unit = unitMatch[2];\n const mapping = UNIT_TO_SYNTAX[unit];\n if (mapping) return mapping;\n }\n\n return null;\n}\n","/**\n * Fast string hash (djb2) for deduplication keys.\n * Not cryptographic — just collision-resistant enough for cache keys.\n */\nexport function hashString(str: string): string {\n let hash = 5381;\n for (let i = 0; i < str.length; i++) {\n hash = ((hash << 5) + hash + str.charCodeAt(i)) | 0;\n }\n return (hash >>> 0).toString(36);\n}\n","/**\n * Name prefix utilities for generated identifiers.\n *\n * Tasty generates three kinds of identifiers from content hashes:\n * - class names (used in DOM `class` attribute)\n * - keyframe names (used in CSS `animation`)\n * - counter-style names (used in CSS `list-style-type`)\n *\n * All three derive from a single configurable prefix so that an app\n * can namespace every identifier under one string. Discriminator letters\n * (`k`, `c`) keep the three kinds visually distinct in devtools — they\n * are not required for correctness (CSS keeps these in separate\n * namespaces), only for readability.\n *\n * The runtime / SSR / RSC paths must agree on the prefix; otherwise the\n * client-side hash for a given style will not match the server-rendered\n * class and hydration breaks. The zero-runtime build path uses a\n * different default (`'ts'`) so its classes can't collide with runtime\n * (`'t'`) classes when both are loaded on the same page.\n */\n\n/** Default prefix used by the runtime / SSR / RSC paths. */\nexport const DEFAULT_NAME_PREFIX = 't';\n\n/** Default prefix used by the zero-runtime (`tastyStatic`) build path. */\nexport const DEFAULT_ZERO_NAME_PREFIX = 'ts';\n\n/**\n * Allowed shape: starts with a letter or underscore, then letters/\n * digits/underscore/hyphen. Length capped at 32 to keep generated\n * names sane. Matches the CSS identifier rules for the common case\n * while keeping the surface conservative.\n */\nconst NAME_PREFIX_PATTERN = /^[a-zA-Z_][a-zA-Z0-9_-]{0,31}$/;\n\n/**\n * Validate a `namePrefix` value.\n * Throws a TypeError with a descriptive message on invalid input so\n * misconfiguration fails loudly at `configure()` time rather than\n * surfacing later as broken hydration.\n */\nexport function validateNamePrefix(prefix: unknown): void {\n if (typeof prefix !== 'string') {\n throw new TypeError(\n `[Tasty] namePrefix must be a string, got ${typeof prefix}.`,\n );\n }\n if (!NAME_PREFIX_PATTERN.test(prefix)) {\n throw new TypeError(\n `[Tasty] namePrefix \"${prefix}\" is invalid. ` +\n `It must start with a letter (a-z, A-Z) or \"_\", contain only ` +\n `letters, digits, \"_\" or \"-\", and be 1-32 characters long. ` +\n `Examples: \"t\", \"ts\", \"myapp-\", \"_foo\".`,\n );\n }\n}\n\n/**\n * Build a class name: `${prefix}${hash}`.\n * The hash is appended verbatim — supply a separator inside the prefix\n * itself if you want one (e.g. `'myapp-'`).\n */\nexport function makeClassName(prefix: string, hash: string): string {\n return `${prefix}${hash}`;\n}\n\n/**\n * Build a keyframe name: `${prefix}k${suffix}`.\n * The `k` discriminator keeps keyframe names visually distinct from\n * class names sharing the same prefix. `suffix` is typically a content\n * hash but may be a counter for ad-hoc allocation.\n */\nexport function makeKeyframeName(prefix: string, suffix: string): string {\n return `${prefix}k${suffix}`;\n}\n\n/**\n * Build a counter-style name: `${prefix}c${suffix}`.\n * The `c` discriminator keeps counter-style names visually distinct\n * from class names sharing the same prefix.\n */\nexport function makeCounterStyleName(prefix: string, suffix: string): string {\n return `${prefix}c${suffix}`;\n}\n\n/** Escape a string for safe inclusion in a regex literal. */\nfunction escapeRegex(str: string): string {\n return str.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n}\n\n/**\n * Regex matching any tasty class for the given prefix.\n * Used by the runtime GC's DOM scan and class-allocation bookkeeping.\n */\nexport function tastyClassRegex(prefix: string): RegExp {\n return new RegExp(`^${escapeRegex(prefix)}[a-z0-9]+$`);\n}\n\n/**\n * Global regex extracting tasty class names from RSC-inlined CSS.\n * Looks for the doubled-specificity pattern `.cls.cls` that\n * `formatRules()` always emits, which makes extraction reliable.\n */\nexport function rscClassRegexGlobal(prefix: string): RegExp {\n return new RegExp(`\\\\.(${escapeRegex(prefix)}[a-z0-9]+)\\\\.\\\\1`, 'g');\n}\n","const PREFIX = '[Tasty]';\n\nexport function warn(...args: unknown[]) {\n console.warn(PREFIX, ...args);\n}\n","/**\n * Deferred CSSOM writes (\"batched injection\").\n *\n * Every `insertRule()` on a live stylesheet invalidates style for the sheet's\n * scope, so Blink recalculates style the next time anything reads layout or\n * computed style. When components inject during React's render phase and other\n * components read layout in the same pass, the two interleave:\n *\n * inject -> read (forced recalc) -> inject -> read (forced recalc) -> ...\n *\n * Batching moves every sheet write out from between those reads. Writes are\n * queued in FIFO order and drained in one go, so the tree is invalidated once\n * per flush instead of once per component.\n *\n * ## Ordering\n *\n * A single queue holds *all* writes — component rules, global rules, keyframes,\n * `@property`, `@font-face`, `@counter-style`, `@function` and raw CSS. Draining\n * it in insertion order keeps the sheet byte-identical to unbatched output,\n * which matters because equal-specificity rules resolve by document order.\n *\n * ## Batch windows — why queuing is safe\n *\n * Deferring a write past React's layout phase would let a `useLayoutEffect`\n * measure an element whose rules are not in the sheet yet, reading the unstyled\n * box. `<TastyBatchProvider>` closes that hole by opening a *window* during its\n * render and closing it — flushing — in its `useInsertionEffect`, which React\n * runs in the mutation phase, before any layout effect:\n *\n * provider renders -> window OPEN\n * children render -> injections queued\n * provider insertionEffect -> FLUSH, window CLOSED\n * layout effects run -> rules are in the sheet\n *\n * So in the default (`batchInjection: true`) mode a write is only ever queued\n * inside a commit whose flush is already guaranteed by that same commit. Every\n * injection outside a window — a deep update the provider did not re-render\n * for, a `useLayoutEffect` that injects, an event handler, an async callback —\n * is written straight through, exactly as with batching off.\n *\n * `batchInjection: 'always'` opts out of the gate and queues unconditionally.\n * That wins on more commits, at the cost of the measurement hazard above.\n *\n * ## Flush points (earliest wins)\n *\n * 1. `<TastyBatchProvider>`'s `useInsertionEffect` — closes the window.\n * 2. A microtask — a backstop for a render that was aborted or suspended and\n * therefore never reached its insertion effect. An aborted render mounts\n * nothing, so nothing can measure what it queued. Microtasks also always\n * drain before paint, so styles are never visually missing.\n * 3. `flushStyles()` — explicit, and called internally by every injector read\n * API (`getCSSText`, `cleanup`, `gc`, `destroy`, ...).\n */\n\nimport { isDevEnv } from '../utils/is-dev-env';\nimport { warn } from '../utils/warnings';\n\nexport interface QueuedWrite {\n /** Perform the deferred sheet write. */\n run: () => void;\n /** Set when the owner disposed before the write happened. */\n cancelled: boolean;\n /** Set once the write has been applied (or skipped as cancelled). */\n done: boolean;\n}\n\n/**\n * FIFO of pending writes. Drained with a moving `head` index rather than\n * `shift()` so a large batch stays O(n) instead of O(n²).\n */\nlet queue: QueuedWrite[] = [];\nlet head = 0;\nlet microtaskScheduled = false;\nlet flushing = false;\n\n/**\n * Whether a `<TastyBatchProvider>` has rendered in the current commit and will\n * therefore flush in its insertion effect, making it safe to queue a write.\n *\n * A flag rather than a depth count, because renders and insertion effects do\n * not pair up one-to-one. StrictMode double-invokes render but runs the\n * insertion effect once, so a counter ends the commit stuck above zero — and a\n * window that stays open past its commit turns the next provider-less commit\n * into `'always'` mode behind the user's back, which is exactly the measurement\n * hazard `true` exists to avoid.\n *\n * Clearing on the first close is safe with nested or sibling providers: React\n * finishes every render in a commit before running any insertion effect, so once\n * one closes, no further render-phase injection can arrive in that commit.\n */\nlet windowOpen = false;\n/** Whether any window has ever been opened, i.e. a provider is in the tree. */\nlet everOpened = false;\n/** Dev-only: warn at most once that batching is on with no provider mounted. */\nlet warnedNoProvider = false;\n\n/**\n * Queue a sheet write.\n *\n * Returns a handle whose `cancel()` drops the write if the caller disposes\n * before the flush. The handle is intentionally tiny — one is allocated per\n * injected class, on the cache-miss path only.\n */\nexport function enqueueStyleWrite(run: () => void): QueuedWrite {\n // A write triggered by the write currently being drained — an `@property`\n // rule inferred from declarations that are going into the sheet right now —\n // has to land at the position the drain is at, not behind everything already\n // queued after it. Appending would reorder the sheet against unbatched\n // output, so run it in place and hand back an already-done handle.\n if (flushing) {\n run();\n return { run, cancelled: false, done: true };\n }\n\n const entry: QueuedWrite = { run, cancelled: false, done: false };\n queue.push(entry);\n scheduleMicrotaskFlush();\n return entry;\n}\n\n/** Whether any write is still waiting to hit a stylesheet. */\nexport function hasPendingStyleWrites(): boolean {\n return head < queue.length;\n}\n\n/**\n * Open a batch window. Called from `<TastyBatchProvider>`'s render, so every\n * descendant injection in this commit is covered by the provider's insertion\n * effect.\n *\n * Called during render on purpose: the window must be open before children\n * render. It is idempotent — so StrictMode's double render costs nothing — and\n * carries no other side effect. A render that is thrown away is recovered by the\n * microtask backstop.\n *\n * A no-op without a `document`. On the server there is no sheet to batch\n * against, and `useInsertionEffect` never runs, so nothing would ever close a\n * window this opened. Skipping it keeps the provider inert during SSR and RSC\n * instead of merely harmless.\n */\nexport function openBatchWindow(): void {\n if (typeof document === 'undefined') return;\n windowOpen = true;\n everOpened = true;\n}\n\n/**\n * Close a batch window and flush. Called from the provider's\n * `useInsertionEffect`, i.e. after every render in the commit and before any\n * layout effect.\n */\nexport function closeBatchWindow(): void {\n windowOpen = false;\n flushStyles();\n}\n\n/** Whether a batch window is currently open. */\nexport function isBatchWindowOpen(): boolean {\n return windowOpen;\n}\n\nfunction scheduleMicrotaskFlush(): void {\n if (microtaskScheduled || flushing) return;\n microtaskScheduled = true;\n queueMicrotask(() => {\n microtaskScheduled = false;\n // Normally a no-op: the provider's insertion effect has already drained the\n // queue. This only does work when a render was aborted or suspended before\n // reaching that effect, or when running in `'always'` mode.\n windowOpen = false;\n flushStyles();\n });\n}\n\n/**\n * Drain every pending sheet write, in insertion order.\n *\n * Safe to call when the queue is empty (the common case, so the guard comes\n * first) and safe to call re-entrantly: a nested `flushStyles()` is a no-op,\n * and work a draining write triggers is written in place by\n * `enqueueStyleWrite` rather than queued behind the rest of the batch.\n */\nexport function flushStyles(): void {\n if (head >= queue.length) return;\n if (flushing) return;\n\n flushing = true;\n try {\n // `queue.length` is re-read every iteration so a write appended by anything\n // reachable from `run()` that does not go through `enqueueStyleWrite` still\n // gets drained by this loop instead of waiting for the next flush.\n while (head < queue.length) {\n const entry = queue[head++];\n if (entry.cancelled) {\n entry.done = true;\n continue;\n }\n entry.run();\n entry.done = true;\n }\n } finally {\n queue = [];\n head = 0;\n flushing = false;\n }\n}\n\n/**\n * Dev-only: `batchInjection: true` batches nothing unless a window opens, and no\n * window has ever opened, so no provider is in the tree. Called by the injector\n * the first time it declines to batch.\n */\nexport function warnBatchProviderMissing(): void {\n if (everOpened || warnedNoProvider || !isDevEnv()) return;\n warnedNoProvider = true;\n warn('[Tasty] batchInjection needs <TastyBatchProvider> mounted to batch.');\n}\n\n/**\n * Drop every pending write without applying it. Test helper — production code\n * should call `flushStyles()` instead.\n */\nexport function resetStyleBatch(): void {\n queue = [];\n head = 0;\n microtaskScheduled = false;\n flushing = false;\n windowOpen = false;\n everOpened = false;\n warnedNoProvider = false;\n}\n","/**\n * PropertyTypeResolver\n *\n * Automatically infers CSS @property types from custom property values.\n * Supports deferred resolution for var() reference chains of arbitrary depth.\n */\n\nimport { inferSyntaxFromValue } from './index';\n\nconst CUSTOM_PROP_DECL = /^\\s*(--[a-z0-9_-]+)\\s*:\\s*(.+?)\\s*$/i;\nconst SINGLE_VAR_REF = /^var\\((--[a-z0-9_-]+)\\)$/i;\n\nexport class PropertyTypeResolver {\n /** propName → the prop it depends on */\n private pendingDeps = new Map<string, string>();\n /** propName → list of props waiting on it */\n private reverseDeps = new Map<string, string[]>();\n\n /**\n * Scan CSS declarations and auto-register @property for custom properties\n * whose types can be inferred from their values.\n */\n scanDeclarations(\n declarations: string,\n isPropertyDefined: (name: string) => boolean,\n registerProperty: (\n name: string,\n syntax: string,\n initialValue: string,\n ) => void,\n ): void {\n if (!declarations.includes('--')) return;\n\n const parts = declarations.split(/;+/);\n\n for (const part of parts) {\n if (!part.trim()) continue;\n\n const match = CUSTOM_PROP_DECL.exec(part);\n if (!match) continue;\n\n const propName = match[1];\n const value = match[2].trim();\n\n if (isPropertyDefined(propName)) continue;\n\n // Name-based: --*-color properties are always <color> (from #name tokens)\n if (propName.endsWith('-color')) {\n registerProperty(propName, '<color>', 'transparent');\n continue;\n }\n\n // Name-based: --*-line-height accepts numbers, lengths, and percentages\n if (propName.endsWith('-line-height')) {\n registerProperty(propName, '<number> | <length-percentage>', '0');\n continue;\n }\n\n // Name-based: --*-opacity accepts numbers and percentages\n if (propName.endsWith('-opacity')) {\n registerProperty(propName, '<number> | <percentage>', '0');\n continue;\n }\n\n // Single var() reference → record dependency for deferred resolution\n const varMatch = SINGLE_VAR_REF.exec(value);\n if (varMatch) {\n const depName = varMatch[1];\n this.addDependency(propName, depName);\n continue;\n }\n\n // Skip complex expressions (calc, multiple var, etc.)\n if (this.isComplexValue(value)) continue;\n\n const inferred = inferSyntaxFromValue(value);\n if (!inferred) continue;\n\n this.resolve(\n propName,\n inferred.syntax,\n inferred.initialValue,\n isPropertyDefined,\n registerProperty,\n );\n }\n }\n\n private addDependency(propName: string, depName: string): void {\n if (propName === depName) return;\n\n this.pendingDeps.set(propName, depName);\n\n let dependents = this.reverseDeps.get(depName);\n if (!dependents) {\n dependents = [];\n this.reverseDeps.set(depName, dependents);\n }\n if (!dependents.includes(propName)) {\n dependents.push(propName);\n }\n }\n\n private resolve(\n propName: string,\n syntax: string,\n initialValue: string,\n isPropertyDefined: (name: string) => boolean,\n registerProperty: (\n name: string,\n syntax: string,\n initialValue: string,\n ) => void,\n resolving?: Set<string>,\n ): void {\n if (!resolving) resolving = new Set();\n if (resolving.has(propName)) return;\n resolving.add(propName);\n\n if (!isPropertyDefined(propName)) {\n registerProperty(propName, syntax, initialValue);\n }\n\n const dependents = this.reverseDeps.get(propName);\n if (dependents) {\n this.reverseDeps.delete(propName);\n\n for (const dependent of dependents) {\n this.pendingDeps.delete(dependent);\n\n if (isPropertyDefined(dependent)) continue;\n\n this.resolve(\n dependent,\n syntax,\n initialValue,\n isPropertyDefined,\n registerProperty,\n resolving,\n );\n }\n }\n }\n\n private isComplexValue(value: string): boolean {\n if (value.includes('calc(')) return true;\n const firstVar = value.indexOf('var(');\n if (firstVar === -1) return false;\n if (value.indexOf('var(', firstVar + 4) !== -1) return true;\n return !SINGLE_VAR_REF.test(value);\n }\n}\n","export const BORDER_STYLES = [\n 'none',\n 'hidden',\n 'dotted',\n 'dashed',\n 'solid',\n 'double',\n 'groove',\n 'ridge',\n 'inset',\n 'outset',\n] as const;\n","import { CSS_WIDE_KEYWORDS } from '../parser/const';\nimport { DIRECTIONS, filterMods, parseStyle } from '../utils/styles';\nimport { BORDER_STYLES } from './const';\nimport { assignLineSlots, extractCSSWideKeyword } from './shared';\n\ntype Direction = (typeof DIRECTIONS)[number];\n\ninterface GroupData {\n values: string[];\n mods: string[];\n colors: string[];\n}\n\ninterface BorderValue {\n width: string;\n style: string;\n color: string;\n}\n\n/**\n * Process a single group and return border values for its directions.\n * @returns Object with directions as keys and border values, or null for \"all directions\"\n */\nfunction processGroup(group: GroupData): {\n directions: Direction[];\n borderValue: BorderValue;\n} {\n const { values, mods, colors } = group;\n\n const directions = filterMods(mods, DIRECTIONS) as Direction[];\n const typeMods = filterMods(mods, BORDER_STYLES as unknown as string[]);\n\n const slots = assignLineSlots(values, typeMods[0], colors?.[0]);\n\n const width = values[0] || 'var(--border-width)';\n const style = slots.style || 'solid';\n const color = slots.color || 'var(--border-color, currentColor)';\n\n return {\n directions,\n borderValue: { width, style, color },\n };\n}\n\n/**\n * Format a border value to CSS string.\n */\nfunction formatBorderValue(value: BorderValue): string {\n return `${value.width} ${value.style} ${value.color}`;\n}\n\n/**\n * Border style handler with multi-group support.\n *\n * Single group (backward compatible):\n * - `border=\"1bw solid #red\"` - all sides\n * - `border=\"1bw solid #red top left\"` - only top and left\n *\n * Multi-group (new):\n * - `border=\"1bw #red, 2bw #blue top\"` - all sides red 1bw, then top overridden to blue 2bw\n * - `border=\"1bw, dashed top bottom, #purple left right\"` - base 1bw, dashed on top/bottom, purple on left/right\n *\n * Later groups override earlier groups for conflicting directions.\n */\nexport function borderStyle({\n border,\n}: {\n border?: string | number | boolean;\n}) {\n if (!border && border !== 0) return null;\n\n if (border === true) border = '1bw';\n\n const strBorder = String(border);\n\n if (CSS_WIDE_KEYWORDS.has(strBorder)) {\n return { border: strBorder };\n }\n\n const processed = parseStyle(strBorder);\n const groups = processed.groups ?? [];\n\n if (!groups.length) return null;\n\n const useLonghand = groups.some((g) => (g.mods ?? []).includes('longhand'));\n\n // Single group - use original logic for backward compatibility\n if (groups.length === 1) {\n const group = groups[0];\n const keyword = extractCSSWideKeyword(group);\n\n if (keyword) {\n if (useLonghand) {\n return Object.fromEntries(\n DIRECTIONS.map((dir) => [`border-${dir}`, keyword]),\n );\n }\n\n return { border: keyword };\n }\n\n const { directions, borderValue } = processGroup({\n values: group.values ?? [],\n mods: group.mods ?? [],\n colors: group.colors ?? [],\n });\n\n const styleValue = formatBorderValue(borderValue);\n\n if (!directions.length) {\n if (useLonghand) {\n return Object.fromEntries(\n DIRECTIONS.map((dir) => [`border-${dir}`, styleValue]),\n );\n }\n\n return { border: styleValue };\n }\n\n const zeroValue = `0 ${borderValue.style} ${borderValue.color}`;\n\n return DIRECTIONS.reduce(\n (styles, dir) => {\n if (directions.includes(dir)) {\n styles[`border-${dir}`] = styleValue;\n } else {\n styles[`border-${dir}`] = zeroValue;\n }\n return styles;\n },\n {} as Record<string, string>,\n );\n }\n\n // Multi-group - process groups in order, later groups override earlier\n // Track whether any group specifies directions\n let hasAnyDirections = false;\n\n // Build a map of direction -> border value\n // Start with undefined (no border set)\n const directionMap: Record<Direction, BorderValue | null> = {\n top: null,\n right: null,\n bottom: null,\n left: null,\n };\n\n // Track the last \"all directions\" value for fallback\n let allDirectionsValue: BorderValue | null = null;\n\n // Process groups in order (first to last)\n for (const group of groups) {\n const { directions, borderValue } = processGroup({\n values: group.values ?? [],\n mods: group.mods ?? [],\n colors: group.colors ?? [],\n });\n\n if (directions.length === 0) {\n // No specific directions - applies to all\n allDirectionsValue = borderValue;\n // Set all directions\n for (const dir of DIRECTIONS) {\n directionMap[dir] = borderValue;\n }\n } else {\n // Specific directions - override only those\n hasAnyDirections = true;\n for (const dir of directions) {\n directionMap[dir] = borderValue;\n }\n }\n }\n\n // If no group specified any directions and we have an all-directions value,\n // return the simple `border` shorthand (or longhands if requested)\n if (!hasAnyDirections && allDirectionsValue) {\n const formatted = formatBorderValue(allDirectionsValue);\n\n if (useLonghand) {\n return Object.fromEntries(\n DIRECTIONS.map((dir) => [`border-${dir}`, formatted]),\n );\n }\n\n return { border: formatted };\n }\n\n // Otherwise, output individual border-* properties\n const result: Record<string, string> = {};\n\n for (const dir of DIRECTIONS) {\n const value = directionMap[dir];\n if (value) {\n result[`border-${dir}`] = formatBorderValue(value);\n } else {\n // No border for this direction - set to 0\n // Use the last all-directions value for style/color consistency, or defaults\n const fallback = allDirectionsValue || {\n width: '0',\n style: 'solid',\n color: 'var(--border-color, currentColor)',\n };\n result[`border-${dir}`] = `0 ${fallback.style} ${fallback.color}`;\n }\n }\n\n return result;\n}\n\nborderStyle.__lookupStyles = ['border'];\n","import { parseColor, resolveCustomProperties } from '../utils/styles';\n\n/**\n * A color that already resolves against the color the element inherits, and so\n * must not be republished as `--current-color`. Covers both spellings: the\n * variable (a self-reference) and the keyword (a second resolution).\n */\nconst RE_READS_CURRENT = /var\\(--current-color[,)]|currentcolor/i;\n\nexport function colorStyle({ color }: { color?: string | boolean }) {\n if (!color) return null;\n\n if (color === true) color = 'currentColor';\n\n // Resolve whatever the parser recognizes as a color — a `#token`, a fallback\n // chain, a color function with tokens inside it. Anything else (a keyword, a\n // bare `$name`) is emitted verbatim, so references still need substituting or\n // the raw DSL leaks into the declaration.\n color = parseColor(color, true).color || resolveCustomProperties(color);\n\n const styles: Record<string, string> = { color };\n\n // Republish the color as `--current-color` so `#current` resolves to a\n // concrete value rather than the `currentcolor` keyword. Every color is\n // published, not only a named token: `color: 'red'` has to displace an\n // ancestor's token color, or a descendant's `#current` would read the\n // ancestor's and not this element's.\n //\n // A value that already reads the color it inherits is skipped. Publishing\n // `var(--current-color)` into `--current-color` is a self-reference, which\n // invalidates the declaration and silently drops back to the initial value;\n // publishing a `color-mix()` over `currentcolor` would be resolved again at\n // the descendant and fade twice.\n if (!RE_READS_CURRENT.test(color)) {\n styles['--current-color'] = color;\n }\n\n return styles;\n}\n\ncolorStyle.__lookupStyles = ['color'];\n","import { normalizeDslName, toSnakeCase } from '../utils/string';\nimport {\n normalizeColorTokenValue,\n parseColor,\n parseStyle,\n} from '../utils/styles';\nimport type {\n CSSMap,\n StyleHandler,\n StyleValue,\n StyleValueStateMap,\n} from '../utils/styles';\n\nconst CACHE: Record<string, StyleHandler> = {};\n\nexport function createStyle(\n styleName: string,\n cssStyle?: string,\n converter?: (styleValue: string | number | true) => string | undefined,\n) {\n const key = `${styleName}.${cssStyle ?? ''}`;\n\n if (!CACHE[key]) {\n const styleHandler = (styleMap: StyleValueStateMap): CSSMap | null => {\n let styleValue = styleMap[styleName];\n\n if (styleValue == null || styleValue === false) return null;\n\n let finalCssStyle: string;\n const isColorToken =\n !cssStyle && typeof styleName === 'string' && styleName.startsWith('#');\n\n if (isColorToken) {\n finalCssStyle = `--${normalizeDslName(styleName.slice(1))}-color`;\n } else if (!cssStyle && styleName[0] === '$') {\n // A `$name` key names a custom property, so it keeps its case rather than\n // being kebab-cased — `$myVar` has to reach the same `--myVar` that\n // `$myVar` in a value references.\n finalCssStyle = `--${normalizeDslName(styleName.slice(1))}`;\n } else {\n finalCssStyle = cssStyle || toSnakeCase(styleName);\n }\n\n if (isColorToken) {\n const normalized = normalizeColorTokenValue(styleValue);\n if (normalized === null) return null;\n styleValue = normalized;\n }\n\n if (converter) {\n const converted = converter(styleValue as string | number | true);\n\n if (converted) {\n styleValue = converted;\n } else if (typeof styleValue !== 'string') {\n // A converter declining a non-string value leaves nothing to emit —\n // `true` and numbers have no meaningful CSS serialization on their\n // own. Strings are already valid CSS, so they pass through untouched.\n return null;\n }\n }\n\n if (\n typeof styleValue === 'string' &&\n finalCssStyle.startsWith('--') &&\n finalCssStyle.endsWith('-color')\n ) {\n styleValue = styleValue.trim();\n\n // The color is emitted as the parser resolved it: a `#token` or fallback\n // chain becomes its `var()` chain, a color function keeps its expanded\n // tokens, a literal or keyword passes through as authored. Nothing needs\n // rewriting into a particular color space — opacity is applied with\n // relative color syntax, which reads the channels off whatever the\n // browser resolves the value to.\n return {\n [finalCssStyle]: parseColor(styleValue as string).color ?? '',\n };\n }\n\n const processed = parseStyle(styleValue as StyleValue);\n return { [finalCssStyle]: processed.output };\n };\n\n styleHandler.__lookupStyles = [styleName];\n\n CACHE[key] = styleHandler;\n }\n\n return CACHE[key];\n}\n","import { parseStyle, resolveCustomProperties } from '../utils/styles';\n\ninterface DisplayStyleProps {\n display?: string;\n hide?: boolean;\n textOverflow?: string | boolean;\n overflow?: string;\n whiteSpace?: string;\n}\n\n/**\n * Process textOverflow into CSS properties for truncation/clamping.\n *\n * - `ellipsis` — single-line truncation with ellipsis\n * - `ellipsis / 3` — multi-line clamping (3 lines) with ellipsis\n * - `clip` — single-line truncation with clip\n * - `clip / 2` — multi-line clip (2 lines)\n * - `true` or `initial` — reset to initial\n */\nfunction processTextOverflow(\n textOverflow: string | boolean,\n whiteSpace?: string,\n): Record<string, string | number> | null {\n if (textOverflow === true || textOverflow === 'initial') {\n return { 'text-overflow': 'initial' };\n }\n\n const processed = parseStyle(String(textOverflow));\n const group = processed.groups[0];\n\n if (!group) return null;\n\n const { parts } = group;\n const modePart = parts[0];\n const clampPart = parts[1];\n\n const hasEllipsis = modePart?.mods.includes('ellipsis');\n const hasClip = modePart?.mods.includes('clip');\n\n if (!hasEllipsis && !hasClip) return null;\n\n let clamp = 1;\n\n if (clampPart?.values[0]) {\n const parsed = parseInt(clampPart.values[0], 10);\n\n if (!isNaN(parsed) && parsed > 0) {\n clamp = parsed;\n }\n }\n\n const result: Record<string, string | number> = {\n overflow: 'hidden',\n 'text-overflow': hasEllipsis ? 'ellipsis' : 'clip',\n };\n\n if (clamp === 1) {\n result['white-space'] = whiteSpace || 'nowrap';\n } else {\n result['display'] = '-webkit-box';\n result['-webkit-box-orient'] = 'vertical';\n result['-webkit-line-clamp'] = clamp;\n result['line-clamp'] = clamp;\n result['white-space'] = whiteSpace || 'initial';\n }\n\n return result;\n}\n\n/**\n * Handles display, hide, textOverflow, overflow, and whiteSpace styles.\n *\n * Priority:\n * 1. `hide` takes precedence (display: none)\n * 2. Multi-line `textOverflow` forces display: -webkit-box\n * 3. Single-line `textOverflow` defaults white-space to nowrap\n * 4. Explicit `whiteSpace` overrides the default from `textOverflow`\n */\nexport function displayStyle({\n display,\n hide,\n textOverflow,\n overflow,\n whiteSpace,\n}: DisplayStyleProps) {\n const result: Record<string, string | number> = {};\n\n // Resolved once up front: `processTextOverflow` emits `whiteSpace` as the\n // clamp's `white-space` too, so substituting only at the branch below would\n // still leak the raw reference through the truncation path.\n const whiteSpaceValue = whiteSpace\n ? resolveCustomProperties(whiteSpace)\n : whiteSpace;\n\n if (textOverflow != null && textOverflow !== false) {\n const textResult = processTextOverflow(textOverflow, whiteSpaceValue);\n\n if (textResult) Object.assign(result, textResult);\n }\n\n if (overflow && !result['overflow']) {\n result['overflow'] = resolveCustomProperties(overflow);\n }\n if (whiteSpaceValue && !result['white-space']) {\n result['white-space'] = whiteSpaceValue;\n }\n\n if (hide) {\n result['display'] = 'none';\n } else if (!result['display'] && display) {\n result['display'] = resolveCustomProperties(display);\n }\n\n if (Object.keys(result).length === 0) {\n return null;\n }\n\n return result;\n}\n\ndisplayStyle.__lookupStyles = [\n 'display',\n 'hide',\n 'textOverflow',\n 'overflow',\n 'whiteSpace',\n];\n","import { CSS_WIDE_KEYWORDS } from '../parser/const';\nimport { DIRECTIONS, filterMods, parseStyle } from '../utils/styles';\n\nimport { warnExtraGroupValues } from './shared';\n\nconst DIRECTION_MAP: Record<(typeof DIRECTIONS)[number], string> = {\n right: 'to left',\n left: 'to right',\n top: 'to bottom',\n bottom: 'to top',\n};\n\n// Default mask colors (standard black with alpha for gradient masks)\nconst DEFAULT_TRANSPARENT_COLOR = 'rgb(0 0 0 / 0)';\nconst DEFAULT_OPAQUE_COLOR = 'rgb(0 0 0 / 1)';\n\ninterface GroupData {\n input: string;\n values: string[];\n mods: string[];\n colors: string[];\n}\n\n/**\n * Process a single group and return gradient strings for its directions.\n */\nfunction processGroup(group: GroupData, isOnlyGroup: boolean): string[] {\n let { values } = group;\n const { input, mods, colors } = group;\n\n const named = filterMods(mods, DIRECTIONS) as (typeof DIRECTIONS)[number][];\n let directions = named;\n\n if (!values.length) {\n values = ['calc(2 * var(--gap))'];\n }\n\n // If this is the only group and no directions specified, apply to all edges\n if (!directions.length) {\n if (isOnlyGroup) {\n directions = ['top', 'right', 'bottom', 'left'];\n } else {\n // For multi-group without explicit direction, skip this group\n return [];\n }\n }\n\n // Extract colors: first = transparent mask color, second = opaque mask color\n const transparentColor = colors?.[0] || DEFAULT_TRANSPARENT_COLOR;\n const opaqueColor = colors?.[1] || DEFAULT_OPAQUE_COLOR;\n\n // A group that names edges takes a single width, applied to every edge it\n // names — different widths per edge come from comma groups\n // (`fade: '3x top, 1x bottom'`). A group that names none covers all four\n // edges and keeps plain CSS shorthand order, so `fade: '3x 1x'` fades block\n // edges at 3x and inline edges at 1x, matching `padding`.\n if (named.length > 0 && values.length > 1) {\n warnExtraGroupValues('fade', input, 1);\n }\n\n return directions.map(\n (direction: (typeof DIRECTIONS)[number], index: number) => {\n const size =\n named.length > 0\n ? values[0]\n : values[index] || values[index % 2] || values[0];\n\n return `linear-gradient(${DIRECTION_MAP[direction]}, ${transparentColor} 0%, ${opaqueColor} ${size})`;\n },\n );\n}\n\nexport function fadeStyle({ fade }: { fade?: string }) {\n if (!fade) return null;\n\n if (CSS_WIDE_KEYWORDS.has(fade)) {\n return { mask: fade, 'mask-composite': fade };\n }\n\n const processed = parseStyle(fade);\n const groups: GroupData[] = processed.groups ?? [];\n\n if (!groups.length) return null;\n\n const isOnlyGroup = groups.length === 1;\n\n // Process all groups and collect gradients\n const gradients: string[] = [];\n\n for (const group of groups) {\n const groupGradients = processGroup(\n {\n input: group.input ?? '',\n values: group.values ?? [],\n mods: group.mods ?? [],\n colors: group.colors ?? [],\n },\n isOnlyGroup,\n );\n gradients.push(...groupGradients);\n }\n\n if (!gradients.length) return null;\n\n return {\n mask: gradients.join(', '),\n 'mask-composite': 'intersect',\n };\n}\n\nfadeStyle.__lookupStyles = ['fade'];\n","import { parseStyle, resolveCustomProperties } from '../utils/styles';\n\nexport function fillStyle({\n fill,\n backgroundColor,\n image,\n backgroundImage,\n backgroundPosition,\n backgroundSize,\n backgroundRepeat,\n backgroundAttachment,\n backgroundOrigin,\n backgroundClip,\n background,\n}: {\n fill?: string;\n backgroundColor?: string;\n image?: string;\n backgroundImage?: string;\n backgroundPosition?: string;\n backgroundSize?: string;\n backgroundRepeat?: string;\n backgroundAttachment?: string;\n backgroundOrigin?: string;\n backgroundClip?: string;\n background?: string;\n}) {\n // If background is set, it overrides everything\n if (background) {\n const processed = parseStyle(background);\n return { background: processed.output || background };\n }\n\n const result: Record<string, string> = {};\n\n // Priority: backgroundColor > fill\n const colorValue = backgroundColor ?? fill;\n if (colorValue) {\n const parsed = parseStyle(colorValue);\n const firstColor = parsed.groups[0]?.colors[0];\n const secondColor = parsed.groups[0]?.colors[1];\n\n // No color found: the value may still be a custom-property reference the\n // parser classified as a plain value (`$name` is a color only when the name\n // ends with `-color`), so substitute before falling back to the raw input.\n result['background-color'] =\n firstColor || resolveCustomProperties(colorValue);\n\n if (secondColor) {\n result['--tasty-second-fill-color'] = secondColor;\n }\n }\n\n const gradientLayer = result['--tasty-second-fill-color']\n ? 'linear-gradient(var(--tasty-second-fill-color), var(--tasty-second-fill-color))'\n : null;\n\n // Priority: backgroundImage > image\n const imageValue = backgroundImage ?? image;\n if (imageValue) {\n const parsed = parseStyle(imageValue);\n const imgCss = parsed.output || imageValue;\n\n result['background-image'] = gradientLayer\n ? `${imgCss}, ${gradientLayer}`\n : imgCss;\n } else if (gradientLayer) {\n result['background-image'] = gradientLayer;\n }\n\n // Other background properties (pass through with parseStyle for token support)\n if (backgroundPosition) {\n result['background-position'] =\n parseStyle(backgroundPosition).output || backgroundPosition;\n }\n if (backgroundSize) {\n result['background-size'] =\n parseStyle(backgroundSize).output || backgroundSize;\n }\n if (backgroundRepeat) {\n result['background-repeat'] = resolveCustomProperties(backgroundRepeat);\n }\n if (backgroundAttachment) {\n result['background-attachment'] =\n resolveCustomProperties(backgroundAttachment);\n }\n if (backgroundOrigin) {\n result['background-origin'] = resolveCustomProperties(backgroundOrigin);\n }\n if (backgroundClip) {\n result['background-clip'] = resolveCustomProperties(backgroundClip);\n }\n\n if (Object.keys(result).length === 0) return null;\n return result;\n}\n\nfillStyle.__lookupStyles = [\n 'fill',\n 'backgroundColor',\n 'image',\n 'backgroundImage',\n 'backgroundPosition',\n 'backgroundSize',\n 'backgroundRepeat',\n 'backgroundAttachment',\n 'backgroundOrigin',\n 'backgroundClip',\n 'background',\n];\n\nexport function svgFillStyle({ svgFill }: { svgFill?: string }) {\n if (!svgFill) return null;\n\n const processed = parseStyle(svgFill);\n svgFill = processed.groups[0]?.colors[0] || resolveCustomProperties(svgFill);\n\n return { fill: svgFill };\n}\n\nsvgFillStyle.__lookupStyles = ['svgFill'];\n","import { resolveCustomProperties } from '../utils/styles';\n\nexport function flowStyle({\n display = 'block',\n flow,\n}: {\n display?: string;\n flow?: string;\n}) {\n let style;\n\n if (display.includes('grid')) {\n style = 'grid-auto-flow';\n } else if (display.includes('flex')) {\n style = 'flex-flow';\n }\n\n return style && flow ? { [style]: resolveCustomProperties(flow) } : null;\n}\n\nflowStyle.__lookupStyles = ['display', 'flow'];\n","import { CSS_WIDE_KEYWORDS } from '../parser/const';\nimport { makeEmptyDetails } from '../parser/types';\nimport { parseStyle } from '../utils/styles';\n\nexport function gapStyle({\n display = 'block',\n flow,\n gap,\n}: {\n display?: string;\n flow?: string;\n gap?: string | number | boolean;\n}) {\n if (typeof gap === 'number') {\n gap = `${gap}px`;\n }\n\n if (!gap) {\n return null;\n }\n\n if (gap === true) {\n gap = '1x';\n }\n\n if (CSS_WIDE_KEYWORDS.has(String(gap))) {\n return { gap: String(gap) };\n }\n\n const isGrid = display.includes('grid');\n const isFlex = display.includes('flex');\n const isWrap = flow\n ? flow.includes('wrap') && !flow.includes('nowrap')\n : false;\n\n if (!isGrid && flow == null) {\n flow = isFlex ? 'row' : 'column';\n }\n\n const processed = parseStyle(gap);\n const { values } = processed.groups[0] ?? makeEmptyDetails();\n\n gap = values.join(' ');\n\n if (isGrid || isFlex) {\n return { gap };\n }\n\n const gapDir = flow?.includes('row') ? 'right' : 'bottom';\n\n return isWrap\n ? [\n {\n 'margin-right': `calc(-1 * ${values[1] || values[0]})`,\n 'margin-bottom': `calc(-1 * ${values[0]})`,\n },\n {\n $: '& > *',\n 'margin-right': values[1] || values[0],\n 'margin-bottom': values[0],\n },\n ]\n : {\n $: '& > *:not(:last-child)',\n [`margin-${gapDir}`]: gap,\n };\n}\n\ngapStyle.__lookupStyles = ['display', 'flow', 'gap'];\n","import { CSS_WIDE_KEYWORDS } from '../parser/const';\nimport { makeEmptyDetails } from '../parser/types';\nimport { parseStyle } from '../utils/styles';\n\nconst DEFAULT_MIN_SIZE = 'var(--gap)';\nconst DEFAULT_MAX_SIZE = '100%';\n\n/**\n * Parse a dimension value (string, number, or boolean) into a CSS value\n */\nfunction parseDimensionValue(\n val: string | number | boolean | undefined,\n): string | null {\n if (val == null) return null;\n if (typeof val === 'number') return `${val}px`;\n if (val === true) return 'initial';\n\n const processed = parseStyle(String(val));\n return processed.groups[0]?.values[0] || null;\n}\n\ninterface DimensionProps {\n value?: string | number | boolean;\n min?: string | number | boolean;\n max?: string | number | boolean;\n}\n\n/**\n * Creates a dimension style handler for width or height.\n *\n * Supports:\n * - Main dimension prop (width/height) with syntax for min/max\n * - Separate min/max props (minWidth/maxWidth or minHeight/maxHeight)\n *\n * Priority: Individual min/max props override values from main prop syntax\n */\nexport function dimensionStyle(name: 'width' | 'height') {\n const minStyle = `min-${name}`;\n const maxStyle = `max-${name}`;\n\n return ({ value, min, max }: DimensionProps) => {\n if (value == null && min == null && max == null) return null;\n\n if (\n value != null &&\n typeof value === 'string' &&\n CSS_WIDE_KEYWORDS.has(value)\n ) {\n const styles: Record<string, string> = {\n [name]: value,\n [minStyle]: value,\n [maxStyle]: value,\n };\n\n const minVal = parseDimensionValue(min);\n const maxVal = parseDimensionValue(max);\n if (minVal) styles[minStyle] = minVal;\n if (maxVal) styles[maxStyle] = maxVal;\n\n return styles;\n }\n\n if (value === true) {\n const styles: Record<string, string | string[]> = {\n [name]: 'auto',\n [minStyle]: 'initial',\n [maxStyle]: 'initial',\n };\n\n // Apply individual min/max overrides\n const minVal = parseDimensionValue(min);\n const maxVal = parseDimensionValue(max);\n if (minVal) styles[minStyle] = minVal;\n if (maxVal) styles[maxStyle] = maxVal;\n\n return styles;\n }\n\n const styles: Record<string, string | string[]> = {\n [name]: 'auto',\n [minStyle]: 'initial',\n [maxStyle]: 'initial',\n };\n\n // Process main dimension value\n if (value != null) {\n let val = value;\n if (typeof val === 'number') {\n val = `${val}px`;\n }\n\n val = String(val);\n\n const processed = parseStyle(val);\n const { mods, values } = processed.groups[0] ?? makeEmptyDetails();\n\n let flag = false;\n\n for (const mod of mods) {\n switch (mod) {\n case 'min':\n styles[minStyle] = values[0] || DEFAULT_MIN_SIZE;\n flag = true;\n break;\n case 'max':\n styles[maxStyle] = values[0] || DEFAULT_MAX_SIZE;\n flag = true;\n break;\n case 'fixed': {\n // Fixed modifier: set all three dimensions to the same value\n const fixedValue = values[0] || 'max-content';\n styles[minStyle] = fixedValue;\n styles[name] = fixedValue;\n styles[maxStyle] = fixedValue;\n flag = true;\n break;\n }\n default:\n break;\n }\n }\n\n if (!flag || !mods.length) {\n if (values.length === 2) {\n styles[minStyle] = values[0];\n styles[maxStyle] = values[1];\n } else if (values.length === 3) {\n styles[minStyle] = values[0];\n styles[name] = values[1];\n styles[maxStyle] = values[2];\n } else {\n styles[name] = values[0] || 'auto';\n }\n }\n\n if (styles[name] === 'stretch') {\n if (name === 'width') {\n styles[name] = [\n 'stretch',\n '-webkit-fill-available',\n '-moz-available',\n ];\n } else {\n styles[name] = 'auto';\n }\n }\n }\n\n // Apply individual min/max props (higher priority, override main prop syntax)\n const minVal = parseDimensionValue(min);\n const maxVal = parseDimensionValue(max);\n if (minVal) styles[minStyle] = minVal;\n if (maxVal) styles[maxStyle] = maxVal;\n\n return styles;\n };\n}\n","import { dimensionStyle } from './dimension';\n\nconst dimension = dimensionStyle('height');\n\ninterface HeightStyleProps {\n height?: string | number | boolean;\n minHeight?: string | number | boolean;\n maxHeight?: string | number | boolean;\n}\n\nexport function heightStyle({\n height,\n minHeight,\n maxHeight,\n}: HeightStyleProps) {\n return dimension({ value: height, min: minHeight, max: maxHeight });\n}\n\nheightStyle.__lookupStyles = ['height', 'minHeight', 'maxHeight'];\n","import type { StyleDetails } from '../parser/types';\nimport { CSS_WIDE_KEYWORDS } from '../parser/const';\nimport { DIRECTIONS, filterMods, parseStyle } from '../utils/styles';\nimport { extractCSSWideKeyword, warnExtraGroupValues } from './shared';\n\ntype Direction = (typeof DIRECTIONS)[number];\n\nexport interface DirectionalConfig {\n /** CSS property name (e.g. 'padding', 'margin', 'inset', 'scroll-margin') */\n property: string;\n /** Default value when parsing yields empty (e.g. 'var(--gap)', '0') */\n defaultValue: string;\n /** Value used when the prop is `true` (e.g. '1x', '0') */\n trueValue: string;\n /** Default per-direction init value (e.g. '0', 'auto') */\n defaultInit: string;\n /**\n * When true, if only individual direction props are set (no shorthand,\n * no block/inline), output individual CSS properties instead of the\n * shorthand. Needed by inset for correct CSS cascade with modifiers.\n */\n individualOnly?: boolean;\n /**\n * Maps individual direction CSS property names. Defaults to\n * `${property}-top`, `${property}-right`, etc. For inset this is\n * `top`, `right`, `bottom`, `left`.\n */\n directionProperty?: (dir: Direction) => string;\n /**\n * Modifiers that expand the named side(s) to also cover the perpendicular\n * pair, so `inset: 'bottom dock'` pins the bottom edge and spans the full\n * width (`inset: auto 0 0 0`).\n *\n * Opt-in per property: only `inset` docks to an edge, so `padding`, `margin`\n * and `scrollMargin` ignore the modifier and treat it as an unknown mod.\n */\n spanModifiers?: readonly string[];\n}\n\nfunction parseSingleValue(\n val: string | number | boolean,\n defaultValue: string,\n trueValue: string,\n): string | null {\n if (typeof val === 'number') return `${val}px`;\n if (!val) return null;\n if (val === true) val = trueValue;\n\n const strVal = String(val);\n\n if (CSS_WIDE_KEYWORDS.has(strVal)) return strVal;\n\n const { values } = parseStyle(strVal).groups[0] ?? { values: [] };\n\n return values[0] || defaultValue;\n}\n\nfunction extractGroupData(\n group: StyleDetails,\n property: string,\n defaultValue: string,\n spanModifiers?: readonly string[],\n): {\n values: string[];\n directions: Direction[];\n span: boolean;\n} {\n const { values = [], mods = [] } = group;\n const directions = filterMods(mods, DIRECTIONS) as Direction[];\n const span = !!spanModifiers?.some((mod) => mods.includes(mod));\n\n // A group that names directions carries one value — two with a span modifier.\n // Guarded inline so the valid path costs a single comparison.\n if (directions.length > 0 && values.length > (span ? 2 : 1)) {\n warnExtraGroupValues(property, group.input, span ? 2 : 1);\n }\n\n return {\n values: values.length ? values : [defaultValue],\n directions,\n span,\n };\n}\n\nfunction applyGroup(\n dirs: Record<Direction, string>,\n values: string[],\n directions: Direction[],\n span = false,\n): void {\n if (!values.length) return;\n\n if (directions.length === 0) {\n // No direction named — plain CSS shorthand order (1-4 values). Unambiguous,\n // so it keeps working: `padding: '1x 2x'` is block 1x / inline 2x.\n dirs.top = values[0];\n dirs.right = values[1] || values[0];\n dirs.bottom = values[2] || values[0];\n dirs.left = values[3] || values[1] || values[0];\n\n return;\n }\n\n // A group that names directions has one meaningful value, applied to every\n // named direction: `padding: '2x top, 4x right'`, not `'2x 4x top right'`.\n // Extra values were reported by extractGroupData and are ignored here.\n const value = values[0];\n\n // Span first so an explicitly named direction always wins over the value it\n // would otherwise inherit as a perpendicular side.\n if (span) {\n // `inset: '2x 4x bottom dock'` pins the bottom at 2x and insets the spanned\n // sides by 4x. Without a second value the span reuses the edge's own value.\n const spanValue = values[1] ?? value;\n\n for (const dir of directions) {\n // The two sides perpendicular to `dir` are its neighbours in DIRECTIONS\n // (top -> left/right, right -> top/bottom, ...).\n const d = DIRECTIONS.indexOf(dir);\n\n dirs[DIRECTIONS[(d + 1) % 4] as Direction] = spanValue;\n dirs[DIRECTIONS[(d + 3) % 4] as Direction] = spanValue;\n }\n }\n\n for (const dir of directions) {\n dirs[dir] = value;\n }\n}\n\nfunction optimizeShorthand(\n property: string,\n dirs: Record<Direction, string>,\n): Record<string, string> {\n const { top, right, bottom, left } = dirs;\n\n if (top === right && right === bottom && bottom === left) {\n return { [property]: top };\n }\n if (top === bottom && left === right) {\n return { [property]: `${top} ${left}` };\n }\n\n return { [property]: `${top} ${right} ${bottom} ${left}` };\n}\n\ninterface DirectionalProps {\n main?: string | number | boolean;\n block?: string | number | boolean;\n inline?: string | number | boolean;\n top?: string | number | boolean;\n right?: string | number | boolean;\n bottom?: string | number | boolean;\n left?: string | number | boolean;\n}\n\n/**\n * Core directional style logic shared by padding, margin, inset, scrollMargin.\n */\nexport function processDirectionalStyle(\n config: DirectionalConfig,\n props: DirectionalProps,\n): Record<string, string> | null {\n const { main, block, inline, top, right, bottom, left } = props;\n\n if (\n main == null &&\n block == null &&\n inline == null &&\n top == null &&\n right == null &&\n bottom == null &&\n left == null\n ) {\n return null;\n }\n\n const {\n property,\n defaultValue,\n trueValue,\n defaultInit,\n individualOnly,\n directionProperty,\n spanModifiers,\n } = config;\n const dirProp =\n directionProperty ?? ((dir: Direction) => `${property}-${dir}`);\n\n if (individualOnly) {\n const onlyIndividualProps = main == null && block == null && inline == null;\n\n if (onlyIndividualProps) {\n const result: Record<string, string> = {};\n\n if (top != null) {\n const val = parseSingleValue(top, defaultValue, trueValue);\n if (val) result[dirProp('top')] = val;\n }\n if (right != null) {\n const val = parseSingleValue(right, defaultValue, trueValue);\n if (val) result[dirProp('right')] = val;\n }\n if (bottom != null) {\n const val = parseSingleValue(bottom, defaultValue, trueValue);\n if (val) result[dirProp('bottom')] = val;\n }\n if (left != null) {\n const val = parseSingleValue(left, defaultValue, trueValue);\n if (val) result[dirProp('left')] = val;\n }\n\n return Object.keys(result).length > 0 ? result : null;\n }\n }\n\n const dirs: Record<Direction, string> = {\n top: defaultInit,\n right: defaultInit,\n bottom: defaultInit,\n left: defaultInit,\n };\n\n let useLonghand = false;\n\n if (main != null) {\n if (typeof main === 'number') {\n const v = `${main}px`;\n dirs.top = dirs.right = dirs.bottom = dirs.left = v;\n } else {\n const strMain = main === true ? trueValue : String(main);\n\n if (strMain) {\n const keyword = CSS_WIDE_KEYWORDS.has(strMain) ? strMain : null;\n\n if (keyword) {\n dirs.top = dirs.right = dirs.bottom = dirs.left = keyword;\n } else {\n const processed = parseStyle(strMain);\n const groups = processed.groups ?? [];\n\n for (const group of groups) {\n if (group.mods.includes('longhand')) {\n useLonghand = true;\n }\n\n const kw = extractCSSWideKeyword(group);\n\n if (kw) {\n const groupDirs = filterMods(\n group.mods,\n DIRECTIONS,\n ) as Direction[];\n\n if (groupDirs.length === 0) {\n dirs.top = dirs.right = dirs.bottom = dirs.left = kw;\n } else {\n for (const dir of groupDirs) {\n dirs[dir] = kw;\n }\n }\n } else {\n const { values, directions, span } = extractGroupData(\n group,\n property,\n defaultValue,\n spanModifiers,\n );\n applyGroup(dirs, values, directions, span);\n }\n }\n }\n }\n }\n }\n\n if (block != null) {\n const val = parseSingleValue(block, defaultValue, trueValue);\n if (val) dirs.top = dirs.bottom = val;\n }\n if (inline != null) {\n const val = parseSingleValue(inline, defaultValue, trueValue);\n if (val) dirs.left = dirs.right = val;\n }\n\n if (top != null) {\n const val = parseSingleValue(top, defaultValue, trueValue);\n if (val) dirs.top = val;\n }\n if (right != null) {\n const val = parseSingleValue(right, defaultValue, trueValue);\n if (val) dirs.right = val;\n }\n if (bottom != null) {\n const val = parseSingleValue(bottom, defaultValue, trueValue);\n if (val) dirs.bottom = val;\n }\n if (left != null) {\n const val = parseSingleValue(left, defaultValue, trueValue);\n if (val) dirs.left = val;\n }\n\n if (useLonghand) {\n return {\n [dirProp('top')]: dirs.top,\n [dirProp('right')]: dirs.right,\n [dirProp('bottom')]: dirs.bottom,\n [dirProp('left')]: dirs.left,\n };\n }\n\n return optimizeShorthand(property, dirs);\n}\n","import { type DirectionalConfig, processDirectionalStyle } from './directional';\n\nconst INSET_CONFIG: DirectionalConfig = {\n property: 'inset',\n defaultValue: '0',\n trueValue: '0',\n defaultInit: 'auto',\n individualOnly: true,\n spanModifiers: ['dock'],\n directionProperty: (dir) => dir,\n};\n\nexport function insetStyle({\n inset,\n insetBlock,\n insetInline,\n top,\n right,\n bottom,\n left,\n}: {\n inset?: string | number | boolean;\n insetBlock?: string | number | boolean;\n insetInline?: string | number | boolean;\n top?: string | number | boolean;\n right?: string | number | boolean;\n bottom?: string | number | boolean;\n left?: string | number | boolean;\n}) {\n return processDirectionalStyle(INSET_CONFIG, {\n main: inset,\n block: insetBlock,\n inline: insetInline,\n top,\n right,\n bottom,\n left,\n });\n}\n\ninsetStyle.__lookupStyles = [\n 'inset',\n 'insetBlock',\n 'insetInline',\n 'top',\n 'right',\n 'bottom',\n 'left',\n];\n","import { processDirectionalStyle } from './directional';\n\nconst MARGIN_CONFIG = {\n property: 'margin',\n defaultValue: 'var(--gap)',\n trueValue: '1x',\n defaultInit: '0',\n} as const;\n\nexport function marginStyle({\n margin,\n marginBlock,\n marginInline,\n marginTop,\n marginRight,\n marginBottom,\n marginLeft,\n}: {\n margin?: string | number | boolean;\n marginBlock?: string | number | boolean;\n marginInline?: string | number | boolean;\n marginTop?: string | number | boolean;\n marginRight?: string | number | boolean;\n marginBottom?: string | number | boolean;\n marginLeft?: string | number | boolean;\n}) {\n return processDirectionalStyle(MARGIN_CONFIG, {\n main: margin,\n block: marginBlock,\n inline: marginInline,\n top: marginTop,\n right: marginRight,\n bottom: marginBottom,\n left: marginLeft,\n });\n}\n\nmarginStyle.__lookupStyles = [\n 'margin',\n 'marginTop',\n 'marginRight',\n 'marginBottom',\n 'marginLeft',\n 'marginBlock',\n 'marginInline',\n];\n","import { CSS_WIDE_KEYWORDS } from '../parser/const';\nimport {\n filterMods,\n parseStyle,\n resolveCustomProperties,\n} from '../utils/styles';\nimport { BORDER_STYLES } from './const';\nimport { assignLineSlots } from './shared';\n\ninterface OutlineStyleProps {\n outline?: string | boolean | number;\n outlineOffset?: string | number;\n}\n\n/**\n * Generates CSS for outline property with optional offset.\n *\n * Syntax:\n * - `outline=\"2px solid #red\"` - outline only\n * - `outline=\"2px solid #red / 4px\"` - outline with offset (slash separator)\n * - `outline=\"2px / 4px\"` - width with offset (simpler form)\n * - `outline={true}` - default 1ow solid outline\n * - `outlineOffset=\"4px\"` - offset as separate prop (can be combined with outline)\n *\n * Priority: slash syntax in outline takes precedence over outlineOffset prop\n *\n * @return CSS properties for outline and optionally outline-offset\n */\nexport function outlineStyle({ outline, outlineOffset }: OutlineStyleProps) {\n const result: Record<string, string> = {};\n\n // Handle outline (0 is valid - means no outline)\n if (outline != null && outline !== false) {\n if (typeof outline === 'string' && CSS_WIDE_KEYWORDS.has(outline)) {\n result['outline'] = outline;\n } else {\n let outlineValue: string | boolean | number = outline;\n if (outline === true) outlineValue = '1ow';\n if (outline === 0) outlineValue = '0';\n\n const processed = parseStyle(String(outlineValue));\n const group = processed.groups[0];\n\n if (group) {\n const { parts } = group;\n const outlinePart = parts[0] ?? { values: [], mods: [], colors: [] };\n const offsetPart = parts[1];\n\n const typeMods = filterMods(\n outlinePart.mods,\n BORDER_STYLES as unknown as string[],\n );\n\n const slots = assignLineSlots(\n outlinePart.values,\n typeMods[0],\n outlinePart.colors[0],\n );\n\n const value = outlinePart.values[0] || 'var(--outline-width)';\n const type = slots.style || 'solid';\n const outlineColor = slots.color || 'var(--outline-color)';\n\n result['outline'] = [value, type, outlineColor].join(' ');\n\n if (offsetPart?.values[0]) {\n result['outline-offset'] = offsetPart.values[0];\n }\n }\n }\n }\n\n // Handle outlineOffset prop (only if not already set by slash syntax)\n if (outlineOffset != null && !result['outline-offset']) {\n const offsetValue =\n typeof outlineOffset === 'number' ? `${outlineOffset}px` : outlineOffset;\n const processed = parseStyle(offsetValue);\n result['outline-offset'] =\n processed.groups[0]?.values[0] || resolveCustomProperties(offsetValue);\n }\n\n if (Object.keys(result).length === 0) {\n return null;\n }\n\n return result;\n}\n\noutlineStyle.__lookupStyles = ['outline', 'outlineOffset'];\n","import { processDirectionalStyle } from './directional';\n\nconst PADDING_CONFIG = {\n property: 'padding',\n defaultValue: 'var(--gap)',\n trueValue: '1x',\n defaultInit: '0',\n} as const;\n\nexport function paddingStyle({\n padding,\n paddingBlock,\n paddingInline,\n paddingTop,\n paddingRight,\n paddingBottom,\n paddingLeft,\n}: {\n padding?: string | number | boolean;\n paddingBlock?: string | number | boolean;\n paddingInline?: string | number | boolean;\n paddingTop?: string | number | boolean;\n paddingRight?: string | number | boolean;\n paddingBottom?: string | number | boolean;\n paddingLeft?: string | number | boolean;\n}) {\n return processDirectionalStyle(PADDING_CONFIG, {\n main: padding,\n block: paddingBlock,\n inline: paddingInline,\n top: paddingTop,\n right: paddingRight,\n bottom: paddingBottom,\n left: paddingLeft,\n });\n}\n\npaddingStyle.__lookupStyles = [\n 'padding',\n 'paddingTop',\n 'paddingRight',\n 'paddingBottom',\n 'paddingLeft',\n 'paddingBlock',\n 'paddingInline',\n];\n","import { resolveCustomProperties } from '../utils/styles';\n\ninterface PlacementStyleProps {\n place?: string | boolean;\n placeItems?: string | boolean;\n placeContent?: string | boolean;\n align?: string | boolean;\n justify?: string | boolean;\n alignItems?: string | boolean;\n alignContent?: string | boolean;\n justifyItems?: string | boolean;\n justifyContent?: string | boolean;\n}\n\nfunction str(val: string | boolean | undefined): string | null {\n if (val == null || val === false || val === '') return null;\n if (val === true) return 'center';\n\n return resolveCustomProperties(String(val));\n}\n\n/**\n * Unified placement handler replacing align, justify, and place.\n *\n * Priority (later overrides earlier):\n * 1. place (lowest) — sets all 4 longhands\n * 2. placeItems, placeContent, align, justify (medium) — each sets 2 longhands\n * 3. alignItems, alignContent, justifyItems, justifyContent (highest) — each sets 1 longhand\n */\nexport function placementStyle({\n place,\n placeItems,\n placeContent,\n align,\n justify,\n alignItems,\n alignContent,\n justifyItems,\n justifyContent,\n}: PlacementStyleProps) {\n const result: Record<string, string> = {};\n\n const placeVal = str(place);\n\n if (placeVal) {\n const parts = placeVal.split(/\\s+/);\n const first = parts[0];\n const second = parts[1] || first;\n\n result['align-items'] = first;\n result['justify-items'] = second;\n result['align-content'] = first;\n result['justify-content'] = second;\n }\n\n const placeItemsVal = str(placeItems);\n\n if (placeItemsVal) {\n const parts = placeItemsVal.split(/\\s+/);\n\n result['align-items'] = parts[0];\n result['justify-items'] = parts[1] || parts[0];\n }\n\n const placeContentVal = str(placeContent);\n\n if (placeContentVal) {\n const parts = placeContentVal.split(/\\s+/);\n\n result['align-content'] = parts[0];\n result['justify-content'] = parts[1] || parts[0];\n }\n\n const alignVal = str(align);\n\n if (alignVal) {\n result['align-items'] = alignVal;\n result['align-content'] = alignVal;\n }\n\n const justifyVal = str(justify);\n\n if (justifyVal) {\n result['justify-items'] = justifyVal;\n result['justify-content'] = justifyVal;\n }\n\n const alignItemsVal = str(alignItems);\n\n if (alignItemsVal) result['align-items'] = alignItemsVal;\n\n const alignContentVal = str(alignContent);\n\n if (alignContentVal) result['align-content'] = alignContentVal;\n\n const justifyItemsVal = str(justifyItems);\n\n if (justifyItemsVal) result['justify-items'] = justifyItemsVal;\n\n const justifyContentVal = str(justifyContent);\n\n if (justifyContentVal) result['justify-content'] = justifyContentVal;\n\n if (Object.keys(result).length === 0) return null;\n\n return result;\n}\n\nplacementStyle.__lookupStyles = [\n 'place',\n 'placeItems',\n 'placeContent',\n 'align',\n 'justify',\n 'alignItems',\n 'alignContent',\n 'justifyItems',\n 'justifyContent',\n];\n","import { CSS_WIDE_KEYWORDS } from '../parser/const';\nimport { parseStyle, resolveCustomProperties } from '../utils/styles';\nimport { isTokenNameReference } from './shared';\nimport type { CSSMap } from '../utils/styles';\n\nconst PRESET_MODIFIERS = new Set([\n 'strong',\n 'bold',\n 'italic',\n 'icon',\n 'tight',\n 'normal',\n]);\n\n/**\n * Convert a value to CSS, handling numbers as pixels for numeric properties\n */\nfunction toCSS(\n value: string | number | undefined,\n isNumeric: boolean,\n): string | null {\n if (value == null) return null;\n if (typeof value === 'number') {\n return isNumeric ? `${value}px` : String(value);\n }\n // Parse through style parser to handle custom units like 1x, 2r, etc.\n const processed = parseStyle(String(value));\n // A `$name-color` reference lands in the color bucket, not `values`, so the\n // fallback still has to substitute custom properties rather than emit the\n // raw DSL.\n return (\n processed.groups[0]?.values[0] || resolveCustomProperties(String(value))\n );\n}\n\nfunction setCSSValue(\n styles: CSSMap,\n styleName: string,\n presetName: string,\n { varOnly, cssOnly }: { varOnly?: boolean; cssOnly?: boolean } = {},\n) {\n const value = (() => {\n if (CSS_WIDE_KEYWORDS.has(presetName)) {\n return presetName;\n }\n\n const defaultValue = `var(--default-${styleName}${\n styleName === 'font-family'\n ? ', var(--font-sans, var(--font-sans-fallback))'\n : ''\n })`;\n const fontSuffix =\n styleName === 'font-family'\n ? ', var(--font-sans, var(--font-sans-fallback))'\n : '';\n\n if (presetName === 'default') {\n return `${defaultValue}${fontSuffix}`;\n } else {\n return `var(--${presetName}-${styleName}, ${defaultValue})${fontSuffix}`;\n }\n })();\n\n if (!cssOnly) {\n styles[`--${styleName}`] = value;\n }\n\n if (!varOnly) {\n styles[styleName] = value;\n }\n}\n\ninterface PresetStyleProps {\n preset?: string | boolean;\n fontSize?: string | number;\n lineHeight?: string | number;\n textTransform?: string;\n letterSpacing?: string | number;\n fontWeight?: string | number;\n fontStyle?: string | boolean;\n fontFamily?: string;\n /** Alias for fontFamily with special handling for 'monospace' and boolean */\n font?: string | boolean;\n}\n\n/**\n * Resolve font/fontFamily value to CSS font-family string.\n *\n * - `font=\"monospace\"` → var(--font-mono, var(--font-mono-fallback))\n * - `font={true}` → var(--font-sans, var(--font-sans-fallback))\n * - `font=\"CustomFont\"` → CustomFont, var(--font-sans, var(--font-sans-fallback))\n * - `fontFamily=\"Arial\"` → Arial (direct, no fallback)\n */\nfunction resolveFontFamily(\n font: string | boolean | undefined,\n fontFamily: string | undefined,\n): string | null {\n // fontFamily takes precedence as a direct value\n if (fontFamily) {\n return resolveCustomProperties(fontFamily);\n }\n\n if (font == null || font === false) {\n return null;\n }\n\n if (font === 'monospace') {\n return 'var(--font-mono, var(--font-mono-fallback))';\n }\n\n if (font === true) {\n return 'var(--font-sans, var(--font-sans-fallback))';\n }\n\n return `${resolveCustomProperties(font)}, var(--font-sans, var(--font-sans-fallback))`;\n}\n\n/**\n * Handles typography preset and individual font properties.\n *\n * Preset syntax uses `/` to separate the name from one or more\n * space-separated modifiers:\n * - `preset=\"h1\"` — name only\n * - `preset=\"h2 / strong\"` — name + modifier\n * - `preset=\"h2 / strong italic\"` — name + multiple modifiers\n * - `preset=\"bold\"` — modifier-only shorthand (name defaults to `inherit`)\n * - `preset=\"bold italic\"` — modifier-only shorthand with multiple modifiers\n *\n * When `preset` is defined, it sets up CSS custom properties for typography.\n * Individual font props can be used with or without `preset`:\n * - With `preset`: overrides the preset value for that property\n * - Without `preset`: outputs the CSS directly\n *\n * Number values are converted to pixels for fontSize, lineHeight, letterSpacing.\n * fontWeight accepts numbers directly (e.g., 400, 700).\n *\n * font vs fontFamily:\n * - `font` is the recommended prop with special handling (monospace, boolean, fallback)\n * - `fontFamily` is a direct value without special handling\n */\nexport function presetStyle({\n preset,\n fontSize,\n lineHeight,\n textTransform,\n letterSpacing,\n fontWeight,\n fontStyle,\n fontFamily,\n font,\n}: PresetStyleProps) {\n // A handler result, not an authoring styles object: every key written below is\n // a kebab-case CSS property or a `--custom-property`.\n const styles: CSSMap = {};\n const hasPreset = preset != null && preset !== false;\n\n // Handle preset if defined\n if (hasPreset) {\n const presetValue = preset === true ? '' : String(preset);\n\n const processed = parseStyle(presetValue);\n const group = processed.groups[0];\n const { parts } = group ?? { parts: [] };\n\n // parts[0] = preset name (or modifiers for shorthand like preset=\"bold italic\")\n // parts[1] = optional space-separated modifiers after slash (e.g. \"t3 / strong italic\")\n const namePart = parts[0];\n const modPart = parts[1];\n\n const nameTokens = namePart?.all ?? [];\n // Mod-only shorthand: all tokens in parts[0] are recognized modifiers.\n const isModOnly =\n nameTokens.length > 0 && nameTokens.every((t) => PRESET_MODIFIERS.has(t));\n\n const nameToken = namePart?.mods[0] ?? namePart?.values[0] ?? '';\n // A reference cannot name a preset; fall back to `inherit`, the same name an\n // absent preset resolves to, rather than emitting `var(--var(--x)-font-size)`.\n const name =\n isModOnly || isTokenNameReference('preset', nameToken)\n ? 'inherit'\n : nameToken || 'inherit';\n\n const modTokens = isModOnly ? nameTokens : (modPart?.all ?? []);\n const activeMods = new Set<string>();\n for (const tok of modTokens) {\n if (PRESET_MODIFIERS.has(tok)) {\n activeMods.add(tok);\n }\n }\n\n const isStrong = activeMods.has('strong') || activeMods.has('bold');\n const isItalic = activeMods.has('italic');\n const isIcon = activeMods.has('icon');\n const isTight = activeMods.has('tight');\n const isNormal = activeMods.has('normal');\n\n // Set preset values for properties not explicitly overridden\n if (fontSize == null) {\n setCSSValue(styles, 'font-size', name, { cssOnly: true });\n }\n if (lineHeight == null) {\n setCSSValue(styles, 'line-height', name, { cssOnly: true });\n }\n if (letterSpacing == null) {\n setCSSValue(styles, 'letter-spacing', name, { cssOnly: true });\n }\n if (fontWeight == null) {\n setCSSValue(styles, 'font-weight', name, { cssOnly: true });\n }\n if (fontStyle == null) {\n setCSSValue(styles, 'font-style', name, { cssOnly: true });\n }\n if (textTransform == null) {\n setCSSValue(styles, 'text-transform', name, { cssOnly: true });\n }\n if (fontFamily == null && font == null) {\n setCSSValue(styles, 'font-family', name, { cssOnly: true });\n }\n\n setCSSValue(styles, 'bold-font-weight', name, { varOnly: true });\n setCSSValue(styles, 'icon-size', name, { varOnly: true });\n\n if (isStrong) {\n styles['font-weight'] = 'var(--bold-font-weight)';\n }\n if (isItalic) {\n styles['font-style'] = 'italic';\n }\n if (isIcon) {\n styles['font-size'] = 'var(--icon-size)';\n styles['line-height'] = 'var(--icon-size)';\n }\n if (isTight) {\n styles['line-height'] = '1em';\n }\n if (isNormal) {\n styles['line-height'] = 'normal';\n }\n }\n\n // Handle individual font properties (work with or without preset)\n const fontSizeVal = toCSS(fontSize, true);\n if (fontSizeVal) {\n styles['font-size'] = fontSizeVal;\n }\n\n const lineHeightVal = toCSS(lineHeight, true);\n if (lineHeightVal) {\n styles['line-height'] = lineHeightVal;\n }\n\n const letterSpacingVal = toCSS(letterSpacing, true);\n if (letterSpacingVal) {\n styles['letter-spacing'] = letterSpacingVal;\n }\n\n // fontWeight: numbers should NOT get 'px' suffix\n const fontWeightVal = toCSS(fontWeight, false);\n if (fontWeightVal) {\n styles['font-weight'] = fontWeightVal;\n }\n\n if (fontStyle != null) {\n if (fontStyle === true) {\n styles['font-style'] = 'italic';\n } else if (\n typeof fontStyle === 'string' &&\n CSS_WIDE_KEYWORDS.has(fontStyle)\n ) {\n styles['font-style'] = fontStyle;\n } else {\n styles['font-style'] = fontStyle ? 'italic' : 'normal';\n }\n }\n\n if (textTransform) {\n styles['text-transform'] = resolveCustomProperties(textTransform);\n }\n\n // Handle font/fontFamily (font has special handling, fontFamily is direct)\n const fontFamily_ = resolveFontFamily(font, fontFamily);\n if (fontFamily_) {\n styles['font-family'] = fontFamily_;\n }\n\n if (Object.keys(styles).length === 0) {\n return null;\n }\n\n return styles;\n}\n\npresetStyle.__lookupStyles = [\n 'preset',\n 'fontSize',\n 'lineHeight',\n 'letterSpacing',\n 'textTransform',\n 'fontWeight',\n 'fontStyle',\n 'fontFamily',\n 'font',\n];\n","import { makeEmptyDetails } from '../parser/types';\nimport { DIRECTIONS, parseStyle } from '../utils/styles';\nimport { extractCSSWideKeyword } from './shared';\n\nconst PROP = 'var(--radius)';\nconst SHARP = 'var(--sharp-radius)';\n\nconst RADIUS_LONGHANDS = [\n 'border-top-left-radius',\n 'border-top-right-radius',\n 'border-bottom-right-radius',\n 'border-bottom-left-radius',\n];\n\n/**\n * Single-corner modifiers, indexed to match `RADIUS_LONGHANDS`.\n *\n * A directional modifier (`top`, `right`, …) addresses the corner *pair* along\n * that edge, so it cannot express one corner on its own. These name a corner\n * directly: `radius: 'top-right'` rounds only the top-right corner.\n */\nconst CORNERS = [\n 'top-left',\n 'top-right',\n 'bottom-right',\n 'bottom-left',\n] as const;\n\n/**\n * Corner indices (into `RADIUS_LONGHANDS`) addressed by the given modifiers.\n * Empty when no corner was named, so callers fall back to all corners.\n */\nfunction cornerIndices(mods: string[]): number[] {\n const out = new Set<number>();\n\n DIRECTIONS.forEach((dir, i) => {\n if (!mods.includes(dir)) return;\n\n out.add(i);\n out.add((i + 1) % 4);\n });\n\n CORNERS.forEach((corner, i) => {\n if (mods.includes(corner)) out.add(i);\n });\n\n return [...out];\n}\n\nexport function radiusStyle({\n radius,\n}: {\n radius?: string | number | boolean;\n}) {\n if (typeof radius === 'number') {\n radius = `${radius}px`;\n }\n\n if (!radius) return null;\n\n if (radius === true) radius = '1r';\n\n const processed = parseStyle(radius);\n const group = processed.groups[0] ?? makeEmptyDetails();\n const { mods } = group;\n let { values } = group;\n\n const keyword = extractCSSWideKeyword(group);\n\n const useLonghand = mods.includes('longhand');\n\n if (keyword) {\n const corners = cornerIndices(mods);\n\n if (!corners.length) {\n if (useLonghand) {\n return Object.fromEntries(\n RADIUS_LONGHANDS.map((prop) => [prop, keyword]),\n );\n }\n\n return { 'border-radius': keyword };\n }\n\n const result: Record<string, string> = {};\n\n for (const i of corners) {\n result[RADIUS_LONGHANDS[i]] = keyword;\n }\n\n return result;\n }\n\n if (mods.includes('round')) {\n values = ['9999rem'];\n } else if (mods.includes('ellipse')) {\n values = ['50%'];\n } else if (!values.length) {\n values = [PROP];\n }\n\n if (mods.includes('leaf')) {\n values = [\n values[1] || SHARP,\n values[0] || PROP,\n values[1] || SHARP,\n values[0] || PROP,\n ];\n } else if (mods.includes('backleaf')) {\n values = [\n values[0] || PROP,\n values[1] || SHARP,\n values[0] || PROP,\n values[1] || SHARP,\n ];\n } else if (mods.length) {\n const corners = cornerIndices(mods);\n\n if (corners.length) {\n const arr = ['0', '0', '0', '0'];\n\n for (const i of corners) {\n arr[i] = values[0] || PROP;\n }\n\n values = arr;\n }\n }\n\n if (useLonghand) {\n return {\n [RADIUS_LONGHANDS[0]]: values[0],\n [RADIUS_LONGHANDS[1]]: values[1] || values[0],\n [RADIUS_LONGHANDS[2]]: values[2] || values[0],\n [RADIUS_LONGHANDS[3]]: values[3] || values[1] || values[0],\n };\n }\n\n return {\n 'border-radius': values.join(' '),\n };\n}\n\nradiusStyle.__lookupStyles = ['radius'];\n","import { processDirectionalStyle } from './directional';\n\nconst SCROLL_MARGIN_CONFIG = {\n property: 'scroll-margin',\n defaultValue: '0',\n trueValue: '1x',\n defaultInit: '0',\n} as const;\n\nexport function scrollMarginStyle({\n scrollMargin,\n scrollMarginBlock,\n scrollMarginInline,\n scrollMarginTop,\n scrollMarginRight,\n scrollMarginBottom,\n scrollMarginLeft,\n}: {\n scrollMargin?: string | number | boolean;\n scrollMarginBlock?: string | number | boolean;\n scrollMarginInline?: string | number | boolean;\n scrollMarginTop?: string | number | boolean;\n scrollMarginRight?: string | number | boolean;\n scrollMarginBottom?: string | number | boolean;\n scrollMarginLeft?: string | number | boolean;\n}) {\n return processDirectionalStyle(SCROLL_MARGIN_CONFIG, {\n main: scrollMargin,\n block: scrollMarginBlock,\n inline: scrollMarginInline,\n top: scrollMarginTop,\n right: scrollMarginRight,\n bottom: scrollMarginBottom,\n left: scrollMarginLeft,\n });\n}\n\nscrollMarginStyle.__lookupStyles = [\n 'scrollMargin',\n 'scrollMarginTop',\n 'scrollMarginRight',\n 'scrollMarginBottom',\n 'scrollMarginLeft',\n 'scrollMarginBlock',\n 'scrollMarginInline',\n];\n","import { CSS_WIDE_KEYWORDS } from '../parser/const';\nimport { makeEmptyDetails } from '../parser/types';\nimport { parseStyle } from '../utils/styles';\nimport { warn } from '../utils/warnings';\n\ninterface ScrollbarStyleProps {\n scrollbar?: string | boolean;\n overflow?: string;\n}\n\n/**\n * Standard CSS scrollbar styling via `scrollbar-width`, `scrollbar-color`,\n * and `scrollbar-gutter`.\n *\n * Width values: `thin` (default), `auto`, `none`\n * Modifiers: `stable`, `both-edges`, `always`\n *\n * Note: `auto` is classified as a VALUE_KEYWORD by the parser, so it lands\n * in `values` rather than `mods`. Both locations are checked for robustness.\n */\nexport function scrollbarStyle({\n scrollbar,\n overflow,\n}: ScrollbarStyleProps): Record<string, string> | null {\n if (!scrollbar) return null;\n\n if (typeof scrollbar === 'string' && CSS_WIDE_KEYWORDS.has(scrollbar)) {\n return {\n 'scrollbar-width': scrollbar,\n 'scrollbar-color': scrollbar,\n };\n }\n\n // `true` is treated as `thin` (empty string is falsy, caught by the guard above)\n const value = scrollbar === true ? 'thin' : scrollbar;\n const processed = parseStyle(String(value));\n const { mods, colors, values } = processed.groups[0] ?? makeEmptyDetails();\n\n const defaultThumbColor = 'var(--scrollbar-thumb-color)';\n const defaultTrackColor = 'var(--scrollbar-track-color, transparent)';\n\n const style: Record<string, string> = {};\n\n if (mods.includes('none')) {\n const ignored = [...mods.filter((m) => m !== 'none'), ...values, ...colors];\n\n if (ignored.length && process.env.NODE_ENV !== 'production') {\n warn(\n `scrollbar=\"none\" hides the scrollbar; other tokens are ignored: ${ignored.join(', ')}`,\n );\n }\n\n style['scrollbar-width'] = 'none';\n\n return style;\n }\n\n // `thin` is the default — accepted as a value for readability but always\n // the fallback when neither `auto` nor `none` is specified.\n // `auto` is a VALUE_KEYWORD in the parser, so it may land in `values`.\n if (mods.includes('auto') || values.includes('auto')) {\n style['scrollbar-width'] = 'auto';\n } else {\n style['scrollbar-width'] = 'thin';\n }\n\n const thumbColor = colors?.[0] || defaultThumbColor;\n const trackColor = colors?.[1] || defaultTrackColor;\n style['scrollbar-color'] = `${thumbColor} ${trackColor}`;\n\n if (mods.includes('stable') || mods.includes('both-edges')) {\n style['scrollbar-gutter'] = mods.includes('both-edges')\n ? 'stable both-edges'\n : 'stable';\n }\n\n if (mods.includes('always')) {\n const effectiveOverflow = overflow || 'scroll';\n style['overflow'] = effectiveOverflow;\n\n // scrollbar-gutter only applies with scroll/auto overflow\n if (\n !style['scrollbar-gutter'] &&\n (effectiveOverflow === 'scroll' || effectiveOverflow === 'auto')\n ) {\n style['scrollbar-gutter'] = 'stable';\n }\n }\n\n return style;\n}\n\nscrollbarStyle.__lookupStyles = ['scrollbar', 'overflow'];\n","import { CSS_WIDE_KEYWORDS } from '../parser/const';\nimport type { StyleDetails } from '../parser/types';\nimport { parseStyle } from '../utils/styles';\n\nfunction toBoxShadow(group: StyleDetails): string {\n const { values, mods, colors } = group;\n const mod = mods[0] || '';\n const shadowColor = colors[0] ?? '';\n\n return [mod, ...values, shadowColor].join(' ');\n}\n\nexport function shadowStyle({ shadow }: { shadow?: string | boolean }) {\n if (!shadow) return null;\n\n if (shadow === true) shadow = 'var(--shadow)';\n\n if (CSS_WIDE_KEYWORDS.has(shadow)) {\n return { 'box-shadow': shadow };\n }\n\n // Shadow layers are split by the parser, not by a plain `split(',')` — a\n // color function brings commas of its own, so `color-mix(in oklab, …)` would\n // otherwise be torn into pieces that are neither a layer nor a color.\n const { groups } = parseStyle(shadow);\n\n return {\n 'box-shadow': groups.map(toBoxShadow).join(','),\n };\n}\n\nshadowStyle.__lookupStyles = ['shadow'];\n","import { CSS_WIDE_KEYWORDS } from '../parser/const';\nimport { parseStyle } from '../utils/styles';\nimport { isTokenNameReference } from './shared';\n\nconst SECOND_FILL_COLOR_PROPERTY = '--tasty-second-fill-color';\n\nconst MAP: Record<string, string[]> = {\n fade: ['mask', 'mask-composite'],\n translate: ['transform', 'translate'],\n rotate: ['transform', 'rotate'],\n scale: ['transform', 'scale'],\n fill: ['background-color', 'background-image', SECOND_FILL_COLOR_PROPERTY],\n image: [\n 'background-image',\n 'background-position',\n 'background-size',\n 'background-repeat',\n 'background-attachment',\n 'background-origin',\n 'background-clip',\n SECOND_FILL_COLOR_PROPERTY,\n ],\n background: [\n 'background-color',\n 'background-image',\n 'background-position',\n 'background-size',\n 'background-repeat',\n 'background-attachment',\n 'background-origin',\n 'background-clip',\n SECOND_FILL_COLOR_PROPERTY,\n ],\n border: [\n 'border',\n 'border-top',\n 'border-right',\n 'border-bottom',\n 'border-left',\n ],\n filter: ['filter', 'backdrop-filter'],\n radius: ['border-radius'],\n shadow: ['box-shadow'],\n outline: ['outline', 'outline-offset'],\n preset: [\n 'font-size',\n 'line-height',\n 'letter-spacing',\n 'font-weight',\n 'font-style',\n ],\n text: ['font-weight', 'text-decoration-color'],\n color: ['color'],\n opacity: ['opacity'],\n theme: [\n 'color',\n 'background-color',\n 'background-image',\n 'box-shadow',\n 'border',\n 'border-radius',\n 'outline',\n 'opacity',\n SECOND_FILL_COLOR_PROPERTY,\n ],\n width: ['max-width', 'min-width', 'width'],\n height: ['max-height', 'min-height', 'height'],\n gap: ['gap', 'margin'],\n zIndex: ['z-index'],\n inset: ['inset', 'top', 'right', 'bottom', 'left'],\n};\n\nconst DEFAULT_EASING = 'linear';\n\nconst EASING_KEYWORDS = new Set([\n 'ease',\n 'ease-in',\n 'ease-out',\n 'ease-in-out',\n 'linear',\n 'step-start',\n 'step-end',\n]);\n\nfunction isEasing(token: string): boolean {\n return (\n EASING_KEYWORDS.has(token) ||\n token.startsWith('cubic-bezier(') ||\n token.startsWith('steps(') ||\n token.startsWith('linear(')\n );\n}\n\nfunction getTiming(name: string): string {\n const varName = name.startsWith('--')\n ? `${name}-transition`\n : `--${name}-transition`;\n return `var(${varName}, var(--transition))`;\n}\n\ntype TransitionEntry = [\n name: string,\n easing: string | undefined,\n timing: string | undefined,\n delay: string | undefined,\n];\n\nexport function transitionStyle({ transition }: { transition?: string }) {\n if (!transition) return null;\n\n if (CSS_WIDE_KEYWORDS.has(transition)) {\n return { transition };\n }\n\n const processed = parseStyle(transition);\n const tokens: string[] = [];\n processed.groups.forEach((g, idx) => {\n tokens.push(...g.all);\n if (idx < processed.groups.length - 1) tokens.push(',');\n });\n\n if (tokens.length === 0) return null;\n\n let tempTransition: string[] = [];\n const transitions: string[][] = [];\n\n tokens.forEach((token) => {\n if (token === ',') {\n if (tempTransition.length) {\n transitions.push(tempTransition);\n tempTransition = [];\n }\n } else {\n tempTransition.push(token);\n }\n });\n\n if (tempTransition.length) {\n transitions.push(tempTransition);\n }\n\n const map: Record<string, TransitionEntry> = {};\n\n transitions.forEach((transition) => {\n const name = transition[0];\n\n // The name doubles as the property to transition and as the timing token, so\n // a reference cannot stand in for it.\n if (isTokenNameReference('transition', name)) return;\n\n let timing: string | undefined;\n let easing: string | undefined;\n let delay: string | undefined;\n\n if (transition[1] && isEasing(transition[1])) {\n easing = transition[1];\n delay = transition[2];\n } else {\n timing = transition[1];\n easing = transition[2];\n delay = transition[3];\n }\n\n const styles = MAP[name] || [name];\n\n styles.forEach((style) => {\n map[style] = [name, easing, timing, delay];\n });\n });\n\n // Every entry may have been rejected as a reference-named transition.\n if (Object.keys(map).length === 0) return null;\n\n const result = Object.entries(map)\n .map(([style, [name, easing, timing, delay]]) => {\n let value = `${style} ${timing || getTiming(name)}`;\n if (easing || delay) {\n value += ` ${easing || DEFAULT_EASING}`;\n }\n if (delay) {\n value += ` ${delay}`;\n }\n return value;\n })\n .join(', ');\n\n return { transition: result };\n}\n\ntransitionStyle.__lookupStyles = ['transition'];\n","import { dimensionStyle } from './dimension';\n\nconst dimension = dimensionStyle('width');\n\ninterface WidthStyleProps {\n width?: string | number | boolean;\n minWidth?: string | number | boolean;\n maxWidth?: string | number | boolean;\n}\n\nexport function widthStyle({ width, minWidth, maxWidth }: WidthStyleProps) {\n return dimension({ value: width, min: minWidth, max: maxWidth });\n}\n\nwidthStyle.__lookupStyles = ['width', 'minWidth', 'maxWidth'];\n","import {\n assignStyleChunk,\n CHUNK_NAMES,\n STYLE_TO_CHUNK,\n} from '../chunks/style-chunk-map';\nimport type { ChunkName } from '../chunks/style-chunk-map';\nimport { isDevEnv } from '../utils/is-dev-env';\nimport type {\n AnyStyleHandler,\n RawStyleHandler,\n StyleHandler,\n StyleHandlerDefinition,\n} from '../utils/styles';\n\nimport { borderStyle } from './border';\nimport { colorStyle } from './color';\nimport { createStyle } from './createStyle';\nimport { displayStyle } from './display';\nimport { fadeStyle } from './fade';\nimport { fillStyle, svgFillStyle } from './fill';\nimport { flowStyle } from './flow';\nimport { gapStyle } from './gap';\nimport { heightStyle } from './height';\nimport { insetStyle } from './inset';\nimport { marginStyle } from './margin';\nimport { outlineStyle } from './outline';\nimport { paddingStyle } from './padding';\nimport { placementStyle } from './placement';\nimport { presetStyle } from './preset';\nimport { radiusStyle } from './radius';\nimport { scrollMarginStyle } from './scrollMargin';\nimport { scrollbarStyle } from './scrollbar';\nimport { shadowStyle } from './shadow';\nimport { transitionStyle } from './transition';\nimport { widthStyle } from './width';\n\nconst devMode = isDevEnv();\n\n/**\n * Dev-mode check evaluated per call rather than at module load.\n *\n * `isDevEnv()` reports `false` for `NODE_ENV=test`, so a module-load capture makes\n * a warning impossible to assert in a test. Only used on paths that already know\n * something is wrong, so the extra call is never on the hot path.\n */\nfunction inDevMode(): boolean {\n return isDevEnv();\n}\n\nconst _numberConverter = (val: string | number | boolean | undefined) => {\n if (typeof val === 'number') {\n return `${val}px`;\n }\n\n return val;\n};\n/**\n * Read a grid track count, or `undefined` when the value isn't one.\n *\n * Plain digit strings count: every value inside a state map arrives as a\n * string, so `gridColumns: { '': '2', '@media(w < 600px)': '1' }` would\n * otherwise emit `grid-template-columns: 2` — invalid CSS that browsers drop\n * silently.\n *\n * Zero and negatives yield `undefined`. Zero already produced an empty value,\n * and a negative number used to throw inside `String.repeat`.\n */\nfunction trackCount(\n val: string | number | boolean | undefined,\n): number | undefined {\n const count =\n typeof val === 'number'\n ? val\n : typeof val === 'string' && /^\\d+$/.test(val.trim())\n ? Number(val.trim())\n : NaN;\n\n return Number.isFinite(count) && count >= 1 ? Math.floor(count) : undefined;\n}\n\nconst columnsConverter = (val: string | number | boolean | undefined) => {\n const count = trackCount(val);\n\n return count === undefined\n ? undefined\n : 'minmax(1px, 1fr) '.repeat(count).trim();\n};\nconst rowsConverter = (val: string | number | boolean | undefined) => {\n const count = trackCount(val);\n\n return count === undefined ? undefined : 'auto '.repeat(count).trim();\n};\n\ntype StyleHandlerMap = Record<string, AnyStyleHandler[]>;\n\nconst STYLE_HANDLER_MAP: StyleHandlerMap = {};\n\n// Store initial handler state for reset functionality\nlet initialHandlerMapSnapshot: StyleHandlerMap | null = null;\n\n/**\n * Capture a snapshot of the current STYLE_HANDLER_MAP.\n * Called after predefine() to preserve built-in handler state.\n */\nfunction captureInitialHandlerState(): void {\n initialHandlerMapSnapshot = {};\n for (const key of Object.keys(STYLE_HANDLER_MAP)) {\n // Shallow copy the array - handlers themselves are immutable\n initialHandlerMapSnapshot[key] = [...STYLE_HANDLER_MAP[key]];\n }\n}\n\n/**\n * Reset STYLE_HANDLER_MAP to the initial built-in state.\n * Called by resetConfig() to restore handlers after tests.\n */\nexport function resetHandlers(): void {\n if (!initialHandlerMapSnapshot) {\n // predefine() hasn't been called yet, nothing to reset\n return;\n }\n\n // Clear current map\n for (const key of Object.keys(STYLE_HANDLER_MAP)) {\n delete STYLE_HANDLER_MAP[key];\n }\n\n // Restore initial state\n for (const key of Object.keys(initialHandlerMapSnapshot)) {\n STYLE_HANDLER_MAP[key] = [...initialHandlerMapSnapshot[key]];\n }\n}\n\nfunction defineCustomStyle(\n names: string[] | AnyStyleHandler,\n handler?: RawStyleHandler,\n) {\n let handlerWithLookup: AnyStyleHandler;\n\n if (typeof names === 'function') {\n handlerWithLookup = names;\n names = handlerWithLookup.__lookupStyles;\n } else if (handler) {\n handlerWithLookup = Object.assign(handler, {\n __lookupStyles: names,\n }) as AnyStyleHandler;\n } else {\n if (process.env.NODE_ENV !== 'production') {\n console.warn('[Tasty] incorrect custom style definition:', names);\n }\n return;\n }\n\n if (Array.isArray(names)) {\n // just to pass type checking\n names.forEach((name) => {\n if (!STYLE_HANDLER_MAP[name]) {\n STYLE_HANDLER_MAP[name] = [];\n }\n\n STYLE_HANDLER_MAP[name].push(handlerWithLookup);\n });\n }\n}\n\ntype ConverterHandler = (\n s: string | boolean | number | undefined,\n) => string | undefined;\n\nfunction defineStyleAlias(\n styleName: string,\n cssStyleName?: string,\n converter?: ConverterHandler,\n) {\n const styleHandler = createStyle(styleName, cssStyleName, converter);\n\n if (!STYLE_HANDLER_MAP[styleName]) {\n STYLE_HANDLER_MAP[styleName] = [];\n }\n\n STYLE_HANDLER_MAP[styleName].push(styleHandler);\n}\n\nexport function predefine() {\n // Style aliases\n defineStyleAlias('gridAreas', 'grid-template-areas');\n defineStyleAlias('gridColumns', 'grid-template-columns', columnsConverter);\n defineStyleAlias('gridRows', 'grid-template-rows', rowsConverter);\n defineStyleAlias(\n 'gridTemplate',\n 'grid-template',\n (val: string | boolean | number | undefined) => {\n if (typeof val !== 'string') return;\n\n // Each side converts independently, and a side that isn't a track count\n // (`auto`, `1fr`, an areas string) is kept verbatim.\n return val\n .split('/')\n .map((s, i) => (i ? columnsConverter : rowsConverter)(s) ?? s)\n .join('/');\n },\n );\n // Note: outlineOffset is now handled by outlineStyle\n\n [\n displayStyle,\n transitionStyle,\n fillStyle,\n svgFillStyle,\n widthStyle,\n marginStyle,\n gapStyle,\n flowStyle,\n colorStyle,\n heightStyle,\n radiusStyle,\n borderStyle,\n shadowStyle,\n paddingStyle,\n placementStyle,\n presetStyle,\n scrollMarginStyle,\n outlineStyle,\n scrollbarStyle,\n fadeStyle,\n insetStyle,\n ].forEach((handler) => defineCustomStyle(handler));\n\n // Capture initial state after all built-in handlers are registered\n captureInitialHandlerState();\n\n return { STYLE_HANDLER_MAP, defineCustomStyle, defineStyleAlias };\n}\n\n// ============================================================================\n// Handler Registration API (for configure())\n// ============================================================================\n\n/**\n * Normalize a handler definition to a StyleHandler with __lookupStyles.\n * - Function only: lookup styles inferred from key name\n * - [string, fn]: single lookup style\n * - [string[], fn]: multiple lookup styles\n */\nexport function normalizeHandlerDefinition(\n keyName: string,\n definition: StyleHandlerDefinition,\n): StyleHandler {\n let handler: RawStyleHandler;\n let lookupStyles: string[];\n\n if (typeof definition === 'function') {\n // Function only - lookup styles inferred from key name\n handler = definition;\n lookupStyles = [keyName];\n } else if (Array.isArray(definition)) {\n const [first, fn] = definition;\n\n if (typeof fn !== 'function') {\n throw new Error(\n `[Tasty] Invalid handler definition for \"${keyName}\". ` +\n 'Tuple must have a function as the second element: [string, function] or [string[], function].',\n );\n }\n\n handler = fn;\n\n if (typeof first === 'string') {\n // [string, fn] - single lookup style\n lookupStyles = [first];\n } else if (Array.isArray(first)) {\n // [string[], fn] - multiple lookup styles\n lookupStyles = first;\n } else {\n throw new Error(\n `[Tasty] Invalid handler definition for \"${keyName}\". ` +\n 'First element must be a string or string array.',\n );\n }\n } else {\n throw new Error(\n `[Tasty] Invalid handler definition for \"${keyName}\". ` +\n 'Expected function, [string, function], or [string[], function].',\n );\n }\n\n // Validate handler in dev mode\n validateHandler(keyName, handler, lookupStyles);\n\n // Wrap the handler to avoid mutation issues when the same function\n // is reused for multiple handler definitions. Each registration\n // gets its own function identity with its own __lookupStyles.\n const wrappedHandler = ((props) => handler(props)) as StyleHandler;\n wrappedHandler.__lookupStyles = lookupStyles;\n\n return wrappedHandler;\n}\n\n/**\n * Validate a handler definition in development mode.\n */\nfunction validateHandler(\n name: string,\n handler: RawStyleHandler,\n lookupStyles: string[],\n): void {\n if (!devMode) return;\n\n if (typeof handler !== 'function') {\n console.warn(\n `[Tasty] Handler \"${name}\" is not a function. ` +\n 'Handlers must be functions that return CSSMap, CSSMap[], or null.',\n );\n }\n\n if (\n !lookupStyles ||\n !Array.isArray(lookupStyles) ||\n lookupStyles.length === 0\n ) {\n console.warn(\n `[Tasty] Handler \"${name}\" has invalid lookupStyles. ` +\n 'Expected non-empty array of style names.',\n );\n }\n}\n\nexport interface RegisterHandlerOptions {\n /** The `handlers` key this handler was registered under, for diagnostics. */\n key?: string;\n /** Where it came from — a plugin name, or `'configure()'`. */\n source?: string;\n}\n\n/** Describe a handler in a warning message. */\nfunction describeHandler(\n lookupStyles: string[],\n options?: RegisterHandlerOptions,\n): string {\n const name = options?.key ?? lookupStyles.join(', ');\n\n return options?.source ? `\"${name}\" (from ${options.source})` : `\"${name}\"`;\n}\n\n/**\n * Keep a handler's dependencies inside one chunk.\n *\n * Chunks are rendered and cached independently and a chunk's cache key covers\n * only its own style values, so a handler whose `__lookupStyles` straddle two\n * chunks gets invoked once per chunk with a *subset* of its inputs — and can emit\n * stale CSS. Custom style names are unknown to the built-in chunk lists and would\n * otherwise fall into `misc`, splitting any handler that mixes them with built-in\n * styles. Pull them into the built-in chunk instead.\n *\n * Runs in production too: this is a correctness fix, not a diagnostic. It only\n * ever moves names the built-in lists don't know, so no existing class name can\n * change.\n */\nfunction alignHandlerChunks(\n lookupStyles: string[],\n options?: RegisterHandlerOptions,\n): void {\n const known = new Set<ChunkName>();\n const unknown: string[] = [];\n\n for (const styleName of lookupStyles) {\n const chunk = STYLE_TO_CHUNK.get(styleName);\n\n if (chunk) {\n known.add(chunk);\n } else {\n unknown.push(styleName);\n }\n }\n\n if (known.size > 1) {\n // The handler bridges two built-in chunks. Resolving this correctly would\n // mean re-deriving chunk membership across the whole handler graph, which can\n // move built-in styles between chunks and change class names — so warn only.\n if (inDevMode()) {\n console.warn(\n `[Tasty] Handler ${describeHandler(lookupStyles, options)} depends on ` +\n `styles from different chunks (${[...known].sort().join(', ')}). ` +\n `Chunks are cached independently, so this handler will be invoked once ` +\n `per chunk with only part of its dependencies and can emit stale CSS. ` +\n `Split it into per-chunk handlers, or have one property expand into the ` +\n `others before chunking.`,\n );\n }\n\n return;\n }\n\n if (unknown.length === 0) return;\n\n // Exactly one known chunk → custom names join it. No known chunk → pin them\n // together in `misc`, where they would land anyway, so they stay together even\n // if one of them later becomes known.\n const target = known.size === 1 ? [...known][0] : CHUNK_NAMES.MISC;\n\n for (const styleName of unknown) {\n assignStyleChunk(styleName, target);\n }\n}\n\n/**\n * Warn when replacing a handler takes unrelated style properties down with it.\n *\n * Built-in handlers are shared across several style names (`displayStyle` also\n * emits `hide`, `overflow`, `whiteSpace`, `textOverflow`), so registering a\n * handler for one of them unregisters the built-in from *all* of its names. The\n * displaced names don't go dark — the pipeline falls back to an auto-generated\n * CSS alias and writes it back into the map — so `hide: true` starts emitting a\n * literal `hide: true` declaration. Silent wrongness, which is worth a warning.\n *\n * Must run before the handlers are actually removed.\n */\nfunction warnAboutOrphanedStyles(\n lookupStyles: string[],\n handlersToRemove: Set<StyleHandler>,\n options?: RegisterHandlerOptions,\n): void {\n const incoming = new Set(lookupStyles);\n const orphaned = new Set<string>();\n\n for (const oldHandler of handlersToRemove) {\n for (const oldStyleName of oldHandler.__lookupStyles ?? []) {\n if (incoming.has(oldStyleName)) continue;\n\n const survivors = (STYLE_HANDLER_MAP[oldStyleName] ?? []).filter(\n (h) => !handlersToRemove.has(h),\n );\n\n if (survivors.length === 0) orphaned.add(oldStyleName);\n }\n }\n\n if (orphaned.size === 0) return;\n\n console.warn(\n `[Tasty] Custom handler ${describeHandler(lookupStyles, options)} displaced ` +\n `built-in handlers that also handle: ${[...orphaned].sort().join(', ')}. ` +\n `Those properties now fall back to auto-generated CSS aliases, which is ` +\n `usually wrong (e.g. \\`hide: true\\` would emit a literal \\`hide: true\\` ` +\n `declaration). Either declare them in this handler's lookup styles and ` +\n `delegate via \\`styleHandlers.*\\`, or pick a narrower style name.`,\n );\n}\n\n/**\n * Register a custom handler, replacing any existing handlers for the same lookup styles.\n * This is called by configure() to process user-defined handlers.\n *\n * When registering a handler for style X, any existing handler that processes X\n * is removed from ALL its lookup styles to prevent double-processing.\n * For example, if gapStyle handles ['display', 'flow', 'gap'] and a new handler\n * is registered for just ['gap'], gapStyle is removed from display and flow too.\n *\n * Note: this bypasses the `configure()` lock, so calling it after styles have\n * been generated changes the handlers for already-emitted class names. Prefer\n * `configure({ handlers })`, which is rejected after first render.\n */\nexport function registerHandler(\n handler: StyleHandler,\n options?: RegisterHandlerOptions,\n): void {\n const lookupStyles = handler.__lookupStyles;\n\n if (!lookupStyles || lookupStyles.length === 0) {\n if (devMode) {\n console.warn(\n '[Tasty] Cannot register handler without __lookupStyles property.',\n );\n }\n return;\n }\n\n alignHandlerChunks(lookupStyles, options);\n\n // Find and remove existing handlers that would conflict\n // A handler conflicts if it handles any of the same styles as the new handler\n const handlersToRemove = new Set<StyleHandler>();\n\n for (const styleName of lookupStyles) {\n const existing = STYLE_HANDLER_MAP[styleName];\n if (existing) {\n for (const existingHandler of existing) {\n handlersToRemove.add(existingHandler);\n }\n }\n }\n\n if (handlersToRemove.size > 0 && inDevMode()) {\n warnAboutOrphanedStyles(lookupStyles, handlersToRemove, options);\n }\n\n // Remove conflicting handlers from ALL their lookup styles\n for (const oldHandler of handlersToRemove) {\n const oldLookupStyles = oldHandler.__lookupStyles;\n if (oldLookupStyles) {\n for (const oldStyleName of oldLookupStyles) {\n const handlers = STYLE_HANDLER_MAP[oldStyleName];\n if (handlers) {\n const filtered = handlers.filter((h) => h !== oldHandler);\n if (filtered.length === 0) {\n delete STYLE_HANDLER_MAP[oldStyleName];\n } else {\n STYLE_HANDLER_MAP[oldStyleName] = filtered;\n }\n }\n }\n }\n }\n\n // Register the new handler under its lookup styles\n for (const styleName of lookupStyles) {\n const existing = STYLE_HANDLER_MAP[styleName];\n if (existing) {\n existing.push(handler);\n } else {\n STYLE_HANDLER_MAP[styleName] = [handler];\n }\n }\n}\n\n// ============================================================================\n// Wrapped Style Handlers Export\n// ============================================================================\n\n/**\n * Create a wrapped handler that can be safely called by users.\n * The wrapper preserves __lookupStyles for proper registration.\n */\nfunction wrapHandler<T extends { __lookupStyles: string[] }>(handler: T): T {\n const fn = handler as unknown as (props: unknown) => unknown;\n const wrapped = ((props: unknown) => fn(props)) as unknown as T;\n wrapped.__lookupStyles = handler.__lookupStyles;\n return wrapped;\n}\n\n/**\n * Exported object containing wrapped predefined style handlers.\n * Users can import and call these to extend or delegate to built-in behavior.\n *\n * Internal handlers use *Style suffix for searchability.\n * External API uses short names for convenience.\n *\n * @example\n * ```ts\n * import { styleHandlers, configure } from '@tenphi/tasty';\n *\n * configure({\n * handlers: {\n * fill: ({ fill }) => {\n * if (fill?.startsWith('gradient:')) {\n * return { background: fill.slice(9) };\n * }\n * return styleHandlers.fill({ fill });\n * },\n * },\n * });\n * ```\n */\nexport const styleHandlers = {\n border: wrapHandler(borderStyle),\n color: wrapHandler(colorStyle),\n display: wrapHandler(displayStyle),\n fade: wrapHandler(fadeStyle),\n fill: wrapHandler(fillStyle),\n svgFill: wrapHandler(svgFillStyle),\n flow: wrapHandler(flowStyle),\n gap: wrapHandler(gapStyle),\n height: wrapHandler(heightStyle),\n inset: wrapHandler(insetStyle),\n margin: wrapHandler(marginStyle),\n outline: wrapHandler(outlineStyle),\n padding: wrapHandler(paddingStyle),\n placement: wrapHandler(placementStyle),\n preset: wrapHandler(presetStyle),\n radius: wrapHandler(radiusStyle),\n scrollMargin: wrapHandler(scrollMarginStyle),\n scrollbar: wrapHandler(scrollbarStyle),\n shadow: wrapHandler(shadowStyle),\n transition: wrapHandler(transitionStyle),\n width: wrapHandler(widthStyle),\n} as const;\n","import type {\n RawStyleHandler,\n ResolvedStyleValue,\n StyleHandlerResult,\n} from '../utils/styles';\n\n/**\n * Declare a multi-dependency style handler with its dependency names inferred\n * into the handler's parameter type.\n *\n * Without it, the multi-dependency tuple form needs a hand-written parameter\n * annotation that can silently drift from the dependency list:\n *\n * ```ts\n * // Annotation and dependency list are maintained separately.\n * handlers: {\n * spacing: [['gap', 'padding'], ({ gap, padding }: { gap?: string; padding?: string }) => …],\n * }\n *\n * // Both come from the same array; a typo in the destructure is a type error.\n * handlers: {\n * spacing: defineHandler(['gap', 'padding'], ({ gap, padding }) => …),\n * }\n * ```\n *\n * Values arrive **state-resolved but unparsed** — the raw authored DSL string\n * (`'2x'`, `'#purple.5'`), so call `parseStyle()` / `parseColor()` as needed. The\n * result is a kebab-case CSS declaration map (or an array of them); the reserved\n * `$` key applies the declarations to a nested selector.\n *\n * All names must belong to the same chunk. Names the built-in chunk lists don't\n * know are pulled into their handler's chunk automatically at registration.\n */\nexport function defineHandler<const TDeps extends readonly string[]>(\n deps: TDeps,\n handler: (\n props: Partial<Record<TDeps[number], ResolvedStyleValue>>,\n ) => StyleHandlerResult,\n): [readonly string[], RawStyleHandler] {\n return [deps, handler as RawStyleHandler];\n}\n","import { predefine, styleHandlers } from './predefined';\n\nconst { STYLE_HANDLER_MAP } = predefine();\n\nexport { STYLE_HANDLER_MAP, styleHandlers };\nexport * from './createStyle';\nexport { defineHandler } from './define-handler';\nexport {\n normalizeHandlerDefinition,\n registerHandler,\n resetHandlers,\n} from './predefined';\n","import { PropertyTypeResolver } from '../properties/property-type-resolver';\nimport { createStyle, STYLE_HANDLER_MAP } from '../styles';\n\nimport type {\n CacheMetrics,\n InjectionMode,\n KeyframesInfo,\n KeyframesSteps,\n RawCSSInfo,\n RawCSSResult,\n RootRegistry,\n RuleInfo,\n SheetInfo,\n StyleInjectorConfig,\n StyleRule,\n} from './types';\n\nimport type { CSSMap, StyleHandler, StyleValueStateMap } from '../utils/styles';\n\nconst supportsConstructableSheets =\n typeof CSSStyleSheet !== 'undefined' &&\n (() => {\n try {\n new CSSStyleSheet();\n return true;\n } catch {\n return false;\n }\n })();\n\nexport class SheetManager {\n private rootRegistries = new WeakMap<Document | ShadowRoot, RootRegistry>();\n /** Strong set of active roots so background GC can iterate them all */\n private activeRoots = new Set<Document | ShadowRoot>();\n private config: StyleInjectorConfig;\n /** Dedicated style elements for raw CSS per root */\n private rawStyleElements = new WeakMap<\n Document | ShadowRoot,\n HTMLStyleElement\n >();\n /** Constructable sheets for raw CSS in adopted mode */\n private rawConstructableSheets = new WeakMap<ShadowRoot, CSSStyleSheet>();\n /** Tracking for raw CSS blocks per root */\n private rawCSSBlocks = new WeakMap<\n Document | ShadowRoot,\n Map<string, RawCSSInfo>\n >();\n /** Counter for generating unique raw CSS IDs */\n private rawCSSCounter = 0;\n\n constructor(config: StyleInjectorConfig) {\n this.config = config;\n }\n\n /**\n * Resolve the underlying CSSStyleSheet from a SheetInfo,\n * abstracting away adopted vs style-element modes.\n */\n getCSSSheet(sheetInfo: SheetInfo): CSSStyleSheet | null {\n if (sheetInfo.constructableSheet) return sheetInfo.constructableSheet;\n return sheetInfo.sheet?.sheet ?? null;\n }\n\n /**\n * Record an inserted rule text at its rule index (text mode only).\n *\n * `textRules` mirrors the sheet's rule order. `textContent` cannot be edited\n * rule-by-rule the way CSSOM can, so keeping the texts is what makes\n * deletion possible at all in this mode.\n */\n private trackTextRule(\n sheet: SheetInfo,\n ruleIndex: number,\n ruleText: string,\n ): void {\n if (!sheet.textMode) return;\n\n const rules = (sheet.textRules ??= []);\n // Defensive: keep the array dense so indices stay meaningful\n while (rules.length < ruleIndex) rules.push('');\n rules[ruleIndex] = ruleText;\n }\n\n /**\n * Remove rule indices from a text-mode sheet and rewrite the element's text.\n * Returns the indices that were actually removed.\n */\n private deleteTextRules(sheet: SheetInfo, indices: number[]): number[] {\n const rules = sheet.textRules;\n if (!rules) return [];\n\n const removed = [...new Set(indices)]\n .filter((idx) => idx >= 0 && idx < rules.length)\n .sort((a, b) => b - a);\n\n for (const idx of removed) {\n rules.splice(idx, 1);\n }\n\n if (removed.length > 0 && sheet.sheet) {\n sheet.sheet.textContent = rules.length ? '\\n' + rules.join('\\n') : '';\n }\n\n return removed;\n }\n\n /**\n * Determine the injection mode for a root.\n * ShadowRoot uses adopted stylesheets when supported; Document uses <style> elements.\n */\n private detectInjectionMode(root: Document | ShadowRoot): InjectionMode {\n if (\n root instanceof ShadowRoot &&\n supportsConstructableSheets &&\n !this.config.forceTextInjection\n ) {\n return 'adopted';\n }\n return 'style-element';\n }\n\n /**\n * Get or create registry for a root (Document or ShadowRoot)\n */\n getRegistry(root: Document | ShadowRoot): RootRegistry {\n let registry = this.rootRegistries.get(root);\n\n if (!registry) {\n const metrics: CacheMetrics | undefined = this.config.devMode\n ? {\n hits: 0,\n misses: 0,\n bulkCleanups: 0,\n totalInsertions: 0,\n totalUnused: 0,\n stylesCleanedUp: 0,\n cleanupHistory: [],\n startTime: Date.now(),\n }\n : undefined;\n\n registry = {\n sheets: [],\n refCounts: new Map(),\n rules: new Map(),\n cacheKeyToClassName: new Map(),\n ruleTextSet: new Set<string>(),\n metrics,\n keyframesCache: new Map(),\n keyframesNameToContent: new Map(),\n keyframesCounter: 0,\n injectedProperties: new Map<string, string>(),\n injectedFontFaces: new Set<string>(),\n injectedCounterStyles: new Map<string, boolean>(),\n injectedFunctions: new Map<string, boolean>(),\n globalRules: new Map(),\n propertyTypeResolver: new PropertyTypeResolver(),\n usageMap: new Map(),\n touchCount: 0,\n touchTick: -1,\n touchedTick: new Set<string>(),\n serverClassSyncIndex: 0,\n rscStylesScanned: false,\n injectionMode: this.detectInjectionMode(root),\n } as unknown as RootRegistry;\n\n this.rootRegistries.set(root, registry);\n this.activeRoots.add(root);\n }\n\n return registry;\n }\n\n /** Return all roots with active registries (for background GC sweep). */\n getActiveRoots(): Iterable<Document | ShadowRoot> {\n return this.activeRoots;\n }\n\n /** Check whether any roots have active registries. */\n hasActiveRoots(): boolean {\n return this.activeRoots.size > 0;\n }\n\n /** Remove registries for ShadowRoots whose host has been detached from the DOM. */\n pruneDisconnectedRoots(): void {\n const toPrune: (Document | ShadowRoot)[] = [];\n for (const root of this.activeRoots) {\n if (root !== document && !(root as ShadowRoot).host?.isConnected) {\n toPrune.push(root);\n }\n }\n for (const root of toPrune) {\n this.cleanup(root);\n }\n }\n\n /**\n * Create a new stylesheet for the registry.\n * In adopted mode (ShadowRoot), creates a constructable CSSStyleSheet and\n * pushes it to adoptedStyleSheets. Otherwise creates a <style> element.\n */\n createSheet(registry: RootRegistry, root: Document | ShadowRoot): SheetInfo {\n if (registry.injectionMode === 'adopted') {\n const constructableSheet = new CSSStyleSheet();\n\n // Append after any existing raw CSS sheet\n (root as ShadowRoot).adoptedStyleSheets = [\n ...(root as ShadowRoot).adoptedStyleSheets,\n constructableSheet,\n ];\n\n const sheetInfo: SheetInfo = {\n sheet: null,\n constructableSheet,\n ruleCount: 0,\n holes: [],\n };\n\n registry.sheets.push(sheetInfo);\n return sheetInfo;\n }\n\n const sheet = this.createStyleElement(root);\n\n // Pin the write mode now: `insertRule` and `deleteRule` must agree on it for\n // the lifetime of the sheet, otherwise tracked rule indices desync from\n // whichever representation is actually applied.\n const textMode =\n this.config.forceTextInjection === true || sheet.sheet == null;\n\n const sheetInfo: SheetInfo = {\n sheet,\n ruleCount: 0,\n holes: [],\n textMode,\n ...(textMode ? { textRules: [] } : {}),\n };\n\n registry.sheets.push(sheetInfo);\n return sheetInfo;\n }\n\n /**\n * Create a style element and append to document\n */\n private createStyleElement(root: Document | ShadowRoot): HTMLStyleElement {\n const style =\n (root as Document).createElement?.('style') ||\n document.createElement('style');\n\n if (this.config.nonce) {\n style.nonce = this.config.nonce;\n }\n\n style.setAttribute('data-tasty', '');\n\n // Append to head or shadow root\n if ('head' in root && root.head) {\n root.head.appendChild(style);\n } else if ('appendChild' in root) {\n root.appendChild(style);\n } else {\n document.head.appendChild(style);\n }\n\n // Verify it was actually added - log only if there's a problem and we're not using forceTextInjection\n if (!style.isConnected && !this.config.forceTextInjection) {\n console.error(\n '[Tasty] SheetManager: style element failed to connect to the DOM.',\n {\n parentNode: style.parentNode?.nodeName,\n isConnected: style.isConnected,\n },\n );\n }\n\n return style;\n }\n\n /**\n * Insert CSS rules as a single block\n */\n insertRule(\n registry: RootRegistry,\n flattenedRules: StyleRule[],\n className: string,\n root: Document | ShadowRoot,\n ): RuleInfo | null {\n // Find or create a sheet with available space\n let targetSheet = this.findAvailableSheet(registry, root);\n\n if (!targetSheet) {\n targetSheet = this.createSheet(registry, root);\n }\n\n const sheetIndex = registry.sheets.indexOf(targetSheet);\n\n try {\n // Group rules by selector, at-rules, and startingStyle to combine declarations\n const groupedRules: StyleRule[] = [];\n const groupMap = new Map<\n string,\n {\n idx: number;\n selector: string;\n atRules?: string[];\n startingStyle?: boolean;\n declarations: string;\n }\n >();\n\n const atKey = (at?: string[]) => (at && at.length ? at.join('|') : '');\n\n flattenedRules.forEach((r) => {\n const key = `${atKey(r.atRules)}||${r.selector}||${r.startingStyle ? '1' : '0'}`;\n const existing = groupMap.get(key);\n if (existing) {\n // Append declarations, preserving order\n existing.declarations = existing.declarations\n ? `${existing.declarations} ${r.declarations}`\n : r.declarations;\n } else {\n groupMap.set(key, {\n idx: groupedRules.length,\n selector: r.selector,\n atRules: r.atRules,\n startingStyle: r.startingStyle,\n declarations: r.declarations,\n });\n groupedRules.push({ ...r });\n }\n });\n\n // Normalize groupedRules from map (with merged declarations)\n groupMap.forEach((val) => {\n groupedRules[val.idx] = {\n selector: val.selector,\n atRules: val.atRules,\n startingStyle: val.startingStyle,\n declarations: val.declarations,\n } as StyleRule;\n });\n\n // Insert grouped rules\n const insertedRuleTexts: string[] = [];\n const insertedIndices: number[] = []; // Track exact indices\n // Calculate rule index atomically right before insertion to prevent race conditions\n let currentRuleIndex = this.findAvailableRuleIndex(targetSheet);\n let firstInsertedIndex: number | null = null;\n let lastInsertedIndex: number | null = null;\n\n for (const rule of groupedRules) {\n const declarations = rule.declarations;\n const innerContent = rule.startingStyle\n ? `@starting-style { ${declarations} }`\n : declarations;\n const baseRule = `${rule.selector} { ${innerContent} }`;\n\n // Wrap with at-rules if present\n let fullRule = baseRule;\n if (rule.atRules && rule.atRules.length > 0) {\n fullRule = rule.atRules.reduce(\n (css, atRule) => `${atRule} { ${css} }`,\n baseRule,\n );\n }\n\n // Insert individual rule\n const styleElement = targetSheet.sheet;\n const styleSheet = this.getCSSSheet(targetSheet);\n\n if (!targetSheet.textMode && styleSheet) {\n // Calculate index atomically for each rule to prevent concurrent insertion races\n const maxIndex = styleSheet.cssRules.length;\n const atomicRuleIndex = this.findAvailableRuleIndex(targetSheet);\n const safeIndex = Math.min(Math.max(0, atomicRuleIndex), maxIndex);\n\n // Helper: split comma-separated selectors safely (ignores commas inside [] () \" ')\n const splitSelectorsSafely = (selectorList: string): string[] => {\n const parts: string[] = [];\n let buf = '';\n let depthSq = 0; // [] depth\n let depthPar = 0; // () depth\n let inStr: '\"' | \"'\" | '' = '';\n for (let i = 0; i < selectorList.length; i++) {\n const ch = selectorList[i];\n if (inStr) {\n if (ch === inStr && selectorList[i - 1] !== '\\\\') {\n inStr = '';\n }\n buf += ch;\n continue;\n }\n if (ch === '\"' || ch === \"'\") {\n inStr = ch as '\"' | \"'\";\n buf += ch;\n continue;\n }\n if (ch === '[') depthSq++;\n else if (ch === ']') depthSq = Math.max(0, depthSq - 1);\n else if (ch === '(') depthPar++;\n else if (ch === ')') depthPar = Math.max(0, depthPar - 1);\n\n if (ch === ',' && depthSq === 0 && depthPar === 0) {\n const part = buf.trim();\n if (part) parts.push(part);\n buf = '';\n } else {\n buf += ch;\n }\n }\n const tail = buf.trim();\n if (tail) parts.push(tail);\n return parts;\n };\n\n try {\n styleSheet.insertRule(fullRule, safeIndex);\n // Update sheet ruleCount immediately to prevent concurrent race conditions\n targetSheet.ruleCount++;\n insertedIndices.push(safeIndex); // Track this index\n if (firstInsertedIndex == null) firstInsertedIndex = safeIndex;\n lastInsertedIndex = safeIndex;\n currentRuleIndex = safeIndex + 1;\n } catch (e) {\n // If the browser rejects the combined selector (e.g., vendor pseudo-elements),\n // try to split and insert each selector independently. Skip unsupported ones.\n const selectors = splitSelectorsSafely(rule.selector);\n if (selectors.length > 1) {\n let anyInserted = false;\n for (const sel of selectors) {\n const singleBase = `${sel} { ${declarations} }`;\n let singleRule = singleBase;\n if (rule.atRules && rule.atRules.length > 0) {\n singleRule = rule.atRules.reduce(\n (css, atRule) => `${atRule} { ${css} }`,\n singleBase,\n );\n }\n\n try {\n // Calculate index atomically for each individual selector insertion\n const maxIdx = styleSheet.cssRules.length;\n const atomicIdx = this.findAvailableRuleIndex(targetSheet);\n const idx = Math.min(Math.max(0, atomicIdx), maxIdx);\n styleSheet.insertRule(singleRule, idx);\n // Update sheet ruleCount immediately\n targetSheet.ruleCount++;\n insertedIndices.push(idx); // Track this index\n if (firstInsertedIndex == null) firstInsertedIndex = idx;\n lastInsertedIndex = idx;\n currentRuleIndex = idx + 1;\n anyInserted = true;\n } catch (singleErr) {\n // Skip unsupported selector in this engine (e.g., ::-moz-selection in Blink)\n if (process.env.NODE_ENV !== 'production') {\n console.warn(\n '[Tasty] Browser rejected CSS rule:',\n singleRule,\n singleErr,\n );\n }\n }\n }\n // If none inserted, continue without throwing to avoid aborting the whole batch\n if (!anyInserted) {\n // noop: all selectors invalid here; safe to skip\n }\n } else {\n // Single selector failed — skip it silently (likely unsupported in this engine).\n // For @property rules specifically, probe once per registry to distinguish\n // \"engine doesn't support @property at all\" (e.g., jsdom) from\n // \"engine supports @property but this specific rule is invalid\"\n // (a real user bug worth warning about).\n if (process.env.NODE_ENV !== 'production') {\n const isAtProperty = fullRule.startsWith('@property ');\n const shouldSuppress =\n isAtProperty &&\n !this.engineSupportsAtProperty(registry, styleSheet);\n if (!shouldSuppress) {\n console.warn(\n '[Tasty] Browser rejected CSS rule:',\n fullRule,\n e,\n );\n }\n }\n }\n }\n } else if (styleElement) {\n // Use textContent (either as fallback or when forceTextInjection is enabled)\n // Calculate index atomically for textContent insertion too\n const atomicRuleIndex = this.findAvailableRuleIndex(targetSheet);\n // Record the text so `deleteRule` can rebuild the element without it\n this.trackTextRule(targetSheet, atomicRuleIndex, fullRule);\n styleElement.textContent =\n (styleElement.textContent || '') + '\\n' + fullRule;\n // Update sheet ruleCount immediately\n targetSheet.ruleCount++;\n insertedIndices.push(atomicRuleIndex); // Track this index\n if (firstInsertedIndex == null) firstInsertedIndex = atomicRuleIndex;\n lastInsertedIndex = atomicRuleIndex;\n currentRuleIndex = atomicRuleIndex + 1;\n }\n\n // Report a detached style element only if there are issues and we're not using forceTextInjection\n if (\n styleElement &&\n !styleElement.parentNode &&\n !this.config.forceTextInjection\n ) {\n console.error(\n '[Tasty] SheetManager: style element is not attached to the DOM; rules will not apply.',\n {\n className,\n ruleIndex: currentRuleIndex,\n },\n );\n }\n\n // Dev-only: store cssText for debugging tools\n if (this.config.devMode) {\n insertedRuleTexts.push(fullRule);\n try {\n registry.ruleTextSet.add(fullRule);\n } catch {\n // noop: defensive in case ruleTextSet is unavailable\n }\n }\n // currentRuleIndex already adjusted above\n }\n\n // Sheet ruleCount is now updated immediately after each insertion\n // No need for deferred update logic\n\n if (insertedIndices.length === 0) {\n return null;\n }\n\n return {\n className,\n ruleIndex: firstInsertedIndex ?? 0,\n sheetIndex,\n cssText: this.config.devMode ? insertedRuleTexts : undefined,\n endRuleIndex: lastInsertedIndex ?? firstInsertedIndex ?? 0,\n indices: insertedIndices,\n };\n } catch (error) {\n console.warn('[Tasty] Failed to insert CSS rules:', error, {\n flattenedRules,\n className,\n });\n return null;\n }\n }\n\n /**\n * Insert global CSS rules\n */\n insertGlobalRule(\n registry: RootRegistry,\n flattenedRules: StyleRule[],\n globalKey: string,\n root: Document | ShadowRoot,\n ): RuleInfo | null {\n // Insert the rule using the same mechanism as regular rules\n const ruleInfo = this.insertRule(registry, flattenedRules, globalKey, root);\n\n // Track global rules for index adjustment\n if (ruleInfo) {\n registry.globalRules.set(globalKey, ruleInfo);\n }\n\n return ruleInfo;\n }\n\n /**\n * Delete a global CSS rule by key\n */\n public deleteGlobalRule(registry: RootRegistry, globalKey: string): void {\n const ruleInfo = registry.globalRules.get(globalKey);\n if (!ruleInfo) {\n return;\n }\n\n // Delete the rule using the standard deletion mechanism\n this.deleteRule(registry, ruleInfo);\n\n // Remove from global rules tracking\n registry.globalRules.delete(globalKey);\n }\n\n /**\n * Adjust rule indices after deletion to account for shifting\n */\n private adjustIndicesAfterDeletion(\n registry: RootRegistry,\n sheetIndex: number,\n startIdx: number,\n endIdx: number,\n deleteCount: number,\n deletedRuleInfo: RuleInfo,\n deletedIndices?: number[],\n ): void {\n try {\n const sortedDeleted =\n deletedIndices && deletedIndices.length > 0\n ? [...deletedIndices].sort((a, b) => a - b)\n : null;\n const countDeletedBefore = (sorted: number[], idx: number): number => {\n let shift = 0;\n for (const delIdx of sorted) {\n if (delIdx < idx) shift++;\n else break;\n }\n return shift;\n };\n // Helper function to adjust a single RuleInfo\n const adjustRuleInfo = (info: RuleInfo): void => {\n if (info === deletedRuleInfo) return; // Skip the deleted rule\n if (info.sheetIndex !== sheetIndex) return; // Different sheet\n\n if (!info.indices || info.indices.length === 0) {\n return;\n }\n\n if (sortedDeleted) {\n // Adjust each index based on how many deleted indices are before it\n info.indices = info.indices.map((idx) => {\n return idx - countDeletedBefore(sortedDeleted, idx);\n });\n } else {\n // Contiguous deletion: shift indices after the deleted range\n info.indices = info.indices.map((idx) =>\n idx > endIdx ? Math.max(0, idx - deleteCount) : idx,\n );\n }\n\n // Update ruleIndex and endRuleIndex to match adjusted indices\n if (info.indices.length > 0) {\n info.ruleIndex = Math.min(...info.indices);\n info.endRuleIndex = Math.max(...info.indices);\n }\n };\n\n // Adjust active rules\n for (const info of registry.rules.values()) {\n adjustRuleInfo(info);\n }\n\n // Adjust global rules\n for (const info of registry.globalRules.values()) {\n adjustRuleInfo(info);\n }\n\n // No need to separately adjust unused rules since they're part of the rules Map\n\n // Adjust keyframes indices stored in cache\n for (const entry of registry.keyframesCache.values()) {\n const ki = entry.info as KeyframesInfo;\n if (ki.sheetIndex !== sheetIndex) continue;\n if (sortedDeleted) {\n const shift = countDeletedBefore(sortedDeleted, ki.ruleIndex);\n if (shift > 0) {\n ki.ruleIndex = Math.max(0, ki.ruleIndex - shift);\n }\n } else if (ki.ruleIndex > endIdx) {\n ki.ruleIndex = Math.max(0, ki.ruleIndex - deleteCount);\n }\n }\n } catch {\n // Defensive: do not let index adjustments crash cleanup\n }\n }\n\n /**\n * Delete a CSS rule from the sheet\n */\n deleteRule(registry: RootRegistry, ruleInfo: RuleInfo): void {\n const sheet = registry.sheets[ruleInfo.sheetIndex];\n\n if (!sheet) {\n return;\n }\n\n try {\n const texts: string[] =\n this.config.devMode && Array.isArray(ruleInfo.cssText)\n ? ruleInfo.cssText.slice()\n : [];\n\n const styleSheet = this.getCSSSheet(sheet);\n\n if (sheet.textMode) {\n // Text mode: splice the rules out of the tracked texts and rewrite the\n // element. Never also touch CSSOM here — assigning textContent\n // reparses the sheet, so a CSSOM delete would be undone anyway.\n let targetIndices: number[];\n\n if (ruleInfo.indices && ruleInfo.indices.length > 0) {\n targetIndices = ruleInfo.indices;\n } else {\n // FALLBACK: range-based deletion, mirroring the CSSOM path below\n const startIdx = Math.max(0, ruleInfo.ruleIndex);\n const endIdx = Math.min(\n (sheet.textRules?.length ?? 0) - 1,\n Number.isFinite(ruleInfo.endRuleIndex as number)\n ? (ruleInfo.endRuleIndex as number)\n : startIdx,\n );\n\n targetIndices = [];\n for (let idx = startIdx; idx <= endIdx; idx++) {\n targetIndices.push(idx);\n }\n }\n\n const deletedIndices = this.deleteTextRules(sheet, targetIndices);\n\n if (deletedIndices.length > 0) {\n sheet.ruleCount = Math.max(\n 0,\n sheet.ruleCount - deletedIndices.length,\n );\n\n this.adjustIndicesAfterDeletion(\n registry,\n ruleInfo.sheetIndex,\n Math.min(...deletedIndices),\n Math.max(...deletedIndices),\n deletedIndices.length,\n ruleInfo,\n deletedIndices,\n );\n }\n } else if (styleSheet) {\n const rules = styleSheet.cssRules;\n\n // Use exact indices if available, otherwise fall back to range\n if (ruleInfo.indices && ruleInfo.indices.length > 0) {\n // NEW: Delete using exact tracked indices\n const sortedIndices = [...ruleInfo.indices].sort((a, b) => b - a); // Sort descending\n const deletedIndices: number[] = [];\n\n for (const idx of sortedIndices) {\n if (idx >= 0 && idx < styleSheet.cssRules.length) {\n try {\n styleSheet.deleteRule(idx);\n deletedIndices.push(idx);\n } catch (e) {\n console.warn(\n `[Tasty] Failed to delete rule at index ${idx}:`,\n e,\n );\n }\n }\n }\n\n sheet.ruleCount = Math.max(\n 0,\n sheet.ruleCount - deletedIndices.length,\n );\n\n // Adjust indices for all other rules\n if (deletedIndices.length > 0) {\n this.adjustIndicesAfterDeletion(\n registry,\n ruleInfo.sheetIndex,\n Math.min(...deletedIndices),\n Math.max(...deletedIndices),\n deletedIndices.length,\n ruleInfo,\n deletedIndices,\n );\n }\n } else {\n // FALLBACK: Use old range-based deletion for backwards compatibility\n const startIdx = Math.max(0, ruleInfo.ruleIndex);\n const endIdx = Math.min(\n rules.length - 1,\n Number.isFinite(ruleInfo.endRuleIndex as number)\n ? (ruleInfo.endRuleIndex as number)\n : startIdx,\n );\n\n if (Number.isFinite(startIdx) && endIdx >= startIdx) {\n const deleteCount = endIdx - startIdx + 1;\n for (let idx = endIdx; idx >= startIdx; idx--) {\n if (idx < 0 || idx >= styleSheet.cssRules.length) continue;\n styleSheet.deleteRule(idx);\n }\n sheet.ruleCount = Math.max(0, sheet.ruleCount - deleteCount);\n\n // After deletion, all subsequent rule indices shift left by deleteCount.\n // We must adjust stored indices for all other RuleInfo within the same sheet.\n this.adjustIndicesAfterDeletion(\n registry,\n ruleInfo.sheetIndex,\n startIdx,\n endIdx,\n deleteCount,\n ruleInfo,\n );\n }\n }\n }\n\n // Dev-only: remove cssText entries from validation set\n if (this.config.devMode && texts.length) {\n try {\n for (const text of texts) {\n registry.ruleTextSet.delete(text);\n }\n } catch {\n // noop\n }\n }\n } catch (error) {\n console.warn('[Tasty] Failed to delete CSS rule:', error);\n }\n }\n\n /**\n * Find a sheet with available space or return null\n */\n private findAvailableSheet(\n registry: RootRegistry,\n _root: Document | ShadowRoot,\n ): SheetInfo | null {\n const maxRules = this.config.maxRulesPerSheet;\n\n if (!maxRules) {\n // No limit, use the last sheet if it exists\n const lastSheet = registry.sheets[registry.sheets.length - 1];\n return lastSheet || null;\n }\n\n // Find sheet with space\n for (const sheet of registry.sheets) {\n if (sheet.ruleCount < maxRules) {\n return sheet;\n }\n }\n\n return null; // No available sheet found\n }\n\n /**\n * Find an available rule index in the sheet\n */\n findAvailableRuleIndex(sheet: SheetInfo): number {\n // Always append to the end - CSS doesn't have holes\n return sheet.ruleCount;\n }\n\n /**\n * Probe whether the underlying CSS engine supports `@property` at-rules.\n * Result is cached per registry on `registry.atPropertySupported`.\n *\n * The probe inserts and immediately deletes a minimal known-valid rule\n * (`@property --__tasty_probe__ { syntax: \"*\"; inherits: true; }`).\n * Engines that lack `@property` support (jsdom, happy-dom) reject any\n * `@property` rule including this one, so a probe failure is a reliable\n * signal that further `@property` rejections are environmental noise and\n * not user-authored bugs.\n *\n * The probe is intentionally a separate operation from the user's failing\n * insertion: we don't want to leak `--__tasty_probe__` into the sheet, so\n * on success we delete the probe rule immediately, leaving `ruleCount`\n * and `cssRules.length` unchanged.\n */\n private engineSupportsAtProperty(\n registry: RootRegistry,\n styleSheet: CSSStyleSheet,\n ): boolean {\n if (registry.atPropertySupported !== undefined) {\n return registry.atPropertySupported;\n }\n\n const probeRule =\n '@property --__tasty_probe__ { syntax: \"*\"; inherits: true; }';\n\n try {\n const probeIdx = styleSheet.cssRules.length;\n styleSheet.insertRule(probeRule, probeIdx);\n try {\n styleSheet.deleteRule(probeIdx);\n } catch {\n // noop: unable to delete the probe; leaving it in is harmless\n // (declares an unused CSS custom property scoped to documentElement)\n }\n registry.atPropertySupported = true;\n } catch {\n registry.atPropertySupported = false;\n }\n\n return registry.atPropertySupported;\n }\n\n /**\n * Force cleanup of unused styles\n */\n public forceCleanup(registry: RootRegistry): void {\n this.performBulkCleanup(registry);\n }\n\n /**\n * Perform bulk cleanup of all unused styles (refCount = 0).\n */\n private performBulkCleanup(registry: RootRegistry): void {\n const cleanupStartTime = Date.now();\n\n // Calculate unused rules dynamically: rules that have refCount = 0\n // and are not tracked in usageMap (GC-kept styles must survive)\n const unusedClassNames = Array.from(registry.refCounts.entries())\n .filter(\n ([className, refCount]) =>\n refCount === 0 && !registry.usageMap.has(className),\n )\n .map(([className]) => className);\n\n if (unusedClassNames.length === 0) return;\n\n const selected = unusedClassNames\n .map((className) => {\n const ruleInfo = registry.rules.get(className);\n return ruleInfo ? { className, ruleInfo } : null;\n })\n .filter((entry): entry is NonNullable<typeof entry> => entry != null);\n\n let cleanedUpCount = 0;\n let totalCssSize = 0;\n let totalRulesDeleted = 0;\n\n // Group by sheet for efficient deletion\n const rulesBySheet = new Map<\n number,\n { className: string; ruleInfo: RuleInfo }[]\n >();\n\n // Calculate CSS size before deletion and group rules\n for (const { className, ruleInfo } of selected) {\n const sheetIndex = ruleInfo.sheetIndex;\n\n // Dev-only metrics: estimate CSS size and rule count if available\n if (this.config.devMode && Array.isArray(ruleInfo.cssText)) {\n const cssSize = ruleInfo.cssText.reduce(\n (total, css) => total + css.length,\n 0,\n );\n totalCssSize += cssSize;\n totalRulesDeleted += ruleInfo.cssText.length;\n }\n\n if (!rulesBySheet.has(sheetIndex)) {\n rulesBySheet.set(sheetIndex, []);\n }\n rulesBySheet.get(sheetIndex)!.push({ className, ruleInfo });\n }\n\n // Delete rules from each sheet (in reverse order to preserve indices)\n for (const [_sheetIndex, rulesInSheet] of rulesBySheet) {\n // Sort by rule index in descending order for safe deletion\n rulesInSheet.sort((a, b) => b.ruleInfo.ruleIndex - a.ruleInfo.ruleIndex);\n\n for (const { className, ruleInfo } of rulesInSheet) {\n // SAFETY 1: Double-check refCount is still 0\n const currentRefCount = registry.refCounts.get(className) || 0;\n if (currentRefCount > 0) {\n // Class became active again; do not delete\n continue;\n }\n\n // SAFETY 2: Ensure rule wasn't replaced\n // Between scheduling and execution a class may have been replaced with a new RuleInfo\n const currentInfo = registry.rules.get(className);\n if (currentInfo !== ruleInfo) {\n // Rule was replaced; skip deletion of the old reference\n continue;\n }\n\n // SAFETY 3: Verify the sheet entry is still valid and accessible\n const sheetInfo = registry.sheets[ruleInfo.sheetIndex];\n if (!sheetInfo || (!sheetInfo.sheet && !sheetInfo.constructableSheet)) {\n // Sheet was removed or corrupted; skip this rule\n continue;\n }\n\n // SAFETY 4: Verify the rule storage itself is accessible.\n // Text-mode sheets are backed by `textRules`, not CSSOM, so a missing\n // CSSStyleSheet is expected there and must not block cleanup.\n const styleSheet = this.getCSSSheet(sheetInfo);\n if (!sheetInfo.textMode && !styleSheet) {\n // Stylesheet not available; skip this rule\n continue;\n }\n\n // SAFETY 5: Verify rule index is still within valid range\n const maxRuleIndex =\n (sheetInfo.textMode\n ? (sheetInfo.textRules?.length ?? 0)\n : (styleSheet?.cssRules.length ?? 0)) - 1;\n const startIdx = ruleInfo.ruleIndex;\n const endIdx = ruleInfo.endRuleIndex ?? ruleInfo.ruleIndex;\n\n if (startIdx < 0 || endIdx > maxRuleIndex || startIdx > endIdx) {\n // Rule indices are out of bounds; skip this rule\n continue;\n }\n\n // All safety checks passed - proceed with deletion\n this.deleteRule(registry, ruleInfo);\n registry.rules.delete(className);\n registry.refCounts.delete(className);\n\n // Clean up cache key mappings that point to this className\n const keysToDelete: string[] = [];\n for (const [\n key,\n mappedClassName,\n ] of registry.cacheKeyToClassName.entries()) {\n if (mappedClassName === className) {\n keysToDelete.push(key);\n }\n }\n for (const key of keysToDelete) {\n registry.cacheKeyToClassName.delete(key);\n }\n cleanedUpCount++;\n }\n }\n\n // Update metrics\n if (registry.metrics) {\n registry.metrics.bulkCleanups++;\n registry.metrics.stylesCleanedUp += cleanedUpCount;\n\n // Add detailed cleanup stats to history\n registry.metrics.cleanupHistory.push({\n timestamp: cleanupStartTime,\n classesDeleted: cleanedUpCount,\n cssSize: totalCssSize,\n rulesDeleted: totalRulesDeleted,\n });\n }\n }\n\n /**\n * Get total number of rules across all sheets\n */\n getTotalRuleCount(registry: RootRegistry): number {\n return registry.sheets.reduce(\n (total, sheet) => total + sheet.ruleCount - sheet.holes.length,\n 0,\n );\n }\n\n /**\n * Get CSS text from all sheets (for SSR)\n */\n getCSSText(registry: RootRegistry): string {\n const cssChunks: string[] = [];\n\n for (const sheetInfo of registry.sheets) {\n try {\n if (sheetInfo.constructableSheet) {\n const rules = Array.from(sheetInfo.constructableSheet.cssRules);\n cssChunks.push(rules.map((rule) => rule.cssText).join('\\n'));\n } else if (sheetInfo.sheet) {\n const styleElement = sheetInfo.sheet;\n if (styleElement.textContent) {\n cssChunks.push(styleElement.textContent);\n } else if (styleElement.sheet) {\n const rules = Array.from(styleElement.sheet.cssRules);\n cssChunks.push(rules.map((rule) => rule.cssText).join('\\n'));\n }\n }\n } catch (error) {\n console.warn('[Tasty] Failed to read CSS from sheet:', error);\n }\n }\n\n return cssChunks.join('\\n');\n }\n\n /**\n * Get cache performance metrics\n */\n getMetrics(registry: RootRegistry): CacheMetrics | null {\n if (!registry.metrics) return null;\n\n // Calculate unusedHits on demand - only count CSS rules since keyframes are disposed immediately\n const unusedRulesCount = Array.from(registry.refCounts.values()).filter(\n (count) => count === 0,\n ).length;\n\n return {\n ...registry.metrics,\n unusedHits: unusedRulesCount,\n };\n }\n\n /**\n * Reset cache performance metrics\n */\n resetMetrics(registry: RootRegistry): void {\n if (registry.metrics) {\n registry.metrics = {\n hits: 0,\n misses: 0,\n bulkCleanups: 0,\n totalInsertions: 0,\n totalUnused: 0,\n stylesCleanedUp: 0,\n cleanupHistory: [],\n startTime: Date.now(),\n };\n }\n }\n\n /**\n * Convert keyframes steps to CSS string.\n * Public so the SSR collector can format keyframes without DOM access.\n * Returns both the CSS text and a combined declarations string for property type scanning.\n */\n stepsToCSS(steps: KeyframesSteps): {\n css: string;\n declarations: string;\n } {\n const rules: string[] = [];\n const allDeclarations: string[] = [];\n\n for (const [key, value] of Object.entries(steps)) {\n // Support raw CSS strings for backwards compatibility\n if (typeof value === 'string') {\n rules.push(`${key} { ${value.trim()} }`);\n allDeclarations.push(value.trim());\n continue;\n }\n\n // Treat value as a style map and process via tasty style handlers\n const styleMap = (value || {}) as StyleValueStateMap;\n\n // Build a deterministic handler queue based on present style keys\n const styleNames = Object.keys(styleMap).sort();\n const handlerQueue: StyleHandler[] = [];\n const seenHandlers = new Set<StyleHandler>();\n\n styleNames.forEach((styleName) => {\n let handlers = STYLE_HANDLER_MAP[styleName];\n if (!handlers) {\n // Create a default handler for unknown styles (maps to kebab-case CSS or custom props)\n handlers = STYLE_HANDLER_MAP[styleName] = [createStyle(styleName)];\n }\n\n handlers.forEach((handler) => {\n if (!seenHandlers.has(handler)) {\n seenHandlers.add(handler);\n handlerQueue.push(handler);\n }\n });\n });\n\n // Accumulate declarations (ordered). We intentionally ignore `$` selector fan-out\n // and any responsive/state bindings for keyframes.\n const declarationPairs: { prop: string; value: string }[] = [];\n\n handlerQueue.forEach((handler) => {\n const lookup = handler.__lookupStyles;\n const filteredMap = lookup.reduce<StyleValueStateMap>((acc, name) => {\n const v = styleMap[name];\n if (v !== undefined) acc[name] = v;\n return acc;\n }, {});\n\n const result = handler(filteredMap);\n if (!result) return;\n\n const results = Array.isArray(result) ? result : [result];\n results.forEach((cssMap) => {\n if (!cssMap || typeof cssMap !== 'object') return;\n const { $: _$, ...props } = cssMap as CSSMap;\n\n Object.entries(props).forEach(([prop, val]) => {\n if (val == null || val === '') return;\n\n if (Array.isArray(val)) {\n // Multiple values for the same property -> emit in order\n val.forEach((v) => {\n if (v != null && v !== '') {\n declarationPairs.push({ prop, value: String(v) });\n }\n });\n } else {\n declarationPairs.push({ prop, value: String(val) });\n }\n });\n });\n });\n\n // Fallback: if nothing produced (e.g., empty object), generate empty block\n const declarations = declarationPairs\n .map((d) => `${d.prop}: ${d.value}`)\n .join('; ');\n\n rules.push(`${key} { ${declarations.trim()} }`);\n allDeclarations.push(declarations);\n }\n\n return { css: rules.join(' '), declarations: allDeclarations.join('; ') };\n }\n\n /**\n * Insert keyframes rule.\n * Returns the KeyframesInfo and the raw declarations string for property type scanning.\n */\n insertKeyframes(\n registry: RootRegistry,\n steps: KeyframesSteps,\n name: string,\n root: Document | ShadowRoot,\n ): { info: KeyframesInfo; declarations: string } | null {\n let targetSheet = this.findAvailableSheet(registry, root);\n if (!targetSheet) {\n targetSheet = this.createSheet(registry, root);\n }\n\n const ruleIndex = this.findAvailableRuleIndex(targetSheet);\n const sheetIndex = registry.sheets.indexOf(targetSheet);\n\n try {\n const { css: cssSteps, declarations } = this.stepsToCSS(steps);\n const fullRule = `@keyframes ${name} { ${cssSteps} }`;\n\n const styleSheet = this.getCSSSheet(targetSheet);\n\n if (!targetSheet.textMode && styleSheet) {\n const safeIndex = Math.min(\n Math.max(0, ruleIndex),\n styleSheet.cssRules.length,\n );\n styleSheet.insertRule(fullRule, safeIndex);\n } else if (targetSheet.sheet) {\n // Keyframes share the sheet's rule-index sequence, so their text has to\n // be tracked too or every later index desyncs\n this.trackTextRule(targetSheet, ruleIndex, fullRule);\n targetSheet.sheet.textContent =\n (targetSheet.sheet.textContent || '') + '\\n' + fullRule;\n }\n\n targetSheet.ruleCount++;\n\n return {\n info: {\n name,\n ruleIndex,\n sheetIndex,\n cssText: this.config.devMode ? fullRule : undefined,\n },\n declarations,\n };\n } catch (error) {\n console.warn('[Tasty] Failed to insert keyframes:', error);\n return null;\n }\n }\n\n /**\n * Delete keyframes rule\n */\n deleteKeyframes(registry: RootRegistry, info: KeyframesInfo): void {\n const sheet = registry.sheets[info.sheetIndex];\n if (!sheet) return;\n\n try {\n const styleSheet = this.getCSSSheet(sheet);\n\n // Adjust indices for all other rules in the same sheet.\n // This is critical - when a keyframe rule is deleted, all rules\n // with higher indices shift down by 1\n const adjustIndices = () =>\n this.adjustIndicesAfterDeletion(\n registry,\n info.sheetIndex,\n info.ruleIndex,\n info.ruleIndex,\n 1,\n // Create a dummy RuleInfo to satisfy the function signature\n {\n className: '',\n ruleIndex: info.ruleIndex,\n sheetIndex: info.sheetIndex,\n } as RuleInfo,\n [info.ruleIndex],\n );\n\n if (sheet.textMode) {\n const deleted = this.deleteTextRules(sheet, [info.ruleIndex]);\n\n if (deleted.length > 0) {\n sheet.ruleCount = Math.max(0, sheet.ruleCount - 1);\n adjustIndices();\n }\n } else if (styleSheet) {\n if (\n info.ruleIndex >= 0 &&\n info.ruleIndex < styleSheet.cssRules.length\n ) {\n styleSheet.deleteRule(info.ruleIndex);\n sheet.ruleCount = Math.max(0, sheet.ruleCount - 1);\n adjustIndices();\n }\n }\n } catch (error) {\n console.warn('[Tasty] Failed to delete keyframes:', error);\n }\n }\n\n /**\n * Clean up resources for a root\n */\n cleanup(root: Document | ShadowRoot): void {\n const registry = this.rootRegistries.get(root);\n\n if (!registry) {\n return;\n }\n\n if (registry.injectionMode === 'adopted') {\n // Remove all adopted stylesheets from the shadow root\n const shadowRoot = root as ShadowRoot;\n\n // Collect all constructable sheets owned by this registry\n const ownedSheets = new Set<CSSStyleSheet>();\n for (const sheetInfo of registry.sheets) {\n if (sheetInfo.constructableSheet) {\n ownedSheets.add(sheetInfo.constructableSheet);\n }\n }\n\n // Also include the raw CSS constructable sheet\n const rawSheet = this.rawConstructableSheets.get(shadowRoot);\n if (rawSheet) {\n ownedSheets.add(rawSheet);\n this.rawConstructableSheets.delete(shadowRoot);\n }\n\n // Remove owned sheets from adoptedStyleSheets\n if (ownedSheets.size > 0) {\n shadowRoot.adoptedStyleSheets = shadowRoot.adoptedStyleSheets.filter(\n (s) => !ownedSheets.has(s),\n );\n }\n } else {\n // Remove all <style> elements\n for (const sheet of registry.sheets) {\n try {\n const styleElement = sheet.sheet;\n if (styleElement?.parentNode) {\n styleElement.parentNode.removeChild(styleElement);\n }\n } catch (error) {\n console.warn('[Tasty] Failed to cleanup sheet:', error);\n }\n }\n\n // Clean up raw CSS style element\n const rawStyleElement = this.rawStyleElements.get(root);\n if (rawStyleElement?.parentNode) {\n rawStyleElement.parentNode.removeChild(rawStyleElement);\n }\n this.rawStyleElements.delete(root);\n }\n\n // Clear registry\n this.rootRegistries.delete(root);\n this.activeRoots.delete(root);\n this.rawCSSBlocks.delete(root);\n }\n\n /**\n * Check if a root uses adopted injection mode.\n */\n private isAdoptedMode(root: Document | ShadowRoot): boolean {\n const registry = this.rootRegistries.get(root);\n if (registry) return registry.injectionMode === 'adopted';\n return this.detectInjectionMode(root) === 'adopted';\n }\n\n /**\n * Get or create a constructable CSSStyleSheet for raw CSS in adopted mode.\n * The raw sheet is prepended to adoptedStyleSheets so it precedes tasty rules.\n */\n private getOrCreateRawAdoptedSheet(root: ShadowRoot): CSSStyleSheet {\n let sheet = this.rawConstructableSheets.get(root);\n\n if (!sheet) {\n sheet = new CSSStyleSheet();\n // Prepend raw sheet before any tasty-managed sheets for cascade ordering\n root.adoptedStyleSheets = [sheet, ...root.adoptedStyleSheets];\n this.rawConstructableSheets.set(root, sheet);\n if (!this.rawCSSBlocks.has(root)) {\n this.rawCSSBlocks.set(root, new Map());\n }\n }\n\n return sheet;\n }\n\n /**\n * Get or create a dedicated style element for raw CSS\n * Raw CSS is kept separate from tasty-managed sheets to avoid index conflicts\n */\n private getOrCreateRawStyleElement(\n root: Document | ShadowRoot,\n ): HTMLStyleElement {\n let styleElement = this.rawStyleElements.get(root);\n\n if (!styleElement) {\n styleElement =\n (root as Document).createElement?.('style') ||\n document.createElement('style');\n\n if (this.config.nonce) {\n styleElement.nonce = this.config.nonce;\n }\n\n styleElement.setAttribute('data-tasty-raw', '');\n\n // Append to head or shadow root\n if ('head' in root && root.head) {\n root.head.appendChild(styleElement);\n } else if ('appendChild' in root) {\n root.appendChild(styleElement);\n } else {\n document.head.appendChild(styleElement);\n }\n\n this.rawStyleElements.set(root, styleElement);\n this.rawCSSBlocks.set(root, new Map());\n }\n\n return styleElement;\n }\n\n /**\n * Inject raw CSS text directly without parsing\n * Returns a dispose function to remove the injected CSS\n */\n injectRawCSS(css: string, root: Document | ShadowRoot): RawCSSResult {\n if (!css.trim()) {\n return {\n dispose: () => {\n /* noop */\n },\n };\n }\n\n // Generate unique ID for this block\n const id = `raw_${this.rawCSSCounter++}`;\n\n if (this.isAdoptedMode(root)) {\n this.getOrCreateRawAdoptedSheet(root as ShadowRoot);\n const blocksMap = this.rawCSSBlocks.get(root)!;\n\n const info: RawCSSInfo = {\n id,\n css,\n startOffset: 0,\n endOffset: css.length,\n };\n blocksMap.set(id, info);\n\n // Rebuild full text and apply via replaceSync\n this.rebuildRawAdoptedSheet(root as ShadowRoot);\n\n return {\n dispose: () => {\n this.disposeRawCSS(id, root);\n },\n };\n }\n\n const styleElement = this.getOrCreateRawStyleElement(root);\n const blocksMap = this.rawCSSBlocks.get(root)!;\n\n // Calculate offsets\n const currentContent = styleElement.textContent || '';\n const startOffset = currentContent.length;\n const cssWithNewline = (currentContent ? '\\n' : '') + css;\n const endOffset = startOffset + cssWithNewline.length;\n\n // Append CSS\n styleElement.textContent = currentContent + cssWithNewline;\n\n // Track the block\n const info: RawCSSInfo = {\n id,\n css,\n startOffset,\n endOffset,\n };\n blocksMap.set(id, info);\n\n return {\n dispose: () => {\n this.disposeRawCSS(id, root);\n },\n };\n }\n\n /**\n * Rebuild the raw CSS constructable sheet from all tracked blocks.\n */\n private rebuildRawAdoptedSheet(root: ShadowRoot): void {\n const sheet = this.rawConstructableSheets.get(root);\n const blocksMap = this.rawCSSBlocks.get(root);\n if (!sheet || !blocksMap) return;\n\n if (blocksMap.size === 0) {\n sheet.replaceSync('');\n return;\n }\n\n const blocks = Array.from(blocksMap.values());\n blocks.sort((a, b) => a.startOffset - b.startOffset);\n const allCSS = blocks.map((b) => b.css).join('\\n');\n sheet.replaceSync(allCSS);\n }\n\n /**\n * Remove a raw CSS block by ID\n */\n private disposeRawCSS(id: string, root: Document | ShadowRoot): void {\n const blocksMap = this.rawCSSBlocks.get(root);\n if (!blocksMap) return;\n\n const info = blocksMap.get(id);\n if (!info) return;\n\n blocksMap.delete(id);\n\n // Adopted mode: rebuild via replaceSync\n if (this.isAdoptedMode(root)) {\n this.rebuildRawAdoptedSheet(root as ShadowRoot);\n return;\n }\n\n // Style-element mode: rebuild textContent\n const styleElement = this.rawStyleElements.get(root);\n if (!styleElement) return;\n\n const remainingBlocks = Array.from(blocksMap.values());\n\n if (remainingBlocks.length === 0) {\n styleElement.textContent = '';\n } else {\n remainingBlocks.sort((a, b) => a.startOffset - b.startOffset);\n const newContent = remainingBlocks.map((block) => block.css).join('\\n');\n styleElement.textContent = newContent;\n\n // Update offsets for remaining blocks\n let offset = 0;\n for (const block of remainingBlocks) {\n block.startOffset = offset;\n block.endOffset = offset + block.css.length;\n offset = block.endOffset + 1; // +1 for newline\n }\n }\n }\n\n /**\n * Get the raw CSS content\n */\n getRawCSSText(root: Document | ShadowRoot): string {\n // In adopted mode, read from the blocks map (source of truth)\n if (this.isAdoptedMode(root)) {\n const blocksMap = this.rawCSSBlocks.get(root);\n if (!blocksMap || blocksMap.size === 0) return '';\n const blocks = Array.from(blocksMap.values());\n blocks.sort((a, b) => a.startOffset - b.startOffset);\n return blocks.map((b) => b.css).join('\\n');\n }\n\n const styleElement = this.rawStyleElements.get(root);\n return styleElement?.textContent || '';\n }\n}\n","/**\n * Font Face Utilities\n *\n * Utilities for extracting and processing CSS @font-face definitions in styles.\n * Font-face rules are permanent once injected and do not need cleanup.\n */\n\nimport type { FontFaceDescriptors, FontFaceInput } from '../injector/types';\nimport type { Styles } from '../styles/types';\n\n// ============================================================================\n// Constants\n// ============================================================================\n\nconst FONT_FACE_KEY = '@font-face';\n\n// ============================================================================\n// Extraction Functions\n// ============================================================================\n\n/**\n * Check if styles object has local @font-face definition.\n */\nexport function hasLocalFontFace(styles: Styles): boolean {\n return FONT_FACE_KEY in styles;\n}\n\n/**\n * Extract local @font-face from styles object.\n * Returns null if no local font faces (fast path).\n */\nexport function extractLocalFontFace(\n styles: Styles,\n): Record<string, FontFaceInput> | null {\n const fontFace = styles[FONT_FACE_KEY];\n if (!fontFace || typeof fontFace !== 'object') {\n return null;\n }\n return fontFace as Record<string, FontFaceInput>;\n}\n\n// ============================================================================\n// CSS Formatting\n// ============================================================================\n\nconst FONT_FACE_DESCRIPTOR_MAP: Record<string, string> = {\n fontWeight: 'font-weight',\n fontStyle: 'font-style',\n fontStretch: 'font-stretch',\n fontDisplay: 'font-display',\n unicodeRange: 'unicode-range',\n ascentOverride: 'ascent-override',\n descentOverride: 'descent-override',\n lineGapOverride: 'line-gap-override',\n sizeAdjust: 'size-adjust',\n fontFeatureSettings: 'font-feature-settings',\n fontVariationSettings: 'font-variation-settings',\n};\n\n/**\n * Format the inner declarations of a @font-face rule (no wrapper).\n * Used by the injector which needs selector and declarations separately.\n */\nexport function formatFontFaceDeclarations(\n family: string,\n descriptors: FontFaceDescriptors,\n): string {\n const parts: string[] = [];\n\n parts.push(`font-family: \"${family}\";`);\n parts.push(`src: ${descriptors.src};`);\n\n for (const [key, cssName] of Object.entries(FONT_FACE_DESCRIPTOR_MAP)) {\n const value = descriptors[key as keyof FontFaceDescriptors];\n if (value !== undefined) {\n parts.push(`${cssName}: ${value};`);\n }\n }\n\n return parts.join(' ');\n}\n\n/**\n * Format a single @font-face rule as CSS.\n */\nexport function formatFontFaceRule(\n family: string,\n descriptors: FontFaceDescriptors,\n): string {\n return `@font-face { ${formatFontFaceDeclarations(family, descriptors)} }`;\n}\n\n/**\n * Format all @font-face rules for a family (handles single or array form).\n * Returns an array of CSS strings, one per rule.\n */\nexport function formatFontFaceRules(\n family: string,\n input: FontFaceInput,\n): string[] {\n const descriptors = Array.isArray(input) ? input : [input];\n return descriptors.map((desc) => formatFontFaceRule(family, desc));\n}\n\n/**\n * Generate a content hash for deduplication of a single font-face rule.\n */\nexport function fontFaceContentHash(\n family: string,\n descriptors: FontFaceDescriptors,\n): string {\n return JSON.stringify({ family, ...descriptors });\n}\n","/**\n * Counter Style Utilities\n *\n * Utilities for extracting and processing CSS @counter-style definitions in styles.\n * Counter-style rules are permanent once injected and do not need cleanup.\n */\n\nimport type { CounterStyleDescriptors } from '../injector/types';\nimport type { Styles } from '../styles/types';\n\n// ============================================================================\n// Constants\n// ============================================================================\n\nconst COUNTER_STYLE_KEY = '@counter-style';\n\n// ============================================================================\n// Extraction Functions\n// ============================================================================\n\n/**\n * Check if styles object has local @counter-style definition.\n */\nexport function hasLocalCounterStyle(styles: Styles): boolean {\n return COUNTER_STYLE_KEY in styles;\n}\n\n/**\n * Extract local @counter-style from styles object.\n * Returns null if no local counter styles (fast path).\n */\nexport function extractLocalCounterStyle(\n styles: Styles,\n): Record<string, CounterStyleDescriptors> | null {\n const counterStyle = styles[COUNTER_STYLE_KEY];\n if (!counterStyle || typeof counterStyle !== 'object') {\n return null;\n }\n return counterStyle as Record<string, CounterStyleDescriptors>;\n}\n\n// ============================================================================\n// CSS Formatting\n// ============================================================================\n\nconst COUNTER_STYLE_DESCRIPTOR_MAP: Record<string, string> = {\n system: 'system',\n symbols: 'symbols',\n additiveSymbols: 'additive-symbols',\n prefix: 'prefix',\n suffix: 'suffix',\n negative: 'negative',\n range: 'range',\n pad: 'pad',\n fallback: 'fallback',\n speakAs: 'speak-as',\n};\n\n/**\n * Format the inner declarations of a @counter-style rule (no wrapper).\n * Used by the injector which needs selector and declarations separately.\n */\nexport function formatCounterStyleDeclarations(\n descriptors: CounterStyleDescriptors,\n): string {\n const parts: string[] = [];\n\n for (const [key, cssName] of Object.entries(COUNTER_STYLE_DESCRIPTOR_MAP)) {\n const value = descriptors[key as keyof CounterStyleDescriptors];\n if (value !== undefined) {\n parts.push(`${cssName}: ${value};`);\n }\n }\n\n return parts.join(' ');\n}\n\n/**\n * Format a @counter-style rule as CSS.\n */\nexport function formatCounterStyleRule(\n name: string,\n descriptors: CounterStyleDescriptors,\n): string {\n return `@counter-style ${name} { ${formatCounterStyleDeclarations(descriptors)} }`;\n}\n","/**\n * Style injector that works with structured style objects\n * Eliminates CSS string parsing for better performance\n */\n\nimport type { StyleResult } from '../pipeline';\nimport {\n getEffectiveDefinition,\n normalizePropertyDefinition,\n} from '../properties';\nimport { hashString } from '../utils/hash';\nimport { isDevEnv } from '../utils/is-dev-env';\nimport {\n DEFAULT_NAME_PREFIX,\n makeClassName,\n makeKeyframeName,\n rscClassRegexGlobal,\n tastyClassRegex,\n validateNamePrefix,\n} from '../utils/name-prefix';\nimport type { StyleValue } from '../utils/styles';\nimport { parseStyle } from '../utils/styles';\n\nimport {\n enqueueStyleWrite,\n flushStyles,\n isBatchWindowOpen,\n warnBatchProviderMissing,\n} from './batch';\nimport type { QueuedWrite } from './batch';\nimport { SheetManager } from './sheet-manager';\nimport { fontFaceContentHash, formatFontFaceDeclarations } from '../font-face';\nimport { formatCounterStyleDeclarations } from '../counter-style';\nimport {\n formatFunctionDeclarations,\n formatFunctionPrelude,\n parseFunctionName,\n} from '../functions';\nimport {\n HYDRATED_RULE_INDEX,\n PENDING_RULE_INDEX,\n PLACEHOLDER_RULE_INDEX,\n} from './types';\nimport type {\n CacheMetrics,\n CounterStyleDescriptors,\n FontFaceDescriptors,\n FunctionDefinition,\n GCOptions,\n GlobalInjectResult,\n InjectResult,\n KeyframesCacheEntry,\n KeyframesInfo,\n KeyframesResult,\n KeyframesSteps,\n PropertyDefinition,\n RawCSSResult,\n RootRegistry,\n RuleInfo,\n StyleInjectorConfig,\n StyleRule,\n} from './types';\n\n/**\n * Placeholder `KeyframesInfo` for a cache entry reserved by a batched write and\n * not yet backed by a real rule. Only ever read through `entry.pending`, which\n * is checked before the info is used.\n */\nconst EMPTY_KEYFRAMES_INFO = {\n name: '',\n ruleIndex: PENDING_RULE_INDEX,\n sheetIndex: PENDING_RULE_INDEX,\n} as unknown as KeyframesInfo;\n\n/**\n * Extract class names from `<style data-tasty-rsc>` tags.\n * The doubled-specificity pattern `.tXXX.tXXX` makes extraction reliable.\n */\nfunction extractRSCClassNames(rscClassRegex: RegExp): string[] {\n if (typeof document === 'undefined') return [];\n const styles = document.querySelectorAll('style[data-tasty-rsc]');\n if (styles.length === 0) return [];\n\n const classSet = new Set<string>();\n for (const style of styles) {\n const text = style.textContent;\n if (!text) continue;\n let match: RegExpExecArray | null;\n rscClassRegex.lastIndex = 0;\n while ((match = rscClassRegex.exec(text)) !== null) {\n classSet.add(match[1]);\n }\n }\n return Array.from(classSet);\n}\n\n/**\n * Lazily sync server-rendered class names into the client registry.\n *\n * Sources:\n * 1. `window.__TASTY__` — pushed by SSR/RSC streaming scripts\n * 2. `<style data-tasty-rsc>` tags — inline CSS emitted by RSC components\n *\n * Called inside `inject()` / `allocateClassName()` to pick up\n * class names rendered on the server (including during SPA navigation).\n */\nfunction syncServerClasses(\n registry: RootRegistry,\n rscClassRegex: RegExp,\n): void {\n if (typeof window === 'undefined') return;\n\n // Source 1: window.__TASTY__ (SSR streaming scripts)\n const classes = window.__TASTY__;\n if (classes && classes.length > registry.serverClassSyncIndex) {\n for (let i = registry.serverClassSyncIndex; i < classes.length; i++) {\n registerHydratedClass(registry, classes[i]);\n }\n registry.serverClassSyncIndex = classes.length;\n }\n\n // Source 2: <style data-tasty-rsc> tags (RSC inline styles)\n if (!registry.rscStylesScanned) {\n registry.rscStylesScanned = true;\n for (const cls of extractRSCClassNames(rscClassRegex)) {\n registerHydratedClass(registry, cls);\n }\n }\n}\n\nfunction registerHydratedClass(\n registry: RootRegistry,\n className: string,\n): void {\n if (registry.rules.has(className)) return;\n registry.rules.set(className, {\n className,\n ruleIndex: HYDRATED_RULE_INDEX,\n sheetIndex: HYDRATED_RULE_INDEX,\n });\n registry.refCounts.set(className, 0);\n}\n\nexport class StyleInjector {\n private sheetManager: SheetManager;\n private config: StyleInjectorConfig;\n private globalRuleCounter = 0;\n private pendingGCHandle: ReturnType<typeof requestIdleCallback> | null = null;\n private namePrefix: string;\n private classRegex: RegExp;\n private rscClassRegex: RegExp;\n\n /** @internal — exposed for debug utilities only */\n get _sheetManager(): SheetManager {\n return this.sheetManager;\n }\n\n /**\n * Whether sheet writes should be queued instead of applied immediately.\n *\n * Only ever true on the client: SSR collects CSS as text and the RSC path\n * returns it as strings, so neither has a live sheet to batch writes against.\n *\n * In the default `true` mode a write is only queued inside an open batch\n * window — a commit in which `<TastyBatchProvider>` rendered and will\n * therefore flush in its insertion effect, before any layout effect can\n * measure. Everything else falls through to a synchronous write, so enabling\n * the flag cannot make a `useLayoutEffect` read an unstyled element.\n * `'always'` drops the gate and accepts that trade for wider coverage.\n */\n private get batching(): boolean {\n const mode = this.config.batchInjection;\n if (!mode || typeof document === 'undefined') return false;\n if (mode === 'always') return true;\n if (isBatchWindowOpen()) return true;\n warnBatchProviderMissing();\n return false;\n }\n\n /**\n * Apply a sheet write now, or queue it when batching is on.\n * Returns the queue handle when deferred, so the caller can cancel it if it\n * disposes before the flush.\n */\n private writeSheet(task: () => void): QueuedWrite | null {\n if (this.batching) return enqueueStyleWrite(task);\n task();\n return null;\n }\n\n /**\n * Insert a global (non-class) rule, honouring batching.\n *\n * `onApplied` records the caller's dedupe bookkeeping. When the write is\n * queued it runs eagerly, so a repeat call before the flush bails out instead\n * of queueing the same rule twice — the same reasoning as\n * `insertPropertyRule`'s eager marking. When written synchronously it runs\n * only on success, preserving the existing retry-on-failure behaviour.\n */\n private writeGlobalRule(\n registry: RootRegistry,\n rules: StyleRule[],\n key: string,\n root: Document | ShadowRoot,\n onApplied?: () => void,\n ): void {\n if (this.batching) {\n onApplied?.();\n enqueueStyleWrite(() => {\n this.sheetManager.insertGlobalRule(registry, rules, key, root);\n });\n return;\n }\n const info = this.sheetManager.insertGlobalRule(registry, rules, key, root);\n if (info) onApplied?.();\n }\n\n constructor(config: StyleInjectorConfig = {}) {\n if (config.namePrefix !== undefined) {\n validateNamePrefix(config.namePrefix);\n }\n this.config = config;\n this.sheetManager = new SheetManager(config);\n this.namePrefix = config.namePrefix ?? DEFAULT_NAME_PREFIX;\n this.classRegex = tastyClassRegex(this.namePrefix);\n this.rscClassRegex = rscClassRegexGlobal(this.namePrefix);\n }\n\n /**\n * Generate a deterministic class name from a cache key using content hash.\n * The same cache key always produces the same class name across environments\n * with the same `namePrefix`.\n */\n private generateClassName(cacheKey: string): string {\n return makeClassName(this.namePrefix, hashString(cacheKey));\n }\n\n /**\n * Check if `className` was hydrated from server-rendered styles and,\n * if so, wire the cacheKey mapping. Returns true on hit.\n */\n private tryHydratedHit(\n registry: RootRegistry,\n cacheKey: string,\n className: string,\n ): boolean {\n syncServerClasses(registry, this.rscClassRegex);\n const rule = registry.rules.get(className);\n if (\n rule &&\n rule.ruleIndex === HYDRATED_RULE_INDEX &&\n rule.sheetIndex === HYDRATED_RULE_INDEX\n ) {\n registry.cacheKeyToClassName.set(cacheKey, className);\n return true;\n }\n return false;\n }\n\n /**\n * Allocate a className for a cacheKey without injecting styles yet.\n * This allows separating className allocation (render phase) from style injection (insertion phase).\n */\n allocateClassName(\n cacheKey: string,\n options?: { root?: Document | ShadowRoot },\n ): { className: string; isNewAllocation: boolean } {\n const root = options?.root || document;\n const registry = this.sheetManager.getRegistry(root);\n\n // Check if we can reuse existing className for this cache key\n if (registry.cacheKeyToClassName.has(cacheKey)) {\n const className = registry.cacheKeyToClassName.get(cacheKey)!;\n return {\n className,\n isNewAllocation: false,\n };\n }\n\n // Generate deterministic className from cache key\n const className = this.generateClassName(cacheKey);\n\n // Check if this className was hydrated from server-rendered styles\n if (this.tryHydratedHit(registry, cacheKey, className)) {\n return { className, isNewAllocation: false };\n }\n\n // Hash collision guard: another cache key already owns this class name\n const existingRule = registry.rules.get(className);\n if (existingRule) {\n if (isDevEnv()) {\n console.warn(\n `[Tasty] Hash collision: cache keys produce the same class \"${className}\". Styles may be incorrect.`,\n );\n }\n // Treat as already allocated to avoid overwriting\n registry.cacheKeyToClassName.set(cacheKey, className);\n return { className, isNewAllocation: false };\n }\n\n // Create placeholder RuleInfo to reserve the className\n const placeholderRuleInfo = {\n className,\n ruleIndex: PLACEHOLDER_RULE_INDEX,\n sheetIndex: PLACEHOLDER_RULE_INDEX,\n };\n\n // Store RuleInfo only once by className, and map cacheKey separately\n registry.rules.set(className, placeholderRuleInfo);\n registry.cacheKeyToClassName.set(cacheKey, className);\n\n return {\n className,\n isNewAllocation: true,\n };\n }\n\n /**\n * Inject styles from StyleResult objects\n */\n inject(\n rules: StyleResult[],\n options?: { root?: Document | ShadowRoot; cacheKey?: string },\n ): InjectResult {\n const root = options?.root || document;\n const registry = this.sheetManager.getRegistry(root);\n\n if (rules.length === 0) {\n return {\n className: '',\n dispose: () => {\n /* noop */\n },\n };\n }\n\n // Rules are now in StyleRule format directly\n\n // Check if we can reuse based on cache key\n const cacheKey = options?.cacheKey;\n let className: string;\n\n if (cacheKey && registry.cacheKeyToClassName.has(cacheKey)) {\n // Reuse existing class for this cache key\n className = registry.cacheKeyToClassName.get(cacheKey)!;\n const existingRuleInfo = registry.rules.get(className)!;\n\n // Rules are already queued for a batched write. Bump the refCount and let\n // the queued write land — injecting again would duplicate every rule.\n if (existingRuleInfo.ruleIndex === PENDING_RULE_INDEX) {\n registry.refCounts.set(\n className,\n (registry.refCounts.get(className) || 0) + 1,\n );\n\n if (registry.metrics) {\n registry.metrics.hits++;\n }\n\n return {\n className,\n dispose: () => this.dispose(className, registry),\n };\n }\n\n // A placeholder means the class name was pre-allocated but its CSS was\n // never injected, so fall through and inject it now. Anything else is\n // already in a sheet.\n const isPreAllocated =\n existingRuleInfo.ruleIndex === PLACEHOLDER_RULE_INDEX &&\n existingRuleInfo.sheetIndex === PLACEHOLDER_RULE_INDEX;\n\n if (!isPreAllocated) {\n // Already injected - just increment refCount\n const currentRefCount = registry.refCounts.get(className) || 0;\n registry.refCounts.set(className, currentRefCount + 1);\n\n // Update metrics\n if (registry.metrics) {\n registry.metrics.hits++;\n }\n\n return {\n className,\n dispose: () => this.dispose(className, registry),\n };\n }\n } else if (cacheKey) {\n // Generate deterministic className from cache key\n className = this.generateClassName(cacheKey);\n\n // Check if this className was hydrated from server-rendered styles\n if (this.tryHydratedHit(registry, cacheKey, className)) {\n registry.refCounts.set(\n className,\n (registry.refCounts.get(className) || 0) + 1,\n );\n\n if (registry.metrics) {\n registry.metrics.hits++;\n }\n\n return {\n className,\n dispose: () => this.dispose(className, registry),\n };\n }\n } else {\n // No cache key — generate from rules content\n const parts = rules.map((r) => `${r.selector}\\0${r.declarations}`);\n className = makeClassName(this.namePrefix, hashString(parts.join('\\n')));\n }\n\n // Process rules: handle needsClassName flag and apply specificity\n const rulesToInsert = rules.map((rule) => {\n let newSelector = rule.selector;\n\n // If rule needs className prepended\n if (rule.needsClassName) {\n // Handle multiple selectors (separated by ||| for OR conditions)\n const selectorParts = newSelector ? newSelector.split('|||') : [''];\n\n const classPrefix = `.${className}.${className}`;\n\n newSelector = selectorParts\n .map((part) => {\n const classSelector = part ? `${classPrefix}${part}` : classPrefix;\n\n // If there's a root prefix, add it before the class selector\n if (rule.rootPrefix) {\n return `${rule.rootPrefix} ${classSelector}`;\n }\n return classSelector;\n })\n .join(', ');\n }\n\n return {\n ...rule,\n selector: newSelector,\n needsClassName: undefined, // Remove the flag after processing\n rootPrefix: undefined, // Remove rootPrefix after processing\n };\n });\n\n // The sheet write, plus the `@property` auto-registration that the rules'\n // declarations may trigger. Kept together in one closure so batching moves\n // them as a unit and the sheet ends up in the same order either way.\n const applySheetWrite = (): RuleInfo | null => {\n // Auto-register @property for custom properties with inferable types.\n // Colors are detected by --*-color name pattern, numeric types by value.\n if (this.config.autoPropertyTypes !== false) {\n const resolver = registry.propertyTypeResolver;\n const defined = registry.injectedProperties;\n for (const rule of rulesToInsert) {\n if (!rule.declarations) continue;\n resolver.scanDeclarations(\n rule.declarations,\n (name) => defined.has(name),\n (name, syntax, initialValue) => {\n this.property(name, {\n syntax,\n inherits: true,\n initialValue,\n root,\n });\n },\n );\n }\n }\n\n // Insert rules using existing sheet manager\n const ruleInfo = this.sheetManager.insertRule(\n registry,\n rulesToInsert,\n className,\n root,\n );\n\n if (!ruleInfo) {\n // Update metrics\n if (registry.metrics) {\n registry.metrics.misses++;\n }\n return null;\n }\n\n // Store in registry. Setting the cacheKey mapping is idempotent when the\n // class was pre-allocated, so both paths can share one branch.\n registry.rules.set(className, ruleInfo);\n if (cacheKey) {\n registry.cacheKeyToClassName.set(cacheKey, className);\n }\n\n // Update metrics\n if (registry.metrics) {\n registry.metrics.totalInsertions++;\n registry.metrics.misses++;\n }\n\n return ruleInfo;\n };\n\n if (this.batching) {\n // Reserve the class name before returning so a repeat inject() with the\n // same cacheKey — very common, one per sibling component — takes the\n // PENDING short-circuit above instead of queueing the same rules again.\n registry.rules.set(className, {\n className,\n ruleIndex: PENDING_RULE_INDEX,\n sheetIndex: PENDING_RULE_INDEX,\n });\n if (cacheKey) {\n registry.cacheKeyToClassName.set(cacheKey, className);\n }\n registry.refCounts.set(className, 1);\n\n const queued = enqueueStyleWrite(() => {\n if (applySheetWrite()) return;\n // Insertion failed. Fall back to the \"allocated but not injected\"\n // state so a later render retries, matching the unbatched path.\n registry.rules.set(className, {\n className,\n ruleIndex: PLACEHOLDER_RULE_INDEX,\n sheetIndex: PLACEHOLDER_RULE_INDEX,\n });\n });\n\n return {\n className,\n dispose: () => {\n // Still queued and this was the only owner: drop the write and the\n // reservation rather than leaving an orphan rule for GC to find.\n if (\n !queued.done &&\n registry.refCounts.get(className) === 1 &&\n registry.rules.get(className)?.ruleIndex === PENDING_RULE_INDEX\n ) {\n queued.cancelled = true;\n registry.rules.delete(className);\n if (cacheKey) {\n registry.cacheKeyToClassName.delete(cacheKey);\n }\n registry.refCounts.set(className, 0);\n return;\n }\n this.dispose(className, registry);\n },\n };\n }\n\n if (!applySheetWrite()) {\n return {\n className,\n dispose: () => {\n /* noop */\n },\n };\n }\n\n registry.refCounts.set(className, 1);\n\n return {\n className,\n dispose: () => this.dispose(className, registry),\n };\n }\n\n /**\n * Inject global styles (rules without a generated tasty class selector)\n * This ensures we don't reserve a tasty class name (t{number}) for global rules,\n * which could otherwise collide with element-level styles and break lookups.\n */\n injectGlobal(\n rules: StyleResult[],\n options?: { root?: Document | ShadowRoot },\n ): GlobalInjectResult {\n const root = options?.root || document;\n const registry = this.sheetManager.getRegistry(root);\n\n if (!rules || rules.length === 0) {\n return {\n dispose: () => {\n /* noop */\n },\n };\n }\n\n // Use a non-tasty identifier to avoid any collisions with .t{number} classes\n const key = `global:${this.globalRuleCounter++}`;\n\n // The `@property` auto-registration inserts rules of its own, so it stays in\n // the same queue slot as the rules that triggered it. Global rules are style\n // rules and do take part in the cascade, so they share the one FIFO with\n // component rules — that is what keeps sheet order identical to unbatched\n // output, and equal-specificity rules resolve by document order.\n const applyWrite = (): RuleInfo | null => {\n // Auto-register @property for custom properties in global rules\n if (this.config.autoPropertyTypes !== false) {\n const resolver = registry.propertyTypeResolver;\n const defined = registry.injectedProperties;\n for (const rule of rules) {\n if (!rule.declarations) continue;\n resolver.scanDeclarations(\n rule.declarations,\n (name) => defined.has(name),\n (name, syntax, initialValue) => {\n this.property(name, {\n syntax,\n inherits: true,\n initialValue,\n root,\n });\n },\n );\n }\n }\n\n const inserted = this.sheetManager.insertGlobalRule(\n registry,\n rules as unknown as StyleRule[],\n key,\n root,\n );\n\n if (registry.metrics) {\n registry.metrics.totalInsertions++;\n }\n\n return inserted;\n };\n\n if (this.batching) {\n let info: RuleInfo | null = null;\n const queued = enqueueStyleWrite(() => {\n info = applyWrite();\n });\n\n return {\n dispose: () => {\n // Cancel instead of deleting a rule that never made it into a sheet.\n if (!queued.done) {\n queued.cancelled = true;\n return;\n }\n if (info) this.sheetManager.deleteGlobalRule(registry, key);\n },\n };\n }\n\n const info = applyWrite();\n\n return {\n dispose: () => {\n if (info) this.sheetManager.deleteGlobalRule(registry, key);\n },\n };\n }\n\n /**\n * Inject raw CSS text directly without parsing\n * This is a low-overhead alternative to createGlobalStyle for raw CSS\n * The CSS is inserted into a separate style element to avoid conflicts with tasty's chunking\n */\n injectRawCSS(\n css: string,\n options?: { root?: Document | ShadowRoot },\n ): RawCSSResult {\n const root = options?.root || document;\n\n if (!this.batching) {\n return this.sheetManager.injectRawCSS(css, root);\n }\n\n // Raw CSS is arbitrary and does take part in the cascade, so it goes through\n // the same FIFO as component and global rules.\n let result: RawCSSResult | null = null;\n const queued = enqueueStyleWrite(() => {\n result = this.sheetManager.injectRawCSS(css, root);\n });\n\n return {\n dispose: () => {\n if (!queued.done) {\n queued.cancelled = true;\n return;\n }\n result?.dispose();\n },\n };\n }\n\n /**\n * Get raw CSS text for SSR\n */\n getRawCSSText(options?: { root?: Document | ShadowRoot }): string {\n flushStyles();\n const root = options?.root || document;\n return this.sheetManager.getRawCSSText(root);\n }\n\n /**\n * Increment refCount for an already-injected cacheKey and return a dispose.\n * Used by useStyles on cache hits (hydration or runtime reuse) where\n * the pipeline was skipped but refCount tracking is still needed.\n * Returns null if the cacheKey is not found.\n */\n trackRef(\n cacheKey: string,\n options?: { root?: Document | ShadowRoot },\n ): InjectResult | null {\n const root = options?.root || document;\n const registry = this.sheetManager.getRegistry(root);\n\n if (!registry.cacheKeyToClassName.has(cacheKey)) return null;\n\n const className = registry.cacheKeyToClassName.get(cacheKey)!;\n const currentRefCount = registry.refCounts.get(className) || 0;\n registry.refCounts.set(className, currentRefCount + 1);\n\n if (registry.metrics) {\n registry.metrics.hits++;\n }\n\n return {\n className,\n dispose: () => this.dispose(className, registry),\n };\n }\n\n /**\n * Dispose of a className (decrements refCount only).\n */\n private dispose(className: string, registry: RootRegistry): void {\n const currentRefCount = registry.refCounts.get(className);\n if (currentRefCount == null || currentRefCount <= 0) {\n return;\n }\n\n const newRefCount = currentRefCount - 1;\n registry.refCounts.set(className, newRefCount);\n\n if (newRefCount === 0 && registry.metrics) {\n registry.metrics.totalUnused++;\n }\n }\n\n /**\n * Force bulk cleanup of unused styles\n */\n cleanup(root?: Document | ShadowRoot): void {\n flushStyles();\n const registry = this.sheetManager.getRegistry(root || document);\n // Clean up ALL unused rules regardless of batch ratio\n this.sheetManager.forceCleanup(registry);\n }\n\n /**\n * Get CSS text from all sheets (for SSR)\n */\n getCSSText(options?: { root?: Document | ShadowRoot }): string {\n flushStyles();\n const root = options?.root || document;\n const registry = this.sheetManager.getRegistry(root);\n return this.sheetManager.getCSSText(registry);\n }\n\n /**\n * Get CSS only for the provided tasty classNames (e.g., [\"t0\",\"t3\"])\n */\n getCSSTextForClasses(\n classNames: Iterable<string>,\n options?: { root?: Document | ShadowRoot },\n ): string {\n flushStyles();\n const root = options?.root || document;\n const registry = this.sheetManager.getRegistry(root);\n\n const cssChunks: string[] = [];\n for (const cls of classNames) {\n const info = registry.rules.get(cls);\n if (info) {\n // Always prefer reading from the live stylesheet, since indices can change\n const sheet = registry.sheets[info.sheetIndex];\n const styleSheet = sheet ? this.sheetManager.getCSSSheet(sheet) : null;\n if (styleSheet) {\n const start = Math.max(0, info.ruleIndex);\n const end = Math.min(\n styleSheet.cssRules.length - 1,\n (info.endRuleIndex as number) ?? info.ruleIndex,\n );\n // Additional validation: ensure indices are valid and in correct order\n if (\n start >= 0 &&\n end >= start &&\n start < styleSheet.cssRules.length\n ) {\n for (let i = start; i <= end; i++) {\n const rule = styleSheet.cssRules[i] as CSSRule | undefined;\n if (rule) cssChunks.push(rule.cssText);\n }\n }\n } else if (info.cssText && info.cssText.length) {\n // Fallback in environments without CSSOM access\n cssChunks.push(...info.cssText);\n }\n }\n }\n return cssChunks.join('\\n');\n }\n\n /**\n * Get cache performance metrics\n */\n getMetrics(options?: { root?: Document | ShadowRoot }): CacheMetrics | null {\n // Batched insertions only count themselves once they reach a sheet, so a read\n // taken mid-window would report a torn picture: `hits` already advanced,\n // `totalInsertions` not yet.\n flushStyles();\n const root = options?.root || document;\n const registry = this.sheetManager.getRegistry(root);\n return this.sheetManager.getMetrics(registry);\n }\n\n /**\n * Reset cache performance metrics\n */\n resetMetrics(options?: { root?: Document | ShadowRoot }): void {\n const root = options?.root || document;\n const registry = this.sheetManager.getRegistry(root);\n this.sheetManager.resetMetrics(registry);\n }\n\n /**\n * Define a CSS @property custom property.\n *\n * Accepts tasty token syntax for the property name:\n * - `$name` → defines `--name`\n * - `#name` → defines `--name-color` (auto-sets syntax: '<color>', defaults initialValue: 'transparent')\n * - `--name` → defines `--name` (legacy format)\n *\n * Example:\n * @property --rotation { syntax: \"<angle>\"; inherits: false; initial-value: 45deg; }\n *\n * Note: No caching or dispose — this defines a global property.\n *\n * If the same property is registered with different options, a warning is emitted\n * but the original definition is preserved (CSS @property cannot be redefined).\n */\n property(\n name: string,\n options?: PropertyDefinition & {\n root?: Document | ShadowRoot;\n },\n ): void {\n const root = options?.root || document;\n const registry = this.sheetManager.getRegistry(root);\n\n // Parse the token and get effective definition\n // This handles $name, #name, --name formats and auto-sets syntax for colors\n const userDefinition: PropertyDefinition = {\n syntax: options?.syntax,\n inherits: options?.inherits,\n initialValue: options?.initialValue,\n };\n\n const effectiveResult = getEffectiveDefinition(name, userDefinition);\n\n if (!effectiveResult.isValid) {\n if (isDevEnv()) {\n console.warn(\n `[Tasty] property(): ${effectiveResult.error}. Got: \"${name}\"`,\n );\n }\n return;\n }\n\n const cssName = effectiveResult.cssName;\n const definition = effectiveResult.definition;\n\n this.insertPropertyRule(registry, root, cssName, definition, name);\n }\n\n /**\n * Build and insert a single `@property` rule into the given registry.\n * No-op if the property was already injected.\n */\n private insertPropertyRule(\n registry: RootRegistry,\n root: Document | ShadowRoot,\n cssName: string,\n definition: PropertyDefinition,\n cacheKey: string,\n ): void {\n if (registry.injectedProperties.has(cssName)) {\n return;\n }\n\n const parts: string[] = [];\n\n if (definition.syntax != null) {\n let syntax = String(definition.syntax).trim();\n if (!/^['\"]/u.test(syntax)) syntax = `\"${syntax}\"`;\n parts.push(`syntax: ${syntax};`);\n }\n\n // inherits is required by the CSS @property spec - default to true\n const inherits = definition.inherits ?? true;\n parts.push(`inherits: ${inherits ? 'true' : 'false'};`);\n\n if (definition.initialValue != null) {\n let initialValueStr: string;\n if (typeof definition.initialValue === 'number') {\n initialValueStr = String(definition.initialValue);\n } else {\n // Process via tasty parser to resolve custom units/functions\n initialValueStr = parseStyle(\n definition.initialValue as StyleValue,\n ).output;\n }\n parts.push(`initial-value: ${initialValueStr};`);\n }\n\n const declarations = parts.join(' ').trim();\n\n const rule: StyleRule = {\n selector: `@property ${cssName}`,\n declarations,\n } as StyleRule;\n\n // Mark as attempted BEFORE inserting so repeated calls bail early even\n // when the insertion ultimately fails (e.g., engines like jsdom that\n // don't support @property reject every @property rule unconditionally).\n // Without this, every render's auto-property scan would re-attempt the\n // same rejected rules and flood the console with warnings.\n registry.injectedProperties.set(\n cssName,\n normalizePropertyDefinition(definition),\n );\n\n this.writeGlobalRule(registry, [rule], `property:${cacheKey}`, root);\n }\n\n /**\n * Check whether a given @property name was already injected by this injector.\n *\n * Accepts tasty token syntax:\n * - `$name` → checks `--name`\n * - `#name` → checks `--name-color`\n * - `--name` → checks `--name` (legacy format)\n */\n isPropertyDefined(\n name: string,\n options?: { root?: Document | ShadowRoot },\n ): boolean {\n flushStyles();\n const root = options?.root || document;\n const registry = this.sheetManager.getRegistry(root);\n\n // Parse the token to get the CSS property name\n const effectiveResult = getEffectiveDefinition(name, {});\n if (!effectiveResult.isValid) {\n return false;\n }\n\n return registry.injectedProperties.has(effectiveResult.cssName);\n }\n\n /**\n * Inject a CSS @font-face rule.\n *\n * Permanent and global — no dispose or ref-counting.\n * Deduplicates by content hash (family + descriptors).\n */\n fontFace(\n family: string,\n descriptors: FontFaceDescriptors,\n options?: { root?: Document | ShadowRoot },\n ): void {\n const root = options?.root || document;\n const registry = this.sheetManager.getRegistry(root);\n\n const hash = fontFaceContentHash(family, descriptors);\n\n if (registry.injectedFontFaces.has(hash)) {\n return;\n }\n\n const rule: StyleRule = {\n selector: '@font-face',\n declarations: formatFontFaceDeclarations(family, descriptors),\n } as StyleRule;\n\n this.writeGlobalRule(registry, [rule], `fontface:${hash}`, root, () => {\n registry.injectedFontFaces.add(hash);\n });\n }\n\n /**\n * Inject a CSS @counter-style rule.\n *\n * Permanent and global — no dispose or ref-counting. Deduplicates by name.\n * By default a definition overrides a previously injected one of the same\n * name. Pass `weak: true` for global `configure()` definitions, which must\n * never clobber an existing rule (so component-local definitions win\n * regardless of injection order).\n */\n counterStyle(\n name: string,\n descriptors: CounterStyleDescriptors,\n options?: { root?: Document | ShadowRoot; weak?: boolean },\n ): void {\n const root = options?.root || document;\n const registry = this.sheetManager.getRegistry(root);\n const isWeak = options?.weak === true;\n\n const existingIsStrong = registry.injectedCounterStyles.get(name);\n if (existingIsStrong !== undefined) {\n // A weak (global) definition never overrides; a strong one keeps the\n // first definition. Only a strong definition replacing a weak one wins.\n if (isWeak || existingIsStrong === true) {\n return;\n }\n this.writeSheet(() => {\n this.sheetManager.deleteGlobalRule(registry, `counterstyle:${name}`);\n });\n }\n\n const rule: StyleRule = {\n selector: `@counter-style ${name}`,\n declarations: formatCounterStyleDeclarations(descriptors),\n } as StyleRule;\n\n this.writeGlobalRule(registry, [rule], `counterstyle:${name}`, root, () => {\n registry.injectedCounterStyles.set(name, !isWeak);\n });\n }\n\n /**\n * Inject a CSS @function rule (custom function).\n *\n * Permanent and global — no dispose or ref-counting. Deduplicates by function\n * name. By default a definition overrides a previously injected one of the\n * same name. Pass `weak: true` for global `configure()` definitions, which\n * must never clobber an existing rule (so component-local definitions win\n * regardless of injection order).\n */\n func(\n name: string,\n definition: FunctionDefinition,\n options?: { root?: Document | ShadowRoot; weak?: boolean },\n ): void {\n const root = options?.root || document;\n const registry = this.sheetManager.getRegistry(root);\n const isWeak = options?.weak === true;\n\n const cssName = parseFunctionName(name);\n\n const existingIsStrong = registry.injectedFunctions.get(cssName);\n if (existingIsStrong !== undefined) {\n // A weak (global) definition never overrides; a strong one keeps the\n // first definition. Only a strong definition replacing a weak one wins.\n if (isWeak || existingIsStrong === true) {\n return;\n }\n this.writeSheet(() => {\n this.sheetManager.deleteGlobalRule(registry, `function:${cssName}`);\n });\n }\n\n const rule: StyleRule = {\n selector: formatFunctionPrelude(\n name,\n definition.args,\n definition.returns,\n ),\n declarations: formatFunctionDeclarations(definition),\n } as StyleRule;\n\n this.writeGlobalRule(registry, [rule], `function:${cssName}`, root, () => {\n registry.injectedFunctions.set(cssName, !isWeak);\n });\n }\n\n /**\n * Inject keyframes and return object with toString() and dispose()\n *\n * Keyframes are cached by content (steps). If the same content is injected\n * multiple times with different provided names, the first injected name is reused.\n *\n * If the same name is provided with different content (collision), a unique\n * name is generated to avoid overwriting the existing keyframes.\n */\n keyframes(\n steps: KeyframesSteps,\n nameOrOptions?: string | { root?: Document | ShadowRoot; name?: string },\n ): KeyframesResult {\n // Parse parameters\n const isStringName = typeof nameOrOptions === 'string';\n const providedName = isStringName ? nameOrOptions : nameOrOptions?.name;\n const root = isStringName ? document : nameOrOptions?.root || document;\n const registry = this.sheetManager.getRegistry(root);\n\n if (Object.keys(steps).length === 0) {\n return {\n toString: () => '',\n dispose: () => {\n /* noop */\n },\n };\n }\n\n // Generate content-based cache key (independent of provided name)\n const contentHash = JSON.stringify(steps);\n\n // Check if this exact content is already cached\n const existing = registry.keyframesCache.get(contentHash);\n if (existing) {\n existing.refCount++;\n return {\n toString: () => existing.name,\n dispose: () => this.disposeKeyframes(contentHash, registry),\n };\n }\n\n // Determine the actual name to use\n let actualName: string;\n\n if (providedName) {\n // Check if this name is already used with different content\n const existingContentForName =\n registry.keyframesNameToContent.get(providedName);\n\n if (existingContentForName && existingContentForName !== contentHash) {\n // Name collision: same name, different content\n // Generate a unique name to avoid overwriting\n actualName = `${providedName}-${makeKeyframeName(\n this.namePrefix,\n String(registry.keyframesCounter++),\n )}`;\n } else {\n // Name is available or used with same content\n actualName = providedName;\n // Track this name -> content mapping\n registry.keyframesNameToContent.set(providedName, contentHash);\n }\n } else {\n // No name provided, generate one\n actualName = makeKeyframeName(\n this.namePrefix,\n String(registry.keyframesCounter++),\n );\n }\n\n // The insertion plus the `@property` scan over the resulting declarations.\n // Returns false when the sheet rejected the rule, so the caller can leave\n // the cache untouched and let a later call retry.\n const applyWrite = (): boolean => {\n const result = this.sheetManager.insertKeyframes(\n registry,\n steps,\n actualName,\n root,\n );\n if (!result) return false;\n\n const { info, declarations } = result;\n\n // Auto-register @property for custom properties found in keyframe declarations\n if (this.config.autoPropertyTypes !== false && declarations) {\n const resolver = registry.propertyTypeResolver;\n resolver.scanDeclarations(\n declarations,\n (name) => registry.injectedProperties.has(name),\n (name, syntax, initialValue) => {\n this.property(name, {\n syntax,\n inherits: true,\n initialValue,\n root,\n });\n },\n );\n }\n\n const entry = registry.keyframesCache.get(contentHash);\n if (entry) {\n // Batched path: the entry was reserved up front, fill in the real info.\n entry.info = info;\n entry.pending = undefined;\n } else {\n registry.keyframesCache.set(contentHash, {\n name: actualName,\n refCount: 1,\n info,\n });\n }\n\n // Update metrics\n if (registry.metrics) {\n registry.metrics.totalInsertions++;\n registry.metrics.misses++;\n }\n\n return true;\n };\n\n if (this.batching) {\n // Reserve the cache entry now so a second keyframes() call with the same\n // content before the flush reuses the name instead of queueing again.\n // `info` is a placeholder until the write lands; `pending` marks that, and\n // disposeKeyframes() cancels rather than deleting a non-existent rule.\n const entry: KeyframesCacheEntry = {\n name: actualName,\n refCount: 1,\n info: EMPTY_KEYFRAMES_INFO,\n };\n registry.keyframesCache.set(contentHash, entry);\n\n entry.pending = enqueueStyleWrite(() => {\n if (applyWrite()) return;\n // Rejected: drop the reservation so a later call can retry, mirroring\n // the unbatched path which never caches a failed insertion.\n if (registry.keyframesCache.get(contentHash) === entry) {\n registry.keyframesCache.delete(contentHash);\n }\n });\n\n return {\n toString: () => actualName,\n dispose: () => this.disposeKeyframes(contentHash, registry),\n };\n }\n\n if (!applyWrite()) {\n return {\n toString: () => '',\n dispose: () => {\n /* noop */\n },\n };\n }\n\n return {\n toString: () => actualName,\n dispose: () => this.disposeKeyframes(contentHash, registry),\n };\n }\n\n /**\n * Dispose keyframes\n */\n private disposeKeyframes(contentHash: string, registry: RootRegistry): void {\n const entry = registry.keyframesCache.get(contentHash);\n if (!entry) return;\n\n entry.refCount--;\n if (entry.refCount <= 0) {\n // Queued but not yet written: cancel the write instead of deleting a rule\n // that was never inserted.\n if (entry.pending && !entry.pending.done) {\n entry.pending.cancelled = true;\n } else {\n // Dispose immediately - keyframes are global and safe to clean up right away\n this.sheetManager.deleteKeyframes(registry, entry.info);\n }\n registry.keyframesCache.delete(contentHash);\n\n // Clean up name-to-content mapping if this name was tracked\n // Find and remove the mapping for this content hash\n for (const [name, hash] of registry.keyframesNameToContent.entries()) {\n if (hash === contentHash) {\n registry.keyframesNameToContent.delete(name);\n break;\n }\n }\n\n // Update metrics\n if (registry.metrics) {\n registry.metrics.totalUnused++;\n registry.metrics.stylesCleanedUp++;\n }\n }\n }\n\n // =========================================================================\n // GC: touch-count-driven garbage collection with DOM safety guard\n // =========================================================================\n\n /**\n * Record a render-time usage hit for one or more classNames.\n * Handles space-separated multi-chunk classNames.\n * When the global touch counter reaches `touchInterval`, schedules a GC\n * via `requestIdleCallback`.\n * No-op on the server.\n */\n touch(className: string, options?: { root?: Document | ShadowRoot }): void {\n if (typeof document === 'undefined') return;\n if (!this.config.gc) return;\n\n const root = options?.root || document;\n const registry = this.sheetManager.getRegistry(root);\n const now = Date.now();\n\n // `touch()` runs on every render of every tasty component — on a fully\n // cached render it is the only work left — and a page typically renders\n // hundreds of components sharing a handful of class names. Everything below\n // stamps `lastTouchedAt` with the millisecond we are already in, so\n // re-touching the same class-name string inside that millisecond writes the\n // value it already holds. Skip it: one Set lookup instead of a split, a\n // regex test and two Map operations per chunk.\n if (registry.touchTick !== now) {\n registry.touchTick = now;\n registry.touchedTick.clear();\n } else if (registry.touchedTick.has(className)) {\n return;\n }\n registry.touchedTick.add(className);\n\n const parts =\n className.indexOf(' ') === -1 ? [className] : className.split(' ');\n\n for (const cls of parts) {\n if (!this.classRegex.test(cls)) continue;\n if (!registry.rules.has(cls)) continue;\n\n const entry = registry.usageMap.get(cls);\n if (entry) {\n entry.lastTouchedAt = now;\n } else {\n registry.usageMap.set(cls, { lastTouchedAt: now });\n }\n registry.touchCount++;\n }\n\n const touchInterval = this.config.gc.touchInterval ?? 1000;\n if (registry.touchCount >= touchInterval) {\n registry.touchCount = 0;\n this.scheduleGC();\n }\n }\n\n /**\n * Schedule a GC via `requestIdleCallback` (or synchronously as fallback).\n * Runs GC on all active roots. Avoids double-scheduling via `pendingGCHandle`.\n */\n private scheduleGC(): void {\n if (this.pendingGCHandle != null) return;\n\n const runGC = () => {\n this.pendingGCHandle = null;\n this.sheetManager.pruneDisconnectedRoots();\n for (const root of this.sheetManager.getActiveRoots()) {\n this.gc({ root });\n }\n };\n\n if (typeof requestIdleCallback !== 'undefined') {\n this.pendingGCHandle = requestIdleCallback(() => runGC());\n } else {\n runGC();\n }\n }\n\n /**\n * Synchronous garbage collection.\n *\n * 1. Quick upper-bound check: skip if unused count can't exceed capacity.\n * 2. Scans the DOM for live tasty classNames (safety guard).\n * 3. With `force: true`: deletes all unused entries inline.\n * Without `force`: collects unused, sorts oldest-first, evicts over capacity.\n *\n * @returns Number of styles evicted.\n */\n gc(options?: GCOptions): number {\n // Pending writes still carry PENDING sentinels in `registry.rules`; sweeping\n // those would corrupt sheet indices, so land every write first.\n flushStyles();\n if (typeof document === 'undefined') return 0;\n\n // Cancel any pending idle-scheduled GC to prevent double runs\n if (this.pendingGCHandle != null) {\n if (typeof cancelIdleCallback !== 'undefined') {\n cancelIdleCallback(this.pendingGCHandle);\n }\n this.pendingGCHandle = null;\n }\n\n const root = options?.root || document;\n const force = options?.force ?? false;\n const registry = this.sheetManager.getRegistry(root);\n const capacity = this.config.gc?.capacity ?? 1000;\n\n // Quick upper-bound check: count active refs to see if there could\n // possibly be enough unused entries to exceed capacity.\n // This avoids the expensive DOM scan when most styles are active.\n if (!force) {\n let activeCount = 0;\n for (const refCount of registry.refCounts.values()) {\n if (refCount > 0) activeCount++;\n }\n if (registry.usageMap.size - activeCount <= capacity) {\n return 0;\n }\n }\n\n // Scan DOM for live classes (classList handles SVG elements too)\n const liveClasses = new Set<string>();\n for (const el of root.querySelectorAll('[class]')) {\n for (const token of el.classList) {\n if (this.classRegex.test(token)) {\n liveClasses.add(token);\n }\n }\n }\n\n let swept = 0;\n\n if (force) {\n for (const [className] of registry.usageMap) {\n if (liveClasses.has(className)) continue;\n if ((registry.refCounts.get(className) ?? 0) > 0) continue;\n registry.usageMap.delete(className);\n swept++;\n }\n } else {\n const unused: { className: string; lastTouchedAt: number }[] = [];\n for (const [className, usage] of registry.usageMap) {\n if (liveClasses.has(className)) continue;\n if ((registry.refCounts.get(className) ?? 0) > 0) continue;\n unused.push({ className, lastTouchedAt: usage.lastTouchedAt });\n }\n\n if (unused.length > capacity) {\n unused.sort((a, b) => a.lastTouchedAt - b.lastTouchedAt);\n const toEvict = unused.length - capacity;\n for (let i = 0; i < toEvict; i++) {\n registry.usageMap.delete(unused[i].className);\n swept++;\n }\n }\n }\n\n if (swept > 0) {\n this.sheetManager.forceCleanup(registry);\n }\n\n return swept;\n }\n\n /**\n * Destroy all resources for a root\n */\n destroy(root?: Document | ShadowRoot): void {\n flushStyles();\n const targetRoot = root || document;\n this.sheetManager.cleanup(targetRoot);\n\n // Clear pending GC when no active roots remain\n if (this.pendingGCHandle != null && !this.sheetManager.hasActiveRoots()) {\n if (typeof cancelIdleCallback !== 'undefined') {\n cancelIdleCallback(this.pendingGCHandle);\n }\n this.pendingGCHandle = null;\n }\n }\n}\n","/**\n * Advanced State Mapping - Predefined States Management\n *\n * This module handles global and local predefined states for the Tasty styling system.\n * See ADVANCED_STATE_MAPPING.md for full specification.\n */\n\nimport { hasStylesGenerated } from '../config';\nimport type { Styles } from '../styles/types';\nimport { isDevEnv } from '../utils/is-dev-env';\n\n/**\n * Parsed advanced state information\n */\nexport interface ParsedAdvancedState {\n type:\n | 'media'\n | 'container'\n | 'root'\n | 'parent'\n | 'own'\n | 'starting'\n | 'predefined'\n | 'modifier';\n condition: string; // e.g., 'width <= 920px' or 'hovered'\n containerName?: string; // for container queries\n raw: string; // original state key\n mediaType?: string; // for @media:screen, @media:print, etc.\n}\n\n/**\n * Context for state parsing operations\n */\nexport interface StateParserContext {\n localPredefinedStates: Record<string, string>;\n globalPredefinedStates: Record<string, string>;\n isSubElement?: boolean; // true when processing sub-element styles (for @own() validation)\n}\n\n/**\n * At-rule context for CSS generation\n */\nexport interface AtRuleContext {\n media?: string[]; // @media conditions to wrap rule in (merged with 'and')\n container?: { name?: string; condition: string }[]; // @container conditions (nested)\n startingStyle?: boolean;\n rootStates?: string[]; // :root state selectors (e.g., '[data-theme=\"dark\"]')\n negatedRootStates?: string[]; // Negated :root state selectors for non-overlapping rules (e.g., ':not([data-theme=\"dark\"])')\n}\n\n// Built-in state names that cannot be overridden\nconst BUILTIN_STATES = new Set([\n '@starting',\n '@keyframes',\n '@property',\n '@font-face',\n '@counter-style',\n '@function',\n '@supports',\n // @inherit is a value (not a key), but reserved here to prevent\n // users from accidentally defining a state named '@inherit'.\n '@inherit',\n]);\n\n// Reserved prefixes that are built-in.\n// Must stay in sync with BUILTIN_STATES above: that list gates exact names,\n// this one gates prefixes (see isCustomStateKey).\nconst RESERVED_PREFIXES = [\n '@media',\n '@root',\n '@parent',\n '@own',\n '@(',\n '@starting',\n '@keyframes',\n '@property',\n '@font-face',\n '@counter-style',\n '@function',\n '@supports',\n '@inherit',\n];\n\n// Global predefined states storage\nlet globalPredefinedStates: Record<string, string> = {};\n\n// Warnings tracking to avoid duplicates\nconst emittedWarnings = new Set<string>();\n\nconst devMode = isDevEnv();\n\n/**\n * Emit a warning only once\n */\nfunction warnOnce(key: string, message: string): void {\n if (devMode && !emittedWarnings.has(key)) {\n emittedWarnings.add(key);\n console.warn(message);\n }\n}\n\n/**\n * Configure global predefined states\n */\nexport function setGlobalPredefinedStates(\n states: Record<string, string>,\n): void {\n if (hasStylesGenerated()) {\n const newStateNames = Object.keys(states).join(', ');\n warnOnce(\n `dynamic-states:${newStateNames}`,\n `[Tasty] Cannot update predefined states after styles have been generated.\\n` +\n `The new definition(s) for ${newStateNames} will be ignored.`,\n );\n return;\n }\n\n // Validate state names\n for (const [name, value] of Object.entries(states)) {\n // Check for valid name format\n if (!/^@[A-Za-z][A-Za-z0-9-]*$/.test(name)) {\n warnOnce(\n `invalid-state-name:${name}`,\n `[Tasty] Invalid predefined state name '${name}'. Must start with '@' followed by a letter.`,\n );\n continue;\n }\n\n // Check for reserved names\n if (BUILTIN_STATES.has(name)) {\n warnOnce(\n `reserved-state:${name}`,\n `[Tasty] Cannot define predefined state '${name}'. This name is reserved for built-in functionality.`,\n );\n continue;\n }\n\n // Check for reserved prefixes (but only exact matches, not user-defined states like @mobile)\n // Reserved prefixes are: @media, @root, @parent, @own, @(\n // A user state like @mobile should NOT be blocked\n const isReservedPrefix =\n name === '@media' ||\n name === '@root' ||\n name === '@parent' ||\n name === '@own' ||\n name.startsWith('@(');\n\n if (isReservedPrefix) {\n warnOnce(\n `reserved-prefix:${name}`,\n `[Tasty] Cannot define predefined state '${name}'. This prefix is reserved for built-in functionality.`,\n );\n continue;\n }\n\n // Check for cross-references\n const crossRefs = extractPredefinedStateRefs(value);\n if (crossRefs.length > 0) {\n warnOnce(\n `cross-ref:${name}`,\n `[Tasty] Predefined state '${name}' references another predefined state '${crossRefs[0]}'.\\n` +\n `Predefined states cannot reference each other. Use the full definition instead.`,\n );\n continue;\n }\n\n // Check for duplicates\n if (\n globalPredefinedStates[name] &&\n globalPredefinedStates[name] !== value\n ) {\n warnOnce(\n `duplicate-state:${name}`,\n `[Tasty] Duplicate predefined state '${name}' in configure(). The last definition will be used.`,\n );\n }\n\n globalPredefinedStates[name] = value;\n }\n}\n\n/**\n * Get global predefined states\n */\nexport function getGlobalPredefinedStates(): Record<string, string> {\n return globalPredefinedStates;\n}\n\n/**\n * Clear global predefined states (for testing only)\n */\nexport function clearGlobalPredefinedStates(): void {\n globalPredefinedStates = {};\n emittedWarnings.clear();\n}\n\n/**\n * Regex to match predefined state references in a string\n * Matches @name that is NOT followed by ( or : and is a complete word\n * Uses word boundary and negative lookahead\n */\nconst PREDEFINED_STATE_PATTERN = /@([A-Za-z][A-Za-z0-9-]*)(?![A-Za-z0-9-:(])/g;\n\n/**\n * Extract predefined state references from a string\n */\nexport function extractPredefinedStateRefs(value: string): string[] {\n const matches = value.matchAll(PREDEFINED_STATE_PATTERN);\n const refs: string[] = [];\n\n for (const match of matches) {\n const stateName = '@' + match[1];\n // Skip built-in states (@starting) and duplicates\n // Note: @media, @root, @own are always followed by '(' so the regex\n // negative lookahead (?![A-Za-z0-9-:(]) already excludes them\n if (!BUILTIN_STATES.has(stateName) && !refs.includes(stateName)) {\n refs.push(stateName);\n }\n }\n\n return refs;\n}\n\n/**\n * Check if a state key is a predefined state reference\n */\nexport function isPredefinedStateRef(stateKey: string): boolean {\n if (!stateKey.startsWith('@')) return false;\n if (BUILTIN_STATES.has(stateKey)) return false;\n\n // Check if it's NOT a built-in prefix\n for (const prefix of RESERVED_PREFIXES) {\n if (stateKey === prefix || stateKey.startsWith(prefix)) {\n // Check if it's exactly @media, @root, @parent, @own, or starts with @( or @media(\n if (\n stateKey === '@media' ||\n stateKey.startsWith('@media(') ||\n stateKey.startsWith('@media:')\n ) {\n return false;\n }\n if (stateKey === '@root' || stateKey.startsWith('@root(')) return false;\n if (stateKey === '@parent' || stateKey.startsWith('@parent('))\n return false;\n if (stateKey === '@own' || stateKey.startsWith('@own(')) return false;\n if (stateKey.startsWith('@(')) return false;\n }\n }\n\n // Must match the predefined state pattern\n return /^@[A-Za-z][A-Za-z0-9-]*$/.test(stateKey);\n}\n\nconst _localStatesCache = new WeakMap<object, Record<string, string>>();\n\n/**\n * Extract local predefined states from a styles object\n * Local predefined states are top-level keys starting with @ that have string values\n * and are valid predefined state names (not built-in like @media, @root, etc.)\n *\n * Results are cached by object identity via WeakMap since the same styles object\n * is passed to this function multiple times per pipeline run (once per chunk\n * in renderStylesForChunk and generateChunkCacheKey).\n */\nexport function extractLocalPredefinedStates(\n styles: Styles,\n): Record<string, string> {\n if (!styles || typeof styles !== 'object') {\n return {};\n }\n\n const cached = _localStatesCache.get(styles as object);\n if (cached !== undefined) return cached;\n\n const localStates: Record<string, string> = {};\n\n for (const [key, value] of Object.entries(styles)) {\n // Check if it's a predefined state definition (starts with @, has string value)\n if (key.startsWith('@') && typeof value === 'string') {\n // Validate name format - must be @[letter][letters/numbers/dashes]*\n if (!/^@[A-Za-z][A-Za-z0-9-]*$/.test(key)) {\n continue; // Skip invalid names silently (might be something else)\n }\n\n // Skip built-in states\n if (BUILTIN_STATES.has(key)) {\n continue;\n }\n\n // Skip reserved prefixes\n if (\n key === '@media' ||\n key === '@root' ||\n key === '@parent' ||\n key === '@own' ||\n key.startsWith('@(')\n ) {\n continue;\n }\n\n // Check for cross-references (predefined states cannot reference each other)\n const crossRefs = extractPredefinedStateRefs(value);\n if (crossRefs.length > 0) {\n warnOnce(\n `local-cross-ref:${key}`,\n `[Tasty] Predefined state '${key}' references another predefined state '${crossRefs[0]}'.\\n` +\n `Predefined states cannot reference each other. Use the full definition instead.`,\n );\n continue;\n }\n\n localStates[key] = value;\n }\n }\n\n _localStatesCache.set(styles as object, localStates);\n\n return localStates;\n}\n\n/**\n * Create a state parser context from styles\n */\nexport function createStateParserContext(\n styles?: Styles,\n isSubElement?: boolean,\n): StateParserContext {\n const localStates = styles ? extractLocalPredefinedStates(styles) : {};\n\n return {\n localPredefinedStates: localStates,\n globalPredefinedStates: getGlobalPredefinedStates(),\n isSubElement,\n };\n}\n\n/**\n * Resolve a predefined state reference to its value\n * Returns the resolved value or null if not found\n */\nexport function resolvePredefinedState(\n stateKey: string,\n ctx: StateParserContext,\n): string | null {\n // Check local first (higher priority)\n if (ctx.localPredefinedStates[stateKey]) {\n return ctx.localPredefinedStates[stateKey];\n }\n\n // Then check global\n if (ctx.globalPredefinedStates[stateKey]) {\n return ctx.globalPredefinedStates[stateKey];\n }\n\n // Not found - emit warning\n warnOnce(\n `undefined-state:${stateKey}`,\n `[Tasty] Undefined predefined state '${stateKey}'.\\n` +\n `Define it in configure({ states: { '${stateKey}': '...' } }) or in the component's styles.`,\n );\n\n return null;\n}\n\n/**\n * Normalize state key by trimming whitespace and removing trailing/leading operators\n */\nexport function normalizeStateKey(stateKey: string): {\n key: string;\n warnings: string[];\n} {\n const warnings: string[] = [];\n let key = stateKey;\n\n // Check for whitespace-only\n if (key.trim() === '') {\n if (key !== '') {\n warnings.push(\n `[Tasty] Whitespace-only state key normalized to default state ''.`,\n );\n }\n return { key: '', warnings };\n }\n\n // Trim whitespace\n key = key.trim();\n\n // Remove trailing operators\n const trailingOpMatch = key.match(/\\s*[&|^]\\s*$/);\n if (trailingOpMatch) {\n const originalKey = key;\n key = key.slice(0, -trailingOpMatch[0].length).trim();\n warnings.push(\n `[Tasty] State key '${originalKey}' has trailing operator. Normalized to '${key}'.`,\n );\n }\n\n // Remove leading operators (except !)\n const leadingOpMatch = key.match(/^\\s*[&|^]\\s*/);\n if (leadingOpMatch) {\n const originalKey = key;\n key = key.slice(leadingOpMatch[0].length).trim();\n warnings.push(\n `[Tasty] State key '${originalKey}' has leading operator. Normalized to '${key}'.`,\n );\n }\n\n return { key, warnings };\n}\n\n/**\n * Expand dimension shorthands in a condition string\n * w -> width, h -> height, is -> inline-size, bs -> block-size\n */\nexport function expandDimensionShorthands(condition: string): string {\n // Replace dimension shorthands (only when they appear as standalone words)\n let result = condition;\n\n // w -> width (but not part of other words)\n result = result.replace(/\\bw\\b/g, 'width');\n\n // h -> height\n result = result.replace(/\\bh\\b/g, 'height');\n\n // is -> inline-size\n result = result.replace(/\\bis\\b/g, 'inline-size');\n\n // bs -> block-size\n result = result.replace(/\\bbs\\b/g, 'block-size');\n\n return result;\n}\n\n/**\n * Convert tasty units in a string (e.g., 40x -> calc(var(--gap) * 40))\n */\nexport function expandTastyUnits(value: string): string {\n // Match number followed by 'x' unit (tasty gap unit)\n return value.replace(/(\\d+(?:\\.\\d+)?)\\s*x\\b/g, (_, num) => {\n return `calc(var(--gap) * ${num})`;\n });\n}\n\n/**\n * Parse an advanced state key and return its type and components\n */\nexport function parseAdvancedState(\n stateKey: string,\n ctx: StateParserContext,\n): ParsedAdvancedState {\n const raw = stateKey;\n\n // Check for @starting (exact match)\n if (stateKey === '@starting') {\n return {\n type: 'starting',\n condition: '',\n raw,\n };\n }\n\n // Check for @media:type (e.g., @media:print)\n if (stateKey.startsWith('@media:')) {\n const mediaType = stateKey.slice(7); // Remove '@media:'\n if (!['all', 'screen', 'print', 'speech'].includes(mediaType)) {\n warnOnce(\n `unknown-media-type:${mediaType}`,\n `[Tasty] Unknown media type '${mediaType}'. Valid types: all, screen, print, speech.`,\n );\n }\n return {\n type: 'media',\n condition: '',\n mediaType,\n raw,\n };\n }\n\n // Check for @media(...) - media query with condition\n if (stateKey.startsWith('@media(')) {\n const endParen = findMatchingParen(stateKey, 6);\n if (endParen === -1) {\n warnOnce(\n `unclosed-media:${stateKey}`,\n `[Tasty] Unclosed media query '${stateKey}'. Missing closing parenthesis.`,\n );\n return { type: 'modifier', condition: stateKey, raw };\n }\n\n let condition = stateKey.slice(7, endParen);\n\n // Check for empty condition\n if (!condition.trim()) {\n warnOnce(\n `empty-media:${stateKey}`,\n `[Tasty] Empty media query condition '${stateKey}'.`,\n );\n return { type: 'modifier', condition: stateKey, raw };\n }\n\n // Expand shorthands and units\n condition = expandDimensionShorthands(condition);\n condition = expandTastyUnits(condition);\n\n return {\n type: 'media',\n condition,\n raw,\n };\n }\n\n // Check for @root(...) - root state\n if (stateKey.startsWith('@root(')) {\n const endParen = findMatchingParen(stateKey, 5);\n if (endParen === -1) {\n warnOnce(\n `unclosed-root:${stateKey}`,\n `[Tasty] Unclosed root state '${stateKey}'. Missing closing parenthesis.`,\n );\n return { type: 'modifier', condition: stateKey, raw };\n }\n\n const condition = stateKey.slice(6, endParen);\n\n if (!condition.trim()) {\n warnOnce(\n `empty-root:${stateKey}`,\n `[Tasty] Empty root state condition '${stateKey}'.`,\n );\n return { type: 'modifier', condition: stateKey, raw };\n }\n\n return {\n type: 'root',\n condition,\n raw,\n };\n }\n\n // Check for @parent(...) - parent element state\n if (stateKey.startsWith('@parent(')) {\n const endParen = findMatchingParen(stateKey, 7);\n if (endParen === -1) {\n warnOnce(\n `unclosed-parent:${stateKey}`,\n `[Tasty] Unclosed parent state '${stateKey}'. Missing closing parenthesis.`,\n );\n return { type: 'modifier', condition: stateKey, raw };\n }\n\n const condition = stateKey.slice(8, endParen);\n\n if (!condition.trim()) {\n warnOnce(\n `empty-parent:${stateKey}`,\n `[Tasty] Empty parent state condition '${stateKey}'.`,\n );\n return { type: 'modifier', condition: stateKey, raw };\n }\n\n return {\n type: 'parent',\n condition,\n raw,\n };\n }\n\n // Check for @own(...) - sub-element own state\n if (stateKey.startsWith('@own(')) {\n const endParen = findMatchingParen(stateKey, 4);\n if (endParen === -1) {\n warnOnce(\n `unclosed-own:${stateKey}`,\n `[Tasty] Unclosed own state '${stateKey}'. Missing closing parenthesis.`,\n );\n return { type: 'modifier', condition: stateKey, raw };\n }\n\n const condition = stateKey.slice(5, endParen);\n\n if (!condition.trim()) {\n warnOnce(\n `empty-own:${stateKey}`,\n `[Tasty] Empty own state condition '${stateKey}'.`,\n );\n return { type: 'modifier', condition: stateKey, raw };\n }\n\n // Check if used outside sub-element context\n if (!ctx.isSubElement) {\n warnOnce(\n `own-outside-subelement:${stateKey}`,\n `[Tasty] @own(${condition}) used outside sub-element context.\\n` +\n `@own() is equivalent to '${condition}' at the root level. ` +\n `Did you mean to use it inside a sub-element?`,\n );\n // Treat as regular modifier\n return {\n type: 'modifier',\n condition,\n raw,\n };\n }\n\n return {\n type: 'own',\n condition,\n raw,\n };\n }\n\n // Check for @(...) - container query (unnamed or named)\n if (stateKey.startsWith('@(')) {\n const endParen = findMatchingParen(stateKey, 1);\n if (endParen === -1) {\n warnOnce(\n `unclosed-container:${stateKey}`,\n `[Tasty] Unclosed container query '${stateKey}'. Missing closing parenthesis.`,\n );\n return { type: 'modifier', condition: stateKey, raw };\n }\n\n const content = stateKey.slice(2, endParen);\n\n if (!content.trim()) {\n warnOnce(\n `empty-container:${stateKey}`,\n `[Tasty] Empty container query '${stateKey}'.`,\n );\n return { type: 'modifier', condition: stateKey, raw };\n }\n\n // Check if named container (first token is name, followed by comma)\n // Use parentheses-aware comma search so inner commas (e.g., scroll-state(a, b)) are skipped\n const commaIndex = findTopLevelComma(content);\n let containerName: string | undefined;\n let condition: string;\n\n if (commaIndex !== -1) {\n // Named container: @(layout, w < 600px)\n containerName = content.slice(0, commaIndex).trim();\n condition = content.slice(commaIndex + 1).trim();\n } else {\n // Unnamed container: @(w < 600px)\n condition = content.trim();\n }\n\n // Check for style query shorthand (starts with $)\n if (condition.startsWith('$')) {\n // Style query: @(layout, $compact) or @(layout, $variant=compact)\n const styleCondition = parseStyleQuery(condition);\n if (!styleCondition) {\n warnOnce(\n `invalid-style-query:${stateKey}`,\n `[Tasty] Invalid style query '${condition}' in container query.`,\n );\n return { type: 'modifier', condition: stateKey, raw };\n }\n condition = styleCondition;\n } else if (/^[a-zA-Z][\\w-]*\\s*\\(/.test(condition)) {\n // Function-like syntax: scroll-state(...), style(...), etc.\n // Pass through verbatim — no dimension expansion needed\n } else {\n // Dimension query - expand shorthands and units\n condition = expandDimensionShorthands(condition);\n condition = expandTastyUnits(condition);\n }\n\n return {\n type: 'container',\n condition,\n containerName,\n raw,\n };\n }\n\n // Check for predefined state reference\n if (isPredefinedStateRef(stateKey)) {\n const resolved = resolvePredefinedState(stateKey, ctx);\n if (resolved) {\n // Recursively parse the resolved value to extract the actual state type\n // (e.g., @mobile -> @media(w < 768px) should become a media state)\n const parsedResolved = parseAdvancedState(resolved, ctx);\n return {\n ...parsedResolved,\n raw, // Keep original raw for traceability\n };\n }\n // If not resolved, treat as modifier (will likely produce invalid CSS)\n return {\n type: 'modifier',\n condition: stateKey,\n raw,\n };\n }\n\n // Regular modifier (boolean mod, pseudo-class, class, attribute)\n return {\n type: 'modifier',\n condition: stateKey,\n raw,\n };\n}\n\n/**\n * Parse a style query condition (e.g., $compact, $variant=compact, $variant=\"very compact\")\n */\nfunction parseStyleQuery(condition: string): string | null {\n // Remove $ prefix\n const query = condition.slice(1);\n\n // Check for comparison operators (not supported)\n if (/[<>]/.test(query)) {\n warnOnce(\n `style-query-comparison:${condition}`,\n `[Tasty] Style queries only support equality. '${condition}' is invalid. Use '${condition.split(/[<>]/)[0]}=...' instead.`,\n );\n return null;\n }\n\n // Check for equality\n const eqIndex = query.indexOf('=');\n if (eqIndex === -1) {\n // Just existence check: style(--compact)\n return `style(--${query})`;\n }\n\n const propName = query.slice(0, eqIndex).trim();\n let value = query.slice(eqIndex + 1).trim();\n\n // Handle quoted values\n if (\n (value.startsWith('\"') && value.endsWith('\"')) ||\n (value.startsWith(\"'\") && value.endsWith(\"'\"))\n ) {\n // Keep quotes for CSS\n } else {\n // Add quotes if needed\n value = `\"${value}\"`;\n }\n\n // Expand tasty units in value\n value = expandTastyUnits(value);\n\n return `style(--${propName}: ${value})`;\n}\n\n/**\n * Find the index of the first comma at parentheses depth 0.\n * Returns -1 if no top-level comma is found.\n * This prevents splitting on commas inside function calls like scroll-state(a, b).\n */\nexport function findTopLevelComma(s: string): number {\n let depth = 0;\n\n for (let i = 0; i < s.length; i++) {\n if (s[i] === '(') depth++;\n else if (s[i] === ')') depth--;\n else if (s[i] === ',' && depth === 0) return i;\n }\n\n return -1;\n}\n\nfunction findMatchingParen(str: string, startIndex: number): number {\n let depth = 1;\n let i = startIndex + 1;\n\n while (i < str.length && depth > 0) {\n if (str[i] === '(') depth++;\n else if (str[i] === ')') depth--;\n i++;\n }\n\n return depth === 0 ? i - 1 : -1;\n}\n\n/**\n * Check if a state key is an advanced state (starts with @)\n */\nexport function isAdvancedState(stateKey: string): boolean {\n return stateKey.startsWith('@') || stateKey.startsWith('!@');\n}\n","/**\n * ConditionNode Types and Helpers\n *\n * Core data structures for representing style conditions as an abstract syntax tree.\n * Used throughout the pipeline for parsing, simplification, and CSS generation.\n */\n\n// ============================================================================\n// Core ConditionNode Types\n// ============================================================================\n\n/**\n * Base interface for all state conditions (leaf nodes)\n */\ninterface BaseStateCondition {\n kind: 'state';\n negated: boolean;\n raw: string; // Original string for debugging/caching\n uniqueId: string; // Normalized ID for comparison (built from props)\n}\n\n/**\n * Modifier condition: [data-attr] or [data-attr=\"value\"]\n */\nexport interface ModifierCondition extends BaseStateCondition {\n type: 'modifier';\n attribute: string; // e.g., 'data-theme', 'data-size'\n value?: string; // e.g., 'danger', 'large' (undefined = boolean attr)\n operator?: '=' | '^=' | '$=' | '*='; // Attribute match operator\n}\n\n/**\n * Pseudo-class condition: :hover, :focus-visible\n */\nexport interface PseudoCondition extends BaseStateCondition {\n type: 'pseudo';\n pseudo: string; // e.g., ':hover', ':focus-visible', ':nth-child(2n)'\n}\n\n/**\n * Numeric bound for dimension queries\n */\nexport interface NumericBound {\n value: string; // e.g., '768px', 'calc(var(--gap) * 40)'\n valueNumeric: number | null; // Parsed numeric value for comparison\n inclusive: boolean; // true for >=/<= , false for >/<\n}\n\n/**\n * Media query condition\n */\nexport interface MediaCondition extends BaseStateCondition {\n type: 'media';\n subtype: 'dimension' | 'feature' | 'type';\n\n // For dimension queries: @media(w < 768px), @media(600px <= w < 1200px)\n dimension?: 'width' | 'height' | 'inline-size' | 'block-size';\n lowerBound?: NumericBound; // >= or >\n upperBound?: NumericBound; // <= or <\n\n // For feature queries: @media(prefers-contrast: high)\n feature?: string; // e.g., 'prefers-contrast', 'prefers-color-scheme'\n featureValue?: string; // e.g., 'high', 'dark' (undefined = boolean feature)\n\n // For type queries: @media:print\n mediaType?: 'print' | 'screen' | 'all' | 'speech';\n}\n\n/**\n * Container query condition\n */\nexport interface ContainerCondition extends BaseStateCondition {\n type: 'container';\n subtype: 'dimension' | 'style' | 'raw';\n containerName?: string; // e.g., 'layout', 'sidebar' (undefined = nearest)\n\n // For dimension queries: @(w < 600px), @(layout, w < 600px)\n dimension?: 'width' | 'height' | 'inline-size' | 'block-size';\n lowerBound?: NumericBound;\n upperBound?: NumericBound;\n\n // For style queries: @(layout, $variant=danger), @($theme)\n property?: string; // CSS custom property name (without --)\n propertyValue?: string; // e.g., 'danger' (undefined = existence check)\n\n // For raw function queries: @(scroll-state(stuck: top)), @(style(display: flex))\n rawCondition?: string; // Verbatim CSS condition string\n}\n\n/**\n * Root state condition: @root(theme=dark)\n */\nexport interface RootCondition extends BaseStateCondition {\n type: 'root';\n innerCondition: ConditionNode;\n}\n\n/**\n * Parent state condition: @parent(hovered), @parent(theme=dark, >)\n */\nexport interface ParentCondition extends BaseStateCondition {\n type: 'parent';\n innerCondition: ConditionNode;\n direct: boolean; // true for @parent(..., >) — direct parent only\n}\n\n/**\n * Own state condition: @own(hovered)\n */\nexport interface OwnCondition extends BaseStateCondition {\n type: 'own';\n innerCondition: ConditionNode; // The parsed inner condition\n}\n\n/**\n * Starting style condition: @starting\n */\nexport interface StartingCondition extends BaseStateCondition {\n type: 'starting';\n}\n\n/**\n * Supports query condition: @supports(display: grid), @supports($, :has(*))\n */\nexport interface SupportsCondition extends BaseStateCondition {\n type: 'supports';\n subtype: 'feature' | 'selector';\n // The raw condition string (e.g., \"display: grid\" or \":has(*)\")\n condition: string;\n}\n\n/**\n * Union of all state condition types\n */\nexport type StateCondition =\n | ModifierCondition\n | PseudoCondition\n | MediaCondition\n | ContainerCondition\n | RootCondition\n | ParentCondition\n | OwnCondition\n | StartingCondition\n | SupportsCondition;\n\n/**\n * Compound node: combines conditions with AND/OR\n */\nexport interface CompoundCondition {\n kind: 'compound';\n operator: 'AND' | 'OR';\n children: ConditionNode[];\n}\n\n/**\n * True condition (matches everything)\n */\nexport interface TrueCondition {\n kind: 'true';\n}\n\n/**\n * False condition (matches nothing - skip this rule)\n */\nexport interface FalseCondition {\n kind: 'false';\n}\n\n/**\n * Union of all condition node types\n */\nexport type ConditionNode =\n | StateCondition\n | CompoundCondition\n | TrueCondition\n | FalseCondition;\n\n// ============================================================================\n// Constructor Functions\n// ============================================================================\n\n/**\n * Create a TRUE condition (matches everything)\n */\nexport function trueCondition(): TrueCondition {\n return { kind: 'true' };\n}\n\n/**\n * Create a FALSE condition (matches nothing)\n */\nexport function falseCondition(): FalseCondition {\n return { kind: 'false' };\n}\n\n/**\n * Create an AND compound condition\n */\nexport function and(...children: ConditionNode[]): ConditionNode {\n const filtered: ConditionNode[] = [];\n\n for (const child of children) {\n // Short-circuit on FALSE\n if (child.kind === 'false') {\n return falseCondition();\n }\n // Skip TRUE (identity for AND)\n if (child.kind === 'true') {\n continue;\n }\n // Flatten nested ANDs\n if (child.kind === 'compound' && child.operator === 'AND') {\n filtered.push(...child.children);\n } else {\n filtered.push(child);\n }\n }\n\n if (filtered.length === 0) {\n return trueCondition();\n }\n if (filtered.length === 1) {\n return filtered[0];\n }\n\n return {\n kind: 'compound',\n operator: 'AND',\n children: filtered,\n };\n}\n\n/**\n * Create an OR compound condition\n */\nexport function or(...children: ConditionNode[]): ConditionNode {\n const filtered: ConditionNode[] = [];\n\n for (const child of children) {\n // Short-circuit on TRUE\n if (child.kind === 'true') {\n return trueCondition();\n }\n // Skip FALSE (identity for OR)\n if (child.kind === 'false') {\n continue;\n }\n // Flatten nested ORs\n if (child.kind === 'compound' && child.operator === 'OR') {\n filtered.push(...child.children);\n } else {\n filtered.push(child);\n }\n }\n\n if (filtered.length === 0) {\n return falseCondition();\n }\n if (filtered.length === 1) {\n return filtered[0];\n }\n\n return {\n kind: 'compound',\n operator: 'OR',\n children: filtered,\n };\n}\n\n/**\n * Negate a condition\n */\nexport function not(node: ConditionNode): ConditionNode {\n // NOT(TRUE) = FALSE\n if (node.kind === 'true') {\n return falseCondition();\n }\n\n // NOT(FALSE) = TRUE\n if (node.kind === 'false') {\n return trueCondition();\n }\n\n // NOT(state) = toggle negated flag\n if (node.kind === 'state') {\n return {\n ...node,\n negated: !node.negated,\n uniqueId: node.negated\n ? node.uniqueId.replace(/^!/, '')\n : `!${node.uniqueId}`,\n };\n }\n\n // NOT(AND(a, b, ...)) = OR(NOT(a), NOT(b), ...) - De Morgan's law\n if (node.kind === 'compound' && node.operator === 'AND') {\n return or(...node.children.map((c) => not(c)));\n }\n\n // NOT(OR(a, b, ...)) = AND(NOT(a), NOT(b), ...) - De Morgan's law\n if (node.kind === 'compound' && node.operator === 'OR') {\n return and(...node.children.map((c) => not(c)));\n }\n\n // Fallback - should not reach here\n return node;\n}\n\n// ============================================================================\n// Condition Type Checking\n// ============================================================================\n\n/**\n * Check if a condition is a compound condition\n */\nexport function isCompoundCondition(\n node: ConditionNode,\n): node is CompoundCondition {\n return node.kind === 'compound';\n}\n\n// ============================================================================\n// UniqueId Generation\n// ============================================================================\n\n/**\n * Generate a normalized unique ID for a modifier condition\n */\nfunction modifierUniqueId(\n attribute: string,\n value?: string,\n operator = '=',\n negated = false,\n): string {\n const base = value\n ? `mod:${attribute}${operator}${value}`\n : `mod:${attribute}`;\n return negated ? `!${base}` : base;\n}\n\n/**\n * Generate a normalized unique ID for a pseudo condition\n */\nfunction pseudoUniqueId(pseudo: string, negated = false): string {\n const base = `pseudo:${pseudo}`;\n return negated ? `!${base}` : base;\n}\n\n/**\n * Generate a normalized unique ID for a media condition\n */\nfunction mediaUniqueId(\n subtype: 'dimension' | 'feature' | 'type',\n props: {\n dimension?: string;\n lowerBound?: NumericBound;\n upperBound?: NumericBound;\n feature?: string;\n featureValue?: string;\n mediaType?: string;\n },\n negated = false,\n): string {\n let base: string;\n\n if (subtype === 'dimension') {\n const parts = ['media', 'dim', props.dimension];\n if (props.lowerBound) {\n parts.push(props.lowerBound.inclusive ? '>=' : '>');\n parts.push(props.lowerBound.value);\n }\n if (props.upperBound) {\n parts.push(props.upperBound.inclusive ? '<=' : '<');\n parts.push(props.upperBound.value);\n }\n base = parts.join(':');\n } else if (subtype === 'feature') {\n base = props.featureValue\n ? `media:feat:${props.feature}:${props.featureValue}`\n : `media:feat:${props.feature}`;\n } else {\n base = `media:type:${props.mediaType}`;\n }\n\n return negated ? `!${base}` : base;\n}\n\n/**\n * Generate a normalized unique ID for a container condition\n */\nfunction containerUniqueId(\n subtype: 'dimension' | 'style' | 'raw',\n props: {\n containerName?: string;\n dimension?: string;\n lowerBound?: NumericBound;\n upperBound?: NumericBound;\n property?: string;\n propertyValue?: string;\n rawCondition?: string;\n },\n negated = false,\n): string {\n let base: string;\n const name = props.containerName || '_';\n\n if (subtype === 'dimension') {\n const parts = ['container', 'dim', name, props.dimension];\n if (props.lowerBound) {\n parts.push(props.lowerBound.inclusive ? '>=' : '>');\n parts.push(props.lowerBound.value);\n }\n if (props.upperBound) {\n parts.push(props.upperBound.inclusive ? '<=' : '<');\n parts.push(props.upperBound.value);\n }\n base = parts.join(':');\n } else if (subtype === 'raw') {\n base = `container:raw:${name}:${props.rawCondition}`;\n } else {\n base = props.propertyValue\n ? `container:style:${name}:--${props.property}:${props.propertyValue}`\n : `container:style:${name}:--${props.property}`;\n }\n\n return negated ? `!${base}` : base;\n}\n\n/**\n * Generate a normalized unique ID for a root condition\n */\nfunction rootUniqueId(innerUniqueId: string, negated = false): string {\n const base = `root:${innerUniqueId}`;\n return negated ? `!${base}` : base;\n}\n\n/**\n * Generate a normalized unique ID for a parent condition\n */\nfunction parentUniqueId(\n innerUniqueId: string,\n direct: boolean,\n negated = false,\n): string {\n const base = `parent:${direct ? '>' : ''}${innerUniqueId}`;\n return negated ? `!${base}` : base;\n}\n\n/**\n * Generate a normalized unique ID for an own condition\n */\nfunction ownUniqueId(innerUniqueId: string, negated = false): string {\n const base = `own:${innerUniqueId}`;\n return negated ? `!${base}` : base;\n}\n\n/**\n * Generate a normalized unique ID for a starting condition\n */\nfunction startingUniqueId(negated = false): string {\n return negated ? '!starting' : 'starting';\n}\n\n/**\n * Generate a normalized unique ID for a supports condition\n */\nfunction supportsUniqueId(\n subtype: 'feature' | 'selector',\n condition: string,\n negated = false,\n): string {\n const base = `supports:${subtype}:${condition}`;\n return negated ? `!${base}` : base;\n}\n\n// ============================================================================\n// Condition Creation Helpers\n// ============================================================================\n\n/**\n * Create a modifier condition\n */\nexport function createModifierCondition(\n attribute: string,\n value?: string,\n operator: '=' | '^=' | '$=' | '*=' = '=',\n negated = false,\n raw?: string,\n): ModifierCondition {\n return {\n kind: 'state',\n type: 'modifier',\n negated,\n raw: raw || (value ? `${attribute}${operator}${value}` : attribute),\n uniqueId: modifierUniqueId(attribute, value, operator, negated),\n attribute,\n value,\n operator: value ? operator : undefined,\n };\n}\n\n/**\n * Create a pseudo condition\n */\nexport function createPseudoCondition(\n pseudo: string,\n negated = false,\n raw?: string,\n): PseudoCondition {\n return {\n kind: 'state',\n type: 'pseudo',\n negated,\n raw: raw || pseudo,\n uniqueId: pseudoUniqueId(pseudo, negated),\n pseudo,\n };\n}\n\n/**\n * Create a media dimension condition\n */\nexport function createMediaDimensionCondition(\n dimension: 'width' | 'height' | 'inline-size' | 'block-size',\n lowerBound?: NumericBound,\n upperBound?: NumericBound,\n negated = false,\n raw?: string,\n): MediaCondition {\n return {\n kind: 'state',\n type: 'media',\n subtype: 'dimension',\n negated,\n raw: raw || `@media(${dimension})`,\n uniqueId: mediaUniqueId(\n 'dimension',\n { dimension, lowerBound, upperBound },\n negated,\n ),\n dimension,\n lowerBound,\n upperBound,\n };\n}\n\n/**\n * Create a media feature condition\n */\nexport function createMediaFeatureCondition(\n feature: string,\n featureValue?: string,\n negated = false,\n raw?: string,\n): MediaCondition {\n return {\n kind: 'state',\n type: 'media',\n subtype: 'feature',\n negated,\n raw: raw || `@media(${feature}${featureValue ? `: ${featureValue}` : ''})`,\n uniqueId: mediaUniqueId('feature', { feature, featureValue }, negated),\n feature,\n featureValue,\n };\n}\n\n/**\n * Create a media type condition\n */\nexport function createMediaTypeCondition(\n mediaType: 'print' | 'screen' | 'all' | 'speech',\n negated = false,\n raw?: string,\n): MediaCondition {\n return {\n kind: 'state',\n type: 'media',\n subtype: 'type',\n negated,\n raw: raw || `@media:${mediaType}`,\n uniqueId: mediaUniqueId('type', { mediaType }, negated),\n mediaType,\n };\n}\n\n/**\n * Create a container dimension condition\n */\nexport function createContainerDimensionCondition(\n dimension: 'width' | 'height' | 'inline-size' | 'block-size',\n lowerBound?: NumericBound,\n upperBound?: NumericBound,\n containerName?: string,\n negated = false,\n raw?: string,\n): ContainerCondition {\n return {\n kind: 'state',\n type: 'container',\n subtype: 'dimension',\n negated,\n raw: raw || `@(${containerName ? containerName + ', ' : ''}${dimension})`,\n uniqueId: containerUniqueId(\n 'dimension',\n { containerName, dimension, lowerBound, upperBound },\n negated,\n ),\n containerName,\n dimension,\n lowerBound,\n upperBound,\n };\n}\n\n/**\n * Create a container style condition\n */\nexport function createContainerStyleCondition(\n property: string,\n propertyValue?: string,\n containerName?: string,\n negated = false,\n raw?: string,\n): ContainerCondition {\n return {\n kind: 'state',\n type: 'container',\n subtype: 'style',\n negated,\n raw:\n raw ||\n `@(${containerName ? containerName + ', ' : ''}$${property}${propertyValue ? '=' + propertyValue : ''})`,\n uniqueId: containerUniqueId(\n 'style',\n { containerName, property, propertyValue },\n negated,\n ),\n containerName,\n property,\n propertyValue,\n };\n}\n\n/**\n * Create a container raw function condition (e.g., scroll-state(), style(), etc.)\n * The condition string is passed through to CSS verbatim.\n */\nexport function createContainerRawCondition(\n rawCondition: string,\n containerName?: string,\n negated = false,\n raw?: string,\n): ContainerCondition {\n return {\n kind: 'state',\n type: 'container',\n subtype: 'raw',\n negated,\n raw:\n raw || `@(${containerName ? containerName + ', ' : ''}${rawCondition})`,\n uniqueId: containerUniqueId(\n 'raw',\n { containerName, rawCondition },\n negated,\n ),\n containerName,\n rawCondition,\n };\n}\n\n/**\n * Create a root condition\n */\nexport function createRootCondition(\n innerCondition: ConditionNode,\n negated = false,\n raw?: string,\n): RootCondition {\n const innerUniqueId = getConditionUniqueId(innerCondition);\n return {\n kind: 'state',\n type: 'root',\n negated,\n raw: raw || `@root(${innerUniqueId})`,\n uniqueId: rootUniqueId(innerUniqueId, negated),\n innerCondition,\n };\n}\n\n/**\n * Create a parent condition\n */\nexport function createParentCondition(\n innerCondition: ConditionNode,\n direct: boolean,\n negated = false,\n raw?: string,\n): ParentCondition {\n const innerUniqueId = getConditionUniqueId(innerCondition);\n return {\n kind: 'state',\n type: 'parent',\n negated,\n raw: raw || `@parent(${innerUniqueId})`,\n uniqueId: parentUniqueId(innerUniqueId, direct, negated),\n innerCondition,\n direct,\n };\n}\n\n/**\n * Create an own condition\n */\nexport function createOwnCondition(\n innerCondition: ConditionNode,\n negated = false,\n raw?: string,\n): OwnCondition {\n const innerUniqueId = getConditionUniqueId(innerCondition);\n return {\n kind: 'state',\n type: 'own',\n negated,\n raw: raw || `@own(...)`,\n uniqueId: ownUniqueId(innerUniqueId, negated),\n innerCondition,\n };\n}\n\n/**\n * Create a starting condition\n */\nexport function createStartingCondition(\n negated = false,\n raw?: string,\n): StartingCondition {\n return {\n kind: 'state',\n type: 'starting',\n negated,\n raw: raw || '@starting',\n uniqueId: startingUniqueId(negated),\n };\n}\n\n/**\n * Create a supports condition\n *\n * @param subtype 'feature' for @supports(display: grid), 'selector' for @supports($, :has(*))\n * @param condition The condition string (e.g., \"display: grid\" or \":has(*)\")\n */\nexport function createSupportsCondition(\n subtype: 'feature' | 'selector',\n condition: string,\n negated = false,\n raw?: string,\n): SupportsCondition {\n return {\n kind: 'state',\n type: 'supports',\n subtype,\n negated,\n raw: raw || `@supports(${condition})`,\n uniqueId: supportsUniqueId(subtype, condition, negated),\n condition,\n };\n}\n\n// ============================================================================\n// Utility Functions\n// ============================================================================\n\nconst uniqueIdCache = new WeakMap<ConditionNode, string>();\n\n/**\n * Get the unique ID for any condition node.\n * Results are memoized via WeakMap since condition nodes are immutable.\n */\nexport function getConditionUniqueId(node: ConditionNode): string {\n const cached = uniqueIdCache.get(node);\n if (cached !== undefined) return cached;\n\n let id: string;\n if (node.kind === 'true') {\n id = 'TRUE';\n } else if (node.kind === 'false') {\n id = 'FALSE';\n } else if (node.kind === 'state') {\n id = node.uniqueId;\n } else if (node.kind === 'compound') {\n const childIds = node.children.map(getConditionUniqueId).sort();\n id = `${node.operator}(${childIds.join(',')})`;\n } else {\n id = 'UNKNOWN';\n }\n\n uniqueIdCache.set(node, id);\n return id;\n}\n","/**\n * Condition Simplification Engine\n *\n * Simplifies condition trees by applying boolean algebra rules,\n * detecting contradictions, merging ranges, and deduplicating terms.\n *\n * This is critical for:\n * 1. Detecting invalid combinations (A & !A → FALSE)\n * 2. Reducing CSS output size\n * 3. Producing cleaner selectors\n */\n\nimport { Lru } from '../parser/lru';\n\nimport type {\n ConditionNode,\n ContainerCondition,\n MediaCondition,\n ModifierCondition,\n NumericBound,\n OwnCondition,\n RootCondition,\n} from './conditions';\nimport {\n and,\n createOwnCondition,\n createParentCondition,\n createRootCondition,\n falseCondition,\n getConditionUniqueId,\n not,\n or,\n trueCondition,\n} from './conditions';\n\n// ============================================================================\n// Caching\n// ============================================================================\n\nconst simplifyCache = new Lru<string, ConditionNode>(5000);\n\n// ============================================================================\n// Main Simplify Function\n// ============================================================================\n\n/**\n * Simplify a condition tree aggressively.\n *\n * This applies all possible simplification rules:\n * - Boolean algebra (identity, annihilator, idempotent, absorption)\n * - Contradiction detection (A & !A → FALSE)\n * - Tautology detection (A | !A → TRUE)\n * - Range intersection for numeric queries\n * - Attribute value conflict detection\n * - Deduplication and sorting\n */\nexport function simplifyCondition(node: ConditionNode): ConditionNode {\n // Check cache\n const key = getConditionUniqueId(node);\n const cached = simplifyCache.get(key);\n if (cached) {\n return cached;\n }\n\n const result = simplifyInner(node);\n\n // Cache result\n simplifyCache.set(key, result);\n\n return result;\n}\n\n/**\n * Clear the simplify cache (for testing)\n */\nexport function clearSimplifyCache(): void {\n simplifyCache.clear();\n}\n\n// ============================================================================\n// Inner Simplification\n// ============================================================================\n\nfunction simplifyInner(node: ConditionNode): ConditionNode {\n // Base cases\n if (node.kind === 'true' || node.kind === 'false') {\n return node;\n }\n\n // State conditions: most are leaves, but @root / @own / @parent wrap a\n // nested condition that benefits from the same simplification (e.g.\n // `@root(schema=dark & schema=light)` → inner is FALSE → wrapper is FALSE).\n // Only descend on non-negated wrappers; negated wrappers would need\n // additional reasoning (`!@root(FALSE)` = TRUE) that isn't worth the\n // surface area for the current bug.\n if (node.kind === 'state') {\n if (\n (node.type === 'root' || node.type === 'own' || node.type === 'parent') &&\n !node.negated\n ) {\n const simplifiedInner = simplifyInner(node.innerCondition);\n if (simplifiedInner.kind === 'false') return falseCondition();\n if (simplifiedInner === node.innerCondition) return node;\n if (node.type === 'root') {\n return createRootCondition(simplifiedInner, false, node.raw);\n }\n if (node.type === 'own') {\n return createOwnCondition(simplifiedInner, false, node.raw);\n }\n return createParentCondition(\n simplifiedInner,\n node.direct,\n false,\n node.raw,\n );\n }\n return node;\n }\n\n // Compound conditions - recursively simplify.\n // Memoize compound results: the cross-level pruning pass\n // (`pruneContradictedOrBranches`) re-simplifies many overlapping\n // `AND(branch, ...siblings)` combinations, so caching by structural id\n // turns repeated work into O(1) lookups and tames otherwise exponential\n // blowup on wide exclusive conditions (large state maps).\n if (node.kind === 'compound') {\n const key = getConditionUniqueId(node);\n const cached = simplifyCache.get(key);\n if (cached) {\n return cached;\n }\n\n // First, recursively simplify all children\n const simplifiedChildren = node.children.map((c) => simplifyInner(c));\n\n // Then apply compound-specific simplifications\n const result =\n node.operator === 'AND'\n ? simplifyAnd(simplifiedChildren)\n : simplifyOr(simplifiedChildren);\n\n simplifyCache.set(key, result);\n return result;\n }\n\n return node;\n}\n\n// ============================================================================\n// AND Simplification\n// ============================================================================\n\nfunction simplifyAnd(children: ConditionNode[]): ConditionNode {\n let terms: ConditionNode[] = [];\n\n // ─── Pass 1: flatten + identity/annihilator ────────────────────────────\n // Flatten nested ANDs, drop TRUE children, short-circuit on any FALSE.\n for (const child of children) {\n if (child.kind === 'false') {\n // AND with FALSE → FALSE\n return falseCondition();\n }\n if (child.kind === 'true') {\n // AND with TRUE → skip (identity)\n continue;\n }\n if (child.kind === 'compound' && child.operator === 'AND') {\n // Flatten nested AND\n terms.push(...child.children);\n } else {\n terms.push(child);\n }\n }\n\n // Empty → TRUE\n if (terms.length === 0) {\n return trueCondition();\n }\n\n // Single term → return it\n if (terms.length === 1) {\n return terms[0];\n }\n\n // ─── Pass 2: filter contradictions ─────────────────────────────────────\n // Any of these indicates the conjunction can never be satisfied.\n\n // Check for contradictions\n if (hasContradiction(terms)) {\n return falseCondition();\n }\n\n // Check for range contradictions in media/container queries\n if (hasRangeContradiction(terms)) {\n return falseCondition();\n }\n\n // Check for attribute value conflicts\n if (hasAttributeConflict(terms)) {\n return falseCondition();\n }\n\n // Check for container style query conflicts\n if (hasContainerStyleConflict(terms)) {\n return falseCondition();\n }\n\n // ─── Passes 3-5: redundancy elimination + boolean reductions ───────────\n // Run to a fixpoint: Pass 5 (`pruneContradictedOrBranches`) can collapse\n // single-branch ORs into flat AND siblings, which then expose fresh\n // implied negations for Pass 3 (`removeImpliedNegations`) and absorption\n // targets for Pass 4. Without re-running, an exclusive condition like\n // `[theme=gray] & OR(!proc, !theme=rose)` keeps a redundant\n // `:not([theme=rose])` term even though `[theme=gray]` already implies it.\n const MAX_SIMPLIFY_PASSES = 4;\n for (let pass = 0; pass < MAX_SIMPLIFY_PASSES; pass++) {\n const lengthBefore = terms.length;\n const keyBefore = simplifyTermsKey(terms);\n\n // Pass 3: redundancy elimination + canonicalization\n // Remove redundant negations implied by positive terms\n // e.g., style(--variant: danger) implies NOT style(--variant: success)\n // and style(--variant: danger) implies style(--variant) (existence)\n terms = removeImpliedNegations(terms);\n terms = deduplicateTerms(terms);\n terms = mergeRanges(terms);\n terms = sortTerms(terms);\n\n // Pass 4: boolean-algebra reductions\n terms = applyAbsorptionAnd(terms); // A & (A | B) → A\n terms = applyConsensusAnd(terms); // (A | B) & (A | !B) → A\n\n // Pass 5: cross-level contradiction pruning\n // A & OR(!A & X, Y) → A & Y\n // For each OR child, prune branches that are impossible given the other\n // AND siblings. This catches dead branches left by exclusive negation.\n terms = pruneContradictedOrBranches(terms);\n\n // Re-check contradictions exposed by pruning before continuing.\n if (terms.length === 0) break;\n if (terms.length === 1) break;\n if (hasContradiction(terms)) {\n return falseCondition();\n }\n if (hasAttributeConflict(terms)) {\n return falseCondition();\n }\n\n // Stop once a full pass made no structural change.\n if (\n terms.length === lengthBefore &&\n simplifyTermsKey(terms) === keyBefore\n ) {\n break;\n }\n }\n\n if (terms.length === 0) {\n return trueCondition();\n }\n if (terms.length === 1) {\n return terms[0];\n }\n\n return {\n kind: 'compound',\n operator: 'AND',\n children: terms,\n };\n}\n\n// ============================================================================\n// OR Simplification\n// ============================================================================\n\nfunction simplifyOr(children: ConditionNode[]): ConditionNode {\n let terms: ConditionNode[] = [];\n\n // ─── Pass 1: flatten + identity/annihilator ────────────────────────────\n // Flatten nested ORs, drop FALSE children, short-circuit on any TRUE.\n for (const child of children) {\n if (child.kind === 'true') {\n // OR with TRUE → TRUE\n return trueCondition();\n }\n if (child.kind === 'false') {\n // OR with FALSE → skip (identity)\n continue;\n }\n if (child.kind === 'compound' && child.operator === 'OR') {\n // Flatten nested OR\n terms.push(...child.children);\n } else {\n terms.push(child);\n }\n }\n\n // Empty → FALSE\n if (terms.length === 0) {\n return falseCondition();\n }\n\n // Single term → return it\n if (terms.length === 1) {\n return terms[0];\n }\n\n // ─── Pass 2: filter tautologies ────────────────────────────────────────\n // A | !A means the disjunction is always satisfied.\n if (hasTautology(terms)) {\n return trueCondition();\n }\n\n // ─── Pass 3: redundancy elimination + canonicalization ─────────────────\n\n // Deduplicate\n terms = deduplicateTerms(terms);\n\n // Sort for canonical form\n terms = sortTerms(terms);\n\n // ─── Pass 4: boolean-algebra reductions ────────────────────────────────\n\n // Apply absorption: A | (A & B) → A\n terms = applyAbsorptionOr(terms);\n\n // Apply complementary factoring: (A & B) | (A & !B) → A\n terms = applyComplementaryFactoring(terms);\n\n if (terms.length === 0) {\n return falseCondition();\n }\n if (terms.length === 1) {\n return terms[0];\n }\n\n return {\n kind: 'compound',\n operator: 'OR',\n children: terms,\n };\n}\n\n// ============================================================================\n// Contradiction Detection\n// ============================================================================\n\n/**\n * Check if any pair of terms has complementary negation (A and !A).\n * Used for both contradiction detection (in AND) and tautology detection (in OR),\n * since the underlying check is identical: the context determines the semantics.\n */\nfunction hasComplementaryPair(terms: ConditionNode[]): boolean {\n const uniqueIds = new Set<string>();\n\n for (const term of terms) {\n if (term.kind !== 'state') continue;\n\n const id = term.uniqueId;\n const negatedId = term.negated ? id.slice(1) : `!${id}`;\n\n if (uniqueIds.has(negatedId)) {\n return true;\n }\n uniqueIds.add(id);\n }\n\n return false;\n}\n\nconst hasContradiction = hasComplementaryPair;\nconst hasTautology = hasComplementaryPair;\n\n// ============================================================================\n// Range Contradiction Detection\n// ============================================================================\n\n/**\n * Effective bounds computed from conditions (including negated single-bound conditions)\n */\ninterface EffectiveBounds {\n lowerBound: number | null;\n lowerInclusive: boolean;\n upperBound: number | null;\n upperInclusive: boolean;\n}\n\n/**\n * Excluded range from a negated range condition\n */\ninterface ExcludedRange {\n lower: number;\n lowerInclusive: boolean;\n upper: number;\n upperInclusive: boolean;\n}\n\n/**\n * Check for range contradictions in media/container queries\n * e.g., @media(w < 400px) & @media(w > 800px) → FALSE\n *\n * Also handles negated conditions:\n * - Single-bound negations are inverted (not (w < 600px) → w >= 600px)\n * - Range negations create excluded ranges that are checked against positive bounds\n */\nfunction hasRangeContradiction(terms: ConditionNode[]): boolean {\n // Group by dimension, separating positive and negated conditions\n const mediaByDim = new Map<\n string,\n { positive: MediaCondition[]; negated: MediaCondition[] }\n >();\n const containerByDim = new Map<\n string,\n { positive: ContainerCondition[]; negated: ContainerCondition[] }\n >();\n\n for (const term of terms) {\n if (term.kind !== 'state') continue;\n\n if (term.type === 'media' && term.subtype === 'dimension') {\n const key = term.dimension || 'width';\n if (!mediaByDim.has(key)) {\n mediaByDim.set(key, { positive: [], negated: [] });\n }\n const group = mediaByDim.get(key)!;\n if (term.negated) {\n group.negated.push(term);\n } else {\n group.positive.push(term);\n }\n }\n\n if (term.type === 'container' && term.subtype === 'dimension') {\n const key = `${term.containerName || '_'}:${term.dimension || 'width'}`;\n if (!containerByDim.has(key)) {\n containerByDim.set(key, { positive: [], negated: [] });\n }\n const group = containerByDim.get(key)!;\n if (term.negated) {\n group.negated.push(term);\n } else {\n group.positive.push(term);\n }\n }\n }\n\n // Check each dimension group for impossible ranges\n for (const group of mediaByDim.values()) {\n if (rangesAreImpossibleWithNegations(group.positive, group.negated)) {\n return true;\n }\n }\n\n for (const group of containerByDim.values()) {\n if (rangesAreImpossibleWithNegations(group.positive, group.negated)) {\n return true;\n }\n }\n\n return false;\n}\n\n/**\n * Check if conditions are impossible, including negated conditions.\n *\n * For negated single-bound conditions:\n * not (w < 600px) → w >= 600px (inverted to lower bound)\n * not (w >= 800px) → w < 800px (inverted to upper bound)\n *\n * For negated range conditions:\n * not (400px <= w < 800px) → excludes [400, 800)\n * If the effective bounds fall entirely within an excluded range, it's impossible.\n */\nfunction rangesAreImpossibleWithNegations(\n positive: (MediaCondition | ContainerCondition)[],\n negated: (MediaCondition | ContainerCondition)[],\n): boolean {\n // Start with bounds from positive conditions\n const bounds = computeEffectiveBounds(positive);\n\n // Apply inverted bounds from single-bound negated conditions\n // and collect excluded ranges from range negated conditions\n const excludedRanges: ExcludedRange[] = [];\n\n for (const cond of negated) {\n const hasLower = cond.lowerBound?.valueNumeric != null;\n const hasUpper = cond.upperBound?.valueNumeric != null;\n\n if (hasLower && hasUpper) {\n // Range negation: not (lower <= w < upper) excludes [lower, upper)\n excludedRanges.push({\n lower: cond.lowerBound!.valueNumeric!,\n lowerInclusive: cond.lowerBound!.inclusive,\n upper: cond.upperBound!.valueNumeric!,\n upperInclusive: cond.upperBound!.inclusive,\n });\n } else if (hasUpper) {\n // not (w < upper) → w >= upper (becomes lower bound)\n // not (w <= upper) → w > upper (becomes lower bound, exclusive)\n const value = cond.upperBound!.valueNumeric!;\n const inclusive = !cond.upperBound!.inclusive; // flip inclusivity\n\n if (bounds.lowerBound === null || value > bounds.lowerBound) {\n bounds.lowerBound = value;\n bounds.lowerInclusive = inclusive;\n } else if (value === bounds.lowerBound && !inclusive) {\n bounds.lowerInclusive = false;\n }\n } else if (hasLower) {\n // not (w >= lower) → w < lower (becomes upper bound)\n // not (w > lower) → w <= lower (becomes upper bound, inclusive)\n const value = cond.lowerBound!.valueNumeric!;\n const inclusive = !cond.lowerBound!.inclusive; // flip inclusivity\n\n if (bounds.upperBound === null || value < bounds.upperBound) {\n bounds.upperBound = value;\n bounds.upperInclusive = inclusive;\n } else if (value === bounds.upperBound && !inclusive) {\n bounds.upperInclusive = false;\n }\n }\n }\n\n // Check if effective bounds are impossible on their own\n if (bounds.lowerBound !== null && bounds.upperBound !== null) {\n if (bounds.lowerBound > bounds.upperBound) {\n return true;\n }\n if (\n bounds.lowerBound === bounds.upperBound &&\n (!bounds.lowerInclusive || !bounds.upperInclusive)\n ) {\n return true;\n }\n }\n\n // Check if effective bounds fall entirely within any excluded range\n if (\n bounds.lowerBound !== null &&\n bounds.upperBound !== null &&\n excludedRanges.length > 0\n ) {\n for (const excluded of excludedRanges) {\n if (boundsWithinExcludedRange(bounds, excluded)) {\n return true;\n }\n }\n }\n\n return false;\n}\n\n/**\n * Compute effective bounds from positive (non-negated) conditions\n */\nfunction computeEffectiveBounds(\n conditions: (MediaCondition | ContainerCondition)[],\n): EffectiveBounds {\n let lowerBound: number | null = null;\n let lowerInclusive = false;\n let upperBound: number | null = null;\n let upperInclusive = false;\n\n for (const cond of conditions) {\n if (cond.lowerBound?.valueNumeric != null) {\n const value = cond.lowerBound.valueNumeric;\n const inclusive = cond.lowerBound.inclusive;\n\n if (lowerBound === null || value > lowerBound) {\n lowerBound = value;\n lowerInclusive = inclusive;\n } else if (value === lowerBound && !inclusive) {\n lowerInclusive = false;\n }\n }\n\n if (cond.upperBound?.valueNumeric != null) {\n const value = cond.upperBound.valueNumeric;\n const inclusive = cond.upperBound.inclusive;\n\n if (upperBound === null || value < upperBound) {\n upperBound = value;\n upperInclusive = inclusive;\n } else if (value === upperBound && !inclusive) {\n upperInclusive = false;\n }\n }\n }\n\n return { lowerBound, lowerInclusive, upperBound, upperInclusive };\n}\n\n/**\n * Check if effective bounds fall entirely within an excluded range.\n *\n * For example:\n * Effective: [400, 800)\n * Excluded: [400, 800)\n * → bounds fall entirely within excluded range → impossible\n */\nfunction boundsWithinExcludedRange(\n bounds: EffectiveBounds,\n excluded: ExcludedRange,\n): boolean {\n if (bounds.lowerBound === null || bounds.upperBound === null) {\n return false;\n }\n\n // Check if bounds.lower >= excluded.lower\n let lowerOk = false;\n if (bounds.lowerBound > excluded.lower) {\n lowerOk = true;\n } else if (bounds.lowerBound === excluded.lower) {\n // If excluded includes lower, and bounds includes or excludes lower, it's within\n // If excluded excludes lower, bounds must also exclude it to be within\n lowerOk = excluded.lowerInclusive || !bounds.lowerInclusive;\n }\n\n // Check if bounds.upper <= excluded.upper\n let upperOk = false;\n if (bounds.upperBound < excluded.upper) {\n upperOk = true;\n } else if (bounds.upperBound === excluded.upper) {\n // If excluded includes upper, and bounds includes or excludes upper, it's within\n // If excluded excludes upper, bounds must also exclude it to be within\n upperOk = excluded.upperInclusive || !bounds.upperInclusive;\n }\n\n return lowerOk && upperOk;\n}\n\n// ============================================================================\n// Attribute Conflict Detection\n// ============================================================================\n\n/**\n * Check for attribute value conflicts\n * e.g., [data-theme=\"dark\"] & [data-theme=\"light\"] → FALSE\n * e.g., [data-theme=\"dark\"] & ![data-theme] → FALSE\n */\n/**\n * Generic value-conflict checker for grouped conditions.\n *\n * Groups terms by a key, splits into positive/negated, then checks:\n * 1. Multiple distinct positive values → conflict\n * 2. Positive value + negated existence (value === undefined) → conflict\n * 3. Positive value + negated same value → conflict\n */\nfunction hasGroupedValueConflict<T extends { negated: boolean }>(\n terms: ConditionNode[],\n match: (term: ConditionNode) => T | null,\n groupKey: (term: T) => string,\n getValue: (term: T) => string | undefined,\n): boolean {\n const groups = new Map<string, { positive: T[]; negated: T[] }>();\n\n for (const term of terms) {\n const matched = match(term);\n if (!matched) continue;\n\n const key = groupKey(matched);\n let group = groups.get(key);\n if (!group) {\n group = { positive: [], negated: [] };\n groups.set(key, group);\n }\n\n if (matched.negated) {\n group.negated.push(matched);\n } else {\n group.positive.push(matched);\n }\n }\n\n for (const [, group] of groups) {\n const positiveValues = group.positive\n .map(getValue)\n .filter((v) => v !== undefined);\n if (new Set(positiveValues).size > 1) return true;\n\n const hasPositiveValue = positiveValues.length > 0;\n const hasNegatedExistence = group.negated.some(\n (t) => getValue(t) === undefined,\n );\n if (hasPositiveValue && hasNegatedExistence) return true;\n\n for (const pos of group.positive) {\n const posVal = getValue(pos);\n if (posVal !== undefined) {\n for (const neg of group.negated) {\n if (getValue(neg) === posVal) return true;\n }\n }\n }\n }\n\n return false;\n}\n\nfunction hasAttributeConflict(terms: ConditionNode[]): boolean {\n // Top-level modifiers: `schema=dark & schema=light`.\n if (\n hasGroupedValueConflict<ModifierCondition>(\n terms,\n (t) => (t.kind === 'state' && t.type === 'modifier' ? t : null),\n (t) => t.attribute,\n (t) => t.value,\n )\n ) {\n return true;\n }\n\n // @root scope (single :root element):\n // `@root(schema=dark) & @root(schema=light)` cannot match anything because\n // there is only one document root.\n if (hasNestedModifierConflict(terms, 'root')) return true;\n\n // @own scope (single sub-element / styled element under `&`):\n // `@own(schema=dark) & @own(schema=light)` is impossible for the same\n // reason — both refer to the same element.\n if (hasNestedModifierConflict(terms, 'own')) return true;\n\n // NOTE: @parent is intentionally NOT checked. Different ancestor elements\n // can hold different attribute values, so two `@parent(schema=...)` calls\n // can both match (different ancestors), even when the values differ.\n\n return false;\n}\n\n/**\n * Collect modifier conditions inside non-negated state wrappers of `kind`\n * and check for the same value-conflict pattern as the top-level pass.\n *\n * Modifiers from multiple sibling wrappers are combined — both wrappers\n * scope to the same element (one :root, one own scope), so an attribute\n * conflict across wrappers is still impossible.\n */\nfunction hasNestedModifierConflict(\n terms: ConditionNode[],\n wrapperType: 'root' | 'own',\n): boolean {\n const innerTerms: ConditionNode[] = [];\n for (const term of terms) {\n if (term.kind === 'state' && term.type === wrapperType && !term.negated) {\n flattenAndIntoArray(\n (term as RootCondition | OwnCondition).innerCondition,\n innerTerms,\n );\n }\n }\n if (innerTerms.length < 2) return false;\n return hasGroupedValueConflict<ModifierCondition>(\n innerTerms,\n (t) => (t.kind === 'state' && t.type === 'modifier' ? t : null),\n (t) => t.attribute,\n (t) => t.value,\n );\n}\n\n/**\n * Flatten a top-level AND tree into a flat list of conjuncts. Non-AND nodes\n * are pushed as-is.\n */\nfunction flattenAndIntoArray(node: ConditionNode, into: ConditionNode[]): void {\n if (node.kind === 'compound' && node.operator === 'AND') {\n for (const child of node.children) flattenAndIntoArray(child, into);\n } else {\n into.push(node);\n }\n}\n\nfunction hasContainerStyleConflict(terms: ConditionNode[]): boolean {\n return hasGroupedValueConflict<ContainerCondition>(\n terms,\n (t) =>\n t.kind === 'state' && t.type === 'container' && t.subtype === 'style'\n ? t\n : null,\n (t) => `${t.containerName || '_'}:${t.property}`,\n (t) => t.propertyValue,\n );\n}\n\n// ============================================================================\n// Implied Negation Removal\n// ============================================================================\n\n/**\n * Remove negations that are implied by positive terms.\n *\n * Key optimizations:\n * 1. style(--variant: danger) implies NOT style(--variant: success)\n * → If we have style(--variant: danger) & not style(--variant: success),\n * the negation is redundant and can be removed.\n *\n * 2. [data-theme=\"dark\"] implies NOT [data-theme=\"light\"]\n * → Same logic for attribute selectors.\n *\n * This produces cleaner CSS:\n * Before: @container style(--variant: danger) and (not style(--variant: success))\n * After: @container style(--variant: danger)\n */\n/**\n * Collect positive values from terms and build a \"is this negation implied?\" check.\n *\n * A negation is implied (redundant) when a positive term for the same group\n * already pins a specific value, making \"NOT other-value\" obvious.\n * e.g. style(--variant: danger) implies NOT style(--variant: success).\n */\nfunction buildImpliedNegationCheck(\n terms: ConditionNode[],\n): (term: ConditionNode) => boolean {\n const positiveValues = new Map<string, string>();\n const negatedBooleanAttrs = new Set<string>();\n\n for (const term of terms) {\n if (term.kind !== 'state') continue;\n\n if (!term.negated) {\n if (term.type === 'container' && term.subtype === 'style') {\n if (term.propertyValue !== undefined) {\n positiveValues.set(\n `c:${term.containerName || '_'}:${term.property}`,\n term.propertyValue,\n );\n }\n } else if (term.type === 'modifier' && term.value !== undefined) {\n positiveValues.set(`m:${term.attribute}`, term.value);\n }\n } else {\n // NOT [data-attr] (boolean negation) implies NOT [data-attr=\"val\"]\n if (term.type === 'modifier' && term.value === undefined) {\n negatedBooleanAttrs.add(term.attribute);\n }\n }\n }\n\n return (term: ConditionNode): boolean => {\n if (term.kind !== 'state' || !term.negated) return false;\n\n if (term.type === 'container' && term.subtype === 'style') {\n if (term.propertyValue === undefined) return false;\n const pos = positiveValues.get(\n `c:${term.containerName || '_'}:${term.property}`,\n );\n return pos !== undefined && term.propertyValue !== pos;\n }\n\n if (term.type === 'modifier' && term.value !== undefined) {\n // :not([data-attr]) already present → :not([data-attr=\"val\"]) is redundant\n if (negatedBooleanAttrs.has(term.attribute)) return true;\n const pos = positiveValues.get(`m:${term.attribute}`);\n return pos !== undefined && term.value !== pos;\n }\n\n return false;\n };\n}\n\nfunction removeImpliedNegations(terms: ConditionNode[]): ConditionNode[] {\n const isImplied = buildImpliedNegationCheck(terms);\n return terms.filter((t) => !isImplied(t));\n}\n\n// ============================================================================\n// Deduplication\n// ============================================================================\n\n/**\n * Build a stable, order-insensitive key for a list of AND terms.\n * Used to detect fixpoint convergence in `simplifyAnd`.\n */\nfunction simplifyTermsKey(terms: ConditionNode[]): string {\n return terms\n .map((t) => getConditionUniqueId(t))\n .sort()\n .join('&');\n}\n\nfunction deduplicateTerms(terms: ConditionNode[]): ConditionNode[] {\n const seen = new Set<string>();\n const result: ConditionNode[] = [];\n\n for (const term of terms) {\n const id = getConditionUniqueId(term);\n if (!seen.has(id)) {\n seen.add(id);\n result.push(term);\n }\n }\n\n return result;\n}\n\n// ============================================================================\n// Range Merging\n// ============================================================================\n\n/**\n * Merge compatible range conditions\n * e.g., @media(w >= 400px) & @media(w <= 800px) → @media(400px <= w <= 800px)\n */\nfunction mergeRanges(terms: ConditionNode[]): ConditionNode[] {\n // Group media conditions by dimension\n const mediaByDim = new Map<\n string,\n { conditions: MediaCondition[]; indices: number[] }\n >();\n const containerByDim = new Map<\n string,\n { conditions: ContainerCondition[]; indices: number[] }\n >();\n\n terms.forEach((term, index) => {\n if (term.kind !== 'state') return;\n\n if (\n term.type === 'media' &&\n term.subtype === 'dimension' &&\n !term.negated\n ) {\n const key = term.dimension || 'width';\n if (!mediaByDim.has(key)) {\n mediaByDim.set(key, { conditions: [], indices: [] });\n }\n const group = mediaByDim.get(key)!;\n group.conditions.push(term);\n group.indices.push(index);\n }\n\n if (\n term.type === 'container' &&\n term.subtype === 'dimension' &&\n !term.negated\n ) {\n const key = `${term.containerName || '_'}:${term.dimension || 'width'}`;\n if (!containerByDim.has(key)) {\n containerByDim.set(key, { conditions: [], indices: [] });\n }\n const group = containerByDim.get(key)!;\n group.conditions.push(term);\n group.indices.push(index);\n }\n });\n\n // Track indices to remove\n const indicesToRemove = new Set<number>();\n const mergedTerms: ConditionNode[] = [];\n\n // Merge media conditions\n for (const [_dim, group] of mediaByDim) {\n if (group.conditions.length > 1) {\n const merged = mergeMediaRanges(group.conditions);\n if (merged) {\n group.indices.forEach((i) => indicesToRemove.add(i));\n mergedTerms.push(merged);\n }\n }\n }\n\n // Merge container conditions\n for (const [, group] of containerByDim) {\n if (group.conditions.length > 1) {\n const merged = mergeContainerRanges(group.conditions);\n if (merged) {\n group.indices.forEach((i) => indicesToRemove.add(i));\n mergedTerms.push(merged);\n }\n }\n }\n\n // Build result\n const result: ConditionNode[] = [];\n terms.forEach((term, index) => {\n if (!indicesToRemove.has(index)) {\n result.push(term);\n }\n });\n result.push(...mergedTerms);\n\n return result;\n}\n\n/**\n * Tighten bounds by picking the most restrictive lower and upper bounds\n * from a set of conditions that have lowerBound/upperBound fields.\n */\nfunction tightenBounds(\n conditions: { lowerBound?: NumericBound; upperBound?: NumericBound }[],\n): { lowerBound?: NumericBound; upperBound?: NumericBound } {\n let lowerBound: NumericBound | undefined;\n let upperBound: NumericBound | undefined;\n\n for (const cond of conditions) {\n if (cond.lowerBound) {\n if (\n !lowerBound ||\n (cond.lowerBound.valueNumeric ?? -Infinity) >\n (lowerBound.valueNumeric ?? -Infinity)\n ) {\n lowerBound = cond.lowerBound;\n }\n }\n if (cond.upperBound) {\n if (\n !upperBound ||\n (cond.upperBound.valueNumeric ?? Infinity) <\n (upperBound.valueNumeric ?? Infinity)\n ) {\n upperBound = cond.upperBound;\n }\n }\n }\n\n return { lowerBound, upperBound };\n}\n\nfunction appendBoundsToUniqueId(\n parts: string[],\n lowerBound?: NumericBound,\n upperBound?: NumericBound,\n): void {\n if (lowerBound) {\n parts.push(lowerBound.inclusive ? '>=' : '>');\n parts.push(lowerBound.value);\n }\n if (upperBound) {\n parts.push(upperBound.inclusive ? '<=' : '<');\n parts.push(upperBound.value);\n }\n}\n\nfunction mergeDimensionRanges<T extends MediaCondition | ContainerCondition>(\n conditions: T[],\n idPrefix: string[],\n): T | null {\n if (conditions.length === 0) return null;\n\n const { lowerBound, upperBound } = tightenBounds(conditions);\n const base = conditions[0];\n\n const parts = [...idPrefix];\n appendBoundsToUniqueId(parts, lowerBound, upperBound);\n\n return {\n ...base,\n negated: false,\n raw: buildMergedRaw(base.dimension || 'width', lowerBound, upperBound),\n uniqueId: parts.join(':'),\n lowerBound,\n upperBound,\n };\n}\n\nfunction mergeMediaRanges(conditions: MediaCondition[]): MediaCondition | null {\n const dim = conditions[0]?.dimension ?? 'width';\n return mergeDimensionRanges(conditions, ['media', 'dim', dim]);\n}\n\nfunction mergeContainerRanges(\n conditions: ContainerCondition[],\n): ContainerCondition | null {\n const base = conditions[0];\n if (!base) return null;\n const name = base.containerName || '_';\n const dim = base.dimension ?? 'width';\n return mergeDimensionRanges(conditions, ['container', 'dim', name, dim]);\n}\n\nfunction buildMergedRaw(\n dimension: string,\n lowerBound?: NumericBound,\n upperBound?: NumericBound,\n): string {\n if (lowerBound && upperBound) {\n const lowerOp = lowerBound.inclusive ? '<=' : '<';\n const upperOp = upperBound.inclusive ? '<=' : '<';\n return `@media(${lowerBound.value} ${lowerOp} ${dimension} ${upperOp} ${upperBound.value})`;\n } else if (upperBound) {\n const op = upperBound.inclusive ? '<=' : '<';\n return `@media(${dimension} ${op} ${upperBound.value})`;\n } else if (lowerBound) {\n const op = lowerBound.inclusive ? '>=' : '>';\n return `@media(${dimension} ${op} ${lowerBound.value})`;\n }\n return '@media()';\n}\n\n// ============================================================================\n// Complementary Factoring\n// ============================================================================\n\n/**\n * Apply complementary factoring: (A & B) | (A & !B) → A\n *\n * Finds pairs of AND compounds that share all children except one,\n * where the differing child is complementary (X vs !X).\n * Replaces the pair with the common terms.\n *\n * This is applied iteratively until no more reductions are possible,\n * since factoring can expose further simplification opportunities.\n */\nfunction applyComplementaryFactoring(terms: ConditionNode[]): ConditionNode[] {\n let changed = true;\n\n while (changed) {\n changed = false;\n\n for (let i = 0; i < terms.length; i++) {\n const a = terms[i];\n if (a.kind !== 'compound' || a.operator !== 'AND') continue;\n\n for (let j = i + 1; j < terms.length; j++) {\n const b = terms[j];\n if (b.kind !== 'compound' || b.operator !== 'AND') continue;\n\n const factored = tryFactorPair(a.children, b.children);\n if (factored) {\n const replacement = simplifyInner(factored);\n terms = [\n ...terms.slice(0, i),\n ...terms.slice(i + 1, j),\n ...terms.slice(j + 1),\n replacement,\n ];\n changed = true;\n break;\n }\n }\n\n if (changed) break;\n }\n }\n\n return terms;\n}\n\n/**\n * Try to factor two AND children lists.\n *\n * Extracts the common children (by uniqueId). If the remaining\n * (non-common) parts of each side OR to TRUE, the common part alone\n * is sufficient: `(common & restA) | (common & restB) → common`\n * when `restA | restB → TRUE`.\n *\n * Also handles the simpler case where exactly one child is\n * complementary: `[A, B, C]` and `[A, !B, C]` → `AND(A, C)`.\n */\nfunction tryFactorPair(\n aChildren: ConditionNode[],\n bChildren: ConditionNode[],\n): ConditionNode | null {\n const aIds = aChildren.map((c) => getConditionUniqueId(c));\n const bIds = bChildren.map((c) => getConditionUniqueId(c));\n\n const bIdSet = new Set(bIds);\n const aIdSet = new Set(aIds);\n\n // Extract common children (present in both by uniqueId)\n const commonIndicesA: number[] = [];\n const restIndicesA: number[] = [];\n for (let i = 0; i < aIds.length; i++) {\n if (bIdSet.has(aIds[i])) {\n commonIndicesA.push(i);\n } else {\n restIndicesA.push(i);\n }\n }\n\n const restIndicesB: number[] = [];\n for (let i = 0; i < bIds.length; i++) {\n if (!aIdSet.has(bIds[i])) {\n restIndicesB.push(i);\n }\n }\n\n // Must have at least one common child and differing parts on both sides\n if (commonIndicesA.length === 0) return null;\n if (restIndicesA.length === 0 && restIndicesB.length === 0) return null;\n\n // Build the \"rest\" conditions for each side\n const restA =\n restIndicesA.length === 0\n ? trueCondition()\n : restIndicesA.length === 1\n ? aChildren[restIndicesA[0]]\n : and(...restIndicesA.map((i) => aChildren[i]));\n\n const restB =\n restIndicesB.length === 0\n ? trueCondition()\n : restIndicesB.length === 1\n ? bChildren[restIndicesB[0]]\n : and(...restIndicesB.map((i) => bChildren[i]));\n\n // Check if restA | restB simplifies to TRUE\n const combined = simplifyInner({\n kind: 'compound',\n operator: 'OR',\n children: [restA, restB],\n });\n\n if (combined.kind !== 'true') {\n // Direct complement check for compound conditions.\n // hasTautology only detects leaf-level A/!A pairs, so compound\n // complements like @hc / !@hc (which expand via De Morgan into\n // structurally different trees) are missed. Compare the simplified\n // negation of one rest against the simplified other rest instead.\n const simplifiedRestB = simplifyInner(restB);\n const negRestA = simplifyInner(not(restA));\n\n if (\n getConditionUniqueId(negRestA) !== getConditionUniqueId(simplifiedRestB)\n ) {\n return null;\n }\n }\n\n // restA | restB = TRUE → (common & restA) | (common & restB) = common\n const common = commonIndicesA.map((i) => aChildren[i]);\n\n if (common.length === 0) {\n return trueCondition();\n }\n if (common.length === 1) {\n return common[0];\n }\n return and(...common);\n}\n\n// ============================================================================\n// Sorting\n// ============================================================================\n\nfunction sortTerms(terms: ConditionNode[]): ConditionNode[] {\n const withIds = terms.map((t) => [getConditionUniqueId(t), t] as const);\n withIds.sort((a, b) => a[0].localeCompare(b[0]));\n return withIds.map(([, t]) => t);\n}\n\n// ============================================================================\n// Absorption\n// ============================================================================\n\n/**\n * Apply the absorption law: removes compound terms that are absorbed by\n * another term already present (simple or compound).\n *\n * For AND context: A & (A | B) → A (absorbs OR compounds)\n * For OR context: A | (A & B) → A (absorbs AND compounds)\n *\n * After flattening, a compound A = OR(X, Y) becomes [X, Y, ...] in the\n * outer OR. A child AND(A, B) = AND(OR(X, Y), B) still references the\n * original un-flattened compound. We reconstruct possible compound\n * absorbers from the flattened terms so absorption works across nesting.\n */\nfunction applyAbsorption(\n terms: ConditionNode[],\n absorbedOperator: 'OR' | 'AND',\n): ConditionNode[] {\n // Collect IDs of ALL top-level terms as potential absorbers.\n const absorberIds = new Set<string>();\n for (const term of terms) {\n absorberIds.add(getConditionUniqueId(term));\n }\n\n // Reconstruct compound absorbers: if all children of a compound node\n // (found inside an absorbable term) are themselves absorbers, then\n // that compound is also an absorber. This handles the case where\n // A = OR(X, Y) was flattened into [X, Y, ...] at the top level,\n // but appears un-flattened as a child of AND(A, B).\n let changed = true;\n while (changed) {\n changed = false;\n for (const term of terms) {\n if (term.kind !== 'compound' || term.operator !== absorbedOperator) {\n continue;\n }\n for (const child of term.children) {\n if (child.kind !== 'compound') continue;\n const childId = getConditionUniqueId(child);\n if (absorberIds.has(childId)) continue;\n if (\n child.children.every((c) => absorberIds.has(getConditionUniqueId(c)))\n ) {\n absorberIds.add(childId);\n changed = true;\n }\n }\n }\n }\n\n return terms.filter((term) => {\n if (term.kind === 'compound' && term.operator === absorbedOperator) {\n for (const child of term.children) {\n if (absorberIds.has(getConditionUniqueId(child))) {\n return false;\n }\n }\n }\n return true;\n });\n}\n\nfunction applyAbsorptionAnd(terms: ConditionNode[]): ConditionNode[] {\n return applyAbsorption(terms, 'OR');\n}\n\nfunction applyAbsorptionOr(terms: ConditionNode[]): ConditionNode[] {\n return applyAbsorption(terms, 'AND');\n}\n\n// ============================================================================\n// Consensus / Resolution (AND dual of complementary factoring)\n// ============================================================================\n\n/**\n * Apply the consensus/resolution rule for AND:\n * (A | B) & (A | !B) → A\n *\n * This is the dual of complementary factoring in OR context:\n * (A & B) | (A & !B) → A\n *\n * Extracts common children from two OR terms. If the remaining\n * parts of each side AND to FALSE, the common part alone is\n * sufficient.\n */\nfunction applyConsensusAnd(terms: ConditionNode[]): ConditionNode[] {\n let changed = true;\n\n while (changed) {\n changed = false;\n\n for (let i = 0; i < terms.length; i++) {\n const a = terms[i];\n if (a.kind !== 'compound' || a.operator !== 'OR') continue;\n\n for (let j = i + 1; j < terms.length; j++) {\n const b = terms[j];\n if (b.kind !== 'compound' || b.operator !== 'OR') continue;\n\n const resolved = tryResolvePair(a.children, b.children);\n if (resolved) {\n const replacement = simplifyInner(resolved);\n terms = [\n ...terms.slice(0, i),\n ...terms.slice(i + 1, j),\n ...terms.slice(j + 1),\n replacement,\n ];\n changed = true;\n break;\n }\n }\n\n if (changed) break;\n }\n }\n\n return terms;\n}\n\n/**\n * Try to resolve two OR children lists.\n *\n * Extracts common children (by uniqueId). If the remaining\n * (non-common) parts AND to FALSE, the common part alone\n * is sufficient: `(common | restA) & (common | restB) → common`\n * when `restA & restB → FALSE`.\n */\nfunction tryResolvePair(\n aChildren: ConditionNode[],\n bChildren: ConditionNode[],\n): ConditionNode | null {\n const aIds = aChildren.map((c) => getConditionUniqueId(c));\n const bIds = bChildren.map((c) => getConditionUniqueId(c));\n\n const bIdSet = new Set(bIds);\n const aIdSet = new Set(aIds);\n\n const commonIndicesA: number[] = [];\n const restIndicesA: number[] = [];\n for (let i = 0; i < aIds.length; i++) {\n if (bIdSet.has(aIds[i])) {\n commonIndicesA.push(i);\n } else {\n restIndicesA.push(i);\n }\n }\n\n const restIndicesB: number[] = [];\n for (let i = 0; i < bIds.length; i++) {\n if (!aIdSet.has(bIds[i])) {\n restIndicesB.push(i);\n }\n }\n\n if (commonIndicesA.length === 0) return null;\n if (restIndicesA.length === 0 && restIndicesB.length === 0) return null;\n\n const restA =\n restIndicesA.length === 0\n ? falseCondition()\n : restIndicesA.length === 1\n ? aChildren[restIndicesA[0]]\n : or(...restIndicesA.map((i) => aChildren[i]));\n\n const restB =\n restIndicesB.length === 0\n ? falseCondition()\n : restIndicesB.length === 1\n ? bChildren[restIndicesB[0]]\n : or(...restIndicesB.map((i) => bChildren[i]));\n\n // Check if restA & restB simplifies to FALSE\n const combined = simplifyInner({\n kind: 'compound',\n operator: 'AND',\n children: [restA, restB],\n });\n\n if (combined.kind !== 'false') {\n // Direct complement check for compound conditions\n const simplifiedRestB = simplifyInner(restB);\n const negRestA = simplifyInner(not(restA));\n\n if (\n getConditionUniqueId(negRestA) !== getConditionUniqueId(simplifiedRestB)\n ) {\n return null;\n }\n }\n\n // restA & restB = FALSE → (common | restA) & (common | restB) = common\n const common = commonIndicesA.map((i) => aChildren[i]);\n\n if (common.length === 0) {\n return falseCondition();\n }\n if (common.length === 1) {\n return common[0];\n }\n return or(...common);\n}\n\n// ============================================================================\n// Cross-level Contradiction Pruning\n// ============================================================================\n\n/**\n * For each OR child of an AND, prune branches that are impossible\n * given the other AND siblings.\n *\n * Example: A & OR(!A & X, Y) → A & Y\n *\n * This catches dead OR branches left by exclusive negation (Stage 2b)\n * where `NOT(combined)` introduces branches contradicting flat siblings.\n */\nfunction pruneContradictedOrBranches(terms: ConditionNode[]): ConditionNode[] {\n const hasOr = terms.some((t) => t.kind === 'compound' && t.operator === 'OR');\n if (!hasOr) return terms;\n\n let changed = false;\n const result: ConditionNode[] = [];\n\n for (let i = 0; i < terms.length; i++) {\n const term = terms[i];\n if (term.kind !== 'compound' || term.operator !== 'OR') {\n result.push(term);\n continue;\n }\n\n // Gather all siblings (everything except this OR)\n const siblings = [...terms.slice(0, i), ...terms.slice(i + 1)];\n\n const surviving: ConditionNode[] = [];\n for (const branch of term.children) {\n const test: ConditionNode = {\n kind: 'compound',\n operator: 'AND',\n children: [branch, ...siblings],\n };\n const simplified = simplifyInner(test);\n if (simplified.kind !== 'false') {\n surviving.push(branch);\n }\n }\n\n if (surviving.length === term.children.length) {\n result.push(term);\n } else if (surviving.length === 0) {\n return [falseCondition()];\n } else {\n changed = true;\n if (surviving.length === 1) {\n result.push(surviving[0]);\n } else {\n result.push({\n kind: 'compound',\n operator: 'OR',\n children: surviving,\n });\n }\n }\n }\n\n if (!changed) return terms;\n\n // Re-flatten after pruning may have unwrapped single-branch ORs\n const flattened: ConditionNode[] = [];\n for (const term of result) {\n if (term.kind === 'compound' && term.operator === 'AND') {\n flattened.push(...term.children);\n } else {\n flattened.push(term);\n }\n }\n\n return flattened;\n}\n","/**\n * Contradiction Detection for Parsed CSS Conditions\n *\n * After conditions are converted into their parsed CSS shapes\n * (`ParsedMediaCondition`, `ParsedContainerCondition`,\n * `ParsedSupportsCondition`), variant merging in `materialize.ts` needs to\n * detect impossible combinations a second time at this lower level — the\n * tree-level simplifier in `simplify.ts` operates on `ConditionNode`s,\n * which can't see post-parse details like dimension bounds collapsing or\n * style-query property conflicts.\n *\n * Functions in this module are pure and self-contained; they take parsed\n * conditions and return booleans. They share no state with each other or\n * with the rest of the materialization pipeline.\n */\n\nimport type {\n ParsedContainerCondition,\n ParsedMediaCondition,\n ParsedSupportsCondition,\n} from './materialize-types';\n\n/**\n * Generic deduplication by a key extraction function.\n * Preserves insertion order, keeping the first occurrence of each key.\n */\nfunction dedupeByKey<T>(items: T[], getKey: (item: T) => string): T[] {\n const seen = new Set<string>();\n const result: T[] = [];\n for (const item of items) {\n const key = getKey(item);\n if (!seen.has(key)) {\n seen.add(key);\n result.push(item);\n }\n }\n return result;\n}\n\nexport function dedupeMediaConditions(\n conditions: ParsedMediaCondition[],\n): ParsedMediaCondition[] {\n return dedupeByKey(\n conditions,\n (c) => `${c.subtype}|${c.condition}|${c.negated}`,\n );\n}\n\nexport function dedupeContainerConditions(\n conditions: ParsedContainerCondition[],\n): ParsedContainerCondition[] {\n return dedupeByKey(\n conditions,\n (c) => `${c.name ?? ''}|${c.condition}|${c.negated}`,\n );\n}\n\nexport function dedupeSupportsConditions(\n conditions: ParsedSupportsCondition[],\n): ParsedSupportsCondition[] {\n return dedupeByKey(\n conditions,\n (c) => `${c.subtype}|${c.condition}|${c.negated}`,\n );\n}\n\n/**\n * Check if supports conditions contain contradictions\n * e.g., @supports(display: grid) AND NOT @supports(display: grid)\n */\nexport function hasSupportsContradiction(\n conditions: ParsedSupportsCondition[],\n): boolean {\n const conditionMap = new Map<string, boolean>(); // key -> isPositive\n\n for (const cond of conditions) {\n const key = `${cond.subtype}|${cond.condition}`;\n const existing = conditionMap.get(key);\n if (existing !== undefined && existing !== !cond.negated) {\n return true; // Contradiction: positive AND negated\n }\n conditionMap.set(key, !cond.negated);\n }\n\n return false;\n}\n\n/**\n * Check if a set of media conditions contains contradictions\n * e.g., (prefers-color-scheme: light) AND NOT (prefers-color-scheme: light)\n * or (width >= 900px) AND (width < 600px)\n *\n * Uses parsed media conditions for efficient analysis without regex parsing.\n */\nexport function hasMediaContradiction(\n conditions: ParsedMediaCondition[],\n): boolean {\n // Track conditions by their key (condition string) to detect A and NOT A\n const featureConditions = new Map<string, boolean>(); // key -> isPositive\n const typeConditions = new Map<string, boolean>(); // mediaType -> isPositive\n const dimensionConditions = new Map<string, boolean>(); // condition -> isPositive\n\n // Track dimension conditions for range contradiction detection (non-negated only)\n const dimensionsByDim = new Map<\n string,\n { lowerBound: number | null; upperBound: number | null }\n >();\n\n for (const cond of conditions) {\n if (cond.subtype === 'type') {\n // Type query: check for direct contradiction (print AND NOT print)\n const key = cond.mediaType || 'all';\n const existing = typeConditions.get(key);\n if (existing !== undefined && existing !== !cond.negated) {\n return true; // Contradiction: positive AND negated\n }\n typeConditions.set(key, !cond.negated);\n } else if (cond.subtype === 'feature') {\n // Feature query: check for direct contradiction\n const key = cond.condition;\n const existing = featureConditions.get(key);\n if (existing !== undefined && existing !== !cond.negated) {\n return true; // Contradiction: positive AND negated\n }\n featureConditions.set(key, !cond.negated);\n } else if (cond.subtype === 'dimension') {\n // First, check for direct contradiction: (width < 600px) AND NOT (width < 600px)\n const condKey = cond.condition;\n const existing = dimensionConditions.get(condKey);\n if (existing !== undefined && existing !== !cond.negated) {\n return true; // Contradiction: positive AND negated\n }\n dimensionConditions.set(condKey, !cond.negated);\n\n // For range analysis, only consider non-negated conditions\n // Negated conditions are handled via the direct contradiction check above\n if (!cond.negated) {\n const dim = cond.dimension || 'width';\n let bounds = dimensionsByDim.get(dim);\n if (!bounds) {\n bounds = { lowerBound: null, upperBound: null };\n dimensionsByDim.set(dim, bounds);\n }\n\n // Track the effective bounds\n if (cond.lowerBound?.valueNumeric != null) {\n const value = cond.lowerBound.valueNumeric;\n if (bounds.lowerBound === null || value > bounds.lowerBound) {\n bounds.lowerBound = value;\n }\n }\n if (cond.upperBound?.valueNumeric != null) {\n const value = cond.upperBound.valueNumeric;\n if (bounds.upperBound === null || value < bounds.upperBound) {\n bounds.upperBound = value;\n }\n }\n\n // Check for impossible range\n if (\n bounds.lowerBound !== null &&\n bounds.upperBound !== null &&\n bounds.lowerBound >= bounds.upperBound\n ) {\n return true;\n }\n }\n }\n }\n\n return false;\n}\n\n/**\n * Check if container conditions contain contradictions in style queries\n * e.g., style(--variant: danger) and style(--variant: success) together\n * Same property with different values = always false\n *\n * Uses parsed container conditions for efficient analysis without regex parsing.\n */\nexport function hasContainerStyleContradiction(\n conditions: ParsedContainerCondition[],\n): boolean {\n // Track style queries by property name\n // key: property name, value: { hasExistence: boolean, values: Set<string>, hasNegatedExistence: boolean }\n const styleQueries = new Map<\n string,\n { hasExistence: boolean; values: Set<string>; hasNegatedExistence: boolean }\n >();\n\n for (const cond of conditions) {\n // Only analyze style queries\n if (cond.subtype !== 'style' || !cond.property) {\n continue;\n }\n\n const property = cond.property;\n const value = cond.propertyValue;\n\n if (!styleQueries.has(property)) {\n styleQueries.set(property, {\n hasExistence: false,\n values: new Set(),\n hasNegatedExistence: false,\n });\n }\n\n const entry = styleQueries.get(property)!;\n\n if (cond.negated) {\n if (value === undefined) {\n // not style(--prop) - negated existence check\n entry.hasNegatedExistence = true;\n }\n // Negated value checks don't contradict positive value checks directly\n // They just mean \"not this value\"\n } else {\n if (value === undefined) {\n // style(--prop) - existence check\n entry.hasExistence = true;\n } else {\n // style(--prop: value) - value check\n entry.values.add(value);\n }\n }\n }\n\n // Check for contradictions\n for (const [, entry] of styleQueries) {\n // Contradiction: existence check + negated existence check\n if (entry.hasExistence && entry.hasNegatedExistence) {\n return true;\n }\n\n // Contradiction: multiple different values for same property\n // style(--variant: danger) AND style(--variant: success) is impossible\n if (entry.values.size > 1) {\n return true;\n }\n\n // Contradiction: negated existence + value check\n // not style(--variant) AND style(--variant: danger) is impossible\n if (entry.hasNegatedExistence && entry.values.size > 0) {\n return true;\n }\n }\n\n return false;\n}\n","/**\n * CSS Materialization\n *\n * Converts condition trees into CSS selectors and at-rules.\n * This is the final stage that produces actual CSS output.\n */\n\nimport { Lru } from '../parser/lru';\n\nimport type {\n ConditionNode,\n ContainerCondition,\n MediaCondition,\n ModifierCondition,\n PseudoCondition,\n StateCondition,\n SupportsCondition,\n} from './conditions';\nimport {\n and,\n getConditionUniqueId,\n isCompoundCondition,\n not,\n} from './conditions';\nimport { simplifyCondition } from './simplify';\nimport {\n dedupeContainerConditions,\n dedupeMediaConditions,\n dedupeSupportsConditions,\n hasContainerStyleContradiction,\n hasMediaContradiction,\n hasSupportsContradiction,\n} from './materialize-contradictions';\nimport type {\n CSSComponents,\n ParentGroup,\n ParsedContainerCondition,\n ParsedMediaCondition,\n ParsedModifierCondition,\n ParsedPseudoCondition,\n ParsedSelectorCondition,\n ParsedSupportsCondition,\n SelectorGroup,\n SelectorVariant,\n} from './materialize-types';\n\n// ============================================================================\n// Caching\n// ============================================================================\n\nconst conditionCache = new Lru<string, CSSComponents>(3000);\n\n// ============================================================================\n// Main Functions\n// ============================================================================\n\n/**\n * Convert a condition tree to CSS components\n */\nexport function conditionToCSS(node: ConditionNode): CSSComponents {\n // Check cache\n const key = getConditionUniqueId(node);\n const cached = conditionCache.get(key);\n if (cached) {\n return cached;\n }\n\n const result = conditionToCSSInner(node);\n\n // Cache result\n conditionCache.set(key, result);\n\n return result;\n}\n\n/**\n * Clear the condition cache (for testing)\n */\nexport function clearConditionCache(): void {\n conditionCache.clear();\n}\n\n// ============================================================================\n// Inner Implementation\n// ============================================================================\n\nfunction emptyVariant(): SelectorVariant {\n return {\n modifierConditions: [],\n pseudoConditions: [],\n selectorGroups: [],\n ownGroups: [],\n mediaConditions: [],\n containerConditions: [],\n supportsConditions: [],\n rootGroups: [],\n parentGroups: [],\n startingStyle: false,\n };\n}\n\nfunction conditionToCSSInner(node: ConditionNode): CSSComponents {\n // Base case: TRUE condition - single empty variant (matches everything)\n if (node.kind === 'true') {\n return {\n variants: [emptyVariant()],\n isImpossible: false,\n };\n }\n\n // Base case: FALSE condition - no variants (matches nothing)\n if (node.kind === 'false') {\n return {\n variants: [],\n isImpossible: true,\n };\n }\n\n // State condition\n if (node.kind === 'state') {\n return stateToCSS(node);\n }\n\n // Compound condition\n if (node.kind === 'compound') {\n if (node.operator === 'AND') {\n return andToCSS(node.children);\n } else {\n return orToCSS(node.children);\n }\n }\n\n // Fallback - single empty variant\n return {\n variants: [emptyVariant()],\n isImpossible: false,\n };\n}\n\n/**\n * Convert a state condition to CSS\n */\nfunction stateToCSS(state: StateCondition): CSSComponents {\n switch (state.type) {\n case 'media': {\n const mediaResults = mediaToParsed(state);\n const variants = mediaResults.map((mediaCond) => {\n const v = emptyVariant();\n v.mediaConditions.push(mediaCond);\n return v;\n });\n return { variants, isImpossible: false };\n }\n\n case 'root':\n return innerConditionToVariants(\n state.innerCondition,\n state.negated ?? false,\n 'rootGroups',\n );\n\n case 'parent':\n return parentConditionToVariants(\n state.innerCondition,\n state.negated ?? false,\n state.direct,\n );\n\n case 'own':\n return innerConditionToVariants(\n state.innerCondition,\n state.negated ?? false,\n 'ownGroups',\n );\n\n case 'modifier': {\n const v = emptyVariant();\n v.modifierConditions.push(modifierToParsed(state));\n return { variants: [v], isImpossible: false };\n }\n\n case 'pseudo': {\n const v = emptyVariant();\n v.pseudoConditions.push(pseudoToParsed(state));\n return { variants: [v], isImpossible: false };\n }\n\n case 'container': {\n const v = emptyVariant();\n v.containerConditions.push(containerToParsed(state));\n return { variants: [v], isImpossible: false };\n }\n\n case 'supports': {\n const v = emptyVariant();\n v.supportsConditions.push(supportsToParsed(state));\n return { variants: [v], isImpossible: false };\n }\n\n case 'starting': {\n const v = emptyVariant();\n v.startingStyle = !state.negated;\n return { variants: [v], isImpossible: false };\n }\n }\n}\n\n/**\n * Convert modifier condition to parsed structure\n */\nfunction modifierToParsed(state: ModifierCondition): ParsedModifierCondition {\n return {\n attribute: state.attribute,\n value: state.value,\n operator: state.operator,\n negated: state.negated ?? false,\n };\n}\n\n/**\n * Convert parsed modifier to CSS selector string (for final output)\n */\nfunction modifierToCSS(mod: ParsedModifierCondition): string {\n let selector: string;\n\n if (mod.value !== undefined) {\n // Value attribute: [data-attr=\"value\"]\n const op = mod.operator || '=';\n selector = `[${mod.attribute}${op}\"${mod.value}\"]`;\n } else {\n // Boolean attribute: [data-attr]\n selector = `[${mod.attribute}]`;\n }\n\n if (mod.negated) {\n return `:not(${selector})`;\n }\n return selector;\n}\n\n/**\n * Convert pseudo condition to parsed structure\n */\nfunction pseudoToParsed(state: PseudoCondition): ParsedPseudoCondition {\n return {\n pseudo: state.pseudo,\n negated: state.negated ?? false,\n };\n}\n\n/**\n * Convert parsed pseudo to CSS selector string (for final output).\n *\n * :not() is normalized to negated :is() at parse time, so pseudo.pseudo\n * never starts with ':not(' here. When negated:\n * - :is(X) → :not(X) (unwrap :is)\n * - :where(X) → :not(X) (unwrap :where)\n * - :has(X) → :not(:has(X))\n * - other → :not(other)\n *\n * When not negated, single-argument :is()/:where() is unwrapped when the\n * inner content is a simple compound selector that can safely append to\n * the base selector (this happens after double-negation of :not()).\n */\nexport function pseudoToCSS(pseudo: ParsedPseudoCondition): string {\n const p = pseudo.pseudo;\n\n if (pseudo.negated) {\n if (p.startsWith(':is(') || p.startsWith(':where(')) {\n return `:not(${p.slice(p.indexOf('(') + 1, -1)})`;\n }\n return `:not(${p})`;\n }\n\n if ((p.startsWith(':is(') || p.startsWith(':where(')) && !p.includes(',')) {\n const inner = p.slice(p.indexOf('(') + 1, -1);\n const ch = inner[0];\n\n // Only unwrap when the inner content is a simple compound selector:\n // must start with a compoundable character and contain no whitespace\n // (whitespace implies combinators like `>`, `+`, `~`, or descendant).\n if (\n (ch === ':' || ch === '.' || ch === '[' || ch === '#') &&\n !/\\s/.test(inner)\n ) {\n return inner;\n }\n }\n\n return p;\n}\n\n/**\n * Convert media condition to parsed structure(s)\n * Returns an array because negated ranges produce OR branches (two separate conditions)\n */\nfunction mediaToParsed(state: MediaCondition): ParsedMediaCondition[] {\n if (state.subtype === 'type') {\n // @media:print → @media print (or @media not print)\n const mediaType = state.mediaType || 'all';\n return [\n {\n subtype: 'type',\n negated: state.negated ?? false,\n condition: mediaType,\n mediaType: state.mediaType,\n },\n ];\n } else if (state.subtype === 'feature') {\n // @media(prefers-contrast: high) → @media (prefers-contrast: high)\n let condition: string;\n if (state.featureValue) {\n condition = `(${state.feature}: ${state.featureValue})`;\n } else {\n condition = `(${state.feature})`;\n }\n return [\n {\n subtype: 'feature',\n negated: state.negated ?? false,\n condition,\n feature: state.feature,\n featureValue: state.featureValue,\n },\n ];\n } else {\n // Dimension query - negation is handled by inverting the condition\n // because \"not (width < x)\" doesn't work reliably in browsers\n return dimensionToMediaParsed(\n state.dimension || 'width',\n state.lowerBound,\n state.upperBound,\n state.negated ?? false,\n );\n }\n}\n\n/**\n * Convert dimension bounds to parsed media condition(s)\n * Uses CSS Media Queries Level 4 `not (condition)` syntax for negation.\n */\nfunction dimensionToMediaParsed(\n dimension: 'width' | 'height' | 'inline-size' | 'block-size',\n lowerBound?: {\n value: string;\n valueNumeric: number | null;\n inclusive: boolean;\n },\n upperBound?: {\n value: string;\n valueNumeric: number | null;\n inclusive: boolean;\n },\n negated?: boolean,\n): ParsedMediaCondition[] {\n // Build the condition string\n let condition: string;\n if (lowerBound && upperBound) {\n const lowerOp = lowerBound.inclusive ? '<=' : '<';\n const upperOp = upperBound.inclusive ? '<=' : '<';\n condition = `(${lowerBound.value} ${lowerOp} ${dimension} ${upperOp} ${upperBound.value})`;\n } else if (upperBound) {\n const op = upperBound.inclusive ? '<=' : '<';\n condition = `(${dimension} ${op} ${upperBound.value})`;\n } else if (lowerBound) {\n const op = lowerBound.inclusive ? '>=' : '>';\n condition = `(${dimension} ${op} ${lowerBound.value})`;\n } else {\n condition = `(${dimension})`;\n }\n\n // For negation, we use CSS `not (condition)` syntax in buildAtRulesFromVariant\n return [\n {\n subtype: 'dimension',\n negated: negated ?? false,\n condition,\n dimension,\n lowerBound,\n upperBound,\n },\n ];\n}\n\n/**\n * Convert container condition to parsed structure\n * This enables structured analysis for contradiction detection and condition combining\n */\nfunction containerToParsed(\n state: ContainerCondition,\n): ParsedContainerCondition {\n let condition: string;\n\n if (state.subtype === 'style') {\n // Style query: style(--prop: value)\n if (state.propertyValue) {\n condition = `style(--${state.property}: ${state.propertyValue})`;\n } else {\n condition = `style(--${state.property})`;\n }\n } else if (state.subtype === 'raw') {\n // Raw function query: passed through verbatim (e.g., scroll-state(stuck: top))\n condition = state.rawCondition!;\n } else {\n // Dimension query\n condition = dimensionToContainerCondition(\n state.dimension || 'width',\n state.lowerBound,\n state.upperBound,\n );\n }\n\n return {\n name: state.containerName,\n condition,\n negated: state.negated ?? false,\n subtype: state.subtype,\n property: state.property,\n propertyValue: state.propertyValue,\n };\n}\n\n/**\n * Convert dimension bounds to container query condition (single string)\n * Container queries support \"not (condition)\", so no need to invert manually\n */\nfunction dimensionToContainerCondition(\n dimension: string,\n lowerBound?: { value: string; inclusive: boolean },\n upperBound?: { value: string; inclusive: boolean },\n): string {\n if (lowerBound && upperBound) {\n const lowerOp = lowerBound.inclusive ? '<=' : '<';\n const upperOp = upperBound.inclusive ? '<=' : '<';\n return `(${lowerBound.value} ${lowerOp} ${dimension} ${upperOp} ${upperBound.value})`;\n } else if (upperBound) {\n const op = upperBound.inclusive ? '<=' : '<';\n return `(${dimension} ${op} ${upperBound.value})`;\n } else if (lowerBound) {\n const op = lowerBound.inclusive ? '>=' : '>';\n return `(${dimension} ${op} ${lowerBound.value})`;\n }\n return '(width)'; // Fallback\n}\n\n/**\n * Convert supports condition to parsed structure\n */\nfunction supportsToParsed(state: SupportsCondition): ParsedSupportsCondition {\n return {\n subtype: state.subtype,\n condition: state.condition,\n negated: state.negated ?? false,\n };\n}\n\n/**\n * Collect all modifier and pseudo conditions from a variant as a flat array.\n */\nfunction collectSelectorConditions(\n variant: SelectorVariant,\n): ParsedSelectorCondition[] {\n return [...variant.modifierConditions, ...variant.pseudoConditions];\n}\n\n/**\n * Convert an inner condition tree into a single SelectorVariant with\n * one SelectorGroup whose branches represent the inner OR alternatives.\n * Shared by @root() and @own().\n *\n * Both positive and negated cases produce one variant with one group.\n * Negation simply sets the `negated` flag, which swaps :is() for :not()\n * in the final CSS output — no De Morgan transformation is needed.\n *\n * This mirrors parentConditionToVariants: OR branches are kept inside\n * a single group and rendered as comma-separated arguments in\n * :is()/:not(), e.g. :root:is([a], [b]) or [el]:not([a], [b]).\n */\nfunction innerConditionToVariants(\n innerCondition: ConditionNode,\n negated: boolean,\n target: 'rootGroups' | 'ownGroups',\n): CSSComponents {\n const innerCSS = conditionToCSS(innerCondition);\n\n if (innerCSS.isImpossible || innerCSS.variants.length === 0) {\n return { variants: [], isImpossible: true };\n }\n\n const branches: ParsedSelectorCondition[][] = [];\n\n for (const innerVariant of innerCSS.variants) {\n const conditions = collectSelectorConditions(innerVariant);\n\n if (conditions.length > 0) {\n branches.push(conditions);\n }\n }\n\n if (branches.length === 0) {\n return { variants: [emptyVariant()], isImpossible: false };\n }\n\n const v = emptyVariant();\n v[target].push({ branches, negated });\n\n return { variants: [v], isImpossible: false };\n}\n\n/**\n * Convert a @parent() inner condition into a single SelectorVariant with\n * one ParentGroup whose branches represent the inner OR alternatives.\n *\n * Both positive and negated cases produce one variant with one group.\n * Negation simply sets the `negated` flag, which swaps :is() for :not()\n * in the final CSS output — no structural transformation is needed.\n */\nfunction parentConditionToVariants(\n innerCondition: ConditionNode,\n negated: boolean,\n direct: boolean,\n): CSSComponents {\n const innerCSS = conditionToCSS(innerCondition);\n\n if (innerCSS.isImpossible || innerCSS.variants.length === 0) {\n return { variants: [], isImpossible: true };\n }\n\n const branches: ParsedSelectorCondition[][] = [];\n\n for (const innerVariant of innerCSS.variants) {\n const conditions = collectSelectorConditions(innerVariant);\n\n if (conditions.length > 0) {\n branches.push(conditions);\n }\n }\n\n if (branches.length === 0) {\n return { variants: [emptyVariant()], isImpossible: false };\n }\n\n const v = emptyVariant();\n v.parentGroups.push({ branches, direct, negated });\n\n return { variants: [v], isImpossible: false };\n}\n\n/**\n * Sort key for canonical condition output within selectors.\n *\n * Priority order:\n * 0: Boolean attribute selectors ([data-hovered])\n * 1: Value attribute selectors ([data-size=\"small\"])\n * 2: Negated boolean attributes (:not([data-disabled]))\n * 3: Negated value attributes (:not([data-size=\"small\"]))\n * 4: Pseudo-classes (:hover, :focus)\n * 5: Negated pseudo-classes (:not(:disabled))\n *\n * Secondary sort: alphabetical by attribute name / pseudo string.\n */\nfunction conditionSortKey(cond: ParsedSelectorCondition): string {\n if ('attribute' in cond) {\n const hasValue = cond.value !== undefined ? 1 : 0;\n const neg = cond.negated ? 2 : 0;\n return `${neg + hasValue}|${cond.attribute}|${cond.value ?? ''}`;\n }\n const priority = cond.negated ? 5 : 4;\n return `${priority}|${cond.pseudo}`;\n}\n\nfunction sortConditions(\n conditions: ParsedSelectorCondition[],\n): ParsedSelectorCondition[] {\n return conditions.toSorted((a, b) =>\n conditionSortKey(a).localeCompare(conditionSortKey(b)),\n );\n}\n\nexport function branchToCSS(branch: ParsedSelectorCondition[]): string {\n let parts = '';\n for (const cond of sortConditions(branch)) {\n parts += selectorConditionToCSS(cond);\n }\n return parts;\n}\n\n/**\n * Wrap serialized selector arguments in :is() or :not().\n * Arguments are sorted for canonical output.\n */\nfunction wrapInIsOrNot(args: string[], negated: boolean): string {\n const wrapper = negated ? ':not' : ':is';\n return `${wrapper}(${args.sort().join(', ')})`;\n}\n\n/**\n * Wrap a non-empty selector fragment in `:where(...)` to zero its\n * specificity. Tasty anchors specificity solely on the doubled class\n * (`.tXX.tXX`) and `data-element` attributes; every stateful selector\n * (modifiers, pseudos, :is()/:not() groups, root/parent context) is wrapped\n * so it contributes nothing to specificity and the cascade is decided by\n * source order alone. Empty input passes through unchanged.\n */\nexport function wrapWhere(inner: string): string {\n if (!inner) return '';\n return `:where(${inner})`;\n}\n\n/**\n * Convert a selector group to a CSS selector fragment.\n *\n * Single-branch groups are unwrapped (no :is() wrapper).\n * Multi-branch groups use :is() or :not().\n * Negation swaps :is() for :not().\n */\nexport function selectorGroupToCSS(group: SelectorGroup): string {\n if (group.branches.length === 0) return '';\n\n // Single branch: emit directly without :is() wrapper\n if (group.branches.length === 1) {\n const parts = branchToCSS(group.branches[0]);\n if (group.negated) {\n return `:not(${parts})`;\n }\n return parts;\n }\n\n return wrapInIsOrNot(group.branches.map(branchToCSS), group.negated);\n}\n\n// ============================================================================\n// Modifier Subsumption (shared by optimizeGroups and dedupeSelectorConditions)\n// ============================================================================\n\ninterface SubsumptionFacts {\n negatedBooleanAttrs: Set<string>;\n positiveExactValuesByAttr: Map<string, Set<string>>;\n}\n\n/**\n * Collect facts about modifier conditions for subsumption analysis.\n * Tracks negated boolean attrs (:not([attr])) and positive exact values ([attr=\"X\"]).\n */\nfunction collectSubsumptionFacts(\n modifiers: Iterable<ParsedModifierCondition>,\n): SubsumptionFacts {\n const negatedBooleanAttrs = new Set<string>();\n const positiveExactValuesByAttr = new Map<string, Set<string>>();\n\n for (const mod of modifiers) {\n if (mod.negated && mod.value === undefined) {\n negatedBooleanAttrs.add(mod.attribute);\n }\n if (\n !mod.negated &&\n mod.value !== undefined &&\n (mod.operator ?? '=') === '='\n ) {\n let vals = positiveExactValuesByAttr.get(mod.attribute);\n if (!vals) {\n vals = new Set();\n positiveExactValuesByAttr.set(mod.attribute, vals);\n }\n vals.add(mod.value);\n }\n }\n\n return { negatedBooleanAttrs, positiveExactValuesByAttr };\n}\n\n/**\n * Check if a negated-value modifier is subsumed by stronger facts:\n * - :not([attr]) subsumes :not([attr=\"val\"])\n * - [attr=\"X\"] implies :not([attr=\"Y\"]) is redundant (single exact value)\n *\n * Only applies to exact-match (=) operators; substring operators don't\n * imply exclusivity between values.\n */\nfunction isSubsumedNegatedModifier(\n mod: ParsedModifierCondition,\n facts: SubsumptionFacts,\n): boolean {\n if (!mod.negated || mod.value === undefined) return false;\n\n if (facts.negatedBooleanAttrs.has(mod.attribute)) return true;\n\n if ((mod.operator ?? '=') === '=') {\n const posVals = facts.positiveExactValuesByAttr.get(mod.attribute);\n if (posVals && posVals.size === 1 && !posVals.has(mod.value)) {\n return true;\n }\n }\n\n return false;\n}\n\n/**\n * Remove redundant single-condition groups that are subsumed by stronger\n * groups on the same attribute. O(n) — only inspects single-branch,\n * single-condition groups.\n */\nexport function optimizeGroups(groups: SelectorGroup[]): SelectorGroup[] {\n if (groups.length <= 1) return groups;\n\n // Exact dedup by key\n const seen = new Set<string>();\n const result: SelectorGroup[] = [];\n for (const g of groups) {\n const key = getSelectorGroupKey(g);\n if (!seen.has(key)) {\n seen.add(key);\n result.push(g);\n }\n }\n\n if (result.length <= 1) return result;\n\n // Extract modifier conditions from simple groups for subsumption analysis\n const effectiveModifiers: ParsedModifierCondition[] = [];\n for (const g of result) {\n if (g.branches.length !== 1 || g.branches[0].length !== 1) continue;\n const cond = g.branches[0][0];\n if (!('attribute' in cond)) continue;\n // Map group-level negation onto the condition for fact collection\n effectiveModifiers.push({\n ...cond,\n negated: g.negated !== cond.negated,\n });\n }\n\n const facts = collectSubsumptionFacts(effectiveModifiers);\n if (\n facts.negatedBooleanAttrs.size === 0 &&\n facts.positiveExactValuesByAttr.size === 0\n ) {\n return result;\n }\n\n return result.filter((g) => {\n if (g.branches.length !== 1 || g.branches[0].length !== 1) return true;\n const cond = g.branches[0][0];\n if (\n !('attribute' in cond) ||\n !g.negated ||\n cond.negated ||\n cond.value === undefined\n ) {\n return true;\n }\n return !isSubsumedNegatedModifier({ ...cond, negated: true }, facts);\n });\n}\n\n/**\n * Convert root groups to CSS selector prefix (for final output)\n */\nexport function rootGroupsToCSS(groups: SelectorGroup[]): string | undefined {\n if (groups.length === 0) return undefined;\n\n const optimized = optimizeGroups(groups);\n if (optimized.length === 0) return undefined;\n\n let prefix = ':root';\n for (const group of optimized) {\n prefix += selectorGroupToCSS(group);\n }\n // The root context prefix carries zero specificity: wrap the whole\n // `:root...` selector in :where() so neither the :root pseudo nor its\n // state groups contribute to specificity.\n return wrapWhere(prefix);\n}\n\n/**\n * Convert parent groups to CSS selector fragments (for final output).\n * Each group produces its own :is()/:not() wrapper with a combinator\n * suffix (` *` or ` > *`) appended to each branch.\n */\nexport function parentGroupsToCSS(groups: ParentGroup[]): string {\n let result = '';\n for (const group of groups) {\n const combinator = group.direct ? ' > *' : ' *';\n const args = group.branches.map(\n (branch) => branchToCSS(branch) + combinator,\n );\n // Ancestor context selectors carry zero specificity: wrap in :where().\n // Negation goes inside as :where(:not(...)) so the negated ancestor\n // adds nothing either.\n const inner = group.negated\n ? `:not(${args.sort().join(', ')})`\n : args.sort().join(', ');\n result += wrapWhere(inner);\n }\n return result;\n}\n\n/**\n * Convert a modifier or pseudo condition to a CSS selector fragment\n */\nfunction selectorConditionToCSS(cond: ParsedSelectorCondition): string {\n if ('attribute' in cond) {\n return modifierToCSS(cond);\n }\n return pseudoToCSS(cond);\n}\n\n/**\n * Get unique key for a modifier condition\n */\nfunction getModifierKey(mod: ParsedModifierCondition): string {\n const base = mod.value\n ? `${mod.attribute}${mod.operator || '='}${mod.value}`\n : mod.attribute;\n return mod.negated ? `!${base}` : base;\n}\n\n/**\n * Get unique key for a pseudo condition\n */\nfunction getPseudoKey(pseudo: ParsedPseudoCondition): string {\n return pseudo.negated ? `!${pseudo.pseudo}` : pseudo.pseudo;\n}\n\n/**\n * Get unique key for any selector condition (modifier or pseudo)\n */\nfunction getSelectorConditionKey(cond: ParsedSelectorCondition): string {\n return 'attribute' in cond\n ? `mod:${getModifierKey(cond)}`\n : `pseudo:${getPseudoKey(cond)}`;\n}\n\n/**\n * Deduplicate selector conditions (modifiers or pseudos).\n * Shared by root, parent, and own conditions.\n */\nfunction dedupeSelectorConditions(\n conditions: ParsedSelectorCondition[],\n): ParsedSelectorCondition[] {\n // Pass 1: exact-key dedup\n const seen = new Set<string>();\n const result: ParsedSelectorCondition[] = [];\n for (const c of conditions) {\n const key = getSelectorConditionKey(c);\n if (!seen.has(key)) {\n seen.add(key);\n result.push(c);\n }\n }\n\n // Pass 2: remove negated value modifiers subsumed by other modifiers\n const modifiers = result.filter(\n (c): c is ParsedModifierCondition => 'attribute' in c,\n );\n const facts = collectSubsumptionFacts(modifiers);\n if (\n facts.negatedBooleanAttrs.size === 0 &&\n facts.positiveExactValuesByAttr.size === 0\n ) {\n return result;\n }\n\n return result.filter((c) => {\n if (!('attribute' in c)) return true;\n if (isSubsumedNegatedModifier(c, facts)) return false;\n // [data-attr] is redundant when [data-attr=\"val\"] already present\n if (\n !c.negated &&\n c.value === undefined &&\n facts.positiveExactValuesByAttr.has(c.attribute)\n ) {\n return false;\n }\n return true;\n });\n}\n\n/**\n * Check for modifier contradiction: same attribute with opposite negation\n */\nfunction hasModifierContradiction(\n conditions: ParsedModifierCondition[],\n): boolean {\n const byKey = new Map<string, boolean>(); // base key -> isPositive\n\n for (const mod of conditions) {\n const baseKey = mod.value\n ? `${mod.attribute}${mod.operator || '='}${mod.value}`\n : mod.attribute;\n const existing = byKey.get(baseKey);\n if (existing !== undefined && existing !== !mod.negated) {\n return true; // Same attribute with opposite negation\n }\n byKey.set(baseKey, !mod.negated);\n }\n return false;\n}\n\n/**\n * Check for pseudo contradiction: same pseudo with opposite negation\n */\nfunction hasPseudoContradiction(conditions: ParsedPseudoCondition[]): boolean {\n const byKey = new Map<string, boolean>(); // pseudo -> isPositive\n\n for (const pseudo of conditions) {\n const existing = byKey.get(pseudo.pseudo);\n if (existing !== undefined && existing !== !pseudo.negated) {\n return true; // Same pseudo with opposite negation\n }\n byKey.set(pseudo.pseudo, !pseudo.negated);\n }\n return false;\n}\n\n/**\n * Check for selector condition contradiction (modifier or pseudo with opposite negation).\n * Shared by root, parent, and own conditions.\n */\nfunction hasSelectorConditionContradiction(\n conditions: ParsedSelectorCondition[],\n): boolean {\n const modifiers: ParsedModifierCondition[] = [];\n const pseudos: ParsedPseudoCondition[] = [];\n\n for (const c of conditions) {\n if ('attribute' in c) {\n modifiers.push(c);\n } else {\n pseudos.push(c);\n }\n }\n\n return hasModifierContradiction(modifiers) || hasPseudoContradiction(pseudos);\n}\n\n/**\n * Check for parent group contradiction: same target (direct + conditions)\n * with opposite negation. E.g. :not([data-hovered] *) and :is([data-hovered] *)\n * in the same variant is impossible.\n */\nfunction getBranchesKey(branches: ParsedSelectorCondition[][]): string {\n if (branches.length === 1) {\n const b = branches[0];\n if (b.length === 1) return getSelectorConditionKey(b[0]);\n return b.map(getSelectorConditionKey).sort().join('+');\n }\n return branches\n .map((b) => b.map(getSelectorConditionKey).sort().join('+'))\n .sort()\n .join(',');\n}\n\nfunction hasParentGroupContradiction(groups: ParentGroup[]): boolean {\n const byBaseKey = new Map<string, boolean>();\n\n for (const g of groups) {\n const baseKey = `${g.direct ? '>' : ''}(${getBranchesKey(g.branches)})`;\n const existing = byBaseKey.get(baseKey);\n if (existing !== undefined && existing !== !g.negated) {\n return true;\n }\n byBaseKey.set(baseKey, !g.negated);\n }\n return false;\n}\n\n/**\n * Check for selector group contradiction: same branches with opposite negation.\n * E.g. :is([data-a]) and :not([data-a]) in the same variant is impossible.\n */\nfunction hasSelectorGroupContradiction(groups: SelectorGroup[]): boolean {\n const byBaseKey = new Map<string, boolean>();\n\n for (const g of groups) {\n const baseKey = getBranchesKey(g.branches);\n const existing = byBaseKey.get(baseKey);\n if (existing !== undefined && existing !== !g.negated) {\n return true;\n }\n byBaseKey.set(baseKey, !g.negated);\n }\n return false;\n}\n\n/**\n * Merge two selector variants (AND operation)\n * Deduplicates conditions and checks for contradictions\n */\nfunction mergeVariants(\n a: SelectorVariant,\n b: SelectorVariant,\n): SelectorVariant | null {\n // Merge media conditions and check for contradictions\n const mergedMedia = dedupeMediaConditions([\n ...a.mediaConditions,\n ...b.mediaConditions,\n ]);\n if (hasMediaContradiction(mergedMedia)) {\n return null; // Impossible variant\n }\n\n // Concatenate root groups, optimize, and check for contradictions\n const mergedRootGroups = optimizeGroups([...a.rootGroups, ...b.rootGroups]);\n if (hasSelectorGroupContradiction(mergedRootGroups)) {\n return null; // Impossible variant\n }\n\n // Merge modifier and pseudo conditions separately, then cross-check\n const mergedModifiers = dedupeSelectorConditions([\n ...a.modifierConditions,\n ...b.modifierConditions,\n ]) as ParsedModifierCondition[];\n const mergedPseudos = dedupeSelectorConditions([\n ...a.pseudoConditions,\n ...b.pseudoConditions,\n ]) as ParsedPseudoCondition[];\n if (\n hasSelectorConditionContradiction([...mergedModifiers, ...mergedPseudos])\n ) {\n return null; // Impossible variant\n }\n\n // Concatenate selector groups, optimize, and check for contradictions\n const mergedSelectorGroups = optimizeGroups([\n ...a.selectorGroups,\n ...b.selectorGroups,\n ]);\n if (hasSelectorGroupContradiction(mergedSelectorGroups)) {\n return null; // Impossible variant\n }\n\n // Concatenate parent groups (each group is an independent :is() wrapper)\n const mergedParentGroups = [...a.parentGroups, ...b.parentGroups];\n if (hasParentGroupContradiction(mergedParentGroups)) {\n return null; // Impossible variant\n }\n\n // Concatenate own groups, optimize, and check for contradictions\n const mergedOwnGroups = optimizeGroups([...a.ownGroups, ...b.ownGroups]);\n if (hasSelectorGroupContradiction(mergedOwnGroups)) {\n return null; // Impossible variant\n }\n\n // Merge container conditions and check for contradictions\n const mergedContainers = dedupeContainerConditions([\n ...a.containerConditions,\n ...b.containerConditions,\n ]);\n if (hasContainerStyleContradiction(mergedContainers)) {\n return null; // Impossible variant\n }\n\n // Merge supports conditions and check for contradictions\n const mergedSupports = dedupeSupportsConditions([\n ...a.supportsConditions,\n ...b.supportsConditions,\n ]);\n if (hasSupportsContradiction(mergedSupports)) {\n return null; // Impossible variant\n }\n\n return {\n modifierConditions: mergedModifiers,\n pseudoConditions: mergedPseudos,\n selectorGroups: mergedSelectorGroups,\n ownGroups: mergedOwnGroups,\n mediaConditions: mergedMedia,\n containerConditions: mergedContainers,\n supportsConditions: mergedSupports,\n rootGroups: mergedRootGroups,\n parentGroups: mergedParentGroups,\n startingStyle: a.startingStyle || b.startingStyle,\n };\n}\n\n// Contradiction-detection helpers (`hasMediaContradiction`,\n// `hasContainerStyleContradiction`, `hasSupportsContradiction`) and the\n// matching `dedupe*Conditions` helpers live in `./materialize-contradictions`.\n// They're imported at the top of this file.\n\nconst variantKeyCache = new WeakMap<SelectorVariant, string>();\n\n/**\n * Get a unique key for a variant (for deduplication).\n * Cached via WeakMap since variants are compared multiple times during\n * deduplication and sorting.\n */\nfunction getSelectorGroupKey(g: SelectorGroup): string {\n return `${g.negated ? '!' : ''}(${getBranchesKey(g.branches)})`;\n}\n\n/**\n * Get a context key for a variant — everything except flat modifier/pseudo\n * conditions. Variants with the same context key can be merged into an\n * :is() group. Also used by getVariantKey as the shared non-selector portion.\n */\nfunction getVariantContextKey(v: SelectorVariant): string {\n const mediaKey = v.mediaConditions\n .map((c) => `${c.subtype}:${c.negated ? '!' : ''}${c.condition}`)\n .sort()\n .join('|');\n const containerKey = v.containerConditions\n .map((c) => `${c.name ?? ''}:${c.negated ? '!' : ''}${c.condition}`)\n .sort()\n .join('|');\n const supportsKey = v.supportsConditions\n .map((c) => `${c.subtype}:${c.negated ? '!' : ''}${c.condition}`)\n .sort()\n .join('|');\n const rootKey = v.rootGroups.map(getSelectorGroupKey).sort().join('|');\n const parentKey = v.parentGroups.map(getParentGroupKey).sort().join('|');\n const ownKey = v.ownGroups.map(getSelectorGroupKey).sort().join('|');\n const selectorGroupKey = v.selectorGroups\n .map(getSelectorGroupKey)\n .sort()\n .join('|');\n\n return [\n mediaKey,\n containerKey,\n supportsKey,\n rootKey,\n parentKey,\n ownKey,\n selectorGroupKey,\n v.startingStyle ? '1' : '0',\n ].join('###');\n}\n\nfunction getVariantKey(v: SelectorVariant): string {\n const cached = variantKeyCache.get(v);\n if (cached !== undefined) return cached;\n const modifierKey = v.modifierConditions.map(getModifierKey).sort().join('|');\n const pseudoKey = v.pseudoConditions.map(getPseudoKey).sort().join('|');\n const key = modifierKey + '###' + pseudoKey + '###' + getVariantContextKey(v);\n variantKeyCache.set(v, key);\n return key;\n}\n\n/**\n * Total number of leaf conditions in a variant (for superset / dedup comparisons).\n */\nfunction groupConditionCount(\n groups: readonly { branches: ParsedSelectorCondition[][] }[],\n): number {\n return groups.reduce(\n (sum, g) => sum + g.branches.reduce((s, b) => s + b.length, 0),\n 0,\n );\n}\n\nfunction variantConditionCount(v: SelectorVariant): number {\n return (\n v.modifierConditions.length +\n v.pseudoConditions.length +\n groupConditionCount(v.selectorGroups) +\n groupConditionCount(v.ownGroups) +\n v.mediaConditions.length +\n v.containerConditions.length +\n v.supportsConditions.length +\n groupConditionCount(v.rootGroups) +\n groupConditionCount(v.parentGroups)\n );\n}\n\n/**\n * Check if variant A is a superset of variant B (A is more restrictive)\n *\n * If A has all of B's conditions plus more, then A is redundant\n * because B already covers the same cases (and more).\n *\n * Example:\n * A: :not([size=large]):not([size=medium]):not([size=small])\n * B: :not([size=large])\n * A is a superset of B, so A is redundant when B exists.\n */\nfunction isVariantSuperset(a: SelectorVariant, b: SelectorVariant): boolean {\n // Must have same context\n if (a.startingStyle !== b.startingStyle) return false;\n\n // Check if a.rootGroups is superset of b.rootGroups\n if (!isSelectorGroupsSuperset(a.rootGroups, b.rootGroups)) return false;\n\n // Check if a.mediaConditions is superset of b.mediaConditions\n if (!isMediaConditionsSuperset(a.mediaConditions, b.mediaConditions))\n return false;\n\n // Check if a.containerConditions is superset of b.containerConditions\n if (\n !isContainerConditionsSuperset(a.containerConditions, b.containerConditions)\n )\n return false;\n\n // Check if a.supportsConditions is superset of b.supportsConditions\n if (!isSupportsConditionsSuperset(a.supportsConditions, b.supportsConditions))\n return false;\n\n // Check if a.modifierConditions is superset of b.modifierConditions\n if (!isModifierConditionsSuperset(a.modifierConditions, b.modifierConditions))\n return false;\n\n // Check if a.pseudoConditions is superset of b.pseudoConditions\n if (!isPseudoConditionsSuperset(a.pseudoConditions, b.pseudoConditions))\n return false;\n\n // Check if a.selectorGroups is superset of b.selectorGroups\n if (!isSelectorGroupsSuperset(a.selectorGroups, b.selectorGroups))\n return false;\n\n // Check if a.ownGroups is superset of b.ownGroups\n if (!isSelectorGroupsSuperset(a.ownGroups, b.ownGroups)) return false;\n\n // Check if a.parentGroups is superset of b.parentGroups\n if (!isParentGroupsSuperset(a.parentGroups, b.parentGroups)) return false;\n\n return variantConditionCount(a) > variantConditionCount(b);\n}\n\n/**\n * Generic superset check: true if every item in B has a matching key in A.\n */\nfunction isConditionsSuperset<T>(\n a: T[],\n b: T[],\n getKey: (item: T) => string,\n): boolean {\n const aKeys = new Set(a.map(getKey));\n return b.every((c) => aKeys.has(getKey(c)));\n}\n\nfunction isMediaConditionsSuperset(\n a: ParsedMediaCondition[],\n b: ParsedMediaCondition[],\n): boolean {\n return isConditionsSuperset(\n a,\n b,\n (c) => `${c.subtype}|${c.condition}|${c.negated}`,\n );\n}\n\nfunction isContainerConditionsSuperset(\n a: ParsedContainerCondition[],\n b: ParsedContainerCondition[],\n): boolean {\n return isConditionsSuperset(\n a,\n b,\n (c) => `${c.name ?? ''}|${c.condition}|${c.negated}`,\n );\n}\n\nfunction isSupportsConditionsSuperset(\n a: ParsedSupportsCondition[],\n b: ParsedSupportsCondition[],\n): boolean {\n return isConditionsSuperset(\n a,\n b,\n (c) => `${c.subtype}|${c.condition}|${c.negated}`,\n );\n}\n\nfunction isModifierConditionsSuperset(\n a: ParsedModifierCondition[],\n b: ParsedModifierCondition[],\n): boolean {\n return isConditionsSuperset(a, b, getModifierKey);\n}\n\nfunction isPseudoConditionsSuperset(\n a: ParsedPseudoCondition[],\n b: ParsedPseudoCondition[],\n): boolean {\n return isConditionsSuperset(a, b, getPseudoKey);\n}\n\nfunction isSelectorGroupsSuperset(\n a: SelectorGroup[],\n b: SelectorGroup[],\n): boolean {\n if (a.length < b.length) return false;\n return isConditionsSuperset(a, b, getSelectorGroupKey);\n}\n\n/**\n * Check if parent groups A is a superset of B.\n * Each group in B must have a matching group in A.\n */\nfunction isParentGroupsSuperset(a: ParentGroup[], b: ParentGroup[]): boolean {\n if (a.length < b.length) return false;\n return isConditionsSuperset(a, b, getParentGroupKey);\n}\n\nfunction getParentGroupKey(g: ParentGroup): string {\n return `${g.negated ? '!' : ''}${g.direct ? '>' : ''}(${getBranchesKey(g.branches)})`;\n}\n\n/**\n * Deduplicate variants\n *\n * Removes:\n * 1. Exact duplicates (same key)\n * 2. Superset variants (more restrictive selectors that are redundant)\n */\nfunction dedupeVariants(variants: SelectorVariant[]): SelectorVariant[] {\n if (variants.length <= 1) return variants;\n\n // First pass: exact deduplication\n const seen = new Set<string>();\n const result: SelectorVariant[] = [];\n\n for (const v of variants) {\n const key = getVariantKey(v);\n if (!seen.has(key)) {\n seen.add(key);\n result.push(v);\n }\n }\n\n if (result.length <= 1) return result;\n\n // Second pass: remove supersets (more restrictive variants)\n // Sort by total condition count (fewer conditions = less restrictive = keep)\n result.sort((a, b) => variantConditionCount(a) - variantConditionCount(b));\n\n // Remove variants that are supersets of earlier (less restrictive) variants\n const filtered: SelectorVariant[] = [];\n for (const candidate of result) {\n let isRedundant = false;\n for (const kept of filtered) {\n if (isVariantSuperset(candidate, kept)) {\n isRedundant = true;\n break;\n }\n }\n if (!isRedundant) {\n filtered.push(candidate);\n }\n }\n\n return filtered;\n}\n\n/**\n * Combine AND conditions into CSS\n *\n * AND of conditions means cartesian product of variants:\n * (A1 | A2) & (B1 | B2) = A1&B1 | A1&B2 | A2&B1 | A2&B2\n *\n * Variants that result in contradictions (e.g., conflicting media rules)\n * are filtered out.\n */\nfunction andToCSS(children: ConditionNode[]): CSSComponents {\n // Make inner OR branches exclusive before materializing so the\n // Cartesian product produces non-overlapping CSS variants.\n const exclusiveChildren = makeOrBranchesExclusive(children);\n\n // Start with a single empty variant\n let currentVariants: SelectorVariant[] = [emptyVariant()];\n\n for (const child of exclusiveChildren) {\n const childCSS = conditionToCSSInner(child);\n\n if (childCSS.isImpossible || childCSS.variants.length === 0) {\n return { variants: [], isImpossible: true };\n }\n\n // Cartesian product: each current variant × each child variant\n const newVariants: SelectorVariant[] = [];\n for (const current of currentVariants) {\n for (const childVariant of childCSS.variants) {\n const merged = mergeVariants(current, childVariant);\n // Skip impossible variants (contradictions detected during merge)\n if (merged !== null) {\n newVariants.push(merged);\n }\n }\n }\n\n if (newVariants.length === 0) {\n return { variants: [], isImpossible: true };\n }\n\n // Deduplicate after each step to prevent exponential blowup\n currentVariants = dedupeVariants(newVariants);\n }\n\n return {\n variants: currentVariants,\n isImpossible: false,\n };\n}\n\n/**\n * Check if a condition involves an `@supports` query (recursively).\n */\nfunction branchHasSupports(node: ConditionNode): boolean {\n if (node.kind === 'state') {\n return node.type === 'supports';\n }\n if (isCompoundCondition(node)) {\n return node.children.some(branchHasSupports);\n }\n return false;\n}\n\n/**\n * Make OR branches within AND children mutually exclusive.\n *\n * For an AND child that is OR(A, B), transforms it to OR(A, B & !A)\n * so that when andToCSS does a Cartesian product, the resulting\n * CSS variants don't overlap.\n *\n * Only transforms OR children whose branches actually produce\n * different at-rule contexts when materialized. This avoids\n * breaking cases where contradiction detection in the Cartesian\n * product naturally handles deduplication.\n */\nfunction makeOrBranchesExclusive(children: ConditionNode[]): ConditionNode[] {\n return children.map((child) => {\n if (!isCompoundCondition(child) || child.operator !== 'OR') return child;\n if (child.children.length <= 1) return child;\n\n // Only apply when branches produce different at-rule contexts.\n // Materialize each branch and compare context keys. If all branches\n // produce the same context key, the :is() merging handles it.\n if (!branchesProduceDifferentContexts(child.children)) return child;\n\n // Process `@supports` branches first so a negated feature guard becomes\n // the bare \"feature unsupported\" fallback and every dependent negation\n // (e.g. a `@container scroll-state(...)` query) nests inside the\n // supported scope. Without this, `simplify`'s alphabetical ordering can\n // emit a dependent query negation bare, where it is meaningless when the\n // feature is unsupported. Stable for ties.\n const sortedBranches = [...child.children].sort(\n (a, b) => (branchHasSupports(a) ? 0 : 1) - (branchHasSupports(b) ? 0 : 1),\n );\n\n const exclusiveBranches: ConditionNode[] = [];\n const priorBranches: ConditionNode[] = [];\n\n for (const branch of sortedBranches) {\n if (priorBranches.length === 0) {\n exclusiveBranches.push(branch);\n } else {\n let exclusive: ConditionNode = branch;\n for (const prior of priorBranches) {\n exclusive = and(exclusive, not(prior));\n }\n const simplified = simplifyCondition(exclusive);\n if (simplified.kind !== 'false') {\n exclusiveBranches.push(simplified);\n }\n }\n priorBranches.push(branch);\n }\n\n if (exclusiveBranches.length === 0) {\n return child;\n }\n if (exclusiveBranches.length === 1) {\n return exclusiveBranches[0];\n }\n\n return {\n kind: 'compound' as const,\n operator: 'OR' as const,\n children: exclusiveBranches,\n };\n });\n}\n\n/**\n * Check if OR branches produce different at-rule contexts when\n * materialized. If so, the Cartesian product in andToCSS will\n * create overlapping CSS variants that need exclusive expansion.\n *\n * Exported so Stage 2a (`expandOrConditions` in `exclusive.ts`) can\n * reuse the same heuristic and skip OR expansion when every branch\n * lives in the same at-rule/root/parent/own context — pure-selector\n * ORs are better collapsed into `:is(...)` at materialization time\n * than expanded into mutually-exclusive `A | (B & !A) | …` cascades.\n */\nexport function branchesProduceDifferentContexts(\n branches: ConditionNode[],\n): boolean {\n const contextKeys = new Set<string>();\n\n for (const branch of branches) {\n const css = conditionToCSSInner(branch);\n if (css.isImpossible) continue;\n\n for (const v of css.variants) {\n contextKeys.add(getVariantContextKey(v));\n }\n }\n\n return contextKeys.size > 1;\n}\n\n/**\n * Combine OR conditions into CSS\n *\n * OR in CSS means multiple selector variants (DNF).\n * After deduplication, variants that differ only in their base\n * modifier/pseudo conditions are merged into :is() groups.\n *\n * Note: OR exclusivity is handled at the pipeline level (expandOrConditions),\n * so here we just collect all variants. Any remaining ORs in the condition\n * tree (e.g., from De Morgan expansion) are handled as simple alternatives.\n */\n/**\n * Serialize a single negated own-element selector leaf (modifier or pseudo)\n * to its *positive* selector string, for use inside a combined `:not(...)`.\n *\n * Returns `null` when the node is not a negated, own-element selector leaf\n * (e.g. positive, or a media/container/parent/root/own/supports/starting\n * wrapper, or a compound), which means it cannot participate in De Morgan\n * recombination.\n */\nfunction negatedSelectorLeafToPositiveSelector(\n node: ConditionNode,\n): string | null {\n if (node.kind !== 'state' || !node.negated) return null;\n\n if (node.type === 'modifier') {\n return modifierToCSS({\n attribute: node.attribute,\n value: node.value,\n operator: node.operator,\n negated: false,\n });\n }\n\n if (node.type === 'pseudo') {\n // `pseudo` may itself be a `:is(X)`/`:where(X)` wrapper (from a parsed\n // `:not(X)`); unwrap so the recombined `:not(...)` stays compound-safe.\n const p = node.pseudo;\n if ((p.startsWith(':is(') || p.startsWith(':where(')) && !p.includes(',')) {\n const inner = p.slice(p.indexOf('(') + 1, -1);\n if (!/\\s/.test(inner)) return inner;\n return `:is(${inner})`;\n }\n return p;\n }\n\n return null;\n}\n\n/**\n * De Morgan recombination for an OR whose every branch is a negated\n * own-element selector leaf:\n *\n * OR(¬a, ¬b, ¬c) ≡ ¬(a ∧ b ∧ c) → single `:not(a b c)`\n *\n * This keeps the catch-all/default exclusive condition (which has no\n * positive terms to prune against) from exploding into a Cartesian product\n * of OR branches at `andToCSS`. Returns `null` when recombination does not\n * apply, so genuine unions (e.g. `:hover | :focus`) fall through to the\n * normal per-branch materialization.\n */\nfunction tryRecombineNegatedSelectorOr(\n children: ConditionNode[],\n): CSSComponents | null {\n if (children.length < 2) return null;\n\n const positiveSelectors: string[] = [];\n for (const child of children) {\n const sel = negatedSelectorLeafToPositiveSelector(child);\n if (sel === null) return null;\n positiveSelectors.push(sel);\n }\n\n // Stable ordering for deterministic hashing/dedupe.\n positiveSelectors.sort();\n const compound = positiveSelectors.join('');\n\n const v = emptyVariant();\n v.pseudoConditions.push({ pseudo: `:is(${compound})`, negated: true });\n return { variants: [v], isImpossible: false };\n}\n\nfunction orToCSS(children: ConditionNode[]): CSSComponents {\n // De Morgan recombination: OR(¬a, ¬b, ...) → single :not(a b ...).\n const recombined = tryRecombineNegatedSelectorOr(children);\n if (recombined !== null) {\n return recombined;\n }\n\n const allVariants: SelectorVariant[] = [];\n\n for (const child of children) {\n const childCSS = conditionToCSSInner(child);\n if (childCSS.isImpossible) continue;\n\n allVariants.push(...childCSS.variants);\n }\n\n if (allVariants.length === 0) {\n return { variants: [], isImpossible: true };\n }\n\n return {\n variants: dedupeVariants(allVariants),\n isImpossible: false,\n };\n}\n\n// ============================================================================\n// OR → :is() Merging\n// ============================================================================\n\n/**\n * Find keys present in ALL condition arrays.\n */\nfunction findCommonKeys<T>(\n conditionSets: T[][],\n getKey: (item: T) => string,\n): Set<string> {\n if (conditionSets.length === 0) return new Set();\n\n const common = new Set(conditionSets[0].map(getKey));\n for (let i = 1; i < conditionSets.length; i++) {\n const keys = new Set(conditionSets[i].map(getKey));\n for (const key of common) {\n if (!keys.has(key)) common.delete(key);\n }\n }\n return common;\n}\n\n/**\n * Merge OR variants that share the same \"context\" (at-rules, root, parent,\n * own, starting) into a single variant with a SelectorGroup.\n *\n * Variants with no modifier/pseudo conditions are kept separate (they match\n * unconditionally and can't be expressed inside :is()).\n */\nexport function mergeVariantsIntoSelectorGroups(\n variants: SelectorVariant[],\n): SelectorVariant[] {\n if (variants.length <= 1) return variants;\n\n // Group variants by their context (everything except flat modifier/pseudo)\n const groups = new Map<string, SelectorVariant[]>();\n for (const v of variants) {\n const key = getVariantContextKey(v);\n const group = groups.get(key);\n if (group) group.push(v);\n else groups.set(key, [v]);\n }\n\n const result: SelectorVariant[] = [];\n for (const group of groups.values()) {\n if (group.length === 1) {\n result.push(group[0]);\n continue;\n }\n\n // Separate variants with no selector conditions (can't merge into :is())\n const withSelectors: SelectorVariant[] = [];\n const withoutSelectors: SelectorVariant[] = [];\n for (const v of group) {\n if (\n v.modifierConditions.length === 0 &&\n v.pseudoConditions.length === 0\n ) {\n withoutSelectors.push(v);\n } else {\n withSelectors.push(v);\n }\n }\n\n result.push(...withoutSelectors);\n\n if (withSelectors.length <= 1) {\n result.push(...withSelectors);\n continue;\n }\n\n // Factor out common conditions and create a SelectorGroup\n result.push(factorAndGroup(withSelectors));\n }\n\n return result;\n}\n\n/**\n * Factor common modifier/pseudo conditions out of variants and create\n * a single variant with a SelectorGroup for the remaining (differing)\n * conditions.\n *\n * Precondition: all variants must share the same context key (identical\n * at-rules, root/parent/own/selector groups, startingStyle).\n */\nfunction factorAndGroup(variants: SelectorVariant[]): SelectorVariant {\n if (process.env.NODE_ENV !== 'production') {\n const key0 = getVariantContextKey(variants[0]);\n for (let i = 1; i < variants.length; i++) {\n const keyI = getVariantContextKey(variants[i]);\n if (keyI !== key0) {\n throw new Error(\n `factorAndGroup: context key mismatch at index ${i}.\\n` +\n ` expected: ${key0}\\n got: ${keyI}`,\n );\n }\n }\n }\n\n // Find common modifier and pseudo keys across ALL variants\n const commonModKeys = findCommonKeys(\n variants.map((v) => v.modifierConditions),\n getModifierKey,\n );\n const commonPseudoKeys = findCommonKeys(\n variants.map((v) => v.pseudoConditions),\n getPseudoKey,\n );\n\n // Extract common conditions from first variant\n const commonModifiers = variants[0].modifierConditions.filter((m) =>\n commonModKeys.has(getModifierKey(m)),\n );\n const commonPseudos = variants[0].pseudoConditions.filter((p) =>\n commonPseudoKeys.has(getPseudoKey(p)),\n );\n\n // Build branches from remaining (non-common) conditions.\n // If any variant has only common conditions (empty branch), it matches\n // unconditionally within this context — the :is() group would lose it.\n // In that case, return the broadest variant (common conditions only).\n const branches: ParsedSelectorCondition[][] = [];\n let hasEmptyBranch = false;\n for (const v of variants) {\n const branch: ParsedSelectorCondition[] = [];\n for (const mod of v.modifierConditions) {\n if (!commonModKeys.has(getModifierKey(mod))) branch.push(mod);\n }\n for (const pseudo of v.pseudoConditions) {\n if (!commonPseudoKeys.has(getPseudoKey(pseudo))) branch.push(pseudo);\n }\n if (branch.length > 0) {\n branches.push(branch);\n } else {\n hasEmptyBranch = true;\n }\n }\n\n // If a variant has only common conditions, it's the broadest match —\n // the :is() group with specific branches is subsumed by it.\n // Return the variant with common conditions only.\n if (hasEmptyBranch) {\n return {\n ...variants[0],\n modifierConditions: commonModifiers,\n pseudoConditions: commonPseudos,\n };\n }\n\n // Try to factor branches into independent :is() groups per attribute\n // e.g. 4 branches for 2 attrs × 2 values → two :is() groups of 2\n const factoredGroups = tryFactorIntoDimensions(branches);\n if (factoredGroups) {\n return {\n modifierConditions: commonModifiers,\n pseudoConditions: commonPseudos,\n selectorGroups: [...variants[0].selectorGroups, ...factoredGroups],\n ownGroups: [...variants[0].ownGroups],\n mediaConditions: [...variants[0].mediaConditions],\n containerConditions: [...variants[0].containerConditions],\n supportsConditions: [...variants[0].supportsConditions],\n rootGroups: [...variants[0].rootGroups],\n parentGroups: [...variants[0].parentGroups],\n startingStyle: variants[0].startingStyle,\n };\n }\n\n return {\n modifierConditions: commonModifiers,\n pseudoConditions: commonPseudos,\n selectorGroups: [\n ...variants[0].selectorGroups,\n { branches, negated: false },\n ],\n ownGroups: [...variants[0].ownGroups],\n mediaConditions: [...variants[0].mediaConditions],\n containerConditions: [...variants[0].containerConditions],\n supportsConditions: [...variants[0].supportsConditions],\n rootGroups: [...variants[0].rootGroups],\n parentGroups: [...variants[0].parentGroups],\n startingStyle: variants[0].startingStyle,\n };\n}\n\n/**\n * Detect when branches form a complete Cartesian product of independent\n * modifier attribute dimensions and return one SelectorGroup per dimension.\n *\n * Example: 4 branches for 2 attributes × 2 values each →\n * :is(A1, A2):is(B1, B2) instead of :is(A1B1, A1B2, A2B1, A2B2)\n */\nfunction tryFactorIntoDimensions(\n branches: ParsedSelectorCondition[][],\n): SelectorGroup[] | null {\n if (branches.length < 4) return null;\n\n // Only factor modifier-only branches\n const dimensions = new Map<string, Map<string, ParsedModifierCondition>>();\n for (const branch of branches) {\n for (const cond of branch) {\n if (!('attribute' in cond)) return null;\n if (!dimensions.has(cond.attribute)) {\n dimensions.set(cond.attribute, new Map());\n }\n dimensions.get(cond.attribute)!.set(getModifierKey(cond), cond);\n }\n }\n\n if (dimensions.size < 2) return null;\n\n // Each branch must have exactly one condition per dimension\n for (const branch of branches) {\n const seen = new Set<string>();\n for (const cond of branch) {\n const attr = (cond as ParsedModifierCondition).attribute;\n if (seen.has(attr)) return null;\n seen.add(attr);\n }\n if (seen.size !== dimensions.size) return null;\n }\n\n // Branch count must equal product of dimension sizes (complete product)\n let expectedCount = 1;\n for (const vals of dimensions.values()) {\n expectedCount *= vals.size;\n }\n if (branches.length !== expectedCount) return null;\n\n return [...dimensions.values()].map((vals) => ({\n branches: [...vals.values()].map((cond) => [\n cond as ParsedSelectorCondition,\n ]),\n negated: false,\n }));\n}\n\n// ============================================================================\n// Utility Functions\n// ============================================================================\n\n/**\n * Build at-rules array from a variant\n */\nexport function buildAtRulesFromVariant(variant: SelectorVariant): string[] {\n const atRules: string[] = [];\n\n // Add media rules - combine all conditions with \"and\"\n if (variant.mediaConditions.length > 0) {\n const conditionParts = variant.mediaConditions.map((c) => {\n if (c.subtype === 'type') {\n // Media type: print, screen, etc.\n return c.negated ? `not ${c.condition}` : c.condition;\n } else {\n // Feature or dimension: use not (condition) syntax for negation\n // MQ Level 4 requires parentheses around the condition for negation\n return c.negated ? `(not ${c.condition})` : c.condition;\n }\n });\n atRules.push(`@media ${conditionParts.sort().join(' and ')}`);\n }\n\n // Add container rules - group by container name and combine with \"and\"\n if (variant.containerConditions.length > 0) {\n // Group conditions by container name (undefined = unnamed/nearest)\n const byName = new Map<string | undefined, ParsedContainerCondition[]>();\n for (const cond of variant.containerConditions) {\n const group = byName.get(cond.name) || [];\n group.push(cond);\n byName.set(cond.name, group);\n }\n\n // Build one @container rule per container name\n for (const [name, conditions] of byName) {\n // CSS Container Query syntax requires parentheses around negated conditions:\n // @container (not style(--x)) and style(--y) - NOT @container not style(--x) and style(--y)\n const conditionParts = conditions.map((c) =>\n c.negated ? `(not ${c.condition})` : c.condition,\n );\n const namePrefix = name ? `${name} ` : '';\n atRules.push(`@container ${namePrefix}${conditionParts.join(' and ')}`);\n }\n }\n\n // Add supports rules - combine all conditions with \"and\"\n if (variant.supportsConditions.length > 0) {\n const conditionParts = variant.supportsConditions.map((c) => {\n // Build the condition based on subtype\n // feature: (display: grid) or (not (display: grid))\n // selector: selector(:has(*)) or (not selector(:has(*)))\n if (c.subtype === 'selector') {\n const selectorCond = `selector(${c.condition})`;\n return c.negated ? `(not ${selectorCond})` : selectorCond;\n } else {\n const featureCond = `(${c.condition})`;\n return c.negated ? `(not ${featureCond})` : featureCond;\n }\n });\n atRules.push(`@supports ${conditionParts.join(' and ')}`);\n }\n\n return atRules;\n}\n","/**\n * Structured warning system for the pipeline.\n *\n * Provides typed warning codes and a configurable handler so consumers\n * can programmatically intercept, suppress, or reroute warnings.\n */\n\ntype TastyWarningCode =\n | 'INVALID_SELECTOR_AFFIX'\n | 'XOR_CHAIN_TOO_LONG'\n | 'INTERNAL_PSEUDO_USED'\n | 'INVALID_TOP_LEVEL_PSEUDO_KEY'\n | 'INVALID_FALLBACK_KEY'\n | 'MISPLACED_DEFAULT_STATE'\n | 'REDUNDANT_DEFAULT_STATE'\n | 'HANDLER_CAMEL_CASE_KEY';\n\ninterface TastyWarning {\n code: TastyWarningCode;\n message: string;\n}\n\ntype TastyWarningHandler = (warning: TastyWarning) => void;\n\nconst defaultWarningHandler: TastyWarningHandler = (warning) => {\n // Diagnostic only — stripped from production builds. A custom handler\n // installed via `setWarningHandler` still receives every warning in\n // production, since `emitWarning` itself stays unconditional.\n if (process.env.NODE_ENV !== 'production') {\n console.warn(`[Tasty] ${warning.message}`);\n }\n};\n\nlet warningHandler: TastyWarningHandler = defaultWarningHandler;\n\n/**\n * Set a custom warning handler for pipeline warnings.\n * Returns a function that restores the previous handler.\n */\nexport function setWarningHandler(handler: TastyWarningHandler): () => void {\n const previous = warningHandler;\n warningHandler = handler;\n return () => {\n warningHandler = previous;\n };\n}\n\n/**\n * Emit a structured pipeline warning via the configured handler.\n */\nexport function emitWarning(code: TastyWarningCode, message: string): void {\n warningHandler({ code, message });\n}\n","/**\n * Exclusive Condition Builder\n *\n * Transforms parsed style entries into exclusive conditions.\n * Each entry's condition is ANDed with the negation of all higher-priority conditions,\n * ensuring exactly one condition matches at any given time.\n */\n\nimport type { StyleValue } from '../utils/styles';\n\nimport type { ConditionNode } from './conditions';\nimport { and, isCompoundCondition, not, or, trueCondition } from './conditions';\nimport { branchesProduceDifferentContexts } from './materialize';\nimport { simplifyCondition } from './simplify';\nimport { emitWarning } from './warnings';\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Parsed style entry with condition\n */\ninterface ParsedStyleEntry {\n styleKey: string; // e.g., 'padding', 'fill'\n stateKey: string; // Original key: '', 'compact', '@media(w < 768px)'\n value: StyleValue; // The style value (before handler processing)\n condition: ConditionNode; // Parsed condition tree\n priority: number; // Order in original object (higher = higher priority)\n /**\n * When true (set by the standalone `_` key), this entry is a map-wide\n * fallback floor. It always applies (its condition is `TRUE`), opts out\n * of RECEIVING negation from higher-priority entries, and never negates\n * lower-priority entries. It is pulled out of the negation cascade and\n * handled separately. See `buildExclusiveConditions`.\n */\n floor?: boolean;\n}\n\n/**\n * Style entry with exclusive condition\n */\nexport interface ExclusiveStyleEntry extends ParsedStyleEntry {\n exclusiveCondition: ConditionNode; // condition & !higherPriorityConditions\n}\n\n// ============================================================================\n// Main Function\n// ============================================================================\n\n/**\n * Build exclusive conditions for a list of parsed style entries.\n *\n * The entries should be ordered by priority (highest priority first).\n *\n * For each entry, we compute:\n * exclusiveCondition = condition & !prior[0] & !prior[1] & ...\n *\n * This ensures exactly one condition matches at any time.\n *\n * Example:\n * Input (ordered highest to lowest priority):\n * A: value1 (priority 2)\n * B: value2 (priority 1)\n * C: value3 (priority 0)\n *\n * Output:\n * A: A\n * B: B & !A\n * C: C & !A & !B\n *\n * @param entries Parsed style entries ordered by priority (highest first)\n * @returns Entries with exclusive conditions, filtered to remove impossible ones\n */\nexport function buildExclusiveConditions(\n entries: ParsedStyleEntry[],\n): ExclusiveStyleEntry[] {\n const result: ExclusiveStyleEntry[] = [];\n const priorConditions: ConditionNode[] = [];\n\n // Pull the `_` fallback floor out of the negation cascade entirely. It\n // always applies (TRUE condition), never receives negation, and never\n // negates lower-priority entries — so the remaining entries can be built\n // with a plain, unconditional negation pass. The floor is re-appended\n // afterward with its TRUE exclusive condition.\n const floors: ParsedStyleEntry[] = [];\n\n for (const entry of entries) {\n if (entry.floor) {\n floors.push(entry);\n continue;\n }\n\n // Build: condition & !prior[0] & !prior[1] & ...\n let exclusive: ConditionNode = entry.condition;\n\n for (const prior of priorConditions) {\n // Skip negating \"always true\" (default state) - it would become \"always false\"\n if (prior.kind === 'true') {\n continue;\n }\n\n // Cheap mutual-exclusivity pre-check: if this entry's own condition\n // already contradicts `prior` (e.g. `[theme=purple]` vs a prior\n // `[theme=green] & ...`), then `prior` can never match when this entry\n // does, so `!prior` is always true here and adds nothing. Skipping it\n // avoids De Morgan'ing `prior` into a wide OR of negations that would\n // otherwise feed an exponential Cartesian product at materialization.\n //\n // This only fires when the contradiction is structurally provable via\n // `simplifyCondition` (memoized, operates on the small pairwise AND).\n // The default entry (no positive terms) is unaffected and keeps its\n // full negation chain, which `orToCSS` recombines into compact :not().\n if (\n entry.condition.kind !== 'true' &&\n simplifyCondition(and(entry.condition, prior)).kind === 'false'\n ) {\n continue;\n }\n\n exclusive = and(exclusive, not(prior));\n }\n\n // Simplify the exclusive condition\n const simplified = simplifyCondition(exclusive);\n\n // Skip impossible conditions (simplified to FALSE)\n if (simplified.kind === 'false') {\n continue;\n }\n\n result.push({\n ...entry,\n exclusiveCondition: simplified,\n });\n\n // Add non-default conditions to prior list for subsequent entries\n if (entry.condition.kind !== 'true') {\n priorConditions.push(entry.condition);\n }\n }\n\n // Re-append the fallback floor(s). Their exclusive condition is just their\n // own (TRUE) condition: always active, never negated.\n for (const floor of floors) {\n result.push({\n ...floor,\n exclusiveCondition: floor.condition,\n });\n }\n\n return result;\n}\n\n/**\n * Parse style entries from a value mapping object.\n *\n * @param styleKey The style key (e.g., 'padding')\n * @param valueMap The value mapping { '': '2x', 'compact': '1x', '@media(w < 768px)': '0.5x' }\n * @param parseCondition Function to parse state keys into conditions\n * @returns Parsed entries ordered by priority (highest first)\n */\nexport function parseStyleEntries(\n styleKey: string,\n valueMap: Record<string, StyleValue>,\n parseCondition: (stateKey: string) => ConditionNode,\n): ParsedStyleEntry[] {\n const entries: ParsedStyleEntry[] = [];\n let floorEntry: ParsedStyleEntry | null = null;\n const keys = Object.keys(valueMap);\n\n keys.forEach((stateKey) => {\n const value = valueMap[stateKey];\n\n // The standalone `_` key is the map-wide fallback floor. It must be used\n // on its own — it cannot be combined with state logic (`_ & hovered`,\n // `_ | x`). A misused `_` is warned about and ignored.\n if (stateKey === '_') {\n floorEntry = {\n styleKey,\n stateKey,\n value,\n condition: trueCondition(),\n priority: 0,\n floor: true,\n };\n return;\n }\n\n if (isMisusedFallbackKey(stateKey)) {\n emitWarning(\n 'INVALID_FALLBACK_KEY',\n `Style key \"${stateKey}\" (in \"${styleKey}\") combines the fallback \"_\" with ` +\n `other state logic. \"_\" can only be used on its own as a map-wide ` +\n `fallback floor. The key has been ignored.`,\n );\n return;\n }\n\n const condition =\n stateKey === '' ? trueCondition() : parseCondition(stateKey);\n\n entries.push({\n styleKey,\n stateKey,\n value,\n condition,\n priority: 0,\n });\n });\n\n // A floor combined only with a bare `\"\"` default (and no other states) is\n // redundant: the `\"\"` default would always be superseded by the floor, so\n // only the floor's value matters. Drop the `\"\"` default and warn.\n if (floorEntry !== null) {\n const hasOtherStates = entries.some((e) => e.condition.kind !== 'true');\n const hasDefault = entries.some((e) => e.condition.kind === 'true');\n if (!hasOtherStates && hasDefault) {\n emitWarning(\n 'REDUNDANT_DEFAULT_STATE',\n `Style \"${styleKey}\" defines both a \"_\" fallback and a \"\" default with no ` +\n `other states. The \"\" default is redundant (always superseded by \"_\"); ` +\n `the \"_\" value is used and the \"\" default is ignored.`,\n );\n // Only the floor remains; drop the redundant bare default.\n entries.length = 0;\n }\n }\n\n const normalized = normalizeDefaultStates(entries, styleKey);\n\n // Assign contiguous priorities: the fallback floor is always lowest\n // priority (0) so it sits first in the cascade (emitted before the states\n // that layer over it); the remaining entries follow in authored order.\n const ordered =\n floorEntry !== null ? [floorEntry, ...normalized] : normalized;\n ordered.forEach((entry, index) => {\n entry.priority = index;\n });\n\n // Reverse so highest priority (last in object) comes first for exclusive building\n // buildExclusiveConditions expects highest priority first\n ordered.reverse();\n\n return ordered;\n}\n\n/**\n * Detect a misused standalone `_` fallback key: a key that is not exactly\n * `_` but contains `_` as a standalone atom among state-logic operators\n * (`&`, `|`, `^`, `,`) or grouping parens. A `_` embedded in a longer token\n * (e.g. a modifier named `_private`) is not a misuse.\n */\nfunction isMisusedFallbackKey(stateKey: string): boolean {\n if (stateKey === '_' || !stateKey.includes('_')) return false;\n return /(?:^|[\\s&|^,(])_(?:[\\s&|^,)]|$)/.test(stateKey);\n}\n\n/**\n * Resolve the bare `''` default state (`condition.kind === 'true'`) in a\n * style value map.\n *\n * The bare default only behaves correctly as the **first** (lowest-priority)\n * key. When it appears later, `buildExclusiveConditions` processes it first\n * (after the reverse), never adds it to the prior list, and never negates it\n * — so it silently overrides every state authored before it.\n *\n * This function, given entries in authored order, moves a misplaced bare\n * default to the front (lowest priority), preserving the relative order of\n * all other entries, and emits a `MISPLACED_DEFAULT_STATE` warning.\n *\n * The `_` fallback floor is pulled out before this runs (see\n * `parseStyleEntries`), so only the bare `''` default is considered here.\n */\nfunction normalizeDefaultStates(\n entries: ParsedStyleEntry[],\n styleKey: string,\n): ParsedStyleEntry[] {\n const defaultPos = entries.findIndex((e) => e.condition.kind === 'true');\n\n // No bare default, or already first: nothing to do (the common case).\n if (defaultPos <= 0) {\n return entries;\n }\n\n const defaultEntry = entries[defaultPos];\n emitWarning(\n 'MISPLACED_DEFAULT_STATE',\n `Style \"${styleKey}\" defines the default state \"${defaultEntry.stateKey}\" ` +\n `after other states. A bare default (\"\") must be the first key, ` +\n `otherwise it overrides the states above it. It has been moved to the ` +\n `first position. Define default states first.`,\n );\n\n return [\n defaultEntry,\n ...entries.slice(0, defaultPos),\n ...entries.slice(defaultPos + 1),\n ];\n}\n\n/**\n * Merge parsed entries that share the same value.\n *\n * When multiple **non-default** state keys map to the same value, their\n * conditions can be combined with OR and treated as a single entry.\n * This must happen **before** exclusive expansion and OR branch splitting\n * to avoid combinatorial explosion and duplicate CSS output.\n *\n * **Merging must preserve the authored cascade.** Merging two same-value\n * entries with priorities `p_h > p_l` lifts the lower-priority entry up\n * to `p_h` and changes the \"blocker\" for intermediate-priority entries\n * from `!C_h` to `!(C_h | C_l) = !C_h & !C_l`. The added `!C_l`\n * constraint can incorrectly block an intermediate entry that should\n * have won.\n *\n * Two same-value entries with conditions `C_h` (higher priority) and\n * `C_l` (lower priority) are safe to merge iff for every entry\n * `e_m` strictly between them in priority with a different value,\n *\n * simplify(C_m & C_l & !C_h) = FALSE\n *\n * i.e. there is no scenario where the intermediate state could have\n * matched (`C_m`), the lower-priority same-value entry would also have\n * matched (`C_l`), and the higher-priority entry would not (`!C_h`).\n * In such scenarios the intermediate is supposed to win; the merge\n * would block it by introducing `!C_l`.\n *\n * Example (UNSAFE — must not merge):\n * `{ hovered: 'red', pressed: 'blue', disabled: 'red' }`.\n * C_h = disabled, C_l = hovered, C_m = pressed. `pressed & hovered &\n * !disabled` is satisfiable (three independent modifiers), so the\n * intermediate `pressed` would lose to a merged red rule when both\n * `pressed` and `hovered` are active — breaking the cascade\n * `disabled > pressed > hovered`.\n *\n * Example (SAFE — still merges):\n * `{ '': light, '@dark': dark, '@hc': hc, '@dark & @hc': dark }`.\n * C_h = `@dark & @hc`, C_l = `@dark`, C_m = `@hc`.\n * `@hc & @dark & !(@dark & @hc) = @hc & @dark & (!@dark | !@hc)`\n * simplifies to FALSE, so merging the two darks into one `@dark` rule\n * at the higher priority does not affect the `@hc` rule.\n *\n * Default (TRUE) entries are never merged with non-default entries.\n * Merging `TRUE | X` collapses to `TRUE`, destroying the non-default\n * condition's participation in exclusive building. Stage 6\n * `mergeByValue` handles combining rules with identical CSS output\n * after exclusive conditions are correctly built.\n *\n * The merged entry keeps the highest priority of the merged entries.\n */\nexport function mergeEntriesByValue(\n entries: ParsedStyleEntry[],\n): ParsedStyleEntry[] {\n if (entries.length <= 1) return entries;\n\n const merged: ParsedStyleEntry[] = [];\n\n for (const entry of entries) {\n // Defaults are never merged with non-defaults. The `_` fallback floor\n // has a `TRUE` condition, so this same guard excludes it from merging;\n // it participates in Stage 6 `mergeByValue` later instead.\n if (entry.condition.kind === 'true') {\n merged.push(entry);\n continue;\n }\n\n const valueKey = serializeValue(entry.value);\n let mergeIdx = -1;\n\n // Find the most recent merged entry with the same value such that\n // merging is provably safe with respect to every different-value\n // entry strictly between them in priority order.\n for (let j = merged.length - 1; j >= 0; j--) {\n const prev = merged[j];\n if (prev.condition.kind === 'true') continue;\n if (serializeValue(prev.value) !== valueKey) continue;\n\n let safe = true;\n for (let k = j + 1; k < merged.length; k++) {\n const inter = merged[k];\n if (inter.condition.kind === 'true') continue;\n if (serializeValue(inter.value) === valueKey) continue;\n\n // Safety: simplify(C_m & C_l & !C_h) must be FALSE.\n // C_h = prev.condition, C_l = entry.condition, C_m = inter.condition.\n const conflict = simplifyCondition(\n and(inter.condition, entry.condition, not(prev.condition)),\n );\n if (conflict.kind !== 'false') {\n safe = false;\n break;\n }\n }\n\n if (safe) {\n mergeIdx = j;\n break;\n }\n }\n\n if (mergeIdx >= 0) {\n const prev = merged[mergeIdx];\n const newCondition = simplifyCondition(\n or(prev.condition, entry.condition),\n );\n // `prev` was processed before `entry`, so its priority is always\n // greater or equal. Keep `Math.max` for clarity of intent.\n merged[mergeIdx] = {\n styleKey: prev.styleKey,\n stateKey: `${prev.stateKey} | ${entry.stateKey}`,\n value: prev.value,\n condition: newCondition,\n priority: Math.max(prev.priority, entry.priority),\n };\n } else {\n merged.push(entry);\n }\n }\n\n // `merged` is already highest-priority-first by construction: input\n // entries arrive in that order, merges update an entry in place\n // without changing its priority, and no insert/delete reorders the\n // array.\n return merged;\n}\n\nfunction serializeValue(value: StyleValue): string {\n if (value === null || value === undefined) return 'null';\n if (typeof value === 'string' || typeof value === 'number') {\n return String(value);\n }\n return JSON.stringify(value);\n}\n\n// ============================================================================\n// Compound State Extraction\n// ============================================================================\n\n/**\n * Eliminate redundant state dimensions from a value map.\n *\n * When a value map contains compound AND state keys (e.g. `@dark & @hc`),\n * checks whether any state atom is a \"don't-care\" variable — i.e. the\n * value is the same whether that atom is present or absent. Redundant\n * atoms are removed from all keys and duplicate entries are collapsed.\n *\n * This runs **before** condition parsing so that downstream stages\n * (`mergeEntriesByValue`, `buildExclusiveConditions`, materialization)\n * never see the irrelevant dimension, producing simpler, smaller CSS.\n *\n * Only pure top-level AND combinations are eligible. Keys that contain\n * `|`, `^`, or `,` at the top level are treated as opaque single atoms.\n *\n * @example\n * { '': A, '@dark': B, '@hc': A, '@dark & @hc': B }\n * // @hc is redundant → { '': A, '@dark': B }\n */\nexport function extractCompoundStates(\n valueMap: Record<string, StyleValue>,\n): Record<string, StyleValue> {\n const keys = Object.keys(valueMap);\n\n if (keys.length < 3 || !keys.some((k) => k.includes('&'))) {\n return valueMap;\n }\n\n const entries = keys.map((key) => {\n const atoms = splitTopLevelAnd(key);\n // Keys containing the `_` fallback floor must stay opaque so `_` is never\n // dropped as a \"redundant atom\" or collapsed into the `\"\"` default.\n // (`_` is handled later in parseStyleEntries.)\n const isOpaque = atoms === null || atoms.includes('_');\n return {\n // null means the key has non-AND operators; treat the whole key\n // as a single opaque atom so it never matches partial pairs.\n atoms: isOpaque ? [key] : (atoms as string[]),\n value: valueMap[key],\n };\n });\n\n const allAtoms = new Set<string>();\n for (const e of entries) {\n for (const a of e.atoms) allAtoms.add(a);\n }\n\n const redundant = new Set<string>();\n for (const atom of allAtoms) {\n if (isAtomRedundant(entries, atom)) {\n redundant.add(atom);\n }\n }\n\n if (redundant.size === 0) return valueMap;\n\n const newMap: Record<string, StyleValue> = {};\n for (const e of entries) {\n const filtered = e.atoms.filter((a) => !redundant.has(a));\n const newKey = filtered.join(' & ');\n if (!(newKey in newMap)) {\n newMap[newKey] = e.value;\n }\n }\n\n return newMap;\n}\n\n/**\n * Split a state key by top-level `&` operators.\n *\n * Returns `null` if the key contains `|`, `^`, or `,` at the top level\n * (making it ineligible for atom-level extraction).\n * Returns `[]` for the empty string (default key).\n */\nfunction splitTopLevelAnd(key: string): string[] | null {\n if (key === '') return [];\n\n const parts: string[] = [];\n let depth = 0;\n let current = '';\n\n for (const ch of key) {\n if (ch === '(' || ch === '[') depth++;\n else if (ch === ')' || ch === ']') depth--;\n\n if (depth === 0) {\n if (ch === '&') {\n const trimmed = current.trim();\n if (trimmed) parts.push(trimmed);\n current = '';\n continue;\n }\n if (ch === '|' || ch === '^' || ch === ',') {\n return null;\n }\n }\n\n current += ch;\n }\n\n const trimmed = current.trim();\n if (trimmed) parts.push(trimmed);\n\n return parts;\n}\n\n/**\n * An atom is redundant when every entry that contains it has a matching\n * partner (same remaining atoms, atom absent) with the same value.\n */\nfunction isAtomRedundant(\n entries: { atoms: string[]; value: StyleValue }[],\n atom: string,\n): boolean {\n const withAtom = entries.filter((e) => e.atoms.includes(atom));\n if (withAtom.length === 0) return false;\n\n for (const wa of withAtom) {\n const remaining = wa.atoms.filter((a) => a !== atom);\n\n const pair = entries.find(\n (e) =>\n !e.atoms.includes(atom) &&\n e.atoms.length === remaining.length &&\n remaining.every((r) => e.atoms.includes(r)),\n );\n\n if (!pair) return false;\n if (serializeValue(wa.value) !== serializeValue(pair.value)) return false;\n }\n\n return true;\n}\n\n/**\n * Check if a value is a style value mapping (object with state keys)\n */\nexport function isValueMapping(\n value: StyleValue | Record<string, StyleValue>,\n): value is Record<string, StyleValue> {\n return (\n value !== null &&\n typeof value === 'object' &&\n !Array.isArray(value) &&\n !(value instanceof Date)\n );\n}\n\n// ============================================================================\n// OR Expansion\n// ============================================================================\n\n/**\n * Expand OR conditions in parsed entries into multiple exclusive entries.\n *\n * For an entry with condition `A | B | C`, this creates 3 entries:\n * - condition: A\n * - condition: B & !A\n * - condition: C & !A & !B\n *\n * This ensures OR branches are mutually exclusive BEFORE the main\n * exclusive condition building pass.\n *\n * @param entries Parsed entries (may contain OR conditions)\n * @returns Expanded entries with OR branches made exclusive\n */\nexport function expandOrConditions(\n entries: ParsedStyleEntry[],\n): ParsedStyleEntry[] {\n const result: ParsedStyleEntry[] = [];\n\n for (const entry of entries) {\n const expanded = expandSingleEntry(entry);\n result.push(...expanded);\n }\n\n return result;\n}\n\n/**\n * Expand a single entry's OR condition into multiple exclusive entries.\n *\n * Note: branches are NOT sorted by at-rule context here (unlike the\n * `expandExclusiveOrs` pass below). User-authored ORs in state keys aren't\n * the product of De Morgan negation, so each branch is expected to render\n * independently in its own scope and at-rule sort isn't load-bearing.\n * The post-build pass needs the sort because it has to preserve at-rule\n * wrapping across branches that came from negating a compound at-rule.\n *\n * Skip optimisation: when every branch renders into the same at-rule /\n * root / parent / own context (see \"Key Design Decision #2\" in\n * `docs/pipeline.md`), forcing mutual exclusivity here produces dead\n * `B & !A`-style branches that materialization later folds back into\n * `:is(A, B)`. Bail out and let `materialize.ts` collapse the OR via\n * `mergeVariantsIntoSelectorGroups`. Cross-entry exclusivity is still\n * enforced by `buildExclusiveConditions`; the post-build `expandExclusiveOrs`\n * pass still handles De Morgan ORs whose branches actually differ in\n * context.\n */\nfunction expandSingleEntry(entry: ParsedStyleEntry): ParsedStyleEntry[] {\n const orBranches = collectOrBranches(entry.condition);\n\n // If no OR (single branch), return as-is\n if (orBranches.length <= 1) {\n return [entry];\n }\n\n // Skip OR expansion when all branches share the same at-rule context.\n // Pure-selector ORs (e.g. `:hover | :focus`,\n // `:-webkit-autofill | :autofill`) are better merged into `:is(...)` at\n // materialization than expanded into mutually-exclusive cascades.\n if (!branchesProduceDifferentContexts(orBranches)) {\n return [entry];\n }\n\n // Make each OR branch exclusive from prior branches\n const result: ParsedStyleEntry[] = [];\n const priorBranches: ConditionNode[] = [];\n\n for (let i = 0; i < orBranches.length; i++) {\n const branch = orBranches[i];\n\n // Build: branch & !prior[0] & !prior[1] & ...\n let exclusiveBranch: ConditionNode = branch;\n for (const prior of priorBranches) {\n exclusiveBranch = and(exclusiveBranch, not(prior));\n }\n\n // Simplify to detect impossible combinations\n const simplified = simplifyCondition(exclusiveBranch);\n\n // Skip impossible branches\n if (simplified.kind === 'false') {\n priorBranches.push(branch);\n continue;\n }\n\n result.push({\n ...entry,\n stateKey: `${entry.stateKey}[${i}]`, // Mark as expanded branch\n condition: simplified,\n // Keep same priority - all branches from same entry have same priority\n });\n\n priorBranches.push(branch);\n }\n\n return result;\n}\n\n/**\n * Collect top-level OR branches from a condition.\n *\n * For `A | B | C`, returns [A, B, C]\n * For `A & B`, returns [A & B] (single branch)\n * For `A | (B & C)`, returns [A, B & C]\n */\nfunction collectOrBranches(condition: ConditionNode): ConditionNode[] {\n if (condition.kind === 'true' || condition.kind === 'false') {\n return [condition];\n }\n\n if (isCompoundCondition(condition) && condition.operator === 'OR') {\n // Flatten nested ORs\n const branches: ConditionNode[] = [];\n for (const child of condition.children) {\n branches.push(...collectOrBranches(child));\n }\n return branches;\n }\n\n // Not an OR - return as single branch\n return [condition];\n}\n\n// ============================================================================\n// Post-Build OR Expansion (for De Morgan ORs)\n// ============================================================================\n\n/**\n * Expand OR conditions in exclusive entries AFTER buildExclusiveConditions.\n *\n * This handles ORs that arise from De Morgan expansion during negation:\n * !(A & B) = !A | !B\n *\n * These ORs need to be made exclusive to avoid overlapping CSS rules:\n * !A | !B → !A | (A & !B)\n *\n * This is logically equivalent but ensures each branch has proper context.\n *\n * Example:\n * Input: { \"\": V1, \"@supports(...) & :has()\": V2 }\n * V2's exclusive = @supports & :has\n * V1's exclusive = !(@supports & :has) = !@supports | !:has\n *\n * Without this fix: V1 gets two rules:\n * - @supports (not ...) → V1 ✓\n * - :not(:has()) → V1 ✗ (missing @supports context!)\n *\n * With this fix: V1 gets two exclusive rules:\n * - @supports (not ...) → V1 ✓\n * - @supports (...) { :not(:has()) } → V1 ✓ (proper context!)\n */\nexport function expandExclusiveOrs(\n entries: ExclusiveStyleEntry[],\n): ExclusiveStyleEntry[] {\n const result: ExclusiveStyleEntry[] = [];\n\n for (const entry of entries) {\n const expanded = expandExclusiveConditionOrs(entry);\n result.push(...expanded);\n }\n\n return result;\n}\n\n/**\n * Check if a condition involves at-rules (media, container, supports, starting)\n */\nfunction hasAtRuleContext(node: ConditionNode): boolean {\n if (node.kind === 'true' || node.kind === 'false') {\n return false;\n }\n\n if (node.kind === 'state') {\n // These condition types generate at-rules\n return (\n node.type === 'media' ||\n node.type === 'container' ||\n node.type === 'supports' ||\n node.type === 'starting'\n );\n }\n\n if (node.kind === 'compound') {\n return node.children.some(hasAtRuleContext);\n }\n\n return false;\n}\n\n/**\n * Check if a condition involves an `@supports` query.\n *\n * `@supports` is feature detection: anything ANDed with it (e.g. a\n * `@container scroll-state(...)` query that only exists when\n * `container-type: scroll-state` is supported) becomes *unknown* — not\n * simply false — when the feature is absent. So a negated supports branch\n * must be emitted first (as the bare \"feature unsupported\" fallback) and\n * every other negated branch must nest inside the supported scope.\n */\nfunction hasSupportsContext(node: ConditionNode): boolean {\n if (node.kind === 'state') {\n return node.type === 'supports';\n }\n\n if (node.kind === 'compound') {\n return node.children.some(hasSupportsContext);\n }\n\n return false;\n}\n\n/**\n * Rank an OR branch for exclusive expansion ordering. Lower rank is\n * processed first (becomes the more \"outer\" / less-constrained branch):\n * 0 — branch involves `@supports` (feature-detection guard)\n * 1 — branch involves another at-rule (media / container / starting)\n * 2 — branch is pure selector context (modifiers / pseudos)\n */\nfunction orBranchRank(node: ConditionNode): 0 | 1 | 2 {\n if (hasSupportsContext(node)) return 0;\n if (hasAtRuleContext(node)) return 1;\n return 2;\n}\n\n/**\n * Sort OR branches to prioritize at-rule conditions first, with\n * `@supports` branches ahead of all other at-rules.\n *\n * This is critical for correct CSS generation. For `!A | !B` where A is at-rule\n * and B is modifier, we want:\n * - Branch 0: !A (at-rule negation - covers \"no @supports/media\" case)\n * - Branch 1: A & !B (modifier negation with at-rule context)\n *\n * If we process in wrong order (!B first), we'd get:\n * - Branch 0: !B (modifier negation WITHOUT at-rule context - WRONG!)\n * - Branch 1: B & !A (at-rule negation with modifier - incomplete coverage)\n *\n * The extra `@supports`-first tier matters when a feature query guards a\n * dependent query. For `!(S & C) = !S | !C` (S = `@supports(...)`, C =\n * `@container scroll-state(...)`), `simplify` sorts the branches\n * alphabetically into `[!C, !S]`. Expanding in that order would emit `!C`\n * as a bare `@container (not scroll-state(...))` — meaningless where the\n * feature is unsupported, so the default would never apply there. Putting\n * `!S` first yields `!S | (S & !C)`: a bare supports fallback plus the\n * dependent negation nested in the supported scope.\n */\nfunction sortOrBranchesForExpansion(\n branches: ConditionNode[],\n): ConditionNode[] {\n return [...branches].sort((a, b) => orBranchRank(a) - orBranchRank(b));\n}\n\n/**\n * Expand ORs in a single entry's exclusive condition\n */\nfunction expandExclusiveConditionOrs(\n entry: ExclusiveStyleEntry,\n): ExclusiveStyleEntry[] {\n let orBranches = collectOrBranches(entry.exclusiveCondition);\n\n // If no OR (single branch), return as-is\n if (orBranches.length <= 1) {\n return [entry];\n }\n\n // Skip OR expansion when all branches share the same at-rule context.\n // De Morgan ORs across different at-rule scopes (e.g.\n // `!@supports | !:has`) still need exclusive splitting so each branch\n // ends up in the correct at-rule wrapper, but pure-selector ORs\n // (`:hover | :focus`, `:-webkit-autofill | :autofill`) collapse\n // cleanly via `:is(...)` at materialization. Matches the same\n // heuristic used by `makeOrBranchesExclusive` in `materialize.ts` and\n // by Stage 2a above.\n if (!branchesProduceDifferentContexts(orBranches)) {\n return [entry];\n }\n\n // Sort branches so at-rule conditions come first\n // This ensures proper context inheritance during expansion\n orBranches = sortOrBranchesForExpansion(orBranches);\n\n // Make each OR branch exclusive from prior branches\n const result: ExclusiveStyleEntry[] = [];\n const priorBranches: ConditionNode[] = [];\n\n for (let i = 0; i < orBranches.length; i++) {\n const branch = orBranches[i];\n\n // Build: branch & !prior[0] & !prior[1] & ...\n // This transforms: !A | !B → !A, !B & !!A = !A, (A & !B)\n let exclusiveBranch: ConditionNode = branch;\n for (const prior of priorBranches) {\n exclusiveBranch = and(exclusiveBranch, not(prior));\n }\n\n // Simplify to detect impossible combinations and clean up double negations\n const simplified = simplifyCondition(exclusiveBranch);\n\n // Skip impossible branches\n if (simplified.kind === 'false') {\n priorBranches.push(branch);\n continue;\n }\n\n result.push({\n ...entry,\n stateKey: `${entry.stateKey}[or:${i}]`, // Mark as expanded OR branch\n exclusiveCondition: simplified,\n });\n\n priorBranches.push(branch);\n }\n\n return result;\n}\n","export function camelToKebab(str: string): string {\n return str.replace(/([a-z0-9])([A-Z])/g, '$1-$2').toLowerCase();\n}\n","/**\n * Shared utility for transforming capitalized PascalCase element names\n * in CSS selector content to `[data-element=\"...\"]` attribute selectors.\n *\n * Lowercase words are treated as HTML tags and left unchanged.\n */\n\n/**\n * Matches a capitalized PascalCase word at the start of the string\n * or after a CSS combinator/separator character.\n */\nconst ELEMENT_NAME_RE = /(^|[\\s>+~,(])([A-Z][a-zA-Z0-9]*)/g;\n\n/**\n * Replace capitalized PascalCase words with `[data-element=\"Name\"]` selectors.\n *\n * @example\n * transformSelectorContent('> Field + input:checked')\n * // → '> [data-element=\"Field\"] + input:checked'\n *\n * transformSelectorContent('Body > Row')\n * // → '[data-element=\"Body\"] > [data-element=\"Row\"]'\n *\n * transformSelectorContent('button')\n * // → 'button' (lowercase = HTML tag, unchanged)\n */\nexport function transformSelectorContent(content: string): string {\n return content.replace(\n ELEMENT_NAME_RE,\n (_, prefix, name) => `${prefix}[data-element=\"${name}\"]`,\n );\n}\n","/**\n * State Key Parser\n *\n * Parses state notation strings (like 'hovered & !disabled', '@media(w < 768px)')\n * into ConditionNode trees for processing in the pipeline.\n */\n\nimport { Lru } from '../parser/lru';\nimport type { StateParserContext } from '../states';\nimport {\n expandDimensionShorthands,\n expandTastyUnits,\n findTopLevelComma,\n resolvePredefinedState,\n} from '../states';\nimport { camelToKebab } from '../utils/case-converter';\nimport { isDevEnv } from '../utils/is-dev-env';\nimport { transformSelectorContent } from '../utils/selector-transform';\n\nimport type { ConditionNode, NumericBound } from './conditions';\nimport { emitWarning } from './warnings';\nimport {\n and,\n createContainerDimensionCondition,\n createContainerRawCondition,\n createContainerStyleCondition,\n createMediaDimensionCondition,\n createMediaFeatureCondition,\n createMediaTypeCondition,\n createModifierCondition,\n createOwnCondition,\n createParentCondition,\n createPseudoCondition,\n createRootCondition,\n createStartingCondition,\n createSupportsCondition,\n not,\n or,\n trueCondition,\n} from './conditions';\n\n// ============================================================================\n// Constants\n// ============================================================================\n\n/**\n * Maximum XOR operands before emitting a performance warning.\n * A ^ B ^ C ^ D = 8 OR branches (2^(n-1)), so chains above 4\n * risk exponential blowup in downstream processing.\n */\nconst MAX_XOR_CHAIN_LENGTH = 4;\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface ParseStateKeyOptions {\n context?: StateParserContext;\n isSubElement?: boolean;\n}\n\n// ============================================================================\n// Caching\n// ============================================================================\n\n// Cache for parsed state keys (key -> ConditionNode)\nconst parseCache = new Lru<string, ConditionNode>(5000);\n\n// ============================================================================\n// Internal-pseudo Detection\n// ============================================================================\n\n/**\n * Chrome-internal pseudo-classes (e.g. `:-internal-autofill-selected`,\n * `:-internal-autofill-previewed`) cannot be targeted from user CSS and\n * may invalidate the surrounding rule in Safari even when wrapped in\n * forgiving `:is(...)`. The regex matches both bare uses and references\n * inside enhanced pseudo arguments like `:is(:-webkit-autofill,\n * :-internal-autofill-selected)`.\n */\nconst INTERNAL_PSEUDO_PATTERN = /:-internal-[a-z0-9-]+/g;\n\n// ============================================================================\n// Tokenizer Patterns\n// ============================================================================\n\n/**\n * Pattern for tokenizing state notation.\n * Matches: operators, parentheses, @-prefixed states, value mods, boolean mods,\n * pseudo-classes, class selectors, and attribute selectors.\n *\n * All @-prefixed state groups (@supports, @root, @parent, @own, @(...))\n * and :is/:has/:not/:where pseudo-classes support up to 2 levels of\n * nested parentheses via:\n * [^()]*(?:\\([^()]*(?:\\([^)]*\\))?[^)]*\\))*[^)]*\n */\nconst STATE_TOKEN_PATTERN =\n /([&|!^])|([()])|(@media:[a-z]+)|(@media\\([^)]+\\))|(@supports\\([^()]*(?:\\([^()]*(?:\\([^)]*\\))?[^)]*\\))*[^)]*\\))|(@root\\([^()]*(?:\\([^()]*(?:\\([^)]*\\))?[^)]*\\))*[^)]*\\))|(@parent\\([^()]*(?:\\([^()]*(?:\\([^)]*\\))?[^)]*\\))*[^)]*\\))|(@own\\([^()]*(?:\\([^()]*(?:\\([^)]*\\))?[^)]*\\))*[^)]*\\))|(@\\([^()]*(?:\\([^()]*(?:\\([^)]*\\))?[^)]*\\))*[^)]*\\))|(@starting)|(@[A-Za-z][A-Za-z0-9-]*)|([a-z][a-z0-9-]*(?:\\^=|\\$=|\\*=|=)(?:\"[^\"]*\"|'[^']*'|[^\\s&|!^()]+))|([a-z][a-z0-9-]+)|(:(?:is|has|not|where)\\([^()]*(?:\\([^()]*(?:\\([^)]*\\))?[^)]*\\))*[^)]*\\))|(:[-a-z][a-z0-9-]*(?:\\([^)]+\\))?)|(\\.[a-z][a-z0-9-]+)|(\\[[^\\]]+\\])/gi;\n\n// ============================================================================\n// Token Types\n// ============================================================================\n\ntype TokenType = 'AND' | 'OR' | 'NOT' | 'XOR' | 'LPAREN' | 'RPAREN' | 'STATE';\n\ninterface Token {\n type: TokenType;\n value: string;\n raw: string;\n}\n\n// ============================================================================\n// Tokenizer\n// ============================================================================\n\n/**\n * Tokenize a state notation string\n */\nfunction tokenize(stateKey: string): Token[] {\n const tokens: Token[] = [];\n let match: RegExpExecArray | null;\n\n // Replace commas with | outside of parentheses (for compatibility)\n const normalized = replaceCommasOutsideParens(stateKey);\n\n STATE_TOKEN_PATTERN.lastIndex = 0;\n while ((match = STATE_TOKEN_PATTERN.exec(normalized)) !== null) {\n const fullMatch = match[0];\n\n if (match[1]) {\n // Operator: &, |, !, ^\n switch (fullMatch) {\n case '&':\n tokens.push({ type: 'AND', value: '&', raw: fullMatch });\n break;\n case '|':\n tokens.push({ type: 'OR', value: '|', raw: fullMatch });\n break;\n case '!':\n tokens.push({ type: 'NOT', value: '!', raw: fullMatch });\n break;\n case '^':\n tokens.push({ type: 'XOR', value: '^', raw: fullMatch });\n break;\n }\n } else if (match[2]) {\n // Parenthesis\n if (fullMatch === '(') {\n tokens.push({ type: 'LPAREN', value: '(', raw: fullMatch });\n } else {\n tokens.push({ type: 'RPAREN', value: ')', raw: fullMatch });\n }\n } else {\n // State token (all other capture groups)\n tokens.push({ type: 'STATE', value: fullMatch, raw: fullMatch });\n }\n }\n\n return tokens;\n}\n\n/**\n * Replace commas with | only outside of parentheses\n */\nfunction replaceCommasOutsideParens(str: string): string {\n let result = '';\n let depth = 0;\n\n for (const char of str) {\n if (char === '(') {\n depth++;\n result += char;\n } else if (char === ')') {\n depth--;\n result += char;\n } else if (char === ',' && depth === 0) {\n result += '|';\n } else {\n result += char;\n }\n }\n\n return result;\n}\n\n// ============================================================================\n// Recursive Descent Parser\n// ============================================================================\n\n/**\n * Parser state\n */\nclass Parser {\n private tokens: Token[];\n private pos = 0;\n private options: ParseStateKeyOptions;\n\n constructor(tokens: Token[], options: ParseStateKeyOptions) {\n this.tokens = tokens;\n this.options = options;\n }\n\n parse(): ConditionNode {\n if (this.tokens.length === 0) {\n return trueCondition();\n }\n const result = this.parseExpression();\n return result;\n }\n\n private current(): Token | undefined {\n return this.tokens[this.pos];\n }\n\n private advance(): Token | undefined {\n return this.tokens[this.pos++];\n }\n\n private match(type: TokenType): boolean {\n if (this.current()?.type === type) {\n this.advance();\n return true;\n }\n return false;\n }\n\n /**\n * Parse expression with operator precedence:\n * ! (NOT) > ^ (XOR) > | (OR) > & (AND)\n */\n private parseExpression(): ConditionNode {\n return this.parseAnd();\n }\n\n private parseAnd(): ConditionNode {\n let left = this.parseOr();\n\n while (this.current()?.type === 'AND') {\n this.advance();\n const right = this.parseOr();\n left = and(left, right);\n }\n\n return left;\n }\n\n private parseOr(): ConditionNode {\n let left = this.parseXor();\n\n while (this.current()?.type === 'OR') {\n this.advance();\n const right = this.parseXor();\n left = or(left, right);\n }\n\n return left;\n }\n\n private parseXor(): ConditionNode {\n let left = this.parseUnary();\n let operandCount = 1;\n\n while (this.current()?.type === 'XOR') {\n this.advance();\n const right = this.parseUnary();\n operandCount++;\n\n if (operandCount > MAX_XOR_CHAIN_LENGTH) {\n emitWarning(\n 'XOR_CHAIN_TOO_LONG',\n `XOR chain with ${operandCount} operands produces ${Math.pow(2, operandCount - 1)} OR branches. ` +\n `Consider breaking into smaller expressions to avoid exponential growth.`,\n );\n }\n\n // XOR: (A & !B) | (!A & B)\n left = or(and(left, not(right)), and(not(left), right));\n }\n\n return left;\n }\n\n private parseUnary(): ConditionNode {\n if (this.match('NOT')) {\n const operand = this.parseUnary();\n return not(operand);\n }\n return this.parsePrimary();\n }\n\n private parsePrimary(): ConditionNode {\n // Handle parentheses\n if (this.match('LPAREN')) {\n const expr = this.parseExpression();\n this.match('RPAREN'); // Consume closing paren (lenient if missing)\n return expr;\n }\n\n // Handle state tokens\n const token = this.current();\n if (token?.type === 'STATE') {\n this.advance();\n return this.parseStateToken(token.value);\n }\n\n // Fallback for empty/invalid - return TRUE\n return trueCondition();\n }\n\n /**\n * Parse a state token into a ConditionNode\n */\n private parseStateToken(value: string): ConditionNode {\n // @starting\n if (value === '@starting') {\n return createStartingCondition(false, value);\n }\n\n // @media:type (e.g., @media:print)\n if (value.startsWith('@media:')) {\n const mediaType = value.slice(7) as 'print' | 'screen' | 'all' | 'speech';\n return createMediaTypeCondition(mediaType, false, value);\n }\n\n // @media(...) - media query\n if (value.startsWith('@media(')) {\n return this.parseMediaQuery(value);\n }\n\n // @supports(...) - feature/selector support query\n if (value.startsWith('@supports(')) {\n return this.parseSupportsQuery(value);\n }\n\n // @root(...) - root state\n if (value.startsWith('@root(')) {\n return this.parseRootState(value);\n }\n\n // @parent(...) - parent element state\n if (value.startsWith('@parent(')) {\n return this.parseParentState(value);\n }\n\n // @own(...) - own state (sub-element)\n if (value.startsWith('@own(')) {\n return this.parseOwnState(value);\n }\n\n // @(...) - container query\n if (value.startsWith('@(')) {\n return this.parseContainerQuery(value);\n }\n\n // @name - predefined state\n if (value.startsWith('@') && /^@[A-Za-z][A-Za-z0-9-]*$/.test(value)) {\n return this.parsePredefinedState(value);\n }\n\n // Enhanced pseudo-classes: :is(), :has(), :not(), :where()\n // Transform capitalized words to [data-element=\"...\"] selectors,\n // auto-complete trailing combinators with *, and\n // normalize :not(X) → negated :is(X) for deduplication.\n if (value.startsWith(':')) {\n const enhancedMatch = /^:(is|has|not|where)\\(/.exec(value);\n if (enhancedMatch) {\n const fn = enhancedMatch[1];\n const prefix = enhancedMatch[0];\n let content = transformSelectorContent(value.slice(prefix.length, -1));\n\n // Auto-complete trailing combinator: :has(Icon >) → :has(... > *)\n content = content.replace(/([>+~])\\s*$/, '$1 *');\n\n if (fn === 'not') {\n return createPseudoCondition(`:is(${content})`, true, value);\n }\n\n return createPseudoCondition(`:${fn}(${content})`, false, value);\n }\n\n return createPseudoCondition(value, false, value);\n }\n\n // Class selector (e.g., .active)\n if (value.startsWith('.')) {\n return createPseudoCondition(value, false, value);\n }\n\n // Attribute selector (e.g., [disabled], [data-state=\"active\"])\n // Single, simple attribute selectors become structured modifiers so the\n // pipeline can reason about their mutual exclusivity (same attribute,\n // different value can never match at once). Complex forms (~=, |=, case\n // flags, namespaces, multiple attrs, combinators) stay opaque pseudos.\n if (value.startsWith('[')) {\n const attrMatch =\n /^\\[\\s*([a-zA-Z_][\\w-]*)\\s*(?:(=|\\^=|\\$=|\\*=)\\s*(?:\"([^\"]*)\"|'([^']*)'|([^\\]\\s]+)))?\\s*\\]$/.exec(\n value,\n );\n if (attrMatch) {\n const [, attribute, operator, dq, sq, bare] = attrMatch;\n if (operator === undefined) {\n // Boolean attribute: [data-disabled]\n return createModifierCondition(\n attribute,\n undefined,\n '=',\n false,\n value,\n );\n }\n const attrValue = dq ?? sq ?? bare;\n return createModifierCondition(\n attribute,\n attrValue,\n operator as '=' | '^=' | '$=' | '*=',\n false,\n value,\n );\n }\n return createPseudoCondition(value, false, value);\n }\n\n // Value modifier (e.g., theme=danger, size=large)\n if (value.includes('=')) {\n return this.parseValueModifier(value);\n }\n\n // Boolean modifier (e.g., hovered, disabled)\n return this.parseBooleanModifier(value);\n }\n\n /**\n * Parse @media(...) query\n */\n private parseMediaQuery(raw: string): ConditionNode {\n const content = raw.slice(7, -1); // Remove '@media(' and ')'\n if (!content.trim()) {\n return trueCondition();\n }\n\n // Expand shorthands and units\n let condition = expandDimensionShorthands(content);\n condition = expandTastyUnits(condition);\n\n // Check for feature queries (contains ':' but not dimension comparison)\n if (\n condition.includes(':') &&\n !condition.includes('<') &&\n !condition.includes('>') &&\n !condition.includes('=')\n ) {\n // Feature query: @media(prefers-contrast: high)\n const colonIdx = condition.indexOf(':');\n const feature = condition.slice(0, colonIdx).trim();\n const featureValue = condition.slice(colonIdx + 1).trim();\n return createMediaFeatureCondition(feature, featureValue, false, raw);\n }\n\n // Boolean feature query: @media(prefers-reduced-motion)\n if (\n !condition.includes('<') &&\n !condition.includes('>') &&\n !condition.includes('=')\n ) {\n return createMediaFeatureCondition(\n condition.trim(),\n undefined,\n false,\n raw,\n );\n }\n\n // Dimension query - parse bounds\n const { dimension, lowerBound, upperBound } =\n this.parseDimensionCondition(condition);\n\n if (!dimension) {\n // Fallback for unparseable - treat as pseudo\n return createPseudoCondition(raw, false, raw);\n }\n\n return createMediaDimensionCondition(\n dimension as 'width' | 'height',\n lowerBound,\n upperBound,\n false,\n raw,\n );\n }\n\n /**\n * Parse dimension condition string (e.g., \"width < 768px\", \"600px <= width < 1200px\")\n */\n private parseDimensionCondition(condition: string): {\n dimension?: string;\n lowerBound?: NumericBound;\n upperBound?: NumericBound;\n } {\n // Range syntax: \"600px <= width < 1200px\"\n const rangeMatch = condition.match(\n /^(.+?)\\s*(<=|<)\\s*(width|height|inline-size|block-size)\\s*(<=|<)\\s*(.+)$/,\n );\n if (rangeMatch) {\n const [, lowerValue, lowerOp, dimension, upperOp, upperValue] =\n rangeMatch;\n return {\n dimension,\n lowerBound: {\n value: lowerValue.trim(),\n valueNumeric: parseNumericValue(lowerValue.trim()),\n inclusive: lowerOp === '<=',\n },\n upperBound: {\n value: upperValue.trim(),\n valueNumeric: parseNumericValue(upperValue.trim()),\n inclusive: upperOp === '<=',\n },\n };\n }\n\n // Simple comparison: \"width < 768px\"\n const simpleMatch = condition.match(\n /^(width|height|inline-size|block-size)\\s*(<=|>=|<|>|=)\\s*(.+)$/,\n );\n if (simpleMatch) {\n const [, dimension, operator, value] = simpleMatch;\n const numeric = parseNumericValue(value.trim());\n\n if (operator === '<' || operator === '<=') {\n return {\n dimension,\n upperBound: {\n value: value.trim(),\n valueNumeric: numeric,\n inclusive: operator === '<=',\n },\n };\n } else if (operator === '>' || operator === '>=') {\n return {\n dimension,\n lowerBound: {\n value: value.trim(),\n valueNumeric: numeric,\n inclusive: operator === '>=',\n },\n };\n } else if (operator === '=') {\n // Exact match: both bounds are the same and inclusive\n return {\n dimension,\n lowerBound: {\n value: value.trim(),\n valueNumeric: numeric,\n inclusive: true,\n },\n upperBound: {\n value: value.trim(),\n valueNumeric: numeric,\n inclusive: true,\n },\n };\n }\n }\n\n // Reversed: \"768px > width\"\n const reversedMatch = condition.match(\n /^(.+?)\\s*(<=|>=|<|>|=)\\s*(width|height|inline-size|block-size)$/,\n );\n if (reversedMatch) {\n const [, value, operator, dimension] = reversedMatch;\n const numeric = parseNumericValue(value.trim());\n\n // Reverse the operator\n if (operator === '<' || operator === '<=') {\n return {\n dimension,\n lowerBound: {\n value: value.trim(),\n valueNumeric: numeric,\n inclusive: operator === '<=',\n },\n };\n } else if (operator === '>' || operator === '>=') {\n return {\n dimension,\n upperBound: {\n value: value.trim(),\n valueNumeric: numeric,\n inclusive: operator === '>=',\n },\n };\n }\n }\n\n return {};\n }\n\n /**\n * Parse @root(...) state\n */\n private parseInnerCondition(\n raw: string,\n prefixLen: number,\n wrap: (inner: ConditionNode) => ConditionNode,\n ): ConditionNode {\n const content = raw.slice(prefixLen, -1);\n if (!content.trim()) return trueCondition();\n return wrap(parseStateKey(content, this.options));\n }\n\n private parseRootState(raw: string): ConditionNode {\n return this.parseInnerCondition(raw, 6, (inner) =>\n createRootCondition(inner, false, raw),\n );\n }\n\n /**\n * Parse @parent(...) state\n *\n * Syntax:\n * @parent(hovered) → :is([data-hovered] *)\n * @parent(theme=dark) → :is([data-theme=\"dark\"] *)\n * @parent(hovered, >) → :is([data-hovered] > *) (direct parent)\n * @parent(.my-class) → :is(.my-class *)\n */\n private parseParentState(raw: string): ConditionNode {\n const content = raw.slice(8, -1);\n if (!content.trim()) {\n return trueCondition();\n }\n\n let condition = content.trim();\n let direct = false;\n\n const lastCommaIdx = condition.lastIndexOf(',');\n if (lastCommaIdx !== -1) {\n const afterComma = condition.slice(lastCommaIdx + 1).trim();\n if (afterComma === '>') {\n direct = true;\n condition = condition.slice(0, lastCommaIdx).trim();\n }\n }\n\n const innerCondition = parseStateKey(condition, this.options);\n return createParentCondition(innerCondition, direct, false, raw);\n }\n\n /**\n * Parse @supports(...) query\n *\n * Syntax:\n * @supports(display: grid) → @supports (display: grid)\n * @supports($, :has(*)) → @supports selector(:has(*))\n */\n private parseSupportsQuery(raw: string): ConditionNode {\n const content = raw.slice(10, -1); // Remove '@supports(' and ')'\n if (!content.trim()) {\n return trueCondition();\n }\n\n // Check for selector syntax: @supports($, :has(*))\n if (content.startsWith('$,')) {\n const selector = content.slice(2).trim(); // Remove '$,' prefix\n return createSupportsCondition('selector', selector, false, raw);\n }\n\n // Feature syntax: @supports(display: grid)\n return createSupportsCondition('feature', content, false, raw);\n }\n\n private parseOwnState(raw: string): ConditionNode {\n return this.parseInnerCondition(raw, 5, (inner) =>\n createOwnCondition(inner, false, raw),\n );\n }\n\n /**\n * Parse @(...) container query\n */\n private parseContainerQuery(raw: string): ConditionNode {\n const content = raw.slice(2, -1); // Remove '@(' and ')'\n if (!content.trim()) {\n return trueCondition();\n }\n\n // Check for named container: @(layout, w < 600px)\n // Use parentheses-aware comma search so inner commas (e.g., scroll-state(a, b)) are skipped\n const commaIdx = findTopLevelComma(content);\n let containerName: string | undefined;\n let condition: string;\n\n if (commaIdx !== -1) {\n containerName = content.slice(0, commaIdx).trim();\n condition = content.slice(commaIdx + 1).trim();\n } else {\n condition = content.trim();\n }\n\n // Check for style query shorthand: @($variant=primary)\n if (condition.startsWith('$')) {\n const styleQuery = condition.slice(1); // Remove '$'\n const eqIdx = styleQuery.indexOf('=');\n\n if (eqIdx === -1) {\n // Existence check: @($variant)\n return createContainerStyleCondition(\n styleQuery,\n undefined,\n containerName,\n false,\n raw,\n );\n }\n\n const property = styleQuery.slice(0, eqIdx).trim();\n let propertyValue = styleQuery.slice(eqIdx + 1).trim();\n\n // Remove quotes if present\n if (\n (propertyValue.startsWith('\"') && propertyValue.endsWith('\"')) ||\n (propertyValue.startsWith(\"'\") && propertyValue.endsWith(\"'\"))\n ) {\n propertyValue = propertyValue.slice(1, -1);\n }\n\n return createContainerStyleCondition(\n property,\n propertyValue,\n containerName,\n false,\n raw,\n );\n }\n\n // Check for function-like syntax: scroll-state(...), style(...), etc.\n // Passes the condition through to CSS verbatim.\n if (/^[a-zA-Z][\\w-]*\\s*\\(/.test(condition)) {\n return createContainerRawCondition(condition, containerName, false, raw);\n }\n\n // Dimension query\n let expandedCondition = expandDimensionShorthands(condition);\n expandedCondition = expandTastyUnits(expandedCondition);\n\n const { dimension, lowerBound, upperBound } =\n this.parseDimensionCondition(expandedCondition);\n\n if (!dimension) {\n // Fallback\n return createPseudoCondition(raw, false, raw);\n }\n\n return createContainerDimensionCondition(\n dimension as 'width' | 'height',\n lowerBound,\n upperBound,\n containerName,\n false,\n raw,\n );\n }\n\n /**\n * Parse predefined state (@mobile, @dark, etc.)\n */\n private parsePredefinedState(raw: string): ConditionNode {\n const ctx = this.options.context;\n if (!ctx) {\n // No context - can't resolve predefined states\n return createPseudoCondition(raw, false, raw);\n }\n\n const resolved = resolvePredefinedState(raw, ctx);\n if (!resolved) {\n // Undefined predefined state - treat as modifier\n return createModifierCondition(\n `data-${camelToKebab(raw.slice(1))}`,\n undefined,\n '=',\n false,\n raw,\n );\n }\n\n // Parse the resolved value recursively\n return parseStateKey(resolved, this.options);\n }\n\n /**\n * Parse value modifier (e.g., theme=danger, size^=sm)\n */\n private parseValueModifier(raw: string): ConditionNode {\n // Match operators: =, ^=, $=, *=\n const opMatch = raw.match(/^([a-z][a-z0-9-]*)(\\^=|\\$=|\\*=|=)(.+)$/i);\n if (!opMatch) {\n return createModifierCondition(\n `data-${camelToKebab(raw)}`,\n undefined,\n '=',\n false,\n raw,\n );\n }\n\n const [, key, operator, value] = opMatch;\n let cleanValue = value;\n\n // Remove quotes if present\n if (\n (cleanValue.startsWith('\"') && cleanValue.endsWith('\"')) ||\n (cleanValue.startsWith(\"'\") && cleanValue.endsWith(\"'\"))\n ) {\n cleanValue = cleanValue.slice(1, -1);\n }\n\n return createModifierCondition(\n `data-${camelToKebab(key)}`,\n cleanValue,\n operator as '=' | '^=' | '$=' | '*=',\n false,\n raw,\n );\n }\n\n /**\n * Parse boolean modifier (e.g., hovered, disabled)\n */\n private parseBooleanModifier(raw: string): ConditionNode {\n return createModifierCondition(\n `data-${camelToKebab(raw)}`,\n undefined,\n '=',\n false,\n raw,\n );\n }\n}\n\n// ============================================================================\n// Helper Functions\n// ============================================================================\n\n/**\n * Parse a numeric value from a CSS value string\n */\nfunction parseNumericValue(value: string): number | null {\n const match = value.match(/^(\\d+(?:\\.\\d+)?)(px|em|rem|vh|vw|%)?$/);\n if (match) {\n return parseFloat(match[1]);\n }\n return null;\n}\n\n// ============================================================================\n// Main Export\n// ============================================================================\n\n/**\n * Parse a state key string into a ConditionNode\n */\nexport function parseStateKey(\n stateKey: string,\n options: ParseStateKeyOptions = {},\n): ConditionNode {\n // Handle empty/default state\n if (!stateKey || !stateKey.trim()) {\n return trueCondition();\n }\n\n const trimmed = stateKey.trim();\n\n // Build cache key including local predefined states (they affect parsing)\n // Global predefined states are set once at initialization and don't change\n const ctx = options.context;\n const localStatesKey =\n ctx && Object.keys(ctx.localPredefinedStates).length > 0\n ? JSON.stringify(ctx.localPredefinedStates)\n : '';\n const cacheKey =\n trimmed + '\\0' + (options.isSubElement ? '1' : '0') + '\\0' + localStatesKey;\n\n // Check cache\n const cached = parseCache.get(cacheKey);\n if (cached) {\n return cached;\n }\n\n // Warn about `:-internal-*` pseudo-classes. The cache miss above\n // means we only emit the warning the first time we encounter a\n // given key (subsequent identical keys reuse the cached result and\n // skip this scan). The regex catches both bare uses and references\n // inside `:is(...)` / `:has(...)` / `:not(...)` / `:where(...)`.\n //\n // Gated behind `isDevEnv()` because this is a developer-only aid.\n // `isDevEnv()` uses bracket notation on `process.env` to survive\n // tasty's own bundling and also returns `false` under `NODE_ENV=test`\n // / `NODE_ENV=production`, so the warning only fires in real dev.\n if (isDevEnv()) {\n INTERNAL_PSEUDO_PATTERN.lastIndex = 0;\n const internalMatches = trimmed.match(INTERNAL_PSEUDO_PATTERN);\n if (internalMatches && internalMatches.length > 0) {\n const unique = Array.from(new Set(internalMatches));\n emitWarning(\n 'INTERNAL_PSEUDO_USED',\n `State key \"${trimmed}\" references internal pseudo-class${unique.length > 1 ? 'es' : ''} ${unique.map((p) => `\\`${p}\\``).join(', ')}. ` +\n `These are unmatchable from user CSS and can invalidate the surrounding rule in Safari (even inside \\`:is(...)\\`). ` +\n `Use \\`:-webkit-autofill | :autofill\\` instead for autofill states.`,\n );\n }\n }\n\n // Tokenize and parse\n const tokens = tokenize(trimmed);\n const parser = new Parser(tokens, options);\n const result = parser.parse();\n\n // Cache result\n parseCache.set(cacheKey, result);\n\n return result;\n}\n\n/**\n * Clear the parse cache (for testing)\n */\nexport function clearParseCache(): void {\n parseCache.clear();\n}\n","/**\n * Tasty Style Rendering Pipeline\n *\n * Main entrypoint for the style rendering pipeline. Transforms a `Styles`\n * object into an array of `CSSRule` objects ready for DOM injection.\n *\n * Per-handler stages (see docs/pipeline.md for full detail):\n * 0. PRE-PARSE NORMALIZATION - extractCompoundStates (exclusive.ts)\n * 1. PARSE CONDITIONS - parseStyleEntries + parseStateKey\n * 1b. MERGE ENTRIES BY VALUE - mergeEntriesByValue (exclusive.ts)\n * 2a. EXPAND USER OR BRANCHES - expandOrConditions (exclusive.ts)\n * 2b. BUILD EXCLUSIVE CONDITIONS - buildExclusiveConditions\n * 3. EXPAND DE MORGAN ORs - expandExclusiveOrs (exclusive.ts)\n * 4. COMPUTE STATE COMBINATIONS - computeStateCombinations\n * 5. CALL HANDLERS - run style handlers for each snapshot\n * 6. MERGE BY VALUE - mergeByValue (index.ts)\n * 7. MATERIALIZE CSS - conditionToCSS + materializeComputedRule\n *\n * Simplification (`simplifyCondition`) runs inside most stages; calls are\n * memoized by condition unique-id. The post-pass in `runPipeline` dedupes\n * identical rules and emits all `@starting-style` rules last so they win\n * the cascade over their equal-specificity normal counterparts.\n */\n\nimport { Lru } from '../parser/lru';\nimport type { StateParserContext } from '../states';\nimport {\n createStateParserContext,\n extractLocalPredefinedStates,\n} from '../states';\nimport { createStyle, STYLE_HANDLER_MAP } from '../styles';\nimport type { Styles } from '../styles/types';\nimport { isDevEnv } from '../utils/is-dev-env';\nimport { toSnakeCase } from '../utils/string';\nimport type {\n StyleHandler,\n StyleMap,\n StyleValue,\n StyleValueStateMap,\n} from '../utils/styles';\nimport { stringifyStyles } from '../utils/styles';\n\nimport type { ConditionNode } from './conditions';\nimport { and, or, trueCondition } from './conditions';\nimport type { ExclusiveStyleEntry } from './exclusive';\nimport {\n buildExclusiveConditions,\n expandExclusiveOrs,\n expandOrConditions,\n extractCompoundStates,\n isValueMapping,\n mergeEntriesByValue,\n parseStyleEntries,\n} from './exclusive';\nimport type { CSSRule, SelectorVariant } from './materialize-types';\nimport {\n branchToCSS,\n buildAtRulesFromVariant,\n conditionToCSS,\n mergeVariantsIntoSelectorGroups,\n optimizeGroups,\n parentGroupsToCSS,\n rootGroupsToCSS,\n selectorGroupToCSS,\n wrapWhere,\n} from './materialize';\nimport { parseStateKey } from './parseStateKey';\nimport { simplifyCondition } from './simplify';\nimport { emitWarning } from './warnings';\n\n/** Any uppercase letter — a CSS property name should never contain one. */\nconst RE_UPPER_CASE = /[A-Z]/;\n\n// ============================================================================\n// Types (compatible with old renderStyles API)\n// ============================================================================\n\n/**\n * Matches the old StyleResult interface for backward compatibility\n */\nexport interface StyleResult {\n selector: string;\n declarations: string;\n atRules?: string[];\n needsClassName?: boolean;\n rootPrefix?: string;\n /** When true, declarations are wrapped in @starting-style { ... } inside the selector rule */\n startingStyle?: boolean;\n}\n\n/**\n * Matches the old RenderResult interface for backward compatibility\n */\nexport interface RenderResult {\n rules: StyleResult[];\n className?: string;\n}\n\ninterface ComputedRule {\n condition: ConditionNode;\n declarations: Record<string, string>;\n selectorSuffix: string;\n /**\n * Cascade order hint (source priority of the highest-priority style entry\n * that contributed to this rule). Higher = should appear later in the\n * stylesheet so it wins the cascade. Used to emit `_` fallback floor rules\n * before the higher-priority rules that layer over them, since `:where()`\n * makes all rules share specificity and source order decides the winner.\n */\n order: number;\n}\n\n// ============================================================================\n// Caching\n// ============================================================================\n\nconst pipelineCache = new Lru<string, CSSRule[]>(5000);\n\n/**\n * Check if a cache key exists in the pipeline cache.\n * Used by renderStylesForChunk to avoid building filtered styles on cache hit.\n */\nexport function hasPipelineCacheEntry(cacheKey: string): boolean {\n return pipelineCache.get(cacheKey) !== undefined;\n}\n\n/**\n * Clear the pipeline cache (for testing)\n */\nexport function clearPipelineCache(): void {\n pipelineCache.clear();\n}\n\n// ============================================================================\n// Pipeline Implementation\n// ============================================================================\n\nfunction runPipeline(\n styles: Styles,\n parserContext: StateParserContext,\n): CSSRule[] {\n const allRules: CSSRule[] = [];\n\n // Process styles recursively (including nested selectors)\n processStyles(styles, '', parserContext, allRules);\n\n // Deduplicate rules\n const seen = new Set<string>();\n const dedupedRules = allRules.filter((rule) => {\n const key = `${rule.selector}|${rule.declarations}|${rule.atRules?.join('|') ?? ''}|${rule.rootPrefix || ''}|${rule.startingStyle ? '1' : '0'}`;\n if (seen.has(key)) return false;\n seen.add(key);\n return true;\n });\n\n // @starting-style rules must come AFTER normal rules for the same selector.\n // They share the same specificity, so source order decides the cascade.\n // If a @starting-style rule appears before its normal counterpart,\n // the later normal rule overrides the starting value.\n const normal: CSSRule[] = [];\n const starting: CSSRule[] = [];\n\n for (const rule of dedupedRules) {\n if (rule.startingStyle) {\n starting.push(rule);\n } else {\n normal.push(rule);\n }\n }\n\n // Order rules by their cascade order hint (ascending source priority) so\n // higher-priority rules come later and win. This is load-bearing once\n // selector specificity is equalized via `:where()`: `_` fallback floor\n // rules (low order) must precede the higher-priority rules that layer over\n // them. The sort is stable, so equal-order rules keep their emission\n // order. Mutually-exclusive rules are unaffected by ordering.\n const stableOrdered = stableSortByOrder(normal);\n\n return stableOrdered.concat(stableSortByOrder(starting));\n}\n\n/**\n * Stable sort CSS rules by their `order` hint ascending. Rules without an\n * `order` are treated as 0. `Array.prototype.sort` is stable (ES2019+,\n * Node >= 20), so equal-order rules keep their emission order — the `_`\n * fallback floor (low order) stays before the overrides that layer over it.\n */\nfunction stableSortByOrder(rules: CSSRule[]): CSSRule[] {\n if (rules.length <= 1) return rules;\n return [...rules].sort((a, b) => (a.order ?? 0) - (b.order ?? 0));\n}\n\n/**\n * Process styles at a given nesting level.\n *\n * Splits keys into nested-selector keys and style-handler keys, recurses\n * into nested selectors, then runs the per-handler stages 1–7 over the\n * style keys.\n */\nfunction processStyles(\n styles: Styles,\n selectorSuffix: string,\n parserContext: StateParserContext,\n allRules: CSSRule[],\n): void {\n const keys = Object.keys(styles);\n\n // Separate selector keys from style keys.\n // Skip @keyframes (processed separately) and other @-prefixed keys\n // (predefined states), which are not handler entries.\n const selectorKeys = keys.filter((key) => isSelector(key));\n const styleKeys: string[] = [];\n for (const key of keys) {\n if (isSelector(key) || key.startsWith('@')) continue;\n\n // Reject top-level pseudo-class / pseudo-element keys like ':hover',\n // '::before', ':has(...)'. These are not valid Tasty style keys —\n // pseudo-states belong inside a value map (e.g. `color: { ':hover': '...' }`),\n // and nested-declaration form requires an `&` prefix (e.g. `'&:hover': {…}`).\n // Without `&`, a key like ':hover' falls through to a generic style\n // handler and produces malformed CSS, so we drop it and warn in dev.\n if (key.startsWith(':')) {\n emitWarning(\n 'INVALID_TOP_LEVEL_PSEUDO_KEY',\n `Style key \"${key}\" starts with ':' which is not a valid Tasty style key. ` +\n `Use \"&${key}\" for nested-selector form, or move the state into a value map ` +\n `(e.g. \\`{ color: { '${key}': value } }\\`). The key has been ignored.`,\n );\n continue;\n }\n\n styleKeys.push(key);\n }\n\n // Process nested selectors first\n processNestedSelectors(\n styles,\n selectorKeys,\n selectorSuffix,\n parserContext,\n allRules,\n );\n\n // Process the handler queue for this level's style keys\n const handlerQueue = buildHandlerQueue(styleKeys, styles);\n processHandlerQueue(handlerQueue, selectorSuffix, parserContext, allRules);\n}\n\n/**\n * Recurse into nested selector keys. Each nested key may expand into multiple\n * suffixes (comma-separated patterns); each suffix is processed independently\n * with the parent's parser context augmented for sub-element scope.\n */\nfunction processNestedSelectors(\n styles: Styles,\n selectorKeys: string[],\n selectorSuffix: string,\n parserContext: StateParserContext,\n allRules: CSSRule[],\n): void {\n for (const key of selectorKeys) {\n const nestedStyles = styles[key] as Styles;\n if (!nestedStyles || typeof nestedStyles !== 'object') continue;\n\n // Get all selectors (handles comma-separated patterns)\n const suffixes = getAllSelectors(key, nestedStyles);\n if (!suffixes) continue; // Invalid selector, skip\n\n // Remove $ from nested styles\n const { $: _$, ...cleanedStyles } = nestedStyles;\n\n // Extract local predefined states scoped to this sub-element\n const subLocalStates = extractLocalPredefinedStates(cleanedStyles);\n const hasSubStates = Object.keys(subLocalStates).length > 0;\n const subContext: StateParserContext = {\n ...parserContext,\n isSubElement: true,\n localPredefinedStates: hasSubStates\n ? { ...parserContext.localPredefinedStates, ...subLocalStates }\n : parserContext.localPredefinedStates,\n };\n\n // Process for each selector (multiple selectors = same styles applied to each)\n for (const suffix of suffixes) {\n processStyles(\n cleanedStyles,\n selectorSuffix + suffix,\n subContext,\n allRules,\n );\n }\n }\n}\n\n/**\n * Run the per-handler pipeline (stages 1–7) over a handler queue and append\n * the resulting CSS rules to `allRules`.\n */\nfunction processHandlerQueue(\n handlerQueue: ReturnType<typeof buildHandlerQueue>,\n selectorSuffix: string,\n parserContext: StateParserContext,\n allRules: CSSRule[],\n): void {\n for (const { handler, styleMap } of handlerQueue) {\n const lookupStyles = handler.__lookupStyles;\n\n // Stages 0–3: build exclusive conditions for each style this handler\n // depends on (extractCompoundStates → parse → mergeEntriesByValue →\n // expandOrConditions → buildExclusiveConditions → expandExclusiveOrs).\n const exclusiveByStyle = buildExclusivesForHandler(\n lookupStyles,\n styleMap,\n parserContext,\n );\n\n // Stage 4: Compute all valid state combinations\n const stateSnapshots = computeStateCombinations(\n exclusiveByStyle,\n lookupStyles,\n );\n\n // Stage 5: Call handler for each snapshot\n const computedRules = invokeHandler(\n handler,\n stateSnapshots,\n selectorSuffix,\n );\n\n // Stage 6: Merge rules with identical CSS output\n const mergedRules = mergeByValue(computedRules);\n\n // Stage 7: Materialize to CSS\n for (const rule of mergedRules) {\n const cssRules = materializeComputedRule(rule);\n allRules.push(...cssRules);\n }\n }\n}\n\n/**\n * Stages 0–3 for a single handler: take the handler's looked-up style names,\n * resolve each style's value map into a list of mutually-exclusive entries.\n * Simple non-mapping values produce a single TRUE-conditioned entry.\n */\nfunction buildExclusivesForHandler(\n lookupStyles: readonly string[],\n styleMap: StyleMap,\n parserContext: StateParserContext,\n): Map<string, ExclusiveStyleEntry[]> {\n const exclusiveByStyle = new Map<string, ExclusiveStyleEntry[]>();\n\n for (const styleName of lookupStyles) {\n const value = styleMap[styleName];\n if (value === undefined) continue;\n\n if (isValueMapping(value)) {\n // Stage 0: Eliminate redundant compound state dimensions before parsing.\n // E.g. { '': A, '@dark': B, '@hc': A, '@dark & @hc': B }\n // reduces to { '': A, '@dark': B } because @hc is irrelevant.\n const reduced = extractCompoundStates(\n value as Record<string, StyleValue>,\n );\n\n // Stage 1: Parse entries from value mapping.\n const parsed = parseStyleEntries(styleName, reduced, (stateKey) =>\n parseStateKey(stateKey, { context: parserContext }),\n );\n\n // Stage 1b: Merge same-value entries before exclusive expansion to\n // prevent combinatorial blowup (e.g. @dark and @dark & @high-contrast\n // mapping to the same color). Merges happen only when provably safe\n // with respect to intermediate-priority entries, so the authored\n // cascade is preserved.\n const merged = mergeEntriesByValue(parsed);\n\n // Stage 2a: Expand user OR conditions into exclusive branches\n // (`A | B | C` becomes `A`, `B & !A`, `C & !A & !B`).\n const expanded = expandOrConditions(merged);\n\n // Stage 2b: Build exclusive conditions across all entries.\n const exclusive = buildExclusiveConditions(expanded);\n\n // Stage 3: Expand De Morgan ORs from negation into at-rule-aware\n // exclusive branches. `!A | !B` → `!A`, `A & !B`. Each branch keeps\n // the correct at-rule context.\n const fullyExpanded = expandExclusiveOrs(exclusive);\n exclusiveByStyle.set(styleName, fullyExpanded);\n } else {\n // Simple value — single entry with TRUE condition.\n exclusiveByStyle.set(styleName, [\n {\n styleKey: styleName,\n stateKey: '',\n value,\n condition: trueCondition(),\n priority: 0,\n exclusiveCondition: trueCondition(),\n },\n ]);\n }\n }\n\n return exclusiveByStyle;\n}\n\n/**\n * Stage 5: invoke the handler for each state snapshot and translate its\n * return value into ComputedRule entries (one per declaration set, fanned\n * out across any `$` selector suffixes the handler returns).\n */\nfunction invokeHandler(\n handler: StyleHandler,\n stateSnapshots: ReturnType<typeof computeStateCombinations>,\n selectorSuffix: string,\n): ComputedRule[] {\n const computedRules: ComputedRule[] = [];\n\n for (const snapshot of stateSnapshots) {\n const result = handler(snapshot.values as StyleValueStateMap);\n if (!result) continue;\n\n // Handler may return single or array\n const results = Array.isArray(result) ? result : [result];\n\n for (const r of results) {\n if (!r || typeof r !== 'object') continue;\n\n const { $, ...styleProps } = r;\n const declarations: Record<string, string> = {};\n\n for (const [prop, val] of Object.entries(styleProps)) {\n // Regex first so the common case is one cheap test; isDevEnv() is called\n // lazily (not captured at module load) only once a bad key is seen, which\n // is both free in production and assertable in tests.\n if (RE_UPPER_CASE.test(prop) && !prop.startsWith('--') && isDevEnv()) {\n // Custom properties are case-sensitive, hence the `--` exemption. Not\n // auto-corrected: silently rewriting a name is worse than a warning,\n // and no type can catch a non-literal return.\n emitWarning(\n 'HANDLER_CAMEL_CASE_KEY',\n `A style handler returned \"${prop}\". CSS property names must be ` +\n `kebab-case (\"${toSnakeCase(prop)}\"). The declaration was ` +\n `emitted verbatim and the browser will ignore it.`,\n );\n }\n\n if (val != null && val !== '') {\n declarations[prop] = String(val);\n }\n }\n\n if (Object.keys(declarations).length === 0) continue;\n\n // Handle $ suffixes\n const suffixes = $\n ? (Array.isArray($) ? $ : [$]).map(\n (s) => selectorSuffix + normalizeSelectorSuffix(String(s)),\n )\n : [selectorSuffix];\n\n for (const suffix of suffixes) {\n computedRules.push({\n condition: snapshot.condition,\n declarations,\n selectorSuffix: suffix,\n order: snapshot.order,\n });\n }\n }\n }\n\n return computedRules;\n}\n\n// ============================================================================\n// Helper Functions\n// ============================================================================\n\n/**\n * Check if a key is a CSS selector\n */\nexport function isSelector(key: string): boolean {\n return key.startsWith('&') || key.startsWith('.') || /^[A-Z]/.test(key);\n}\n\n/**\n * Result of processing a selector affix ($) pattern.\n *\n * @example\n * // Valid result with multiple selectors\n * { valid: true, selectors: ['> [data-element=\"Cell\"]', ' [data-element=\"Body\"] > [data-element=\"Cell\"]'] }\n *\n * // Invalid result with error message\n * { valid: false, reason: 'Selector affix \"+\" targets elements outside the root scope.' }\n */\ntype AffixResult =\n | { valid: true; selectors: string[] }\n | { valid: false; reason: string };\n\n/**\n * Get all selector suffixes for a sub-element key.\n *\n * Handles three types of selector keys:\n * - `&` prefix: Raw selector suffix (e.g., `&:hover` → `:hover`)\n * - `.` prefix: Class selector (e.g., `.active` → ` .active`)\n * - Uppercase: Sub-element with optional `$` affix pattern\n *\n * @param key - The sub-element key (e.g., 'Label', '&:hover', '.active')\n * @param styles - The styles object, may contain `$` property for selector affix\n * @returns Array of selector suffixes, or null if invalid (with console warning)\n *\n * @example\n * getAllSelectors('Label', {})\n * // → [' [data-element=\"Label\"]']\n *\n * getAllSelectors('Cell', { $: '>, >Body>' })\n * // → ['> [data-element=\"Cell\"]', ' [data-element=\"Body\"] > [data-element=\"Cell\"]']\n */\nfunction getAllSelectors(key: string, styles?: Styles): string[] | null {\n if (key.startsWith('&')) {\n return [key.slice(1)];\n }\n\n if (key.startsWith('.')) {\n return [` ${key}`];\n }\n\n if (/^[A-Z]/.test(key)) {\n const affix = styles?.$;\n if (affix !== undefined) {\n const result = processAffix(String(affix), key);\n if (!result.valid) {\n emitWarning('INVALID_SELECTOR_AFFIX', result.reason);\n return null;\n }\n return result.selectors;\n }\n return [` [data-element=\"${key}\"]`];\n }\n\n return null;\n}\n\n/**\n * Process selector affix pattern and return selector(s)\n *\n * Supports:\n * - Direct child: '>'\n * - Chained elements: '>Body>Row>'\n * - HTML tags (no key injection): 'h1', '>ul>li', 'button:hover'\n * - Universal selector: '*', 'h1 *'\n * - Pseudo-elements on root: '::before'\n * - Pseudo on sub-element: '@::before', '>@:hover'\n * - Classes: '.active', '>@.active'\n * - Multiple selectors: '>, >Body>'\n * - Sibling combinators (after element): '>Item+', '>Item~'\n */\nfunction processAffix(affix: string, key: string): AffixResult {\n const trimmed = affix.trim();\n\n // Empty = default behavior (descendant selector with key)\n if (!trimmed) {\n return { valid: true, selectors: [` [data-element=\"${key}\"]`] };\n }\n\n // Split by comma for multiple selectors\n const patterns = trimmed.split(',').map((p) => p.trim());\n const selectors: string[] = [];\n\n for (const pattern of patterns) {\n const validation = validatePattern(pattern);\n if (!validation.valid) {\n return validation;\n }\n\n const selector = processSinglePattern(pattern, key);\n selectors.push(selector);\n }\n\n return { valid: true, selectors };\n}\n\n/**\n * Recognized token patterns for selector affix validation.\n *\n * These patterns are used to tokenize and validate `$` affix strings.\n * Order matters: more specific patterns must come first to avoid\n * partial matches (e.g., `::before` must match before `:` alone).\n *\n * Unrecognized tokens (like `#id`, `*`, or numbers) will cause validation to fail.\n */\nconst VALID_TOKEN_PATTERNS = [\n /^[>+~]/, // Combinators: >, +, ~\n /^\\*/, // Universal selector (*)\n /^[A-Z][a-zA-Z0-9]*/, // Uppercase element names → [data-element=\"...\"]\n /^@/, // @ placeholder for key injection position\n /^::?-?[a-z][a-z0-9-]*(?:\\([^)]*\\))?/, // Pseudo-elements/classes (:hover, ::before, :not(.x), ::-webkit-slider-thumb)\n /^\\.[a-zA-Z_-][a-zA-Z0-9_-]*/, // Class selectors (.active, .is-open)\n /^\\[[^\\]]+\\]/, // Attribute selectors ([type=\"text\"], [role])\n /^[a-z][a-z0-9-]*/, // HTML tag names (a, div, button, my-component)\n /^\\s+/, // Whitespace (ignored during parsing)\n /^&/, // Root reference (stripped, kept for backward compat)\n];\n\n/**\n * Scan a pattern for unrecognized tokens.\n *\n * Iterates through the pattern, consuming recognized tokens until\n * either the pattern is fully consumed (valid) or an unrecognized\n * character sequence is found (invalid).\n *\n * @param pattern - The selector pattern to validate\n * @returns The first unrecognized token found, or null if all tokens are valid\n *\n * @example\n * findUnrecognizedTokens('>Body>Row>') // → null (valid)\n * findUnrecognizedTokens('123') // → '123' (invalid)\n * findUnrecognizedTokens('#myId') // → '#' (invalid)\n */\nfunction findUnrecognizedTokens(pattern: string): string | null {\n let remaining = pattern;\n\n while (remaining.length > 0) {\n let matched = false;\n\n for (const regex of VALID_TOKEN_PATTERNS) {\n const match = remaining.match(regex);\n if (match) {\n remaining = remaining.slice(match[0].length);\n matched = true;\n break;\n }\n }\n\n if (!matched) {\n // Found unrecognized content - extract the problematic part\n const unrecognized = remaining.match(/^[^\\s>+~@.:[\\]A-Z]+/);\n return unrecognized ? unrecognized[0] : remaining[0];\n }\n }\n\n return null;\n}\n\n/**\n * Validate a selector pattern for structural correctness.\n *\n * Checks for:\n * 1. Out-of-scope selectors: Patterns starting with `+` or `~` target siblings\n * of the root element, which is outside the component's DOM scope.\n * 2. Consecutive combinators: Patterns like `>>` or `>+` are malformed CSS.\n * 3. Unrecognized tokens: Characters/sequences not matching valid CSS selectors.\n *\n * @param pattern - A single selector pattern (already split by comma)\n * @returns AffixResult indicating validity and error reason if invalid\n *\n * @example\n * validatePattern('>Body>Row>') // → { valid: true, selectors: [] }\n * validatePattern('+') // → { valid: false, reason: '...outside root scope...' }\n * validatePattern('>>') // → { valid: false, reason: '...consecutive combinators...' }\n */\nfunction validatePattern(pattern: string): AffixResult {\n const trimmed = pattern.trim();\n\n // Patterns starting with + or ~ target siblings of the root element,\n // which is outside the component's scope. Valid sibling patterns must\n // be preceded by an element: \">Item+\", \">Item~\"\n if (/^[+~]/.test(trimmed)) {\n return {\n valid: false,\n reason:\n `Selector affix \"${pattern}\" targets elements outside the root scope. ` +\n `Sibling selectors (+, ~) must be preceded by an element inside the root. ` +\n `Use \">Element+\" or \">Element~\" instead.`,\n };\n }\n\n // Check for consecutive combinators\n if (/[>+~]{2,}/.test(trimmed.replace(/\\s+/g, ''))) {\n return {\n valid: false,\n reason: `Selector affix \"${pattern}\" contains consecutive combinators.`,\n };\n }\n\n // Check for unrecognized tokens (e.g., lowercase text like \"foo\")\n const unrecognized = findUnrecognizedTokens(trimmed);\n if (unrecognized) {\n return {\n valid: false,\n reason:\n `Selector affix \"${pattern}\" contains unrecognized token \"${unrecognized}\". ` +\n `Valid tokens: combinators (>, +, ~), element names (Uppercase), ` +\n `@ placeholder, pseudo (:hover, ::before), class (.name), attribute ([attr]).`,\n };\n }\n\n return { valid: true, selectors: [] };\n}\n\n/**\n * Process a single selector pattern into a CSS selector suffix.\n *\n * This is the main transformation function that converts a `$` affix pattern\n * into a valid CSS selector suffix. It handles:\n *\n * 1. `@` placeholder replacement with `[data-element=\"key\"]`\n * 2. Key injection based on pattern ending (see `shouldInjectKey`)\n * 3. Proper spacing for descendant vs direct child selectors\n *\n * @param pattern - A single validated selector pattern\n * @param key - The sub-element key to inject (e.g., 'Label', 'Cell')\n * @returns CSS selector suffix ready to append to the root selector\n *\n * @example\n * processSinglePattern('>', 'Row')\n * // → '> [data-element=\"Row\"]'\n *\n * processSinglePattern('>Body>Row>', 'Cell')\n * // → '> [data-element=\"Body\"] > [data-element=\"Row\"] > [data-element=\"Cell\"]'\n *\n * processSinglePattern('&::before', 'Before')\n * // → '::before' (& attaches pseudo directly to root, no key injection)\n *\n * processSinglePattern('>@:hover', 'Item')\n * // → '> [data-element=\"Item\"]:hover'\n */\nfunction processSinglePattern(pattern: string, key: string): string {\n // Explicit & means \"attach directly to root\" (no space prefix)\n const startsWithAmpersand = pattern.startsWith('&');\n const normalized = (startsWithAmpersand ? pattern.slice(1) : pattern).trim();\n\n if (!normalized) {\n return ` [data-element=\"${key}\"]`;\n }\n\n // Pseudo-elements/classes at start (used for @ placeholder branch only)\n const startsWithPseudo = /^::?[a-z]/.test(normalized);\n\n // Transform the pattern: convert element names and normalize spacing\n let result = transformPattern(normalized);\n\n // Handle @ placeholder: explicit key injection position\n if (result.includes('@')) {\n // Remove space between @ and following class/pseudo for proper attachment\n // e.g., \"@ .active\" → \"[el].active\", but \"@ > span\" → \"[el] > span\"\n result = result.replace(/@ (?=[.:])/g, '@');\n result = result.replace(/@/g, `[data-element=\"${key}\"]`);\n\n if (!startsWithPseudo && !result.startsWith(' ')) {\n result = ' ' + result;\n }\n return result;\n }\n\n // Auto-inject key based on pattern ending (see shouldInjectKey for rules)\n if (shouldInjectKey(normalized, key)) {\n result = result + ' ' + `[data-element=\"${key}\"]`;\n }\n\n // & prefix skips space so the suffix attaches directly to the root selector\n if (!startsWithAmpersand && !result.startsWith(' ')) {\n result = ' ' + result;\n }\n\n return result;\n}\n\n/**\n * Transform a selector pattern by converting element names and normalizing spacing.\n *\n * This is a character-by-character tokenizer that:\n * - Converts uppercase names to `[data-element=\"Name\"]` selectors\n * - Adds proper spacing around combinators (>, +, ~)\n * - Preserves lowercase tags, classes, pseudos, and attributes as-is\n * - Keeps @ placeholder for later replacement\n *\n * The tokenizer handles these token types in order:\n * 1. Whitespace (skipped)\n * 2. Combinators: >, +, ~ (add surrounding spaces)\n * 3. Universal selector: * (keep as-is with spacing)\n * 4. Uppercase names: Body, Row (convert to [data-element=\"...\"])\n * 5. @ placeholder (keep for later replacement)\n * 6. Pseudo: :hover, ::before (attach to previous token)\n * 7. Tags: a, div, button (keep as-is with spacing)\n * 8. Classes: .active (attach to previous element/tag/placeholder)\n * 9. Attributes: [type=\"text\"] (keep as-is)\n *\n * @param pattern - The raw selector pattern to transform\n * @returns Transformed pattern with proper CSS selector syntax\n *\n * @example\n * transformPattern('>Body>Row>')\n * // → '> [data-element=\"Body\"] > [data-element=\"Row\"] >'\n *\n * transformPattern('button.primary:hover')\n * // → 'button.primary:hover'\n */\nfunction transformPattern(pattern: string): string {\n let result = '';\n let lastCh = '';\n let i = 0;\n\n while (i < pattern.length) {\n const char = pattern[i];\n\n if (/\\s/.test(char)) {\n i++;\n continue;\n }\n\n if (/[>+~]/.test(char)) {\n if (result && lastCh !== ' ') {\n result += ' ';\n }\n result += char;\n lastCh = char;\n i++;\n continue;\n }\n\n if (char === '*') {\n if (result && lastCh !== ' ') {\n result += ' ';\n }\n result += '*';\n lastCh = '*';\n i++;\n continue;\n }\n\n if (/[A-Z]/.test(char)) {\n const nameStart = i;\n while (i < pattern.length && /[a-zA-Z0-9]/.test(pattern[i])) {\n i++;\n }\n if (result && lastCh !== ' ') {\n result += ' ';\n }\n const segment = `[data-element=\"${pattern.slice(nameStart, i)}\"]`;\n result += segment;\n lastCh = ']';\n continue;\n }\n\n if (char === '@') {\n if (result && lastCh !== ' ') {\n result += ' ';\n }\n result += '@';\n lastCh = '@';\n i++;\n continue;\n }\n\n if (char === ':') {\n const pseudoStart = i;\n while (\n i < pattern.length &&\n !/[\\s>+~,@]/.test(pattern[i]) &&\n !/[A-Z]/.test(pattern[i])\n ) {\n i++;\n }\n const segment = pattern.slice(pseudoStart, i);\n result += segment;\n lastCh = segment[segment.length - 1] || lastCh;\n continue;\n }\n\n if (/[a-z]/.test(char)) {\n const tagStart = i;\n while (i < pattern.length && /[a-z0-9-]/.test(pattern[i])) {\n i++;\n }\n if (result && lastCh !== ' ') {\n result += ' ';\n }\n const segment = pattern.slice(tagStart, i);\n result += segment;\n lastCh = segment[segment.length - 1] || lastCh;\n continue;\n }\n\n if (char === '.') {\n const attachToLast =\n lastCh === ']' || lastCh === '@' || /[a-zA-Z0-9-]/.test(lastCh);\n if (result && !attachToLast && lastCh !== ' ') {\n result += ' ';\n }\n const clsStart = i;\n i++;\n while (i < pattern.length && /[a-zA-Z0-9_-]/.test(pattern[i])) {\n i++;\n }\n const segment = pattern.slice(clsStart, i);\n result += segment;\n lastCh = segment[segment.length - 1] || lastCh;\n continue;\n }\n\n if (char === '[') {\n const attachToLast =\n lastCh === ']' || lastCh === '@' || /[a-zA-Z0-9-]/.test(lastCh);\n if (result && !attachToLast && lastCh !== ' ') {\n result += ' ';\n }\n const attrStart = i;\n let depth = 0;\n while (i < pattern.length) {\n if (pattern[i] === '[') depth++;\n if (pattern[i] === ']') depth--;\n i++;\n if (depth === 0) break;\n }\n result += pattern.slice(attrStart, i);\n lastCh = ']';\n continue;\n }\n\n result += char;\n lastCh = char;\n i++;\n }\n\n return result;\n}\n\n/**\n * Determine if the sub-element key should be auto-injected based on pattern ending.\n *\n * Key injection rules (when no @ placeholder is present):\n *\n * | Pattern Ending | Inject Key? | Example | Result |\n * |----------------|-------------|---------|--------|\n * | Combinator (>, +, ~) | Yes | `'>Body>'` | `> [data-element=\"Body\"] > [el]` |\n * | Uppercase element | Yes | `'>Body>Row'` | `> [el1] > [el2] [key]` |\n * | Lowercase tag | No | `'h1'` | ` h1` |\n * | Universal (*) | No | `'h1 *'` | ` h1 *` |\n * | Pseudo (:hover, ::before) | No | `'::before'` | `::before` |\n * | Class (.active) | No | `'.active'` | `.active` |\n * | Attribute ([type]) | No | `'[type=\"text\"]'` | `[type=\"text\"]` |\n *\n * @param pattern - The normalized pattern (after stripping &)\n * @param key - The sub-element key being styled. If the trailing element name\n * equals this key, it acts as an explicit placeholder for the key\n * (same role as `@`) and no auto-injection happens.\n * @returns true if key should be injected, false otherwise\n *\n * @example\n * shouldInjectKey('>', 'Key') // → true (trailing combinator)\n * shouldInjectKey('>Body>Row', 'Key') // → true (ends with different element)\n * shouldInjectKey('>Body>Key', 'Key') // → false (trailing name === key)\n * shouldInjectKey('Key', 'Key') // → false (sole element === key)\n * shouldInjectKey('h1', 'Key') // → false (ends with tag)\n * shouldInjectKey('*', 'Key') // → false (universal selector)\n * shouldInjectKey('::before', 'Key') // → false (ends with pseudo)\n * shouldInjectKey('.active', 'Key') // → false (ends with class)\n * shouldInjectKey('a:hover', 'Key') // → false (ends with pseudo)\n * shouldInjectKey('button.primary', 'Key') // → false (ends with class)\n */\nfunction shouldInjectKey(pattern: string, key: string): boolean {\n const trimmed = pattern.trim();\n\n // Rule 1: Ends with combinator → inject key after it\n // e.g., '>' → '> [data-element=\"Key\"]'\n if (/[>+~]$/.test(trimmed)) {\n return true;\n }\n\n // Rule 2: Ends with uppercase element name. The lookbehind ensures we're\n // matching a standalone element name, not part of a class like .myClass.\n // If that trailing name is the sub-element's own key, it already represents\n // the target element (acts like the `@` placeholder) — no re-injection.\n // Otherwise inject the key as a descendant of the trailing element.\n // e.g., '>Body' (key=Cell) → '> [data-element=\"Body\"] [data-element=\"Cell\"]'\n // '>Body>Cell' (key=Cell) → '> [data-element=\"Body\"] > [data-element=\"Cell\"]'\n const trailingElement = trimmed.match(/(?:^|[\\s>+~\\]:])([A-Z][a-zA-Z0-9]*)$/);\n if (trailingElement) {\n return trailingElement[1] !== key;\n }\n\n // Otherwise (tags, universal *, pseudo, class, attribute) → no injection\n // The pattern is complete as-is, applying to root or a specific selector\n return false;\n}\n\n/**\n * Normalize selector suffix from $ property\n */\nfunction normalizeSelectorSuffix(suffix: string): string {\n if (!suffix) return '';\n return suffix.startsWith('&') ? suffix.slice(1) : suffix;\n}\n\n/**\n * Build handler queue from style keys\n */\nfunction buildHandlerQueue(\n styleKeys: string[],\n styles: Styles,\n): { handler: StyleHandler; styleMap: StyleMap }[] {\n const queue: { handler: StyleHandler; styleMap: StyleMap }[] = [];\n const seenHandlers = new Set<StyleHandler>();\n\n for (const styleName of styleKeys) {\n let handlers: StyleHandler[] = STYLE_HANDLER_MAP[styleName];\n\n if (!handlers) {\n handlers = STYLE_HANDLER_MAP[styleName] = [createStyle(styleName)];\n }\n\n for (const handler of handlers) {\n if (seenHandlers.has(handler)) continue;\n seenHandlers.add(handler);\n\n const lookupStyles = handler.__lookupStyles;\n const styleMap: StyleMap = {};\n\n for (const name of lookupStyles) {\n const val = styles[name];\n if (val !== undefined) {\n styleMap[name] = val as StyleValue | StyleValueStateMap;\n }\n }\n\n queue.push({ handler, styleMap });\n }\n }\n\n return queue;\n}\n\n/**\n * Compute all valid state combinations for a handler's lookup styles\n */\nfunction computeStateCombinations(\n exclusiveByStyle: Map<string, ExclusiveStyleEntry[]>,\n lookupStyles: string[],\n): {\n condition: ConditionNode;\n values: Record<string, StyleValue>;\n order: number;\n}[] {\n // Get entries for each style\n const entriesPerStyle = lookupStyles.map(\n (style) => exclusiveByStyle.get(style) || [],\n );\n\n // Cartesian product of all combinations\n const combinations = cartesianProduct(entriesPerStyle);\n\n // Build snapshots, simplifying and filtering impossible combinations\n const snapshots: {\n condition: ConditionNode;\n values: Record<string, StyleValue>;\n order: number;\n }[] = [];\n\n for (const combo of combinations) {\n // Combine all exclusive conditions with AND\n const conditions = combo.map((e) => e.exclusiveCondition);\n const combined = and(...conditions);\n const simplified = simplifyCondition(combined);\n\n // Skip impossible combinations\n if (simplified.kind === 'false') continue;\n\n // Build values map\n const values: Record<string, StyleValue> = {};\n // Cascade order = highest source priority among the contributing entries.\n let order = 0;\n for (const entry of combo) {\n values[entry.styleKey] = entry.value;\n if (entry.priority > order) order = entry.priority;\n }\n\n snapshots.push({\n condition: simplified,\n values,\n order,\n });\n }\n\n return snapshots;\n}\n\n/**\n * Cartesian product of arrays\n */\nfunction cartesianProduct<T>(arrays: T[][]): T[][] {\n if (arrays.length === 0) return [[]];\n\n const nonEmpty = arrays.filter((a) => a.length > 0);\n if (nonEmpty.length === 0) return [[]];\n\n let result: T[][] = [[]];\n for (const arr of nonEmpty) {\n const next: T[][] = [];\n for (const combo of result) {\n for (const item of arr) {\n const newCombo = new Array<T>(combo.length + 1);\n for (let i = 0; i < combo.length; i++) newCombo[i] = combo[i];\n newCombo[combo.length] = item;\n next.push(newCombo);\n }\n }\n result = next;\n }\n return result;\n}\n\nconst declStringCache = new WeakMap<Record<string, string>, string>();\n\nfunction stringifyDeclarations(decl: Record<string, string>): string {\n let cached = declStringCache.get(decl);\n if (cached === undefined) {\n cached = JSON.stringify(decl);\n declStringCache.set(decl, cached);\n }\n return cached;\n}\n\n/**\n * Merge rules with identical CSS output\n */\nfunction mergeByValue(rules: ComputedRule[]): ComputedRule[] {\n const groups = new Map<string, ComputedRule[]>();\n\n for (const rule of rules) {\n const key = `${rule.selectorSuffix}|${stringifyDeclarations(rule.declarations)}`;\n if (!groups.has(key)) {\n groups.set(key, []);\n }\n groups.get(key)!.push(rule);\n }\n\n // Merge conditions with OR for each group\n const merged: ComputedRule[] = [];\n\n for (const [, groupRules] of groups) {\n if (groupRules.length === 1) {\n merged.push(groupRules[0]);\n } else {\n // Merge conditions with OR\n const mergedCondition = simplifyCondition(\n or(...groupRules.map((r) => r.condition)),\n );\n // Take the lowest order so a merged group carrying a fallback's value\n // keeps the fallback's early cascade position.\n let order = groupRules[0].order;\n for (const r of groupRules) if (r.order < order) order = r.order;\n merged.push({\n condition: mergedCondition,\n declarations: groupRules[0].declarations,\n selectorSuffix: groupRules[0].selectorSuffix,\n order,\n });\n }\n }\n\n return merged;\n}\n\n/**\n * Build selector fragment from a variant (without className prefix)\n */\nfunction buildSelectorFromVariant(\n variant: SelectorVariant,\n selectorSuffix: string,\n): string {\n let selector = '';\n\n // Root-element state segment: flat modifiers/pseudos + :is()/:not()\n // groups, all attaching to the root element. Combine into a single\n // `:where(...)` so the whole segment carries zero specificity (the\n // doubled class is the only anchor). See `wrapWhere`.\n let rootSegment = branchToCSS([\n ...variant.modifierConditions,\n ...variant.pseudoConditions,\n ]);\n for (const group of variant.selectorGroups) {\n rootSegment += selectorGroupToCSS(group);\n }\n selector += wrapWhere(rootSegment);\n\n // Add parent selectors (before sub-element suffix). parentGroupsToCSS\n // already wraps each group in :where() so ancestor state adds no\n // specificity.\n if (variant.parentGroups.length > 0) {\n selector += parentGroupsToCSS(variant.parentGroups);\n }\n\n selector += selectorSuffix;\n\n // Sub-element (own) state segment: wrapped in its own separate\n // `:where(...)` so the sub-element's own structural specificity\n // ([data-element=\"X\"]) is preserved while its states are zeroed.\n const ownOptimized = optimizeGroups(variant.ownGroups);\n let ownSegment = '';\n for (const group of ownOptimized) {\n ownSegment += selectorGroupToCSS(group);\n }\n selector += wrapWhere(ownSegment);\n\n return selector;\n}\n\n/**\n * Materialize a computed rule to final CSS format\n *\n * Returns an array because OR conditions may generate multiple CSS rules\n * (when different branches have different at-rules)\n */\nfunction materializeComputedRule(rule: ComputedRule): CSSRule[] {\n const components = conditionToCSS(rule.condition);\n\n if (components.isImpossible || components.variants.length === 0) {\n return [];\n }\n\n const declarations = Object.entries(rule.declarations)\n .map(([prop, value]) => `${prop}: ${value};`)\n .join(' ');\n\n // Helper to get root prefix key for grouping\n const getRootPrefixKey = (variant: SelectorVariant): string => {\n return rootGroupsToCSS(variant.rootGroups) || '';\n };\n\n // Group variants by their at-rules + startingStyle (variants with same context can be combined with commas)\n const byAtRules = new Map<\n string,\n {\n variants: SelectorVariant[];\n atRules: string[];\n rootPrefix?: string;\n startingStyle?: boolean;\n }\n >();\n\n for (const variant of components.variants) {\n const atRules = buildAtRulesFromVariant(variant);\n const startingStyle = variant.startingStyle;\n const key =\n atRules.sort().join('|||') +\n '###' +\n getRootPrefixKey(variant) +\n '###' +\n (startingStyle ? '1' : '0');\n\n const group = byAtRules.get(key);\n if (group) {\n group.variants.push(variant);\n } else {\n byAtRules.set(key, {\n variants: [variant],\n atRules,\n rootPrefix: rootGroupsToCSS(variant.rootGroups),\n startingStyle: startingStyle || undefined,\n });\n }\n }\n\n // Generate one CSSRule per at-rules group\n const rules: CSSRule[] = [];\n for (const [, group] of byAtRules) {\n // Merge variants that differ only in flat modifier/pseudo conditions\n // into :is() groups before building selector strings\n const mergedVariants = mergeVariantsIntoSelectorGroups(group.variants);\n\n // Build selector fragments for each variant (will be joined with className later)\n const selectorFragments = mergedVariants.map((v) =>\n buildSelectorFromVariant(v, rule.selectorSuffix),\n );\n\n // Store as array if multiple, string if single\n const selector =\n selectorFragments.length === 1 ? selectorFragments[0] : selectorFragments;\n\n const cssRule: CSSRule = {\n selector,\n declarations,\n order: rule.order,\n };\n\n if (group.atRules.length > 0) {\n cssRule.atRules = group.atRules;\n }\n\n if (group.rootPrefix) {\n cssRule.rootPrefix = group.rootPrefix;\n }\n\n if (group.startingStyle) {\n cssRule.startingStyle = true;\n }\n\n rules.push(cssRule);\n }\n\n return rules;\n}\n\n// ============================================================================\n// StyleResult merging (group by selector + at-rules)\n// ============================================================================\n\n/**\n * Merge StyleResult entries that share the same selector and at-rules,\n * concatenating their declarations into a single rule.\n *\n * This reduces CSS output size when many style keys (e.g. design tokens)\n * resolve to the same selector/state combination.\n */\nfunction mergeStyleResults(results: StyleResult[]): StyleResult[] {\n if (results.length <= 1) return results;\n\n const groups = new Map<string, StyleResult>();\n\n for (const result of results) {\n const atKey = result.atRules?.join('|') ?? '';\n const key = `${atKey}||${result.selector}||${result.startingStyle ? '1' : '0'}`;\n\n const existing = groups.get(key);\n if (existing) {\n existing.declarations = existing.declarations\n ? `${existing.declarations} ${result.declarations}`\n : result.declarations;\n } else {\n groups.set(key, { ...result });\n }\n }\n\n return Array.from(groups.values());\n}\n\n// ============================================================================\n// Public API: renderStyles (compatible with old API)\n// ============================================================================\n\n/**\n * Options for renderStyles when using direct selector mode.\n */\ninterface RenderStylesOptions {\n /**\n * Whether to double the class selector for increased specificity.\n * When true, `.myClass` becomes `.myClass.myClass` for higher specificity.\n *\n * @default false - User-provided selectors are not doubled.\n *\n * Note: This only applies when a classNameOrSelector is provided.\n * When renderStyles returns RenderResult with needsClassName=true,\n * the injector handles doubling automatically.\n */\n doubleSelector?: boolean;\n}\n\n/**\n * Render styles to CSS rules.\n *\n * When called without classNameOrSelector, returns RenderResult with needsClassName=true.\n * When called with a selector/className string, returns StyleResult[] for direct injection.\n */\nexport function renderStyles(\n styles?: Styles,\n classNameOrSelector?: undefined,\n options?: undefined,\n pipelineCacheKey?: string,\n): RenderResult;\nexport function renderStyles(\n styles: Styles | undefined,\n classNameOrSelector: string,\n options?: RenderStylesOptions,\n): StyleResult[];\nexport function renderStyles(\n styles?: Styles,\n classNameOrSelector?: string,\n options?: RenderStylesOptions,\n pipelineCacheKey?: string,\n): RenderResult | StyleResult[] {\n // Check if we have a direct selector/className\n const directSelector = !!classNameOrSelector;\n\n // Check cache first when a pre-computed key is available.\n // This allows callers to skip building the styles object on cache hit.\n let rules: CSSRule[] | undefined;\n if (pipelineCacheKey) {\n rules = pipelineCache.get(pipelineCacheKey);\n }\n\n if (!rules && !styles) {\n return directSelector ? [] : { rules: [] };\n }\n\n // Use pre-computed cache key when available (from chunk path),\n // falling back to stringifyStyles for direct renderStyles() calls\n const cacheKey = pipelineCacheKey || stringifyStyles(styles!);\n if (!rules) {\n rules = pipelineCache.get(cacheKey);\n }\n\n if (!rules) {\n // styles is guaranteed non-null here: early return above handles (!rules && !styles)\n const parserContext = createStateParserContext(styles!);\n rules = runPipeline(styles!, parserContext);\n pipelineCache.set(cacheKey, rules);\n }\n\n // Direct selector/className mode: return StyleResult[] directly\n if (directSelector) {\n const shouldDouble = options?.doubleSelector ?? false;\n\n const results = rules.map((rule): StyleResult => {\n // Handle selector as array (OR conditions) or string\n const selectorParts = Array.isArray(rule.selector)\n ? rule.selector\n : rule.selector\n ? [rule.selector]\n : [''];\n\n const finalSelector = selectorParts\n .map((part) => {\n let sel = part\n ? `${classNameOrSelector}${part}`\n : classNameOrSelector;\n\n // Double class selector for increased specificity if requested\n // This is used when the caller explicitly wants higher specificity\n if (shouldDouble && sel.startsWith('.')) {\n const classMatch = sel.match(/^\\.[a-zA-Z_-][a-zA-Z0-9_-]*/);\n if (classMatch) {\n const baseClass = classMatch[0];\n sel = baseClass + sel;\n }\n }\n\n // Handle root prefix for this selector\n if (rule.rootPrefix) {\n sel = `${rule.rootPrefix} ${sel}`;\n }\n\n return sel;\n })\n .join(', ');\n\n const result: StyleResult = {\n selector: finalSelector,\n declarations: rule.declarations,\n };\n\n if (rule.atRules && rule.atRules.length > 0) {\n result.atRules = rule.atRules;\n }\n\n if (rule.startingStyle) {\n result.startingStyle = true;\n }\n\n return result;\n });\n\n return mergeStyleResults(results);\n }\n\n // No className mode: return RenderResult with needsClassName flag\n // Normalize selector to string (join array with placeholder that injector will handle)\n return {\n rules: rules.map(\n (r): StyleResult => ({\n selector: Array.isArray(r.selector)\n ? r.selector.join('|||')\n : r.selector,\n declarations: r.declarations,\n atRules: r.atRules,\n needsClassName: true,\n rootPrefix: r.rootPrefix,\n startingStyle: r.startingStyle,\n }),\n ),\n };\n}\n\nexport type { ConditionNode } from './conditions';\nexport { parseStateKey } from './parseStateKey';\n","export const BASE_STYLES = [\n 'display',\n 'font',\n 'preset',\n 'hide',\n 'whiteSpace',\n 'opacity',\n 'transition',\n] as const;\n\nexport const POSITION_STYLES = [\n 'gridArea',\n 'order',\n 'gridColumn',\n 'gridRow',\n 'placeSelf',\n 'alignSelf',\n 'justifySelf',\n 'zIndex',\n 'margin',\n 'inset',\n 'position',\n 'scrollMargin',\n] as const;\n\nexport const BLOCK_INNER_STYLES = [\n 'padding',\n 'paddingInline',\n 'paddingBlock',\n 'overflow',\n 'scrollbar',\n 'textAlign',\n] as const;\n\nexport const BLOCK_OUTER_STYLES = [\n 'border',\n 'radius',\n 'shadow',\n 'outline',\n] as const;\n\nexport const BLOCK_STYLES = [\n ...BLOCK_INNER_STYLES,\n ...BLOCK_OUTER_STYLES,\n] as const;\n\nexport const COLOR_STYLES = ['color', 'fill', 'fade', 'image'] as const;\n\nexport const TEXT_STYLES = [\n 'textTransform',\n 'fontWeight',\n 'fontStyle',\n] as const;\n\nexport const DIMENSION_STYLES = [\n 'width',\n 'height',\n 'flexBasis',\n 'flexGrow',\n 'flexShrink',\n 'flex',\n] as const;\n\nexport const FLOW_STYLES = [\n 'flow',\n 'place',\n 'placeItems',\n 'placeContent',\n 'alignItems',\n 'alignContent',\n 'justifyItems',\n 'justifyContent',\n 'align',\n 'justify',\n 'gap',\n 'columnGap',\n 'rowGap',\n 'gridColumns',\n 'gridRows',\n 'gridTemplate',\n 'gridAreas',\n] as const;\n\nexport const CONTAINER_STYLES = [\n ...BASE_STYLES,\n ...COLOR_STYLES,\n ...DIMENSION_STYLES,\n ...POSITION_STYLES,\n ...BLOCK_STYLES,\n ...FLOW_STYLES,\n] as const;\n\nexport const OUTER_STYLES = [\n ...POSITION_STYLES,\n ...DIMENSION_STYLES,\n ...BLOCK_OUTER_STYLES,\n] as const;\n\nexport const INNER_STYLES = [\n ...BASE_STYLES,\n ...COLOR_STYLES,\n ...BLOCK_INNER_STYLES,\n ...FLOW_STYLES,\n] as const;\n","/**\n * Registry for style properties promoted to base props on every tasty component.\n *\n * `BASE_STYLES` stays a frozen `as const` — a dozen type helpers in `src/types.ts`\n * are derived from it — so `configure({ baseStyleProps })` records the additions\n * here instead. A version counter lets each `tasty()` factory memoize its prop\n * list and refresh only when the registry changes: factories are created at module\n * eval, which can run *before* `configure()`, and `resetConfig()` (plus the\n * zero-runtime Babel worker) reopens configuration, so a one-shot lazy init would\n * go stale.\n */\n\nimport { isDevEnv } from '../utils/is-dev-env';\n\nimport { BASE_STYLES } from './list';\n\n/** Props consumed by `tasty()` itself, which a style name must never shadow. */\nconst RESERVED_PROP_NAMES = new Set<string>([\n 'as',\n 'styles',\n 'variant',\n 'mods',\n 'element',\n 'qa',\n 'qaVal',\n 'className',\n 'tokens',\n 'style',\n 'theme',\n 'children',\n 'ref',\n 'key',\n]);\n\nconst VALID_NAME = /^[a-z][a-zA-Z0-9]*$/;\n\ninterface BaseStylePropsRegistry {\n /** Style names added on top of BASE_STYLES. */\n list: readonly string[];\n /** Bumped on every change; factories compare against it to refresh their memo. */\n version: number;\n}\n\nconst GTKEY = '__tasty_base_style_props__';\n\nconst globalStore = globalThis as unknown as Record<string, unknown>;\n\nexport const baseStylePropsRegistry: BaseStylePropsRegistry =\n (globalStore[GTKEY] as BaseStylePropsRegistry | undefined) ??\n ((globalStore[GTKEY] = { list: [], version: 0 }) as BaseStylePropsRegistry);\n\n/**\n * Expose style properties as top-level props on every tasty component, in\n * addition to `BASE_STYLES`.\n *\n * Each name costs one property check per render of every component, forever, so\n * keep the list short. The effect is app-global and cannot be scoped to a subtree;\n * use a factory's own `styleProps` for anything narrower.\n */\nexport function registerBaseStyleProps(names: readonly string[]): void {\n const added: string[] = [];\n\n for (const name of names) {\n if (isDevEnv()) {\n if (!VALID_NAME.test(name)) {\n console.warn(\n `[Tasty] baseStyleProps entry \"${name}\" is invalid. Names must start ` +\n `with a lowercase letter and contain only letters and digits ` +\n `(capitalised names are sub-element selectors, and \"@\", \"$\", \"#\", ` +\n `\".\", \"&\", \"_\" prefixes are reserved).`,\n );\n continue;\n }\n\n if (RESERVED_PROP_NAMES.has(name)) {\n console.warn(\n `[Tasty] baseStyleProps entry \"${name}\" collides with a prop tasty() ` +\n `consumes itself and was ignored.`,\n );\n continue;\n }\n } else if (!VALID_NAME.test(name) || RESERVED_PROP_NAMES.has(name)) {\n continue;\n }\n\n if (\n (BASE_STYLES as readonly string[]).includes(name) ||\n baseStylePropsRegistry.list.includes(name) ||\n added.includes(name)\n ) {\n continue;\n }\n\n added.push(name);\n }\n\n if (added.length === 0) return;\n\n baseStylePropsRegistry.list = baseStylePropsRegistry.list.concat(added);\n baseStylePropsRegistry.version++;\n}\n\n/** Style names promoted via `configure({ baseStyleProps })`. */\nexport function getBaseStyleProps(): readonly string[] {\n return baseStylePropsRegistry.list;\n}\n\n/** Drop promoted base style props. Called by `resetConfig()`. */\nexport function resetBaseStyleProps(): void {\n if (baseStylePropsRegistry.list.length === 0) return;\n\n baseStylePropsRegistry.list = [];\n // Must bump on reset too, or factory memos keep the stale list.\n baseStylePropsRegistry.version++;\n}\n","import type { ConfigTokens } from '../styles/types';\n\nconst RESERVED_PRESET_NAMES = new Set([\n 'strong',\n 'bold',\n 'italic',\n 'icon',\n 'tight',\n]);\n\n/**\n * A typography token value: plain value or a state map for responsive/theme-aware presets.\n *\n * @example\n * // Plain value\n * fontWeight: '400'\n * // State map\n * fontWeight: { '': '400', '@dark': '300' }\n */\nexport type TypographyTokenValue =\n | string\n | number\n | Record<string, string | number | undefined | null | '@inherit'>;\n\n/**\n * Typography preset configuration.\n * Each preset defines font properties that get expanded into CSS custom properties.\n * All fields accept plain values or state maps for responsive/theme-aware tokens.\n *\n * Use with `generateTypographyTokens()` to create typography tokens for your design system.\n */\nexport interface TypographyPreset {\n fontSize: TypographyTokenValue;\n lineHeight: TypographyTokenValue;\n letterSpacing?: TypographyTokenValue;\n fontWeight: TypographyTokenValue;\n boldFontWeight?: TypographyTokenValue;\n iconSize?: TypographyTokenValue;\n textTransform?: TypographyTokenValue;\n fontFamily?: TypographyTokenValue;\n fontStyle?: TypographyTokenValue;\n}\n\n/**\n * Generate typography tokens with $ prefix for CSS custom properties.\n *\n * Each preset generates the following CSS custom properties:\n * - `${name}-font-size`\n * - `${name}-line-height`\n * - `${name}-letter-spacing`\n * - `${name}-font-weight`\n * - `${name}-bold-font-weight` (if defined)\n * - `${name}-icon-size` (if defined)\n * - `${name}-text-transform` (if defined)\n * - `${name}-font-family` (if defined)\n * - `${name}-font-style` (if defined)\n *\n * @param presets - Typography presets object\n * @returns ConfigTokens object with $ prefixed keys\n *\n * @example\n * const customTokens = generateTypographyTokens({\n * myHeading: { fontSize: '24px', lineHeight: '32px', fontWeight: '700' },\n * body: { fontSize: '16px', lineHeight: '24px', fontWeight: '400' },\n * });\n */\nexport function generateTypographyTokens(\n presets: Record<string, TypographyPreset>,\n): ConfigTokens {\n const tokens: ConfigTokens = {} as ConfigTokens;\n\n for (const [name, preset] of Object.entries(presets)) {\n if (RESERVED_PRESET_NAMES.has(name)) {\n throw new Error(\n `Invalid typography preset name \"${name}\". This name is reserved as a preset modifier.`,\n );\n }\n\n tokens[`$${name}-font-size`] = preset.fontSize;\n tokens[`$${name}-line-height`] = preset.lineHeight;\n tokens[`$${name}-letter-spacing`] = preset.letterSpacing ?? 'normal';\n tokens[`$${name}-font-weight`] = preset.fontWeight;\n\n if (preset.boldFontWeight !== undefined) {\n tokens[`$${name}-bold-font-weight`] = preset.boldFontWeight;\n }\n\n if (preset.iconSize !== undefined) {\n tokens[`$${name}-icon-size`] = preset.iconSize;\n }\n\n if (preset.textTransform !== undefined) {\n tokens[`$${name}-text-transform`] = preset.textTransform;\n }\n\n if (preset.fontFamily !== undefined) {\n tokens[`$${name}-font-family`] = preset.fontFamily;\n }\n\n if (preset.fontStyle !== undefined) {\n tokens[`$${name}-font-style`] = preset.fontStyle;\n }\n }\n\n return tokens;\n}\n","/**\n * Tasty Configuration Module\n *\n * Centralizes all tasty configuration, including:\n * - Style injector settings (nonce, cleanup thresholds, etc.)\n * - Global predefined states for advanced state mapping\n * - stylesGenerated flag that locks configuration after first style generation\n *\n * Configuration must be done BEFORE any styles are generated.\n * After the first `inject()` call, configuration is locked and attempts to\n * reconfigure will emit a warning and be ignored.\n */\n\nimport {\n registerFunctionPolyfill,\n resetFunctionPolyfills,\n splitFunctions,\n} from './functions';\nimport { resetStyleChunks } from './chunks/style-chunk-map';\nimport type { PropHandlerDefinition } from './prop-handlers';\nimport { registerPropHandler, resetPropHandlers } from './prop-handlers';\nimport { StyleInjector } from './injector/injector';\nimport { clearPipelineCache, isSelector, renderStyles } from './pipeline';\nimport { setGlobalPredefinedStates } from './states';\nimport {\n normalizeHandlerDefinition,\n registerHandler,\n resetHandlers,\n} from './styles/predefined';\nimport {\n registerBaseStyleProps,\n resetBaseStyleProps,\n} from './styles/base-props';\nimport { resetStyleWarnings } from './styles/shared';\nimport { isDevEnv } from './utils/is-dev-env';\nimport { DEFAULT_NAME_PREFIX, validateNamePrefix } from './utils/name-prefix';\nimport {\n CUSTOM_UNITS,\n getGlobalParseFunctions,\n getGlobalParser,\n normalizeColorTokenValue,\n resetGlobalParseFunctions,\n resetGlobalPredefinedTokens,\n setGlobalPredefinedTokens,\n} from './utils/styles';\n\nimport type { FunctionsConfig, ParseFunction } from './functions';\nimport type { ColorSpace } from './utils/color-space';\n\nimport type {\n CounterStyleDescriptors,\n FontFaceInput,\n FunctionDefinition,\n GCConfig,\n KeyframesSteps,\n PropertyDefinition,\n} from './injector/types';\nimport type { UnitHandler } from './parser/types';\nimport type { StyleResult } from './pipeline';\nimport type { TastyPlugin } from './plugins/types';\nimport type { RecipeStyles, ConfigTokens } from './styles/types';\nimport type { Styles } from './styles/types';\nimport type { StyleHandlerDefinition } from './utils/styles';\nimport type { TypographyPreset } from './utils/typography';\nimport { generateTypographyTokens } from './utils/typography';\n\n/**\n * Configuration options for the Tasty style system\n */\nexport interface TastyConfig {\n /** CSP nonce for style elements */\n nonce?: string;\n /** Maximum rules per stylesheet (default: 8192) */\n maxRulesPerSheet?: number;\n /** Force text injection mode, auto-detected in test environments (default: auto) */\n forceTextInjection?: boolean;\n /** Enable development mode features: performance metrics and debug info (default: auto) */\n devMode?: boolean;\n /**\n * Global predefined states for advanced state mapping.\n * These are state aliases that can be used in any component.\n * Example: { '@mobile': '@media(w < 920px)', '@dark': '@root(theme=dark)' }\n */\n states?: Record<string, string>;\n /**\n * Parser LRU cache size (default: 1000).\n * Larger values improve performance for apps with many unique style values.\n */\n parserCacheSize?: number;\n /**\n * Custom units for the style parser (merged with built-in units).\n * Units transform numeric values like `2x` → `calc(2 * var(--gap))`.\n * @example { em: 'em', vw: 'vw', custom: (n) => `${n * 10}px` }\n */\n units?: Record<string, string | UnitHandler>;\n /**\n * Custom functions (merged with existing). A single map holds both flavors,\n * discriminated by value type:\n *\n * - **Bare key + function value** — a parse-time function that processes the\n * parsed argument groups and returns a CSS value. Called as `name(...)`.\n * - **`$$name` key + object value** — a declarative CSS `@function`\n * definition. Called as `$$name(...)` (→ native `--name(...)`).\n *\n * A key whose prefix does not match its value type (object under a bare key,\n * or function under a `$$` key) is ignored with a dev warning.\n *\n * @example\n * ```ts\n * configure({\n * functions: {\n * double: (groups) => `calc(2 * ${groups[0].output})`, // parse function\n * $$negative: { args: ['$value'], result: '(-1 * $value)' }, // CSS function\n * },\n * });\n * ```\n */\n functions?: FunctionsConfig;\n /**\n * @deprecated No longer has any effect; will be removed in the next major.\n * Setting it warns in development.\n *\n * A `#name` token's value used to be rewritten into this color space so an\n * opacity suffix had numeric channels to write an alpha into. Opacity now uses\n * relative color syntax — `oklch(from var(--name-color) l c h / .5)` — which\n * has the browser read the channels, so a color is emitted exactly as\n * authored and there is nothing left for the setting to decide.\n *\n * To address a token's channels yourself, write relative color syntax against\n * the token: `oklch(from var(--brand-color) calc(l * 1.2) c h)`. It works on\n * every `<color>`, including the ones no conversion could evaluate.\n */\n colorSpace?: ColorSpace;\n /**\n * Automatically infer and register CSS @property declarations\n * from custom property values found in styles, keyframes, and global config.\n * Covers all types: \\<color\\>, \\<number\\>, \\<length\\>, \\<angle\\>, \\<percentage\\>, \\<time\\>.\n * When false, only explicitly declared @property are registered.\n * @default true\n */\n autoPropertyTypes?: boolean;\n /**\n * Defer stylesheet writes and apply them in one batch instead of performing\n * one `insertRule()` per component during render.\n *\n * Each `insertRule()` on a live sheet invalidates style for that sheet's\n * scope. When components inject during React's render phase while other\n * components read layout in the same pass, the two interleave and the browser\n * is forced to recalculate style between every injection. Batching collapses\n * that into one invalidation per flush.\n *\n * - `false` (default) — inject synchronously, one write per component.\n * - `true` — batch, but only inside a *batch window*: a commit in which\n * `<TastyBatchProvider>` rendered and will therefore flush in its\n * `useInsertionEffect`, before any `useLayoutEffect` runs. Any injection\n * outside a window — a deep update the provider did not re-render for, an\n * injection from a layout effect, an event handler, an async callback — is\n * written straight through. Enabling this can never make a layout effect\n * measure an unstyled element. Requires `<TastyBatchProvider>`; without it\n * nothing is batched (and dev mode says so once).\n * - `'always'` — batch every injection, flushing on a microtask when no\n * window is open. Wins on more commits, but a `useLayoutEffect` that\n * measures a freshly mounted element can read its unstyled box, because\n * microtasks run after the layout phase. Paint is unaffected: microtasks\n * always drain before the browser paints.\n *\n * No effect during SSR or RSC: styles are collected as text there, the\n * runtime injector never runs, and the provider is inert without a\n * `document`. No effect on zero-runtime `tastyStatic` styles either — those\n * are extracted at build time and never reach the injector.\n *\n * @default false\n * @example\n * ```tsx\n * configure({ batchInjection: true });\n *\n * <TastyBatchProvider>\n * <App />\n * </TastyBatchProvider>\n * ```\n */\n batchInjection?: boolean | 'always';\n /**\n * Garbage collection configuration for unused styles.\n * GC is triggered by touch count: every `touchInterval` touches, the\n * oldest unused styles are evicted when their count exceeds `capacity`.\n * @example\n * ```ts\n * configure({\n * gc: { touchInterval: 1000, capacity: 1000 },\n * });\n * ```\n */\n gc?: GCConfig;\n /**\n * Prefix prepended to every generated identifier (class names,\n * keyframe names, counter-style names). The hash is appended verbatim,\n * so include any separator inside the prefix itself (e.g. `'myapp-'`).\n *\n * Discriminator letters are inserted between the prefix and the hash\n * for non-class names so the three kinds stay visually distinct:\n * - class: `${namePrefix}${hash}` — e.g. `t1a2b3`\n * - keyframe: `${namePrefix}k${hash}` — e.g. `tk1a2b3`\n * - counter-style: `${namePrefix}c${hash}` — e.g. `tc1a2b3`\n *\n * The runtime, SSR, and RSC paths must agree on this value or\n * hydration will mismatch. The zero-runtime build path defaults to\n * `'ts'` (overridable via the same option) so its classes can't\n * collide with runtime classes when both are loaded on the same page.\n *\n * Must match `^[a-zA-Z_][a-zA-Z0-9_-]{0,31}$`. Locked once styles\n * have been generated.\n *\n * @default 't'\n */\n namePrefix?: string;\n /**\n * Plugins that extend tasty with custom functions, units, or states.\n * Plugins are processed in order, with later plugins overriding earlier ones.\n * @example\n * ```ts\n * import { okhslPlugin } from '@tenphi/tasty';\n *\n * configure({\n * plugins: [okhslPlugin()],\n * });\n * ```\n */\n plugins?: TastyPlugin[];\n /**\n * Global keyframes definitions that can be referenced by animation names in styles.\n * Keys are animation names, values are keyframes step definitions.\n * Keyframes are only injected when actually used in styles.\n * @example\n * ```ts\n * configure({\n * keyframes: {\n * fadeIn: { from: { opacity: 0 }, to: { opacity: 1 } },\n * pulse: { '0%, 100%': { transform: 'scale(1)' }, '50%': { transform: 'scale(1.05)' } },\n * },\n * });\n * ```\n */\n keyframes?: Record<string, KeyframesSteps>;\n /**\n * Global CSS @property definitions for custom properties.\n * Keys use tasty token syntax ($name for properties, #name for colors).\n *\n * Tasty ships with `DEFAULT_PROPERTIES` (e.g. `$gap`, `$radius`, `#white`,\n * `#black`, `#clear`, `#border`, etc.) that are always included.\n * Properties you specify here are merged on top, so you can override any\n * default by using the same key.\n *\n * For color tokens (#name), `syntax: '<color>'` is auto-set and\n * `initialValue` defaults to `'transparent'` if not specified.\n *\n * @example\n * ```ts\n * configure({\n * properties: {\n * '$rotation': { syntax: '<angle>', initialValue: '0deg' },\n * '$scale': { syntax: '<number>', inherits: false, initialValue: 1 },\n * '#accent': { initialValue: 'purple' }, // syntax: '<color>' auto-set\n * // Override a default property:\n * '$gap': { syntax: '<length>', inherits: true, initialValue: '8px' },\n * },\n * });\n *\n * // Now use in styles - properties are registered when component renders:\n * const Spinner = tasty({\n * styles: {\n * transform: 'rotate($rotation)',\n * transition: '$$rotation 0.3s', // outputs: --rotation 0.3s\n * },\n * });\n * ```\n */\n properties?: Record<string, PropertyDefinition>;\n /**\n * Global @font-face definitions.\n * Keys are font-family names, values are descriptors or arrays of descriptors\n * (for multiple weights/styles of the same family).\n * Injected eagerly when styles are first generated.\n * @example\n * ```ts\n * configure({\n * fontFaces: {\n * 'Brand Sans': [\n * { src: 'url(\"/fonts/brand-regular.woff2\") format(\"woff2\")', fontWeight: 400, fontDisplay: 'swap' },\n * { src: 'url(\"/fonts/brand-bold.woff2\") format(\"woff2\")', fontWeight: 700, fontDisplay: 'swap' },\n * ],\n * Icons: { src: 'url(\"/fonts/icons.woff2\") format(\"woff2\")', fontDisplay: 'block' },\n * },\n * });\n * ```\n */\n fontFaces?: Record<string, FontFaceInput>;\n /**\n * Global @counter-style definitions.\n * Keys are counter-style names, values are descriptor objects.\n * Injected eagerly when styles are first generated.\n * @example\n * ```ts\n * configure({\n * counterStyles: {\n * thumbs: { system: 'cyclic', symbols: '\"👍\"', suffix: '\" \"' },\n * },\n * });\n * ```\n */\n counterStyles?: Record<string, CounterStyleDescriptors>;\n /**\n * Opt-in polyfills for not-yet-baseline CSS features. Each key toggles a\n * feature polyfill; all default to `false`.\n *\n * - `functions` — polyfill CSS `@function` by inlining every `$$name(...)`\n * call into plain CSS (calc/var/color-mix) at parse time instead of\n * emitting the native `@function` at-rule. Enables `@function` usage in\n * browsers that don't support it yet (Firefox/Safari). Note this is the\n * `functions` *feature toggle*, distinct from the top-level `functions`\n * definitions map.\n *\n * @example\n * ```ts\n * configure({ polyfills: { functions: true } });\n * ```\n */\n polyfills?: { functions?: boolean };\n /**\n * Custom style handlers that transform style properties into CSS declarations.\n * Handlers replace built-in handlers for the same style name.\n * @example\n * ```ts\n * import { styleHandlers } from '@tenphi/tasty';\n *\n * configure({\n * handlers: {\n * // Override fill with custom behavior\n * fill: ({ fill }) => {\n * if (fill?.startsWith('gradient:')) {\n * return { background: fill.slice(9) };\n * }\n * return styleHandlers.fill({ fill });\n * },\n * // Add new custom style\n * elevation: ({ elevation }) => {\n * const level = parseInt(elevation) || 1;\n * return {\n * 'box-shadow': `0 ${level * 2}px ${level * 4}px rgba(0,0,0,0.1)`,\n * 'z-index': String(level * 100),\n * };\n * },\n * },\n * });\n * ```\n */\n handlers?: Record<string, StyleHandlerDefinition>;\n /**\n * Props middleware for every tasty component. A prop handler receives the\n * component's props and returns them, changed or not — the extension point for\n * props that are not style properties.\n *\n * The map key is the handler's name and, by default, the prop that triggers it.\n * Use `['*', fn]` for an unconditional handler, or `[['a', 'b'], fn]` to trigger\n * on any of several props.\n *\n * Handlers must be pure and must not mutate their input: style values are cached\n * by object identity, so mutating one in place yields stale CSS. Memoize the\n * styles you build per input value.\n *\n * Not applicable to zero-runtime mode — `tastyStatic()` takes styles objects, not\n * props, so there is nothing for middleware to run on. Components rendered\n * through `tasty()` are unaffected and keep the runtime injector.\n *\n * @example\n * ```ts\n * configure({\n * propHandlers: {\n * glaze: (props) => {\n * const { glaze, ...rest } = props;\n * if (!glaze) return rest;\n * return { ...rest, styles: mergeStyles(glazeStyles(glaze), rest.styles) };\n * },\n * },\n * });\n *\n * <Element glaze=\"purple\" />\n * ```\n */\n propHandlers?: Record<string, PropHandlerDefinition>;\n /**\n * Style properties exposed as top-level props on **every** tasty component, in\n * addition to the built-in base styles, without each component listing them in\n * `styleProps`.\n *\n * Augment `TastyBaseStylePropNames` to type them. Each name costs one property\n * check per render of every component, so keep the list short; the effect is\n * app-global and cannot be scoped to a subtree.\n *\n * @example\n * ```ts\n * configure({ baseStyleProps: ['radius', 'shadow'] });\n *\n * <Card radius=\"1r\" shadow />\n * ```\n */\n baseStyleProps?: readonly string[];\n /**\n * Design tokens injected as CSS custom properties on `:root`.\n * Values are parsed through the Tasty DSL. Supports state maps\n * for responsive/theme-aware tokens.\n *\n * - `$name` keys become `--name` CSS custom properties\n * - `#name` keys become `--name-color` properties\n *\n * Tokens are injected once when the first style is rendered.\n *\n * @example\n * ```ts\n * configure({\n * tokens: {\n * '$gap': '4px',\n * '#primary': {\n * '': '#purple',\n * '@dark': '#light-purple',\n * },\n * },\n * });\n * ```\n */\n tokens?: ConfigTokens;\n /**\n * Predefined tokens that are replaced during style parsing (parse-time substitution).\n * Use `$name` for custom properties and `#name` for color tokens.\n * Values are substituted inline before CSS generation, unlike `tokens` which\n * inject CSS custom properties on `:root`.\n *\n * For color tokens (#name), boolean `true` is converted to `transparent`.\n *\n * @example\n * ```ts\n * configure({\n * replaceTokens: {\n * $spacing: '2x',\n * '#accent': '#purple',\n * '#overlay': true, // → transparent\n * },\n * });\n *\n * // Now use in styles - tokens are replaced at parse time:\n * const Card = tasty({\n * styles: {\n * padding: '$spacing', // → calc(2 * var(--gap))\n * fill: '#accent', // → var(--purple-color)\n * },\n * });\n * ```\n */\n replaceTokens?: Record<`$${string}`, string | number | boolean> &\n Record<`#${string}`, string | number | boolean>;\n /**\n * Predefined style recipes -- named style bundles that can be applied via `recipe` style property.\n * Recipe values are flat tasty styles (no sub-element keys). They may contain base styles,\n * tokens (`$name`/`#name` definitions), local states, `@keyframes`, and `@property`.\n *\n * Components reference recipes via: `recipe: 'name1 name2'` in their styles.\n * Use `/` to separate base recipes from post recipes: `recipe: 'base1 base2 / post1'`.\n * Use `none` to skip base recipes: `recipe: 'none / post1'`.\n * Resolution order: `base_recipes → component styles → post_recipes`.\n *\n * Recipes cannot reference other recipes.\n *\n * @example\n * ```ts\n * configure({\n * recipes: {\n * card: { padding: '4x', fill: '#surface', radius: '1r', border: true },\n * elevated: { shadow: '2x 2x 4x #shadow' },\n * },\n * });\n *\n * // Usage in styles:\n * const Card = tasty({\n * styles: {\n * recipe: 'card elevated',\n * color: '#text', // Overrides recipe values\n * },\n * });\n * ```\n */\n recipes?: Record<string, RecipeStyles>;\n /**\n * Typography presets — shorthand for `generateTypographyTokens()`.\n * Accepts the same input and internally generates typography tokens\n * that are merged into `tokens`. Explicit `tokens` override preset-generated ones.\n *\n * @example\n * ```ts\n * configure({\n * presets: {\n * h1: { fontSize: '32px', lineHeight: '1.2', fontWeight: '700' },\n * t2: { fontSize: '16px', lineHeight: '1.5', fontWeight: '400' },\n * },\n * tokens: {\n * // Overrides the preset-generated $t2-font-weight\n * '$t2-font-weight': { '': '400', '@dark': '300' },\n * },\n * });\n * ```\n */\n presets?: Record<string, TypographyPreset>;\n /**\n * Global Tasty styles keyed by CSS selector.\n * Each entry applies the full Tasty style syntax (style properties,\n * tokens, state maps, selector-based sub-styling) to the given selector.\n * Injected alongside `:root` tokens when the first style is rendered.\n *\n * @example\n * ```ts\n * configure({\n * globalStyles: {\n * body: { fill: '#surface', color: '#text', preset: 't2', margin: 0 },\n * html: { overflow: 'hidden' },\n * },\n * });\n * ```\n */\n globalStyles?: Record<string, Styles>;\n}\n\n// Warnings tracking to avoid duplicates\nconst emittedWarnings = new Set<string>();\n\nconst devMode = isDevEnv();\n\n/**\n * Emit a warning only once\n */\nfunction warnOnce(key: string, message: string): void {\n if (devMode && !emittedWarnings.has(key)) {\n emittedWarnings.add(key);\n console.warn(message);\n }\n}\n\n// ============================================================================\n// Configuration State\n// ============================================================================\n\n// Track whether styles have been generated (locks configuration)\nlet stylesGenerated = false;\n\n// Current configuration (null until first configure() or auto-configured on first use)\nlet currentConfig: TastyConfig | null = null;\n\n// Global keyframes storage (null = no keyframes configured, empty object checked via hasGlobalKeyframes)\nlet globalKeyframes: Record<string, KeyframesSteps> | null = null;\n\n// Global font-face storage (null = no font faces configured)\nlet globalFontFace: Record<string, FontFaceInput> | null = null;\n\n// Global counter-style storage (null = no counter styles configured)\nlet globalCounterStyle: Record<string, CounterStyleDescriptors> | null = null;\n\n// Global @function storage (null = no functions configured)\nlet globalFunction: Record<string, FunctionDefinition> | null = null;\n\n// Global polyfill toggles (null = no polyfills configured)\nlet globalPolyfills: { functions?: boolean } | null = null;\n\n// Global properties storage (null = no properties configured)\nlet globalProperties: Record<string, PropertyDefinition> | null = null;\n\n// Global recipes storage (null = no recipes configured)\nlet globalRecipes: Record<string, RecipeStyles> | null = null;\n\n// Global token styles storage (injected as :root CSS custom properties)\nlet globalConfigTokens: ConfigTokens | null = null;\n\n// Global styles storage (injected as CSS for configured selectors)\nlet globalStyles: Record<string, Styles> | null = null;\n\n// ============================================================================\n// Cross-module config sharing via globalThis\n//\n// Frameworks like Astro may load middleware and page components from\n// separate module graphs, creating duplicate module-level state.\n// Config values read by SSR collector's collectInternals() are mirrored\n// to globalThis so they're accessible regardless of which module instance\n// the collector was loaded from.\n// ============================================================================\n\nconst GTKEY_TOKENS = '__tasty_cfg_tokens__';\nconst GTKEY_FONT_FACE = '__tasty_cfg_font_face__';\nconst GTKEY_COUNTER_STYLE = '__tasty_cfg_counter_style__';\nconst GTKEY_FUNCTION = '__tasty_cfg_function__';\nconst GTKEY_POLYFILLS = '__tasty_cfg_polyfills__';\nconst GTKEY_PROPERTIES = '__tasty_cfg_properties__';\nconst GTKEY_GLOBAL_STYLES = '__tasty_cfg_global_styles__';\n\nfunction setOnGlobalThis(key: string, value: unknown): void {\n (globalThis as Record<string, unknown>)[key] = value;\n}\n\nfunction getFromGlobalThis<T>(key: string): T | undefined {\n return (globalThis as Record<string, unknown>)[key] as T | undefined;\n}\n\nfunction clearGlobalThisConfig(): void {\n const g = globalThis as Record<string, unknown>;\n delete g[GTKEY_TOKENS];\n delete g[GTKEY_FONT_FACE];\n delete g[GTKEY_COUNTER_STYLE];\n delete g[GTKEY_FUNCTION];\n delete g[GTKEY_POLYFILLS];\n delete g[GTKEY_PROPERTIES];\n delete g[GTKEY_GLOBAL_STYLES];\n}\n\n/**\n * Default properties shipped with tasty.\n * These are always included unless explicitly overridden via `configure({ properties })`.\n * Keys use tasty token syntax (#name for colors, $name for other properties).\n *\n * For properties with CSS @property-compatible types (length, time, number, color),\n * an `initialValue` is provided so the property works even without a project-level token.\n */\nconst DEFAULT_PROPERTIES: Record<string, PropertyDefinition> = {\n // Used by dual-fill feature to enable CSS transitions on the second fill color\n '#tasty-second-fill': {\n inherits: false,\n initialValue: 'transparent',\n },\n // What `#current` resolves through. The `color` handler publishes it, and\n // `initial-value: currentcolor` is what makes it a true stand-in where nothing\n // has: a registered `<color>` property keeps the keyword as its computed value\n // and resolves it against each element's own color, so an unpublished\n // `#current` behaves exactly as the keyword would. `transparent` here would\n // render it invisible instead.\n '#current': {\n inherits: true,\n initialValue: 'currentcolor',\n },\n // White and black are fundamental colors that need explicit initial values.\n '#white': {\n inherits: true,\n initialValue: 'rgb(255 255 255)',\n },\n '#black': {\n inherits: true,\n initialValue: 'rgb(0 0 0)',\n },\n // Shorthand for transparent\n '#clear': {\n inherits: true,\n initialValue: 'transparent',\n },\n // Default border color\n '#border': {\n inherits: true,\n initialValue: 'rgb(0 0 0)',\n },\n\n // ---- Core design tokens used by style handlers ----\n // These provide sensible defaults so tasty works standalone without a design system.\n // Consuming projects (e.g. uikit) override these by defining tokens on :root.\n\n $gap: {\n syntax: '<length>',\n inherits: true,\n initialValue: '4px',\n },\n $radius: {\n syntax: '<length>',\n inherits: true,\n initialValue: '6px',\n },\n '$border-width': {\n syntax: '<length>',\n inherits: true,\n initialValue: '1px',\n },\n '$outline-width': {\n syntax: '<length>',\n inherits: true,\n initialValue: '3px',\n },\n $transition: {\n syntax: '<time>',\n inherits: true,\n initialValue: '80ms',\n },\n // Used by radius.ts for `radius=\"leaf\"` modifier\n '$sharp-radius': {\n syntax: '<length>',\n inherits: true,\n initialValue: '0px',\n },\n // Used by preset.ts for `preset=\"name / strong\"`\n '$bold-font-weight': {\n syntax: '<number>',\n inherits: true,\n initialValue: '700',\n },\n // Used by preset.ts as fallback font stacks\n '$font-sans-fallback': {\n syntax: '*',\n inherits: true,\n initialValue:\n 'system-ui, -apple-system, \"Segoe UI\", Roboto, Helvetica, Arial, \"Apple Color Emoji\", \"Segoe UI Emoji\", sans-serif',\n },\n '$font-mono-fallback': {\n syntax: '*',\n inherits: true,\n initialValue:\n 'ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace',\n },\n};\n\n// Global injector instance key\nconst GLOBAL_INJECTOR_KEY = '__TASTY_GLOBAL_INJECTOR__';\n\ninterface TastyGlobalStorage {\n [GLOBAL_INJECTOR_KEY]?: StyleInjector;\n}\n\ndeclare global {\n interface Window {\n [GLOBAL_INJECTOR_KEY]?: StyleInjector;\n }\n\n var __TASTY_GLOBAL_INJECTOR__: StyleInjector | undefined;\n}\n\n/**\n * Detect if we're running in a test environment\n */\nexport function isTestEnvironment(): boolean {\n // Check Node.js environment\n if (typeof process !== 'undefined' && process.env?.NODE_ENV === 'test') {\n return true;\n }\n\n // Check for test runner globals (safely)\n if (typeof global !== 'undefined') {\n const g = global as unknown as Record<string, unknown>;\n if (g.vi || g.jest || g.expect || g.describe || g.it) {\n return true;\n }\n }\n\n // Check for simulated DOM environments (common in tests)\n if (typeof window !== 'undefined') {\n const ua = window.navigator?.userAgent;\n if (ua?.includes('jsdom') || ua?.includes('HappyDOM')) {\n return true;\n }\n }\n\n // Check for other test runners\n if (typeof globalThis !== 'undefined') {\n const gt = globalThis as unknown as Record<string, unknown>;\n if (gt.vitest || gt.mocha) {\n return true;\n }\n }\n\n return false;\n}\n\n/**\n * Create default configuration with optional test environment detection\n */\nfunction createDefaultConfig(isTest?: boolean): TastyConfig {\n return {\n maxRulesPerSheet: 8192,\n forceTextInjection: isTest ?? false,\n devMode: isDevEnv(),\n namePrefix: DEFAULT_NAME_PREFIX,\n };\n}\n\n// ============================================================================\n// stylesGenerated Flag Management\n// ============================================================================\n\n/**\n * Mark that styles have been generated (called by injector on first inject)\n * This locks the configuration - no further changes allowed.\n * Also injects internal and global properties.\n */\nexport function markStylesGenerated(): void {\n if (stylesGenerated) return; // Already marked, skip\n\n stylesGenerated = true;\n\n // When SSR styles are already in the document, the SSR collector's\n // collectInternals() already rendered tokens, @property, globalStyles,\n // @font-face, and @counter-style. Skip client-side injection to avoid\n // duplicate CSS rules.\n if (\n typeof document !== 'undefined' &&\n document.querySelector('style[data-tasty-ssr]')\n ) {\n warnOnce(\n 'ssr-globals-skip',\n '[Tasty] SSR styles detected — skipping client-side global CSS injection to avoid duplicates.',\n );\n return;\n }\n\n const injector = getGlobalInjector();\n\n // Inject all properties (defaults merged with user-configured overrides)\n for (const [token, definition] of Object.entries(getEffectiveProperties())) {\n injector.property(token, definition);\n }\n\n // Inject global @font-face rules (eagerly — fonts should be available before render)\n if (globalFontFace && Object.keys(globalFontFace).length > 0) {\n for (const [family, input] of Object.entries(globalFontFace)) {\n const descriptors = Array.isArray(input) ? input : [input];\n for (const desc of descriptors) {\n injector.fontFace(family, desc);\n }\n }\n }\n\n // Inject global @counter-style rules (eagerly, weakly — never override a\n // component-local definition of the same name)\n if (globalCounterStyle && Object.keys(globalCounterStyle).length > 0) {\n for (const [name, descriptors] of Object.entries(globalCounterStyle)) {\n injector.counterStyle(name, descriptors, { weak: true });\n }\n }\n\n // Inject global @function rules (eagerly, weakly — never override a\n // component-local definition of the same name)\n if (globalFunction && Object.keys(globalFunction).length > 0) {\n for (const [name, definition] of Object.entries(globalFunction)) {\n injector.func(name, definition, { weak: true });\n }\n }\n\n // Inject configured tokens as :root CSS custom properties\n if (globalConfigTokens && Object.keys(globalConfigTokens).length > 0) {\n const tokenRules = renderStyles(\n globalConfigTokens,\n ':root',\n ) as StyleResult[];\n if (tokenRules.length > 0) {\n injector.injectGlobal(tokenRules);\n }\n }\n\n // Inject configured global styles\n if (globalStyles) {\n for (const [selector, styles] of Object.entries(globalStyles)) {\n if (Object.keys(styles).length > 0) {\n const rules = renderStyles(styles, selector) as StyleResult[];\n if (rules.length > 0) {\n injector.injectGlobal(rules);\n }\n }\n }\n }\n}\n\n/**\n * Check if styles have been generated (configuration is locked)\n */\nexport function hasStylesGenerated(): boolean {\n return stylesGenerated;\n}\n\n/**\n * Reset styles generated flag (for testing only)\n */\nexport function resetStylesGenerated(): void {\n stylesGenerated = false;\n emittedWarnings.clear();\n}\n\n// ============================================================================\n// Global Keyframes Management\n// ============================================================================\n\nlet _hasGlobalKeyframes = false;\n\n/**\n * Check if any global keyframes are configured.\n * Uses a pre-computed flag to avoid Object.keys() allocation on every call.\n */\nexport function hasGlobalKeyframes(): boolean {\n return _hasGlobalKeyframes;\n}\n\n/**\n * Get global keyframes configuration.\n * Returns null if no keyframes configured (fast path for zero-overhead).\n */\nexport function getGlobalKeyframes(): Record<string, KeyframesSteps> | null {\n return globalKeyframes;\n}\n\n/**\n * Set global keyframes (called from configure).\n * Internal use only.\n */\nfunction setGlobalKeyframes(keyframes: Record<string, KeyframesSteps>): void {\n if (stylesGenerated) {\n warnOnce(\n 'keyframes-after-styles',\n `[Tasty] Cannot update keyframes after styles have been generated.\\n` +\n `The new keyframes will be ignored.`,\n );\n return;\n }\n globalKeyframes = { ...(globalKeyframes ?? {}), ...keyframes };\n _hasGlobalKeyframes = Object.keys(globalKeyframes).length > 0;\n}\n\n// ============================================================================\n// Global Properties Management\n// ============================================================================\n\n/**\n * Set global properties (called from configure).\n * Internal use only.\n */\nfunction setGlobalProperties(\n properties: Record<string, PropertyDefinition>,\n): void {\n if (stylesGenerated) {\n warnOnce(\n 'properties-after-styles',\n `[Tasty] Cannot update properties after styles have been generated.\\n` +\n `The new properties will be ignored.`,\n );\n return;\n }\n // Merge against the raw user map, not getEffectiveProperties(), which would\n // bake DEFAULT_PROPERTIES into it.\n globalProperties = {\n ...(globalProperties ?? getFromGlobalThis(GTKEY_PROPERTIES) ?? {}),\n ...properties,\n };\n setOnGlobalThis(GTKEY_PROPERTIES, globalProperties);\n}\n\n/**\n * Get the effective properties: DEFAULT_PROPERTIES merged with user-configured\n * properties. User properties override defaults with matching keys.\n * Reads from globalThis first for cross-module SSR support.\n */\nexport function getEffectiveProperties(): Record<string, PropertyDefinition> {\n const props =\n globalProperties ??\n getFromGlobalThis<Record<string, PropertyDefinition>>(GTKEY_PROPERTIES);\n if (!props) return DEFAULT_PROPERTIES;\n return { ...DEFAULT_PROPERTIES, ...props };\n}\n\n// ============================================================================\n// Global Font Face Management\n// ============================================================================\n\n/**\n * Get global font-face configuration.\n * Returns null if no font faces configured.\n * Reads from globalThis first for cross-module SSR support.\n */\nexport function getGlobalFontFaces(): Record<string, FontFaceInput> | null {\n return (\n globalFontFace ??\n getFromGlobalThis<Record<string, FontFaceInput>>(GTKEY_FONT_FACE) ??\n null\n );\n}\n\n/**\n * Set global font faces (called from configure).\n * Internal use only.\n */\nfunction setGlobalFontFace(fontFace: Record<string, FontFaceInput>): void {\n if (stylesGenerated) {\n warnOnce(\n 'fontface-after-styles',\n `[Tasty] Cannot update fontFaces after styles have been generated.\\n` +\n `The new font faces will be ignored.`,\n );\n return;\n }\n globalFontFace = { ...(getGlobalFontFaces() ?? {}), ...fontFace };\n setOnGlobalThis(GTKEY_FONT_FACE, globalFontFace);\n}\n\n// ============================================================================\n// Global Counter Style Management\n// ============================================================================\n\n/**\n * Get global counter-style configuration.\n * Returns null if no counter styles configured.\n * Reads from globalThis first for cross-module SSR support.\n */\nexport function getGlobalCounterStyles(): Record<\n string,\n CounterStyleDescriptors\n> | null {\n return (\n globalCounterStyle ??\n getFromGlobalThis<Record<string, CounterStyleDescriptors>>(\n GTKEY_COUNTER_STYLE,\n ) ??\n null\n );\n}\n\n/**\n * Set global counter styles (called from configure).\n * Internal use only.\n */\nfunction setGlobalCounterStyle(\n counterStyle: Record<string, CounterStyleDescriptors>,\n): void {\n if (stylesGenerated) {\n warnOnce(\n 'counterstyle-after-styles',\n `[Tasty] Cannot update counterStyles after styles have been generated.\\n` +\n `The new counter styles will be ignored.`,\n );\n return;\n }\n globalCounterStyle = { ...(getGlobalCounterStyles() ?? {}), ...counterStyle };\n setOnGlobalThis(GTKEY_COUNTER_STYLE, globalCounterStyle);\n}\n\n// ============================================================================\n// Global Function Management\n// ============================================================================\n\n/**\n * Get global @function configuration.\n * Returns null if no functions configured.\n * Reads from globalThis first for cross-module SSR support.\n */\nexport function getGlobalFunctions(): Record<\n string,\n FunctionDefinition\n> | null {\n return (\n globalFunction ??\n getFromGlobalThis<Record<string, FunctionDefinition>>(GTKEY_FUNCTION) ??\n null\n );\n}\n\n/**\n * Set global functions (called from configure).\n * Internal use only.\n */\nfunction setGlobalFunction(\n functions: Record<string, FunctionDefinition>,\n): void {\n if (stylesGenerated) {\n warnOnce(\n 'function-after-styles',\n `[Tasty] Cannot update functions after styles have been generated.\\n` +\n `The new functions will be ignored.`,\n );\n return;\n }\n globalFunction = { ...(getGlobalFunctions() ?? {}), ...functions };\n setOnGlobalThis(GTKEY_FUNCTION, globalFunction);\n}\n\n// ============================================================================\n// Polyfills Management\n// ============================================================================\n\n/**\n * Whether the CSS `@function` polyfill (inline expansion) is enabled.\n * Reads from globalThis first for cross-module SSR/zero-runtime support.\n */\nexport function isFunctionsPolyfillEnabled(): boolean {\n const polyfills =\n globalPolyfills ??\n getFromGlobalThis<{ functions?: boolean }>(GTKEY_POLYFILLS) ??\n null;\n return polyfills?.functions === true;\n}\n\n/**\n * Set global polyfill toggles (called from configure).\n * Internal use only.\n */\nfunction setGlobalPolyfills(polyfills: { functions?: boolean }): void {\n if (stylesGenerated) {\n warnOnce(\n 'polyfills-after-styles',\n `[Tasty] Cannot update polyfills after styles have been generated.\\n` +\n `The new polyfill toggles will be ignored.`,\n );\n return;\n }\n\n globalPolyfills = { ...(globalPolyfills ?? {}), ...polyfills };\n setOnGlobalThis(GTKEY_POLYFILLS, globalPolyfills);\n}\n\n// ============================================================================\n// Global Recipes Management\n// ============================================================================\n\n/**\n * Check if any global recipes are configured.\n * Fast path: returns false if no recipes were ever set.\n */\nexport function hasGlobalRecipes(): boolean {\n return globalRecipes !== null && Object.keys(globalRecipes).length > 0;\n}\n\n/**\n * Get global recipes configuration.\n * Returns null if no recipes configured (fast path for zero-overhead).\n */\nexport function getGlobalRecipes(): Record<string, RecipeStyles> | null {\n return globalRecipes;\n}\n\n/**\n * Set global recipes (called from configure).\n * Internal use only.\n */\nfunction setGlobalRecipes(recipes: Record<string, RecipeStyles>): void {\n if (stylesGenerated) {\n warnOnce(\n 'recipes-after-styles',\n `[Tasty] Cannot update recipes after styles have been generated.\\n` +\n `The new recipes will be ignored.`,\n );\n return;\n }\n\n // Dev-mode validation\n if (devMode) {\n for (const [name, recipeStyles] of Object.entries(recipes)) {\n if (name === 'none') {\n warnOnce(\n 'recipe-reserved-none',\n `[Tasty] Recipe name \"none\" is reserved. ` +\n `It is used as a keyword meaning \"no base recipes\" ` +\n `(e.g. recipe: 'none / post-recipe'). ` +\n `Choose a different name for your recipe.`,\n );\n }\n\n for (const key of Object.keys(recipeStyles)) {\n if (isSelector(key)) {\n warnOnce(\n `recipe-selector-${name}-${key}`,\n `[Tasty] Recipe \"${name}\" contains sub-element key \"${key}\". ` +\n `Recipes must be flat styles without sub-element keys. ` +\n `Remove the sub-element key from the recipe definition.`,\n );\n }\n if (key === 'recipe') {\n warnOnce(\n `recipe-recursive-${name}`,\n `[Tasty] Recipe \"${name}\" contains a \"recipe\" key. ` +\n `Recipes cannot reference other recipes. ` +\n `Use space-separated names for composition: recipe: 'base elevated'.`,\n );\n }\n }\n }\n }\n\n globalRecipes = { ...(globalRecipes ?? {}), ...recipes };\n}\n\n// ============================================================================\n// Global Token Styles Management\n// ============================================================================\n\n/**\n * Get global token styles for :root injection.\n * Returns null if no tokens configured.\n * Reads from globalThis first for cross-module SSR support.\n */\nexport function getGlobalConfigTokens(): ConfigTokens | null {\n return (\n globalConfigTokens ?? getFromGlobalThis<ConfigTokens>(GTKEY_TOKENS) ?? null\n );\n}\n\n/**\n * Set global token styles (called from configure).\n * Internal use only.\n */\nfunction setGlobalConfigTokens(styles: ConfigTokens): void {\n if (stylesGenerated) {\n warnOnce(\n 'tokens-after-styles',\n `[Tasty] Cannot update tokens after styles have been generated.\\n` +\n `The new tokens will be ignored.`,\n );\n return;\n }\n globalConfigTokens = globalConfigTokens\n ? { ...globalConfigTokens, ...styles }\n : styles;\n setOnGlobalThis(GTKEY_TOKENS, globalConfigTokens);\n}\n\n// ============================================================================\n// Global Styles Management\n// ============================================================================\n\n/**\n * Get configured global styles for injection.\n * Returns null if no global styles configured.\n * Reads from globalThis first for cross-module SSR support.\n */\nexport function getGlobalStyles(): Record<string, Styles> | null {\n return (\n globalStyles ??\n getFromGlobalThis<Record<string, Styles>>(GTKEY_GLOBAL_STYLES) ??\n null\n );\n}\n\n/**\n * Set configured global styles (called from configure).\n * Internal use only.\n */\nfunction setGlobalStyles(styles: Record<string, Styles>): void {\n if (stylesGenerated) {\n warnOnce(\n 'globalStyles-after-styles',\n `[Tasty] Cannot update globalStyles after styles have been generated.\\n` +\n `The new global styles will be ignored.`,\n );\n return;\n }\n if (globalStyles) {\n for (const [selector, selectorStyles] of Object.entries(styles)) {\n globalStyles[selector] = globalStyles[selector]\n ? { ...globalStyles[selector], ...selectorStyles }\n : selectorStyles;\n }\n } else {\n globalStyles = { ...styles };\n }\n setOnGlobalThis(GTKEY_GLOBAL_STYLES, globalStyles);\n}\n\n/**\n * Check if configuration is locked (styles have been generated)\n */\nexport function isConfigLocked(): boolean {\n return stylesGenerated;\n}\n\n// ============================================================================\n// Configuration API\n// ============================================================================\n\n/**\n * Configure the Tasty style system.\n *\n * Must be called BEFORE any styles are generated (before first render that uses tasty).\n * After styles are generated, configuration is locked and calls to configure() will\n * emit a warning and be ignored.\n *\n * @example\n * ```ts\n * import { configure } from '@tenphi/tasty';\n *\n * // Configure before app renders\n * configure({\n * nonce: 'abc123',\n * states: {\n * '@mobile': '@media(w < 768px)',\n * '@dark': '@root(theme=dark)',\n * },\n * });\n * ```\n */\nexport function configure(config: Partial<TastyConfig> = {}): void {\n if (stylesGenerated) {\n warnOnce(\n 'configure-after-styles',\n `[Tasty] Cannot call configure() after styles have been generated.\\n` +\n `Configuration must be done before the first render. The configuration will be ignored.`,\n );\n return;\n }\n\n // Validate namePrefix early so misconfiguration fails loudly before any\n // CSS is generated under a bad prefix.\n if (config.namePrefix !== undefined) {\n validateNamePrefix(config.namePrefix);\n }\n\n // Collect merged values from plugins first, then override with direct config\n let mergedStates: Record<string, string> = {};\n let mergedUnits: Record<string, string | UnitHandler> = {};\n let mergedFunctions: FunctionsConfig = {};\n let mergedHandlers: Record<string, StyleHandlerDefinition> = {};\n /** Where each handler key came from, so registration warnings can name it. */\n const handlerSources = new Map<string, string>();\n let mergedPropHandlers: Record<string, PropHandlerDefinition> = {};\n /** Where each prop handler key came from, for its warnings. */\n const propHandlerSources = new Map<string, string>();\n const mergedBaseStyleProps: string[] = [];\n let mergedProperties: Record<string, PropertyDefinition> = {};\n let mergedKeyframes: Record<string, KeyframesSteps> = {};\n let mergedFontFaces: Record<string, FontFaceInput> = {};\n let mergedCounterStyles: Record<string, CounterStyleDescriptors> = {};\n let mergedReplaceTokens: Record<string, string | number | boolean> = {};\n let mergedConfigTokens: ConfigTokens = {} as ConfigTokens;\n let mergedRecipes: Record<string, RecipeStyles> = {};\n let mergedPresets: Record<string, TypographyPreset> = {};\n const mergedGlobalStyles: Record<string, Styles> = {};\n\n // Process plugins in order\n if (config.plugins) {\n for (const plugin of config.plugins) {\n if (plugin.states) {\n mergedStates = { ...mergedStates, ...plugin.states };\n }\n if (plugin.units) {\n mergedUnits = { ...mergedUnits, ...plugin.units };\n }\n if (plugin.functions) {\n mergedFunctions = { ...mergedFunctions, ...plugin.functions };\n }\n if (plugin.handlers) {\n mergedHandlers = { ...mergedHandlers, ...plugin.handlers };\n for (const key of Object.keys(plugin.handlers)) {\n handlerSources.set(key, `plugin \"${plugin.name}\"`);\n }\n }\n if (plugin.propHandlers) {\n mergedPropHandlers = { ...mergedPropHandlers, ...plugin.propHandlers };\n for (const key of Object.keys(plugin.propHandlers)) {\n propHandlerSources.set(key, `plugin \"${plugin.name}\"`);\n }\n }\n if (plugin.baseStyleProps) {\n mergedBaseStyleProps.push(...plugin.baseStyleProps);\n }\n if (plugin.properties) {\n mergedProperties = { ...mergedProperties, ...plugin.properties };\n }\n if (plugin.keyframes) {\n mergedKeyframes = { ...mergedKeyframes, ...plugin.keyframes };\n }\n if (plugin.fontFaces) {\n mergedFontFaces = { ...mergedFontFaces, ...plugin.fontFaces };\n }\n if (plugin.counterStyles) {\n mergedCounterStyles = {\n ...mergedCounterStyles,\n ...plugin.counterStyles,\n };\n }\n if (plugin.replaceTokens) {\n mergedReplaceTokens = {\n ...mergedReplaceTokens,\n ...plugin.replaceTokens,\n };\n }\n if (plugin.tokens) {\n mergedConfigTokens = { ...mergedConfigTokens, ...plugin.tokens };\n }\n if (plugin.recipes) {\n mergedRecipes = { ...mergedRecipes, ...plugin.recipes };\n }\n if (plugin.presets) {\n mergedPresets = { ...mergedPresets, ...plugin.presets };\n }\n if (plugin.globalStyles) {\n for (const [sel, styles] of Object.entries(plugin.globalStyles)) {\n mergedGlobalStyles[sel] = mergedGlobalStyles[sel]\n ? { ...mergedGlobalStyles[sel], ...styles }\n : styles;\n }\n }\n }\n }\n\n // Direct config overrides plugins\n if (config.states) {\n mergedStates = { ...mergedStates, ...config.states };\n }\n if (config.units) {\n mergedUnits = { ...mergedUnits, ...config.units };\n }\n if (config.functions) {\n mergedFunctions = { ...mergedFunctions, ...config.functions };\n }\n if (config.handlers) {\n mergedHandlers = { ...mergedHandlers, ...config.handlers };\n for (const key of Object.keys(config.handlers)) {\n handlerSources.set(key, 'configure()');\n }\n }\n if (config.propHandlers) {\n mergedPropHandlers = { ...mergedPropHandlers, ...config.propHandlers };\n for (const key of Object.keys(config.propHandlers)) {\n propHandlerSources.set(key, 'configure()');\n }\n }\n if (config.baseStyleProps) {\n mergedBaseStyleProps.push(...config.baseStyleProps);\n }\n if (config.properties) {\n mergedProperties = { ...mergedProperties, ...config.properties };\n }\n if (config.keyframes) {\n mergedKeyframes = { ...mergedKeyframes, ...config.keyframes };\n }\n if (config.fontFaces) {\n mergedFontFaces = { ...mergedFontFaces, ...config.fontFaces };\n }\n if (config.counterStyles) {\n mergedCounterStyles = { ...mergedCounterStyles, ...config.counterStyles };\n }\n if (config.replaceTokens) {\n mergedReplaceTokens = { ...mergedReplaceTokens, ...config.replaceTokens };\n }\n if (config.presets) {\n mergedPresets = { ...mergedPresets, ...config.presets };\n }\n\n // Generate typography tokens from presets and merge UNDER explicit tokens\n if (Object.keys(mergedPresets).length > 0) {\n const presetTokens = generateTypographyTokens(mergedPresets);\n mergedConfigTokens = {\n ...presetTokens,\n ...mergedConfigTokens,\n };\n }\n\n if (config.tokens) {\n mergedConfigTokens = { ...mergedConfigTokens, ...config.tokens };\n }\n if (config.recipes) {\n mergedRecipes = { ...mergedRecipes, ...config.recipes };\n }\n if (config.globalStyles) {\n for (const [sel, styles] of Object.entries(config.globalStyles)) {\n mergedGlobalStyles[sel] = mergedGlobalStyles[sel]\n ? { ...mergedGlobalStyles[sel], ...styles }\n : styles;\n }\n }\n\n // Warn on tokens/replaceTokens key conflicts\n if (devMode) {\n const tokenKeys = new Set(Object.keys(mergedConfigTokens));\n for (const key of Object.keys(mergedReplaceTokens)) {\n if (tokenKeys.has(key)) {\n warnOnce(\n `token-conflict-${key}`,\n `[Tasty] Token \"${key}\" is defined in both \\`tokens\\` and \\`replaceTokens\\`. ` +\n `\\`replaceTokens\\` performs parse-time substitution, so the \\`tokens\\` ` +\n `CSS custom property will be injected but never used by Tasty styles. ` +\n `Remove it from one of the two.`,\n );\n }\n }\n }\n\n if (config.colorSpace) {\n warnOnce(\n 'colorSpace-deprecated',\n '[Tasty] configure({ colorSpace }) no longer has any effect and will be ' +\n 'removed in the next major. Colors are emitted as authored, and opacity ' +\n \"is applied with relative color syntax, which reads a color's channels \" +\n 'in the browser. To address channels yourself, write ' +\n '`oklch(from var(--name-color) l c h)` against the token.',\n );\n }\n\n // Handle predefined states\n if (Object.keys(mergedStates).length > 0) {\n setGlobalPredefinedStates(mergedStates);\n }\n\n // Handle parser configuration (merge semantics - extend, not replace)\n const parser = getGlobalParser();\n\n if (config.parserCacheSize !== undefined) {\n parser.updateOptions({ cacheSize: config.parserCacheSize });\n }\n\n if (Object.keys(mergedUnits).length > 0) {\n // Merge with existing units\n const currentUnits = parser.getUnits() ?? CUSTOM_UNITS;\n parser.setUnits({ ...currentUnits, ...mergedUnits });\n }\n\n // Record polyfill toggles before processing functions so we know whether to\n // register inline closures or emit native @function rules.\n if (config.polyfills) {\n setGlobalPolyfills(config.polyfills);\n }\n\n // Split the unified `functions` map by value type into parse functions\n // (bare keys) and declarative CSS @function definitions (`$$` keys).\n const { parseFuncs, functionDefs } = splitFunctions(\n mergedFunctions,\n (key, kind) => {\n warnOnce(\n `functions-mismatch-${key}`,\n kind === 'expected-definition'\n ? `[Tasty] functions[\"${key}\"]: a \"$$\"-prefixed key denotes a CSS @function ` +\n `and expects a definition object, but received a function. Entry ignored.`\n : `[Tasty] functions[\"${key}\"]: a bare key denotes a parse function and ` +\n `expects a function value, but received an object. ` +\n `Did you mean \"$$${key}\"? Entry ignored.`,\n );\n },\n );\n\n if (Object.keys(parseFuncs).length > 0) {\n // Merge with existing parse functions\n const currentFuncs = getGlobalParseFunctions();\n const finalFuncs: Record<string, ParseFunction> = {\n ...currentFuncs,\n ...parseFuncs,\n };\n parser.setFunctions(finalFuncs);\n // Also update the global registry so customFunction() continues to work\n Object.assign(currentFuncs, parseFuncs);\n }\n\n // Declarative CSS @function definitions. When the polyfill is enabled, compile\n // each into an inline parse-function closure (and skip native emission);\n // otherwise store them for eager native @function injection.\n if (Object.keys(functionDefs).length > 0) {\n if (isFunctionsPolyfillEnabled()) {\n for (const [name, definition] of Object.entries(functionDefs)) {\n registerFunctionPolyfill(name, definition);\n }\n } else {\n setGlobalFunction(functionDefs);\n }\n }\n\n // Handle keyframes\n if (Object.keys(mergedKeyframes).length > 0) {\n setGlobalKeyframes(mergedKeyframes);\n }\n\n // Handle properties\n if (Object.keys(mergedProperties).length > 0) {\n setGlobalProperties(mergedProperties);\n }\n\n // Handle font faces\n if (Object.keys(mergedFontFaces).length > 0) {\n setGlobalFontFace(mergedFontFaces);\n }\n\n // Handle counter styles\n if (Object.keys(mergedCounterStyles).length > 0) {\n setGlobalCounterStyle(mergedCounterStyles);\n }\n\n // Handle custom handlers\n if (Object.keys(mergedHandlers).length > 0) {\n for (const [name, definition] of Object.entries(mergedHandlers)) {\n const handler = normalizeHandlerDefinition(name, definition);\n registerHandler(handler, {\n key: name,\n source: handlerSources.get(name),\n });\n }\n }\n\n // Handle props middleware\n if (Object.keys(mergedPropHandlers).length > 0) {\n for (const [name, definition] of Object.entries(mergedPropHandlers)) {\n registerPropHandler(name, definition, {\n source: propHandlerSources.get(name),\n });\n }\n }\n\n // Handle promoted base style props\n if (mergedBaseStyleProps.length > 0) {\n registerBaseStyleProps(mergedBaseStyleProps);\n }\n\n // Handle replaceTokens (parse-time substitution)\n if (Object.keys(mergedReplaceTokens).length > 0) {\n const processedTokens: Record<string, string> = {};\n for (const [key, value] of Object.entries(mergedReplaceTokens)) {\n if (key.startsWith('#')) {\n const normalized = normalizeColorTokenValue(value);\n if (normalized === null) continue;\n processedTokens[key] = String(normalized);\n } else if (value === false) {\n continue;\n } else {\n processedTokens[key] = String(value);\n }\n }\n setGlobalPredefinedTokens(processedTokens);\n }\n\n // Handle tokens (CSS custom properties on :root)\n if (Object.keys(mergedConfigTokens).length > 0) {\n setGlobalConfigTokens(mergedConfigTokens);\n }\n\n // Handle recipes\n if (Object.keys(mergedRecipes).length > 0) {\n setGlobalRecipes(mergedRecipes);\n }\n\n // Handle global styles\n if (Object.keys(mergedGlobalStyles).length > 0) {\n setGlobalStyles(mergedGlobalStyles);\n }\n\n const {\n states: _states,\n parserCacheSize: _parserCacheSize,\n units: _units,\n functions: _functions,\n polyfills: _polyfills,\n plugins: _plugins,\n keyframes: _keyframes,\n properties: _properties,\n fontFaces: _fontFaces,\n counterStyles: _counterStyles,\n handlers: _handlers,\n propHandlers: _propHandlers,\n baseStyleProps: _baseStyleProps,\n tokens: _tokens,\n replaceTokens: _replaceTokens,\n recipes: _recipes,\n colorSpace: _colorSpace,\n presets: _presets,\n globalStyles: _globalStyles,\n ...injectorConfig\n } = config;\n\n const fullConfig: TastyConfig = {\n ...createDefaultConfig(),\n ...currentConfig,\n ...injectorConfig,\n };\n\n // Store the config\n currentConfig = fullConfig;\n\n // Create/replace the global injector\n const storage: TastyGlobalStorage =\n typeof window !== 'undefined' ? window : globalThis;\n storage[GLOBAL_INJECTOR_KEY] = new StyleInjector(fullConfig);\n}\n\n/**\n * Get the current configuration.\n * If not configured, returns default configuration.\n */\nexport function getConfig(): TastyConfig {\n if (!currentConfig) {\n currentConfig = createDefaultConfig(isTestEnvironment());\n }\n return currentConfig;\n}\n\n/**\n * Get the configured prefix used for every generated identifier\n * (class names, keyframe names, counter-style names).\n *\n * Falls back to the default prefix (`'t'`) when `configure()` has not\n * been called yet — this matches the auto-configuration behavior used\n * by the rest of the system.\n */\nexport function getNamePrefix(): string {\n return currentConfig?.namePrefix ?? DEFAULT_NAME_PREFIX;\n}\n\n/**\n * Get the global injector instance.\n * Auto-configures with defaults if not already configured.\n */\nexport function getGlobalInjector(): StyleInjector {\n const storage: TastyGlobalStorage =\n typeof window !== 'undefined' ? window : globalThis;\n\n if (!storage[GLOBAL_INJECTOR_KEY]) {\n configure();\n }\n\n return storage[GLOBAL_INJECTOR_KEY]!;\n}\n\n/**\n * Reset configuration (for testing only).\n * Clears the global injector and allows reconfiguration.\n */\nexport function resetConfig(): void {\n stylesGenerated = false;\n currentConfig = null;\n globalKeyframes = null;\n _hasGlobalKeyframes = false;\n globalProperties = null;\n globalFontFace = null;\n globalCounterStyle = null;\n globalFunction = null;\n globalPolyfills = null;\n globalRecipes = null;\n globalConfigTokens = null;\n globalStyles = null;\n clearGlobalThisConfig();\n resetGlobalPredefinedTokens();\n resetGlobalParseFunctions();\n resetFunctionPolyfills();\n resetHandlers();\n resetStyleChunks();\n resetPropHandlers();\n resetBaseStyleProps();\n clearPipelineCache();\n emittedWarnings.clear();\n resetStyleWarnings();\n\n const storage: TastyGlobalStorage =\n typeof window !== 'undefined' ? window : globalThis;\n delete storage[GLOBAL_INJECTOR_KEY];\n}\n"],"mappings":"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"}