fashionable 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (111) hide show
  1. package/README.md +276 -0
  2. package/dist/calc/index.d.mts +2 -0
  3. package/dist/calc/index.mjs +1 -334
  4. package/dist/data/index.d.mts +208 -0
  5. package/dist/data/index.mjs +696 -0
  6. package/dist/data/index.mjs.map +1 -0
  7. package/dist/declaration/index.d.mts +2 -0
  8. package/dist/declaration/index.mjs +2 -2
  9. package/dist/declaration/index.mjs.map +1 -1
  10. package/dist/fontFace/index.d.mts +2 -0
  11. package/dist/fontFace/index.mjs +10 -8
  12. package/dist/fontFace/index.mjs.map +1 -1
  13. package/dist/property/index.d.mts +2 -0
  14. package/dist/property/index.mjs +13 -9
  15. package/dist/property/index.mjs.map +1 -1
  16. package/dist/query/index.d.mts +2 -0
  17. package/dist/query/index.mjs +6 -5
  18. package/dist/query/index.mjs.map +1 -1
  19. package/dist/rule/index.d.mts +2 -0
  20. package/dist/rule/index.mjs +19 -2
  21. package/dist/rule/index.mjs.map +1 -1
  22. package/dist/selector/index.d.mts +2 -0
  23. package/dist/selector/index.mjs +2 -2
  24. package/dist/shared/calc-Cih4o2r7.mjs +1145 -0
  25. package/dist/shared/calc-Cih4o2r7.mjs.map +1 -0
  26. package/dist/shared/color-BvNJ2YqL.d.mts +590 -0
  27. package/dist/shared/color.internal-Dts5ycTm.mjs +450 -0
  28. package/dist/shared/color.internal-Dts5ycTm.mjs.map +1 -0
  29. package/dist/shared/declaration-1DlO_ltT.d.mts +166 -0
  30. package/dist/shared/{declaration.internal-DvZknsDc.mjs → declaration.internal-wLB4ssxC.mjs} +4 -4
  31. package/dist/shared/declaration.internal-wLB4ssxC.mjs.map +1 -0
  32. package/dist/shared/{equal-C96LR7p4.mjs → equal-U9G5LhtL.mjs} +2 -14
  33. package/dist/shared/{equal-C96LR7p4.mjs.map → equal-U9G5LhtL.mjs.map} +1 -1
  34. package/dist/shared/fontFaceRule-C7nYgH6X.d.mts +294 -0
  35. package/dist/shared/{fontFaceRule.internal-CgnEJbNS.mjs → fontFaceRule.internal-D5u48TUO.mjs} +51 -10
  36. package/dist/shared/fontFaceRule.internal-D5u48TUO.mjs.map +1 -0
  37. package/dist/shared/index-BvtwY4FQ.d.mts +841 -0
  38. package/dist/shared/mediaQuery-BYR1z-iD.d.mts +145 -0
  39. package/dist/shared/{mediaQuery.internal-BZF1beZO.mjs → mediaQuery.internal-B6iuMd75.mjs} +2 -2
  40. package/dist/shared/{mediaQuery.internal-BZF1beZO.mjs.map → mediaQuery.internal-B6iuMd75.mjs.map} +1 -1
  41. package/dist/shared/mediaRule-BDB4WCYy.d.mts +558 -0
  42. package/dist/shared/precision.internal-0lv1nEpF.mjs +40 -0
  43. package/dist/shared/precision.internal-0lv1nEpF.mjs.map +1 -0
  44. package/dist/shared/propertyRule-BbkFh9b9.d.mts +466 -0
  45. package/dist/shared/{propertyRule.internal-BY1ghubC.mjs → propertyRule.internal-Bc_HrfcL.mjs} +4 -4
  46. package/dist/shared/propertyRule.internal-Bc_HrfcL.mjs.map +1 -0
  47. package/dist/shared/rolldown-runtime-D7D4PA-g.mjs +13 -0
  48. package/dist/shared/{ruleSet.internal-DQjyPgko.mjs → ruleSet.internal-DodzVMUU.mjs} +13 -7
  49. package/dist/shared/{ruleSet.internal-DQjyPgko.mjs.map → ruleSet.internal-DodzVMUU.mjs.map} +1 -1
  50. package/dist/shared/selector-HZY-W6l6.d.mts +346 -0
  51. package/dist/shared/{selector.internal-BLQtVoIM.mjs → selector.internal-ESe9s0IH.mjs} +2 -2
  52. package/dist/shared/{selector.internal-BLQtVoIM.mjs.map → selector.internal-ESe9s0IH.mjs.map} +1 -1
  53. package/dist/shared/utils-BKm298I-.d.mts +179 -0
  54. package/dist/stylesheet/index.d.mts +316 -0
  55. package/dist/stylesheet/index.mjs +50 -11
  56. package/dist/stylesheet/index.mjs.map +1 -1
  57. package/dist/utils.d.mts +2 -0
  58. package/package.json +16 -16
  59. package/dist/calc/calc.d.ts +0 -425
  60. package/dist/calc/calc.internal.d.ts +0 -2
  61. package/dist/calc/index.d.ts +0 -6
  62. package/dist/calc/index.mjs.map +0 -1
  63. package/dist/calc/precision.d.ts +0 -72
  64. package/dist/calc/precision.internal.d.ts +0 -2
  65. package/dist/color/color.d.ts +0 -121
  66. package/dist/color/color.internal.d.ts +0 -2
  67. package/dist/color/index.d.ts +0 -3
  68. package/dist/color/index.mjs +0 -73
  69. package/dist/color/index.mjs.map +0 -1
  70. package/dist/declaration/declaration.d.ts +0 -159
  71. package/dist/declaration/declaration.internal.d.ts +0 -2
  72. package/dist/declaration/index.d.ts +0 -3
  73. package/dist/fontFace/fontFaceRule.d.ts +0 -257
  74. package/dist/fontFace/fontFaceRule.internal.d.ts +0 -4
  75. package/dist/fontFace/index.d.ts +0 -3
  76. package/dist/internal/equal.d.ts +0 -13
  77. package/dist/internal/format.d.ts +0 -6
  78. package/dist/internal/refs.d.ts +0 -8
  79. package/dist/internal/render.d.ts +0 -6
  80. package/dist/property/index.d.ts +0 -6
  81. package/dist/property/propertyRule.d.ts +0 -174
  82. package/dist/property/propertyRule.internal.d.ts +0 -2
  83. package/dist/property/propertySyntax.d.ts +0 -282
  84. package/dist/property/propertySyntax.internal.d.ts +0 -2
  85. package/dist/query/index.d.ts +0 -3
  86. package/dist/query/mediaQuery.d.ts +0 -134
  87. package/dist/query/mediaQuery.internal.d.ts +0 -2
  88. package/dist/rule/index.d.ts +0 -9
  89. package/dist/rule/mediaRule.d.ts +0 -115
  90. package/dist/rule/mediaRule.internal.d.ts +0 -2
  91. package/dist/rule/rule.internal.d.ts +0 -13
  92. package/dist/rule/ruleSet.d.ts +0 -249
  93. package/dist/rule/ruleSet.internal.d.ts +0 -2
  94. package/dist/rule/styleRule.d.ts +0 -110
  95. package/dist/rule/styleRule.internal.d.ts +0 -2
  96. package/dist/selector/index.d.ts +0 -6
  97. package/dist/selector/selector.d.ts +0 -243
  98. package/dist/selector/selector.internal.d.ts +0 -2
  99. package/dist/selector/specificity.d.ts +0 -92
  100. package/dist/selector/specificity.internal.d.ts +0 -2
  101. package/dist/shared/calc.internal-C1g_NRsl.mjs +0 -568
  102. package/dist/shared/calc.internal-C1g_NRsl.mjs.map +0 -1
  103. package/dist/shared/color.internal-D7P91Rvv.mjs +0 -100
  104. package/dist/shared/color.internal-D7P91Rvv.mjs.map +0 -1
  105. package/dist/shared/declaration.internal-DvZknsDc.mjs.map +0 -1
  106. package/dist/shared/fontFaceRule.internal-CgnEJbNS.mjs.map +0 -1
  107. package/dist/shared/propertyRule.internal-BY1ghubC.mjs.map +0 -1
  108. package/dist/stylesheet/index.d.ts +0 -3
  109. package/dist/stylesheet/stylesheet.d.ts +0 -275
  110. package/dist/stylesheet/stylesheet.internal.d.ts +0 -2
  111. package/dist/utils.d.ts +0 -176
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.mjs","names":["rad","deg","internal.rad","internal.deg","L","C","H","R","G","B","Alpha","internal.L","internal.C","internal.H","internal.R","internal.G","internal.B","internal.Alpha","internal.isColor","oklch","internal.oklch","srgb","internal.srgb","internal.named","internal.transparent","internal.ref","internal.lightDark","internal.mix","internal.from","internal.bind","internal.serialize","internal.refs","internal.channels","internal.equals","internal.oklch","internal.srgb","internal.srgbLinear","internal.displayP3","internal.a98Rgb","internal.prophotoRgb","internal.rec2020","internal.lab","internal.oklab","internal.xyz","internal.xyzD50","internal.xyzD65","internal.hsl","internal.hwb","internal.lch","internal.shorter","internal.longer","internal.increasing","internal.decreasing","internal.interpolate","internal.none","internal.isNone","px","rem","em","vw","vh","vmin","vmax","internal.px","internal.rem","internal.em","internal.vw","internal.vh","internal.vmin","internal.vmax","internal.of"],"sources":["../../src/data/angle.internal.ts","../../src/data/angle.ts","../../src/data/channels.internal.ts","../../src/data/channels.ts","../../src/data/color.ts","../../src/data/colorSpace.ts","../../src/data/hueInterpolation.ts","../../src/data/keywords.ts","../../src/data/length.internal.ts","../../src/data/length.ts","../../src/data/percentage.ts","../../src/data/units.ts"],"sourcesContent":["import type { Calc } from '#calc/calc'\nimport { dimension } from '#calc/calc.internal'\nimport type { Precision } from '#calc/precision'\nimport type { Deg, Rad } from './units.ts'\n\n/** @internal */\nexport const rad = (value: number, precision?: Precision): Calc<never, 'angle', Rad> =>\n dimension(value, 'rad', 'angle', precision)\n\n/** @internal */\nexport const deg = (value: number, precision?: Precision): Calc<never, 'angle', Deg> =>\n dimension(value, 'deg', 'angle', precision)\n","/**\n * `<angle>` constructors. An angle-kind expression composes with the `Calc`\n * combinators like any other dimension — `Calc.subtract` of two angles is an\n * angle, scaling by a number stays an angle — and subtracting a plain number\n * from an angle is a type error, so the radian phase of a trig expression is\n * written `Angle.rad(...)` rather than a bare number.\n *\n * `rad` and `deg` are modeled today; `turn`/`grad` arrive as a consumer needs\n * them.\n *\n * @since 0.2.0\n */\n\nimport type { Calc } from '#calc/calc'\nimport type { Precision } from '#calc/precision'\nimport * as internal from './angle.internal.ts'\nimport type { Angle as AngleUnit, Deg, Rad } from './units.ts'\n\n/**\n * An `<angle>` expression: a `Calc` of angle kind, in any angle unit. Names the\n * dimension without spelling `Calc<Refs, 'angle', Unit.Angle>` — `Angle.rad(2)`\n * produces one, and it composes with every `Calc` combinator (subtracting two\n * angles is an angle, scaling by a number stays an angle). `Refs` unions the\n * unbound reference names, as on `Calc`.\n *\n * The leaf is the widened `Unit.Angle`, so every specific angle expression is\n * assignable to it; a constructor narrows it (`Angle.rad` carries `Unit.Rad`).\n *\n * @since 0.2.0\n */\nexport type Angle<Refs extends string = string> = Calc<Refs, 'angle', AngleUnit>\n\n/**\n * An angle in `rad` (radians). Radians are the numeric measure of an angle, so\n * a radian-only expression solves with no unit context.\n *\n * @param value - The angle in radians.\n * @param precision - Optional serialization precision.\n * @returns A `rad` angle expression.\n * @example\n * ```ts\n * Calc.serialize(Angle.rad(1.5708)) // '1.5708rad'\n * ```\n * @since 0.2.0\n */\nexport const rad: (value: number, precision?: Precision) => Calc<never, 'angle', Rad> = internal.rad\n\n/**\n * An angle in `deg` (degrees). Degrees lower to radians at solve (`180deg` is\n * `pi`), a fixed ratio, so a degree-only expression solves with no unit context.\n *\n * @param value - The angle in degrees.\n * @param precision - Optional serialization precision.\n * @returns A `deg` angle expression.\n * @example\n * ```ts\n * Calc.serialize(Angle.deg(45)) // '45deg'\n * ```\n * @since 0.2.0\n */\nexport const deg: (value: number, precision?: Precision) => Calc<never, 'angle', Deg> = internal.deg\n","import type { Calc } from '#calc/calc'\nimport { ident } from '#calc/calc.internal'\n\n/** @internal */\nexport const L: Calc<never> = ident('l')\n\n/** @internal */\nexport const C: Calc<never> = ident('c')\n\n/** @internal */\nexport const H: Calc<never> = ident('h')\n\n/** @internal */\nexport const R: Calc<never> = ident('r')\n\n/** @internal */\nexport const G: Calc<never> = ident('g')\n\n/** @internal */\nexport const B: Calc<never> = ident('b')\n\n/** @internal */\nexport const Alpha: Calc<never> = ident('alpha')\n","/**\n * Origin-channel keywords for relative color syntax. Inside a relative color\n * — `Color.from(origin, ColorSpace.oklch, ...)` — these reference the channels\n * of the `from` origin, converted into the destination space:\n * `oklch(from <origin> l c h)` rebuilds the origin unchanged, and arithmetic\n * on the keywords derives a new color (`calc(l * 0.8)` darkens it).\n *\n * Each keyword is a `Calc` number expression that serializes bare — `l`, not\n * `var(--l)` — and contributes no references: it is neither a custom property\n * nor a `Color.bind` target, since the browser resolves it from the origin. It\n * is not opaque to `Calc.solve`, though — each carries a leaf brand, so an\n * expression built on one solves by supplying the keyword's value in the\n * context (`Calc.solve(expr, {}, { l: 0.62 })`), the way a viewport unit\n * supplies a ratio. They compose with every `Calc` combinator, and the\n * destination `ColorSpace` passed to `Color.from` fixes which are in scope —\n * `l`/`c`/`h` for `oklch`, `r`/`g`/`b` for `srgb`, `alpha` for both — through\n * a brand each keyword carries, so an out-of-space keyword is a compile error.\n *\n * Modeled today: the `oklch` and `color(srgb ...)` channels. Siblings\n * (`s`/`w`, the `lab` axes) arrive with the color functions that name them.\n *\n * @since 0.2.0\n */\n\nimport type { Calc } from '#calc/calc'\nimport * as internal from './channels.internal.ts'\nimport type { ChannelLeaf } from './units.ts'\n\n/**\n * The `l` origin channel — lightness in `oklch`. Serializes bare as `l`.\n *\n * @since 0.2.0\n */\nexport const L: Calc<never, 'number', ChannelLeaf<'l'>> = internal.L\n\n/**\n * The `c` origin channel — chroma in `oklch`. Serializes bare as `c`.\n *\n * @since 0.2.0\n */\nexport const C: Calc<never, 'number', ChannelLeaf<'c'>> = internal.C\n\n/**\n * The `h` origin channel — hue in `oklch`, in degrees. Serializes bare as `h`.\n *\n * @since 0.2.0\n */\nexport const H: Calc<never, 'number', ChannelLeaf<'h'>> = internal.H\n\n/**\n * The `r` origin channel — red in `color(srgb ...)`. Serializes bare as `r`.\n *\n * @since 0.2.0\n */\nexport const R: Calc<never, 'number', ChannelLeaf<'r'>> = internal.R\n\n/**\n * The `g` origin channel — green in `color(srgb ...)`. Serializes bare as `g`.\n *\n * @since 0.2.0\n */\nexport const G: Calc<never, 'number', ChannelLeaf<'g'>> = internal.G\n\n/**\n * The `b` origin channel — blue in `color(srgb ...)`. Serializes bare as `b`.\n *\n * @since 0.2.0\n */\nexport const B: Calc<never, 'number', ChannelLeaf<'b'>> = internal.B\n\n/**\n * The `alpha` origin channel — the opacity of the `from` origin, in `oklch`\n * and `color(srgb ...)` alike. Serializes bare as `alpha`.\n *\n * @since 0.2.0\n */\nexport const Alpha: Calc<never, 'number', ChannelLeaf<'alpha'>> = internal.Alpha\n","import type { ApplyBindings, Bindings, Calc, Input, SerializeOptions } from '#calc/calc'\nimport type { Pipeable } from '#util'\nimport type { ColorTypeId } from './color.internal.ts'\nimport * as internal from './color.internal.ts'\nimport type { ColorSpace, PolarSpace } from './colorSpace.ts'\nimport type { HueInterpolation } from './hueInterpolation.ts'\nimport type { None } from './keywords.ts'\n\ndeclare const ColorRefs: unique symbol\n\n/**\n * A CSS color expression whose channels are `Calc` number expressions.\n *\n * A color is not a number: it can be bound and serialized, but not\n * solved. The `Refs` parameter unions the channels' unbound reference\n * names, exactly as on `Calc`.\n *\n * `oklch(...)`, `color(srgb ...)`, `light-dark(...)`, `color-mix(...)`,\n * relative colors (`oklch(from ...)`, `color(from ...)`), a color-valued\n * `var(...)`, and named colors are modeled today; other color functions\n * arrive as a consumer needs them. Channels accept `Keyword.none`, CSS's\n * missing-component value.\n *\n * Construct via `oklch`, `srgb`, `lightDark`, `mix`, `named`, `from`, and\n * `ref` (or the `transparent` constant).\n *\n * @since 0.1.0\n */\nexport interface Color<out Refs extends string = string> extends Pipeable {\n readonly [ColorTypeId]: ColorTypeId\n readonly [ColorRefs]?: Refs\n}\n\n/**\n * Checks if a value is a `Color`.\n *\n * True only for values built by this module's constructors, which carry\n * the brand.\n *\n * @param u - The value to check.\n * @returns `true` if the value is a `Color`, `false` otherwise.\n * @since 0.1.0\n */\nexport const isColor: (u: unknown) => u is Color<string> = internal.isColor\n\n/**\n * Creates an `oklch(...)` color from three channel expressions: lightness\n * (`0` to `1`), chroma (`0` upward), and hue (degrees). A channel may be\n * `Keyword.none` — the missing-component keyword, the conventional hue\n * for achromatic colors: `oklch(0 0 none)`.\n *\n * Each channel serializes independently, wrapped in `calc()` when it is\n * arithmetic: `oklch(var(--l) calc(var(--c) * 0.5) 220)`.\n *\n * @param lightness - The lightness channel.\n * @param chroma - The chroma channel.\n * @param hue - The hue channel, in degrees.\n * @returns A `Color` with the channels' references unioned.\n * @example\n * ```ts\n * const accent = Color.oklch(Calc.ref('lightness'), 0.15, 220)\n * Color.serialize(accent) // 'oklch(var(--lightness) 0.15 220)'\n * ```\n * @since 0.1.0\n */\nexport const oklch: <L extends string = never, C extends string = never, H extends string = never>(\n lightness: Input<L> | None,\n chroma: Input<C> | None,\n hue: Input<H> | None,\n) => Color<L | C | H> = internal.oklch\n\n/**\n * Creates a `color(srgb ...)` color from three channel expressions, each\n * `0` to `1`. A channel may be `Keyword.none`, the missing-component\n * keyword.\n *\n * Each channel serializes independently, wrapped in `calc()` when it is\n * arithmetic, inside the `color()` function's `srgb` colorspace:\n * `color(srgb 0.18 0.34 0.78)`.\n *\n * @param red - The red channel.\n * @param green - The green channel.\n * @param blue - The blue channel.\n * @returns A `Color` with the channels' references unioned.\n * @example\n * ```ts\n * const brand = Color.srgb(0.18, 0.34, 0.78)\n * Color.serialize(brand) // 'color(srgb 0.18 0.34 0.78)'\n * ```\n * @since 0.2.0\n */\nexport const srgb: <R extends string = never, G extends string = never, B extends string = never>(\n red: Input<R> | None,\n green: Input<G> | None,\n blue: Input<B> | None,\n) => Color<R | G | B> = internal.srgb\n\n/**\n * Creates a named color, rendered bare: `named('rebeccapurple')`\n * serializes as `rebeccapurple`. The name is the whole value — a named\n * color has no channels, contributes no references, and binds nothing.\n *\n * That the name is one of the specification's named colors is not\n * checked, matching the library's posture on identifiers — with one\n * exception: the CSS-wide keywords (`inherit`, `initial`, ...) are\n * whole-declaration values, not colors (`light-dark(inherit, ...)` is\n * invalid CSS), and are rejected.\n *\n * @param name - The color name. Must be non-empty and not a CSS-wide keyword.\n * @returns A `Color<never>`.\n * @throws `Error` when `name` is empty or a CSS-wide keyword.\n * @since 0.2.0\n */\nexport const named: (name: string) => Color<never> = internal.named\n\n/**\n * The `transparent` named color — `rgb(0 0 0 / 0)` by definition, and\n * the conventional \"no color\" value.\n *\n * @since 0.2.0\n */\nexport const transparent: Color<never> = internal.transparent\n\n/**\n * Creates a color-valued custom-property reference — `ref('accent')`\n * serializes as `var(--accent)`. Use it where a whole color is read from a\n * custom property: as a standalone value, or as the origin of a relative color\n * (`from`).\n *\n * The reference is the whole value, so it carries `name` as its one unbound\n * reference — a dependency, exactly as an unbound `Calc.ref` does — but has no\n * channels. `bind` substitutes channel expressions, not whole colors, so it\n * leaves a color reference in place; the browser resolves it from the cascade.\n *\n * @param name - The custom-property name, without the `--` prefix. Must be non-empty.\n * @returns A `Color` with `name` as its one unbound reference.\n * @throws `Error` when `name` is empty.\n * @example\n * ```ts\n * Color.serialize(Color.ref('accent')) // 'var(--accent)'\n * ```\n * @since 0.2.0\n */\nexport const ref: <Name extends string>(name: Name) => Color<Name> = internal.ref\n\n/**\n * Creates a scheme-conditional `light-dark(...)` color: the browser uses\n * the first color under the light scheme and the second under dark.\n *\n * The arms are whole colors and positional — `lightDark(a, b)` and\n * `lightDark(b, a)` are different colors. Any `Color` is accepted,\n * including another `lightDark` (grammatically an arm is any `<color>`;\n * nesting is redundant but legal, and simplification is not this type's\n * job). Note the resolution context: `light-dark()` requires\n * `color-scheme` to be set — that contract is the consumer's.\n *\n * @param light - The color used under the light scheme.\n * @param dark - The color used under the dark scheme.\n * @returns A `Color` with both arms' references unioned.\n * @example\n * ```ts\n * const accent = Color.lightDark(Color.srgb(0.85, 0.3, 0.4), Color.srgb(0.95, 0.5, 0.55))\n * Color.serialize(accent) // 'light-dark(color(srgb 0.85 0.3 0.4), color(srgb 0.95 0.5 0.55))'\n * ```\n * @since 0.2.0\n */\nexport const lightDark: <A extends string = never, B extends string = never>(\n light: Color<A>,\n dark: Color<B>,\n) => Color<A | B> = internal.lightDark\n\n// A mix arm: a bare color, or a [color, weight] tuple. A bare number weight\n// reads as a percent; a `Percentage` expression carries an annotated or\n// computed one, and a plain number-kind `Calc` is rejected.\ntype MixArm<C extends string, P extends string> =\n | Color<C>\n | readonly [Color<C>, number | Calc<P, 'percentage', unknown>]\n\n/**\n * Creates a `color-mix(...)`: the browser mixes `color1` and `color2` in the\n * interpolation `space`. Each arm is a bare `Color` or a `[color, percentage]`\n * tuple giving its weight — a bare number reads as a percent (`20` is `20%`,\n * the `<percentage>` convention), a `Percentage` expression an annotated or\n * computed weight (`Percentage.of(20)`, `Calc.multiply(Percentage.of(50), ...)`);\n * a plain number-kind `Calc` is rejected, a weight being a `<percentage>`.\n *\n * A polar `space` (`ColorSpace.oklch`, `ColorSpace.lch`, ...) may take a\n * `HueInterpolation` strategy between the space and the colors — the second\n * overload — for how the hue circle is traversed; omit it and the browser\n * defaults to `shorter`. A rectangular space has no hue channel, so passing a\n * strategy is a compile error, mirroring the grammar where\n * `<hue-interpolation-method>` follows only a polar space.\n *\n * Percentages are optional and preserved verbatim — fashionable emits the\n * authored form and never runs the spec's mixing normalization (omitted weights\n * defaulting to `50%`, weights off `100%` rescaling with an alpha multiplier),\n * which is computed-value behavior the browser owns. Like every `Color`, a mix\n * binds and serializes but does not solve, and each arm and each percentage\n * contributes its references to the result.\n *\n * @param space - The interpolation `ColorSpace`; a polar one may be followed by a `HueInterpolation`.\n * @param color1 - The first color, or a `[color, percentage]` tuple weighting it.\n * @param color2 - The second color, or a `[color, percentage]` tuple weighting it.\n * @returns A `Color` unioning both arms' and both percentages' references.\n * @example\n * ```ts\n * Color.serialize(Color.mix(ColorSpace.oklch, Color.named('red'), Color.named('blue')))\n * // 'color-mix(in oklch, red, blue)'\n * Color.serialize(Color.mix(ColorSpace.srgb, [Color.named('white'), 20], Color.named('black')))\n * // 'color-mix(in srgb, white 20%, black)'\n * Color.serialize(Color.mix(ColorSpace.oklch, HueInterpolation.longer, Color.named('red'), Color.named('blue')))\n * // 'color-mix(in oklch longer hue, red, blue)'\n * ```\n * @since 0.2.0\n */\nexport const mix: {\n <\n C1 extends string = never,\n P1 extends string = never,\n C2 extends string = never,\n P2 extends string = never,\n >(\n space: ColorSpace,\n color1: MixArm<C1, P1>,\n color2: MixArm<C2, P2>,\n ): Color<C1 | P1 | C2 | P2>\n <\n C1 extends string = never,\n P1 extends string = never,\n C2 extends string = never,\n P2 extends string = never,\n >(\n space: PolarSpace,\n hue: HueInterpolation,\n color1: MixArm<C1, P1>,\n color2: MixArm<C2, P2>,\n ): Color<C1 | P1 | C2 | P2>\n} = internal.mix\n\n/**\n * A channel slot of a relative color: a bare number, `Keyword.none`, or a\n * `Calc` number expression. `Channels` is the set of origin-channel keyword\n * brands (`Channel`) the expression may read — the space's own channels — so a\n * keyword from another color space (`Channel.R` in an `oklch` slot) is a\n * compile error. A plain expression (a constant, a `Calc.ref`, a `clamp`)\n * carries no channel keyword and fits any slot.\n *\n * @since 0.2.0\n */\nexport type RelativeChannel<Refs extends string, Channels> =\n | number\n | None\n | Calc<Refs, 'number', Channels>\n\n// The channel-keyword brands a `ColorSpace` admits, extracted for scoping.\ntype ChannelsOf<Space> = Space extends ColorSpace<infer Channels> ? Channels : never\n\n/**\n * Creates a relative color from an origin and a destination `ColorSpace`:\n * `Color.from(origin, ColorSpace.oklch, l, c, h)` is `oklch(from origin l c h)`\n * and `Color.from(origin, ColorSpace.srgb, r, g, b)` is\n * `color(from origin srgb r g b)`. The browser converts `origin` into the\n * space and exposes its channels as the `Channel` keywords the space names\n * (`Channel.L`/`C`/`H` for `oklch`, `Channel.R`/`G`/`B` for `srgb`, `Channel.Alpha`\n * for both); passing them straight through reproduces the origin, and\n * arithmetic on them derives a related color.\n *\n * The `space` scopes the channel arguments — a keyword the space does not name\n * is a compile error. Each channel serializes independently, wrapped in\n * `calc()` when arithmetic and bare when a lone keyword, and may be\n * `Keyword.none`. A supplied `alpha` renders after a slash\n * (`/ calc(alpha * 0.5)`); omitted, the origin's alpha carries through. The\n * origin's own references union into the result; the channel keywords\n * contribute none, since the browser resolves them from the origin.\n *\n * @param origin - The color to derive from — any `Color`, commonly a `ref`.\n * @param space - The destination `ColorSpace`, fixing the function form and the channels in scope.\n * @param channel1 - The first channel (`l`/`r`), in the space's order.\n * @param channel2 - The second channel (`c`/`g`).\n * @param channel3 - The third channel (`h`/`b`).\n * @param alpha - The optional alpha channel; omitted, the origin's alpha is kept.\n * @returns A `Color` unioning the origin's and the channels' references.\n * @example\n * ```ts\n * const hover = Color.from(Color.ref('accent'), ColorSpace.oklch, Calc.multiply(Channel.L, 0.8), Channel.C, Channel.H)\n * Color.serialize(hover) // 'oklch(from var(--accent) calc(l * 0.8) c h)'\n * const faded = Color.from(Color.ref('brand'), ColorSpace.srgb, Channel.R, Channel.G, Channel.B, Calc.multiply(Channel.Alpha, 0.5))\n * Color.serialize(faded) // 'color(from var(--brand) srgb r g b / calc(alpha * 0.5))'\n * ```\n * @since 0.2.0\n */\nexport const from: <\n O extends string = never,\n Space extends ColorSpace = ColorSpace,\n C1 extends string = never,\n C2 extends string = never,\n C3 extends string = never,\n A extends string = never,\n>(\n origin: Color<O>,\n space: Space,\n channel1: RelativeChannel<C1, ChannelsOf<Space>>,\n channel2: RelativeChannel<C2, ChannelsOf<Space>>,\n channel3: RelativeChannel<C3, ChannelsOf<Space>>,\n alpha?: RelativeChannel<A, ChannelsOf<Space>>,\n) => Color<O | C1 | C2 | C3 | A> = internal.from\n\nexport const bind: {\n /**\n * Returns a function that binds the given names in a color's channels.\n *\n * @param bindings - Reference names to values or expressions.\n * @returns A function replacing bound references in its argument.\n * @since 0.1.0\n */\n <const B extends Bindings>(\n bindings: B,\n ): <Refs extends string>(color: Color<Refs>) => Color<ApplyBindings<Refs, B>>\n /**\n * Replaces references in the color's channels with values or other\n * expressions, re-folding constant subtrees. Semantics match\n * `Calc.bind`: unreferenced names and `undefined` values are ignored,\n * and expression-valued bindings contribute their own references.\n *\n * @param color - The color to bind.\n * @param bindings - Reference names to values or expressions.\n * @returns The bound color.\n * @since 0.1.0\n */\n <Refs extends string, const B extends Bindings>(\n color: Color<Refs>,\n bindings: B,\n ): Color<ApplyBindings<Refs, B>>\n} = internal.bind\n\n/**\n * Renders a color as CSS text. Channels render space-separated inside\n * the color's own function form — `oklch(...)` or `color(srgb ...)` —\n * each wrapped in `calc()` when it is arithmetic; a `lightDark` renders\n * both arms in full, comma-separated.\n *\n * Options match `Calc.serialize`: partial bindings applied first, and a\n * precision context for unannotated constants.\n *\n * @param color - The color to render.\n * @param options - Optional bindings and precision context.\n * @returns Deterministic CSS text.\n * @example\n * ```ts\n * const surface = Color.oklch(Calc.add(Calc.ref('l'), 0.1), 0.04, 250)\n * Color.serialize(surface) // 'oklch(calc(var(--l) + 0.1) 0.04 250)'\n * ```\n * @since 0.1.0\n */\nexport const serialize: <Refs extends string>(\n color: Color<Refs>,\n options?: SerializeOptions<Refs>,\n) => string = internal.serialize\n\n/**\n * The color's unbound reference names, unioned across channels.\n *\n * @param color - The color to inspect.\n * @returns The set of unbound reference names.\n * @since 0.1.0\n */\nexport const refs: <Refs extends string>(color: Color<Refs>) => ReadonlySet<Refs> = internal.refs\n\n/**\n * The origin-channel keyword tokens the color reads — the `Channel` keywords a\n * relative color's channels reference (`l`, `c`, `h`, ...), gathered across its\n * channels and any nested colors. Empty for a color with no relative parts.\n *\n * The `Color` companion to `Calc.channels`, and the mirror of `refs`: where\n * `refs` reports the custom properties a color depends on, `channels` reports\n * the origin channels a relative color reads. They are disjoint — a channel\n * keyword is never a reference — so a channel token never appears in `refs` nor\n * reaches a `Stylesheet`'s dependency report.\n *\n * @param color - The color to inspect.\n * @returns The set of channel-keyword tokens the color reads.\n * @example\n * ```ts\n * const hover = Color.from(Color.ref('accent'), ColorSpace.oklch, Calc.multiply(Channel.L, 0.8), Channel.C, Channel.H)\n * Color.channels(hover) // Set { 'l', 'c', 'h' }\n * Color.refs(hover) // Set { 'accent' }\n * ```\n * @since 0.2.0\n */\nexport const channels: (color: Color<string>) => ReadonlySet<string> = internal.channels\n\nexport const equals: {\n /**\n * Returns a function that checks structural equality against `that`.\n *\n * @param that - The color to compare against.\n * @returns A function testing its argument for structural equality with `that`.\n * @since 0.1.0\n */\n (that: Color<string>): (self: Color<string>) => boolean\n /**\n * Structural equality over colors: channel trees compare node for node,\n * as in `Calc.equals`. Different color functions never compare equal,\n * even where they would name the same point in color space.\n *\n * @param self - The first color.\n * @param that - The second color.\n * @returns `true` if the colors are structurally equal.\n * @since 0.1.0\n */\n (self: Color<string>, that: Color<string>): boolean\n} = internal.equals\n","/**\n * A CSS color space, as a nominal value. Two consumers share the vocabulary:\n * `Color.from` derives a relative color *in* the space (its channels and\n * serialized function form), and `Color.mix` interpolates *in* the space (the\n * `in <space>` of `color-mix()`). `ColorSpace.oklch` serves both — an\n * `oklch(from ...)` destination and a polar interpolation space.\n *\n * Capabilities are carried as type-level **traits** (the curvy pattern): a\n * space's `Trait` parameter accumulates the brands it satisfies, and a position\n * requires a capability by naming its brand. `Polar` is the trait a space with\n * a hue channel carries (`oklch`, `lch`, `hsl`, `hwb`), and `Color.mix` requires\n * it to accept a `HueInterpolation`; rectangular spaces simply lack it. The\n * `Channels` parameter is the payload `Color.from` scopes on — the `Channel`\n * keywords valid in the space. Only `oklch` and `srgb` name their channels\n * today; the rest are interpolation-only until a consumer needs their `from`\n * channels.\n *\n * @since 0.2.0\n */\n\nimport type { ColorSpaceTraits, ColorSpaceTypeId } from './colorSpace.internal.ts'\nimport * as internal from './colorSpace.internal.ts'\nimport type { ChannelLeaf } from './units.ts'\n\ndeclare const ColorSpaceChannels: unique symbol\ndeclare const PolarId: unique symbol\n\n/**\n * The trait a polar color space carries — one with a hue channel. `Color.mix`\n * requires it to take a `HueInterpolation`, and `PolarSpace` is the space type\n * that has it. Composes by intersection with future space traits, as curvy's\n * brands do.\n *\n * @since 0.2.0\n */\nexport type Polar = { readonly [PolarId]: 'polar' }\n\n/**\n * A color space. `Channels` carries the origin-channel keyword brands\n * (`Channel`) valid for `Color.from`; `Trait` accumulates the space's\n * capability brands (`Polar`), defaulting to `unknown` — a space with no\n * capability claims. A position requires a capability by naming its brand in\n * `Trait` (`ColorSpace<Channels, Polar>`).\n *\n * @since 0.2.0\n */\nexport interface ColorSpace<out Channels = ChannelLeaf<string>, out Trait = unknown> {\n readonly [ColorSpaceTypeId]: ColorSpaceTypeId\n readonly [ColorSpaceChannels]?: Channels\n readonly [ColorSpaceTraits]?: Trait\n}\n\n/**\n * A polar color space — one carrying the `Polar` trait, so `Color.mix` may take\n * a `HueInterpolation` after it.\n *\n * @since 0.2.0\n */\nexport type PolarSpace<Channels = ChannelLeaf<string>> = ColorSpace<Channels, Polar>\n\n/**\n * The `oklch` space: a polar interpolation space, and an `oklch(from ...)`\n * destination with `Channel.L`/`C`/`H` (and `Alpha`) in scope.\n *\n * @since 0.2.0\n */\nexport const oklch: ColorSpace<\n ChannelLeaf<'l'> | ChannelLeaf<'c'> | ChannelLeaf<'h'> | ChannelLeaf<'alpha'>,\n Polar\n> = internal.oklch\n\n/**\n * The `srgb` space: a rectangular interpolation space, and a\n * `color(from ... srgb ...)` destination with `Channel.R`/`G`/`B` (and `Alpha`)\n * in scope.\n *\n * @since 0.2.0\n */\nexport const srgb: ColorSpace<\n ChannelLeaf<'r'> | ChannelLeaf<'g'> | ChannelLeaf<'b'> | ChannelLeaf<'alpha'>\n> = internal.srgb\n\n/**\n * The `srgb-linear` space (rectangular).\n *\n * @since 0.2.0\n */\nexport const srgbLinear: ColorSpace<never> = internal.srgbLinear\n\n/**\n * The `display-p3` space (rectangular).\n *\n * @since 0.2.0\n */\nexport const displayP3: ColorSpace<never> = internal.displayP3\n\n/**\n * The `a98-rgb` space (rectangular).\n *\n * @since 0.2.0\n */\nexport const a98Rgb: ColorSpace<never> = internal.a98Rgb\n\n/**\n * The `prophoto-rgb` space (rectangular).\n *\n * @since 0.2.0\n */\nexport const prophotoRgb: ColorSpace<never> = internal.prophotoRgb\n\n/**\n * The `rec2020` space (rectangular).\n *\n * @since 0.2.0\n */\nexport const rec2020: ColorSpace<never> = internal.rec2020\n\n/**\n * The `lab` space (rectangular).\n *\n * @since 0.2.0\n */\nexport const lab: ColorSpace<never> = internal.lab\n\n/**\n * The `oklab` space (rectangular).\n *\n * @since 0.2.0\n */\nexport const oklab: ColorSpace<never> = internal.oklab\n\n/**\n * The `xyz` space (rectangular; an alias for `xyz-d65`).\n *\n * @since 0.2.0\n */\nexport const xyz: ColorSpace<never> = internal.xyz\n\n/**\n * The `xyz-d50` space (rectangular).\n *\n * @since 0.2.0\n */\nexport const xyzD50: ColorSpace<never> = internal.xyzD50\n\n/**\n * The `xyz-d65` space (rectangular).\n *\n * @since 0.2.0\n */\nexport const xyzD65: ColorSpace<never> = internal.xyzD65\n\n/**\n * The `hsl` space (polar).\n *\n * @since 0.2.0\n */\nexport const hsl: ColorSpace<never, Polar> = internal.hsl\n\n/**\n * The `hwb` space (polar).\n *\n * @since 0.2.0\n */\nexport const hwb: ColorSpace<never, Polar> = internal.hwb\n\n/**\n * The `lch` space (polar).\n *\n * @since 0.2.0\n */\nexport const lch: ColorSpace<never, Polar> = internal.lch\n","/**\n * How a polar `color-mix()` traverses the hue circle between its two colors —\n * the argument that follows a polar `ColorSpace` in `Color.mix`. `shorter` and\n * `longer` take the short or long arc between the hues; `increasing` and\n * `decreasing` force the direction of travel. Serialized before the literal\n * `hue` keyword, as CSS spells it: `in oklch longer hue`.\n *\n * A polar space in `Color.mix` may be given without one — the browser defaults\n * to `shorter` — so these are the explicit override.\n *\n * @since 0.2.0\n */\n\nimport type { Calc, Input } from '#calc/calc'\nimport type { HueInterpolationTypeId } from './hueInterpolation.internal.ts'\nimport * as internal from './hueInterpolation.internal.ts'\n\ndeclare const HueInterpolationStrategy: unique symbol\n\n/**\n * A hue-interpolation strategy. The `Strategy` parameter names the specific\n * one (`'longer'`), letting a position accept a particular strategy where it\n * matters; `Color.mix` accepts any.\n *\n * @since 0.2.0\n */\nexport interface HueInterpolation<Strategy extends string = string> {\n readonly [HueInterpolationTypeId]: HueInterpolationTypeId\n readonly [HueInterpolationStrategy]?: Strategy\n}\n\n/**\n * The `shorter` strategy — the short arc between the two hues (the browser\n * default). Serializes as `shorter hue`.\n *\n * @since 0.2.0\n */\nexport const shorter: HueInterpolation<'shorter'> = internal.shorter\n\n/**\n * The `longer` strategy — the long arc between the two hues. Serializes as\n * `longer hue`.\n *\n * @since 0.2.0\n */\nexport const longer: HueInterpolation<'longer'> = internal.longer\n\n/**\n * The `increasing` strategy — hues traversed in increasing order, wrapping past\n * `360` if needed. Serializes as `increasing hue`.\n *\n * @since 0.2.0\n */\nexport const increasing: HueInterpolation<'increasing'> = internal.increasing\n\n/**\n * The `decreasing` strategy — hues traversed in decreasing order, wrapping past\n * `0` if needed. Serializes as `decreasing hue`.\n *\n * @since 0.2.0\n */\nexport const decreasing: HueInterpolation<'decreasing'> = internal.decreasing\n\n/**\n * Builds the hue at `t` along the arc from `from` to `to` under `strategy` — the\n * JS side of what a polar `Color.mix` emits for the browser. Hues are numbers of\n * degrees (as an oklch/lch hue channel is), and `from`, `to`, and `t` are each a\n * number or a `Calc`, so the result is a `Calc` too: fully symbolic when any\n * argument is, folding to a constant when all are numbers.\n *\n * The hue math is the CSS Color 4 fixup, written branchlessly with `mod`: each\n * strategy is a signed delta added to `from` as `t` runs `0` (at `from`) to `1`\n * (at `to`). `shorter` and `longer` take the short or long arc between the hues;\n * `increasing`/`decreasing` force the direction. The result is unwrapped — it may\n * fall outside `[0, 360)`, which the browser resolves as a hue — and unions the\n * arguments' references. Drop it straight into a hue channel (`Color.oklch`).\n *\n * @param strategy - The traversal strategy (`shorter`, `longer`, ...).\n * @param from - The start hue, in degrees: a number or a `Calc`.\n * @param to - The end hue, in degrees: a number or a `Calc`.\n * @param t - The interpolation parameter, `0` to `1`: a number or a `Calc`.\n * @returns The interpolated hue in degrees, a `Calc` unioning the arguments' references.\n * @example\n * ```ts\n * const hue = HueInterpolation.interpolate(HueInterpolation.shorter, 30, Calc.ref('to'), Calc.ref('t'))\n * Calc.serialize(hue) // 'calc(30 + (mod(var(--to) - 30 + 180, 360) - 180) * var(--t))'\n * Calc.serialize(HueInterpolation.interpolate(HueInterpolation.increasing, 20, 350, 0.5)) // '185'\n * ```\n * @since 0.2.0\n */\nexport const interpolate: <\n F extends string = never,\n T extends string = never,\n P extends string = never,\n>(\n strategy: HueInterpolation,\n from: Input<F>,\n to: Input<T>,\n t: Input<P>,\n) => Calc<F | T | P> = internal.interpolate\n","/**\n * Value-position keywords. CSS reuses a small set of keywords inside\n * otherwise-typed value slots; the constants here give those slots a\n * branded value to accept — a position that takes one declares it in\n * its signature, so keyword acceptance is explicit per position rather\n * than ambient.\n *\n * Only `none` is modeled today; siblings arrive as consumers need them.\n *\n * @since 0.2.0\n */\n\nimport type { Pipeable } from '#util'\nimport type { NoneTypeId } from './keywords.internal.ts'\nimport * as internal from './keywords.internal.ts'\n\n/**\n * The type of `none` alone. Naming it lets accepting positions spell\n * their signatures (`Input<R> | Keyword.None`) and overloads recognize\n * the keyword.\n *\n * @since 0.2.0\n */\nexport interface None extends Pipeable {\n readonly [NoneTypeId]: NoneTypeId\n}\n\n/**\n * The `none` keyword — CSS's missing-component value. Accepted where a\n * position declares it: color channels today (`oklch(0 0 none)`), other\n * slots as they arrive.\n *\n * @since 0.2.0\n */\nexport const none: None = internal.none\n\n/**\n * Checks if a value is the `none` keyword.\n *\n * True only for `none` itself, which carries the brand.\n *\n * @param u - The value to check.\n * @returns `true` if the value is `none`, `false` otherwise.\n * @since 0.2.0\n */\nexport const isNone: (u: unknown) => u is None = internal.isNone\n","import type { Calc } from '#calc/calc'\nimport { dimension } from '#calc/calc.internal'\nimport type { Precision } from '#calc/precision'\nimport type { Em, Px, Rem, Vh, Vmax, Vmin, Vw } from './units.ts'\n\n/** @internal */\nexport const px = (value: number, precision?: Precision): Calc<never, 'length', Px> =>\n dimension(value, 'px', 'length', precision)\n\n/** @internal */\nexport const rem = (value: number, precision?: Precision): Calc<never, 'length', Rem> =>\n dimension(value, 'rem', 'length', precision)\n\n/** @internal */\nexport const em = (value: number, precision?: Precision): Calc<never, 'length', Em> =>\n dimension(value, 'em', 'length', precision)\n\n/** @internal */\nexport const vw = (value: number, precision?: Precision): Calc<never, 'length', Vw> =>\n dimension(value, 'vw', 'length', precision)\n\n/** @internal */\nexport const vh = (value: number, precision?: Precision): Calc<never, 'length', Vh> =>\n dimension(value, 'vh', 'length', precision)\n\n/** @internal */\nexport const vmin = (value: number, precision?: Precision): Calc<never, 'length', Vmin> =>\n dimension(value, 'vmin', 'length', precision)\n\n/** @internal */\nexport const vmax = (value: number, precision?: Precision): Calc<never, 'length', Vmax> =>\n dimension(value, 'vmax', 'length', precision)\n","/**\n * `<length>` constructors. Each builds a dimensioned `Calc` constant — a\n * `<length>`-kind expression carrying its unit brand — that composes through\n * the `Calc` combinators: `Calc.add(Length.px(16), Length.vw(2))` is a\n * `<length>`, `Calc.divide` of two lengths is a `<number>`, and adding a length\n * to a plain number is a type error.\n *\n * Values pass through unrounded; the optional `Precision` pins serialization\n * exactly as `Calc.of` does. The unit is applied structurally, so it survives\n * `refs`, structural equality, and folding — no string assembly.\n *\n * @since 0.2.0\n */\n\nimport type { Calc } from '#calc/calc'\nimport type { Precision } from '#calc/precision'\nimport * as internal from './length.internal.ts'\nimport type { Em, Length as LengthUnit, Px, Rem, Vh, Vmax, Vmin, Vw } from './units.ts'\n\n/**\n * A `<length>` expression: a `Calc` of length kind, in any length unit. Names\n * the dimension without spelling `Calc<Refs, 'length', Unit.Length>` —\n * `Length.px(16)` produces one, and it composes with every `Calc` combinator\n * (adding two lengths is a length, dividing one by another is a number). `Refs`\n * unions the unbound reference names, as on `Calc`.\n *\n * The leaf is the widened `Unit.Length`, so a mixed-unit sum\n * (`Calc.add(Length.px(16), Length.vw(2))`) and every single-unit length are\n * alike assignable to it.\n *\n * @since 0.2.0\n */\nexport type Length<Refs extends string = string> = Calc<Refs, 'length', LengthUnit>\n\n/**\n * A length in `px` (absolute pixels).\n *\n * @param value - The pixel count.\n * @param precision - Optional serialization precision.\n * @returns A `px` length expression.\n * @example\n * ```ts\n * Calc.serialize(Length.px(16)) // '16px'\n * ```\n * @since 0.2.0\n */\nexport const px: (value: number, precision?: Precision) => Calc<never, 'length', Px> = internal.px\n\n/**\n * A length in `rem` (relative to the root font size).\n *\n * @param value - The multiple of the root font size.\n * @param precision - Optional serialization precision.\n * @returns A `rem` length expression.\n * @since 0.2.0\n */\nexport const rem: (value: number, precision?: Precision) => Calc<never, 'length', Rem> =\n internal.rem\n\n/**\n * A length in `em` (relative to the element font size).\n *\n * @param value - The multiple of the element font size.\n * @param precision - Optional serialization precision.\n * @returns An `em` length expression.\n * @since 0.2.0\n */\nexport const em: (value: number, precision?: Precision) => Calc<never, 'length', Em> = internal.em\n\n/**\n * A length in `vw` (1% of the viewport width).\n *\n * @param value - The percentage of viewport width.\n * @param precision - Optional serialization precision.\n * @returns A `vw` length expression.\n * @since 0.2.0\n */\nexport const vw: (value: number, precision?: Precision) => Calc<never, 'length', Vw> = internal.vw\n\n/**\n * A length in `vh` (1% of the viewport height).\n *\n * @param value - The percentage of viewport height.\n * @param precision - Optional serialization precision.\n * @returns A `vh` length expression.\n * @since 0.2.0\n */\nexport const vh: (value: number, precision?: Precision) => Calc<never, 'length', Vh> = internal.vh\n\n/**\n * A length in `vmin` (1% of the smaller viewport axis).\n *\n * @param value - The percentage of the smaller viewport axis.\n * @param precision - Optional serialization precision.\n * @returns A `vmin` length expression.\n * @since 0.2.0\n */\nexport const vmin: (value: number, precision?: Precision) => Calc<never, 'length', Vmin> =\n internal.vmin\n\n/**\n * A length in `vmax` (1% of the larger viewport axis).\n *\n * @param value - The percentage of the larger viewport axis.\n * @param precision - Optional serialization precision.\n * @returns A `vmax` length expression.\n * @since 0.2.0\n */\nexport const vmax: (value: number, precision?: Precision) => Calc<never, 'length', Vmax> =\n internal.vmax\n","/**\n * The `<percentage>` constructor. A percentage-kind expression composes with the\n * `Calc` combinators like any other dimension — `Calc.add` of two percentages is\n * a percentage, scaling one by a number stays a percentage, and one percentage\n * over another cancels to a `<number>` — while adding a bare number to a\n * percentage is a type error, so a raw `50` never slips into a percentage slot\n * as `50%` by accident.\n *\n * There is one unit (`%`), so the module is a single `of` constructor rather\n * than a family. A percentage binds and serializes but does not `solve`: its\n * only consumer today is `Color.mix`, which serializes rather than solves, so\n * the `%` leaf carries no `solve`-context ratio. (Nothing in the model needs to\n * know what a `50%` is a percentage *of* — that would only ever be a context\n * ratio supplied at `solve`, the same leaf lowering a viewport unit uses.)\n *\n * @since 0.2.0\n */\n\nimport type { Calc } from '#calc/calc'\nimport type { Precision } from '#calc/precision'\nimport * as internal from './percentage.internal.ts'\nimport type { Percent, Percentage as PercentageUnit } from './units.ts'\n\n/**\n * A `<percentage>` expression: a `Calc` of percentage kind. Names the dimension\n * without spelling `Calc<Refs, 'percentage', Unit.Percentage>` —\n * `Percentage.of(40)` produces one, and it composes with every `Calc`\n * combinator (adding two percentages is a percentage, one over another is a\n * number). `Refs` unions the unbound reference names, as on `Calc`.\n *\n * @since 0.2.0\n */\nexport type Percentage<Refs extends string = string> = Calc<Refs, 'percentage', PercentageUnit>\n\n/**\n * A percentage — a number rendered with a trailing `%`. `Percentage.of(40)`\n * serializes as `40%`. The value passes through unrounded; the optional\n * `Precision` pins serialization exactly as `Calc.of` does.\n *\n * @param value - The percentage magnitude (`40` for `40%`, not `0.4`).\n * @param precision - Optional serialization precision.\n * @returns A `<percentage>` expression.\n * @example\n * ```ts\n * Calc.serialize(Percentage.of(40)) // '40%'\n * Calc.serialize(Calc.add(Percentage.of(20), Percentage.of(5))) // '25%'\n * ```\n * @since 0.2.0\n */\nexport const of: (value: number, precision?: Precision) => Calc<never, 'percentage', Percent> =\n internal.of\n","/**\n * The unit vocabulary: the leaf-provenance brands threaded through `Calc`'s\n * third type parameter. Each unit is a distinct nominal type carrying its CSS\n * token, keyed by a per-dimension `unique symbol` so a length unit and an angle\n * unit never unify — that nominal split is what lets `solve` demand a context\n * for viewport-relative units while leaving absolute ones alone.\n *\n * You rarely name a unit type directly — `Length.px(10)` and `Angle.rad(2)`\n * stamp them — but they surface in `Calc<Refs, Kind, Leaves>` hovers as the set\n * of units an expression contains (`Calc<never, 'number', Unit.Vw | Unit.Px>`).\n *\n * Not every leaf provenance is a unit: a relative-color channel keyword\n * (`ChannelLeaf`) rides the same third parameter, so `solve` can demand a value\n * for it the way it demands a ratio for a viewport unit.\n *\n * @since 0.2.0\n */\n\ndeclare const LengthUnitId: unique symbol\ndeclare const AngleUnitId: unique symbol\ndeclare const PercentageUnitId: unique symbol\ndeclare const ChannelId: unique symbol\n\n/**\n * The `px` unit (absolute length).\n *\n * @since 0.2.0\n */\nexport interface Px {\n readonly [LengthUnitId]: 'px'\n}\n\n/**\n * The `rem` unit (length relative to the root font size).\n *\n * @since 0.2.0\n */\nexport interface Rem {\n readonly [LengthUnitId]: 'rem'\n}\n\n/**\n * The `em` unit (length relative to the element font size).\n *\n * @since 0.2.0\n */\nexport interface Em {\n readonly [LengthUnitId]: 'em'\n}\n\n/**\n * The `vw` unit (length relative to 1% of viewport width).\n *\n * @since 0.2.0\n */\nexport interface Vw {\n readonly [LengthUnitId]: 'vw'\n}\n\n/**\n * The `vh` unit (length relative to 1% of viewport height).\n *\n * @since 0.2.0\n */\nexport interface Vh {\n readonly [LengthUnitId]: 'vh'\n}\n\n/**\n * The `vmin` unit (length relative to 1% of the smaller viewport axis).\n *\n * @since 0.2.0\n */\nexport interface Vmin {\n readonly [LengthUnitId]: 'vmin'\n}\n\n/**\n * The `vmax` unit (length relative to 1% of the larger viewport axis).\n *\n * @since 0.2.0\n */\nexport interface Vmax {\n readonly [LengthUnitId]: 'vmax'\n}\n\n/**\n * The `rad` unit (angle in radians).\n *\n * @since 0.2.0\n */\nexport interface Rad {\n readonly [AngleUnitId]: 'rad'\n}\n\n/**\n * The `deg` unit (angle in degrees). Degrees lower to radians at solve\n * (`180deg` is `pi`), a fixed ratio, so like `rad` a degree needs no context.\n *\n * @since 0.2.0\n */\nexport interface Deg {\n readonly [AngleUnitId]: 'deg'\n}\n\n/**\n * The `%` unit (percentage). Keyed by its own dimension symbol, so a\n * percentage never unifies with a length or an angle — a `<percentage>`\n * is its own `Calc` kind, not a length that happens to be relative.\n *\n * @since 0.2.0\n */\nexport interface Percent {\n readonly [PercentageUnitId]: '%'\n}\n\n/**\n * A relative-color channel keyword (`Channel.L` -> `l`) as a leaf provenance\n * rather than a CSS unit. It carries the keyword name and is keyed by its own\n * `unique symbol`, so it never unifies with a unit; `solve` treats it like a\n * context-dependent unit, but demands a *value* for the keyword rather than a\n * pixels-per-unit ratio — there is no `value * ratio`, the keyword is itself the\n * value the browser reads from the origin. Surfaces in `Calc<Refs, Kind, Leaves>`\n * hovers as `Calc<never, 'number', Unit.ChannelLeaf<'l'>>`.\n *\n * @since 0.2.0\n */\nexport interface ChannelLeaf<Name extends string> {\n readonly [ChannelId]: Name\n}\n\n/**\n * Any `<length>` unit.\n *\n * @since 0.2.0\n */\nexport type Length = Px | Rem | Em | Vw | Vh | Vmin | Vmax\n\n/**\n * Any `<angle>` unit.\n *\n * @since 0.2.0\n */\nexport type Angle = Rad | Deg\n\n/**\n * Any `<percentage>` unit. There is only one (`%`); the alias exists for\n * symmetry with `Length` and `Angle`, so `Calc<never, 'percentage', Unit.Percentage>`\n * reads uniformly.\n *\n * @since 0.2.0\n */\nexport type Percentage = Percent\n\n/**\n * The context-dependent length units — those whose pixel ratio depends on the\n * viewport or a font size, so `solve` requires a `UnitContext` entry for each.\n *\n * @since 0.2.0\n */\nexport type Relative = Rem | Em | Vw | Vh | Vmin | Vmax\n\n/**\n * The absolute length units, whose pixel ratio is fixed (`px` is `1`). A\n * `UnitContext` may override them but need not supply them.\n *\n * @since 0.2.0\n */\nexport type AbsoluteLength = Px\n\n/**\n * The units an expression may carry and still `solve` with no context: absolute\n * lengths (fixed ratio) and angles (radians are already numbers).\n *\n * @since 0.2.0\n */\nexport type ContextFree = AbsoluteLength | Angle\n\n/**\n * The CSS token of a unit brand (`Unit.Px` -> `'px'`), used to key the solve\n * context and to render the unit suffix.\n *\n * @since 0.2.0\n */\nexport type Token<U> = U extends { readonly [LengthUnitId]: infer T }\n ? T\n : U extends { readonly [AngleUnitId]: infer T }\n ? T\n : U extends { readonly [PercentageUnitId]: infer T }\n ? T\n : U extends { readonly [ChannelId]: infer T }\n ? T\n : never\n\n/**\n * The context `Calc.solve` requires to lower an expression carrying the units\n * `L` to a number. Each context-dependent (relative) unit present is a required\n * `number` ratio — pixels per unit, as `sampleWidth / 100` is per `vw` — while\n * absolute lengths (`px`) are optional overrides and angle units never appear\n * (radians are already numeric). Each relative-color channel keyword present is\n * a required `number` too, but the value itself, not a ratio (`{ l: 0.62 }`),\n * keyed by the keyword token. An expression whose leaves are all context-free\n * needs no context at all.\n *\n * @since 0.2.0\n */\nexport type UnitContext<L> = {\n readonly [K in Token<Extract<L, Relative>> & string]: number\n} & {\n readonly [K in Token<Extract<L, ChannelLeaf<string>>> & string]: number\n} & {\n readonly [K in Token<Extract<L, AbsoluteLength>> & string]?: number\n}\n"],"mappings":";;;;;AAMA,MAAaA,SAAO,OAAe,cACjC,UAAU,OAAO,OAAO,SAAS,SAAS;;AAG5C,MAAaC,SAAO,OAAe,cACjC,UAAU,OAAO,OAAO,SAAS,SAAS;;;;;;;;;;;;;;;;;;;;ACkC5C,MAAa,MAA2EC;;;;;;;;;;;;;;AAexF,MAAa,MAA2EC;;;;ACxDxF,MAAaC,MAAiB,MAAM,GAAG;;AAGvC,MAAaC,MAAiB,MAAM,GAAG;;AAGvC,MAAaC,MAAiB,MAAM,GAAG;;AAGvC,MAAaC,MAAiB,MAAM,GAAG;;AAGvC,MAAaC,MAAiB,MAAM,GAAG;;AAGvC,MAAaC,MAAiB,MAAM,GAAG;;AAGvC,MAAaC,UAAqB,MAAM,OAAO;;;;;;;;;;;;;;;;;ACW/C,MAAa,IAA6CC;;;;;;AAO1D,MAAa,IAA6CC;;;;;;AAO1D,MAAa,IAA6CC;;;;;;AAO1D,MAAa,IAA6CC;;;;;;AAO1D,MAAa,IAA6CC;;;;;;AAO1D,MAAa,IAA6CC;;;;;;;AAQ1D,MAAa,QAAqDC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACjClE,MAAa,UAA8CC;;;;;;;;;;;;;;;;;;;;;AAsB3D,MAAaC,UAIWC;;;;;;;;;;;;;;;;;;;;;AAsBxB,MAAaC,SAIWC;;;;;;;;;;;;;;;;;AAkBxB,MAAa,QAAwCC;;;;;;;AAQrD,MAAa,cAA4BC;;;;;;;;;;;;;;;;;;;;;AAsBzC,MAAa,MAAwDC;;;;;;;;;;;;;;;;;;;;;;AAuBrE,MAAa,YAGOC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8CpB,MAAa,MAsBTC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAsDJ,MAAa,OAcsBC;AAEnC,MAAa,OA0BTC;;;;;;;;;;;;;;;;;;;;AAqBJ,MAAa,YAGCC;;;;;;;;AASd,MAAa,OAAuEC;;;;;;;;;;;;;;;;;;;;;;AAuBpF,MAAa,WAA0DC;AAEvE,MAAa,SAoBTC;;;;;;;;;;;;;;;;;;;;;;;;;;ACzVJ,MAAa,QAGTC;;;;;;;;AASJ,MAAa,OAETC;;;;;;AAOJ,MAAa,aAAgCC;;;;;;AAO7C,MAAa,YAA+BC;;;;;;AAO5C,MAAa,SAA4BC;;;;;;AAOzC,MAAa,cAAiCC;;;;;;AAO9C,MAAa,UAA6BC;;;;;;AAO1C,MAAa,MAAyBC;;;;;;AAOtC,MAAa,QAA2BC;;;;;;AAOxC,MAAa,MAAyBC;;;;;;AAOtC,MAAa,SAA4BC;;;;;;AAOzC,MAAa,SAA4BC;;;;;;AAOzC,MAAa,MAAgCC;;;;;;AAO7C,MAAa,MAAgCC;;;;;;AAO7C,MAAa,MAAgCC;;;;;;;;;;;;;;;;ACtI7C,MAAa,UAAuCC;;;;;;;AAQpD,MAAa,SAAqCC;;;;;;;AAQlD,MAAa,aAA6CC;;;;;;;AAQ1D,MAAa,aAA6CC;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6B1D,MAAa,cASUC;;;;;;;;;;;;;;ACjEvB,MAAa,OAAaC;;;;;;;;;;AAW1B,MAAa,SAAoCC;;;;ACvCjD,MAAaC,QAAM,OAAe,cAChC,UAAU,OAAO,MAAM,UAAU,SAAS;;AAG5C,MAAaC,SAAO,OAAe,cACjC,UAAU,OAAO,OAAO,UAAU,SAAS;;AAG7C,MAAaC,QAAM,OAAe,cAChC,UAAU,OAAO,MAAM,UAAU,SAAS;;AAG5C,MAAaC,QAAM,OAAe,cAChC,UAAU,OAAO,MAAM,UAAU,SAAS;;AAG5C,MAAaC,QAAM,OAAe,cAChC,UAAU,OAAO,MAAM,UAAU,SAAS;;AAG5C,MAAaC,UAAQ,OAAe,cAClC,UAAU,OAAO,QAAQ,UAAU,SAAS;;AAG9C,MAAaC,UAAQ,OAAe,cAClC,UAAU,OAAO,QAAQ,UAAU,SAAS;;;;;;;;;;;;;;;;;;;;;;;;ACe9C,MAAa,KAA0EC;;;;;;;;;AAUvF,MAAa,MACXC;;;;;;;;;AAUF,MAAa,KAA0EC;;;;;;;;;AAUvF,MAAa,KAA0EC;;;;;;;;;AAUvF,MAAa,KAA0EC;;;;;;;;;AAUvF,MAAa,OACXC;;;;;;;;;AAUF,MAAa,OACXC;;;;;;;;;;;;;;;;;;;AC5DF,MAAa,KACXC"}
@@ -0,0 +1,2 @@
1
+ import { r as declaration_d_exports } from "../shared/declaration-1DlO_ltT.mjs";
2
+ export { declaration_d_exports as Declaration };
@@ -1,5 +1,5 @@
1
- import { c as __exportAll } from "../shared/equal-C96LR7p4.mjs";
2
- import { a as refs$1, i as make$1, n as equals$1, r as isDeclaration$1, s as render$1, t as bind$1 } from "../shared/declaration.internal-DvZknsDc.mjs";
1
+ import { t as __exportAll } from "../shared/rolldown-runtime-D7D4PA-g.mjs";
2
+ import { a as refs$1, i as make$1, n as equals$1, r as isDeclaration$1, s as render$1, t as bind$1 } from "../shared/declaration.internal-wLB4ssxC.mjs";
3
3
  //#region src/declaration/declaration.ts
