fashionable 0.0.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 (67) hide show
  1. package/LICENSE.md +21 -0
  2. package/README.md +276 -0
  3. package/dist/calc/index.d.mts +2 -0
  4. package/dist/calc/index.mjs +2 -0
  5. package/dist/data/index.d.mts +208 -0
  6. package/dist/data/index.mjs +696 -0
  7. package/dist/data/index.mjs.map +1 -0
  8. package/dist/declaration/index.d.mts +2 -0
  9. package/dist/declaration/index.mjs +74 -0
  10. package/dist/declaration/index.mjs.map +1 -0
  11. package/dist/fontFace/index.d.mts +2 -0
  12. package/dist/fontFace/index.mjs +102 -0
  13. package/dist/fontFace/index.mjs.map +1 -0
  14. package/dist/property/index.d.mts +2 -0
  15. package/dist/property/index.mjs +293 -0
  16. package/dist/property/index.mjs.map +1 -0
  17. package/dist/query/index.d.mts +2 -0
  18. package/dist/query/index.mjs +62 -0
  19. package/dist/query/index.mjs.map +1 -0
  20. package/dist/rule/index.d.mts +2 -0
  21. package/dist/rule/index.mjs +234 -0
  22. package/dist/rule/index.mjs.map +1 -0
  23. package/dist/selector/index.d.mts +2 -0
  24. package/dist/selector/index.mjs +178 -0
  25. package/dist/selector/index.mjs.map +1 -0
  26. package/dist/shared/calc-Cih4o2r7.mjs +1145 -0
  27. package/dist/shared/calc-Cih4o2r7.mjs.map +1 -0
  28. package/dist/shared/color-BvNJ2YqL.d.mts +590 -0
  29. package/dist/shared/color.internal-Dts5ycTm.mjs +450 -0
  30. package/dist/shared/color.internal-Dts5ycTm.mjs.map +1 -0
  31. package/dist/shared/declaration-1DlO_ltT.d.mts +166 -0
  32. package/dist/shared/declaration.internal-wLB4ssxC.mjs +73 -0
  33. package/dist/shared/declaration.internal-wLB4ssxC.mjs.map +1 -0
  34. package/dist/shared/equal-U9G5LhtL.mjs +71 -0
  35. package/dist/shared/equal-U9G5LhtL.mjs.map +1 -0
  36. package/dist/shared/fontFaceRule-C7nYgH6X.d.mts +294 -0
  37. package/dist/shared/fontFaceRule.internal-D5u48TUO.mjs +214 -0
  38. package/dist/shared/fontFaceRule.internal-D5u48TUO.mjs.map +1 -0
  39. package/dist/shared/format-B9jsmCER.mjs +53 -0
  40. package/dist/shared/format-B9jsmCER.mjs.map +1 -0
  41. package/dist/shared/index-BvtwY4FQ.d.mts +841 -0
  42. package/dist/shared/mediaQuery-BYR1z-iD.d.mts +145 -0
  43. package/dist/shared/mediaQuery.internal-B6iuMd75.mjs +100 -0
  44. package/dist/shared/mediaQuery.internal-B6iuMd75.mjs.map +1 -0
  45. package/dist/shared/mediaRule-BDB4WCYy.d.mts +558 -0
  46. package/dist/shared/precision.internal-0lv1nEpF.mjs +40 -0
  47. package/dist/shared/precision.internal-0lv1nEpF.mjs.map +1 -0
  48. package/dist/shared/propertyRule-BbkFh9b9.d.mts +466 -0
  49. package/dist/shared/propertyRule.internal-Bc_HrfcL.mjs +246 -0
  50. package/dist/shared/propertyRule.internal-Bc_HrfcL.mjs.map +1 -0
  51. package/dist/shared/render-BqcFH9Vr.mjs +9 -0
  52. package/dist/shared/render-BqcFH9Vr.mjs.map +1 -0
  53. package/dist/shared/rolldown-runtime-D7D4PA-g.mjs +13 -0
  54. package/dist/shared/ruleSet.internal-DodzVMUU.mjs +218 -0
  55. package/dist/shared/ruleSet.internal-DodzVMUU.mjs.map +1 -0
  56. package/dist/shared/selector-HZY-W6l6.d.mts +346 -0
  57. package/dist/shared/selector.internal-ESe9s0IH.mjs +290 -0
  58. package/dist/shared/selector.internal-ESe9s0IH.mjs.map +1 -0
  59. package/dist/shared/utils-BKm298I-.d.mts +179 -0
  60. package/dist/stylesheet/index.d.mts +316 -0
  61. package/dist/stylesheet/index.mjs +296 -0
  62. package/dist/stylesheet/index.mjs.map +1 -0
  63. package/dist/utils.d.mts +2 -0
  64. package/dist/utils.mjs +131 -0
  65. package/dist/utils.mjs.map +1 -0
  66. package/package.json +96 -8
  67. package/index.js +0 -1
