@theme-registry/refract 0.1.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 (135) hide show
  1. package/LICENSE +21 -0
  2. package/dist/_createTheme-255ff48e.esm.js +2 -0
  3. package/dist/_createTheme-255ff48e.esm.js.map +1 -0
  4. package/dist/_createTheme-41c01033.cjs.js +2 -0
  5. package/dist/_createTheme-41c01033.cjs.js.map +1 -0
  6. package/dist/_errors-be768b25.cjs.js +2 -0
  7. package/dist/_errors-be768b25.cjs.js.map +1 -0
  8. package/dist/_errors-d75a5c74.esm.js +2 -0
  9. package/dist/_errors-d75a5c74.esm.js.map +1 -0
  10. package/dist/adapter-kit.cjs.js +2 -0
  11. package/dist/adapter-kit.cjs.js.map +1 -0
  12. package/dist/adapter-kit.d.ts +88 -0
  13. package/dist/adapter-kit.esm.js +2 -0
  14. package/dist/adapter-kit.esm.js.map +1 -0
  15. package/dist/build/auditCommand.d.ts +19 -0
  16. package/dist/build/buildCommand.d.ts +23 -0
  17. package/dist/build/cli.d.ts +2 -0
  18. package/dist/build/config.d.ts +58 -0
  19. package/dist/build/diff.d.ts +56 -0
  20. package/dist/build/diffCommand.d.ts +29 -0
  21. package/dist/build/emit.d.ts +20 -0
  22. package/dist/build/emitTheme.d.ts +39 -0
  23. package/dist/build/guide.d.ts +34 -0
  24. package/dist/build/importCommand.d.ts +42 -0
  25. package/dist/build/index.d.ts +33 -0
  26. package/dist/build/init.d.ts +32 -0
  27. package/dist/build/paths.d.ts +42 -0
  28. package/dist/build/skillsCommand.d.ts +53 -0
  29. package/dist/build/tokensCommand.d.ts +17 -0
  30. package/dist/build/vendor.d.ts +39 -0
  31. package/dist/build.cjs.js +2 -0
  32. package/dist/build.cjs.js.map +1 -0
  33. package/dist/build.esm.js +2 -0
  34. package/dist/build.esm.js.map +1 -0
  35. package/dist/cli.js +8250 -0
  36. package/dist/cli.js.map +1 -0
  37. package/dist/color-math.cjs.js +2 -0
  38. package/dist/color-math.cjs.js.map +1 -0
  39. package/dist/color-math.esm.js +2 -0
  40. package/dist/color-math.esm.js.map +1 -0
  41. package/dist/core/ThemeAdapter.d.ts +234 -0
  42. package/dist/core/createTheme.d.ts +96 -0
  43. package/dist/core/cssProperties.d.ts +8 -0
  44. package/dist/core/defineAdapter.d.ts +25 -0
  45. package/dist/core/derive/crossProperty.d.ts +31 -0
  46. package/dist/core/derive/index.d.ts +11 -0
  47. package/dist/core/derive/resolveTokens.d.ts +27 -0
  48. package/dist/core/errors.d.ts +24 -0
  49. package/dist/core/index.d.ts +16 -0
  50. package/dist/core/media/containers.d.ts +20 -0
  51. package/dist/core/media/defaults.d.ts +3 -0
  52. package/dist/core/media/descriptors.d.ts +12 -0
  53. package/dist/core/media/index.d.ts +11 -0
  54. package/dist/core/media/queries.d.ts +20 -0
  55. package/dist/core/model/buildModel.d.ts +116 -0
  56. package/dist/core/model/index.d.ts +14 -0
  57. package/dist/core/model/interpreted.d.ts +37 -0
  58. package/dist/core/model/mergeRuleSet.d.ts +68 -0
  59. package/dist/core/model/model.d.ts +260 -0
  60. package/dist/core/noopAdapter.d.ts +26 -0
  61. package/dist/core/normalize/index.d.ts +15 -0
  62. package/dist/core/normalize/properties.d.ts +20 -0
  63. package/dist/core/normalize/recipeResolver.d.ts +19 -0
  64. package/dist/core/normalize/recipes.d.ts +38 -0
  65. package/dist/core/normalize/responsive.d.ts +40 -0
  66. package/dist/core/normalize/types.d.ts +261 -0
  67. package/dist/core/rawTheme.d.ts +53 -0
  68. package/dist/core/ref.d.ts +13 -0
  69. package/dist/core/subsystem.d.ts +115 -0
  70. package/dist/core/types.d.ts +31 -0
  71. package/dist/core/units.d.ts +93 -0
  72. package/dist/dtcg/export.d.ts +48 -0
  73. package/dist/dtcg/import.d.ts +43 -0
  74. package/dist/dtcg/index.d.ts +21 -0
  75. package/dist/dtcg/parse.d.ts +6 -0
  76. package/dist/dtcg/types.d.ts +69 -0
  77. package/dist/dtcg.cjs.js +2 -0
  78. package/dist/dtcg.cjs.js.map +1 -0
  79. package/dist/dtcg.esm.js +2 -0
  80. package/dist/dtcg.esm.js.map +1 -0
  81. package/dist/index.cjs.js +2 -0
  82. package/dist/index.cjs.js.map +1 -0
  83. package/dist/index.d.ts +27 -0
  84. package/dist/index.esm.js +2 -0
  85. package/dist/index.esm.js.map +1 -0
  86. package/dist/subsystems/animation/index.d.ts +13 -0
  87. package/dist/subsystems/animation/recipes.d.ts +20 -0
  88. package/dist/subsystems/animation/types.d.ts +52 -0
  89. package/dist/subsystems/borders/index.d.ts +10 -0
  90. package/dist/subsystems/borders/recipes.d.ts +29 -0
  91. package/dist/subsystems/borders/types.d.ts +50 -0
  92. package/dist/subsystems/colors/audit.d.ts +67 -0
  93. package/dist/subsystems/colors/colorInput.d.ts +17 -0
  94. package/dist/subsystems/colors/index.d.ts +12 -0
  95. package/dist/subsystems/colors/keywords.d.ts +9 -0
  96. package/dist/subsystems/colors/normalize.d.ts +26 -0
  97. package/dist/subsystems/colors/recipes.d.ts +21 -0
  98. package/dist/subsystems/colors/types.d.ts +98 -0
  99. package/dist/subsystems/colors/utils.d.ts +104 -0
  100. package/dist/subsystems/components/index.d.ts +13 -0
  101. package/dist/subsystems/components/recipes.d.ts +22 -0
  102. package/dist/subsystems/components/types.d.ts +46 -0
  103. package/dist/subsystems/effects/index.d.ts +9 -0
  104. package/dist/subsystems/effects/recipes.d.ts +24 -0
  105. package/dist/subsystems/effects/types.d.ts +63 -0
  106. package/dist/subsystems/effects/utils.d.ts +57 -0
  107. package/dist/subsystems/globals/index.d.ts +21 -0
  108. package/dist/subsystems/globals/presets.d.ts +33 -0
  109. package/dist/subsystems/globals/types.d.ts +48 -0
  110. package/dist/subsystems/index.d.ts +21 -0
  111. package/dist/subsystems/layout/index.d.ts +14 -0
  112. package/dist/subsystems/layout/normalize.d.ts +35 -0
  113. package/dist/subsystems/layout/recipes.d.ts +16 -0
  114. package/dist/subsystems/layout/structural.d.ts +37 -0
  115. package/dist/subsystems/layout/types.d.ts +154 -0
  116. package/dist/subsystems/typography/index.d.ts +9 -0
  117. package/dist/subsystems/typography/normalize.d.ts +17 -0
  118. package/dist/subsystems/typography/recipes.d.ts +21 -0
  119. package/dist/subsystems/typography/types.d.ts +49 -0
  120. package/package.json +83 -0
  121. package/skills/adapter-scaffold/SKILL.md +85 -0
  122. package/skills/adapter-usage/SKILL.md +75 -0
  123. package/skills/build-config/SKILL.md +77 -0
  124. package/skills/colors/SKILL.md +134 -0
  125. package/skills/consuming-the-output/SKILL.md +62 -0
  126. package/skills/dtcg-import/SKILL.md +76 -0
  127. package/skills/layout/SKILL.md +65 -0
  128. package/skills/overrides-and-child-themes/SKILL.md +70 -0
  129. package/skills/recipes-and-composition/SKILL.md +110 -0
  130. package/skills/theme-authoring/SKILL.md +107 -0
  131. package/skills/theme-foundations/SKILL.md +127 -0
  132. package/skills/troubleshooting/SKILL.md +97 -0
  133. package/skills/typography/SKILL.md +66 -0
  134. package/skills/visual-effects/SKILL.md +96 -0
  135. package/src/subsystems/colors/utils.ts +299 -0
