@tenphi/tasty 3.9.11 → 3.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +399 -380
- package/dist/babel-types-BKDTT4--.d.ts +18 -0
- package/dist/chunks/async-storage-f9j9JRtq.js +37 -0
- package/dist/chunks/async-storage-f9j9JRtq.js.map +1 -0
- package/dist/chunks/build-config-5d8WlQbq.js +60 -0
- package/dist/chunks/build-config-5d8WlQbq.js.map +1 -0
- package/dist/chunks/{collector-D2ARGT2L.js → collector-CjCak4iE.js} +8 -6
- package/dist/chunks/collector-CjCak4iE.js.map +1 -0
- package/dist/chunks/{config-engine-DEmmPPdp.js → config-engine-uOFYZidB.js} +4 -4
- package/dist/chunks/{config-engine-DEmmPPdp.js.map → config-engine-uOFYZidB.js.map} +1 -1
- package/dist/chunks/config-file-DlZXJMj8.js +25 -0
- package/dist/chunks/config-file-DlZXJMj8.js.map +1 -0
- package/dist/chunks/{css-definitions-DotDkIXt.js → css-definitions-ubrHP97m.js} +130 -96
- package/dist/chunks/css-definitions-ubrHP97m.js.map +1 -0
- package/dist/chunks/{debug-D8pg9RGI.js → debug-CJ31U_WE.js} +6 -6
- package/dist/chunks/{debug-D8pg9RGI.js.map → debug-CJ31U_WE.js.map} +1 -1
- package/dist/chunks/{dsl-DRhFWQzo.js → dsl-DYSJc1-T.js} +11 -6
- package/dist/chunks/dsl-DYSJc1-T.js.map +1 -0
- package/dist/chunks/{react-runtime-BpxlOTbO.js → react-runtime-CyyCI02N.js} +190 -63
- package/dist/chunks/react-runtime-CyyCI02N.js.map +1 -0
- package/dist/chunks/{runtime-engine-CKFXUH-A.js → runtime-engine-BQmOu5-W.js} +69 -53
- package/dist/chunks/runtime-engine-BQmOu5-W.js.map +1 -0
- package/dist/chunks/{runtime-state-BxaLhVdP.js → runtime-state-DEsyUMU-.js} +28 -3
- package/dist/chunks/runtime-state-DEsyUMU-.js.map +1 -0
- package/dist/chunks/{style-engine-BBbBuSkT.js → style-engine-BX2LshDZ.js} +309 -103
- package/dist/chunks/style-engine-BX2LshDZ.js.map +1 -0
- package/dist/chunks/{zero-engine-gJrKBRiw.js → zero-engine-Dw0P4yGM.js} +62 -27
- package/dist/chunks/zero-engine-Dw0P4yGM.js.map +1 -0
- package/dist/{collector-w4mBj5gd.d.ts → collector-CTU-nl0g.d.ts} +2 -2
- package/dist/{config-CZWCzBr6.d.ts → config-CcxqSZI2.d.ts} +35 -16
- package/dist/core/index.d.ts +4 -4
- package/dist/core/index.js +7 -7
- package/dist/hydrate-CRyjjAyl.d.ts +22 -0
- package/dist/{index-G9JuwM9p.d.ts → index-xtey-KDu.d.ts} +43 -13
- package/dist/index.d.ts +4 -4
- package/dist/index.js +8 -8
- package/dist/{merge-styles-VXwJ0Frr.d.ts → merge-styles-DSkVc6CD.d.ts} +2 -2
- package/dist/ssr/astro.js +4 -4
- package/dist/ssr/client.d.ts +2 -0
- package/dist/ssr/client.js +2 -0
- package/dist/ssr/index.d.ts +3 -22
- package/dist/ssr/index.js +4 -4
- package/dist/ssr/index.js.map +1 -1
- package/dist/ssr/next-config.d.ts +1 -1
- package/dist/ssr/next-config.js +13 -18
- package/dist/ssr/next-config.js.map +1 -1
- package/dist/ssr/next.d.ts +1 -1
- package/dist/ssr/next.js +3 -3
- package/dist/static/index.d.ts +2 -2
- package/dist/{types-JEY8PVYP.d.ts → types-DJEM_BOJ.d.ts} +6 -6
- package/dist/zero/babel.d.ts +67 -2
- package/dist/zero/babel.js +47 -44
- package/dist/zero/babel.js.map +1 -1
- package/dist/zero/index.d.ts +58 -3
- package/dist/zero/index.js +24 -2
- package/dist/zero/index.js.map +1 -0
- package/dist/zero/next.d.ts +2 -1
- package/dist/zero/next.js +3 -7
- package/dist/zero/next.js.map +1 -1
- package/docs/README.md +4 -1
- package/docs/adoption.md +25 -17
- package/docs/ai-agents.md +37 -34
- package/docs/comparison.md +9 -8
- package/docs/configuration.md +174 -59
- package/docs/debug.md +3 -2
- package/docs/design-system.md +117 -15
- package/docs/dsl.md +122 -81
- package/docs/getting-started.md +81 -24
- package/docs/injector.md +39 -40
- package/docs/methodology.md +45 -20
- package/docs/migration-v3.md +2 -2
- package/docs/pipeline.md +20 -17
- package/docs/plugins.md +20 -40
- package/docs/react-api.md +28 -8
- package/docs/runtime-benchmarks.md +4 -4
- package/docs/ssr.md +83 -63
- package/docs/styles.md +27 -17
- package/docs/tasty-static.md +142 -55
- package/package.json +24 -10
- package/dist/babel-rZcEwPLM.d.ts +0 -82
- package/dist/chunks/async-storage-CG5HnUT5.js +0 -20
- package/dist/chunks/async-storage-CG5HnUT5.js.map +0 -1
- package/dist/chunks/build-config-CL4eRu2z.js +0 -42
- package/dist/chunks/build-config-CL4eRu2z.js.map +0 -1
- package/dist/chunks/collector-D2ARGT2L.js.map +0 -1
- package/dist/chunks/css-definitions-DotDkIXt.js.map +0 -1
- package/dist/chunks/dsl-DRhFWQzo.js.map +0 -1
- package/dist/chunks/react-runtime-BpxlOTbO.js.map +0 -1
- package/dist/chunks/runtime-engine-CKFXUH-A.js.map +0 -1
- package/dist/chunks/runtime-state-BxaLhVdP.js.map +0 -1
- package/dist/chunks/style-engine-BBbBuSkT.js.map +0 -1
- package/dist/chunks/zero-engine-gJrKBRiw.js.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"dsl-DRhFWQzo.js","names":["clamp"],"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/plugins/color-func.ts","../../src/plugins/okhsl-plugin.ts","../../src/plugins/okhst-plugin.ts","../../src/plugins/defaults.ts","../../src/utils/styles.ts","../../src/utils/function-color.ts","../../src/utils/colors.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];\ntype Vec2 = [number, number];\n\n// ============================================================================\n// Conversion Matrices\n// ============================================================================\n\nconst OKLab_to_LMS_ab: Vec2[] = [\n [0.3963377773761749, 0.2158037573099136],\n [-0.1055613458156586, -0.0638541728258133],\n [-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 = (vector: Vec2, x: number, y: number): number =>\n vector[0] * x + vector[1] * y;\n\nconst dotXYZ = (matrix: Vec3, x: number, y: number, z: number): number =>\n matrix[0] * x + matrix[1] * y + matrix[2] * z;\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\n let chnlCoeff: number[];\n let chnlLMS: Vec3;\n\n if (dotXY(okCoeff[0][0], a, b) > 1) {\n chnlCoeff = okCoeff[0][1];\n chnlLMS = lmsToRgb[0];\n } else if (dotXY(okCoeff[1][0], a, b) > 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 kl = dotXY(OKLab_to_LMS_ab[0], a, b);\n const km = dotXY(OKLab_to_LMS_ab[1], a, b);\n const ks = dotXY(OKLab_to_LMS_ab[2], a, b);\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\n let t: number;\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 = dotXY(OKLab_to_LMS_ab[0], a, b);\n const km = dotXY(OKLab_to_LMS_ab[1], a, b);\n const ks = dotXY(OKLab_to_LMS_ab[2], a, b);\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 let correction = Number.MAX_VALUE;\n for (const matrix of lmsToRgb) {\n const value = dotXYZ(matrix, l, m, s) - 1;\n const slope = dotXYZ(matrix, ldt, mdt, sdt);\n const slope2 = dotXYZ(matrix, ldt2, mdt2, sdt2);\n const u = slope / (slope * slope - 0.5 * value * slope2);\n if (u >= 0) correction = Math.min(correction, -value * u);\n }\n t += correction;\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\n // The second string stores one six-digit value for every space-separated\n // name in the first. The table checksum test keeps the packed columns in\n // lockstep while avoiding an object literal in every runtime bundle.\n const names =\n 'aliceblue antiquewhite aqua aquamarine azure beige bisque black blanchedalmond blue blueviolet brown burlywood cadetblue chartreuse chocolate coral cornflowerblue cornsilk crimson cyan darkblue darkcyan darkgoldenrod darkgray darkgreen darkgrey darkkhaki darkmagenta darkolivegreen darkorange darkorchid darkred darksalmon darkseagreen darkslateblue darkslategray darkslategrey darkturquoise darkviolet deeppink deepskyblue dimgray dimgrey dodgerblue firebrick floralwhite forestgreen fuchsia gainsboro ghostwhite gold goldenrod gray green greenyellow grey honeydew hotpink indianred indigo ivory khaki lavender lavenderblush lawngreen lemonchiffon lightblue lightcoral lightcyan lightgoldenrodyellow lightgray lightgreen lightgrey lightpink lightsalmon lightseagreen lightskyblue lightslategray lightslategrey lightsteelblue lightyellow lime limegreen linen magenta maroon mediumaquamarine mediumblue mediumorchid mediumpurple mediumseagreen mediumslateblue mediumspringgreen mediumturquoise mediumvioletred midnightblue mintcream mistyrose moccasin navajowhite navy oldlace olive olivedrab orange orangered orchid palegoldenrod palegreen paleturquoise palevioletred papayawhip peachpuff peru pink plum powderblue purple rebeccapurple red rosybrown royalblue saddlebrown salmon sandybrown seagreen seashell sienna silver skyblue slateblue slategray slategrey snow springgreen steelblue tan teal thistle tomato turquoise violet wheat white whitesmoke yellow yellowgreen'.split(\n ' ',\n );\n const hex =\n 'f0f8fffaebd700ffff7fffd4f0fffff5f5dcffe4c4000000ffebcd0000ff8a2be2a52a2adeb8875f9ea07fff00d2691eff7f506495edfff8dcdc143c00ffff00008b008b8bb8860ba9a9a9006400a9a9a9bdb76b8b008b556b2fff8c009932cc8b0000e9967a8fbc8f483d8b2f4f4f2f4f4f00ced19400d3ff149300bfff6969696969691e90ffb22222fffaf0228b22ff00ffdcdcdcf8f8ffffd700daa520808080008000adff2f808080f0fff0ff69b4cd5c5c4b0082fffff0f0e68ce6e6fafff0f57cfc00fffacdadd8e6f08080e0fffffafad2d3d3d390ee90d3d3d3ffb6c1ffa07a20b2aa87cefa778899778899b0c4deffffe000ff0032cd32faf0e6ff00ff80000066cdaa0000cdba55d39370db3cb3717b68ee00fa9a48d1ccc71585191970f5fffaffe4e1ffe4b5ffdead000080fdf5e68080006b8e23ffa500ff4500da70d6eee8aa98fb98afeeeedb7093ffefd5ffdab9cd853fffc0cbdda0ddb0e0e6800080663399ff0000bc8f8f4169e18b4513fa8072f4a4602e8b57fff5eea0522dc0c0c087ceeb6a5acd708090708090fffafa00ff7f4682b4d2b48c008080d8bfd8ff634740e0d0ee82eef5deb3fffffff5f5f5ffff009acd32';\n const colors = new Map<string, string>();\n\n for (let i = 0; i < names.length; i++) {\n colors.set(names[i], `#${hex.slice(i * 6, i * 6 + 6)}`);\n }\n\n return (_namedColorHex = colors);\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","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 if (token.includes('(')) {\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) depth--;\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` is the `currentcolor` keyword, and emitting the keyword itself is\n // what makes it compose: it resolves against each element's own color, so a\n // `#current` under an ancestor that faded its color reads the *faded* color.\n // `var(--current-color)` cannot do that — the variable carries whatever the\n // nearest publishing ancestor put in it, and a faded color is deliberately not\n // published (see `colorStyle`), so a ramp built on `#current` would read\n // through to the unfaded color above it.\n if (token === '#current') {\n return { bucket: Bucket.Color, processed: 'currentcolor' };\n }\n\n // #current with opacity: #current.5 or #current.$opacity\n //\n // `color-mix()` rather than the relative color syntax a token fade uses.\n // Fading a token *names* a color, so it replaces the alpha; `currentcolor` is\n // the color an element inherits, which an ancestor may already have faded, so\n // `#current.4` means \"40% of what reaches me\" and composes — `#current.4` with\n // `#current.18` under it lands at `.072`. `color-mix()` with `currentcolor`\n // has worked since Safari 16.2.\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","interface LruNode<K, V> {\n key: K;\n prev: LruNode<K, V> | null;\n next: LruNode<K, V> | null;\n value: V;\n}\n\n/**\n * Doubly-linked-list LRU.\n *\n * The list holds direct node references rather than keys, so rewiring on a\n * `get()` of a non-MRU entry is pure pointer work. Storing keys instead cost\n * three extra `Map.get()` lookups per read (prev, next and the current head),\n * which is measurable on these read-mostly caches: they are hit on every\n * render once the style pipeline is warm.\n */\nexport class Lru<K, V> {\n private map = new Map<K, LruNode<K, V>>();\n private head: LruNode<K, V> | null = null;\n private tail: LruNode<K, V> | 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 === undefined) return undefined;\n // Fast path: already MRU, nothing to rewire.\n if (this.head !== node) this.moveToHead(node);\n return node.value;\n }\n\n set(key: K, value: V) {\n const existing = this.map.get(key);\n if (existing !== undefined) {\n existing.value = value;\n if (this.head !== existing) this.moveToHead(existing);\n return;\n }\n\n const node: LruNode<K, V> = { key, prev: null, next: this.head, value };\n if (this.head) this.head.prev = node;\n this.head = node;\n if (!this.tail) this.tail = node;\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 === undefined) return;\n this.detach(node);\n this.map.delete(key);\n }\n\n keys(): IterableIterator<K> {\n return this.map.keys();\n }\n\n private detach(node: LruNode<K, V>) {\n if (node.prev) node.prev.next = node.next;\n if (node.next) node.next.prev = node.prev;\n if (this.head === node) this.head = node.next;\n if (this.tail === node) this.tail = node.prev;\n node.prev = null;\n node.next = null;\n }\n\n private moveToHead(node: LruNode<K, V>) {\n this.detach(node);\n node.next = this.head;\n if (this.head) this.head.prev = node;\n this.head = node;\n if (!this.tail) this.tail = node;\n }\n\n private evict() {\n const node = this.tail;\n if (!node) return;\n this.detach(node);\n this.map.delete(node.key);\n\n if (this.onEvict) {\n try {\n this.onEvict(node.key, 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) => 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 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 cb(src.slice(start, i), isComma, actualSlash);\n } else if (isComma) {\n cb('', true, false); // empty token followed by comma => group break.\n } else if (actualSlash) {\n cb('', false, true); // 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 // Parenthesis tracking keeps separators inside any function together.\n if (ch === '(') {\n depth++;\n continue;\n }\n if (ch === ')') {\n if (depth) depth--;\n continue;\n }\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 { Bucket, makeEmptyDetails, makeEmptyPart } 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 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 currentPart.values[currentPart.values.length - 1] += ` ${processed}`;\n currentPart.all[currentPart.all.length - 1] += ` ${processed}`;\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 = (reset = true) => {\n // Only add non-empty parts\n if (currentPart.all.length > 0) {\n currentPart.output = currentPart.all.join(' ');\n parts.push(currentPart);\n }\n if (reset) currentPart = makeEmptyPart();\n };\n\n const endGroup = (reset = true) => {\n endPart(reset); // 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 }\n\n currentGroup.parts = parts;\n for (const part of parts) {\n currentGroup.mods.push(...part.mods);\n currentGroup.values.push(...part.values);\n currentGroup.colors.push(...part.colors);\n currentGroup.all.push(...part.all);\n }\n currentGroup.output =\n parts.length === 1\n ? parts[0].output\n : parts.map((part) => part.output).join(' / ');\n groups.push(currentGroup);\n\n if (reset) {\n currentGroup = makeEmptyDetails();\n parts = [];\n }\n };\n\n scan(stripped, (tok, isComma, isSlash) => {\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)\n endGroup(false);\n\n const output =\n groups.length === 1\n ? groups[0].output\n : groups.map((group) => group.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","import { Lru } from '../parser/lru';\nimport { isDevEnv } from '../utils/is-dev-env';\nimport { warnOnceDev } from '../utils/warnings';\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(\n mods: string[],\n allowedMods: readonly string[],\n): string[] {\n const filtered: string[] = [];\n\n for (const mod of mods) {\n if (allowedMods.includes(mod)) filtered.push(mod);\n }\n\n return filtered;\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","import { getGlobalParseFunctions, getGlobalParser } from './styles';\n\nconst RE_FUNC_NAME = /^([a-z][a-z0-9-]*)\\s*\\(/i;\nconst RE_COLOR_OUT =\n /^(?:rgb|hsl|hwb|lab|lch|oklab|oklch|color)\\(|^#|^var\\(--/i;\n\n/**\n * Resolve a `name(...)` value produced by a registered custom parse function\n * into its concrete color output.\n *\n * A color function is just a `functions` entry whose output is an already\n * supported color (`rgb`, `hsl`, `#…`, `oklch`, …). This helper delegates the\n * value to the global parser (which already runs the registered parse function)\n * and returns the result only when it looks like a color. Returns `null` when\n * `str` is not a registered custom function or its output is not a color.\n *\n * This is the generic replacement for the previously hardcoded okhsl/okhst\n * conversion branches scattered across `strToRgb`, `resolveToRgbaValues`, and\n * the `#token.alpha` injection path.\n */\nexport function resolveFunctionColor(str: string): string | null {\n const m = RE_FUNC_NAME.exec(str);\n if (!m) return null;\n\n const name = m[1].toLowerCase();\n // Ensure the global parser (and therefore the default color functions) is\n // initialized before consulting the function registry.\n getGlobalParser();\n const functions = getGlobalParseFunctions();\n if (!(name in functions)) return null;\n\n const out = getGlobalParser().process(str).output;\n if (!out || !RE_COLOR_OUT.test(out)) return null;\n\n return out;\n}\n","import { overrideColorAlpha } from './color-space';\n\nexport function color(name: string, opacity = 1) {\n if (opacity !== 1) {\n // The alpha slot takes a `<number>`, so the value goes in as authored —\n // no percentage conversion to introduce a float artifact.\n return overrideColorAlpha(`var(--${name}-color)`, String(opacity));\n }\n\n return `var(--${name}-color)`;\n}\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"react-runtime-BpxlOTbO.js","names":["getClientState"],"sources":["../../src/utils/get-display-name.ts","../../src/utils/is-valid-element-type.ts","../../src/tasty.tsx","../../src/ssr/context.ts","../../src/hooks/useStyles.ts","../../src/hooks/useGlobalStyles.ts","../../src/hooks/useRawCSS.ts","../../src/hooks/useKeyframes.ts","../../src/hooks/useProperty.ts","../../src/hooks/useFontFace.ts","../../src/hooks/useCounterStyle.ts","../../src/hooks/useFunction.ts","../../src/batch-provider.tsx"],"sourcesContent":["import type { ElementType } from 'react';\n\nconst DEFAULT_NAME = 'Anonymous';\n\nexport function getDisplayName<T>(\n Component: ElementType<T>,\n fallbackName = DEFAULT_NAME,\n): string {\n if (typeof Component === 'function') {\n return Component.displayName ?? Component.name ?? fallbackName;\n }\n\n return fallbackName;\n}\n","/**\n * Lightweight replacement for `react-is`'s isValidElementType.\n * Detects string tags, function/class components, and React exotic types\n * (forwardRef, memo, lazy, etc.) via their internal $$typeof symbol.\n */\nexport function isValidElementType(value: unknown): boolean {\n if (typeof value === 'string' || typeof value === 'function') {\n return true;\n }\n\n if (typeof value === 'object' && value !== null) {\n return typeof (value as { $$typeof?: unknown }).$$typeof === 'symbol';\n }\n\n return false;\n}\n","import type {\n AllHTMLAttributes,\n ComponentType,\n ElementType,\n ForwardRefExoticComponent,\n JSX,\n PropsWithoutRef,\n RefAttributes,\n} from 'react';\nimport { createElement, forwardRef, Fragment } from 'react';\nimport type { ComputeStylesOptions } from './compute-styles';\nimport { computeStyles } from './compute-styles';\nimport type { PropHandlerProps } from './prop-handlers';\nimport { propHandlerRegistry } from './prop-handlers';\nimport { baseStylePropsRegistry } from './styles/base-props';\nimport { BASE_STYLES } from './styles/list';\nimport type { Styles, StylesInterface } from './styles/types';\nimport type {\n AllBaseProps,\n BaseProps,\n BaseStyleProps,\n ExtraBaseStyleProps,\n ModValue,\n Mods,\n TastyCustomProps,\n TokenValue,\n Tokens,\n} from './types';\nimport { getDisplayName } from './utils/get-display-name';\nimport { hasKeys } from './utils/has-keys';\nimport { isValidElementType } from './utils/is-valid-element-type';\nimport { isSelector } from './utils/is-selector';\nimport { mergeStyles } from './utils/merge-styles';\nimport { modAttrs } from './utils/mod-attrs';\nimport { processTokens } from './utils/process-tokens';\nimport { getConfig } from './config';\nimport { touch } from './injector';\n\nimport type { StyleValue, StyleValueStateMap } from './utils/styles';\n\n/** Transform one is* prop to its HTML and matching data attributes. */\nfunction handleIsProperty(\n props: Record<string, unknown>,\n isProperty: string,\n targetAttribute: string,\n dataAttribute: string,\n) {\n if (isProperty in props) {\n props[targetAttribute] = props[isProperty];\n delete props[isProperty];\n }\n\n if (!(dataAttribute in props) && props[targetAttribute]) {\n props[dataAttribute] = '';\n }\n}\n\nfunction handleIsProperties(props: Record<string, unknown>) {\n handleIsProperty(props, 'isDisabled', 'disabled', 'data-disabled');\n handleIsProperty(props, 'isHidden', 'hidden', 'data-hidden');\n handleIsProperty(props, 'isChecked', 'checked', 'data-checked');\n}\n\n/**\n * Creates a sub-element component for compound component patterns.\n * Sub-elements are lightweight components with data-element attribute for CSS targeting.\n */\nfunction createSubElement<Tag extends keyof JSX.IntrinsicElements>(\n elementName: string,\n definition: SubElementDefinition<Tag>,\n): ForwardRefExoticComponent<\n PropsWithoutRef<SubElementProps<Tag>> & RefAttributes<unknown>\n> {\n // Normalize definition to object form\n const config =\n typeof definition === 'string'\n ? { as: definition as Tag }\n : (definition as { as?: Tag; qa?: string; qaVal?: string | number });\n\n const tag = config.as ?? ('div' as Tag);\n const defaultQa = config.qa;\n const defaultQaVal = config.qaVal;\n\n const SubElement = forwardRef<unknown, SubElementProps<Tag>>((props, ref) => {\n const {\n qa,\n qaVal,\n mods,\n tokens,\n isDisabled,\n isHidden,\n isChecked,\n className,\n style,\n ...htmlProps\n } = props as SubElementProps<Tag> & {\n className?: string;\n style?: Record<string, unknown>;\n };\n\n // Build mod attributes\n let modDataAttrs: Record<string, unknown> | undefined;\n if (mods) {\n modDataAttrs = modAttrs(mods as Mods) as Record<string, unknown>;\n }\n\n // Process tokens into inline style properties\n const tokenStyle = tokens\n ? (processTokens(tokens) as Record<string, unknown>)\n : undefined;\n\n // Merge token styles with explicit style prop (style has priority)\n let mergedStyle: Record<string, unknown> | undefined;\n if (tokenStyle || style) {\n mergedStyle =\n tokenStyle && style\n ? { ...tokenStyle, ...style }\n : ((tokenStyle ?? style) as Record<string, unknown>);\n }\n\n const elementProps = {\n 'data-element': elementName,\n 'data-qa': qa ?? defaultQa,\n 'data-qaval': qaVal ?? defaultQaVal,\n ...(modDataAttrs || {}),\n ...htmlProps,\n className,\n style: mergedStyle,\n isDisabled: isDisabled ?? (htmlProps as Record<string, unknown>).disabled,\n isHidden: isHidden ?? (htmlProps as Record<string, unknown>).hidden,\n isChecked: isChecked ?? (htmlProps as Record<string, unknown>).checked,\n ref,\n } as Record<string, unknown>;\n\n // Handle is* properties (isDisabled -> disabled + data-disabled, etc.)\n handleIsProperties(elementProps);\n\n // Clean up undefined data attributes\n if (elementProps['data-qa'] === undefined) delete elementProps['data-qa'];\n if (elementProps['data-qaval'] === undefined)\n delete elementProps['data-qaval'];\n\n return createElement(tag, elementProps);\n });\n\n SubElement.displayName = `SubElement(${elementName})`;\n\n return SubElement as ForwardRefExoticComponent<\n PropsWithoutRef<SubElementProps<Tag>> & RefAttributes<unknown>\n >;\n}\n\ntype StyleList = readonly (keyof {\n [key in keyof StylesInterface]: StylesInterface[key];\n})[];\n\n// ============================================================================\n// Mod props types — expose modifier keys as top-level component props\n// ============================================================================\n\n/** Type descriptor for a single mod prop: a JS constructor or an enum array. */\nexport type ModPropDef =\n | BooleanConstructor\n | StringConstructor\n | NumberConstructor\n | readonly string[];\n\n/** Array form: list of mod key names (types default to ModValue). */\ntype ModPropsList = readonly string[];\n\n/** Object form: map of mod key names to type descriptors. */\ntype ModPropsMap = Readonly<Record<string, ModPropDef>>;\n\n/** Either array or object form accepted by `modProps` option. */\nexport type ModPropsInput = ModPropsList | ModPropsMap;\n\n/** Resolve a single ModPropDef to its TypeScript type. */\nexport type ResolveModPropDef<T> = T extends BooleanConstructor\n ? boolean\n : T extends StringConstructor\n ? string\n : T extends NumberConstructor\n ? number\n : T extends readonly (infer U)[]\n ? U\n : ModValue;\n\n/** Resolve an entire `modProps` definition to the component prop types it adds. */\nexport type ResolveModProps<M extends ModPropsInput> =\n M extends readonly (infer K)[]\n ? Partial<Record<K & string, ModValue>>\n : M extends Record<string, ModPropDef>\n ? { [key in keyof M & string]?: ResolveModPropDef<M[key]> }\n : // eslint-disable-next-line @typescript-eslint/no-empty-object-type\n {};\n\n// ============================================================================\n// Token props types — expose token keys as top-level component props\n// ============================================================================\n\n/** A token key with `$` or `#` prefix. */\ntype TokenPropKey = `$${string}` | `#${string}`;\n\n/** Array form: list of prop names. Names ending in `Color` map to `#` color tokens. */\ntype TokenPropsList = readonly string[];\n\n/** Object form: prop name -> token key with explicit `$`/`#` prefix. */\ntype TokenPropsMap = Readonly<Record<string, TokenPropKey>>;\n\n/** Either array or object form accepted by `tokenProps` option. */\nexport type TokenPropsInput = TokenPropsList | TokenPropsMap;\n\n/** Resolve a `tokenProps` definition to the component prop types it adds. */\nexport type ResolveTokenProps<TP extends TokenPropsInput> =\n TP extends readonly (infer K)[]\n ? Partial<Record<K & string, TokenValue>>\n : TP extends Record<string, TokenPropKey>\n ? Partial<Record<keyof TP & string, TokenValue>>\n : // eslint-disable-next-line @typescript-eslint/no-empty-object-type\n {};\n\n/**\n * Pre-compute the mapping from prop name to token key at component-creation time.\n * Array form: `'progress'` -> `'$progress'`, `'accentColor'` -> `'#accent'`.\n * Object form: entries used as-is.\n */\nfunction buildTokenPropsMapping(\n def: TokenPropsInput,\n): [propName: string, tokenKey: string][] {\n if (Array.isArray(def)) {\n return (def as string[]).map((propName) => {\n if (propName.endsWith('Color') && propName.length > 5) {\n return [propName, `#${propName.slice(0, -5)}`];\n }\n return [propName, `$${propName}`];\n });\n }\n return Object.entries(def);\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype AnyProps = Record<string, any>;\n\ntype PropsWithStyles = {\n styles?: Styles;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n} & Omit<Record<string, any>, 'styles'>;\n\nexport type VariantMap = Record<string, Styles>;\n\nexport interface WithVariant<V extends VariantMap> {\n variant?: keyof V;\n}\n\n// ============================================================================\n// Sub-element types for compound components\n// ============================================================================\n\n/**\n * Definition for a sub-element. Can be either:\n * - A tag name string (e.g., 'div', 'span')\n * - An object with configuration options\n */\nexport type SubElementDefinition<\n Tag extends keyof JSX.IntrinsicElements = 'div',\n> =\n | Tag\n | {\n as?: Tag;\n qa?: string;\n qaVal?: string | number;\n };\n\n/**\n * Map of sub-element definitions.\n * Keys become the sub-component names (e.g., { Icon: 'span' } -> Component.Icon)\n */\nexport type ElementsDefinition = Record<\n string,\n SubElementDefinition<keyof JSX.IntrinsicElements>\n>;\n\n/**\n * Resolves the tag from a SubElementDefinition\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype ResolveElementTag<T extends SubElementDefinition<any>> = T extends string\n ? T\n : T extends { as?: infer Tag }\n ? Tag extends keyof JSX.IntrinsicElements\n ? Tag\n : 'div'\n : 'div';\n\n/**\n * Props for sub-element components.\n * Combines HTML attributes with tasty-specific props (qa, qaVal, mods, tokens, isDisabled, etc.)\n */\nexport type SubElementProps<Tag extends keyof JSX.IntrinsicElements = 'div'> =\n Omit<\n JSX.IntrinsicElements[Tag],\n 'ref' | 'color' | 'content' | 'translate'\n > & {\n qa?: string;\n qaVal?: string | number;\n mods?: Mods;\n tokens?: Tokens;\n isDisabled?: boolean;\n isHidden?: boolean;\n isChecked?: boolean;\n };\n\n/**\n * Generates the sub-element component types from an ElementsDefinition\n */\ntype SubElementComponents<E extends ElementsDefinition> = {\n [K in keyof E]: ForwardRefExoticComponent<\n PropsWithoutRef<SubElementProps<ResolveElementTag<E[K]>>> &\n RefAttributes<\n ResolveElementTag<E[K]> extends keyof HTMLElementTagNameMap\n ? HTMLElementTagNameMap[ResolveElementTag<E[K]>]\n : Element\n >\n >;\n};\n\n/**\n * Base type containing common properties shared between TastyProps and TastyElementOptions.\n * Separated to avoid code duplication while allowing different type constraints.\n */\ntype TastyBaseProps<\n K extends StyleList,\n V extends VariantMap,\n E extends ElementsDefinition = Record<string, never>,\n M extends ModPropsInput = readonly never[],\n TP extends TokenPropsInput = readonly never[],\n> = {\n /** Default styles of the element. */\n styles?: Styles;\n /** The list of styles that can be provided by props */\n styleProps?: K;\n /** Modifier keys exposed as top-level component props (array or typed object form). */\n modProps?: M;\n /** Token keys exposed as top-level component props (array or typed object form). */\n tokenProps?: TP;\n element?: BaseProps['element'];\n variants?: V;\n /** Default tokens for inline CSS custom properties */\n tokens?: Tokens;\n /** Sub-element definitions for compound components */\n elements?: E;\n} & Pick<BaseProps, 'qa' | 'qaVal'> &\n WithVariant<V>;\n\nexport type TastyProps<\n K extends StyleList,\n V extends VariantMap,\n E extends ElementsDefinition = Record<string, never>,\n DefaultProps = AnyProps,\n M extends ModPropsInput = readonly never[],\n TP extends TokenPropsInput = readonly never[],\n> = TastyBaseProps<K, V, E, M, TP> & {\n /** The tag name of the element or a React component. */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n as?: string | ComponentType<any>;\n} & Partial<\n Omit<\n DefaultProps,\n 'as' | 'styles' | 'styleProps' | 'modProps' | 'tokenProps' | 'tokens'\n >\n >;\n\n/**\n * Resolves the props of a polymorphic `as` value (intrinsic tag or component).\n * - For intrinsic tags (`'div'`, `'button'`, ...): returns `JSX.IntrinsicElements[Tag]`.\n * - For React component types: returns the component's own props.\n * - Falls back to an empty record for anything else.\n */\nexport type ResolveAsProps<AsType extends ElementType> =\n AsType extends keyof JSX.IntrinsicElements\n ? JSX.IntrinsicElements[AsType]\n : AsType extends ComponentType<infer P>\n ? P\n : Record<string, never>;\n\n/**\n * TastyElementOptions is used for the element-creation overload of tasty().\n * It includes an `AsType` generic that allows TypeScript to infer the correct\n * element type from the `as` prop — both for intrinsic tags and for React\n * components (so the wrapped component's prop API is preserved).\n *\n * Note: Uses a separate index signature with `unknown` instead of an `any`\n * record to ensure strict type checking for styles.\n */\nexport type TastyElementOptions<\n K extends StyleList,\n V extends VariantMap,\n E extends ElementsDefinition = Record<string, never>,\n AsType extends ElementType = 'div',\n M extends ModPropsInput = readonly never[],\n TP extends TokenPropsInput = readonly never[],\n> = TastyBaseProps<K, V, E, M, TP> & {\n /** The tag name of the element or a React component. */\n as?: AsType;\n} & Record<string, unknown>;\n\nexport type AllBasePropsWithMods<\n K extends StyleList,\n M extends ModPropsInput = readonly never[],\n TP extends TokenPropsInput = readonly never[],\n> = AllBaseProps & {\n [key in K[number]]?:\n StyleValue<StylesInterface[key]> | StyleValueStateMap<StylesInterface[key]>;\n} & BaseStyleProps &\n ExtraBaseStyleProps &\n Partial<TastyCustomProps> &\n ResolveModProps<M> &\n ResolveTokenProps<TP>;\n\n/**\n * Props consumed by Tasty rather than forwarded to the `as` component.\n * Event handlers are resolved from JSX.IntrinsicElements or the component's own props.\n */\ntype TastySpecificKeys =\n | keyof BaseStyleProps\n | 'as'\n | 'qa'\n | 'qaVal'\n | 'element'\n | 'styles'\n | 'mods'\n | 'isHidden'\n | 'isDisabled'\n | 'isChecked'\n | 'style'\n | 'theme'\n | 'tokens'\n | 'ref';\n\n/** Extract prop key names from a ModPropsInput (array elements or object keys). */\ntype ModPropsKeys<M extends ModPropsInput> = M extends readonly (infer K)[]\n ? K & string\n : keyof M & string;\n\n/** Extract prop key names from a TokenPropsInput (array elements or object keys). */\ntype TokenPropsKeys<TP extends TokenPropsInput> =\n TP extends readonly (infer K)[] ? K & string : keyof TP & string;\n\n/**\n * Props type for tasty elements that combines:\n * - AllBasePropsWithMods for style props with strict tokens type\n * - HTML attributes for flexibility (properly typed based on `as`)\n * - Variant support\n *\n * AllBasePropsWithMods carries generic AllHTMLAttributes which can conflict\n * with element-specific types (e.g. `src` is `string` in AllHTMLAttributes but\n * `string | Blob` in ImgHTMLAttributes, or the custom props on a third-party\n * component like Next.js `Link`). To avoid intersection-narrowing, we Omit\n * element-specific keys from AllBasePropsWithMods (keeping TastySpecificKeys,\n * style props, mod props, and token props) and let the resolved `as` props\n * supply the authoritative attribute types. The `AllHTMLAttributes<HTMLElement>`\n * baseline is preserved so generic HTML attributes still work even when `as`\n * is a component type with a narrower prop API.\n */\nexport type TastyElementProps<\n K extends StyleList,\n V extends VariantMap,\n AsType extends ElementType = 'div',\n M extends ModPropsInput = readonly never[],\n TP extends TokenPropsInput = readonly never[],\n> = Omit<\n AllBasePropsWithMods<K, M, TP>,\n Exclude<\n keyof ResolveAsProps<AsType>,\n | TastySpecificKeys\n | keyof TastyCustomProps\n | keyof ExtraBaseStyleProps\n | K[number]\n | ModPropsKeys<M>\n | TokenPropsKeys<TP>\n >\n> &\n WithVariant<V> &\n Omit<\n Omit<AllHTMLAttributes<HTMLElement>, keyof ResolveAsProps<AsType>> &\n ResolveAsProps<AsType>,\n | TastySpecificKeys\n | keyof TastyCustomProps\n | keyof ExtraBaseStyleProps\n | K[number]\n | ModPropsKeys<M>\n | TokenPropsKeys<TP>\n >;\n\nexport type TastyComponentPropsWithDefaults<\n Props extends PropsWithStyles,\n DefaultProps extends Partial<Props>,\n> = keyof DefaultProps extends never\n ? Props\n : {\n [key in Extract<keyof Props, keyof DefaultProps>]?: Props[key];\n } & {\n [key in keyof Omit<Props, keyof DefaultProps>]: Props[key];\n };\n\n/**\n * The component type returned by the `tasty(options)` element-factory overload.\n *\n * It's a regular React forward-ref component whose props are typed from the\n * factory-time `as` value. Polymorphism is at factory time: each call to\n * `tasty({ as: X })` produces a component whose prop API includes `X`'s own\n * props (so `tasty({ as: NextLink })` exposes `href`, `replace`, `prefetch`,\n * etc.) alongside the Tasty-specific props (`mods`, `tokens`, `styleProps`,\n * `modProps`, `tokenProps`).\n *\n * Note: a render-time `<X as={SomeComponent} />` does not re-infer props from\n * `SomeComponent`; create another `tasty({ as: SomeComponent })` for that.\n */\nexport type TastyPolymorphicComponent<\n DefaultAs extends ElementType,\n K extends StyleList,\n V extends VariantMap,\n M extends ModPropsInput,\n TP extends TokenPropsInput,\n> = ForwardRefExoticComponent<\n PropsWithoutRef<TastyElementProps<K, V, DefaultAs, M, TP>> &\n RefAttributes<unknown>\n>;\n\n// An omitted styleProps list must not infer the entire StyleList constraint:\n// that would claim every CSS name, including the `as` component's own props.\nexport function tasty<\n K extends StyleList = readonly never[],\n V extends VariantMap = VariantMap,\n E extends ElementsDefinition = Record<string, never>,\n AsType extends ElementType = 'div',\n M extends ModPropsInput = readonly never[],\n TP extends TokenPropsInput = readonly never[],\n>(\n options: TastyElementOptions<K, V, E, AsType, M, TP>,\n secondArg?: never,\n): TastyPolymorphicComponent<AsType, K, V, M, TP> & SubElementComponents<E>;\nexport function tasty<\n Props extends PropsWithStyles,\n DefaultProps extends Partial<Props> = Partial<Props>,\n K extends StyleList = readonly never[],\n V extends VariantMap = VariantMap,\n E extends ElementsDefinition = Record<string, never>,\n M extends ModPropsInput = readonly never[],\n TP extends TokenPropsInput = readonly never[],\n>(\n Component: ComponentType<Props>,\n options?: TastyProps<K, V, E, Props, M, TP>,\n): ComponentType<TastyComponentPropsWithDefaults<Props, DefaultProps>>;\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\n// Implementation\nexport function tasty<\n K extends StyleList,\n V extends VariantMap,\n _C = Record<string, unknown>,\n>(Component: any, options?: any) {\n if (isValidElementType(Component)) {\n return tastyWrap(Component as ComponentType<any>, options);\n }\n\n return tastyElement(Component as TastyProps<K, V>);\n}\n\nfunction tastyWrap<\n P extends PropsWithStyles,\n DefaultProps extends Partial<P> = Partial<P>,\n K extends StyleList = readonly never[],\n V extends VariantMap = VariantMap,\n E extends ElementsDefinition = Record<string, never>,\n M extends ModPropsInput = readonly never[],\n TP extends TokenPropsInput = readonly never[],\n>(\n Component: ComponentType<P>,\n options?: TastyProps<K, V, E, P, M, TP>,\n): ComponentType<TastyComponentPropsWithDefaults<P, DefaultProps>> {\n // The wrap path forwards default props + merges `styles`/`*Styles` props.\n // Factory-only options (`styleProps`, `modProps`, `tokenProps`, `variants`,\n // `elements`) are stripped here, not forwarded to the wrapped component.\n const {\n as: extendTag,\n element: extendElement,\n styleProps: _styleProps,\n modProps: _modProps,\n tokenProps: _tokenProps,\n variants: _variants,\n elements: _elements,\n ...defaultProps\n } = (options ?? {}) as TastyProps<K, V, E, P, M, TP>;\n\n const propsWithStyles = ['styles'];\n for (const prop of Object.keys(defaultProps)) {\n if (prop.endsWith('Styles')) propsWithStyles.push(prop);\n }\n\n const _WrappedComponent = forwardRef<any, any>((props, ref) => {\n const { as, element, ...restProps } = props as Record<string, unknown>;\n\n const mergedStylesMap: Record<string, unknown> = {};\n for (const prop of propsWithStyles) {\n const restValue = (restProps as any)[prop];\n const defaultValue = (defaultProps as any)[prop];\n\n mergedStylesMap[prop] =\n restValue != null && defaultValue != null\n ? mergeStyles(defaultValue, restValue)\n : (restValue ?? defaultValue);\n }\n\n const elementProps = {\n ...(defaultProps as unknown as Record<string, unknown>),\n ...(restProps as unknown as Record<string, unknown>),\n ...mergedStylesMap,\n as: (as as string | undefined) ?? extendTag,\n element: (element as string | undefined) || extendElement,\n ref,\n } as unknown as P;\n\n return createElement(Component as ComponentType<P>, elementProps);\n });\n\n _WrappedComponent.displayName = `TastyWrappedComponent(${getDisplayName(\n Component,\n (defaultProps as any).qa ?? (extendTag as any) ?? 'Anonymous',\n )})`;\n\n return _WrappedComponent as unknown as ComponentType<\n TastyComponentPropsWithDefaults<P, DefaultProps>\n >;\n}\n\nfunction tastyElement<\n K extends StyleList,\n V extends VariantMap,\n E extends ElementsDefinition,\n>(tastyOptions: TastyProps<K, V, E>) {\n const {\n as: originalAs = 'div',\n element: defaultElement,\n styles: defaultStyles,\n styleProps,\n modProps: modPropsDef,\n tokenProps: tokenPropsDef,\n variants,\n tokens: defaultTokens,\n elements,\n ...defaultProps\n } = tastyOptions;\n\n // Pre-compute merged styles for each variant (if variants are defined)\n // This avoids creating separate component instances per variant\n let variantStylesMap: Record<string, Styles | undefined> | undefined;\n if (variants) {\n // Split defaultStyles: extend-mode state maps (no '' key, non-selector)\n // are pulled out and applied AFTER variant merge so they survive\n // replace-mode maps in variants.\n let baseStyles = defaultStyles;\n let extensionStyles: Styles | undefined;\n\n if (defaultStyles) {\n for (const key of Object.keys(defaultStyles)) {\n if (isSelector(key)) continue;\n\n const value = (defaultStyles as Record<string, unknown>)[key];\n\n if (\n typeof value === 'object' &&\n value !== null &&\n !Array.isArray(value) &&\n !('' in value)\n ) {\n if (!extensionStyles) {\n baseStyles = { ...defaultStyles } as Styles;\n extensionStyles = {} as Styles;\n }\n (extensionStyles as Record<string, unknown>)[key] = value;\n delete (baseStyles as Record<string, unknown>)[key];\n }\n }\n }\n\n variantStylesMap = {};\n for (const [variant, variantStyles] of Object.entries(variants) as [\n string,\n Styles,\n ][]) {\n variantStylesMap[variant] = extensionStyles\n ? mergeStyles(baseStyles, variantStyles, extensionStyles)\n : mergeStyles(baseStyles, variantStyles);\n }\n // Ensure 'default' variant always exists\n if (!variantStylesMap['default']) {\n variantStylesMap['default'] = defaultStyles;\n }\n }\n\n const {\n qa: defaultQa,\n qaVal: defaultQaVal,\n ...otherDefaultProps\n } = defaultProps;\n\n // Fixed at factory-creation time — no dependency on global config.\n const ownPropsToCheck: readonly string[] = styleProps\n ? (styleProps as StyleList).concat(BASE_STYLES)\n : BASE_STYLES;\n\n // Resolved lazily and refreshed on registry version change. `configure()` can\n // run *after* this factory was created (module eval order — see `Element` at\n // the bottom of this file), and `resetConfig()` reopens configuration, so a\n // one-shot lazy init would go stale. Starts at -1 to force first resolution.\n let propsToCheck: readonly string[] = ownPropsToCheck;\n let propsToCheckVersion = -1;\n\n const modPropsKeys: string[] | undefined = modPropsDef\n ? ((Array.isArray(modPropsDef)\n ? modPropsDef\n : Object.keys(modPropsDef)) as string[])\n : undefined;\n\n const tokenPropsMapping: [string, string][] | undefined = tokenPropsDef\n ? buildTokenPropsMapping(tokenPropsDef as TokenPropsInput)\n : undefined;\n\n // Factory-level cache: maps stable style references to computed classNames.\n // For the common case (no instance overrides), this avoids recomputation.\n const classNameCache = new Map<Styles | undefined, string>();\n\n // Passed when the styles object handed to computeStyles() is the factory's\n // own AND computeStyles() will see it again — which is only true where\n // classNameCache is unavailable, i.e. the server. On the client that cache\n // answers every render after the first, so memoizing chunk keys during that\n // first render would write entries nothing ever reads back. Hoisted so the\n // hot path does not allocate it.\n const STABLE_STYLES: ComputeStylesOptions = { stableStyles: true };\n\n const _TastyComponent = forwardRef<\n unknown,\n AllBasePropsWithMods<K> & WithVariant<V>\n >((incomingProps, ref) => {\n // Global props middleware (`configure({ propHandlers })`). Runs before any\n // destructuring so a handler can rewrite every tasty prop — `styles`, `mods`,\n // `tokens`, `variant`, `as`, `element`, `qa` — and strip its own custom props\n // so they never reach the DOM. `ref` is out of reach: forwardRef separates it.\n // Fast path while nothing is registered: one property load and one branch.\n const applyPropHandlers = propHandlerRegistry.apply;\n const allProps = applyPropHandlers\n ? (applyPropHandlers(\n incomingProps as unknown as PropHandlerProps,\n ) as unknown as typeof incomingProps)\n : incomingProps;\n\n const {\n as,\n styles: rawStyles,\n variant,\n mods,\n element,\n qa,\n qaVal,\n className: userClassName,\n tokens,\n style,\n theme,\n ...otherProps\n } = allProps as Record<string, unknown> as AllBasePropsWithMods<K> &\n WithVariant<V> & {\n className?: string;\n tokens?: Tokens;\n style?: Record<string, unknown>;\n theme?: string;\n };\n\n const styles = rawStyles;\n\n let propStyles: Styles | null = null;\n\n if (propsToCheckVersion !== baseStylePropsRegistry.version) {\n const promoted = baseStylePropsRegistry.list;\n\n propsToCheck =\n promoted.length === 0\n ? ownPropsToCheck\n : ownPropsToCheck.concat(promoted);\n propsToCheckVersion = baseStylePropsRegistry.version;\n }\n\n for (const prop of propsToCheck) {\n const key = prop as unknown as string;\n\n if (key in otherProps) {\n if (!propStyles) propStyles = {};\n const value = (otherProps as any)[key];\n (propStyles as any)[key] = value;\n delete (otherProps as any)[key];\n }\n }\n\n let propMods: Record<string, ModValue> | undefined;\n if (modPropsKeys) {\n for (const key of modPropsKeys) {\n if (key in otherProps) {\n if (!propMods) propMods = {};\n propMods[key] = (otherProps as Record<string, unknown>)[\n key\n ] as ModValue;\n delete (otherProps as Record<string, unknown>)[key];\n }\n }\n }\n\n let propTokens: Tokens | undefined;\n if (tokenPropsMapping) {\n for (const [propName, tokenKey] of tokenPropsMapping) {\n if (propName in otherProps) {\n if (!propTokens) propTokens = {} as Tokens;\n (propTokens as Record<string, TokenValue>)[tokenKey] = (\n otherProps as Record<string, unknown>\n )[propName] as TokenValue;\n delete (otherProps as Record<string, unknown>)[propName];\n }\n }\n }\n\n const baseStyles = variantStylesMap\n ? (variantStylesMap[(variant as string) || 'default'] ??\n variantStylesMap['default'])\n : defaultStyles;\n\n const hasInstanceStyles =\n styles && hasKeys(styles as Record<string, unknown>);\n const hasPropStyles = !!propStyles;\n\n const allStyles =\n hasInstanceStyles || hasPropStyles\n ? mergeStyles(baseStyles, styles as Styles, propStyles as Styles)\n : baseStyles;\n\n // Use factory-level cache for stable style references (client only).\n // On the server the cache must be skipped: both the SSR collector and\n // the RSC inline-style paths are per-request, so every request must\n // call computeStyles() to ensure CSS is actually collected/emitted.\n const useFactoryCache = typeof document !== 'undefined';\n let generatedClassName =\n useFactoryCache && allStyles === baseStyles\n ? classNameCache.get(allStyles)\n : undefined;\n let rscCSS: string | undefined;\n\n if (generatedClassName !== undefined) {\n touch(generatedClassName);\n } else {\n const result = computeStyles(\n allStyles,\n !useFactoryCache && allStyles === baseStyles\n ? STABLE_STYLES\n : undefined,\n );\n generatedClassName = result.className;\n rscCSS = result.css;\n if (useFactoryCache && allStyles === baseStyles) {\n classNameCache.set(allStyles, generatedClassName);\n }\n }\n\n // Merge tokens: default -> instance -> tokenProps\n let mergedTokens: Tokens | undefined;\n if (defaultTokens || tokens || propTokens) {\n if (!defaultTokens && !propTokens) {\n mergedTokens = tokens as Tokens;\n } else if (!tokens && !propTokens) {\n mergedTokens = defaultTokens;\n } else {\n mergedTokens = {\n ...defaultTokens,\n ...(tokens as Tokens),\n ...propTokens,\n } as Tokens;\n }\n }\n\n const processedTokenStyle = processTokens(mergedTokens);\n\n let mergedStyle: Record<string, unknown> | undefined;\n if (processedTokenStyle || style) {\n if (!processedTokenStyle) {\n mergedStyle = style;\n } else if (!style) {\n mergedStyle = processedTokenStyle as Record<string, unknown>;\n } else {\n mergedStyle = {\n ...(processedTokenStyle as Record<string, unknown>),\n ...style,\n };\n }\n }\n\n const mergedMods = propMods\n ? { ...(mods as Record<string, ModValue>), ...propMods }\n : (mods as Record<string, ModValue> | undefined);\n\n let modDataAttrs: Record<string, unknown> | undefined;\n if (mergedMods) {\n modDataAttrs = modAttrs(mergedMods as unknown as Mods) as Record<\n string,\n unknown\n >;\n }\n\n let finalClassName = generatedClassName;\n if (userClassName) {\n finalClassName = finalClassName\n ? `${userClassName} ${finalClassName}`\n : userClassName;\n }\n\n const elementProps = {\n 'data-element': (element as string | undefined) || defaultElement,\n 'data-qa': (qa as string | undefined) || defaultQa,\n 'data-qaval': (qaVal as string | undefined) || defaultQaVal,\n 'data-theme': theme,\n ...(otherDefaultProps as unknown as Record<string, unknown>),\n ...(modDataAttrs || {}),\n ...(otherProps as unknown as Record<string, unknown>),\n className: finalClassName,\n style: mergedStyle,\n ref,\n } as Record<string, unknown>;\n\n handleIsProperties(elementProps);\n\n if (elementProps['data-theme'] === undefined) {\n delete elementProps['data-theme'];\n }\n\n const el = createElement(\n (as as string | 'div') ?? originalAs,\n elementProps,\n );\n\n // RSC mode: wrap element with inline <style> tag.\n // Class names are extracted from these tags on the client via\n // the doubled-specificity pattern (.tXXX.tXXX), so no <script> is needed.\n if (rscCSS) {\n const nonce = getConfig().nonce;\n\n return createElement(\n Fragment,\n null,\n createElement('style', {\n 'data-tasty-rsc': '',\n nonce,\n dangerouslySetInnerHTML: { __html: rscCSS },\n }),\n el,\n );\n }\n\n return el;\n });\n\n _TastyComponent.displayName = `TastyComponent(${\n (defaultProps as any).qa || originalAs\n })`;\n\n // Attach sub-element components if elements are defined\n if (elements) {\n const subElements: Record<string, ForwardRefExoticComponent<any>> = {};\n for (const [name, definition] of Object.entries(elements)) {\n subElements[name] = createSubElement(\n name,\n definition as SubElementDefinition<keyof JSX.IntrinsicElements>,\n );\n }\n\n return Object.assign(_TastyComponent, subElements);\n }\n\n return _TastyComponent;\n}\n\nexport const Element = /* @__PURE__ */ tasty({});\n","/**\n * React context for SSR collector discovery.\n *\n * Used by Next.js TastyRegistry to provide the ServerStyleCollector\n * to useStyles() via React context (the streaming-compatible path).\n *\n * This avoids relying on globalThis for cross-layer communication,\n * which leaks between RSC and SSR module graphs in Next.js App Router.\n *\n * The context is created lazily to avoid calling createContext() at\n * module evaluation time, which would break Server Components that\n * import from `@tenphi/tasty` without using any React hooks.\n */\n\nimport { createContext, type Context } from 'react';\n\nimport type { ServerStyleCollector } from './collector';\n\nlet _ctx: Context<ServerStyleCollector | null> | undefined;\n\nexport function getTastySSRContext(): Context<ServerStyleCollector | null> {\n if (!_ctx) {\n _ctx = createContext<ServerStyleCollector | null>(null);\n }\n return _ctx;\n}\n","import { useContext } from 'react';\n\nimport { computeStyles } from '../compute-styles';\nimport { getTastySSRContext } from '../ssr/context';\nimport type { Styles } from '../styles/types';\n\nexport interface UseStylesResult {\n /**\n * Generated className(s) to apply to the element.\n * Can be empty string if no styles are provided.\n * With chunking enabled, may contain multiple space-separated class names.\n */\n className: string;\n}\n\n/**\n * Hook to generate CSS classes from Tasty styles.\n * Thin wrapper around `computeStyles()` that adds React context-based\n * SSR collector discovery for backward compatibility with TastyRegistry.\n *\n * For hook-free usage (e.g. in server components), use `computeStyles()` directly.\n *\n * @example\n * ```tsx\n * function MyComponent() {\n * const { className } = useStyles({\n * padding: '2x',\n * fill: '#purple',\n * radius: '1r',\n * });\n *\n * return <div className={className}>Styled content</div>;\n * }\n * ```\n */\nexport function useStyles(\n styles: Styles | undefined,\n options?: { root?: Document | ShadowRoot },\n): UseStylesResult {\n return computeStyles(styles, {\n ssrCollector: useContext(getTastySSRContext()),\n root: options?.root,\n });\n}\n","import { getConfig } from '../config';\nimport { injectGlobal } from '../injector';\nimport type { StyleResult } from '../pipeline';\nimport { renderStyles } from '../pipeline';\nimport { getStyleTarget, pushRSCCSS } from '../rsc-cache';\nimport {\n collectAutoInferredProperties,\n collectAutoInferredPropertiesRSC,\n} from '../ssr/collect-auto-properties';\nimport { formatGlobalRules } from '../ssr/format-global-rules';\nimport type { Styles } from '../styles/types';\nimport { createClientState } from '../utils/client-state';\nimport { hashString } from '../utils/hash';\nimport { resolveRecipes } from '../utils/resolve-recipes';\n\ninterface UseGlobalStylesOptions {\n /**\n * Stable identifier for update tracking (client-only). When provided,\n * changing the styles will dispose the previous injection and inject the\n * new one. Without an id, the selector is used as the slot key.\n * In RSC mode, renders are single-pass so update tracking does not apply.\n */\n id?: string;\n /** Shadow root or document to inject into (client only). */\n root?: Document | ShadowRoot;\n}\n\ninterface ClientGlobalEntry {\n stylesKey: string;\n dispose: () => void;\n}\n\nconst getClientGlobalSlots = /* @__PURE__ */ createClientState(\n () => new Map<string, ClientGlobalEntry>(),\n);\n\nconst noop = () => {\n /* nothing to dispose */\n};\n\n/**\n * Inject global styles for a given selector.\n * Useful for styling elements by selector without generating classNames.\n *\n * SSR-aware: when a ServerStyleCollector is available, CSS is collected\n * during the render phase instead of being injected into the DOM.\n *\n * Works in all environments: client, SSR with collector, and React Server Components.\n *\n * Injected styles are permanent — they are not cleaned up on component unmount.\n * Use the `id` option for update tracking when styles change over the\n * component lifecycle.\n *\n * Update tracking is per-slot and per-root: a slot (`id`, or the selector when\n * no `id` is given) holds exactly one injection per `root`. Changing the styles\n * replaces it; rendering styles that produce no CSS clears it.\n *\n * @param selector - CSS selector to apply styles to (e.g., '.my-class', ':root', 'body')\n * @param styles - Tasty styles object\n * @param options - Optional settings including `id` for update tracking\n *\n * @example\n * ```tsx\n * function MyComponent() {\n * useGlobalStyles('.card', {\n * padding: '2x',\n * radius: '1r',\n * fill: '#white',\n * });\n *\n * return <div className=\"card\">Content</div>;\n * }\n * ```\n */\nexport function useGlobalStyles(\n selector: string,\n styles?: Styles,\n options?: UseGlobalStylesOptions,\n): void {\n if (!styles) return;\n\n if (!selector) {\n if (process.env.NODE_ENV !== 'production') {\n console.warn(\n '[Tasty] useGlobalStyles: selector is required and cannot be empty. ' +\n 'Styles will not be injected.',\n );\n }\n return;\n }\n\n const target = getStyleTarget();\n\n // Resolve the client slot once — both the fast path below and the injection\n // at the end need it.\n const slots =\n target.mode === 'client'\n ? getClientGlobalSlots(options?.root ?? document)\n : null;\n const slotKey = options?.id ?? selector;\n const stylesKey = slots ? JSON.stringify(styles) : '';\n const existing = slots?.get(slotKey);\n\n // Client fast path: skip resolveRecipes/renderStyles if styles haven't changed\n if (existing && existing.stylesKey === stylesKey) return;\n\n const resolvedStyles = resolveRecipes(styles);\n\n const styleResults = renderStyles(resolvedStyles, selector) as StyleResult[];\n\n if (styleResults.length === 0) {\n // An update that renders no CSS must still clear the slot's previous\n // injection, otherwise the stale rules keep applying to the selector.\n if (slots) {\n existing?.dispose();\n slots.set(slotKey, { stylesKey, dispose: noop });\n }\n return;\n }\n\n if (target.mode === 'ssr') {\n target.collector.collectInternals();\n\n const css = formatGlobalRules(styleResults);\n if (css) {\n // A slot key (explicit `id`) replaces, matching client update tracking;\n // content-hashed keys only dedup.\n const key = options?.id\n ? `global:${options.id}`\n : `global:${selector}:${hashString(css)}`;\n target.collector.collectGlobalStyles(key, css, options?.id != null);\n }\n\n if (getConfig().autoPropertyTypes !== false) {\n collectAutoInferredProperties(\n styleResults,\n target.collector,\n resolvedStyles,\n );\n }\n return;\n }\n\n if (target.mode === 'rsc') {\n const css = formatGlobalRules(styleResults);\n if (css) {\n const key = options?.id\n ? `__global:${options.id}`\n : `__global:${selector}:${hashString(css)}`;\n pushRSCCSS(target.cache, key, css, options?.id != null);\n }\n\n if (getConfig().autoPropertyTypes !== false) {\n collectAutoInferredPropertiesRSC(\n styleResults,\n target.cache,\n resolvedStyles,\n );\n }\n return;\n }\n\n // Client path\n if (slots) {\n existing?.dispose();\n\n const { dispose } = injectGlobal(styleResults, { root: options?.root });\n slots.set(slotKey, { stylesKey, dispose });\n }\n}\n","import { injectRawCSS } from '../injector';\nimport { getStyleTarget, pushRSCCSS } from '../rsc-cache';\nimport { createClientState } from '../utils/client-state';\nimport { depsEqual } from '../utils/deps-equal';\nimport { hashString } from '../utils/hash';\n\ninterface UseRawCSSOptions {\n /**\n * Shadow root or document to inject into. Update tracking is per-root: the\n * same id in two roots holds a separate injection in each.\n */\n root?: Document | ShadowRoot;\n /**\n * Stable identifier for update tracking (client-only). When provided,\n * changing the CSS content will dispose the previous injection and inject\n * the new one. Without an id, deduplication is purely content-based (same\n * CSS is injected only once). In RSC mode, renders are single-pass so\n * update tracking does not apply.\n */\n id?: string;\n}\n\ninterface ClientEntry {\n css: string;\n dispose: () => void;\n}\n\ninterface ClientRawCSSState {\n /** id -> the single injection that slot currently owns */\n entries: Map<string, ClientEntry>;\n /** content hashes injected without an id (permanent, deduped) */\n dedup: Set<string>;\n /** id -> last factory deps, to skip re-evaluating the factory */\n deps: Map<string, readonly unknown[]>;\n}\n\nconst getClientState = /* @__PURE__ */ createClientState(\n (): ClientRawCSSState => ({\n entries: new Map(),\n dedup: new Set(),\n deps: new Map(),\n }),\n);\n\n// Overload 1: Static CSS string\nexport function useRawCSS(css: string, options?: UseRawCSSOptions): void;\n\n// Overload 2: Factory function with dependencies\nexport function useRawCSS(\n factory: () => string,\n deps: readonly unknown[],\n options?: UseRawCSSOptions,\n): void;\n\n/**\n * Inject raw CSS text directly without parsing.\n * This is a low-overhead alternative for injecting global CSS that doesn't need tasty processing.\n *\n * The CSS is inserted into a separate style element (data-tasty-raw) to avoid conflicts\n * with tasty's chunked style sheets.\n *\n * Works in all environments: client, SSR with collector, and React Server Components.\n *\n * Injected styles are permanent — they are not cleaned up on component unmount.\n * Use the `id` option for update tracking when styles change over the\n * component lifecycle.\n *\n * @example Static CSS string\n * ```tsx\n * function GlobalStyles() {\n * useRawCSS(`\n * body {\n * margin: 0;\n * padding: 0;\n * font-family: sans-serif;\n * }\n * `);\n *\n * return null;\n * }\n * ```\n *\n * @example Factory function with dependencies\n * ```tsx\n * function ThemeStyles({ theme }: { theme: 'light' | 'dark' }) {\n * useRawCSS(() => `\n * :root {\n * --bg-color: ${theme === 'dark' ? '#1a1a1a' : '#ffffff'};\n * --text-color: ${theme === 'dark' ? '#ffffff' : '#1a1a1a'};\n * }\n * `, [theme], { id: 'theme-vars' });\n *\n * return null;\n * }\n * ```\n *\n * @example With options\n * ```tsx\n * function ShadowStyles({ shadowRoot }) {\n * useRawCSS(() => `.scoped { color: red; }`, [], { root: shadowRoot });\n * return null;\n * }\n * ```\n */\nexport function useRawCSS(\n cssOrFactory: string | (() => string),\n depsOrOptions?: readonly unknown[] | UseRawCSSOptions,\n options?: UseRawCSSOptions,\n): void {\n const isFactory = typeof cssOrFactory === 'function';\n\n const deps =\n isFactory && Array.isArray(depsOrOptions) ? depsOrOptions : undefined;\n const opts = isFactory\n ? options\n : (depsOrOptions as UseRawCSSOptions | undefined);\n const id = opts?.id;\n\n const target = getStyleTarget();\n\n const state =\n target.mode === 'client' ? getClientState(opts?.root ?? document) : null;\n\n // Client deps cache: skip factory re-evaluation when deps haven't changed\n if (isFactory && deps && id && state) {\n const cachedDeps = state.deps.get(id);\n if (cachedDeps && depsEqual(cachedDeps, deps)) {\n return;\n }\n }\n\n const css = isFactory\n ? (cssOrFactory as () => string)()\n : (cssOrFactory as string);\n\n if (!css.trim()) return;\n\n if (target.mode !== 'client') {\n // A slot key (explicit `id`) replaces, matching client update tracking;\n // content-hashed keys only dedup.\n const key = `${target.mode === 'rsc' ? '__' : ''}raw:${id || hashString(css)}`;\n const replace = id != null;\n if (target.mode === 'ssr') {\n target.collector.collectRawCSS(key, css, replace);\n } else {\n pushRSCCSS(target.cache, key, css, replace);\n }\n return;\n }\n\n // Client path\n if (!state) return;\n\n if (id) {\n const existing = state.entries.get(id);\n if (existing) {\n if (existing.css === css) return;\n existing.dispose();\n }\n\n const { dispose } = injectRawCSS(css, opts);\n state.entries.set(id, { css, dispose });\n if (deps) state.deps.set(id, deps);\n } else {\n const contentKey = hashString(css);\n if (state.dedup.has(contentKey)) return;\n state.dedup.add(contentKey);\n injectRawCSS(css, opts);\n }\n}\n","import { getNamePrefix } from '../config';\nimport { keyframes } from '../injector';\nimport type { KeyframesSteps } from '../injector/types';\nimport { getStyleTarget, pushRSCCSS } from '../rsc-cache';\nimport { formatKeyframesCSS } from '../ssr/format-keyframes';\nimport { createClientState } from '../utils/client-state';\nimport { depsEqual } from '../utils/deps-equal';\nimport { hashString } from '../utils/hash';\nimport { makeKeyframeName } from '../utils/name-prefix';\n\ninterface UseKeyframesOptions {\n name?: string;\n root?: Document | ShadowRoot;\n}\n\ninterface FactoryDepsEntry {\n deps: readonly unknown[];\n name: string;\n}\n\ninterface NamedSlotEntry {\n cacheKey: string;\n dispose: () => void;\n}\n\ninterface ClientKeyframesState {\n /** cacheKey (name + serialized steps) -> generated animation name */\n contentToName: Map<string, string>;\n /** provided name -> the single injection that slot currently owns */\n namedSlots: Map<string, NamedSlotEntry>;\n /** provided name -> last factory deps, to skip re-evaluating the factory */\n factoryDeps: Map<string, FactoryDepsEntry>;\n}\n\nconst getClientState = /* @__PURE__ */ createClientState(\n (): ClientKeyframesState => ({\n contentToName: new Map(),\n namedSlots: new Map(),\n factoryDeps: new Map(),\n }),\n);\n\n/**\n * Inject CSS @keyframes and return the generated animation name.\n * Deduplicates by content — identical steps always return the same name.\n *\n * Works in all environments: client, SSR with collector, and React Server Components.\n *\n * Passing `name` claims a slot owned by that one call site (like `useRawCSS`'s\n * `id`): when its steps change, the previous injection is disposed and the name\n * is reused, so the rules don't accumulate. Anonymous keyframes are permanent\n * and shared by content.\n *\n * @example Basic usage - steps object is the dependency\n * ```tsx\n * function MyComponent() {\n * const bounce = useKeyframes({\n * '0%': { transform: 'scale(1)' },\n * '50%': { transform: 'scale(1.1)' },\n * '100%': { transform: 'scale(1)' },\n * });\n *\n * return <div style={{ animation: `${bounce} 1s infinite` }}>Bouncing</div>;\n * }\n * ```\n *\n * @example With custom name\n * ```tsx\n * function MyComponent() {\n * const fadeIn = useKeyframes(\n * { from: { opacity: 0 }, to: { opacity: 1 } },\n * { name: 'fadeIn' }\n * );\n *\n * return <div style={{ animation: `${fadeIn} 0.3s ease-out` }}>Fading in</div>;\n * }\n * ```\n *\n * @example Factory function with dependencies\n * ```tsx\n * function MyComponent({ scale }: { scale: number }) {\n * const pulse = useKeyframes(\n * () => ({\n * '0%': { transform: 'scale(1)' },\n * '100%': { transform: `scale(${scale})` },\n * }),\n * [scale]\n * );\n *\n * return <div style={{ animation: `${pulse} 1s infinite` }}>Pulsing</div>;\n * }\n * ```\n */\n\n// Overload 1: Static steps object\nexport function useKeyframes(\n steps: KeyframesSteps,\n options?: UseKeyframesOptions,\n): string;\n\n// Overload 2: Factory function with dependencies\nexport function useKeyframes(\n factory: () => KeyframesSteps,\n deps: readonly unknown[],\n options?: UseKeyframesOptions,\n): string;\n\n// Implementation\nexport function useKeyframes(\n stepsOrFactory: KeyframesSteps | (() => KeyframesSteps),\n depsOrOptions?: readonly unknown[] | UseKeyframesOptions,\n options?: UseKeyframesOptions,\n): string {\n const isFactory = typeof stepsOrFactory === 'function';\n\n const deps =\n isFactory && Array.isArray(depsOrOptions) ? depsOrOptions : undefined;\n const opts = isFactory\n ? options\n : (depsOrOptions as UseKeyframesOptions | undefined);\n\n const target = getStyleTarget();\n\n const clientState =\n target.mode === 'client' ? getClientState(opts?.root ?? document) : null;\n\n // Client deps cache: skip factory re-evaluation when deps haven't changed\n if (isFactory && deps && opts?.name && clientState) {\n const cached = clientState.factoryDeps.get(opts.name);\n if (cached && depsEqual(cached.deps, deps)) {\n return cached.name;\n }\n }\n\n const steps = isFactory\n ? (stepsOrFactory as () => KeyframesSteps)()\n : (stepsOrFactory as KeyframesSteps);\n\n if (!steps || Object.keys(steps).length === 0) {\n return '';\n }\n\n if (target.mode === 'ssr') {\n const actualName = target.collector.allocateKeyframeName(opts?.name);\n const css = formatKeyframesCSS(actualName, steps);\n target.collector.collectKeyframes(actualName, css);\n return actualName;\n }\n\n if (target.mode === 'rsc') {\n const serializedContent = JSON.stringify(steps);\n const key = `__kf:${opts?.name ?? ''}:${serializedContent}`;\n\n const existingName = target.cache.generatedNames.get(key);\n if (existingName) return existingName;\n\n const actualName =\n opts?.name ??\n makeKeyframeName(getNamePrefix(), hashString(serializedContent));\n const css = formatKeyframesCSS(actualName, steps);\n pushRSCCSS(target.cache, key, css);\n target.cache.generatedNames.set(key, actualName);\n return actualName;\n }\n\n // Client path: stable name via content-based dedup\n const state = clientState ?? getClientState(opts?.root ?? document);\n const serializedContent = JSON.stringify(steps);\n const cacheKey = `${opts?.name ?? ''}:${serializedContent}`;\n\n const cachedName = state.contentToName.get(cacheKey);\n if (cachedName) {\n return cachedName;\n }\n\n const providedName = opts?.name;\n\n // A named slot owns exactly one injection. When its content changes, drop the\n // previous one first: disposing frees the name so the new steps can reclaim\n // it, and it keeps old @keyframes rules from piling up in the sheet.\n if (providedName) {\n const slot = state.namedSlots.get(providedName);\n\n if (slot && slot.cacheKey !== cacheKey) {\n slot.dispose();\n // Forget the stale content too, so any other call site still passing the\n // old steps re-injects instead of pointing at a removed rule.\n state.contentToName.delete(slot.cacheKey);\n state.namedSlots.delete(providedName);\n }\n }\n\n const result = keyframes(steps, {\n name: providedName,\n root: opts?.root,\n });\n\n const name = result.toString();\n state.contentToName.set(cacheKey, name);\n\n if (providedName) {\n state.namedSlots.set(providedName, { cacheKey, dispose: result.dispose });\n\n if (deps) {\n state.factoryDeps.set(providedName, { deps, name });\n }\n }\n\n return name;\n}\n","import { getGlobalInjector } from '../config';\nimport { getStyleTarget, pushRSCCSS } from '../rsc-cache';\nimport { formatPropertyCSS } from '../ssr/format-property';\nimport type { PropertyOptions } from '../injector/types';\n\n/**\n * Options for {@link useProperty}. Extends the shared {@link PropertyOptions}\n * (which is `PropertyDefinition` plus an optional injection `root`).\n */\nexport type UsePropertyOptions = PropertyOptions;\n\n/**\n * Register a CSS @property custom property.\n * This enables advanced features like animating custom properties.\n *\n * Note: @property rules are global and persistent once defined.\n * The function ensures the property is only registered once per root.\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 * Works in all environments: client, SSR with collector, and React Server Components.\n *\n * @param name - The property token ($name, #name) or CSS property name (--name)\n * @param options - Property configuration\n *\n * @example Basic property with token syntax\n * ```tsx\n * function Spinner() {\n * useProperty('$rotation', {\n * syntax: '<angle>',\n * inherits: false,\n * initialValue: '0deg',\n * });\n *\n * return <div className=\"spinner\" />;\n * }\n * ```\n *\n * @example Color property with token syntax (auto-sets syntax)\n * ```tsx\n * function MyComponent() {\n * useProperty('#theme', {\n * initialValue: 'red', // syntax: '<color>' is auto-set\n * });\n *\n * // Now --theme-color can be animated with CSS transitions\n * return <div style={{ '--theme-color': 'blue' } as React.CSSProperties}>Colored</div>;\n * }\n * ```\n *\n * @example Legacy format (still supported)\n * ```tsx\n * function ResizableBox() {\n * useProperty('--box-size', {\n * syntax: '<length>',\n * initialValue: '100px',\n * });\n *\n * return <div style={{ width: 'var(--box-size)' }} />;\n * }\n * ```\n */\nexport function useProperty(name: string, options?: UsePropertyOptions): void {\n if (!name) {\n if (process.env.NODE_ENV !== 'production') {\n console.warn(`[Tasty] useProperty: property name is required`);\n }\n return;\n }\n\n const target = getStyleTarget();\n\n if (target.mode === 'ssr') {\n target.collector.collectInternals();\n\n const css = formatPropertyCSS(name, {\n syntax: options?.syntax,\n inherits: options?.inherits,\n initialValue: options?.initialValue,\n });\n if (css) {\n target.collector.collectProperty(name, css);\n }\n return;\n }\n\n if (target.mode === 'rsc') {\n const css = formatPropertyCSS(name, {\n syntax: options?.syntax,\n inherits: options?.inherits,\n initialValue: options?.initialValue,\n });\n if (css) {\n pushRSCCSS(target.cache, `__prop:${name}`, css);\n }\n return;\n }\n\n const injector = getGlobalInjector();\n\n if (injector.isPropertyDefined(name, { root: options?.root })) {\n return;\n }\n\n injector.property(name, {\n syntax: options?.syntax,\n inherits: options?.inherits,\n initialValue: options?.initialValue,\n root: options?.root,\n });\n}\n","import { getGlobalInjector } from '../config';\nimport { fontFaceContentHash, formatFontFaceRule } from '../font-face';\nimport type { FontFaceDescriptors, FontFaceInput } from '../injector/types';\nimport { getStyleTarget, pushRSCCSS } from '../rsc-cache';\n\ninterface UseFontFaceOptions {\n root?: Document | ShadowRoot;\n}\n\n/**\n * Inject CSS @font-face rules.\n * Permanent — no cleanup on unmount. Deduplicates by content hash.\n *\n * Works in all environments: client, SSR with collector, and React Server Components.\n *\n * @param family - The font-family name\n * @param input - Single descriptor object or array of descriptors (for multiple weights/styles)\n * @param options - Optional settings (e.g. Shadow DOM root)\n *\n * @example Single weight\n * ```tsx\n * function App() {\n * useFontFace('Brand Sans', {\n * src: 'url(\"/fonts/brand-sans.woff2\") format(\"woff2\")',\n * fontWeight: '400 700',\n * fontDisplay: 'swap',\n * });\n *\n * return <div style={{ fontFamily: '\"Brand Sans\", sans-serif' }}>Hello</div>;\n * }\n * ```\n *\n * @example Multiple weights\n * ```tsx\n * function App() {\n * useFontFace('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 *\n * return <div style={{ fontFamily: '\"Brand Sans\", sans-serif' }}>Hello</div>;\n * }\n * ```\n */\nexport function useFontFace(\n family: string,\n input: FontFaceInput,\n options?: UseFontFaceOptions,\n): void {\n if (!family) return;\n\n const descriptors: FontFaceDescriptors[] = Array.isArray(input)\n ? input\n : [input];\n\n const target = getStyleTarget();\n\n if (target.mode === 'ssr') {\n for (const desc of descriptors) {\n const hash = fontFaceContentHash(family, desc);\n const css = formatFontFaceRule(family, desc);\n target.collector.collectFontFace(hash, css);\n }\n return;\n }\n\n if (target.mode === 'rsc') {\n for (const desc of descriptors) {\n const hash = fontFaceContentHash(family, desc);\n const css = formatFontFaceRule(family, desc);\n pushRSCCSS(target.cache, `__ff:${hash}`, css);\n }\n return;\n }\n\n const injector = getGlobalInjector();\n for (const desc of descriptors) {\n injector.fontFace(family, desc, { root: options?.root });\n }\n}\n","import { getGlobalInjector, getNamePrefix } from '../config';\nimport { formatCounterStyleRule } from '../counter-style';\nimport type { CounterStyleDescriptors } from '../injector/types';\nimport { getStyleTarget, pushRSCCSS } from '../rsc-cache';\nimport { createClientState } from '../utils/client-state';\nimport { hashString } from '../utils/hash';\nimport { makeCounterStyleName } from '../utils/name-prefix';\n\ninterface UseCounterStyleOptions {\n name?: string;\n root?: Document | ShadowRoot;\n}\n\nlet clientCounterStyleCounter = 0;\n\nconst getClientContentToName = /* @__PURE__ */ createClientState(\n () => new Map<string, string>(),\n);\n\n/**\n * Inject a CSS @counter-style rule and return the generated name.\n * Permanent — no cleanup on unmount. Deduplicates by name.\n *\n * Works in all environments: client, SSR with collector, and React Server Components.\n *\n * @example Basic usage\n * ```tsx\n * function EmojiList() {\n * const styleName = useCounterStyle({\n * system: 'cyclic',\n * symbols: '\"👍\"',\n * suffix: '\" \"',\n * }, { name: 'thumbs' });\n *\n * return (\n * <ol style={{ listStyleType: styleName }}>\n * <li>First</li>\n * <li>Second</li>\n * </ol>\n * );\n * }\n * ```\n *\n */\nexport function useCounterStyle(\n descriptors: CounterStyleDescriptors,\n options?: UseCounterStyleOptions,\n): string {\n if (!descriptors || !descriptors.system) {\n return '';\n }\n\n const target = getStyleTarget();\n\n if (target.mode === 'ssr') {\n const actualName = target.collector.allocateCounterStyleName(options?.name);\n const css = formatCounterStyleRule(actualName, descriptors);\n target.collector.collectCounterStyle(actualName, css);\n return actualName;\n }\n\n if (target.mode === 'rsc') {\n const serializedContent = JSON.stringify(descriptors);\n const key = `__cs:${options?.name ?? ''}:${serializedContent}`;\n\n const existingName = target.cache.generatedNames.get(key);\n if (existingName) return existingName;\n\n const actualName =\n options?.name ??\n makeCounterStyleName(getNamePrefix(), hashString(serializedContent));\n const css = formatCounterStyleRule(actualName, descriptors);\n pushRSCCSS(target.cache, key, css);\n target.cache.generatedNames.set(key, actualName);\n return actualName;\n }\n\n // Client path: stable name via content-based dedup\n const contentToName = getClientContentToName(options?.root ?? document);\n const serializedContent = JSON.stringify(descriptors);\n const cacheKey = `${options?.name ?? ''}:${serializedContent}`;\n\n const existingName = contentToName.get(cacheKey);\n if (existingName) {\n return existingName;\n }\n\n const name =\n options?.name ??\n makeCounterStyleName(getNamePrefix(), String(clientCounterStyleCounter++));\n contentToName.set(cacheKey, name);\n\n const injector = getGlobalInjector();\n injector.counterStyle(name, descriptors, { root: options?.root });\n\n return name;\n}\n","import { getGlobalInjector, isFunctionsPolyfillEnabled } from '../config';\nimport {\n formatFunctionRule,\n parseFunctionName,\n registerFunctionPolyfill,\n} from '../functions';\nimport type { FunctionDefinition } from '../injector/types';\nimport { getStyleTarget, pushRSCCSS } from '../rsc-cache';\n\nexport interface UseFunctionOptions {\n /** Shadow root or document to inject into. */\n root?: Document | ShadowRoot;\n}\n\n/**\n * Register a CSS @function (custom function).\n *\n * @function rules are global and persistent once defined. The hook ensures the\n * function is only registered once per root (deduplicated by function name).\n *\n * Accepts tasty token syntax for the function name:\n * - `$$name` → defines `--name` (matches the call site `$$name(...)`)\n * - `$name` / `--name` → also accepted\n *\n * Works in all environments: client, SSR with collector, and React Server Components.\n *\n * @param name - The function name token (`$$name`, `$name`, or `--name`)\n * @param definition - Function definition (args, returns, result, local vars)\n *\n * Call the function through the Tasty DSL, not a raw `style` prop: an inline\n * `style` value reaches the browser unparsed, so the `$$name(...)` sugar is never\n * expanded and `polyfills.functions` cannot rewrite it either.\n *\n * @example\n * ```tsx\n * const Box = tasty({ styles: { marginTop: '$$negative(10px)' } });\n *\n * function Layout() {\n * useFunction('$$negative', { args: ['$value'], result: '(-1 * $value)' });\n * return <Box />;\n * }\n * ```\n */\nexport function useFunction(\n name: string,\n definition: FunctionDefinition,\n options?: UseFunctionOptions,\n): void {\n if (!name) {\n if (process.env.NODE_ENV !== 'production') {\n console.warn(`[Tasty] useFunction: function name is required`);\n }\n return;\n }\n\n // @function polyfill: register an inline closure so call sites are expanded\n // into plain CSS by the parser. No native @function rule is emitted.\n if (isFunctionsPolyfillEnabled()) {\n registerFunctionPolyfill(name, definition);\n return;\n }\n\n const target = getStyleTarget();\n\n if (target.mode === 'ssr') {\n target.collector.collectInternals();\n\n const css = formatFunctionRule(name, definition);\n if (css) {\n target.collector.collectFunction(parseFunctionName(name), css);\n }\n return;\n }\n\n if (target.mode === 'rsc') {\n const css = formatFunctionRule(name, definition);\n if (css) {\n pushRSCCSS(target.cache, `__func:${parseFunctionName(name)}`, css);\n }\n return;\n }\n\n getGlobalInjector().func(name, definition, { root: options?.root });\n}\n","import { useInsertionEffect } from 'react';\nimport type { ReactNode } from 'react';\n\nimport { closeBatchWindow, openBatchWindow } from './injector/batch';\n\nexport interface TastyBatchProviderProps {\n children?: ReactNode;\n}\n\n/**\n * Opens a *batch window* for the commit it renders in, so `batchInjection`\n * can defer stylesheet writes without ever letting a layout effect measure an\n * unstyled element.\n *\n * Every `insertRule()` on a live sheet invalidates style for that sheet's\n * scope. When components inject during React's render phase while others read\n * layout in the same pass, the two interleave and the browser recalculates\n * style between every injection. Batching collapses that into one invalidation\n * per flush — but only if the flush happens before anything can measure.\n *\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 *\n * `useInsertionEffect` runs in React's mutation phase, after every render in\n * the commit and before any `useLayoutEffect` — which is exactly why React\n * added it for CSS-in-JS libraries. Effects fire child-first, so this\n * provider's runs after every descendant's and still before all layout\n * effects.\n *\n * A commit that does not re-render this provider gets no window, and those\n * injections are written synchronously instead. That is the point: turning\n * `batchInjection: true` on can only ever make injection cheaper, never make a\n * measurement wrong. It also means batching applies to commits this provider\n * takes part in, so mount it as high in the tree as you can.\n *\n * Requires `configure({ batchInjection: true })`; without it this component\n * only renders its children. `batchInjection: 'always'` does not need the\n * provider at all — see that option's docs for the trade-off it accepts.\n *\n * @example\n * ```tsx\n * configure({ batchInjection: true });\n *\n * createRoot(el).render(\n * <TastyBatchProvider>\n * <App />\n * </TastyBatchProvider>,\n * );\n * ```\n */\nexport function TastyBatchProvider({ children }: TastyBatchProviderProps) {\n // Opened during render on purpose: the window has to be open before children\n // render, and this is the only phase that precedes them. It is idempotent and\n // has no other side effect, so StrictMode's double render costs nothing. A\n // render that is thrown away (aborted or suspended) leaves the window open,\n // which the microtask backstop closes — and such a render mounts nothing, so\n // nothing can measure what it queued.\n openBatchWindow();\n\n // Fires in the mutation phase, before any layout effect. No dependency array:\n // it must run on every commit this provider is part of.\n useInsertionEffect(() => {\n closeBatchWindow();\n });\n\n return children;\n}\n"],"mappings":"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"}
|