@@ -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 };
@@ -0,0 +1,74 @@
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
+ //#region src/declaration/declaration.ts
4
+ var declaration_exports = /* @__PURE__ */ __exportAll({
5
+ bind: () => bind,
6
+ equals: () => equals,
7
+ isDeclaration: () => isDeclaration,
8
+ make: () => make,
9
+ refs: () => refs,
10
+ render: () => render
11
+ });
12
+ /**
13
+ * Checks if a value is a `Declaration`.
14
+ *
15
+ * True only for values built by this module's constructors, which carry
16
+ * the brand.
17
+ *
18
+ * @param u - The value to check.
19
+ * @returns `true` if the value is a `Declaration`, `false` otherwise.
20
+ * @since 0.1.0
21
+ */
22
+ const isDeclaration = isDeclaration$1;
23
+ /**
24
+ * Creates a declaration.
25
+ *
26
+ * Literal text is stored verbatim — no parsing, no escaping. A bare
27
+ * number is coerced to an unannotated constant expression, as anywhere
28
+ * else an expression is accepted, so it serializes under the precision
29
+ * context rather than as raw text.
30
+ *
31
+ * @param name - The property name, exactly as it renders (`--x` keeps its dashes). Must be non-empty.
32
+ * @param value - Literal CSS text, a number, or a `Calc`/`Color` expression.
33
+ * @returns A `Declaration` carrying the value's reference names — `Declaration<never>` for text and numbers.
34
+ * @throws `Error` when `name` is empty, or `value` is a non-finite number.
35
+ * @example
36
+ * ```ts
37
+ * Declaration.make('color', 'red')
38
+ * Declaration.make('--fluid', Calc.add(14, Calc.multiply(Calc.ref('vw'), 0.01)))
39
+ * ```
40
+ * @since 0.1.0
41
+ */
42
+ const make = make$1;
43
+ const bind = bind$1;
44
+ /**
45
+ * The declaration's unbound reference names — empty for literal text,
46
+ * the value's references otherwise.
47
+ *
48
+ * @param declaration - The declaration to inspect.
49
+ * @returns The set of unbound reference names.
50
+ * @since 0.1.0
51
+ */
52
+ const refs = refs$1;
53
+ /**
54
+ * Renders the declaration as one CSS declaration, semicolon included:
55
+ * `name: value;`. Literal text passes through verbatim; expression
56
+ * values serialize as `Calc.serialize`/`Color.serialize` would, with
57
+ * unbound references rendering as `var(--name)`.
58
+ *
59
+ * @param declaration - The declaration to render.
60
+ * @param options - Optional precision context for expression values.
61
+ * @returns Deterministic CSS text.
62
+ * @example
63
+ * ```ts
64
+ * Declaration.render(Declaration.make('--indent', Calc.multiply(Calc.ref('depth'), 8)))
65
+ * // '--indent: calc(var(--depth) * 8);'
66
+ * ```
67
+ * @since 0.1.0
68
+ */
69
+ const render = render$1;
70
+ const equals = equals$1;
71
+ //#endregion
72
+ export { declaration_exports as Declaration };
73
+
74
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +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, 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 };
@@ -0,0 +1,102 @@
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
+ //#region src/fontFace/fontFaceRule.ts
4
+ var fontFaceRule_exports = /* @__PURE__ */ __exportAll({
5
+ equals: () => equals,
6
+ isFontFaceRule: () => isFontFaceRule,
7
+ isSource: () => isSource,
8
+ local: () => local,
9
+ make: () => make,
10
+ render: () => render,
11
+ url: () => url
12
+ });
13
+ /**
14
+ * Checks if a value is a `FontFaceRule`.
15
+ *
16
+ * True only for values built by this module's constructors, which carry
17
+ * the brand.
18
+ *
19
+ * @param u - The value to check.
20
+ * @returns `true` if the value is a `FontFaceRule`, `false` otherwise.
21
+ * @since 0.1.0
22
+ */
23
+ const isFontFaceRule = isFontFaceRule$1;
24
+ /**
25
+ * Checks if a value is a font `Source`.
26
+ *
27
+ * True only for values built by `url` and `local`, which carry the brand.
28
+ *
29
+ * @param u - The value to check.
30
+ * @returns `true` if the value is a `Source`, `false` otherwise.
31
+ * @since 0.1.0
32
+ */
33
+ const isSource = isSource$1;
34
+ /**
35
+ * Creates a downloadable font source, rendered `url('href')` — with a
36
+ * `format('...')` hint appended when `format` is given.
37
+ *
38
+ * @param href - The URL the face loads from. Must be non-empty; rendered single-quoted with embedded quotes and backslashes escaped.
39
+ * @param format - The optional format hint (`woff2`, `woff`, ...). Must be non-empty when given.
40
+ * @returns A `Source` for `Descriptors.src`.
41
+ * @throws `Error` when `href` is empty, or `format` is given but empty.
42
+ * @since 0.1.0
43
+ */
44
+ const url = url$1;
45
+ /**
46
+ * Creates a local font lookup, rendered `local('name')` — the expected
47
+ * sole source of a metrics-adjusted fallback face.
48
+ *
49
+ * @param name - The locally installed family name. Must be non-empty; rendered single-quoted with embedded quotes and backslashes escaped.
50
+ * @returns A `Source` for `Descriptors.src`.
51
+ * @throws `Error` when `name` is empty.
52
+ * @since 0.1.0
53
+ */
54
+ const local = local$1;
55
+ /**
56
+ * Creates an `@font-face` rule.
57
+ *
58
+ * @param descriptors - The face's descriptors; `family` and `src` are required.
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, a unicode-range entry is empty, out of order, or outside `[0x0, 0x10FFFF]`, or a metric override is negative or non-finite.
61
+ * @example
62
+ * ```ts
63
+ * FontFaceRule.make({
64
+ * family: 'Inter',
65
+ * weight: [100, 900],
66
+ * style: 'normal',
67
+ * display: 'swap',
68
+ * src: [FontFaceRule.url('/fonts/inter-variable.woff2', 'woff2')],
69
+ * })
70
+ * ```
71
+ * @since 0.1.0
72
+ */
73
+ const make = make$1;
74
+ /**
75
+ * Renders the rule as a complete `@font-face { ... }` block.
76
+ *
77
+ * Descriptors render in a fixed order — `font-family`, `font-weight`,
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 `%`.
84
+ *
85
+ * @param rule - The rule to render.
86
+ * @param options - Optional indentation unit and precision context.
87
+ * @returns Deterministic CSS text.
88
+ * @example
89
+ * ```ts
90
+ * FontFaceRule.render(
91
+ * FontFaceRule.make({ family: 'Inter', src: [FontFaceRule.url('/inter.woff2', 'woff2')] }),
92
+ * )
93
+ * // "@font-face {\n\tfont-family: 'Inter';\n\tsrc: url('/inter.woff2') format('woff2');\n}"
94
+ * ```
95
+ * @since 0.1.0
96
+ */
97
+ const render = render$1;
98
+ const equals = equals$1;
99
+ //#endregion
100
+ export { fontFaceRule_exports as FontFaceRule };
101
+
102
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +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 `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 };
@@ -0,0 +1,293 @@
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
+ //#region src/property/propertyRule.ts
4
+ var propertyRule_exports = /* @__PURE__ */ __exportAll({
5
+ equals: () => equals$1,
6
+ inheritable: () => inheritable,
7
+ isPropertyRule: () => isPropertyRule,
8
+ make: () => make,
9
+ render: () => render$1
10
+ });
11
+ /**
12
+ * Checks if a value is a `PropertyRule`.
13
+ *
14
+ * True only for values built by this module's constructors, which carry
15
+ * the brand.
16
+ *
17
+ * @param u - The value to check.
18
+ * @returns `true` if the value is a `PropertyRule`, `false` otherwise.
19
+ * @since 0.1.0
20
+ */
21
+ const isPropertyRule = isPropertyRule$1;
22
+ const make = make$1;
23
+ /**
24
+ * Registers the rule as inheriting. `make` constructs every rule with
25
+ * `inherits: false` — the safe default for computed channels, where
26
+ * inheritance would leak intermediate values down the tree — so
27
+ * inheritance is an explicit opt-in.
28
+ *
29
+ * @param rule - The rule to opt in.
30
+ * @returns The inheriting rule; the same rule when it already inherits.
31
+ * @example
32
+ * ```ts
33
+ * PropertyRule.make('--fill', PropertySyntax.color, 'red').pipe(PropertyRule.inheritable)
34
+ * ```
35
+ * @since 0.1.0
36
+ */
37
+ const inheritable = inheritable$1;
38
+ /**
39
+ * Renders the rule as a complete `@property --name { ... }` block, the
40
+ * descriptors in fixed order: `syntax`, `inherits`, `initial-value`.
41
+ *
42
+ * @param rule - The rule to render.
43
+ * @param options - Optional indentation unit and precision context.
44
+ * @returns Deterministic CSS text.
45
+ * @example
46
+ * ```ts
47
+ * PropertyRule.render(PropertyRule.make('--depth', PropertySyntax.number, 0))
48
+ * // "@property --depth {\n\tsyntax: '<number>';\n\tinherits: false;\n\tinitial-value: 0;\n}"
49
+ * ```
50
+ * @since 0.1.0
51
+ */
52
+ const render$1 = render$2;
53
+ const equals$1 = equals$2;
54
+ //#endregion
55
+ //#region src/property/propertySyntax.ts
56
+ var propertySyntax_exports = /* @__PURE__ */ __exportAll({
57
+ angle: () => angle,
58
+ color: () => color,
59
+ commaListOf: () => commaListOf,
60
+ customIdent: () => customIdent,
61
+ equals: () => equals,
62
+ image: () => image,
63
+ integer: () => integer,
64
+ isPropertySyntax: () => isPropertySyntax,
65
+ keyword: () => keyword,
66
+ keywords: () => keywords,
67
+ length: () => length,
68
+ lengthPercentage: () => lengthPercentage,
69
+ listOf: () => listOf,
70
+ number: () => number,
71
+ oneOf: () => oneOf,
72
+ percentage: () => percentage,
73
+ render: () => render,
74
+ resolution: () => resolution,
75
+ string: () => string,
76
+ time: () => time,
77
+ transformFunction: () => transformFunction,
78
+ transformList: () => transformList,
79
+ universal: () => universal,
80
+ url: () => url
81
+ });
82
+ /**
83
+ * Checks if a value is a `PropertySyntax`.
84
+ *
85
+ * True only for values built by this module's constructors, which carry
86
+ * the brand.
87
+ *
88
+ * @param u - The value to check.
89
+ * @returns `true` if the value is a `PropertySyntax`, `false` otherwise.
90
+ * @since 0.1.0
91
+ */
92
+ const isPropertySyntax = isPropertySyntax$1;
93
+ /**
94
+ * The universal syntax, `*` — any value at all. The one syntax under
95
+ * which `@property` may omit its initial value.
96
+ *
97
+ * @since 0.1.0
98
+ */
99
+ const universal = universal$1;
100
+ /**
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
+ *
104
+ * @since 0.1.0
105
+ */
106
+ const angle = angle$1;
107
+ /**
108
+ * The `<color>` data type. Initial values are closed `Color` expressions
109
+ * or literal text (`'transparent'`, `'#fff'`).
110
+ *
111
+ * @since 0.1.0
112
+ */
113
+ const color = color$1;
114
+ /**
115
+ * The `<custom-ident>` data type — any custom identifier. To accept a
116
+ * fixed set of identifiers instead, combine `keyword` values with
117
+ * `oneOf`.
118
+ *
119
+ * @since 0.1.0
120
+ */
121
+ const customIdent = customIdent$1;
122
+ /**
123
+ * The `<image>` data type. Initial values are literal text.
124
+ *
125
+ * @since 0.1.0
126
+ */
127
+ const image = image$1;
128
+ /**
129
+ * The `<integer>` data type. Initial values are numbers or closed `Calc`
130
+ * expressions; that the value is a whole number is the browser's parse
131
+ * check, not this library's.
132
+ *
133
+ * @since 0.1.0
134
+ */
135
+ const integer = integer$1;
136
+ /**
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.
142
+ *
143
+ * @since 0.1.0
144
+ */
145
+ const length = length$1;
146
+ /**
147
+ * The `<length-percentage>` data type. Initial values are a closed
148
+ * absolute-length or percentage `Calc`, or literal text.
149
+ *
150
+ * @since 0.1.0
151
+ */
152
+ const lengthPercentage = lengthPercentage$1;
153
+ /**
154
+ * The `<number>` data type. Initial values are numbers or closed `Calc`
155
+ * expressions — the typed channel this library models; text is not
156
+ * accepted where the number form exists.
157
+ *
158
+ * @since 0.1.0
159
+ */
160
+ const number = number$1;
161
+ /**
162
+ * The `<percentage>` data type. Initial values are a closed percentage-kind
163
+ * `Calc` (`Percentage.of(50)`) or literal text carrying the `%` unit (`'50%'`).
164
+ *
165
+ * @since 0.1.0
166
+ */
167
+ const percentage = percentage$1;
168
+ /**
169
+ * The `<resolution>` data type. Initial values are literal text.
170
+ *
171
+ * @since 0.1.0
172
+ */
173
+ const resolution = resolution$1;
174
+ /**
175
+ * The `<string>` data type. Initial values are literal text including
176
+ * their own quotes (`'"hello"'`).
177
+ *
178
+ * @since 0.1.0
179
+ */
180
+ const string = string$1;
181
+ /**
182
+ * The `<time>` data type. Initial values are literal text carrying a
183
+ * time unit (`'200ms'`).
184
+ *
185
+ * @since 0.1.0
186
+ */
187
+ const time = time$1;
188
+ /**
189
+ * The `<transform-function>` data type. Initial values are literal text.
190
+ *
191
+ * @since 0.1.0
192
+ */
193
+ const transformFunction = transformFunction$1;
194
+ /**
195
+ * The `<transform-list>` data type — a list of transform functions. It
196
+ * is pre-multiplied, so `listOf`/`commaListOf` reject it. Initial values
197
+ * are literal text.
198
+ *
199
+ * @since 0.1.0
200
+ */
201
+ const transformList = transformList$1;
202
+ /**
203
+ * The `<url>` data type. Initial values are literal text.
204
+ *
205
+ * @since 0.1.0
206
+ */
207
+ const url = url$1;
208
+ /**
209
+ * A keyword component: one specific custom identifier, rendered bare.
210
+ * Combined under `oneOf`, keywords give the registered property an
211
+ * enum-like domain — and the `V` parameter carries the literal, so
212
+ * `initialValue` autocompletes and checks against exactly the declared
213
+ * set.
214
+ *
215
+ * @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.
216
+ * @returns A `PropertySyntax` accepting exactly `name`.
217
+ * @throws `Error` when `name` is empty or a CSS-wide keyword.
218
+ * @since 0.1.0
219
+ */
220
+ const keyword = keyword$1;
221
+ /**
222
+ * A keyword set: shorthand for `oneOf` over `keyword` values, accepting
223
+ * — and narrowing `initialValue` to — exactly the given identifiers. A
224
+ * single name is just that `keyword`.
225
+ *
226
+ * @param names - One or more identifiers, each under `keyword`'s constraints.
227
+ * @returns A `PropertySyntax` accepting exactly the given names.
228
+ * @throws `Error` when a name is empty or a CSS-wide keyword.
229
+ * @example
230
+ * ```ts
231
+ * const size = PropertySyntax.keywords('small', 'medium', 'large')
232
+ * PropertySyntax.render(size) // 'small | medium | large'
233
+ * PropertyRule.make('--size', size, 'medium') // initialValue checks against the three names
234
+ * ```
235
+ * @since 0.1.0
236
+ */
237
+ const keywords = keywords$1;
238
+ /**
239
+ * A `|` combination: the value may satisfy any one of the components,
240
+ * tried in order — authored order is preserved (it is parse order, so
241
+ * `'<length> | auto'` and `'auto | <length>'` are different syntaxes).
242
+ * Nested combinations flatten into the enclosing one.
243
+ *
244
+ * @param components - Two or more components. The universal syntax stands alone and may not join a combination.
245
+ * @returns A `PropertySyntax` accepting any component's values, unioned in `V`.
246
+ * @throws `Error` when a component is the universal syntax.
247
+ * @example
248
+ * ```ts
249
+ * const size = PropertySyntax.oneOf(PropertySyntax.keyword('small'), PropertySyntax.keyword('large'))
250
+ * PropertySyntax.render(size) // 'small | large'
251
+ * PropertyRule.make('--size', size, 'small') // initialValue is 'small' | 'large' only
252
+ * ```
253
+ * @since 0.1.0
254
+ */
255
+ const oneOf = oneOf$1;
256
+ /**
257
+ * A space-separated list of one component, rendered with the `+`
258
+ * multiplier (`'<length>+'`).
259
+ *
260
+ * A one-item list is valid, so the component's own value forms stay
261
+ * accepted; longer lists are literal text.
262
+ *
263
+ * @param component - The repeated component. Must be a single unmultiplied component — not the universal syntax, a combination, a list, or the pre-multiplied `transformList`.
264
+ * @returns A `PropertySyntax` accepting the component's values or list text.
265
+ * @throws `Error` when the component cannot take a multiplier.
266
+ * @since 0.1.0
267
+ */
268
+ const listOf = listOf$1;
269
+ /**
270
+ * A comma-separated list of one component, rendered with the `#`
271
+ * multiplier (`'<color>#'`). Constraints match `listOf`.
272
+ *
273
+ * @param component - The repeated component. Must be a single unmultiplied component — not the universal syntax, a combination, a list, or the pre-multiplied `transformList`.
274
+ * @returns A `PropertySyntax` accepting the component's values or list text.
275
+ * @throws `Error` when the component cannot take a multiplier.
276
+ * @since 0.1.0
277
+ */
278
+ const commaListOf = commaListOf$1;
279
+ /**
280
+ * Renders the syntax as its descriptor string, unquoted: `'*'`,
281
+ * `'<number>'`, `'<length>+'`, `'small | large'`. `PropertyRule.render`
282
+ * wraps this in the quotes the descriptor requires.
283
+ *
284
+ * @param syntax - The syntax to render.
285
+ * @returns Deterministic descriptor text.
286
+ * @since 0.1.0
287
+ */
288
+ const render = render$3;
289
+ const equals = equals$3;
290
+ //#endregion
291
+ export { propertyRule_exports as PropertyRule, propertySyntax_exports as PropertySyntax };
292
+
293
+ //# sourceMappingURL=index.mjs.map