@@ -0,0 +1,98 @@
1
+ import type { DerivationModifier, ExternalProperty, ModeOverride, NormalizedPropertyValue, RecipeBlock, ResponsiveOverride } from "../../core/normalize";
2
+ import type { RGBTuple } from "./utils";
3
+ export type { AdjustDials } from "./utils";
4
+ /**
5
+ * A colour's authored **base** value — a hex string (`"#4dabf7"` / `"#4af"`), an `[r, g, b]` tuple
6
+ * (0–255), or any CSS colour string: `oklch()`, `hsl()/hsla()`, `rgb()/rgba()`, or a named keyword
7
+ * (`"rebeccapurple"`). All are normalized to the canonical `rgb()` form at build (derivation runs in
8
+ * OKLCH). A `var(--…)` is **rejected** — it can't be tonally derived at build time; borrow an external
9
+ * token instead (`{ external: … }`). Tuple/keyword/function forms are coerced at normalize time.
10
+ */
11
+ export type ColorInput = string | RGBTuple;
12
+ /**
13
+ * A **derivation spec** variant (§13.3, §20.4, dec.2) — a named variant derived from a source colour
14
+ * by an ordered `modifiers` chain of single-key `{ [fn]: args }` dials (`darken`/`lighten`/`alpha`/
15
+ * `adjust`/`setL`/`rotateHue`): `value = modifiers.reduce((v, {fn,arg}) => fn(v, arg), resolve(ref))`.
16
+ * `ref` names the source token (defaults to the property's own base; may point to another variant/step).
17
+ * `darken`/`lighten` shift OKLCH lightness by N points (alpha preserved); `alpha` sets absolute opacity
18
+ * (`{ alpha: 40 }` ⇒ 40% opaque); `adjust` places an absolute lightness and/or scales chroma and/or
19
+ * rotates hue in one shot (see {@link AdjustDials}).
20
+ */
21
+ export type PaletteDerivationSpec = {
22
+ ref?: string;
23
+ modifiers: DerivationModifier[];
24
+ };
25
+ /**
26
+ * A built-in colour-harmony scheme — rotations of the base's hue around the perceptual wheel, each
27
+ * generated variant holding the base's lightness and chroma (only the hue turns).
28
+ */
29
+ export type HarmonyScheme = "complement" | "analogous" | "split-complement" | "triadic" | "tetradic";
30
+ /**
31
+ * The palette-level `harmony` option (§20.5). The **string** form uses each scheme's default member
32
+ * names (`"triadic"` → `triadic1` / `triadic2`); the **object** form renames them positionally
33
+ * (`{ triadic: ["mint", "coral"] }` → `mint` / `coral`). Exactly one scheme per colour.
34
+ */
35
+ export type HarmonyOption = HarmonyScheme | Partial<Record<HarmonyScheme, string[]>>;
36
+ /**
37
+ * One authored variant value — a literal colour, a {@link PaletteDerivationSpec}, or the extended
38
+ * `{ base, …extra }` form (for literal variants carrying siblings like `text`).
39
+ */
40
+ export type PaletteVariantInput = ColorInput | PaletteDerivationSpec | ({
41
+ base: ColorInput;
42
+ } & Record<string, unknown>);
43
+ /**
44
+ * Colors' property extras — the palette-synthesis config that rides alongside a colour value.
45
+ * `steps` is **numeric only** and defines an absolute OKLCH lightness ladder (§20.2): each
46
+ * Tailwind-style label maps to a fixed lightness via `L = (1000 − label) / 10` (low = light, high =
47
+ * dark), so the same label reads at the same lightness across every palette. Named tonal variants
48
+ * (`light`/`lighter`/`dark`/`darker`) are auto-generated when no `steps` are declared; they stay
49
+ * relative, compounding `lightenBy`/`darkenBy` as OKLCH ΔL points (which do NOT apply to numeric
50
+ * steps). (`variants` is NOT here — it's a first-class key on {@link PaletteExtendedProperty},
51
+ * widened to accept derivation specs.)
52
+ */
53
+ export type PalettePropertyExtras = {
54
+ text?: ColorInput;
55
+ steps?: number[];
56
+ lightenBy?: number;
57
+ darkenBy?: number;
58
+ harmony?: HarmonyOption;
59
+ };
60
+ /**
61
+ * Colors' extended-property authoring shape — mirrors core's `ExtendedProperty` but with a
62
+ * {@link ColorInput} base (hex string or `[r,g,b]` tuple) and a `variants` map widened to accept
63
+ * {@link PaletteVariantInput} (literal colours, derivation specs, or extended literals). Coerced to
64
+ * the canonical core shape (`base: string`) at normalize time.
65
+ */
66
+ export type PaletteExtendedProperty = {
67
+ base: ColorInput;
68
+ responsive?: ResponsiveOverride<ColorInput, PalettePropertyExtras>[];
69
+ variants?: Record<string, PaletteVariantInput>;
70
+ modes?: ModeOverride<ColorInput, PalettePropertyExtras>[];
71
+ } & PalettePropertyExtras;
72
+ export type PalettePropertyValue = ColorInput | PaletteExtendedProperty | ExternalProperty;
73
+ export type NormalizedPaletteValue = NormalizedPropertyValue<string, PalettePropertyExtras>;
74
+ /**
75
+ * The palette recipe declaration shape — colour-bearing CSS properties whose values
76
+ * name a palette reference (`"primary"`, `"primary.text"`, `"neutral.light"`) or a
77
+ * literal. Any additional style property is allowed (passed through as a literal).
78
+ */
79
+ export type PaletteRecipeValue = string | number;
80
+ export type PaletteRecipeProps = {
81
+ background?: PaletteRecipeValue;
82
+ backgroundColor?: PaletteRecipeValue;
83
+ color?: PaletteRecipeValue;
84
+ borderColor?: PaletteRecipeValue;
85
+ outlineColor?: PaletteRecipeValue;
86
+ [property: string]: PaletteRecipeValue | undefined;
87
+ };
88
+ /**
89
+ * The authored `raw.colors` slice (§8a). An **open** map: keys are arbitrary palette names
90
+ * (`primary`, `neutral`, …), each a {@link PalettePropertyValue} — a bare hex/ref string, an
91
+ * `[r,g,b]` tuple, or a full `ExtendedProperty` with `text` / `steps` / `variants` / `responsive`.
92
+ * The reserved `recipes` key is a {@link RecipeBlock} of palette recipes. Authoring type only —
93
+ * the spine still consumes the slice as `Record<string, unknown>`.
94
+ */
95
+ export interface ColorsRaw {
96
+ recipes?: RecipeBlock<PaletteRecipeProps>;
97
+ [palette: string]: PalettePropertyValue | RecipeBlock<PaletteRecipeProps> | undefined;
98
+ }
@@ -0,0 +1,104 @@
1
+ /**
2
+ * Pure colour math for palette step + variant synthesis.
3
+ *
4
+ * Lightness / hue / chroma work runs in **OKLCH** (a perceptual space) via Björn Ottosson's
5
+ * public-domain matrices — parse → sRGB → linear → OKLab → OKLCH → apply → gamut-map → linear →
6
+ * sRGB → quantize → serialize — so equal lightness steps look even and one lightness reads the same
7
+ * across hues. hex / `rgba()` strings are only touched at the boundary (`parseColor` in,
8
+ * `serializeColor` out). `lighten` / `darken` shift OKLCH lightness by ΔL points; `setL` places an
9
+ * absolute lightness; `rotateHue` / `complement` turn the hue; `alpha` sets opacity. All are
10
+ * string-in / string-out so the same fns run at normalize time (baking the cached value) and later
11
+ * in the derivation registry — AND are vendored to consumers (see `build/vendor.ts`) so a value
12
+ * computed live in the app matches the emitted CSS variable. Kept dependency-free for that vendoring.
13
+ */
14
+ /** An `[r, g, b]` channel triple, each `0–255`. */
15
+ export type RGBTuple = readonly [number, number, number];
16
+ /** An `[r, g, b, a]` quad — channels `0–255`, alpha `0–1`. */
17
+ export type RGBATuple = readonly [number, number, number, number];
18
+ /** A colour authored/worked as a tuple — opaque `[r,g,b]` or translucent `[r,g,b,a]`. */
19
+ export type ColorTuple = RGBTuple | RGBATuple;
20
+ /** Parse a 3- or 6-digit hex string (with or without `#`) into an `[r, g, b]` tuple. */
21
+ export declare const convertHexToRGB: (hex: string) => RGBTuple;
22
+ /** Serialize an `[r, g, b]` tuple back to a `#rrggbb` string, clamping each channel to `0–255`. */
23
+ export declare const convertRgbToHex: (rgb: RGBTuple) => string;
24
+ /**
25
+ * Parse any canonical colour string this subsystem produces — a 3/6-digit hex **or** an
26
+ * `rgb()` / `rgba()` string — into `{ rgb, a }` (alpha defaults to `1`). This is the boundary
27
+ * gate; a value that isn't parseable rgb (e.g. a bare CSS keyword or `var(--…)`) throws, so
28
+ * callers can surface a friendly "this colour can't be derived from" error.
29
+ */
30
+ export declare const parseColor: (value: string) => {
31
+ rgb: RGBTuple;
32
+ a: number;
33
+ };
34
+ /**
35
+ * Serialize `[r, g, b]` (+ optional alpha) to the canonical CSS string — always `rgb(r, g, b)`
36
+ * when fully opaque, else `rgba(r, g, b, a)`. The single serialization point for the subsystem, so
37
+ * the Model (and every adapter + `resolveToken`) always carries one canonical `rgb()/rgba()` form
38
+ * per colour — never hex. (`convertRgbToHex` remains for the vendored consumer helper + input parsing.)
39
+ */
40
+ export declare const serializeColor: (rgb: RGBTuple, a?: number) => string;
41
+ /** Whether a string is a 3- or 6-digit `#`-prefixed hex colour. */
42
+ export declare const isHexColor: (value: string) => boolean;
43
+ /** An OKLCH colour — perceptual lightness `L` (0–100), chroma `C` (≥ 0), hue `h` (degrees, 0–360). */
44
+ export type OKLCH = {
45
+ L: number;
46
+ C: number;
47
+ h: number;
48
+ };
49
+ /** Convert an sRGB `[r, g, b]` (0–255) triple to OKLCH (`L` on a 0–100 scale). */
50
+ export declare const rgbToOklch: (rgb: RGBTuple) => OKLCH;
51
+ /**
52
+ * Convert OKLCH back to an sRGB `[r, g, b]` triple (**unquantized** 0–255 floats). Holds `L` and
53
+ * `h`; when the requested chroma is outside sRGB it binary-searches `C` downward — fixed iterations,
54
+ * no data-dependent early exit, so build- and runtime-computed values agree (§20.8) — until the
55
+ * linear result is in `[0, 1]`. Lightness and hue are never adjusted, so a synthesized ramp keeps
56
+ * its hue and even lightness spacing; only saturation gives way at the gamut boundary. The floats
57
+ * are quantized exactly once, later, by `serializeColor`, so the 0–255 channel clamp never fires.
58
+ */
59
+ export declare const oklchToRgb: (color: OKLCH) => RGBTuple;
60
+ /** Lighten a colour by `delta` OKLCH lightness points (0–100 scale); hue, chroma, alpha preserved. */
61
+ export declare const lighten: (value: string, delta: number) => string;
62
+ /** Darken a colour by `delta` OKLCH lightness points (0–100 scale); hue, chroma, alpha preserved. */
63
+ export declare const darken: (value: string, delta: number) => string;
64
+ /** Set a colour's absolute OKLCH lightness to `L` (0–100); hue, chroma, alpha preserved. */
65
+ export declare const setL: (value: string, L: number) => string;
66
+ /** Rotate a colour's OKLCH hue by `deg` (signed) around the perceptual wheel; L, C, alpha preserved. */
67
+ export declare const rotateHue: (value: string, deg: number) => string;
68
+ /** The perceptual complement — a 180° hue rotation at the same lightness and chroma. */
69
+ export declare const complement: (value: string) => string;
70
+ /**
71
+ * An `adjust` dial set — any subset. `l` = **absolute** OKLCH lightness target (0–100, raw L, the
72
+ * opposite direction from a numeric-`steps` label); `c` = chroma **multiplier** (`1` keep, `0` grey,
73
+ * `>1` more saturated where the gamut allows); `h` = **signed** hue rotation in degrees. Numbers
74
+ * only — keeps the vendored math string-free.
75
+ */
76
+ export type AdjustDials = {
77
+ l?: number;
78
+ c?: number;
79
+ h?: number;
80
+ };
81
+ /**
82
+ * One-shot OKLCH placement — set an absolute lightness, scale chroma, and/or rotate hue in a single
83
+ * derivation (each dial optional; an omitted dial leaves that component untouched). Alpha preserved.
84
+ */
85
+ export declare const adjust: (value: string, dials: AdjustDials) => string;
86
+ /**
87
+ * Convert any canonical colour string (the subsystem's `rgb()` / `rgba()` form, or a hex string)
88
+ * to hex — 6-digit `#rrggbb` when opaque, 8-digit `#rrggbbaa` when translucent. Used by the DTCG
89
+ * exporter, whose `color` token type is conventionally hex (every other output stays `rgb()`).
90
+ */
91
+ export declare const toHexColor: (value: string) => string;
92
+ /**
93
+ * Convert any canonical colour string (the subsystem's `rgb()` / `rgba()` form, or a hex string) to
94
+ * a CSS Color 4 `oklch(L% C H)` string — `oklch(L% C H / a)` when translucent. `L` is a percentage
95
+ * (0–100), `C` the absolute chroma, `H` in degrees, derived from the stored (quantized) rgb. Used by
96
+ * the CSS adapter's `colorFormat: "oklch"` output; the colour is identical to the `rgb()` form.
97
+ */
98
+ export declare const toOklchColor: (value: string) => string;
99
+ /**
100
+ * Set a colour's opacity to `percent` (0–100) — an **absolute** alpha, not a relative fade
101
+ * (`alpha(x, 40)` ⇒ 40% opaque). The rgb channels are untouched; only the alpha channel is
102
+ * replaced. Result serializes to `rgba(…)` (or hex when `percent` is 100).
103
+ */
104
+ export declare const alpha: (value: string, percent: number) => string;
@@ -0,0 +1,13 @@
1
+ /**
2
+ * The components (composition) subsystem.
3
+ *
4
+ * Owns **no primitive properties** (the property pipeline never runs — `normalizeProperties`
5
+ * returns empty). It contributes only recipes that reference other subsystems' recipes plus an
6
+ * own `css` delta. The generic recipe path drives `interpretRecipe` (own delta → refs) and, via
7
+ * the `extractReferences` hook, keeps each variant's cross-subsystem references as Model pointers
8
+ * (`"colors:solid.primary"`) so the referenced recipe's states ride along on its shared class.
9
+ * It grows a hook, never the spine.
10
+ */
11
+ import type { Subsystem } from "../../core/subsystem";
12
+ export declare const componentsSubsystem: Subsystem;
13
+ export type { ComponentsRecipeProps, ResolvedComponentClass, ComponentsRaw } from "./types";
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Components' `interpretRecipe` hook — the composition interpreter.
3
+ *
4
+ * A component variant carries cross-subsystem references (`colors: "solid.primary"`) that are
5
+ * NOT declarations (they're extracted separately as Model `references` pointers) plus an own
6
+ * `css` delta. This interpreter emits ONLY the own-delta declarations, each a format-neutral
7
+ * {@link Ref}. The delta is **literal-first**: a bare string / number value is a raw CSS literal
8
+ * → `{ value }`; a `ref("…")` / `{ ref: "…" }` marker is a token path → `{ ref }` (the adapter lowers
9
+ * it to `var(--…)` against the global token union). The
10
+ * referenced recipes' own states ride along on their shared classes (via the `references`
11
+ * pointers), so the component only emits its own delta + own states — which win at equal
12
+ * specificity by later source order.
13
+ */
14
+ import type { InterpretedRecipeVariant } from "../../core/model";
15
+ import type { NormalizedRecipeVariant } from "../../core/normalize";
16
+ import type { RecipeInterpretContext } from "../../core/subsystem";
17
+ import type { ComponentsRecipeProps } from "./types";
18
+ /**
19
+ * Interpret one component variant into base + state/responsive override declarations from its
20
+ * `css` delta. Cross-subsystem references are handled by `extractComponentReferences`, not here.
21
+ */
22
+ export declare const interpretComponentsRecipeVariant: (_variantName: string, variant: NormalizedRecipeVariant<ComponentsRecipeProps, string>, _ctx: RecipeInterpretContext) => InterpretedRecipeVariant<string>;
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Components (composition) subsystem types.
3
+ *
4
+ * A component recipe variant references other subsystems' recipes (`colors: "solid.primary"`,
5
+ * `layout: "padding.button-lg"`, …) and may add its own `css` delta (+ grouped `states` /
6
+ * `responsive`). It owns **no primitive properties** — the property pipeline never runs for it.
7
+ */
8
+ import type { RecipeBlock } from "../../core/normalize";
9
+ /**
10
+ * One value in a component `css` delta. **Literal-first**: a bare `string` is a raw CSS value
11
+ * (`display: "flex"`), a `number` is a literal, and a token **reference** uses `ref("colors.on-primary")`
12
+ * (the {@link ref} helper) or the JSON-safe object form `{ ref: "colors.on-primary" }` → `var(--…)`.
13
+ * (This differs from the sibling composition fields — `colors: "solid.primary"` — where a bare string is
14
+ * always a reference: those compose tokens, the `css` block is raw CSS.)
15
+ */
16
+ export type CssDeltaValue = string | number | {
17
+ ref: string;
18
+ };
19
+ /** One component recipe variant: cross-subsystem references + an own `css` delta. */
20
+ export type ComponentsRecipeProps = {
21
+ colors?: string;
22
+ typography?: string;
23
+ layout?: string;
24
+ effects?: string;
25
+ borders?: string;
26
+ css?: Record<string, CssDeltaValue>;
27
+ [subsystem: string]: string | Record<string, CssDeltaValue> | undefined;
28
+ };
29
+ /**
30
+ * The authored `raw.components` slice (§8a). **Closed** and recipes-only — components own no
31
+ * primitive properties (the property pipeline never runs); they contribute only composition
32
+ * recipes referencing other subsystems' recipes plus an own `css` delta. Authoring type only.
33
+ */
34
+ export interface ComponentsRaw {
35
+ recipes?: RecipeBlock<ComponentsRecipeProps>;
36
+ }
37
+ /**
38
+ * The resolved class surface for one component variant — the referenced recipe classes (which
39
+ * carry their own `:hover` etc. on the shared class) followed by the component's own delta class.
40
+ * `className` is the space-joined list. Mirrors the OLD `ResolvedComponentClass` shape (`classes`
41
+ * renamed `classList`).
42
+ */
43
+ export type ResolvedComponentClass = {
44
+ className: string;
45
+ classList: string[];
46
+ };
@@ -0,0 +1,9 @@
1
+ /**
2
+ * The effects subsystem — a "regular" subsystem with no property finalize hook (values
3
+ * pass straight through the shared normalize). Iterates `raw.effects` (skipping the
4
+ * reserved `recipes` key) and interprets recipes into token-path refs (incl. the `blur`
5
+ * compound as a `{ ref, wrap: "blur" }` ref). It grows a hook, never the spine.
6
+ */
7
+ import type { Subsystem } from "../../core/subsystem";
8
+ export declare const effectsSubsystem: Subsystem;
9
+ export type { EffectsRaw, EffectsPropertyValue } from "./types";
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Effects' `interpretRecipe` hook — resolves recipe declarations to token-path Refs.
3
+ *
4
+ * An effects recipe prop names a **variant** of the matching property, but the recipe key
5
+ * differs from the token key (`boxShadow` → `shadow`, `transition` → `transitions`) — the
6
+ * resolve-key map bridges them. Each declaration lowers to a format-neutral {@link Ref}
7
+ * carrying the canonical token path (`effects.shadow.lg`, `effects.shadow` for the base) —
8
+ * **no `var(--…)` strings**; the CSS adapter maps the path to a `var(--…)` at render time.
9
+ *
10
+ * The `blur` compound is the notable reshape: the old `effects/recipes.ts` baked
11
+ * `filter: blur(var(--…))` as a `{ value }` literal that **embedded** `var()` — not format-
12
+ * neutral. Here it emits `{ ref: "effects.blur", wrap: "blur" }`; the adapter's `refToStyleValue`
13
+ * renders `ref.wrap` → `blur(var(--…))`, so the wrap lives in the adapter, not the Model.
14
+ */
15
+ import type { InterpretedRecipeVariant } from "../../core/model";
16
+ import type { NormalizedRecipeVariant } from "../../core/normalize";
17
+ import type { RecipeInterpretContext } from "../../core/subsystem";
18
+ import type { EffectsRecipeProps } from "./types";
19
+ /**
20
+ * Interpret one effects recipe variant into base + responsive/state override declarations,
21
+ * each a token-path {@link Ref}. A responsive `variant:` swap inherits the sibling's base
22
+ * declarations (via `ctx.resolveRecipeVariant`).
23
+ */
24
+ export declare const interpretEffectsRecipeVariant: (variantName: string, variant: NormalizedRecipeVariant<EffectsRecipeProps, string>, ctx: RecipeInterpretContext) => InterpretedRecipeVariant<string>;
@@ -0,0 +1,63 @@
1
+ import type { PropertyValue, RecipeBlock } from "../../core/normalize";
2
+ import type { ShadowInput, ShadowLayerInput, TransitionInput, TransitionPartInput } from "./utils";
3
+ /**
4
+ * Effects' property + recipe types. A "regular" subsystem — plain property values
5
+ * (no palette-style synthesis). Ported from the old `subsystems/effects/types.ts`,
6
+ * trimmed to the normalize / recipe surface the clean-room pipeline needs.
7
+ */
8
+ /**
9
+ * A structured object-leaf property (§15, structured-only per the 2026-07-16 amendment). The FLAT
10
+ * authoring shape: the leaf fields (`TLeaf`) sit at the property top level and ARE the (single-layer)
11
+ * base; `variants` / `responsive` / `modes` hold full leaf values (`TInput` = a flat leaf, an array
12
+ * of leaves for a multi-layer variant/mode, or the `"none"` keyword). **No `base` key** — the base is
13
+ * the top-level leaves (or `"none"` when none are authored); there is no multi-layer BASE. A bare
14
+ * `"none"` is also accepted (no shadow / no transition at all). Raw CSS strings are rejected at coerce.
15
+ */
16
+ export type StructuredProperty<TInput, TLeaf> = "none" | (TLeaf & {
17
+ variants?: Record<string, TInput>;
18
+ responsive?: Array<{
19
+ breakpoint: string;
20
+ query?: "min" | "max" | "exact";
21
+ variant?: string;
22
+ target?: string;
23
+ orientation?: "landscape" | "portrait";
24
+ } & TLeaf>;
25
+ modes?: Record<string, TInput>;
26
+ });
27
+ /** Authored box-shadow property (§15) — structured single-layer base + structured variants/modes. */
28
+ export type ShadowValue = StructuredProperty<ShadowInput, ShadowLayerInput>;
29
+ /** Authored transition property (§15) — structured single-part base + structured variants/modes. */
30
+ export type TransitionValue = StructuredProperty<TransitionInput, TransitionPartInput>;
31
+ export type BlurValue = PropertyValue<number | string>;
32
+ export type ZIndexValue = PropertyValue<number>;
33
+ export type OpacityValue = PropertyValue<number>;
34
+ /**
35
+ * An effects recipe declaration block. Each value names a **variant** of the matching
36
+ * effects property; the recipe prop key differs from the token key (`boxShadow` → `shadow`,
37
+ * `transition` → `transitions`) — the interpreter maps it via its resolve-key map. `blur` is
38
+ * a compound: it lowers to `filter: blur(var(--…))` via a `{ ref, wrap: "blur" }` ref.
39
+ */
40
+ export type EffectsRecipeProps = {
41
+ boxShadow?: string;
42
+ opacity?: string;
43
+ blur?: string;
44
+ transition?: string;
45
+ zIndex?: string;
46
+ [property: string]: string | undefined;
47
+ };
48
+ /**
49
+ * An effects property value (§8a, §15). Effects properties span plain scalars (`blur`
50
+ * `number | string`, `opacity`/`zIndex` numbers) AND the structured object-leaf properties
51
+ * `shadow` / `transitions`. An **open** authoring union — the `EffectsRaw` index signature keys
52
+ * every property to it; runtime coercion (`effects/utils.ts`) validates the concrete shape per key.
53
+ */
54
+ export type EffectsPropertyValue = PropertyValue<string | number> | ShadowValue | TransitionValue;
55
+ /**
56
+ * The authored `raw.effects` slice (§8a). An **open** map: keys are effects property names
57
+ * (`shadow`, `blur`, `transitions`, …), each an {@link EffectsPropertyValue}; the reserved
58
+ * `recipes` key is a {@link RecipeBlock} of effects recipes. Authoring type only.
59
+ */
60
+ export interface EffectsRaw {
61
+ recipes?: RecipeBlock<EffectsRecipeProps>;
62
+ [property: string]: EffectsPropertyValue | RecipeBlock<EffectsRecipeProps> | undefined;
63
+ }
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Effects value coercion (§15) — parse/validate authored shadow / transition leaves into the
3
+ * canonical, **format-neutral** Model form.
4
+ *
5
+ * Modeled on `colors/utils.ts`: a single boundary that runs at normalize time (via the subsystem's
6
+ * `coerceValue`) and turns the ergonomic authoring shapes — a flat single leaf or an array of leaves
7
+ * — into ONE canonical representation the Model carries on `Ref.struct`:
8
+ *
9
+ * - **shadow** → {@link ShadowLayer}`[]` (always an array, even single-layer); `color` kept as its
10
+ * `colors.*` token-path string (never an embedded `rgba()` — §15.1), resolved late by the adapter.
11
+ * A translucent shadow references a translucent colour (an `alpha` colour variant — §13.3).
12
+ * - **transitions** → {@link TransitionPart}`[]`; `duration`/`delay` in ms.
13
+ *
14
+ * **Structured-only (§15.2, amended 2026-07-16):** raw CSS strings are REJECTED — the ONLY accepted
15
+ * string is the keyword `"none"` (no shadow / no transition). Every other string throws a path-labelled
16
+ * error. Serialization to CSS text stays in the adapter; this module holds structure, not format. Its
17
+ * only core dependency is the shared length parser (`parseLength`, §21) — so a pinned geometry string
18
+ * (`offsetY: "1px"`) is parsed by the same grammar every length uses, rather than a duplicate here.
19
+ */
20
+ import type { ShadowLayer, TransitionPart } from "../../core/model";
21
+ /** A single authored shadow layer (flat leaf object) — geometry as a bare number (deferred, resolved by
22
+ * the §21 unit pass) or a pinned length string (`"1px"`, `"0.5rem"`) + a `colors.*` color ref
23
+ * (translucency comes from an `alpha` colour variant, not a shadow field). */
24
+ export type ShadowLayerInput = {
25
+ offsetX?: number | string;
26
+ offsetY?: number | string;
27
+ blur?: number | string;
28
+ spread?: number | string;
29
+ color?: string;
30
+ inset?: boolean;
31
+ };
32
+ /** An authored shadow value: a flat single layer, an array of layers, or the `"none"` keyword. */
33
+ export type ShadowInput = "none" | ShadowLayerInput | ShadowLayerInput[];
34
+ /** A single authored transition part — `property` (required) + ms durations + timing keyword. */
35
+ export type TransitionPartInput = {
36
+ property?: string;
37
+ duration?: number;
38
+ timingFunction?: string;
39
+ delay?: number;
40
+ };
41
+ /** An authored transition value: a flat single part, an array of parts, or the `"none"` keyword. */
42
+ export type TransitionInput = "none" | TransitionPartInput | TransitionPartInput[];
43
+ /** The canonical Model form of a shadow value — an array of layers, or the `"none"` keyword. */
44
+ export type ShadowCanonical = "none" | ShadowLayer[];
45
+ /** The canonical Model form of a transition value — an array of parts, or the `"none"` keyword. */
46
+ export type TransitionCanonical = "none" | TransitionPart[];
47
+ /**
48
+ * Coerce an authored shadow value into its canonical Model form. A string passes through (escape
49
+ * hatch); a flat leaf becomes a one-element `ShadowLayer[]`; an array becomes a multi-layer
50
+ * `ShadowLayer[]`. `label` is the property path for friendly errors.
51
+ */
52
+ export declare const coerceShadowValue: (input: ShadowInput, label?: string) => ShadowCanonical;
53
+ /**
54
+ * Coerce an authored transition value into its canonical Model form. A string passes through; a flat
55
+ * part becomes a one-element `TransitionPart[]`; an array becomes a multi-part `TransitionPart[]`.
56
+ */
57
+ export declare const coerceTransitionValue: (input: TransitionInput, label?: string) => TransitionCanonical;
@@ -0,0 +1,21 @@
1
+ /**
2
+ * The globals subsystem (§9 — formerly `reset`).
3
+ *
4
+ * Owns **no primitive properties** and **no minted-class recipes** — it fills the Model with two
5
+ * kinds of selector-targeting rule-set:
6
+ *
7
+ * - **preset layers** (`static` + default `defaults`) — `kind:"reset"`, literal/opportunistic
8
+ * normalization the adapters render at specificity-0 (`:where(sel)`). Unchanged from `reset`.
9
+ * - **themed elements** (`elements`) — `kind:"globals"`, one rule-set per selector, carrying base
10
+ * declarations + `states`/`responsive` overrides + delta-only `variants`. The adapters render
11
+ * these at a higher tier (bare `a { }`, variant `a.subtle` / nested `&.subtle`).
12
+ *
13
+ * Element rules reuse the shared recipe normalization (`normalizeRecipeGroup`) for the genuinely
14
+ * common part — flattening `states` + `responsive` into one `overrides` list — but stay *structural*
15
+ * (a base selector + a named-variant map), not §7A recipe-sibling classes: they're elements, not
16
+ * recipes. Their token refs resolve late in each adapter and are validated up-front in `createTheme`
17
+ * (`validateGlobalsRefs`), like `components`. It grows a hook, never the spine.
18
+ */
19
+ import type { Subsystem } from "../../core/subsystem";
20
+ export declare const globalsSubsystem: Subsystem;
21
+ export type { GlobalsRaw, GlobalsPreset, GlobalsDeclValue, GlobalsDeclarations, GlobalsElement } from "./types";
@@ -0,0 +1,33 @@
1
+ /**
2
+ * The globals preset library (§9, formerly §10.1 reset) — the single, format-neutral source for the
3
+ * static normalization rule-sets and the default `h1`–`h6` → type-scale map.
4
+ *
5
+ * These produce Model {@link RuleSet}s (declarations are `{ value }` literals for the static
6
+ * layer, `{ ref }` token paths for the default heading map), so every web adapter shares one
7
+ * source (à la `color-math`) and lowers them itself. No CSS strings here — the adapter wraps
8
+ * each `selector` in `:where(…)` (specificity-0) and orders reset ahead of recipes.
9
+ *
10
+ * Layers:
11
+ * - **static** — literal-declaration rule-sets that strip UA opinions (box model, margins,
12
+ * heading sizing, list markers, form typography, media block/max-width, anchor colour).
13
+ * - **default headings** — themed rule-sets binding `h1`–`h6` to typography's ratio-generated
14
+ * `fontSize` scale variants (`typography.fontSize.4xl` …). Opportunistic: the adapter drops a
15
+ * heading whose scale step wasn't generated (a theme with a ratio-less `fontSize`).
16
+ */
17
+ import type { RuleSetGroup } from "../../core/model";
18
+ import type { GlobalsPreset } from "./types";
19
+ /** The default `h1`–`h6` themed group — each binds `font-size` to `typography.fontSize.<step>`. */
20
+ export declare const buildDefaultHeadingGroup: () => RuleSetGroup;
21
+ /** The recommended default preset (what `refract init` scaffolds). */
22
+ export declare const DEFAULT_GLOBALS_PRESET: Exclude<GlobalsPreset, false>;
23
+ /** The known preset names — for validation / error messages. */
24
+ export declare const GLOBALS_PRESET_NAMES: ReadonlyArray<Exclude<GlobalsPreset, false>>;
25
+ /**
26
+ * Expand a preset name into its `{ static, defaults? }` rule-set groups. `false` yields no groups
27
+ * (elements-only). An unknown name throws (typo detection). The default heading group is included
28
+ * only when the preset opts into it (`preflight` / `reset`, not `normalize`).
29
+ */
30
+ export declare const expandPreset: (preset: GlobalsPreset) => {
31
+ static?: RuleSetGroup;
32
+ defaults?: RuleSetGroup;
33
+ };
@@ -0,0 +1,48 @@
1
+ /**
2
+ * The globals subsystem's authoring types (§9).
3
+ *
4
+ * `globals` owns the bare-element layer: a **preset** (opinionated static normalization + a default
5
+ * `h1`–`h6` map bound to the type scale) plus **themed element rules** (`elements`) bound to raw
6
+ * selectors. An element rule is a recipe *item* (declarations + `states` / `responsive` / `variants`),
7
+ * not a two-level recipe group — the selector IS the leaf. Authoring type only; the subsystem lowers
8
+ * it to Model rule-sets (`kind:"reset"` for the preset layer, `kind:"globals"` for elements) that each
9
+ * web adapter renders.
10
+ */
11
+ import type { RecipeVariantDefinition, GlobalsElementVariantModifier } from "../../core/normalize";
12
+ /** The built-in normalization preset names. `false` disables the static + default layers (elements only). */
13
+ export type GlobalsPreset = "preflight" | "normalize" | "reset" | false;
14
+ /**
15
+ * One themed-element declaration value (§9) — components' `CssDeltaValue`, minus cross-subsystem
16
+ * composition refs. **Literal-first**: a bare `string` is a raw CSS value (`textDecoration: "underline"`),
17
+ * a `number` is a literal, and a token **reference** uses `ref("colors.link")` or the JSON-safe object
18
+ * form `{ ref: "colors.link" }` → `var(--…)`. Flat leaves bound to a selector, never the class-list
19
+ * composition of `components`.
20
+ */
21
+ export type GlobalsDeclValue = string | number | {
22
+ ref: string;
23
+ };
24
+ /** The flat declaration map a globals element instantiates the recipe-item shape's `TProps` with. */
25
+ export type GlobalsDeclarations = Record<string, GlobalsDeclValue>;
26
+ /**
27
+ * One themed element rule (§9) — the recipe-item shape ({@link RecipeVariantDefinition}) instantiated
28
+ * with flat globals leaves: base declarations plus the three condition axes `states` / `responsive` /
29
+ * `variants`. There is **no `modes` axis** — light/dark rides the referenced token's own modes. Each
30
+ * `variants` entry is a delta-only modifier the adapters render as a higher-specificity variant of the
31
+ * element (CSS `a.subtle`, styled-components / SCSS nested `&.subtle`).
32
+ */
33
+ export type GlobalsElement = RecipeVariantDefinition<GlobalsDeclarations, string, GlobalsElementVariantModifier<GlobalsDeclarations, string>>;
34
+ /**
35
+ * The authored `rawTheme.globals` slice (§9).
36
+ *
37
+ * - `preset` — the normalization base (`"preflight" | "normalize" | "reset" | false`). The key is
38
+ * `preset` (not `reset`) because a `reset: "reset"` collides with the `"reset"` value. There is **no
39
+ * bare-string shorthand** — the one form is `globals: { preset }`. The preset expands the static
40
+ * layer (+ a default `h1`–`h6` heading map for `preflight` / `reset`); it must be explicit for those
41
+ * layers to emit, so a bare `{ elements }` (no `preset` key) emits only the themed element rules and
42
+ * an `override({ globals: { elements } })` inherits the parent's preset.
43
+ * - `elements` — selector → themed element rule.
44
+ */
45
+ export interface GlobalsRaw {
46
+ preset?: GlobalsPreset;
47
+ elements?: Record<string, GlobalsElement>;
48
+ }
@@ -0,0 +1,21 @@
1
+ /** Subsystems: colors · typography · layout · effects · borders · animation · components · globals. Wired in Steps 1–4 / §10.2 / §14 / §9. */
2
+ export { colorsSubsystem } from "./colors";
3
+ /** Contrast audit (WCAG 2 + advisory APCA) — reads a built theme, reports/strict-throws. */
4
+ export { audit } from "./colors";
5
+ export type { AuditResult, AuditOptions, PairingScore, PairingKind, WcagLevel } from "./colors";
6
+ export { typographySubsystem } from "./typography";
7
+ export { layoutSubsystem } from "./layout";
8
+ export { effectsSubsystem } from "./effects";
9
+ export { bordersSubsystem } from "./borders";
10
+ export { animationSubsystem } from "./animation";
11
+ export { componentsSubsystem } from "./components";
12
+ export { globalsSubsystem } from "./globals";
13
+ /** Per-subsystem raw authoring-input types (§8a) — composed into `RawTheme`. */
14
+ export type { ColorsRaw } from "./colors";
15
+ export type { TypographyRaw, TypographyPropertyValue } from "./typography";
16
+ export type { EffectsRaw, EffectsPropertyValue } from "./effects";
17
+ export type { BordersRaw, BordersPropertyValue } from "./borders";
18
+ export type { AnimationRaw } from "./animation";
19
+ export type { LayoutRaw, ContainerRaw, ContainerVariantRaw } from "./layout";
20
+ export type { ComponentsRaw } from "./components";
21
+ export type { GlobalsRaw, GlobalsPreset, GlobalsDeclValue, GlobalsDeclarations, GlobalsElement } from "./globals";
@@ -0,0 +1,14 @@
1
+ /**
2
+ * The layout subsystem — the biggest one, with three parts:
3
+ * 1. Regular property tokens (`spacing` / `gutters` / `aspectRatio`) — like typography/effects,
4
+ * plus the forced `none` variant on spacing/gutters (`finalizeLayoutNormalization`).
5
+ * 2. Recipes (`padding` / `section`) — ordinary token-path recipes (`interpretRecipe`).
6
+ * 3. Structural generators (`columns` / `grids` / `stacks` / `container`) — emitted as native
7
+ * Model rule-sets via the `buildStructural` hook (see `structural.ts`), with the columns/
8
+ * container config knobs riding along as `configProperties` (Model `extraProperties`).
9
+ *
10
+ * It grows the spine's hooks (`interpretRecipe`, `buildStructural`), never the spine's control flow.
11
+ */
12
+ import type { Subsystem } from "../../core/subsystem";
13
+ export declare const layoutSubsystem: Subsystem;
14
+ export type { LayoutRaw, ContainerRaw, ContainerVariantRaw } from "./types";
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Layout's `normalizeProperty` hook — numeric scale synthesis (§10.6) + the forced `none` variant.
3
+ *
4
+ * `spacing` / `gutters` / `sizes` can synthesize their variant ramp from a base + a curve, the same
5
+ * way colors generates tonal steps and typography the type scale:
6
+ * - **geometric** (`ratio`) — `base × ratio^n`, `steps` an ordered name array (index = exponent);
7
+ * - **linear** (`step`) — `step × n`, `steps` a name→multiplier map (the 4/8-pt grid).
8
+ *
9
+ * Each synthesized step is stored as a **derived** variant (`{ base, derive:{ ref, fn:"scaleStep",
10
+ * arg } }`) so the Model carries it as a re-resolving `Ref` — `override()` of the base re-synthesizes
11
+ * every step (mirror colors, NOT typography's frozen literals). A ramp entry inside a property's
12
+ * `responsive` list (D6) regenerates the WHOLE named scale at that breakpoint, expanding into one
13
+ * `target` override per step — the already-existing responsive channel, no new Model member.
14
+ *
15
+ * Synthesis is **opt-in + additive**: absent a `ratio`/`step`, behaviour is byte-identical to before
16
+ * (spacing/gutters still get the forced `none`; sizes/aspectRatio pass through). Authored `variants`
17
+ * always win over synthesized ones — the way sizes' semantic caps (`prose`) and pinned values
18
+ * (`full: "100%"`, no magnitude → never synthesized) coexist with the ramp.
19
+ */
20
+ import type { NormalizedPropertyValue } from "../../core/normalize";
21
+ import type { Literal } from "../../core/model";
22
+ /**
23
+ * The `scaleStep` derivation fn (registered by the layout subsystem). Re-derives a synthesized step
24
+ * from its curve config: **geometric** `base × ratio^exp` (from the resolved base token, so an
25
+ * `override()` of the base rescales it), **linear** `step × mult` (a fixed grid, self-contained in
26
+ * `arg`). A responsive ramp step with an explicit breakpoint base carries it on `arg.base`, so it
27
+ * derives from its own breakpoint base (precedent: colors' appearance modes). Mirrors the way the
28
+ * derivation registry hands every fn `(resolvedValue, arg)`.
29
+ */
30
+ export declare const scaleStep: (value: Literal, arg?: unknown) => Literal;
31
+ /**
32
+ * @param propertyKey The layout property being normalized.
33
+ * @param normalized The property after the shared property normalize pass.
34
+ */
35
+ export declare const finalizeLayoutNormalization: (propertyKey: string, normalized: NormalizedPropertyValue<unknown>) => NormalizedPropertyValue<unknown>;