4
4
  var declaration_exports = /* @__PURE__ */ __exportAll({
5
5
  bind: () => bind,
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":["internal.isDeclaration","internal.make","internal.bind","internal.refs","internal.render","internal.equals"],"sources":["../../src/declaration/declaration.ts"],"sourcesContent":["import type { ApplyBindings, Bindings, Calc } from '#calc/calc'\nimport type { Precision } from '#calc/precision'\nimport type { Color } from '#color/color'\nimport type { RenderOptions as MediaQueryRenderOptions } from '#query/mediaQuery'\nimport type { Pipeable } from '#util'\nimport type { DeclarationTypeId } from './declaration.internal.ts'\nimport * as internal from './declaration.internal.ts'\n\n/**\n * A CSS declaration: a property name paired with a value.\n *\n * This is the seam where the library's two halves meet — the value is\n * either literal CSS text, passed through verbatim, or a value-layer\n * expression (`Calc` or `Color`) serialized when the declaration renders.\n * Expression values stay number-land: units are applied by the consumer,\n * in text or at the property's `@property` syntax.\n *\n * The `Refs` parameter carries the value's unbound reference names, as on\n * `Calc`; literal text binds nothing and a text-valued declaration is a\n * `Declaration<never>`.\n *\n * Construct via `make`.\n *\n * @since 0.1.0\n */\nexport interface Declaration<out Refs extends string = string> extends Pipeable {\n readonly [DeclarationTypeId]: DeclarationTypeId\n /**\n * The property name, exactly as it renders — `font-size`, or `--depth`\n * for a custom property.\n */\n readonly name: string\n /**\n * The declaration's value: literal CSS text or a value-layer expression.\n */\n readonly value: Value<Refs>\n}\n\n/**\n * The value forms a declaration can hold: literal CSS text, a `Calc`\n * number expression, or a `Color` expression.\n *\n * @since 0.1.0\n */\nexport type Value<Refs extends string = string> = string | Calc<Refs> | Color<Refs>\n\n/**\n * Checks if a value is a `Declaration`.\n *\n * True only for values built by this module's constructors, which carry\n * the brand.\n *\n * @param u - The value to check.\n * @returns `true` if the value is a `Declaration`, `false` otherwise.\n * @since 0.1.0\n */\nexport const isDeclaration: (u: unknown) => u is Declaration<string> = internal.isDeclaration\n\n/**\n * Creates a declaration.\n *\n * Literal text is stored verbatim — no parsing, no escaping. A bare\n * number is coerced to an unannotated constant expression, as anywhere\n * else an expression is accepted, so it serializes under the precision\n * context rather than as raw text.\n *\n * @param name - The property name, exactly as it renders (`--x` keeps its dashes). Must be non-empty.\n * @param value - Literal CSS text, a number, or a `Calc`/`Color` expression.\n * @returns A `Declaration` carrying the value's reference names — `Declaration<never>` for text and numbers.\n * @throws `Error` when `name` is empty, or `value` is a non-finite number.\n * @example\n * ```ts\n * Declaration.make('color', 'red')\n * Declaration.make('--fluid', Calc.add(14, Calc.multiply(Calc.ref('vw'), 0.01)))\n * ```\n * @since 0.1.0\n */\nexport const make: <Refs extends string = never>(\n name: string,\n value: Value<Refs> | number,\n) => Declaration<Refs> = internal.make\n\nexport const bind: {\n /**\n * Returns a function that binds the given names in a declaration's\n * value.\n *\n * @param bindings - Reference names to values or expressions.\n * @returns A function replacing bound references in its argument's value.\n * @since 0.1.0\n */\n <const B extends Bindings>(\n bindings: B,\n ): <Refs extends string>(declaration: Declaration<Refs>) => Declaration<ApplyBindings<Refs, B>>\n /**\n * Replaces references in the declaration's value with values or other\n * expressions, re-folding constant subtrees. Semantics match\n * `Calc.bind`: unreferenced names and `undefined` values are ignored,\n * and expression-valued bindings contribute their own references. A\n * literal-text value binds nothing; the declaration is returned as-is.\n *\n * @param declaration - The declaration to bind.\n * @param bindings - Reference names to values or expressions.\n * @returns The bound declaration.\n * @since 0.1.0\n */\n <Refs extends string, const B extends Bindings>(\n declaration: Declaration<Refs>,\n bindings: B,\n ): Declaration<ApplyBindings<Refs, B>>\n} = internal.bind\n\n/**\n * The declaration's unbound reference names — empty for literal text,\n * the value's references otherwise.\n *\n * @param declaration - The declaration to inspect.\n * @returns The set of unbound reference names.\n * @since 0.1.0\n */\nexport const refs: <Refs extends string>(declaration: Declaration<Refs>) => ReadonlySet<Refs> =\n internal.refs\n\n/**\n * Options for `render`, extending `MediaQuery.RenderOptions` — the\n * render-options family's base — with the precision context.\n *\n * @since 0.1.0\n */\nexport interface RenderOptions extends MediaQueryRenderOptions {\n /**\n * The precision for expression constants that carry no annotation of\n * their own. Defaults to `Precision.decimals(5)`, as in\n * `Calc.serialize`.\n */\n readonly precision?: Precision\n}\n\n/**\n * Renders the declaration as one CSS declaration, semicolon included:\n * `name: value;`. Literal text passes through verbatim; expression\n * values serialize as `Calc.serialize`/`Color.serialize` would, with\n * unbound references rendering as `var(--name)`.\n *\n * @param declaration - The declaration to render.\n * @param options - Optional precision context for expression values.\n * @returns Deterministic CSS text.\n * @example\n * ```ts\n * Declaration.render(Declaration.make('--indent', Calc.multiply(Calc.ref('depth'), 8)))\n * // '--indent: calc(var(--depth) * 8);'\n * ```\n * @since 0.1.0\n */\nexport const render: (declaration: Declaration<string>, options?: RenderOptions) => string =\n internal.render\n\nexport const equals: {\n /**\n * Returns a function that checks structural equality against `that`.\n *\n * @param that - The declaration to compare against.\n * @returns A function testing its argument for structural equality with `that`.\n * @since 0.1.0\n */\n (that: Declaration<string>): (self: Declaration<string>) => boolean\n /**\n * Structural equality: names compare as text, expression values as\n * expression trees (`Calc.equals` semantics, precision annotations\n * included). Literal text never equals an expression, even one that\n * would serialize to the same characters.\n *\n * @param self - The first declaration.\n * @param that - The second declaration.\n * @returns `true` if the declarations are structurally equal.\n * @since 0.1.0\n */\n (self: Declaration<string>, that: Declaration<string>): boolean\n} = internal.equals\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAwDA,MAAa,gBAA0DA;;;;;;;;;;;;;;;;;;;;AAqBvE,MAAa,OAGYC;AAEzB,MAAa,OA4BTC;;;;;;;;;AAUJ,MAAa,OACXC;;;;;;;;;;;;;;;;;AAiCF,MAAa,SACXC;AAEF,MAAa,SAqBTC"}
1
+ {"version":3,"file":"index.mjs","names":["internal.isDeclaration","internal.make","internal.bind","internal.refs","internal.render","internal.equals"],"sources":["../../src/declaration/declaration.ts"],"sourcesContent":["import type { ApplyBindings, Bindings, Calc, Kind } from '#calc/calc'\nimport type { Precision } from '#calc/precision'\nimport type { Color } from '#data/color'\nimport type { RenderOptions as MediaQueryRenderOptions } from '#query/mediaQuery'\nimport type { Pipeable } from '#util'\nimport type { DeclarationTypeId } from './declaration.internal.ts'\nimport * as internal from './declaration.internal.ts'\n\n/**\n * A CSS declaration: a property name paired with a value.\n *\n * This is the seam where the library's two halves meet — the value is\n * either literal CSS text, passed through verbatim, or a value-layer\n * expression (`Calc` or `Color`) serialized when the declaration renders.\n * A `Calc` of any dimension is accepted: a `<number>`, or a `<length>` /\n * `<angle>` built from `fashionable/data`, which carries its own units.\n *\n * The `Refs` parameter carries the value's unbound reference names, as on\n * `Calc`; literal text binds nothing and a text-valued declaration is a\n * `Declaration<never>`.\n *\n * Construct via `make`.\n *\n * @since 0.1.0\n */\nexport interface Declaration<out Refs extends string = string> extends Pipeable {\n readonly [DeclarationTypeId]: DeclarationTypeId\n /**\n * The property name, exactly as it renders — `font-size`, or `--depth`\n * for a custom property.\n */\n readonly name: string\n /**\n * The declaration's value: literal CSS text or a value-layer expression.\n */\n readonly value: Value<Refs>\n}\n\n/**\n * The value forms a declaration can hold: literal CSS text, a `Calc`\n * expression of any dimension, or a `Color` expression.\n *\n * @since 0.1.0\n */\nexport type Value<Refs extends string = string> = string | Calc<Refs, Kind, unknown> | Color<Refs>\n\n/**\n * Checks if a value is a `Declaration`.\n *\n * True only for values built by this module's constructors, which carry\n * the brand.\n *\n * @param u - The value to check.\n * @returns `true` if the value is a `Declaration`, `false` otherwise.\n * @since 0.1.0\n */\nexport const isDeclaration: (u: unknown) => u is Declaration<string> = internal.isDeclaration\n\n/**\n * Creates a declaration.\n *\n * Literal text is stored verbatim — no parsing, no escaping. A bare\n * number is coerced to an unannotated constant expression, as anywhere\n * else an expression is accepted, so it serializes under the precision\n * context rather than as raw text.\n *\n * @param name - The property name, exactly as it renders (`--x` keeps its dashes). Must be non-empty.\n * @param value - Literal CSS text, a number, or a `Calc`/`Color` expression.\n * @returns A `Declaration` carrying the value's reference names — `Declaration<never>` for text and numbers.\n * @throws `Error` when `name` is empty, or `value` is a non-finite number.\n * @example\n * ```ts\n * Declaration.make('color', 'red')\n * Declaration.make('--fluid', Calc.add(14, Calc.multiply(Calc.ref('vw'), 0.01)))\n * ```\n * @since 0.1.0\n */\nexport const make: <Refs extends string = never>(\n name: string,\n value: Value<Refs> | number,\n) => Declaration<Refs> = internal.make\n\nexport const bind: {\n /**\n * Returns a function that binds the given names in a declaration's\n * value.\n *\n * @param bindings - Reference names to values or expressions.\n * @returns A function replacing bound references in its argument's value.\n * @since 0.1.0\n */\n <const B extends Bindings>(\n bindings: B,\n ): <Refs extends string>(declaration: Declaration<Refs>) => Declaration<ApplyBindings<Refs, B>>\n /**\n * Replaces references in the declaration's value with values or other\n * expressions, re-folding constant subtrees. Semantics match\n * `Calc.bind`: unreferenced names and `undefined` values are ignored,\n * and expression-valued bindings contribute their own references. A\n * literal-text value binds nothing; the declaration is returned as-is.\n *\n * @param declaration - The declaration to bind.\n * @param bindings - Reference names to values or expressions.\n * @returns The bound declaration.\n * @since 0.1.0\n */\n <Refs extends string, const B extends Bindings>(\n declaration: Declaration<Refs>,\n bindings: B,\n ): Declaration<ApplyBindings<Refs, B>>\n} = internal.bind\n\n/**\n * The declaration's unbound reference names — empty for literal text,\n * the value's references otherwise.\n *\n * @param declaration - The declaration to inspect.\n * @returns The set of unbound reference names.\n * @since 0.1.0\n */\nexport const refs: <Refs extends string>(declaration: Declaration<Refs>) => ReadonlySet<Refs> =\n internal.refs\n\n/**\n * Options for `render`, extending `MediaQuery.RenderOptions` — the\n * render-options family's base — with the precision context.\n *\n * @since 0.1.0\n */\nexport interface RenderOptions extends MediaQueryRenderOptions {\n /**\n * The precision for expression constants that carry no annotation of\n * their own. Defaults to `Precision.decimals(5)`, as in\n * `Calc.serialize`.\n */\n readonly precision?: Precision\n}\n\n/**\n * Renders the declaration as one CSS declaration, semicolon included:\n * `name: value;`. Literal text passes through verbatim; expression\n * values serialize as `Calc.serialize`/`Color.serialize` would, with\n * unbound references rendering as `var(--name)`.\n *\n * @param declaration - The declaration to render.\n * @param options - Optional precision context for expression values.\n * @returns Deterministic CSS text.\n * @example\n * ```ts\n * Declaration.render(Declaration.make('--indent', Calc.multiply(Calc.ref('depth'), 8)))\n * // '--indent: calc(var(--depth) * 8);'\n * ```\n * @since 0.1.0\n */\nexport const render: (declaration: Declaration<string>, options?: RenderOptions) => string =\n internal.render\n\nexport const equals: {\n /**\n * Returns a function that checks structural equality against `that`.\n *\n * @param that - The declaration to compare against.\n * @returns A function testing its argument for structural equality with `that`.\n * @since 0.1.0\n */\n (that: Declaration<string>): (self: Declaration<string>) => boolean\n /**\n * Structural equality: names compare as text, expression values as\n * expression trees (`Calc.equals` semantics, precision annotations\n * included). Literal text never equals an expression, even one that\n * would serialize to the same characters.\n *\n * @param self - The first declaration.\n * @param that - The second declaration.\n * @returns `true` if the declarations are structurally equal.\n * @since 0.1.0\n */\n (self: Declaration<string>, that: Declaration<string>): boolean\n} = internal.equals\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAwDA,MAAa,gBAA0DA;;;;;;;;;;;;;;;;;;;;AAqBvE,MAAa,OAGYC;AAEzB,MAAa,OA4BTC;;;;;;;;;AAUJ,MAAa,OACXC;;;;;;;;;;;;;;;;;AAiCF,MAAa,SACXC;AAEF,MAAa,SAqBTC"}
@@ -0,0 +1,2 @@
1
+ import { n as fontFaceRule_d_exports } from "../shared/fontFaceRule-C7nYgH6X.mjs";
2
+ export { fontFaceRule_d_exports as FontFaceRule };
@@ -1,5 +1,5 @@
1
- import { c as __exportAll } from "../shared/equal-C96LR7p4.mjs";
2
- import { a as make$1, i as local$1, n as isFontFaceRule$1, o as render$1, r as isSource$1, s as url$1, t as equals$1 } from "../shared/fontFaceRule.internal-CgnEJbNS.mjs";
1
+ import { t as __exportAll } from "../shared/rolldown-runtime-D7D4PA-g.mjs";
2
+ import { a as make$1, i as local$1, n as isFontFaceRule$1, o as render$1, r as isSource$1, s as url$1, t as equals$1 } from "../shared/fontFaceRule.internal-D5u48TUO.mjs";
3
3
  //#region src/fontFace/fontFaceRule.ts
4
4
  var fontFaceRule_exports = /* @__PURE__ */ __exportAll({
5
5
  equals: () => equals,
@@ -57,7 +57,7 @@ const local = local$1;
57
57
  *
58
58
  * @param descriptors - The face's descriptors; `family` and `src` are required.
59
59
  * @returns A `FontFaceRule`.
60
- * @throws `Error` when `family` is empty, `src` is empty, a weight is outside `[1, 1000]` or a range is out of order, or a metric override is negative or non-finite.
60
+ * @throws `Error` when `family` is empty, `src` is empty, a weight is outside `[1, 1000]` or a range is out of order, a unicode-range entry is empty, out of order, or outside `[0x0, 0x10FFFF]`, or a metric override is negative or non-finite.
61
61
  * @example
62
62
  * ```ts
63
63
  * FontFaceRule.make({
@@ -75,13 +75,15 @@ const make = make$1;
75
75
  * Renders the rule as a complete `@font-face { ... }` block.
76
76
  *
77
77
  * Descriptors render in a fixed order — `font-family`, `font-weight`,
78
- * `font-style`, `font-display`, `src`, then the metric overrides — one
79
- * per line. A single-source `src` stays inline; multiple sources render
80
- * one per line at double indent, comma-separated. Numbers format at the
81
- * library default precision; the metric descriptors append `%`.
78
+ * `font-style`, `font-display`, `src`, `unicode-range`, then the metric
79
+ * overrides — one per line. A single-source `src` stays inline; multiple
80
+ * sources render one per line at double indent, comma-separated.
81
+ * Unicode ranges render uppercase-hex (`U+400, U+500-5FF`), in canonical
82
+ * order. Numbers format at the `precision` context (default
83
+ * `Precision.decimals(5)`); the metric descriptors append `%`.
82
84
  *
83
85
  * @param rule - The rule to render.
84
- * @param options - Optional indentation unit.
86
+ * @param options - Optional indentation unit and precision context.
85
87
  * @returns Deterministic CSS text.
86
88
  * @example
87
89
  * ```ts
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":["internal.isFontFaceRule","internal.isSource","internal.url","internal.local","internal.make","internal.render","internal.equals"],"sources":["../../src/fontFace/fontFaceRule.ts"],"sourcesContent":["import type { RenderOptions as DeclarationRenderOptions } from '#declaration/declaration'\nimport type { Pipeable } from '#util'\nimport type { FontFaceRuleTypeId, SourceTypeId } from './fontFaceRule.internal.ts'\nimport * as internal from './fontFaceRule.internal.ts'\n\n/**\n * An `@font-face` rule: a font family, its sources, and the optional\n * descriptors that scope and adjust the face.\n *\n * A declaration-block at-rule lives at the top level of a stylesheet —\n * it is deliberately not a rule-block member, so it cannot nest. All\n * fields are plain data: nothing in `@font-face` takes an expression.\n *\n * Construct via `make`.\n *\n * @since 0.1.0\n */\nexport interface FontFaceRule extends Pipeable {\n readonly [FontFaceRuleTypeId]: FontFaceRuleTypeId\n /**\n * The `font-family` descriptor: the name the face binds to, quoted when\n * rendered.\n */\n readonly family: string\n /**\n * The `src` descriptor's sources, in authored order — the browser uses\n * the first it supports.\n */\n readonly src: ReadonlyArray<Source>\n /**\n * The `font-weight` descriptor: one weight or an ordered\n * `[min, max]` range, in `[1, 1000]`.\n */\n readonly weight: Weight | undefined\n /**\n * The `font-style` descriptor keyword.\n */\n readonly style: Style | undefined\n /**\n * The `font-display` descriptor keyword.\n */\n readonly display: Display | undefined\n /**\n * The `ascent-override` metric, as a percentage number (`90` renders\n * `90%`).\n */\n readonly ascentOverride: number | undefined\n /**\n * The `descent-override` metric, as a percentage number.\n */\n readonly descentOverride: number | undefined\n /**\n * The `line-gap-override` metric, as a percentage number.\n */\n readonly lineGapOverride: number | undefined\n /**\n * The `size-adjust` metric, as a percentage number.\n */\n readonly sizeAdjust: number | undefined\n}\n\n/**\n * One entry of an `@font-face` `src` list: a downloadable `url(...)`\n * (optionally with a `format(...)` hint) or a `local(...)` lookup.\n *\n * Construct via `url` and `local`.\n *\n * @since 0.1.0\n */\nexport interface Source extends Pipeable {\n readonly [SourceTypeId]: SourceTypeId\n}\n\n/**\n * A `font-weight` descriptor value: a single weight, or an ordered\n * `[min, max]` range (`[100, 900]` renders `100 900`) for variable faces.\n *\n * @since 0.1.0\n */\nexport type Weight = number | readonly [number, number]\n\n/**\n * The `font-style` descriptor keywords. Oblique angle ranges are a later\n * extension when a consumer needs them.\n *\n * @since 0.1.0\n */\nexport type Style = 'normal' | 'italic' | 'oblique'\n\n/**\n * The `font-display` descriptor keywords.\n *\n * @since 0.1.0\n */\nexport type Display = 'auto' | 'block' | 'swap' | 'fallback' | 'optional'\n\n/**\n * The descriptors accepted by `make`.\n *\n * Metrics-adjusted fallback faces are the expected use: a face whose sole\n * source is `local(...)`, carrying overrides computed from the primary\n * face's metrics.\n *\n * @since 0.1.0\n */\nexport interface Descriptors {\n /**\n * The `font-family` descriptor: the name the face binds to. Required.\n */\n readonly family: string\n /**\n * The `src` descriptor's sources, tried in the order given — the\n * browser uses the first it supports. Required and non-empty.\n */\n readonly src: ReadonlyArray<Source>\n /**\n * The `font-weight` descriptor: one weight or an ordered `[min, max]`\n * range, each in `[1, 1000]`.\n */\n readonly weight?: Weight\n /**\n * The `font-style` descriptor keyword.\n */\n readonly style?: Style\n /**\n * The `font-display` descriptor keyword.\n */\n readonly display?: Display\n /**\n * The `ascent-override` metric, as a percentage number (`90` means\n * `90%`).\n */\n readonly ascentOverride?: number\n /**\n * The `descent-override` metric, as a percentage number.\n */\n readonly descentOverride?: number\n /**\n * The `line-gap-override` metric, as a percentage number.\n */\n readonly lineGapOverride?: number\n /**\n * The `size-adjust` metric, as a percentage number.\n */\n readonly sizeAdjust?: number\n}\n\n/**\n * Options for `render`, in the render-options family rooted at\n * `MediaQuery.RenderOptions` (via `Declaration.RenderOptions`). This\n * renderer consumes `indent`; the inherited keys are accepted and\n * ignored, so one options object composes across the library.\n *\n * @since 0.1.0\n */\nexport interface RenderOptions extends DeclarationRenderOptions {\n /**\n * The indentation unit for the block's declarations. Defaults to a tab.\n */\n readonly indent?: string\n}\n\n/**\n * Checks if a value is a `FontFaceRule`.\n *\n * True only for values built by this module's constructors, which carry\n * the brand.\n *\n * @param u - The value to check.\n * @returns `true` if the value is a `FontFaceRule`, `false` otherwise.\n * @since 0.1.0\n */\nexport const isFontFaceRule: (u: unknown) => u is FontFaceRule = internal.isFontFaceRule\n\n/**\n * Checks if a value is a font `Source`.\n *\n * True only for values built by `url` and `local`, which carry the brand.\n *\n * @param u - The value to check.\n * @returns `true` if the value is a `Source`, `false` otherwise.\n * @since 0.1.0\n */\nexport const isSource: (u: unknown) => u is Source = internal.isSource\n\n/**\n * Creates a downloadable font source, rendered `url('href')` — with a\n * `format('...')` hint appended when `format` is given.\n *\n * @param href - The URL the face loads from. Must be non-empty; rendered single-quoted with embedded quotes and backslashes escaped.\n * @param format - The optional format hint (`woff2`, `woff`, ...). Must be non-empty when given.\n * @returns A `Source` for `Descriptors.src`.\n * @throws `Error` when `href` is empty, or `format` is given but empty.\n * @since 0.1.0\n */\nexport const url: (href: string, format?: string) => Source = internal.url\n\n/**\n * Creates a local font lookup, rendered `local('name')` — the expected\n * sole source of a metrics-adjusted fallback face.\n *\n * @param name - The locally installed family name. Must be non-empty; rendered single-quoted with embedded quotes and backslashes escaped.\n * @returns A `Source` for `Descriptors.src`.\n * @throws `Error` when `name` is empty.\n * @since 0.1.0\n */\nexport const local: (name: string) => Source = internal.local\n\n/**\n * Creates an `@font-face` rule.\n *\n * @param descriptors - The face's descriptors; `family` and `src` are required.\n * @returns A `FontFaceRule`.\n * @throws `Error` when `family` is empty, `src` is empty, a weight is outside `[1, 1000]` or a range is out of order, or a metric override is negative or non-finite.\n * @example\n * ```ts\n * FontFaceRule.make({\n * family: 'Inter',\n * weight: [100, 900],\n * style: 'normal',\n * display: 'swap',\n * src: [FontFaceRule.url('/fonts/inter-variable.woff2', 'woff2')],\n * })\n * ```\n * @since 0.1.0\n */\nexport const make: (descriptors: Descriptors) => FontFaceRule = internal.make\n\n/**\n * Renders the rule as a complete `@font-face { ... }` block.\n *\n * Descriptors render in a fixed order — `font-family`, `font-weight`,\n * `font-style`, `font-display`, `src`, then the metric overrides — one\n * per line. A single-source `src` stays inline; multiple sources render\n * one per line at double indent, comma-separated. Numbers format at the\n * library default precision; the metric descriptors append `%`.\n *\n * @param rule - The rule to render.\n * @param options - Optional indentation unit.\n * @returns Deterministic CSS text.\n * @example\n * ```ts\n * FontFaceRule.render(\n * FontFaceRule.make({ family: 'Inter', src: [FontFaceRule.url('/inter.woff2', 'woff2')] }),\n * )\n * // \"@font-face {\\n\\tfont-family: 'Inter';\\n\\tsrc: url('/inter.woff2') format('woff2');\\n}\"\n * ```\n * @since 0.1.0\n */\nexport const render: (rule: FontFaceRule, options?: RenderOptions) => string = internal.render\n\nexport const equals: {\n /**\n * Returns a function that checks structural equality against `that`.\n *\n * @param that - The rule to compare against.\n * @returns A function testing its argument for structural equality with `that`.\n * @since 0.1.0\n */\n (that: FontFaceRule): (self: FontFaceRule) => boolean\n /**\n * Structural equality over descriptors. `src` order participates (it is\n * fallback order); a single weight never equals a range, even a\n * degenerate one.\n *\n * @param self - The first rule.\n * @param that - The second rule.\n * @returns `true` if the rules are structurally equal.\n * @since 0.1.0\n */\n (self: FontFaceRule, that: FontFaceRule): boolean\n} = internal.equals\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AA4KA,MAAa,iBAAoDA;;;;;;;;;;AAWjE,MAAa,WAAwCC;;;;;;;;;;;AAYrD,MAAa,MAAiDC;;;;;;;;;;AAW9D,MAAa,QAAkCC;;;;;;;;;;;;;;;;;;;AAoB/C,MAAa,OAAmDC;;;;;;;;;;;;;;;;;;;;;;AAuBhE,MAAa,SAAkEC;AAE/E,MAAa,SAoBTC"}
1
+ {"version":3,"file":"index.mjs","names":["internal.isFontFaceRule","internal.isSource","internal.url","internal.local","internal.make","internal.render","internal.equals"],"sources":["../../src/fontFace/fontFaceRule.ts"],"sourcesContent":["import type { RenderOptions as DeclarationRenderOptions } from '#declaration/declaration'\nimport type { Pipeable } from '#util'\nimport type { FontFaceRuleTypeId, SourceTypeId } from './fontFaceRule.internal.ts'\nimport * as internal from './fontFaceRule.internal.ts'\n\n/**\n * An `@font-face` rule: a font family, its sources, and the optional\n * descriptors that scope and adjust the face.\n *\n * A declaration-block at-rule lives at the top level of a stylesheet —\n * it is deliberately not a rule-block member, so it cannot nest. All\n * fields are plain data: nothing in `@font-face` takes an expression.\n *\n * Construct via `make`.\n *\n * @since 0.1.0\n */\nexport interface FontFaceRule extends Pipeable {\n readonly [FontFaceRuleTypeId]: FontFaceRuleTypeId\n /**\n * The `font-family` descriptor: the name the face binds to, quoted when\n * rendered.\n */\n readonly family: string\n /**\n * The `src` descriptor's sources, in authored order — the browser uses\n * the first it supports.\n */\n readonly src: ReadonlyArray<Source>\n /**\n * The `font-weight` descriptor: one weight or an ordered\n * `[min, max]` range, in `[1, 1000]`.\n */\n readonly weight: Weight | undefined\n /**\n * The `font-style` descriptor keyword.\n */\n readonly style: Style | undefined\n /**\n * The `font-display` descriptor keyword.\n */\n readonly display: Display | undefined\n /**\n * The `unicode-range` descriptor's ranges, canonically ordered (by\n * start, then end) with exact duplicates dropped.\n */\n readonly unicodeRange: ReadonlyArray<UnicodeRange> | undefined\n /**\n * The `ascent-override` metric, as a percentage number (`90` renders\n * `90%`).\n */\n readonly ascentOverride: number | undefined\n /**\n * The `descent-override` metric, as a percentage number.\n */\n readonly descentOverride: number | undefined\n /**\n * The `line-gap-override` metric, as a percentage number.\n */\n readonly lineGapOverride: number | undefined\n /**\n * The `size-adjust` metric, as a percentage number.\n */\n readonly sizeAdjust: number | undefined\n}\n\n/**\n * One entry of an `@font-face` `src` list: a downloadable `url(...)`\n * (optionally with a `format(...)` hint) or a `local(...)` lookup.\n *\n * Construct via `url` and `local`.\n *\n * @since 0.1.0\n */\nexport interface Source extends Pipeable {\n readonly [SourceTypeId]: SourceTypeId\n}\n\n/**\n * A `font-weight` descriptor value: a single weight, or an ordered\n * `[min, max]` range (`[100, 900]` renders `100 900`) for variable faces.\n *\n * @since 0.1.0\n */\nexport type Weight = number | readonly [number, number]\n\n/**\n * The `font-style` descriptor keywords. Oblique angle ranges are a later\n * extension when a consumer needs them.\n *\n * @since 0.1.0\n */\nexport type Style = 'normal' | 'italic' | 'oblique'\n\n/**\n * The `font-display` descriptor keywords.\n *\n * @since 0.1.0\n */\nexport type Display = 'auto' | 'block' | 'swap' | 'fallback' | 'optional'\n\n/**\n * One `unicode-range` descriptor entry: a single codepoint (`0x400`\n * renders `U+400`) or an inclusive `[start, end]` range (`[0x400, 0x4ff]`\n * renders `U+400-4FF`), each in `[0x0, 0x10FFFF]`.\n *\n * The wildcard spelling (`U+4??`) is range sugar and is not modeled.\n *\n * @since 0.2.0\n */\nexport type UnicodeRange = number | readonly [start: number, end: number]\n\n/**\n * The descriptors accepted by `make`.\n *\n * Metrics-adjusted fallback faces are the expected use: a face whose sole\n * source is `local(...)`, carrying overrides computed from the primary\n * face's metrics.\n *\n * @since 0.1.0\n */\nexport interface Descriptors {\n /**\n * The `font-family` descriptor: the name the face binds to. Required.\n */\n readonly family: string\n /**\n * The `src` descriptor's sources, tried in the order given — the\n * browser uses the first it supports. Required and non-empty.\n */\n readonly src: ReadonlyArray<Source>\n /**\n * The `font-weight` descriptor: one weight or an ordered `[min, max]`\n * range, each in `[1, 1000]`.\n */\n readonly weight?: Weight\n /**\n * The `font-style` descriptor keyword.\n */\n readonly style?: Style\n /**\n * The `font-display` descriptor keyword.\n */\n readonly display?: Display\n /**\n * The `unicode-range` descriptor: the codepoints the face applies to,\n * as single codepoints and inclusive `[start, end]` ranges. Non-empty\n * when given. The descriptor is a set union, so entries canonicalize —\n * sorted by start then end, exact duplicates dropped — and\n * construction order never matters.\n */\n readonly unicodeRange?: ReadonlyArray<UnicodeRange>\n /**\n * The `ascent-override` metric, as a percentage number (`90` means\n * `90%`).\n */\n readonly ascentOverride?: number\n /**\n * The `descent-override` metric, as a percentage number.\n */\n readonly descentOverride?: number\n /**\n * The `line-gap-override` metric, as a percentage number.\n */\n readonly lineGapOverride?: number\n /**\n * The `size-adjust` metric, as a percentage number.\n */\n readonly sizeAdjust?: number\n}\n\n/**\n * Options for `render`, in the render-options family rooted at\n * `MediaQuery.RenderOptions` (via `Declaration.RenderOptions`). This\n * renderer consumes `indent` and the inherited `precision` (for the\n * weight and metric-override numbers); `mediaSyntax` is accepted and\n * ignored, so one options object composes across the library.\n *\n * @since 0.1.0\n */\nexport interface RenderOptions extends DeclarationRenderOptions {\n /**\n * The indentation unit for the block's declarations. Defaults to a tab.\n */\n readonly indent?: string\n}\n\n/**\n * Checks if a value is a `FontFaceRule`.\n *\n * True only for values built by this module's constructors, which carry\n * the brand.\n *\n * @param u - The value to check.\n * @returns `true` if the value is a `FontFaceRule`, `false` otherwise.\n * @since 0.1.0\n */\nexport const isFontFaceRule: (u: unknown) => u is FontFaceRule = internal.isFontFaceRule\n\n/**\n * Checks if a value is a font `Source`.\n *\n * True only for values built by `url` and `local`, which carry the brand.\n *\n * @param u - The value to check.\n * @returns `true` if the value is a `Source`, `false` otherwise.\n * @since 0.1.0\n */\nexport const isSource: (u: unknown) => u is Source = internal.isSource\n\n/**\n * Creates a downloadable font source, rendered `url('href')` — with a\n * `format('...')` hint appended when `format` is given.\n *\n * @param href - The URL the face loads from. Must be non-empty; rendered single-quoted with embedded quotes and backslashes escaped.\n * @param format - The optional format hint (`woff2`, `woff`, ...). Must be non-empty when given.\n * @returns A `Source` for `Descriptors.src`.\n * @throws `Error` when `href` is empty, or `format` is given but empty.\n * @since 0.1.0\n */\nexport const url: (href: string, format?: string) => Source = internal.url\n\n/**\n * Creates a local font lookup, rendered `local('name')` — the expected\n * sole source of a metrics-adjusted fallback face.\n *\n * @param name - The locally installed family name. Must be non-empty; rendered single-quoted with embedded quotes and backslashes escaped.\n * @returns A `Source` for `Descriptors.src`.\n * @throws `Error` when `name` is empty.\n * @since 0.1.0\n */\nexport const local: (name: string) => Source = internal.local\n\n/**\n * Creates an `@font-face` rule.\n *\n * @param descriptors - The face's descriptors; `family` and `src` are required.\n * @returns A `FontFaceRule`.\n * @throws `Error` when `family` is empty, `src` is empty, a weight is outside `[1, 1000]` or a range is out of order, a unicode-range entry is empty, out of order, or outside `[0x0, 0x10FFFF]`, or a metric override is negative or non-finite.\n * @example\n * ```ts\n * FontFaceRule.make({\n * family: 'Inter',\n * weight: [100, 900],\n * style: 'normal',\n * display: 'swap',\n * src: [FontFaceRule.url('/fonts/inter-variable.woff2', 'woff2')],\n * })\n * ```\n * @since 0.1.0\n */\nexport const make: (descriptors: Descriptors) => FontFaceRule = internal.make\n\n/**\n * Renders the rule as a complete `@font-face { ... }` block.\n *\n * Descriptors render in a fixed order — `font-family`, `font-weight`,\n * `font-style`, `font-display`, `src`, `unicode-range`, then the metric\n * overrides — one per line. A single-source `src` stays inline; multiple\n * sources render one per line at double indent, comma-separated.\n * Unicode ranges render uppercase-hex (`U+400, U+500-5FF`), in canonical\n * order. Numbers format at the `precision` context (default\n * `Precision.decimals(5)`); the metric descriptors append `%`.\n *\n * @param rule - The rule to render.\n * @param options - Optional indentation unit and precision context.\n * @returns Deterministic CSS text.\n * @example\n * ```ts\n * FontFaceRule.render(\n * FontFaceRule.make({ family: 'Inter', src: [FontFaceRule.url('/inter.woff2', 'woff2')] }),\n * )\n * // \"@font-face {\\n\\tfont-family: 'Inter';\\n\\tsrc: url('/inter.woff2') format('woff2');\\n}\"\n * ```\n * @since 0.1.0\n */\nexport const render: (rule: FontFaceRule, options?: RenderOptions) => string = internal.render\n\nexport const equals: {\n /**\n * Returns a function that checks structural equality against `that`.\n *\n * @param that - The rule to compare against.\n * @returns A function testing its argument for structural equality with `that`.\n * @since 0.1.0\n */\n (that: FontFaceRule): (self: FontFaceRule) => boolean\n /**\n * Structural equality over descriptors. `src` order participates (it is\n * fallback order); `unicode-range` order does not (entries canonicalize\n * at construction); a single weight or codepoint never equals a range,\n * even a degenerate one.\n *\n * @param self - The first rule.\n * @param that - The second rule.\n * @returns `true` if the rules are structurally equal.\n * @since 0.1.0\n */\n (self: FontFaceRule, that: FontFaceRule): boolean\n} = internal.equals\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAqMA,MAAa,iBAAoDA;;;;;;;;;;AAWjE,MAAa,WAAwCC;;;;;;;;;;;AAYrD,MAAa,MAAiDC;;;;;;;;;;AAW9D,MAAa,QAAkCC;;;;;;;;;;;;;;;;;;;AAoB/C,MAAa,OAAmDC;;;;;;;;;;;;;;;;;;;;;;;;AAyBhE,MAAa,SAAkEC;AAE/E,MAAa,SAqBTC"}
@@ -0,0 +1,2 @@
1
+ import { n as propertyRule_d_exports, r as propertySyntax_d_exports } from "../shared/propertyRule-BbkFh9b9.mjs";
2
+ export { propertyRule_d_exports as PropertyRule, propertySyntax_d_exports as PropertySyntax };
@@ -1,5 +1,5 @@
1
- import { c as __exportAll } from "../shared/equal-C96LR7p4.mjs";
2
- import { C as resolution$1, D as transformList$1, E as transformFunction$1, O as universal$1, S as render$3, T as time$1, _ as lengthPercentage$1, a as render$2, b as oneOf$1, c as commaListOf$1, d as image$1, f as integer$1, g as length$1, h as keywords$1, i as make$1, k as url$1, l as customIdent$1, m as keyword$1, n as inheritable$1, o as angle$1, p as isPropertySyntax$1, r as isPropertyRule$1, s as color$1, t as equals$2, u as equals$3, v as listOf$1, w as string$1, x as percentage$1, y as number$1 } from "../shared/propertyRule.internal-BY1ghubC.mjs";
1
+ import { t as __exportAll } from "../shared/rolldown-runtime-D7D4PA-g.mjs";
2
+ import { C as resolution$1, D as transformList$1, E as transformFunction$1, O as universal$1, S as render$3, T as time$1, _ as lengthPercentage$1, a as render$2, b as oneOf$1, c as commaListOf$1, d as image$1, f as integer$1, g as length$1, h as keywords$1, i as make$1, k as url$1, l as customIdent$1, m as keyword$1, n as inheritable$1, o as angle$1, p as isPropertySyntax$1, r as isPropertyRule$1, s as color$1, t as equals$2, u as equals$3, v as listOf$1, w as string$1, x as percentage$1, y as number$1 } from "../shared/propertyRule.internal-Bc_HrfcL.mjs";
3
3
  //#region src/property/propertyRule.ts
4
4
  var propertyRule_exports = /* @__PURE__ */ __exportAll({
5
5
  equals: () => equals$1,
@@ -98,8 +98,8 @@ const isPropertySyntax = isPropertySyntax$1;
98
98
  */
99
99
  const universal = universal$1;
100
100
  /**
101
- * The `<angle>` data type. Initial values are literal text carrying an
102
- * angle unit (`'90deg'`).
101
+ * The `<angle>` data type. Initial values are a closed angle-kind `Calc`
102
+ * (`Angle.rad(...)`) or literal text carrying an angle unit (`'90deg'`).
103
103
  *
104
104
  * @since 0.1.0
105
105
  */
@@ -134,14 +134,18 @@ const image = image$1;
134
134
  */
135
135
  const integer = integer$1;
136
136
  /**
137
- * The `<length>` data type. Initial values are literal text carrying a
138
- * length unit (`'0px'` — a bare `0` is not a valid registered length).
137
+ * The `<length>` data type. Initial values are a closed length-kind `Calc`
138
+ * (`Length.px(8)`) or literal text carrying a length unit (`'8px'` — a bare
139
+ * `0` is not a valid registered length). An `@property` initial value must be
140
+ * computationally independent, so an expression may carry only absolute units
141
+ * (`px`) — a viewport- or font-relative length (`Length.vw(8)`) is rejected.
139
142
  *
140
143
  * @since 0.1.0
141
144
  */
142
145
  const length = length$1;
143
146
  /**
144
- * The `<length-percentage>` data type. Initial values are literal text.
147
+ * The `<length-percentage>` data type. Initial values are a closed
148
+ * absolute-length or percentage `Calc`, or literal text.
145
149
  *
146
150
  * @since 0.1.0
147
151
  */
@@ -155,8 +159,8 @@ const lengthPercentage = lengthPercentage$1;
155
159
  */
156
160
  const number = number$1;
157
161
  /**
158
- * The `<percentage>` data type. Initial values are literal text carrying
159
- * the `%` unit (`'50%'`).
162
+ * The `<percentage>` data type. Initial values are a closed percentage-kind
163
+ * `Calc` (`Percentage.of(50)`) or literal text carrying the `%` unit (`'50%'`).
160
164
  *
161
165
  * @since 0.1.0
162
166
  */
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":["internal.isPropertyRule","internal.make","internal.inheritable","render","internal.render","equals","internal.equals","internal.isPropertySyntax","internal.universal","internal.angle","internal.color","internal.customIdent","internal.image","internal.integer","internal.length","internal.lengthPercentage","internal.number","internal.percentage","internal.resolution","internal.string","internal.time","internal.transformFunction","internal.transformList","internal.url","internal.keyword","internal.keywords","internal.oneOf","internal.listOf","internal.commaListOf","internal.render","internal.equals"],"sources":["../../src/property/propertyRule.ts","../../src/property/propertySyntax.ts"],"sourcesContent":["import type { Calc } from '#calc/calc'\nimport type { Color } from '#color/color'\nimport type { RenderOptions as DeclarationRenderOptions } from '#declaration/declaration'\nimport type { Pipeable } from '#util'\nimport type { PropertyRuleTypeId } from './propertyRule.internal.ts'\nimport * as internal from './propertyRule.internal.ts'\nimport type { PropertySyntax, Universal } from './propertySyntax.ts'\n\n/**\n * An `@property` rule: the registration that gives a custom property a\n * syntax, an inheritance behavior, and an initial value.\n *\n * A declaration-block at-rule lives at the top level of a stylesheet —\n * it is deliberately not a rule-block member, so it cannot nest.\n *\n * The registration is what turns a custom property into a typed,\n * animatable channel; a computed-property chain pairs one of these with\n * a `Declaration` writing the property and `Calc.ref` reads downstream.\n *\n * Construct via `make`.\n *\n * @since 0.1.0\n */\nexport interface PropertyRule extends Pipeable {\n readonly [PropertyRuleTypeId]: PropertyRuleTypeId\n /**\n * The registered custom property name, `--` prefix included.\n */\n readonly name: `--${string}`\n /**\n * The modeled `syntax` descriptor; `render` emits it single-quoted.\n */\n readonly syntax: PropertySyntax\n /**\n * The `inherits` descriptor. `make` registers `false`; `inheritable`\n * flips it.\n */\n readonly inherits: boolean\n /**\n * The `initial-value` descriptor: literal text or a closed expression.\n * Absent only under the universal syntax.\n */\n readonly initialValue: Value | undefined\n}\n\n/**\n * The value forms an `initial-value` descriptor can hold once\n * constructed. The `never` parameters are the spec rule in the types:\n * `@property` initial values must be computationally independent, so\n * only closed expressions — no unbound references — are accepted.\n *\n * `make` narrows further: its `initialValue` option takes only the forms\n * the declared syntax accepts (the syntax's `V` parameter).\n *\n * @since 0.1.0\n */\nexport type Value = string | Calc<never> | Color<never>\n\n/**\n * Options for `render`, in the render-options family rooted at\n * `MediaQuery.RenderOptions` (via `Declaration.RenderOptions`). This\n * renderer consumes `indent` and the inherited `precision` (for an\n * expression-valued `initial-value`); `mediaSyntax` is accepted and\n * ignored.\n *\n * @since 0.1.0\n */\nexport interface RenderOptions extends DeclarationRenderOptions {\n /**\n * The indentation unit for the block's declarations. Defaults to a tab.\n */\n readonly indent?: string\n}\n\n/**\n * Checks if a value is a `PropertyRule`.\n *\n * True only for values built by this module's constructors, which carry\n * the brand.\n *\n * @param u - The value to check.\n * @returns `true` if the value is a `PropertyRule`, `false` otherwise.\n * @since 0.1.0\n */\nexport const isPropertyRule: (u: unknown) => u is PropertyRule = internal.isPropertyRule\n\nexport const make: {\n /**\n * Registers under the universal syntax — the default when `syntax` is\n * omitted — where the initial value is optional.\n *\n * @param name - The custom property name to register, `--` prefix included.\n * @param syntax - The universal syntax; omit for the same effect.\n * @param initialValue - Optional under the universal syntax: any value form.\n * @returns A `PropertyRule` with `inherits: false`.\n * @throws `Error` when `name` is not a `--`-prefixed custom property name (bare `--` included), or an expression value has unbound references.\n * @since 0.1.0\n */\n (name: `--${string}`, syntax?: Universal, initialValue?: Value | number): PropertyRule\n /**\n * Creates an `@property` rule.\n *\n * The syntax value types the initial value: only forms the syntax\n * accepts are admitted — numbers and closed `Calc` expressions under\n * `PropertySyntax.number`, exactly the declared literals under a\n * keyword set, and so on — and the computational-independence rule\n * rides along, since an expression with unbound references is not a\n * `Calc<never>` (backed by a runtime check for untyped callers). Bare\n * numbers coerce to unannotated constants. That literal-text values\n * parse under the syntax is not checked — this library does not parse\n * CSS.\n *\n * Rules register with `inherits: false`; pipe through `inheritable` to\n * opt in.\n *\n * @param name - The custom property name to register, `--` prefix included.\n * @param syntax - The modeled `syntax` descriptor; see `PropertySyntax`.\n * @param initialValue - The `initial-value` descriptor, required for every non-universal syntax and typed by it.\n * @returns A `PropertyRule` with `inherits: false`.\n * @throws `Error` when `name` is not a `--`-prefixed custom property name (bare `--` included), `initialValue` is missing under a non-universal syntax, or an expression value has unbound references.\n * @example\n * ```ts\n * PropertyRule.make('--depth', PropertySyntax.number, 0)\n * ```\n * @since 0.1.0\n */\n <V extends Value | number>(\n name: `--${string}`,\n syntax: PropertySyntax<V>,\n initialValue: NoInfer<V>,\n ): PropertyRule\n} = internal.make\n\n/**\n * Registers the rule as inheriting. `make` constructs every rule with\n * `inherits: false` — the safe default for computed channels, where\n * inheritance would leak intermediate values down the tree — so\n * inheritance is an explicit opt-in.\n *\n * @param rule - The rule to opt in.\n * @returns The inheriting rule; the same rule when it already inherits.\n * @example\n * ```ts\n * PropertyRule.make('--fill', PropertySyntax.color, 'red').pipe(PropertyRule.inheritable)\n * ```\n * @since 0.1.0\n */\nexport const inheritable: (rule: PropertyRule) => PropertyRule = internal.inheritable\n\n/**\n * Renders the rule as a complete `@property --name { ... }` block, the\n * descriptors in fixed order: `syntax`, `inherits`, `initial-value`.\n *\n * @param rule - The rule to render.\n * @param options - Optional indentation unit and precision context.\n * @returns Deterministic CSS text.\n * @example\n * ```ts\n * PropertyRule.render(PropertyRule.make('--depth', PropertySyntax.number, 0))\n * // \"@property --depth {\\n\\tsyntax: '<number>';\\n\\tinherits: false;\\n\\tinitial-value: 0;\\n}\"\n * ```\n * @since 0.1.0\n */\nexport const render: (rule: PropertyRule, options?: RenderOptions) => string = internal.render\n\nexport const equals: {\n /**\n * Returns a function that checks structural equality against `that`.\n *\n * @param that - The rule to compare against.\n * @returns A function testing its argument for structural equality with `that`.\n * @since 0.1.0\n */\n (that: PropertyRule): (self: PropertyRule) => boolean\n /**\n * Structural equality: `name` and `inherits` compare as data, the\n * syntax as its modeled grammar (`PropertySyntax.equals` semantics),\n * and expression initial values as expression trees (`Calc.equals`\n * semantics). Literal text never equals an expression.\n *\n * @param self - The first rule.\n * @param that - The second rule.\n * @returns `true` if the rules are structurally equal.\n * @since 0.1.0\n */\n (self: PropertyRule, that: PropertyRule): boolean\n} = internal.equals\n","import type { Calc } from '#calc/calc'\nimport type { Color } from '#color/color'\nimport type { Pipeable } from '#util'\nimport type { PropertySyntaxTypeId } from './propertySyntax.internal.ts'\nimport * as internal from './propertySyntax.internal.ts'\n\ndeclare const AcceptedValue: unique symbol\ndeclare const UniversalMarker: unique symbol\n\n/**\n * A modeled `@property` syntax descriptor: the universal syntax, a data\n * type, a keyword, a multiplied list, or a `|` combination of these.\n *\n * The point of modeling the descriptor as a value is twofold. The\n * supported grammar becomes discoverable — the data types are constants\n * (`number`, `color`, `lengthPercentage`, ...), and the combinators\n * (`keyword`, `oneOf`, `listOf`, `commaListOf`) enforce the grammar's\n * constraints at construction. And the `V` parameter tracks the\n * initial-value forms the syntax accepts, so `PropertyRule.make` can\n * type its `initialValue` from the syntax it is registered under.\n *\n * Construct via the data type constants, `universal`, `keyword`,\n * `keywords`, `oneOf`, `listOf`, and `commaListOf`.\n *\n * @since 0.1.0\n */\nexport interface PropertySyntax<out V = Value> extends Pipeable {\n readonly [PropertySyntaxTypeId]: PropertySyntaxTypeId\n readonly [AcceptedValue]?: V\n}\n\n/**\n * The full initial-value domain — what the universal syntax accepts.\n * Individual syntaxes narrow this: number-land syntaxes take numbers and\n * closed `Calc` expressions, `color` takes closed `Color` expressions or\n * text, keyword sets take exactly their literals, and everything else\n * takes literal text carrying its own units.\n *\n * @since 0.1.0\n */\nexport type Value = string | number | Calc<never> | Color<never>\n\n/**\n * The initial-value forms a syntax accepts — the type-level counterpart\n * of the `V` parameter, extracted from a syntax (or union of syntaxes).\n *\n * @since 0.1.0\n */\nexport type ValueOf<S extends PropertySyntax<unknown>> =\n S extends PropertySyntax<infer V> ? V : never\n\n/**\n * Checks if a value is a `PropertySyntax`.\n *\n * True only for values built by this module's constructors, which carry\n * the brand.\n *\n * @param u - The value to check.\n * @returns `true` if the value is a `PropertySyntax`, `false` otherwise.\n * @since 0.1.0\n */\nexport const isPropertySyntax: (u: unknown) => u is PropertySyntax = internal.isPropertySyntax\n\n/**\n * The type of `universal` alone. Naming it lets `PropertyRule.make`\n * recognize the universal syntax in overload resolution — the one syntax\n * under which the initial value is optional.\n *\n * @since 0.1.0\n */\nexport interface Universal extends PropertySyntax<Value> {\n readonly [UniversalMarker]: true\n}\n\n/**\n * The universal syntax, `*` — any value at all. The one syntax under\n * which `@property` may omit its initial value.\n *\n * @since 0.1.0\n */\nexport const universal: Universal = internal.universal\n\n/**\n * The `<angle>` data type. Initial values are literal text carrying an\n * angle unit (`'90deg'`).\n *\n * @since 0.1.0\n */\nexport const angle: PropertySyntax<string> = internal.angle\n\n/**\n * The `<color>` data type. Initial values are closed `Color` expressions\n * or literal text (`'transparent'`, `'#fff'`).\n *\n * @since 0.1.0\n */\nexport const color: PropertySyntax<string | Color<never>> = internal.color\n\n/**\n * The `<custom-ident>` data type — any custom identifier. To accept a\n * fixed set of identifiers instead, combine `keyword` values with\n * `oneOf`.\n *\n * @since 0.1.0\n */\nexport const customIdent: PropertySyntax<string> = internal.customIdent\n\n/**\n * The `<image>` data type. Initial values are literal text.\n *\n * @since 0.1.0\n */\nexport const image: PropertySyntax<string> = internal.image\n\n/**\n * The `<integer>` data type. Initial values are numbers or closed `Calc`\n * expressions; that the value is a whole number is the browser's parse\n * check, not this library's.\n *\n * @since 0.1.0\n */\nexport const integer: PropertySyntax<number | Calc<never>> = internal.integer\n\n/**\n * The `<length>` data type. Initial values are literal text carrying a\n * length unit (`'0px'` — a bare `0` is not a valid registered length).\n *\n * @since 0.1.0\n */\nexport const length: PropertySyntax<string> = internal.length\n\n/**\n * The `<length-percentage>` data type. Initial values are literal text.\n *\n * @since 0.1.0\n */\nexport const lengthPercentage: PropertySyntax<string> = internal.lengthPercentage\n\n/**\n * The `<number>` data type. Initial values are numbers or closed `Calc`\n * expressions — the typed channel this library models; text is not\n * accepted where the number form exists.\n *\n * @since 0.1.0\n */\nexport const number: PropertySyntax<number | Calc<never>> = internal.number\n\n/**\n * The `<percentage>` data type. Initial values are literal text carrying\n * the `%` unit (`'50%'`).\n *\n * @since 0.1.0\n */\nexport const percentage: PropertySyntax<string> = internal.percentage\n\n/**\n * The `<resolution>` data type. Initial values are literal text.\n *\n * @since 0.1.0\n */\nexport const resolution: PropertySyntax<string> = internal.resolution\n\n/**\n * The `<string>` data type. Initial values are literal text including\n * their own quotes (`'\"hello\"'`).\n *\n * @since 0.1.0\n */\nexport const string: PropertySyntax<string> = internal.string\n\n/**\n * The `<time>` data type. Initial values are literal text carrying a\n * time unit (`'200ms'`).\n *\n * @since 0.1.0\n */\nexport const time: PropertySyntax<string> = internal.time\n\n/**\n * The `<transform-function>` data type. Initial values are literal text.\n *\n * @since 0.1.0\n */\nexport const transformFunction: PropertySyntax<string> = internal.transformFunction\n\n/**\n * The `<transform-list>` data type — a list of transform functions. It\n * is pre-multiplied, so `listOf`/`commaListOf` reject it. Initial values\n * are literal text.\n *\n * @since 0.1.0\n */\nexport const transformList: PropertySyntax<string> = internal.transformList\n\n/**\n * The `<url>` data type. Initial values are literal text.\n *\n * @since 0.1.0\n */\nexport const url: PropertySyntax<string> = internal.url\n\n/**\n * A keyword component: one specific custom identifier, rendered bare.\n * Combined under `oneOf`, keywords give the registered property an\n * enum-like domain — and the `V` parameter carries the literal, so\n * `initialValue` autocompletes and checks against exactly the declared\n * set.\n *\n * @param name - The identifier. Must be non-empty and not a CSS-wide keyword (`inherit`, `initial`, `unset`, `revert`, `revert-layer`, `default`), which the specification excludes.\n * @returns A `PropertySyntax` accepting exactly `name`.\n * @throws `Error` when `name` is empty or a CSS-wide keyword.\n * @since 0.1.0\n */\nexport const keyword: <const K extends string>(name: K) => PropertySyntax<K> = internal.keyword\n\n/**\n * A keyword set: shorthand for `oneOf` over `keyword` values, accepting\n * — and narrowing `initialValue` to — exactly the given identifiers. A\n * single name is just that `keyword`.\n *\n * @param names - One or more identifiers, each under `keyword`'s constraints.\n * @returns A `PropertySyntax` accepting exactly the given names.\n * @throws `Error` when a name is empty or a CSS-wide keyword.\n * @example\n * ```ts\n * const size = PropertySyntax.keywords('small', 'medium', 'large')\n * PropertySyntax.render(size) // 'small | medium | large'\n * PropertyRule.make('--size', size, 'medium') // initialValue checks against the three names\n * ```\n * @since 0.1.0\n */\nexport const keywords: <const Names extends readonly [string, ...ReadonlyArray<string>]>(\n ...names: Names\n) => PropertySyntax<Names[number]> = internal.keywords\n\n/**\n * A `|` combination: the value may satisfy any one of the components,\n * tried in order — authored order is preserved (it is parse order, so\n * `'<length> | auto'` and `'auto | <length>'` are different syntaxes).\n * Nested combinations flatten into the enclosing one.\n *\n * @param components - Two or more components. The universal syntax stands alone and may not join a combination.\n * @returns A `PropertySyntax` accepting any component's values, unioned in `V`.\n * @throws `Error` when a component is the universal syntax.\n * @example\n * ```ts\n * const size = PropertySyntax.oneOf(PropertySyntax.keyword('small'), PropertySyntax.keyword('large'))\n * PropertySyntax.render(size) // 'small | large'\n * PropertyRule.make('--size', size, 'small') // initialValue is 'small' | 'large' only\n * ```\n * @since 0.1.0\n */\nexport const oneOf: <\n const Components extends readonly [\n PropertySyntax<unknown>,\n PropertySyntax<unknown>,\n ...ReadonlyArray<PropertySyntax<unknown>>,\n ],\n>(\n ...components: Components\n) => PropertySyntax<ValueOf<Components[number]>> = internal.oneOf\n\n/**\n * A space-separated list of one component, rendered with the `+`\n * multiplier (`'<length>+'`).\n *\n * A one-item list is valid, so the component's own value forms stay\n * accepted; longer lists are literal text.\n *\n * @param component - The repeated component. Must be a single unmultiplied component — not the universal syntax, a combination, a list, or the pre-multiplied `transformList`.\n * @returns A `PropertySyntax` accepting the component's values or list text.\n * @throws `Error` when the component cannot take a multiplier.\n * @since 0.1.0\n */\nexport const listOf: <V>(component: PropertySyntax<V>) => PropertySyntax<V | (string & {})> =\n internal.listOf\n\n/**\n * A comma-separated list of one component, rendered with the `#`\n * multiplier (`'<color>#'`). Constraints match `listOf`.\n *\n * @param component - The repeated component. Must be a single unmultiplied component — not the universal syntax, a combination, a list, or the pre-multiplied `transformList`.\n * @returns A `PropertySyntax` accepting the component's values or list text.\n * @throws `Error` when the component cannot take a multiplier.\n * @since 0.1.0\n */\nexport const commaListOf: <V>(component: PropertySyntax<V>) => PropertySyntax<V | (string & {})> =\n internal.commaListOf\n\n/**\n * Renders the syntax as its descriptor string, unquoted: `'*'`,\n * `'<number>'`, `'<length>+'`, `'small | large'`. `PropertyRule.render`\n * wraps this in the quotes the descriptor requires.\n *\n * @param syntax - The syntax to render.\n * @returns Deterministic descriptor text.\n * @since 0.1.0\n */\nexport const render: (syntax: PropertySyntax) => string = internal.render\n\nexport const equals: {\n /**\n * Returns a function that checks structural equality against `that`.\n *\n * @param that - The syntax to compare against.\n * @returns A function testing its argument for structural equality with `that`.\n * @since 0.1.0\n */\n (that: PropertySyntax): (self: PropertySyntax) => boolean\n /**\n * Structural equality over the modeled grammar. Combination order\n * participates — it is parse order.\n *\n * @param self - The first syntax.\n * @param that - The second syntax.\n * @returns `true` if the syntaxes are structurally equal.\n * @since 0.1.0\n */\n (self: PropertySyntax, that: PropertySyntax): boolean\n} = internal.equals\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAoFA,MAAa,iBAAoDA;AAEjE,MAAa,OA6CTC;;;;;;;;;;;;;;;AAgBJ,MAAa,cAAoDC;;;;;;;;;;;;;;;AAgBjE,MAAaC,WAAkEC;AAE/E,MAAaC,WAqBTC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC7HJ,MAAa,mBAAwDC;;;;;;;AAmBrE,MAAa,YAAuBC;;;;;;;AAQpC,MAAa,QAAgCC;;;;;;;AAQ7C,MAAa,QAA+CC;;;;;;;;AAS5D,MAAa,cAAsCC;;;;;;AAOnD,MAAa,QAAgCC;;;;;;;;AAS7C,MAAa,UAAgDC;;;;;;;AAQ7D,MAAa,SAAiCC;;;;;;AAO9C,MAAa,mBAA2CC;;;;;;;;AASxD,MAAa,SAA+CC;;;;;;;AAQ5D,MAAa,aAAqCC;;;;;;AAOlD,MAAa,aAAqCC;;;;;;;AAQlD,MAAa,SAAiCC;;;;;;;AAQ9C,MAAa,OAA+BC;;;;;;AAO5C,MAAa,oBAA4CC;;;;;;;;AASzD,MAAa,gBAAwCC;;;;;;AAOrD,MAAa,MAA8BC;;;;;;;;;;;;;AAc3C,MAAa,UAAkEC;;;;;;;;;;;;;;;;;AAkB/E,MAAa,WAEwBC;;;;;;;;;;;;;;;;;;AAmBrC,MAAa,QAQsCC;;;;;;;;;;;;;AAcnD,MAAa,SACXC;;;;;;;;;;AAWF,MAAa,cACXC;;;;;;;;;;AAWF,MAAa,SAA6CC;AAE1D,MAAa,SAmBTC"}
1
+ {"version":3,"file":"index.mjs","names":["internal.isPropertyRule","internal.make","internal.inheritable","render","internal.render","equals","internal.equals","internal.isPropertySyntax","internal.universal","internal.angle","internal.color","internal.customIdent","internal.image","internal.integer","internal.length","internal.lengthPercentage","internal.number","internal.percentage","internal.resolution","internal.string","internal.time","internal.transformFunction","internal.transformList","internal.url","internal.keyword","internal.keywords","internal.oneOf","internal.listOf","internal.commaListOf","internal.render","internal.equals"],"sources":["../../src/property/propertyRule.ts","../../src/property/propertySyntax.ts"],"sourcesContent":["import type { Calc, Kind } from '#calc/calc'\nimport type { Color } from '#data/color'\nimport type { RenderOptions as DeclarationRenderOptions } from '#declaration/declaration'\nimport type { Pipeable } from '#util'\nimport type { PropertyRuleTypeId } from './propertyRule.internal.ts'\nimport * as internal from './propertyRule.internal.ts'\nimport type { PropertySyntax, Universal } from './propertySyntax.ts'\n\n/**\n * An `@property` rule: the registration that gives a custom property a\n * syntax, an inheritance behavior, and an initial value.\n *\n * A declaration-block at-rule lives at the top level of a stylesheet —\n * it is deliberately not a rule-block member, so it cannot nest.\n *\n * The registration is what turns a custom property into a typed,\n * animatable channel; a computed-property chain pairs one of these with\n * a `Declaration` writing the property and `Calc.ref` reads downstream.\n *\n * Construct via `make`.\n *\n * @since 0.1.0\n */\nexport interface PropertyRule extends Pipeable {\n readonly [PropertyRuleTypeId]: PropertyRuleTypeId\n /**\n * The registered custom property name, `--` prefix included.\n */\n readonly name: `--${string}`\n /**\n * The modeled `syntax` descriptor; `render` emits it single-quoted.\n */\n readonly syntax: PropertySyntax\n /**\n * The `inherits` descriptor. `make` registers `false`; `inheritable`\n * flips it.\n */\n readonly inherits: boolean\n /**\n * The `initial-value` descriptor: literal text or a closed expression.\n * Absent only under the universal syntax.\n */\n readonly initialValue: Value | undefined\n}\n\n/**\n * The value forms an `initial-value` descriptor can hold once\n * constructed. The closed (`never`-ref) parameter is the spec rule in the\n * types: `@property` initial values must be computationally independent, so\n * only closed expressions — no unbound references — are accepted. A `Calc`\n * of any dimension is admitted here; `make` narrows to the forms the declared\n * syntax accepts (the syntax's `V` parameter), where a `<length>` is limited\n * to absolute units.\n *\n * @since 0.1.0\n */\nexport type Value = string | Calc<never, Kind, unknown> | Color<never>\n\n/**\n * Options for `render`, in the render-options family rooted at\n * `MediaQuery.RenderOptions` (via `Declaration.RenderOptions`). This\n * renderer consumes `indent` and the inherited `precision` (for an\n * expression-valued `initial-value`); `mediaSyntax` is accepted and\n * ignored.\n *\n * @since 0.1.0\n */\nexport interface RenderOptions extends DeclarationRenderOptions {\n /**\n * The indentation unit for the block's declarations. Defaults to a tab.\n */\n readonly indent?: string\n}\n\n/**\n * Checks if a value is a `PropertyRule`.\n *\n * True only for values built by this module's constructors, which carry\n * the brand.\n *\n * @param u - The value to check.\n * @returns `true` if the value is a `PropertyRule`, `false` otherwise.\n * @since 0.1.0\n */\nexport const isPropertyRule: (u: unknown) => u is PropertyRule = internal.isPropertyRule\n\nexport const make: {\n /**\n * Registers under the universal syntax — the default when `syntax` is\n * omitted — where the initial value is optional.\n *\n * @param name - The custom property name to register, `--` prefix included.\n * @param syntax - The universal syntax; omit for the same effect.\n * @param initialValue - Optional under the universal syntax: any value form.\n * @returns A `PropertyRule` with `inherits: false`.\n * @throws `Error` when `name` is not a `--`-prefixed custom property name (bare `--` included), or an expression value has unbound references.\n * @since 0.1.0\n */\n (name: `--${string}`, syntax?: Universal, initialValue?: Value | number): PropertyRule\n /**\n * Creates an `@property` rule.\n *\n * The syntax value types the initial value: only forms the syntax\n * accepts are admitted — numbers and closed `Calc` expressions under\n * `PropertySyntax.number`, exactly the declared literals under a\n * keyword set, and so on — and the computational-independence rule\n * rides along, since an expression with unbound references is not a\n * `Calc<never>` (backed by a runtime check for untyped callers). Bare\n * numbers coerce to unannotated constants. That literal-text values\n * parse under the syntax is not checked — this library does not parse\n * CSS.\n *\n * Rules register with `inherits: false`; pipe through `inheritable` to\n * opt in.\n *\n * @param name - The custom property name to register, `--` prefix included.\n * @param syntax - The modeled `syntax` descriptor; see `PropertySyntax`.\n * @param initialValue - The `initial-value` descriptor, required for every non-universal syntax and typed by it.\n * @returns A `PropertyRule` with `inherits: false`.\n * @throws `Error` when `name` is not a `--`-prefixed custom property name (bare `--` included), `initialValue` is missing under a non-universal syntax, or an expression value has unbound references.\n * @example\n * ```ts\n * PropertyRule.make('--depth', PropertySyntax.number, 0)\n * ```\n * @since 0.1.0\n */\n <V extends Value | number>(\n name: `--${string}`,\n syntax: PropertySyntax<V>,\n initialValue: NoInfer<V>,\n ): PropertyRule\n} = internal.make\n\n/**\n * Registers the rule as inheriting. `make` constructs every rule with\n * `inherits: false` — the safe default for computed channels, where\n * inheritance would leak intermediate values down the tree — so\n * inheritance is an explicit opt-in.\n *\n * @param rule - The rule to opt in.\n * @returns The inheriting rule; the same rule when it already inherits.\n * @example\n * ```ts\n * PropertyRule.make('--fill', PropertySyntax.color, 'red').pipe(PropertyRule.inheritable)\n * ```\n * @since 0.1.0\n */\nexport const inheritable: (rule: PropertyRule) => PropertyRule = internal.inheritable\n\n/**\n * Renders the rule as a complete `@property --name { ... }` block, the\n * descriptors in fixed order: `syntax`, `inherits`, `initial-value`.\n *\n * @param rule - The rule to render.\n * @param options - Optional indentation unit and precision context.\n * @returns Deterministic CSS text.\n * @example\n * ```ts\n * PropertyRule.render(PropertyRule.make('--depth', PropertySyntax.number, 0))\n * // \"@property --depth {\\n\\tsyntax: '<number>';\\n\\tinherits: false;\\n\\tinitial-value: 0;\\n}\"\n * ```\n * @since 0.1.0\n */\nexport const render: (rule: PropertyRule, options?: RenderOptions) => string = internal.render\n\nexport const equals: {\n /**\n * Returns a function that checks structural equality against `that`.\n *\n * @param that - The rule to compare against.\n * @returns A function testing its argument for structural equality with `that`.\n * @since 0.1.0\n */\n (that: PropertyRule): (self: PropertyRule) => boolean\n /**\n * Structural equality: `name` and `inherits` compare as data, the\n * syntax as its modeled grammar (`PropertySyntax.equals` semantics),\n * and expression initial values as expression trees (`Calc.equals`\n * semantics). Literal text never equals an expression.\n *\n * @param self - The first rule.\n * @param that - The second rule.\n * @returns `true` if the rules are structurally equal.\n * @since 0.1.0\n */\n (self: PropertyRule, that: PropertyRule): boolean\n} = internal.equals\n","import type { Calc, Kind } from '#calc/calc'\nimport type { Color } from '#data/color'\nimport type { AbsoluteLength, Angle, Percentage } from '#data/units'\nimport type { Pipeable } from '#util'\nimport type { PropertySyntaxTypeId } from './propertySyntax.internal.ts'\nimport * as internal from './propertySyntax.internal.ts'\n\ndeclare const AcceptedValue: unique symbol\ndeclare const UniversalMarker: unique symbol\n\n/**\n * A modeled `@property` syntax descriptor: the universal syntax, a data\n * type, a keyword, a multiplied list, or a `|` combination of these.\n *\n * The point of modeling the descriptor as a value is twofold. The\n * supported grammar becomes discoverable — the data types are constants\n * (`number`, `color`, `lengthPercentage`, ...), and the combinators\n * (`keyword`, `oneOf`, `listOf`, `commaListOf`) enforce the grammar's\n * constraints at construction. And the `V` parameter tracks the\n * initial-value forms the syntax accepts, so `PropertyRule.make` can\n * type its `initialValue` from the syntax it is registered under.\n *\n * Construct via the data type constants, `universal`, `keyword`,\n * `keywords`, `oneOf`, `listOf`, and `commaListOf`.\n *\n * @since 0.1.0\n */\nexport interface PropertySyntax<out V = Value> extends Pipeable {\n readonly [PropertySyntaxTypeId]: PropertySyntaxTypeId\n readonly [AcceptedValue]?: V\n}\n\n/**\n * The full initial-value domain — what the universal syntax accepts.\n * Individual syntaxes narrow this: number-land syntaxes take numbers and\n * closed `Calc` expressions, dimensioned syntaxes take a closed `Calc` of\n * their kind (a `<length>` initial value must be computationally independent,\n * so only absolute units), `color` takes closed `Color` expressions or text,\n * keyword sets take exactly their literals, and the rest take literal text.\n *\n * @since 0.1.0\n */\nexport type Value = string | number | Calc<never, Kind, unknown> | Color<never>\n\n/**\n * The initial-value forms a syntax accepts — the type-level counterpart\n * of the `V` parameter, extracted from a syntax (or union of syntaxes).\n *\n * @since 0.1.0\n */\nexport type ValueOf<S extends PropertySyntax<unknown>> =\n S extends PropertySyntax<infer V> ? V : never\n\n/**\n * Checks if a value is a `PropertySyntax`.\n *\n * True only for values built by this module's constructors, which carry\n * the brand.\n *\n * @param u - The value to check.\n * @returns `true` if the value is a `PropertySyntax`, `false` otherwise.\n * @since 0.1.0\n */\nexport const isPropertySyntax: (u: unknown) => u is PropertySyntax = internal.isPropertySyntax\n\n/**\n * The type of `universal` alone. Naming it lets `PropertyRule.make`\n * recognize the universal syntax in overload resolution — the one syntax\n * under which the initial value is optional.\n *\n * @since 0.1.0\n */\nexport interface Universal extends PropertySyntax<Value> {\n readonly [UniversalMarker]: true\n}\n\n/**\n * The universal syntax, `*` — any value at all. The one syntax under\n * which `@property` may omit its initial value.\n *\n * @since 0.1.0\n */\nexport const universal: Universal = internal.universal\n\n/**\n * The `<angle>` data type. Initial values are a closed angle-kind `Calc`\n * (`Angle.rad(...)`) or literal text carrying an angle unit (`'90deg'`).\n *\n * @since 0.1.0\n */\nexport const angle: PropertySyntax<string | Calc<never, 'angle', Angle>> = internal.angle\n\n/**\n * The `<color>` data type. Initial values are closed `Color` expressions\n * or literal text (`'transparent'`, `'#fff'`).\n *\n * @since 0.1.0\n */\nexport const color: PropertySyntax<string | Color<never>> = internal.color\n\n/**\n * The `<custom-ident>` data type — any custom identifier. To accept a\n * fixed set of identifiers instead, combine `keyword` values with\n * `oneOf`.\n *\n * @since 0.1.0\n */\nexport const customIdent: PropertySyntax<string> = internal.customIdent\n\n/**\n * The `<image>` data type. Initial values are literal text.\n *\n * @since 0.1.0\n */\nexport const image: PropertySyntax<string> = internal.image\n\n/**\n * The `<integer>` data type. Initial values are numbers or closed `Calc`\n * expressions; that the value is a whole number is the browser's parse\n * check, not this library's.\n *\n * @since 0.1.0\n */\nexport const integer: PropertySyntax<number | Calc<never>> = internal.integer\n\n/**\n * The `<length>` data type. Initial values are a closed length-kind `Calc`\n * (`Length.px(8)`) or literal text carrying a length unit (`'8px'` — a bare\n * `0` is not a valid registered length). An `@property` initial value must be\n * computationally independent, so an expression may carry only absolute units\n * (`px`) — a viewport- or font-relative length (`Length.vw(8)`) is rejected.\n *\n * @since 0.1.0\n */\nexport const length: PropertySyntax<string | Calc<never, 'length', AbsoluteLength>> =\n internal.length\n\n/**\n * The `<length-percentage>` data type. Initial values are a closed\n * absolute-length or percentage `Calc`, or literal text.\n *\n * @since 0.1.0\n */\nexport const lengthPercentage: PropertySyntax<\n string | Calc<never, 'length', AbsoluteLength> | Calc<never, 'percentage', Percentage>\n> = internal.lengthPercentage\n\n/**\n * The `<number>` data type. Initial values are numbers or closed `Calc`\n * expressions — the typed channel this library models; text is not\n * accepted where the number form exists.\n *\n * @since 0.1.0\n */\nexport const number: PropertySyntax<number | Calc<never>> = internal.number\n\n/**\n * The `<percentage>` data type. Initial values are a closed percentage-kind\n * `Calc` (`Percentage.of(50)`) or literal text carrying the `%` unit (`'50%'`).\n *\n * @since 0.1.0\n */\nexport const percentage: PropertySyntax<string | Calc<never, 'percentage', Percentage>> =\n internal.percentage\n\n/**\n * The `<resolution>` data type. Initial values are literal text.\n *\n * @since 0.1.0\n */\nexport const resolution: PropertySyntax<string> = internal.resolution\n\n/**\n * The `<string>` data type. Initial values are literal text including\n * their own quotes (`'\"hello\"'`).\n *\n * @since 0.1.0\n */\nexport const string: PropertySyntax<string> = internal.string\n\n/**\n * The `<time>` data type. Initial values are literal text carrying a\n * time unit (`'200ms'`).\n *\n * @since 0.1.0\n */\nexport const time: PropertySyntax<string> = internal.time\n\n/**\n * The `<transform-function>` data type. Initial values are literal text.\n *\n * @since 0.1.0\n */\nexport const transformFunction: PropertySyntax<string> = internal.transformFunction\n\n/**\n * The `<transform-list>` data type — a list of transform functions. It\n * is pre-multiplied, so `listOf`/`commaListOf` reject it. Initial values\n * are literal text.\n *\n * @since 0.1.0\n */\nexport const transformList: PropertySyntax<string> = internal.transformList\n\n/**\n * The `<url>` data type. Initial values are literal text.\n *\n * @since 0.1.0\n */\nexport const url: PropertySyntax<string> = internal.url\n\n/**\n * A keyword component: one specific custom identifier, rendered bare.\n * Combined under `oneOf`, keywords give the registered property an\n * enum-like domain — and the `V` parameter carries the literal, so\n * `initialValue` autocompletes and checks against exactly the declared\n * set.\n *\n * @param name - The identifier. Must be non-empty and not a CSS-wide keyword (`inherit`, `initial`, `unset`, `revert`, `revert-layer`, `default`), which the specification excludes.\n * @returns A `PropertySyntax` accepting exactly `name`.\n * @throws `Error` when `name` is empty or a CSS-wide keyword.\n * @since 0.1.0\n */\nexport const keyword: <const K extends string>(name: K) => PropertySyntax<K> = internal.keyword\n\n/**\n * A keyword set: shorthand for `oneOf` over `keyword` values, accepting\n * — and narrowing `initialValue` to — exactly the given identifiers. A\n * single name is just that `keyword`.\n *\n * @param names - One or more identifiers, each under `keyword`'s constraints.\n * @returns A `PropertySyntax` accepting exactly the given names.\n * @throws `Error` when a name is empty or a CSS-wide keyword.\n * @example\n * ```ts\n * const size = PropertySyntax.keywords('small', 'medium', 'large')\n * PropertySyntax.render(size) // 'small | medium | large'\n * PropertyRule.make('--size', size, 'medium') // initialValue checks against the three names\n * ```\n * @since 0.1.0\n */\nexport const keywords: <const Names extends readonly [string, ...ReadonlyArray<string>]>(\n ...names: Names\n) => PropertySyntax<Names[number]> = internal.keywords\n\n/**\n * A `|` combination: the value may satisfy any one of the components,\n * tried in order — authored order is preserved (it is parse order, so\n * `'<length> | auto'` and `'auto | <length>'` are different syntaxes).\n * Nested combinations flatten into the enclosing one.\n *\n * @param components - Two or more components. The universal syntax stands alone and may not join a combination.\n * @returns A `PropertySyntax` accepting any component's values, unioned in `V`.\n * @throws `Error` when a component is the universal syntax.\n * @example\n * ```ts\n * const size = PropertySyntax.oneOf(PropertySyntax.keyword('small'), PropertySyntax.keyword('large'))\n * PropertySyntax.render(size) // 'small | large'\n * PropertyRule.make('--size', size, 'small') // initialValue is 'small' | 'large' only\n * ```\n * @since 0.1.0\n */\nexport const oneOf: <\n const Components extends readonly [\n PropertySyntax<unknown>,\n PropertySyntax<unknown>,\n ...ReadonlyArray<PropertySyntax<unknown>>,\n ],\n>(\n ...components: Components\n) => PropertySyntax<ValueOf<Components[number]>> = internal.oneOf\n\n/**\n * A space-separated list of one component, rendered with the `+`\n * multiplier (`'<length>+'`).\n *\n * A one-item list is valid, so the component's own value forms stay\n * accepted; longer lists are literal text.\n *\n * @param component - The repeated component. Must be a single unmultiplied component — not the universal syntax, a combination, a list, or the pre-multiplied `transformList`.\n * @returns A `PropertySyntax` accepting the component's values or list text.\n * @throws `Error` when the component cannot take a multiplier.\n * @since 0.1.0\n */\nexport const listOf: <V>(component: PropertySyntax<V>) => PropertySyntax<V | (string & {})> =\n internal.listOf\n\n/**\n * A comma-separated list of one component, rendered with the `#`\n * multiplier (`'<color>#'`). Constraints match `listOf`.\n *\n * @param component - The repeated component. Must be a single unmultiplied component — not the universal syntax, a combination, a list, or the pre-multiplied `transformList`.\n * @returns A `PropertySyntax` accepting the component's values or list text.\n * @throws `Error` when the component cannot take a multiplier.\n * @since 0.1.0\n */\nexport const commaListOf: <V>(component: PropertySyntax<V>) => PropertySyntax<V | (string & {})> =\n internal.commaListOf\n\n/**\n * Renders the syntax as its descriptor string, unquoted: `'*'`,\n * `'<number>'`, `'<length>+'`, `'small | large'`. `PropertyRule.render`\n * wraps this in the quotes the descriptor requires.\n *\n * @param syntax - The syntax to render.\n * @returns Deterministic descriptor text.\n * @since 0.1.0\n */\nexport const render: (syntax: PropertySyntax) => string = internal.render\n\nexport const equals: {\n /**\n * Returns a function that checks structural equality against `that`.\n *\n * @param that - The syntax to compare against.\n * @returns A function testing its argument for structural equality with `that`.\n * @since 0.1.0\n */\n (that: PropertySyntax): (self: PropertySyntax) => boolean\n /**\n * Structural equality over the modeled grammar. Combination order\n * participates — it is parse order.\n *\n * @param self - The first syntax.\n * @param that - The second syntax.\n * @returns `true` if the syntaxes are structurally equal.\n * @since 0.1.0\n */\n (self: PropertySyntax, that: PropertySyntax): boolean\n} = internal.equals\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAoFA,MAAa,iBAAoDA;AAEjE,MAAa,OA6CTC;;;;;;;;;;;;;;;AAgBJ,MAAa,cAAoDC;;;;;;;;;;;;;;;AAgBjE,MAAaC,WAAkEC;AAE/E,MAAaC,WAqBTC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC3HJ,MAAa,mBAAwDC;;;;;;;AAmBrE,MAAa,YAAuBC;;;;;;;AAQpC,MAAa,QAA8DC;;;;;;;AAQ3E,MAAa,QAA+CC;;;;;;;;AAS5D,MAAa,cAAsCC;;;;;;AAOnD,MAAa,QAAgCC;;;;;;;;AAS7C,MAAa,UAAgDC;;;;;;;;;;AAW7D,MAAa,SACXC;;;;;;;AAQF,MAAa,mBAETC;;;;;;;;AASJ,MAAa,SAA+CC;;;;;;;AAQ5D,MAAa,aACXC;;;;;;AAOF,MAAa,aAAqCC;;;;;;;AAQlD,MAAa,SAAiCC;;;;;;;AAQ9C,MAAa,OAA+BC;;;;;;AAO5C,MAAa,oBAA4CC;;;;;;;;AASzD,MAAa,gBAAwCC;;;;;;AAOrD,MAAa,MAA8BC;;;;;;;;;;;;;AAc3C,MAAa,UAAkEC;;;;;;;;;;;;;;;;;AAkB/E,MAAa,WAEwBC;;;;;;;;;;;;;;;;;;AAmBrC,MAAa,QAQsCC;;;;;;;;;;;;;AAcnD,MAAa,SACXC;;;;;;;;;;AAWF,MAAa,cACXC;;;;;;;;;;AAWF,MAAa,SAA6CC;AAE1D,MAAa,SAmBTC"}
@@ -0,0 +1,2 @@
1
+ import { r as mediaQuery_d_exports } from "../shared/mediaQuery-BYR1z-iD.mjs";
2
+ export { mediaQuery_d_exports as MediaQuery };
@@ -1,5 +1,5 @@
1
- import { c as __exportAll } from "../shared/equal-C96LR7p4.mjs";
2
- import { a as prefersColorScheme$1, i as minWidth$1, n as equals$1, o as render$1, r as isMediaQuery$1, t as and$1 } from "../shared/mediaQuery.internal-BZF1beZO.mjs";
1
+ import { t as __exportAll } from "../shared/rolldown-runtime-D7D4PA-g.mjs";
2
+ import { a as prefersColorScheme$1, i as minWidth$1, n as equals$1, o as render$1, r as isMediaQuery$1, t as and$1 } from "../shared/mediaQuery.internal-B6iuMd75.mjs";
3
3
  //#region src/query/mediaQuery.ts
4
4
  var mediaQuery_exports = /* @__PURE__ */ __exportAll({
5
5
  and: () => and,
@@ -44,9 +44,10 @@ const minWidth = minWidth$1;
44
44
  const prefersColorScheme = prefersColorScheme$1;
45
45
  const and = and$1;
46
46
  /**
47
- * Renders the query as CSS text: features in canonical order, joined
48
- * with ` and `. The `mediaSyntax` option picks the width-feature
49
- * spelling (default `'prefix'`).
47
+ * Renders the query as CSS text: features in canonical order
48
+ * `min-width` ascending, then `prefers-color-scheme` joined with
49
+ * ` and `. The `mediaSyntax` option picks the width-feature spelling
50
+ * (default `'prefix'`).
50
51
  *
51
52
  * @param query - The query to render.
52
53
  * @param options - Optional syntax selection.
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":["internal.isMediaQuery","internal.minWidth","internal.prefersColorScheme","internal.and","internal.render","internal.equals"],"sources":["../../src/query/mediaQuery.ts"],"sourcesContent":["import type { Pipeable } from '#util'\nimport type { MediaQueryTypeId } from './mediaQuery.internal.ts'\nimport * as internal from './mediaQuery.internal.ts'\n\n/**\n * A media query: a canonically ordered, deduplicated and-set of media\n * features.\n *\n * Feature constructors (`minWidth`, `prefersColorScheme`) return\n * one-feature queries; `and` merges. Conjunction is commutative and\n * idempotent, so construction sorts features canonically and drops exact\n * duplicates — structurally equal queries compare equal however they\n * were built. Distinct features always all render, even when one\n * subsumes another (`minWidth(768)` and `minWidth(1024)`): simplification\n * changes no meaning but is not this type's job.\n *\n * `or` and `not` become new node kinds when a consumer needs them.\n *\n * @since 0.1.0\n */\nexport interface MediaQuery extends Pipeable {\n readonly [MediaQueryTypeId]: MediaQueryTypeId\n}\n\n/**\n * Options for `render` — and the base of the library's render-options\n * family: every other module's `RenderOptions` extends this interface\n * (directly or through `Declaration.RenderOptions` and\n * `RuleSet.RenderOptions`), so an options object built for a bigger\n * renderer is accepted by every smaller one. A key means the same thing\n * wherever it appears; renderers ignore inherited keys that don't apply\n * to them.\n *\n * @since 0.1.0\n */\nexport interface RenderOptions {\n /**\n * The width-feature spelling: classic prefix syntax\n * (`(min-width: 768px)`, the default) or modern range syntax\n * (`(width >= 768px)`). Text only — the model is semantic and the two\n * spellings mean the same thing.\n */\n readonly mediaSyntax?: 'prefix' | 'range'\n}\n\n/**\n * Checks if a value is a `MediaQuery`.\n *\n * True only for values built by this module's constructors, which carry\n * the brand.\n *\n * @param u - The value to check.\n * @returns `true` if the value is a `MediaQuery`, `false` otherwise.\n * @since 0.1.0\n */\nexport const isMediaQuery: (u: unknown) => u is MediaQuery = internal.isMediaQuery\n\n/**\n * Creates a viewport-width lower bound.\n *\n * @param px - The threshold in CSS pixels. Must be a non-negative finite number.\n * @returns A one-feature `MediaQuery`.\n * @throws `Error` when `px` is negative or not finite.\n * @example\n * ```ts\n * MediaQuery.render(MediaQuery.minWidth(768)) // '(min-width: 768px)'\n * MediaQuery.render(MediaQuery.minWidth(768), { mediaSyntax: 'range' }) // '(width >= 768px)'\n * ```\n * @since 0.1.0\n */\nexport const minWidth: (px: number) => MediaQuery = internal.minWidth\n\n/**\n * Creates a `prefers-color-scheme` condition.\n *\n * @param scheme - The scheme to match, `'dark'` or `'light'`.\n * @returns A one-feature `MediaQuery`.\n * @since 0.1.0\n */\nexport const prefersColorScheme: (scheme: 'dark' | 'light') => MediaQuery =\n internal.prefersColorScheme\n\nexport const and: {\n /**\n * Returns a function that conjoins `that` with its argument.\n *\n * @param that - The query to merge in.\n * @returns A function producing the conjunction.\n * @since 0.1.0\n */\n (that: MediaQuery): (self: MediaQuery) => MediaQuery\n /**\n * Conjoins two queries: the result matches where both match. Features\n * re-sort into canonical order and exact duplicates collapse, so `and`\n * is commutative and idempotent.\n *\n * @param self - The first query.\n * @param that - The second query.\n * @returns The conjunction.\n * @example\n * ```ts\n * MediaQuery.minWidth(1280).pipe(\n * MediaQuery.and(MediaQuery.prefersColorScheme('dark')),\n * MediaQuery.render,\n * ) // '(min-width: 1280px) and (prefers-color-scheme: dark)'\n * ```\n * @since 0.1.0\n */\n (self: MediaQuery, that: MediaQuery): MediaQuery\n} = internal.and\n\n/**\n * Renders the query as CSS text: features in canonical order, joined\n * with ` and `. The `mediaSyntax` option picks the width-feature\n * spelling (default `'prefix'`).\n *\n * @param query - The query to render.\n * @param options - Optional syntax selection.\n * @returns Deterministic CSS text, without the `@media ` prefix.\n * @since 0.1.0\n */\nexport const render: (query: MediaQuery, options?: RenderOptions) => string = internal.render\n\nexport const equals: {\n /**\n * Returns a function that checks structural equality against `that`.\n *\n * @param that - The query to compare against.\n * @returns A function testing its argument for structural equality with `that`.\n * @since 0.1.0\n */\n (that: MediaQuery): (self: MediaQuery) => boolean\n /**\n * Structural equality over canonically ordered features: two queries\n * built from the same conditions compare equal regardless of\n * construction order.\n *\n * @param self - The first query.\n * @param that - The second query.\n * @returns `true` if the queries are structurally equal.\n * @since 0.1.0\n */\n (self: MediaQuery, that: MediaQuery): boolean\n} = internal.equals\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAuDA,MAAa,eAAgDA;;;;;;;;;;;;;;AAe7D,MAAa,WAAuCC;;;;;;;;AASpD,MAAa,qBACXC;AAEF,MAAa,MA2BTC;;;;;;;;;;;AAYJ,MAAa,SAAiEC;AAE9E,MAAa,SAoBTC"}
1
+ {"version":3,"file":"index.mjs","names":["internal.isMediaQuery","internal.minWidth","internal.prefersColorScheme","internal.and","internal.render","internal.equals"],"sources":["../../src/query/mediaQuery.ts"],"sourcesContent":["import type { Pipeable } from '#util'\nimport type { MediaQueryTypeId } from './mediaQuery.internal.ts'\nimport * as internal from './mediaQuery.internal.ts'\n\n/**\n * A media query: a canonically ordered, deduplicated and-set of media\n * features.\n *\n * Feature constructors (`minWidth`, `prefersColorScheme`) return\n * one-feature queries; `and` merges. Conjunction is commutative and\n * idempotent, so construction sorts features canonically and drops exact\n * duplicates — structurally equal queries compare equal however they\n * were built. The canonical order is stable public API: `min-width`\n * features first (ascending by threshold), then `prefers-color-scheme`\n * (schemes alphabetically). Distinct features always all render, even\n * when one subsumes another (`minWidth(768)` and `minWidth(1024)`):\n * simplification changes no meaning but is not this type's job.\n *\n * `or` and `not` become new node kinds when a consumer needs them.\n *\n * @since 0.1.0\n */\nexport interface MediaQuery extends Pipeable {\n readonly [MediaQueryTypeId]: MediaQueryTypeId\n}\n\n/**\n * Options for `render` — and the base of the library's render-options\n * family: every other module's `RenderOptions` extends this interface\n * (directly or through `Declaration.RenderOptions` and\n * `RuleSet.RenderOptions`), so an options object built for a bigger\n * renderer is accepted by every smaller one. A key means the same thing\n * wherever it appears; renderers ignore inherited keys that don't apply\n * to them.\n *\n * @since 0.1.0\n */\nexport interface RenderOptions {\n /**\n * The width-feature spelling: classic prefix syntax\n * (`(min-width: 768px)`, the default) or modern range syntax\n * (`(width >= 768px)`). Text only — the model is semantic and the two\n * spellings mean the same thing.\n */\n readonly mediaSyntax?: 'prefix' | 'range'\n}\n\n/**\n * Checks if a value is a `MediaQuery`.\n *\n * True only for values built by this module's constructors, which carry\n * the brand.\n *\n * @param u - The value to check.\n * @returns `true` if the value is a `MediaQuery`, `false` otherwise.\n * @since 0.1.0\n */\nexport const isMediaQuery: (u: unknown) => u is MediaQuery = internal.isMediaQuery\n\n/**\n * Creates a viewport-width lower bound.\n *\n * @param px - The threshold in CSS pixels. Must be a non-negative finite number.\n * @returns A one-feature `MediaQuery`.\n * @throws `Error` when `px` is negative or not finite.\n * @example\n * ```ts\n * MediaQuery.render(MediaQuery.minWidth(768)) // '(min-width: 768px)'\n * MediaQuery.render(MediaQuery.minWidth(768), { mediaSyntax: 'range' }) // '(width >= 768px)'\n * ```\n * @since 0.1.0\n */\nexport const minWidth: (px: number) => MediaQuery = internal.minWidth\n\n/**\n * Creates a `prefers-color-scheme` condition.\n *\n * @param scheme - The scheme to match, `'dark'` or `'light'`.\n * @returns A one-feature `MediaQuery`.\n * @since 0.1.0\n */\nexport const prefersColorScheme: (scheme: 'dark' | 'light') => MediaQuery =\n internal.prefersColorScheme\n\nexport const and: {\n /**\n * Returns a function that conjoins `that` with its argument.\n *\n * @param that - The query to merge in.\n * @returns A function producing the conjunction.\n * @since 0.1.0\n */\n (that: MediaQuery): (self: MediaQuery) => MediaQuery\n /**\n * Conjoins two queries: the result matches where both match. Features\n * re-sort into canonical order and exact duplicates collapse, so `and`\n * is commutative and idempotent.\n *\n * @param self - The first query.\n * @param that - The second query.\n * @returns The conjunction.\n * @example\n * ```ts\n * MediaQuery.minWidth(1280).pipe(\n * MediaQuery.and(MediaQuery.prefersColorScheme('dark')),\n * MediaQuery.render,\n * ) // '(min-width: 1280px) and (prefers-color-scheme: dark)'\n * ```\n * @since 0.1.0\n */\n (self: MediaQuery, that: MediaQuery): MediaQuery\n} = internal.and\n\n/**\n * Renders the query as CSS text: features in canonical order —\n * `min-width` ascending, then `prefers-color-scheme` — joined with\n * ` and `. The `mediaSyntax` option picks the width-feature spelling\n * (default `'prefix'`).\n *\n * @param query - The query to render.\n * @param options - Optional syntax selection.\n * @returns Deterministic CSS text, without the `@media ` prefix.\n * @since 0.1.0\n */\nexport const render: (query: MediaQuery, options?: RenderOptions) => string = internal.render\n\nexport const equals: {\n /**\n * Returns a function that checks structural equality against `that`.\n *\n * @param that - The query to compare against.\n * @returns A function testing its argument for structural equality with `that`.\n * @since 0.1.0\n */\n (that: MediaQuery): (self: MediaQuery) => boolean\n /**\n * Structural equality over canonically ordered features: two queries\n * built from the same conditions compare equal regardless of\n * construction order.\n *\n * @param self - The first query.\n * @param that - The second query.\n * @returns `true` if the queries are structurally equal.\n * @since 0.1.0\n */\n (self: MediaQuery, that: MediaQuery): boolean\n} = internal.equals\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAyDA,MAAa,eAAgDA;;;;;;;;;;;;;;AAe7D,MAAa,WAAuCC;;;;;;;;AASpD,MAAa,qBACXC;AAEF,MAAa,MA2BTC;;;;;;;;;;;;AAaJ,MAAa,SAAiEC;AAE9E,MAAa,SAoBTC"}
@@ -0,0 +1,2 @@
1
+ import { i as ruleSet_d_exports, o as styleRule_d_exports, t as mediaRule_d_exports } from "../shared/mediaRule-BDB4WCYy.mjs";
2
+ export { mediaRule_d_exports as MediaRule, ruleSet_d_exports as RuleSet, styleRule_d_exports as StyleRule };
@@ -1,5 +1,5 @@
1
- import { c as __exportAll } from "../shared/equal-C96LR7p4.mjs";
2
- import { _ as refs$3, a as isRuleSet$1, c as render$4, d as make$5, f as refs$5, g as make$3, h as isMediaRule$1, i as equals$4, l as equals$5, m as equals$3, n as concat$1, o as make$4, p as render$5, r as empty$1, s as refs$4, t as append$1, u as isStyleRule$1, v as render$3 } from "../shared/ruleSet.internal-DQjyPgko.mjs";
1
+ import { t as __exportAll } from "../shared/rolldown-runtime-D7D4PA-g.mjs";
2
+ import { _ as equals$3, a as forMediaQuery$1, b as refs$3, c as isRuleSet$1, d as render$4, f as equals$5, g as render$5, h as refs$5, i as equals$4, l as make$4, m as make$5, n as concat$1, o as forSelector$1, p as isStyleRule$1, r as empty$1, s as isEmpty$1, t as append$1, u as refs$4, v as isMediaRule$1, x as render$3, y as make$3 } from "../shared/ruleSet.internal-DodzVMUU.mjs";
3
3
  //#region src/rule/mediaRule.ts
4
4
  var mediaRule_exports = /* @__PURE__ */ __exportAll({
5
5
  equals: () => equals$2,
@@ -75,6 +75,9 @@ var ruleSet_exports = /* @__PURE__ */ __exportAll({
75
75
  concat: () => concat,
76
76
  empty: () => empty,
77
77
  equals: () => equals$1,
78
+ forMediaQuery: () => forMediaQuery,
79
+ forSelector: () => forSelector,
80
+ isEmpty: () => isEmpty,
78
81
  isRuleSet: () => isRuleSet,
79
82
  make: () => make$1,
80
83
  refs: () => refs$1,
@@ -98,6 +101,18 @@ const isRuleSet = isRuleSet$1;
98
101
  */
99
102
  const empty = empty$1;
100
103
  /**
104
+ * Checks if the block has no members.
105
+ *
106
+ * Structural emptiness only: a non-empty block can still *render* as the
107
+ * empty string, when every member is a nested rule whose block renders
108
+ * empty.
109
+ *
110
+ * @param set - The block to inspect.
111
+ * @returns `true` if the block has no members.
112
+ * @since 0.2.0
113
+ */
114
+ const isEmpty = isEmpty$1;
115
+ /**
101
116
  * Creates a rule set holding the given members, in the given order.
102
117
  *
103
118
  * @param members - Declarations and nested rules, in authored order.
@@ -114,6 +129,8 @@ const empty = empty$1;
114
129
  const make$1 = make$4;
115
130
  const append = append$1;
116
131
  const concat = concat$1;
132
+ const forSelector = forSelector$1;
133
+ const forMediaQuery = forMediaQuery$1;
117
134
  /**
118
135
  * The block's unbound reference names, unioned across members —
119
136
  * including everything nested rules contribute.