@theme-registry/refract 0.1.2 → 0.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +17 -1
- package/dist/build/createCommand.d.ts +47 -0
- package/dist/build/createInterview.d.ts +56 -0
- package/dist/build/index.d.ts +4 -0
- package/dist/build/init.d.ts +42 -0
- package/dist/build/prompt.d.ts +76 -0
- package/dist/build/scaffold.d.ts +146 -0
- package/dist/build.cjs.js +1 -1
- package/dist/build.cjs.js.map +1 -1
- package/dist/build.esm.js +1 -1
- package/dist/build.esm.js.map +1 -1
- package/dist/cli.js +1139 -14
- package/dist/cli.js.map +1 -1
- package/package.json +1 -1
- package/skills/theme-authoring/SKILL.md +3 -0
- package/skills/theme-scaffold/SKILL.md +130 -0
package/dist/build.esm.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"build.esm.js","sources":["../src/build/vendor.ts","../src/build/paths.ts","../src/build/guide.ts","../src/core/errors.ts","../src/core/model/buildModel.ts","../src/core/units.ts","../src/core/normalize/responsive.ts","../src/core/normalize/properties.ts","../src/core/normalize/recipes.ts","../src/core/normalize/recipeResolver.ts","../src/core/derive/resolveTokens.ts","../src/core/derive/crossProperty.ts","../src/core/media/descriptors.ts","../src/core/media/queries.ts","../src/core/media/defaults.ts","../src/core/media/containers.ts","../src/subsystems/colors/utils.ts","../src/subsystems/colors/keywords.ts","../src/subsystems/colors/colorInput.ts","../src/subsystems/colors/normalize.ts","../src/core/cssProperties.ts","../src/subsystems/colors/recipes.ts","../src/subsystems/colors/audit.ts","../src/subsystems/colors/index.ts","../src/subsystems/typography/normalize.ts","../src/subsystems/typography/recipes.ts","../src/subsystems/typography/index.ts","../src/subsystems/layout/types.ts","../src/subsystems/layout/normalize.ts","../src/subsystems/layout/recipes.ts","../src/subsystems/layout/structural.ts","../src/subsystems/layout/index.ts","../src/subsystems/effects/recipes.ts","../src/subsystems/effects/utils.ts","../src/subsystems/effects/index.ts","../src/subsystems/borders/recipes.ts","../src/subsystems/borders/index.ts","../src/subsystems/animation/recipes.ts","../src/subsystems/animation/index.ts","../src/subsystems/components/recipes.ts","../src/subsystems/components/index.ts","../src/subsystems/globals/presets.ts","../src/subsystems/globals/index.ts","../src/core/createTheme.ts","../src/build/emit.ts","../src/dtcg/types.ts","../src/dtcg/parse.ts","../src/core/defineAdapter.ts","../src/core/noopAdapter.ts","../src/dtcg/import.ts","../src/dtcg/export.ts","../src/build/emitTheme.ts","../src/build/config.ts","../src/build/init.ts","../src/build/importCommand.ts","../src/build/buildCommand.ts","../src/build/tokensCommand.ts","../src/build/auditCommand.ts","../src/build/diff.ts","../src/build/diffCommand.ts","../src/core/assertRawTheme.ts","../src/build/skillsCommand.ts","../src/build/cli.ts"],"sourcesContent":["/**\n * Vendorable-helper registry (build-time, Node-only) — the SINGLE source of truth for which live\n * helper modules get shipped into a consumer's build output.\n *\n * Option A vendoring (locked 2026-07-11): a helper is authored ONCE in its natural home (e.g.\n * `lighten`/`darken` in `src/subsystems/colors/utils.ts`) and stays there for refract's own\n * runtime use. This registry merely POINTS at that source; the build layer (`src/build/`, added in\n * 10b) transpiles it (type-strip) and writes the standalone result to the consumer's output. There\n * is NO second copy of the function bodies anywhere, so drift is structurally impossible.\n *\n * Requirement on a listed source: it must be **self-contained** (import-free, or its imports are\n * themselves vendored) so the transpiled artifact is standalone — the \"package not needed at\n * runtime\" promise. `test/color-math.test.ts` asserts this for `color-math`.\n *\n * This module is build metadata (plain data, no `node:fs`), deliberately NOT re-exported from the\n * runtime `.` barrel — it belongs to the Node-only build/CLI surface (the `./build` subpath, 10e).\n *\n * NOTE (packaging, resolved in 10b): `source` is repo-relative. The published package ships only\n * `dist/`, so the build layer will either ship these helper sources or read a built standalone\n * artifact; that resolution detail is 10b's, not baked in here.\n */\n\n/** A shared, static helper refract can vendor into a consumer's build output. */\nexport interface VendorHelperSource {\n /** Stable id — also the key a build target opts in by. */\n readonly id: string;\n /** Filename written into the consumer's output directory. */\n readonly outfile: string;\n /** Repo-relative path to the single-source module whose transpiled output is the vendored artifact. */\n readonly source: string;\n /** The named exports the vendored module provides (for docs / validation). */\n readonly exports: readonly string[];\n /** What the helper is for. */\n readonly description: string;\n}\n\n/** The shared vendorable helpers. Theme-specific helpers (e.g. the SC media module with baked\n * `@media` strings) are NOT here — those are generated per-theme by the owning adapter's `emit()`. */\nexport const VENDOR_HELPERS: readonly VendorHelperSource[] = [\n {\n id: \"color-math\",\n outfile: \"color-math.js\",\n source: \"src/subsystems/colors/utils.ts\",\n exports: [\n \"lighten\",\n \"darken\",\n \"alpha\",\n \"setL\",\n \"rotateHue\",\n \"complement\",\n \"adjust\",\n \"rgbToOklch\",\n \"oklchToRgb\",\n \"toHexColor\",\n \"toOklchColor\",\n \"convertHexToRGB\",\n \"convertRgbToHex\",\n ],\n description:\n \"Pure OKLCH colour math — the exact lighten/darken/setL/rotateHue/complement/adjust (+ OKLCH and hex converters) refract synthesizes palette steps/variants with, so a value computed live in the consumer matches the emitted CSS variables.\",\n },\n];\n\n/** Look up a vendorable helper by id. */\nexport const findVendorHelper = (id: string): VendorHelperSource | undefined =>\n VENDOR_HELPERS.find(h => h.id === id);\n","/**\n * Build-layer path + transpile helpers (Node-only).\n *\n * Two jobs, both needed to materialize Option-A vendored helpers (§7 10a/10b): locate a\n * vendorable source's single origin (which lives in the package, NOT a second copy) and\n * type-strip it to a standalone ES module the consumer's build output can drop in.\n *\n * Packaging (resolved 2026-07-11): `VENDOR_HELPERS[].source` is package-root-relative. The\n * published package ships only `dist/`, so the vendorable sources are added to `package.json#files`\n * and this module resolves them against the discovered package root — working the SAME way in-repo\n * (root = repo root) and installed (root = the installed package dir).\n */\nimport { existsSync, readFileSync, rmSync, writeFileSync } from \"node:fs\";\nimport { basename, dirname, join, resolve } from \"node:path\";\nimport type ts from \"typescript\";\n\n/** Walk up from `startDir` to the first ancestor that contains a `package.json`. */\nexport const findPackageRoot = (startDir: string = __dirname): string => {\n let dir = startDir;\n for (;;) {\n if (existsSync(join(dir, \"package.json\"))) return dir;\n const parent = dirname(dir);\n if (parent === dir) {\n throw new Error(`No package.json found walking up from \"${startDir}\".`);\n }\n dir = parent;\n }\n};\n\n/** Read a package-root-relative vendorable source (must ship via `package.json#files`). */\nexport const readVendorSource = (source: string): string => {\n const path = join(findPackageRoot(), source);\n if (!existsSync(path)) {\n throw new Error(\n `Vendor helper source \"${source}\" not found at \"${path}\". ` +\n `Ensure it is listed in package.json \"files\" so it ships with the package.`,\n );\n }\n return readFileSync(path, \"utf8\");\n};\n\n/**\n * Lazily resolve the `typescript` peer (Step 10e). `typescript` is an OPTIONAL peer dependency — a\n * consumer who only uses the runtime (`createTheme` + adapters), `./dtcg`, or a `.mjs`/`.js` config\n * with the CSS `emit()` never needs it. It's pulled in ONLY on the two paths that actually transpile\n * TS: loading a `.ts` config and vendoring a shared helper module. If it's absent when one of those\n * runs, we throw a clear, actionable error instead of an opaque module-resolution failure.\n */\nasync function loadTypescript(): Promise<typeof ts> {\n try {\n const mod = (await import(\"typescript\")) as unknown as { default?: typeof ts } & typeof ts;\n return mod.default ?? mod;\n } catch {\n throw new Error(\n 'refract: the optional peer dependency \"typescript\" is required to transpile a `.ts` ' +\n \"theme.config or vendor a shared helper module, but it could not be resolved. Install it \" +\n \"(`npm i -D typescript`), or use a `.mjs`/`.js` config and avoid the `helpers` opt-in.\",\n );\n }\n}\n\n/**\n * Type-strip a self-contained TS module to standalone ESM — exactly what the 10a gate proves the\n * vendored artifact does. Reused for the `.ts` config loader (types stripped, `import`s preserved).\n *\n * Async because it lazy-loads the optional `typescript` peer (see {@link loadTypescript}); the\n * `.mjs`/`.js` config + CSS `emit()` paths never call it, so those work with `typescript` absent.\n */\nexport const transpileToEsm = async (sourceText: string): Promise<string> => {\n const tsc = await loadTypescript();\n return tsc.transpileModule(sourceText, {\n compilerOptions: { module: tsc.ModuleKind.ESNext, target: tsc.ScriptTarget.ES2020 },\n }).outputText;\n};\n\n/** The result of a graph compile: the emitted entry to import + a cleanup that unlinks every temp file. */\nexport interface CompiledTsGraph {\n /** Absolute path of the emitted config entry (an adjacent hidden `.mjs`) to dynamically import. */\n readonly entry: string;\n /** Remove every emitted temp file — call in a `finally` after importing `entry`. */\n readonly cleanup: () => void;\n}\n\n// Module-local counter keeps concurrent emit-file names unique without Date/Math.random.\nlet graphCounter = 0;\n\n/** Extension-stripped absolute key so a source `.ts` and its emitted `.js` name map to one entry. */\nconst graphKey = (p: string): string =>\n resolve(p).replace(/\\.(ts|tsx|mts|cts|js|jsx|mjs|cjs)$/, \"\");\n\n/**\n * Compile a `.ts` theme config **and its local relative `.ts` graph** to standalone ESM so a `.ts`\n * config can `import` a sibling `theme.raw.ts` (§8b — the 8a `RawTheme` payoff). Upgrades the old\n * single-file `transpileToEsm` path to a `ts.createProgram` compile: relative `.ts`/`.tsx`/`.mts`/\n * `.cts` imports are followed + compiled; **bare specifiers and relative `.mjs`/`.js`/`.json` stay\n * external** (untouched — resolved at their original location).\n *\n * **Adjacent-per-file emit** (settled 2026-07-11, supersedes the kickoff's temp-subdir): each compiled\n * source emits to a hidden unique `.<base>.<pid>-<n>.mjs` **next to its own source**. That's the one\n * layout where a mixed graph resolves — the emitted config sits in the original dir, so bare imports\n * resolve up to the project's `node_modules`, uncompiled relative siblings (`./adapter.mjs`,\n * `./tokens.json`) resolve adjacent, and compiled siblings resolve to their emitted `.mjs`. Parent-dir\n * imports (`../shared/theme.raw`) need no `rootDir`→`outDir` mapping — each file emits by its own source.\n *\n * A `before` transformer rewrites relative specifiers that resolve to a **compiled** source to its\n * emitted `.mjs` (so extensionless `./theme.raw` → `./.theme.raw.<pid>-<n>.mjs`); `.json` / `.mjs` /\n * `.js` / bare specifiers are left untouched (their `with { type: \"json\" }` attributes preserved).\n * No type-checking — diagnostics are ignored (`noEmitOnError: false`); this is a transpile, not a build.\n *\n * `paths`/tsconfig aliases are **NOT** resolved in v1 (a fixed `compilerOptions` set; the user's\n * tsconfig is ignored) — documented limitation.\n */\nexport const compileTsConfigGraph = async (configPath: string): Promise<CompiledTsGraph> => {\n const tsc = await loadTypescript();\n const options: ts.CompilerOptions = {\n module: tsc.ModuleKind.ESNext,\n target: tsc.ScriptTarget.ES2020,\n moduleResolution: tsc.ModuleResolutionKind.Bundler,\n resolveJsonModule: true,\n allowJs: false,\n noLib: true,\n skipLibCheck: true,\n noEmitOnError: false,\n declaration: false,\n sourceMap: false,\n types: [],\n };\n\n const host = tsc.createCompilerHost(options);\n const program = tsc.createProgram([configPath], options, host);\n\n // Map each compiled TS source (config + its relative `.ts` graph) → an adjacent hidden temp `.mjs`.\n const tempFor = new Map<string, string>();\n const isCompiledTs = (sf: ts.SourceFile): boolean =>\n !sf.isDeclarationFile &&\n !sf.fileName.includes(\"/node_modules/\") &&\n /\\.(ts|tsx|mts|cts)$/.test(sf.fileName);\n for (const sf of program.getSourceFiles()) {\n if (!isCompiledTs(sf)) continue;\n const abs = resolve(sf.fileName);\n const base = basename(abs).replace(/\\.(ts|tsx|mts|cts)$/, \"\");\n tempFor.set(graphKey(abs), join(dirname(abs), `.${base}.${process.pid}-${graphCounter++}.mjs`));\n }\n\n // Does this relative specifier resolve to one of the compiled sources? → its emitted `.mjs`, else undefined.\n const rewriteTarget = (spec: string, containingFile: string): string | undefined => {\n if (!spec.startsWith(\".\")) return undefined; // bare → external\n const resolved = tsc.resolveModuleName(spec, containingFile, options, host).resolvedModule\n ?.resolvedFileName;\n return resolved ? tempFor.get(graphKey(resolved)) : undefined;\n };\n\n // Rewrite relative import/export/dynamic-import specifiers that point at a compiled source.\n const rewrite: ts.TransformerFactory<ts.SourceFile> = context => sourceFile => {\n const containing = resolve(sourceFile.fileName);\n const factory = context.factory;\n const specFor = (text: string): ts.StringLiteral | undefined => {\n const temp = rewriteTarget(text, containing);\n return temp ? factory.createStringLiteral(`./${basename(temp)}`) : undefined;\n };\n const visit = (node: ts.Node): ts.Node => {\n if (tsc.isImportDeclaration(node) && tsc.isStringLiteral(node.moduleSpecifier)) {\n const next = specFor(node.moduleSpecifier.text);\n if (next) {\n return factory.updateImportDeclaration(\n node,\n node.modifiers,\n node.importClause,\n next,\n node.attributes,\n );\n }\n } else if (\n tsc.isExportDeclaration(node) &&\n node.moduleSpecifier &&\n tsc.isStringLiteral(node.moduleSpecifier)\n ) {\n const next = specFor(node.moduleSpecifier.text);\n if (next) {\n return factory.updateExportDeclaration(\n node,\n node.modifiers,\n node.isTypeOnly,\n node.exportClause,\n next,\n node.attributes,\n );\n }\n } else if (\n tsc.isCallExpression(node) &&\n node.expression.kind === tsc.SyntaxKind.ImportKeyword &&\n node.arguments.length &&\n tsc.isStringLiteral(node.arguments[0])\n ) {\n const next = specFor(node.arguments[0].text);\n if (next) {\n return factory.updateCallExpression(node, node.expression, node.typeArguments, [\n next,\n ...node.arguments.slice(1),\n ]);\n }\n }\n return tsc.visitEachChild(node, visit, context);\n };\n return tsc.visitNode(sourceFile, visit) as ts.SourceFile;\n };\n\n // Redirect TS's computed `<source>.js` emit to the adjacent hidden `.mjs` (forces ESM regardless of\n // the project's `package.json#type`); ignore anything unexpected.\n const written: string[] = [];\n const writeFile: ts.WriteFileCallback = (fileName, text) => {\n const target = tempFor.get(graphKey(fileName));\n if (!target) return;\n writeFileSync(target, text, \"utf8\");\n written.push(target);\n };\n\n const cleanup = (): void => {\n for (const file of written) rmSync(file, { force: true });\n };\n\n try {\n program.emit(undefined, writeFile, undefined, false, { before: [rewrite] });\n } catch (err) {\n cleanup();\n throw err;\n }\n\n const entry = tempFor.get(graphKey(configPath));\n if (!entry || !existsSync(entry)) {\n cleanup();\n throw new Error(`refract: failed to compile the \\`.ts\\` config graph for \"${configPath}\".`);\n }\n return { entry, cleanup };\n};\n","/**\n * Self-documenting theme output (Node-only) — render an `llms.txt` consumption guide + a\n * `manifest.json` index from an adapter's {@link UsageDescriptor} and a DTCG token export.\n *\n * The point: a theme built by refract is often shipped onward as a published package, a zip / CI\n * artifact, or a vendored folder to developers who have **neither refract nor its skills** (and may\n * not know refract exists). These two files travel *inside* `outDir`, so they accompany any\n * distribution form, and they name the theme's REAL class names / export ids / token paths — a\n * downstream agent consumes the theme from the folder alone, never guessing an identifier.\n *\n * Distribution-agnostic by construction: references are **relative** by default (`./theme.css`); the\n * `@scope/name` import form is added only as an overlay when a package name is configured (a zip has\n * no package specifier, so it must not be assumed).\n */\nimport type { UsageDescriptor } from \"../core/ThemeAdapter\";\n\n/** How many recipe rows to inline into `llms.txt` before deferring the rest to `manifest.json`. */\nconst LLMS_RECIPE_CAP = 60;\n\nexport interface GuideOptions {\n /** The static file names emitted for this target (relative), so the guide points at real artifacts. */\n readonly files: readonly string[];\n /** The published package specifier, if any — adds an import-by-specifier overlay to the prose. */\n readonly packageName?: string;\n /** Output name for the narrative guide (default `\"llms.txt\"`). */\n readonly llmsFile?: string;\n /** Output name for the machine index (default `\"manifest.json\"`); `false` suppresses it. */\n readonly manifestFile?: string | false;\n}\n\nexport interface GuideOutput {\n /** filename → contents, ready for the build layer to write into `outDir`. */\n readonly files: Record<string, string>;\n}\n\nconst escapeCell = (s: string): string => s.replace(/\\|/g, \"\\\\|\");\n\n/** Render the `llms.txt` narrative. */\nfunction renderLlms(descriptor: UsageDescriptor, options: GuideOptions, manifestName: string | false): string {\n const lines: string[] = [];\n lines.push(`# Theme consumption guide (${descriptor.format})`);\n lines.push(\"\");\n lines.push(\n \"This folder is a self-contained theme built with refract. You do NOT need refract to use it —\",\n \"everything below refers to files in THIS folder (relative paths), so it works whether the theme\",\n \"was installed as a package, unzipped from an artifact, or vendored into a repo.\",\n );\n lines.push(\"\");\n\n if (options.files.length > 0) {\n lines.push(\"## Files\");\n lines.push(\"\");\n for (const f of options.files) lines.push(`- \\`./${f}\\``);\n lines.push(\"\");\n }\n\n lines.push(\"## How to use\");\n lines.push(\"\");\n for (const s of descriptor.summary) lines.push(s);\n if (options.packageName) {\n lines.push(\"\");\n lines.push(\n `If this theme is installed as the \\`${options.packageName}\\` package, you may import the same`,\n `files by specifier (e.g. \\`${options.packageName}/${options.files[0] ?? \"theme.css\"}\\`) instead of by relative path.`,\n );\n }\n lines.push(\"\");\n\n const { recipes } = descriptor;\n if (recipes.length > 0) {\n lines.push(\"## Recipes — real names\");\n lines.push(\"\");\n lines.push(\"Use these exact identities; do not invent names.\");\n lines.push(\"\");\n lines.push(\"| Recipe | Identity |\");\n lines.push(\"| --- | --- |\");\n const shown = recipes.slice(0, LLMS_RECIPE_CAP);\n for (const r of shown) {\n lines.push(`| \\`${escapeCell(`${r.subsystem}.${r.group}.${r.variant}`)}\\` | \\`${escapeCell(r.name)}\\` |`);\n }\n if (recipes.length > shown.length) {\n const rest = recipes.length - shown.length;\n lines.push(\"\");\n lines.push(\n `_(+${rest} more recipe(s) — the complete list is in ${manifestName ? `\\`./${manifestName}\\`` : \"the manifest\"}.)_`,\n );\n }\n lines.push(\"\");\n }\n\n if (manifestName) {\n lines.push(\"## Machine-readable index\");\n lines.push(\"\");\n lines.push(`See \\`./${manifestName}\\` for the full recipe index and the theme's tokens (DTCG format).`);\n lines.push(\"\");\n }\n\n return lines.join(\"\\n\");\n}\n\n/**\n * Build the guide artifacts. `tokens` is a DTCG document (from `toDTCG`) embedded verbatim into the\n * manifest so the machine index carries every token path + value beside the recipe identities.\n */\nexport function buildGuide(\n descriptor: UsageDescriptor,\n tokens: unknown,\n options: GuideOptions,\n): GuideOutput {\n const llmsName = options.llmsFile ?? \"llms.txt\";\n const manifestName = options.manifestFile === undefined ? \"manifest.json\" : options.manifestFile;\n\n const files: Record<string, string> = {\n [llmsName]: renderLlms(descriptor, options, manifestName),\n };\n\n if (manifestName) {\n const manifest = {\n schema: 1,\n format: descriptor.format,\n files: options.files,\n packageName: options.packageName,\n recipes: descriptor.recipes,\n tokens,\n };\n files[manifestName] = `${JSON.stringify(manifest, null, 2)}\\n`;\n }\n\n return { files };\n}\n","/**\n * Stable, machine-readable error codes (§P2-3). Every error refract throws for a theme authoring /\n * build problem — everything reachable from {@link createTheme} (subsystem normalization, token\n * derivation, DTCG parsing) — is a {@link RefractError} carrying a `code` from {@link RefractErrorCode}:\n * a stable identifier an agent (or a catch block) can branch on without string-matching the human\n * message. The message text stays human-first and unchanged; the code is additive.\n *\n * Scope: authoring/build errors. Pure CLI-tooling failures in `src/build/*` (bad arguments, a missing\n * file, an unknown command) stay plain `Error`s — they're usage errors from `refract <cmd>`, not a\n * problem with the theme an agent is editing. The one build-layer exception is `REFRACT_E_RAW_SHAPE`:\n * a value handed to `diff` / `validate` (or the MCP server) where a `RawTheme` is required but the\n * value isn't theme-shaped — that IS a theme problem, and a governance tool must fail loud + coded on\n * it (see {@link assertRawTheme}) rather than emit a nonsense \"everything removed\" diff at exit 0.\n *\n * Dependency-free leaf on purpose, so any module (including the standalone `adapter-kit`) can throw one\n * without pulling in the core graph.\n */\nexport type RefractErrorCode =\n | \"REFRACT_E_COLOR_INPUT\" // a colour value wasn't a derivable colour\n | \"REFRACT_E_COLOR_TUPLE\" // an [r,g,b] tuple was malformed\n | \"REFRACT_E_STEPS\" // colors.<name>.steps out of range / non-numeric\n | \"REFRACT_E_VARIANT\" // a derivation-spec variant / modifier chain was malformed\n | \"REFRACT_E_VARIANT_REF\" // a variant referenced an unknown source\n | \"REFRACT_E_CYCLE\" // a cyclic reference (colour variant, token, recipe, DTCG alias)\n | \"REFRACT_E_ADJUST\" // an adjust dial was out of range\n | \"REFRACT_E_HARMONY\" // an invalid harmony scheme\n | \"REFRACT_E_VALIDATION\" // aggregate: one or more post-build ref-validation failures (see `failures`)\n | \"REFRACT_E_RECIPE_PROPERTY\" // a recipe declaration key is neither a known CSS property nor a reserved key\n | \"REFRACT_E_TOKEN_PATH\" // a token path is unknown / malformed / uses an unknown derivation fn\n | \"REFRACT_E_BREAKPOINT\" // a responsive entry omitted or named an unknown breakpoint\n | \"REFRACT_E_STATE\" // a recipe state entry named a state the adapter doesn't know\n | \"REFRACT_E_CONTAINER\" // a container-query entry named an unknown container / size / unsupported axis\n | \"REFRACT_E_RESPONSIVE\" // a responsive/mode override was malformed (variant+target conflict, unknown ref)\n | \"REFRACT_E_MEDIA\" // an invalid media / container query range (min > max)\n | \"REFRACT_E_MODE\" // an appearance-mode override with no base to override\n | \"REFRACT_E_PRESET\" // an unknown globals preset name\n | \"REFRACT_E_EFFECTS\" // a malformed effects value (shadow / transition layer)\n | \"REFRACT_E_LAYOUT\" // a malformed layout scale (ratio+step, bad rung)\n | \"REFRACT_E_UNITS\" // a malformed units config\n | \"REFRACT_E_PROPERTY\" // a property couldn't be normalized (no resolvable base value)\n | \"REFRACT_E_REFERENCE\" // a composition / rule-set reference didn't resolve\n | \"REFRACT_E_NAMING\" // a naming override / default path produced a collision\n | \"REFRACT_E_DTCG_VERSION\" // an unreadable DTCG refract-extension version\n | \"REFRACT_E_AUDIT\" // a strict contrast audit failed\n | \"REFRACT_E_RAW_SHAPE\"; // a value passed where a RawTheme is required isn't theme-shaped (e.g. a defineConfig, an array, null)\n\n/**\n * An authoring / build error with a stable {@link RefractErrorCode}. For an aggregate (collect-all)\n * error, `failures` lists each individual message so a caller can report them all at once.\n */\nexport class RefractError extends Error {\n readonly code: RefractErrorCode;\n readonly failures?: readonly string[];\n\n constructor(code: RefractErrorCode, message: string, failures?: readonly string[]) {\n super(message);\n this.name = \"RefractError\";\n this.code = code;\n if (failures) this.failures = failures;\n // Keep `instanceof RefractError` working after transpilation to ES5-ish targets.\n Object.setPrototypeOf(this, RefractError.prototype);\n }\n}\n","/**\n * Model builder (clean-room port of `core/common/buildModel.ts`).\n *\n * Pure functions that assemble the format-neutral {@link ThemeModel} from data the\n * pipeline computes — the normalized property collections and the interpreted recipe\n * groups. `buildThemeModel` consumes each subsystem's already-interpreted rule-set\n * groups (see `buildRuleSetGroupFromInterpreted`), whose declarations already carry\n * format-neutral {@link Ref}s (`{ ref: \"colors.primary\" }` for a token-path reference,\n * `{ value }` for a literal). The builder is a structural copy — it never string-parses\n * `var(--…)`; the interpreter emits canonical token paths directly.\n *\n * `pathify*` rewrites refs via a supplied map (used by later subsystems that still emit\n * var-name refs); `buildTokenMap` flattens the property tokens into a `path -> Ref` map.\n */\nimport type { NormalizedPropertyValue } from \"../normalize\";\nimport type { InterpretedRecipeGroup, InterpretedRecipeVariant } from \"./interpreted\";\nimport type {\n ContainerModel,\n Keyframe,\n Literal,\n PropertyModel,\n PropertyOverride,\n Ref,\n RuleSet,\n RuleSetGroup,\n RuleSetOverride,\n StructuredValue,\n SubsystemModel,\n ThemeModel,\n VariantModel,\n} from \"./model\";\nimport { RefractError } from \"../errors\";\n\nconst isLiteral = (value: unknown): value is Literal =>\n typeof value === \"string\" || typeof value === \"number\";\n\n/**\n * A structured compound value (§15) reaches the Model as an **array** of layers/parts (the owning\n * subsystem canonicalizes it in `coerceValue`). Colors serialize to a string before the Model, so\n * an array base here is unambiguously a §15 effects value → carried on `Ref.struct`.\n */\nconst isStructuredValue = (value: unknown): value is StructuredValue => Array.isArray(value);\n\nconst toRef = (value: Literal): Ref => ({ value });\n\n/**\n * A base/variant value → its `Ref`: a `Literal` becomes the `value` cache; a structured compound\n * value (§15 shadow/transition) is carried on `struct` (no single literal to cache). Used wherever\n * a value may now be structured rather than scalar.\n */\nconst valueToRef = (value: unknown): Ref =>\n isStructuredValue(value) ? { struct: value } : toRef(value as Literal);\n\n/** Build a variant `Ref`: a derived `{ ref, fn?, arg?, value }` when the normalized variant carries\n * a `derive`, else a plain literal. `value` is kept as the cached resolution (the lowering reads it). */\nconst variantToRef = (\n value: Literal | undefined,\n derive?: { ref: string; fn?: string; arg?: unknown; modifiers?: Array<{ fn: string; arg?: unknown }> },\n): Ref => {\n if (!derive) return toRef(value as Literal);\n const ref: Ref = { ref: derive.ref };\n if (derive.fn !== undefined) ref.fn = derive.fn;\n if (derive.arg !== undefined) ref.arg = derive.arg;\n if (derive.modifiers !== undefined) ref.modifiers = derive.modifiers; // dec.2 — carry the chain\n // dec.4 — a cross-property derivation arrives UNBAKED (`value` undefined); the post-build\n // `bakeCrossPropertyDerivations` pass fills it. Omit the key rather than set `value: undefined`.\n if (value !== undefined) ref.value = value;\n return ref;\n};\n\n/** Structural keys of a normalized appearance-mode override entry (`{ mode, target, base, derive,\n * …literalExtras }`) — the condition/target keys + base/derive are NOT extras. */\nconst MODE_STRUCTURAL_KEYS: ReadonlySet<string> = new Set([\"mode\", \"target\", \"base\", \"derive\"]);\n\n/**\n * One normalized appearance mode (`{ base?, derive?, …literalExtras }`) → its `field → Ref` map\n * (§10.3). `base` becomes a literal or derived `Ref` (a derived base must have been baked by the\n * owning subsystem hook — colors — so `base` and `derive.ref` are present); literal extras (e.g.\n * colors' `text`) each become a literal `Ref`. Field-keyed, mirroring a responsive override.\n */\nconst buildModeFields = (\n mode: Record<string, unknown>,\n propertyName: string,\n modeName: string,\n): Record<string, Ref> => {\n const fields: Record<string, Ref> = {};\n const derive = mode.derive as\n | { ref?: string; fn?: string; arg?: unknown; modifiers?: Array<{ fn: string; arg?: unknown }> }\n | undefined;\n const base = mode.base;\n\n if (derive) {\n // A derived mode must name a source (`derive.ref`) so it can be baked — by the owning subsystem\n // (colors) for a same-property source, or by the post-build cross-property pass for a dotted one.\n // A derive WITHOUT a ref never got a baker (e.g. a non-colors subsystem) → fail loud.\n if (derive.ref === undefined) {\n throw new RefractError(\n \"REFRACT_E_REFERENCE\",\n `Derived appearance mode \"${propertyName}.modes.${modeName}\" was not baked — derived ` +\n `modes require a subsystem that resolves them (colors). Use a literal value instead.`,\n );\n }\n // `base` is the cached resolution for a same-property source; ABSENT for a dec.4 cross-property\n // source (filled post-build by `bakeCrossPropertyDerivations`). `variantToRef` omits the value key.\n fields.base = variantToRef(\n isLiteral(base) ? base : undefined,\n derive as { ref: string; fn?: string; arg?: unknown; modifiers?: Array<{ fn: string; arg?: unknown }> },\n );\n } else if (isLiteral(base)) {\n fields.base = toRef(base);\n } else if (isStructuredValue(base)) {\n fields.base = { struct: base };\n }\n\n for (const [key, value] of Object.entries(mode)) {\n if (MODE_STRUCTURAL_KEYS.has(key)) continue;\n if (isLiteral(value)) fields[key] = toRef(value);\n }\n return fields;\n};\n\n/** Own scalar (string/number) properties of `obj`, minus `exclude`, each wrapped as a `Ref`. */\nconst collectScalarRefs = (\n obj: Record<string, unknown>,\n exclude: ReadonlySet<string>,\n): Record<string, Ref> => {\n const out: Record<string, Ref> = {};\n for (const [key, value] of Object.entries(obj)) {\n if (exclude.has(key)) continue;\n if (isLiteral(value)) out[key] = toRef(value);\n }\n return out;\n};\n\n/**\n * Like {@link collectScalarRefs} but also carries a structured field value (§15) onto `Ref.struct`.\n * Used for responsive override fields, where a `base` may now be a structured shadow/transition value\n * (whole-value replacement) rather than a scalar.\n */\nconst collectFieldRefs = (\n obj: Record<string, unknown>,\n exclude: ReadonlySet<string>,\n): Record<string, Ref> => {\n const out: Record<string, Ref> = {};\n for (const [key, value] of Object.entries(obj)) {\n if (exclude.has(key)) continue;\n if (isLiteral(value)) out[key] = toRef(value);\n else if (isStructuredValue(value)) out[key] = { struct: value };\n }\n return out;\n};\n\n// ---------------------------------------------------------------------------\n// Properties → PropertyModel\n// ---------------------------------------------------------------------------\n\n/** dec.3 — keys of a normalized variant that are NOT extras (the base value + its derivation meta). */\nconst VARIANT_STRUCTURAL_KEYS: ReadonlySet<string> = new Set([\"base\", \"derive\"]);\n\nconst PROPERTY_STRUCTURAL_KEYS: ReadonlySet<string> = new Set([\n \"base\",\n \"responsive\",\n \"variants\",\n \"modes\",\n // §W6b — an external property's `external` (the parent var name) rides on the base Ref, not as a\n // token extra; excluding it here prevents a spurious `<prop>.external` token leaking into the map.\n \"external\",\n]);\n\nconst RESPONSIVE_CONDITION_KEYS: ReadonlySet<string> = new Set([\n \"breakpoint\",\n \"query\",\n \"state\",\n \"orientation\",\n \"ref\", // dec.5 — property-responsive swap source\n \"modifiers\", // dec.5 — derivation chain on `ref` (subsystem-baked; never a field)\n \"mode\", // dec.9 — property-responsive appearance-mode condition\n \"variant\", // recipe-responsive scope (recipe path still uses `variant`)\n \"target\",\n // §10.6 D6: a synthesized responsive ramp step carries derivation metadata (`derive`) alongside its\n // baked `base` value — excluded from plain field collection; the `base` override is rebuilt as a\n // derived Ref below. Ramp-config keys (`ratio`/`step`/`steps`) never reach here — the layout hook\n // expands a ramp entry into per-step `target` overrides during normalize.\n \"derive\",\n \"ratio\",\n \"step\",\n \"steps\",\n]);\n\n/**\n * One normalized property (`{ base, responsive, variants?, ...extras }`) → a\n * {@link PropertyModel}. `base` and each variant become value refs; scalar sibling\n * extras (e.g. colors' `text`) go in `extras`; the responsive list maps entry-for-entry.\n */\nexport const buildPropertyModel = (\n normalized: NormalizedPropertyValue<unknown, Record<string, unknown>>,\n propertyName = \"property\",\n): PropertyModel => {\n const model: PropertyModel = {\n // §W6b — an external property carries the literal parent var name on its base Ref; the `value`\n // is the resolved `var(…)` string so raw `.value` readers (JSON, SC) stay happy.\n base:\n normalized.external !== undefined\n ? { value: `var(${normalized.external})`, external: normalized.external }\n : valueToRef(normalized.base),\n };\n\n const extras = collectScalarRefs(\n normalized as Record<string, unknown>,\n PROPERTY_STRUCTURAL_KEYS,\n );\n if (Object.keys(extras).length) model.extras = extras;\n\n if (normalized.variants && Object.keys(normalized.variants).length) {\n const variants: Record<string, VariantModel> = {};\n for (const [name, variant] of Object.entries(normalized.variants)) {\n let base: Ref | undefined;\n const variantDerive = (variant as {\n derive?: { ref: string; fn?: string; arg?: unknown; modifiers?: Array<{ fn: string; arg?: unknown }> };\n }).derive;\n if (isLiteral(variant.base)) {\n base = variantToRef(variant.base, variantDerive);\n } else if (isStructuredValue(variant.base)) {\n // §15: a structured shadow/transition variant (no derivation — those are colors-only).\n base = { struct: variant.base };\n } else if (variantDerive?.ref !== undefined) {\n // dec.4 — an UNBAKED cross-property derivation (base absent): carry the derived Ref with no\n // cached value; `bakeCrossPropertyDerivations` fills `.value` against the full token map.\n base = variantToRef(undefined, variantDerive);\n }\n if (!base) continue;\n // dec.3 — collect the variant's OWN extras (any non-structural leaf, e.g. colours' `text`) →\n // `--<prop>-<variant>-<extra>`, exactly like the property-level extras above.\n const variantExtras = collectScalarRefs(variant as Record<string, unknown>, VARIANT_STRUCTURAL_KEYS);\n variants[name] = Object.keys(variantExtras).length ? { base, extras: variantExtras } : { base };\n }\n if (Object.keys(variants).length) model.variants = variants;\n }\n\n // Appearance modes — a LIST of `PropertyOverride`s (each `{ mode, target?, overrides }`), so one\n // mode can carry several targeted entries. `buildModeFields` builds the field-map; `mode`/`target`\n // are structural (excluded from the extras it collects).\n const normalizedModes = (normalized as { modes?: Array<Record<string, unknown>> }).modes;\n if (normalizedModes && normalizedModes.length) {\n const modes: PropertyOverride[] = [];\n for (const entry of normalizedModes) {\n const modeName = entry.mode as string;\n const fields = buildModeFields(entry, propertyName, modeName);\n if (!Object.keys(fields).length) continue;\n const override: PropertyOverride = { mode: modeName, overrides: fields };\n if (typeof entry.target === \"string\") override.target = entry.target;\n modes.push(override);\n }\n if (modes.length) model.modes = modes;\n }\n\n if (normalized.responsive?.length) {\n const responsive: PropertyOverride[] = normalized.responsive.map(entry => {\n const e = entry as Record<string, unknown>;\n const override: PropertyOverride = { breakpoint: e.breakpoint as string };\n if (typeof e.query === \"string\") override.query = e.query as PropertyOverride[\"query\"];\n if (typeof e.orientation === \"string\") override.orientation = e.orientation as PropertyOverride[\"orientation\"];\n if (typeof e.ref === \"string\") override.ref = e.ref; // dec.5 — swap source (was `variant`)\n if (typeof e.mode === \"string\") override.mode = e.mode; // dec.9 — appearance-mode condition\n if (typeof e.target === \"string\") override.target = e.target;\n const overrides = collectFieldRefs(e, RESPONSIVE_CONDITION_KEYS);\n // §10.6 D6: a synthesized ramp step's `base` is a derived Ref (`{ ref, fn:\"scaleStep\", arg }`),\n // so `theme.tokens` / adapters carry the recipe just like a variant step. `value` stays the\n // cached resolution the lowering reads.\n const derive = e.derive as\n | { ref: string; fn?: string; arg?: unknown; modifiers?: Array<{ fn: string; arg?: unknown }> }\n | undefined;\n if (derive && overrides.base && overrides.base.value !== undefined) {\n overrides.base = variantToRef(overrides.base.value as Literal, derive);\n }\n if (Object.keys(overrides).length) override.overrides = overrides;\n return override;\n });\n model.responsive = responsive;\n }\n\n return model;\n};\n\n/** A whole normalized collection (`name → normalized property`) → `name → PropertyModel`. */\nexport const buildPropertiesModel = (\n collection: Record<string, NormalizedPropertyValue<unknown, Record<string, unknown>>>,\n): Record<string, PropertyModel> => {\n const out: Record<string, PropertyModel> = {};\n for (const [name, normalized] of Object.entries(collection)) {\n out[name] = buildPropertyModel(normalized, name);\n }\n return out;\n};\n\n// ---------------------------------------------------------------------------\n// Interpreted recipes → RuleSet (declarations carry refs)\n// ---------------------------------------------------------------------------\n\n/**\n * One *interpreted* recipe variant → a {@link RuleSet}. The interpreter has already\n * resolved every declaration to a {@link Ref} (`{ ref }` for token references, `{ value }`\n * for literals) and separated the condition axes from the declarations, so this is a\n * structural copy — **no string-parsing of `var(…)`**. Format-neutral by construction:\n * refs are token paths, not var names.\n */\nexport const buildRuleSetFromInterpreted = (\n variant: InterpretedRecipeVariant<string>,\n): RuleSet => {\n const declarations = { ...variant.base };\n\n const overrides: RuleSetOverride[] = variant.responsive.map(entry => {\n const override: RuleSetOverride = {};\n if (entry.state !== undefined) override.state = entry.state;\n if (entry.breakpoint !== undefined) override.breakpoint = entry.breakpoint;\n if (entry.query !== undefined) override.query = entry.query;\n if (entry.orientation !== undefined) override.orientation = entry.orientation;\n if (entry.container !== undefined) override.container = entry.container;\n if (entry.size !== undefined) override.size = entry.size;\n if (entry.variant !== undefined) override.variant = entry.variant;\n if (entry.target !== undefined) override.target = entry.target;\n if (Object.keys(entry.declarations).length) override.declarations = { ...entry.declarations };\n return override;\n });\n\n return { kind: \"recipe\", declarations, overrides };\n};\n\n/** An interpreted recipe group (`variant → interpreted`) → a {@link RuleSetGroup} with refs. */\nexport const buildRuleSetGroupFromInterpreted = (\n group: InterpretedRecipeGroup<string>,\n): RuleSetGroup => {\n const out: RuleSetGroup = {};\n for (const [name, variant] of Object.entries(group)) {\n out[name] = buildRuleSetFromInterpreted(variant);\n }\n return out;\n};\n\n/**\n * Rewrite a rule-set group's declaration refs from CSS var names to canonical **token paths**\n * (e.g. `--dt-color--primary` → `colors.primary`) using `varToPath`. Refs already absent from the\n * map are left untouched (var name preserved). Pure — returns a new group. Applied to the Model\n * copy so `theme.model` is format-neutral; the CSS adapter's own lowering is unaffected.\n */\nexport const pathifyRuleSetGroup = (\n group: RuleSetGroup,\n varToPath: Record<string, string>,\n): RuleSetGroup => {\n const mapRef = (ref: Ref): Ref =>\n ref.ref !== undefined && varToPath[ref.ref] !== undefined\n ? { ...ref, ref: varToPath[ref.ref] }\n : ref;\n const mapDecls = (decls: Record<string, Ref>): Record<string, Ref> => {\n const out: Record<string, Ref> = {};\n for (const [prop, ref] of Object.entries(decls)) out[prop] = mapRef(ref);\n return out;\n };\n const out: RuleSetGroup = {};\n for (const [name, ruleSet] of Object.entries(group)) {\n out[name] = {\n ...ruleSet,\n declarations: mapDecls(ruleSet.declarations),\n overrides: ruleSet.overrides.map(override =>\n override.declarations\n ? { ...override, declarations: mapDecls(override.declarations) }\n : override,\n ),\n };\n }\n return out;\n};\n\n/**\n * Rewrite property tokens' refs from CSS var names to canonical token paths using `varToPath`\n * (base / variants / extras). Refs absent from the map are left untouched. Pure — returns a new\n * map. Used to pathify layout's structural-config `extraProperties` in the Model.\n */\nexport const pathifyProperties = (\n properties: Record<string, PropertyModel>,\n varToPath: Record<string, string>,\n): Record<string, PropertyModel> => {\n const mapRef = (ref: Ref): Ref =>\n ref.ref !== undefined && varToPath[ref.ref] !== undefined\n ? { ...ref, ref: varToPath[ref.ref] }\n : ref;\n const mapRecord = (rec: Record<string, Ref>): Record<string, Ref> => {\n const out: Record<string, Ref> = {};\n for (const [key, ref] of Object.entries(rec)) out[key] = mapRef(ref);\n return out;\n };\n // dec.3 — a variant carries a base Ref + its own extras; map each.\n const mapVariants = (rec: Record<string, VariantModel>): Record<string, VariantModel> => {\n const out: Record<string, VariantModel> = {};\n for (const [key, v] of Object.entries(rec)) {\n out[key] = v.extras ? { base: mapRef(v.base), extras: mapRecord(v.extras) } : { base: mapRef(v.base) };\n }\n return out;\n };\n const out: Record<string, PropertyModel> = {};\n for (const [name, model] of Object.entries(properties)) {\n out[name] = {\n ...model,\n base: mapRef(model.base),\n ...(model.variants ? { variants: mapVariants(model.variants) } : {}),\n ...(model.extras ? { extras: mapRecord(model.extras) } : {}),\n };\n }\n return out;\n};\n\n/**\n * Extract `\"subsystem:group.variant\"` references from a component variant's normalized base, in\n * **authored order** — the order the composition references were written (`{ effects, layout }` →\n * `[\"effects:…\", \"layout:…\"]`). The CSS adapter renders this ordered list into the className, so the\n * Model `references` array IS the canonical composition order (the referenced recipe classes precede\n * the component's own delta class). Only the cross-subsystem keys are recognised; other base keys\n * (`css`, literals) are skipped.\n */\nexport const extractComponentReferences = (\n rawVariantBase: Record<string, unknown>,\n): string[] => {\n const references: string[] = [];\n for (const [key, value] of Object.entries(rawVariantBase)) {\n if (!COMPONENT_SUBSYSTEM_KEYS.has(key)) continue;\n if (typeof value === \"string\" && value.includes(\".\")) references.push(`${key}:${value}`);\n }\n return references;\n};\n\n/**\n * An interpreted component variant (its `css` delta) + its cross-subsystem `references`\n * → a component {@link RuleSet} (`kind: \"recipe\"`, own delta declarations carry refs,\n * cross-subsystem pointers kept as `references`).\n */\nexport const buildComponentRuleSetFromInterpreted = (\n variant: InterpretedRecipeVariant<string>,\n references: string[],\n): RuleSet => {\n const ruleSet = buildRuleSetFromInterpreted(variant);\n ruleSet.kind = \"recipe\";\n if (references.length) ruleSet.references = references;\n return ruleSet;\n};\n\n// ---------------------------------------------------------------------------\n// Components → RuleSet (cross-subsystem references + css delta)\n// ---------------------------------------------------------------------------\n\nconst COMPONENT_SUBSYSTEM_KEYS: ReadonlySet<string> = new Set([\n \"colors\",\n \"typography\",\n \"layout\",\n \"effects\",\n \"borders\",\n]);\n\n// ---------------------------------------------------------------------------\n// Assembly\n// ---------------------------------------------------------------------------\n\n/**\n * One subsystem's Model input. `ruleSetGroups` carries the already-interpreted rule-sets\n * (declarations with refs) that `createTheme` produces.\n */\nexport type SubsystemModelInput = {\n properties?: Record<string, NormalizedPropertyValue<unknown, Record<string, unknown>>>;\n ruleSetGroups?: Record<string, RuleSetGroup>;\n /**\n * Already-built {@link PropertyModel}s to merge into `properties` (after the normalized ones).\n * Layout uses this to carry its structural config knobs (columns/container size, gutter, inset)\n * as tokens — the subsystem's `buildStructural` hook emits them (see `subsystems/layout/structural.ts`).\n */\n extraProperties?: Record<string, PropertyModel>;\n /**\n * Named keyframe definitions (§10.2) — the animation subsystem's `buildStructural` output. Neither\n * property nor rule-set; attached to {@link SubsystemModel.keyframes} verbatim.\n */\n keyframes?: Record<string, Keyframe>;\n};\n\n/** Everything `buildThemeModel` needs — read from `createTheme`'s live caches/sources. */\nexport type BuildThemeModelInput = {\n breakpoints: Record<string, number>;\n /** Named query containers (§10.5) — carried onto the Model verbatim. Additive (absent → no field). */\n containers?: Record<string, ContainerModel>;\n colors?: SubsystemModelInput;\n typography?: SubsystemModelInput;\n layout?: SubsystemModelInput;\n effects?: SubsystemModelInput;\n /** Borders (§14): stroke geometry (width/style/offset/radius) + border/outline recipes. */\n borders?: SubsystemModelInput;\n animation?: SubsystemModelInput;\n components?: {\n ruleSetGroups?: Record<string, RuleSetGroup>;\n };\n globals?: SubsystemModelInput;\n};\n\nconst hasEntries = (obj: Record<string, unknown> | undefined): boolean =>\n !!obj && Object.keys(obj).length > 0;\n\n/**\n * One subsystem's Model input → a {@link SubsystemModel} (normalized properties built into\n * {@link PropertyModel}s, `extraProperties` merged in, rule-set groups attached). Returns\n * `undefined` when the slice contributes nothing. Exported so `override` can turn a *partial*\n * subsystem input into a Model fragment with the exact same shape the initial build produces.\n */\nexport const buildSubsystemModel = (\n slice: SubsystemModelInput | undefined,\n): SubsystemModel | undefined => {\n if (!slice) return undefined;\n const model: SubsystemModel = {};\n if (slice.properties && Object.keys(slice.properties).length) {\n model.properties = buildPropertiesModel(slice.properties);\n }\n if (slice.extraProperties && Object.keys(slice.extraProperties).length) {\n model.properties = { ...(model.properties ?? {}), ...slice.extraProperties };\n }\n if (hasEntries(slice.ruleSetGroups)) model.ruleSets = slice.ruleSetGroups;\n if (hasEntries(slice.keyframes)) model.keyframes = slice.keyframes;\n return Object.keys(model).length ? model : undefined;\n};\n\n/** Assemble the whole {@link ThemeModel} from the pipeline's normalized data + rule-set groups. */\nexport const buildThemeModel = (input: BuildThemeModelInput): ThemeModel => {\n const subsystems: Record<string, SubsystemModel> = {};\n\n const colors = buildSubsystemModel(input.colors);\n if (colors) subsystems.colors = colors;\n\n const typography = buildSubsystemModel(input.typography);\n if (typography) subsystems.typography = typography;\n\n const layout = buildSubsystemModel(input.layout);\n if (layout) subsystems.layout = layout;\n\n const effects = buildSubsystemModel(input.effects);\n if (effects) subsystems.effects = effects;\n\n // Borders (§14): stroke geometry + border/outline recipes. Positioned after effects (matching the\n // SUBSYSTEMS order); a theme with no `borders` slice yields none → byte-identical for such themes.\n const borders = buildSubsystemModel(input.borders);\n if (borders) subsystems.borders = borders;\n\n // Animation (§10.2): motion tokens (duration/easing/delay) + keyframes + animation-shorthand\n // recipes. Positioned after effects; a theme with no `animation` slice yields none → byte-identical.\n const animation = buildSubsystemModel(input.animation);\n if (animation) subsystems.animation = animation;\n\n if (hasEntries(input.components?.ruleSetGroups)) {\n subsystems.components = { ruleSets: input.components!.ruleSetGroups };\n }\n\n // Globals is last (§9): a selector-targeting rule-set subsystem (no properties) — the `kind:\"reset\"`\n // preset layers + `kind:\"globals\"` themed elements. Its refs resolve late in the adapter, so its\n // Model position is immaterial — the adapter hoists the preset layer ahead.\n const globals = buildSubsystemModel(input.globals);\n if (globals) subsystems.globals = globals;\n\n const model: ThemeModel = { breakpoints: input.breakpoints, subsystems };\n if (input.containers && Object.keys(input.containers).length) model.containers = input.containers;\n return model;\n};\n\n// ---------------------------------------------------------------------------\n// Token map (flat `path -> Ref` view of the Model's property tokens)\n// ---------------------------------------------------------------------------\n\n/**\n * Flatten a {@link ThemeModel} into one `path -> Ref` map — one entry per property token:\n * `\"<subsystem>.<property>\"` (base), `\"<subsystem>.<property>.<variant>\"`, and\n * `\"<subsystem>.<property>.<extra>\"`. Rule-sets are not tokens and are excluded. Each entry is\n * the Model's own `Ref` — `{ value }` for a literal, `{ ref }` for a reference. Additive source\n * for `theme.tokens`; the flat, format-neutral replacement for the per-subsystem `tokens` shape.\n */\nexport const buildTokenMap = (model: ThemeModel): Record<string, Ref> => {\n const out: Record<string, Ref> = {};\n for (const [subsystem, subModel] of Object.entries(model.subsystems)) {\n for (const [property, propertyModel] of Object.entries(subModel.properties ?? {})) {\n const base = `${subsystem}.${property}`;\n out[base] = propertyModel.base;\n for (const [variant, v] of Object.entries(propertyModel.variants ?? {})) {\n out[`${base}.${variant}`] = v.base;\n // dec.3 — a variant's extras are addressable tokens too: `<prop>.<variant>.<extra>`.\n for (const [field, ref] of Object.entries(v.extras ?? {})) {\n out[`${base}.${variant}.${field}`] = ref;\n }\n }\n for (const [field, ref] of Object.entries(propertyModel.extras ?? {})) {\n out[`${base}.${field}`] = ref;\n }\n }\n }\n return out;\n};\n","/**\n * Length units as a property of the value (§21).\n *\n * A length's unit belongs to the value, not to one global adapter switch. This module owns the whole\n * length-unit story: the CSS unit set, parsing an authored length input into a canonical dimension,\n * the three-layer role resolution, and the format-neutral **Model pass** that bakes a fully-resolved\n * `{ value, unit }` onto every length leaf. Adapters downstream only stringify (`value + unit`).\n *\n * Resolution order for a length leaf's unit (most-specific wins):\n * ① value-level unit — the token pinned `\"1px\"`; trusted verbatim, never converted\n * ② role default — `units[\"<sub>.<prop>\"]` → `units[\"<sub>\"]` → `units.default`\n * ③ built-in seed — length subsystems seed `px`; `lineHeight` → none; `letterSpacing` → em\n *\n * A bare number is **deferred** (px-intended magnitude, unit resolved by ②/③); `rem` is the one unit\n * whose resolution divides (`value ÷ baseFontSize`). An explicit unit is **pinned** — passed through.\n * Functions / keywords (`calc(…)`, `clamp(…)`, `var(…)`, `none`) are raw-string escapes, never parsed.\n */\n\nimport type { PropertyModel, Ref, ShadowLayer, SubsystemModel, ThemeModel, VariantModel } from \"./model\";\nimport { RefractError } from \"./errors\";\n\n// ---------------------------------------------------------------------------\n// Unit set\n// ---------------------------------------------------------------------------\n\n/**\n * The CSS length / relative unit set we parse + validate (§21 D2 — support every unit, exclude only\n * functions). A `<number><unit>` whose suffix is here becomes a pinned dimension; an unknown suffix is\n * an authoring error; anything with parens / whitespace / no digits is a raw-string escape.\n */\nexport const CSS_UNITS = [\n // absolute\n \"px\", \"cm\", \"mm\", \"q\", \"in\", \"pc\", \"pt\",\n // font-relative\n \"rem\", \"em\", \"ex\", \"cap\", \"ch\", \"ic\", \"lh\", \"rlh\",\n // percentage\n \"%\",\n // viewport\n \"vw\", \"vh\", \"vi\", \"vb\", \"vmin\", \"vmax\",\n \"svw\", \"svh\", \"lvw\", \"lvh\", \"dvw\", \"dvh\",\n // container-query\n \"cqw\", \"cqh\", \"cqi\", \"cqb\", \"cqmin\", \"cqmax\",\n] as const;\n\nexport type Unit = (typeof CSS_UNITS)[number];\n\n/** A resolved role: a concrete unit, or `\"none\"` (a length leaf that stays unit-less, e.g. lineHeight). */\nexport type RoleUnit = Unit | \"none\";\n\nconst UNIT_SET: ReadonlySet<string> = new Set(CSS_UNITS);\n\n// ---------------------------------------------------------------------------\n// Parse\n// ---------------------------------------------------------------------------\n\n/** A parsed length: a magnitude + optional unit (absent ⇒ deferred), or a raw escape string. */\nexport type ParsedLength = { value: number; unit?: Unit } | { raw: string };\n\nconst NUMERIC_RE = /^-?(?:\\d+\\.?\\d*|\\.\\d+)(?:e-?\\d+)?$/i;\nconst LENGTH_RE = /^(-?(?:\\d+\\.?\\d*|\\.\\d+)(?:e-?\\d+)?)([a-z%]+)$/i;\n\n/**\n * Parse one authored length input into a {@link ParsedLength}. A number, or a bare numeric string, is\n * deferred (`{ value }`). A `<number><unit>` with a known CSS unit is pinned (`{ value, unit }`). A\n * `<number><unknown>` is an authoring error (a typo — real functions/keywords carry parens or letters\n * with no leading number and fall through to `{ raw }`).\n */\nexport const parseLength = (input: number | string): ParsedLength => {\n if (typeof input === \"number\") return { value: input };\n const trimmed = input.trim();\n if (NUMERIC_RE.test(trimmed)) return { value: Number(trimmed) };\n const m = LENGTH_RE.exec(trimmed);\n if (m) {\n const unit = m[2].toLowerCase();\n if (UNIT_SET.has(unit)) return { value: Number(m[1]), unit: unit as Unit };\n throw new RefractError(\n \"REFRACT_E_UNITS\",\n `Unknown length unit \"${m[2]}\" in \"${input}\". Use a CSS unit, or wrap functions/keywords ` +\n `(calc(), clamp(), var(), a keyword) — those pass through as raw strings.`,\n );\n }\n return { raw: input };\n};\n\n// ---------------------------------------------------------------------------\n// Role resolution\n// ---------------------------------------------------------------------------\n\n/**\n * The build/theme-level unit config (§21 D3). Keys are token-path prefixes — `units.default` (global),\n * `units[\"<subsystem>\"]` (subsystem grain), `units[\"<subsystem>.<property>\"]` (property grain). Values\n * are a concrete unit or `\"none\"`. Most-specific wins; falls back to the built-in seed, then `px`.\n */\nexport type UnitsConfig = { default?: RoleUnit } & Record<string, RoleUnit | undefined>;\n\nexport type UnitResolutionConfig = {\n units?: UnitsConfig;\n /** Divisor for a deferred magnitude resolving to `rem` (matches typography + media). Default `16`. */\n baseFontSize?: number;\n};\n\nexport const DEFAULT_BASE_FONT_SIZE = 16;\n\n/**\n * The built-in seed (§21 D1) — the zero-config role default per length path. Length subsystems seed\n * `px` (the implicit fallback below, so they need no entry); the only entries are the two exceptions\n * whose natural unit differs: `lineHeight` is unit-less, `letterSpacing` is font-relative. Keeping the\n * px subsystems un-seeded is what makes default output byte-identical to the pre-§21 px-everywhere path.\n */\nconst SEED: Record<string, RoleUnit> = {\n \"typography.lineHeight\": \"none\",\n \"typography.letterSpacing\": \"em\",\n};\n\n/**\n * Resolve the role unit for a length leaf at `pathKey` (`\"typography.letterSpacing\"`). Precedence is\n * by **grain**, most-specific first, with the built-in property-grain seed slotted at its own grain —\n * so `SEED[\"typography.lineHeight\"] = \"none\"` beats a blunt subsystem-grain `units.typography = \"rem\"`\n * (§21 D1: property grain beats subsystem grain), while a user can still force it with the property key.\n */\nexport const resolveRoleUnit = (pathKey: string, units: UnitsConfig | undefined): RoleUnit => {\n const subsystem = pathKey.slice(0, pathKey.indexOf(\".\"));\n return (\n units?.[pathKey] ?? // ① user property grain\n SEED[pathKey] ?? // ② built-in property grain\n units?.[subsystem] ?? // ③ user subsystem grain\n units?.default ?? // ④ user global\n \"px\" // ⑤ built-in fallback\n );\n};\n\n/** Round a rem conversion to 4 dp, trailing zeros trimmed (matches the pre-§21 `formatLength`). */\nconst roundRem = (value: number, baseFontSize: number): number =>\n Number((value / baseFontSize).toFixed(4));\n\n/**\n * Resolve a deferred magnitude against its role unit → a concrete `{ value, unit? }`. `\"none\"` keeps\n * the value unit-less; `rem` divides by `baseFontSize`; every other unit is a straight tag.\n */\nconst resolveDeferred = (\n value: number,\n role: RoleUnit,\n baseFontSize: number,\n): { value: number; unit?: Unit } => {\n if (role === \"none\") return { value };\n if (role === \"rem\") return { value: roundRem(value, baseFontSize), unit: \"rem\" };\n return { value, unit: role };\n};\n\n// ---------------------------------------------------------------------------\n// Leaf resolution\n// ---------------------------------------------------------------------------\n\n/**\n * Resolve one length leaf {@link Ref} against its role. A pure token reference (`{ ref }`, no baked\n * value) is left untouched (its unit resolves at its own address). A **derived** length leaf\n * (`{ ref, fn, arg, value }` — §10.6 scale steps) carries its own baked `value`, emitted as a literal,\n * so its unit IS resolved here. A numeric or numeric-string value is deferred → resolved via the role;\n * a `<number><unit>` string is pinned → carried verbatim onto `{ value, unit }`; a raw escape\n * (`calc()`, keyword) is left as its string value. Returns a NEW ref when anything changed, else the\n * original (structural sharing preserved for byte-identical untouched branches).\n */\nexport const resolveLengthRef = (\n ref: Ref,\n role: RoleUnit,\n baseFontSize: number,\n): Ref => {\n if (ref.unit !== undefined) return ref; // already resolved (idempotent — `override` re-runs the pass)\n if (ref.ref !== undefined && ref.value === undefined) return ref; // pure alias — resolved at its own token\n const v = ref.value;\n\n if (typeof v === \"number\") {\n const { value, unit } = resolveDeferred(v, role, baseFontSize);\n return unit === undefined ? ref : { ...ref, value, unit };\n }\n\n if (typeof v === \"string\") {\n const parsed = parseLength(v);\n if (\"raw\" in parsed) return ref; // keyword / function — untouched\n if (parsed.unit !== undefined) return { ...ref, value: parsed.value, unit: parsed.unit }; // pinned\n const { value, unit } = resolveDeferred(parsed.value, role, baseFontSize); // numeric string → deferred\n return unit === undefined ? { ...ref, value } : { ...ref, value, unit };\n }\n\n return ref;\n};\n\n/** Resolve every geometry field of a structured shadow layer (§15) against the `effects.shadow` role. */\nconst resolveShadowLayer = (\n layer: ShadowLayer,\n role: RoleUnit,\n baseFontSize: number,\n): ShadowLayer => {\n const out: ShadowLayer = { ...layer };\n let changed = false;\n for (const field of [\"offsetX\", \"offsetY\", \"blur\", \"spread\"] as const) {\n const dim = layer[field];\n if (dim === undefined) continue;\n const resolved = resolveShadowDimension(dim, role, baseFontSize);\n if (resolved !== dim) {\n out[field] = resolved;\n changed = true;\n }\n }\n return changed ? out : layer;\n};\n\n/**\n * Resolve one shadow geometry field — a bare number (deferred) or a `{ value, unit }` (pinned, e.g.\n * authored `\"1px\"`). Deferred resolves via the role; pinned passes through. Mirrors {@link resolveLengthRef}\n * for the struct case, where the field is a {@link ShadowDimension} rather than a {@link Ref}.\n */\nconst resolveShadowDimension = (\n dim: ShadowDimension,\n role: RoleUnit,\n baseFontSize: number,\n): ShadowDimension => {\n if (typeof dim === \"number\") {\n const { value, unit } = resolveDeferred(dim, role, baseFontSize);\n return unit === undefined ? dim : { value, unit };\n }\n return dim; // already a pinned { value, unit }\n};\n\n/** A shadow geometry field after §21 widening — a deferred magnitude or a pinned `{ value, unit }`. */\nexport type ShadowDimension = number | { value: number; unit: Unit };\n\n// ---------------------------------------------------------------------------\n// Length-field registry\n// ---------------------------------------------------------------------------\n\n/** How a length-bearing property carries its value: a scalar leaf, or the shadow struct geometry. */\nexport type LengthKind = \"length\" | \"shadow\";\n\n/**\n * The length-field declaration (formalizes the scattered `PX_*_KEYS` of §16). Which `<subsystem>.<property>`\n * tokens are length-valued, and how they carry it. Anything absent (opacity, zIndex, aspectRatio, easing,\n * durations) is left untouched by the resolver. `lineHeight` is a length that seeds to `none` — listed so a\n * theme CAN opt it into a unit, resolving to unit-less by default.\n */\nexport const LENGTH_REGISTRY: Record<string, Record<string, LengthKind>> = {\n typography: { fontSize: \"length\", letterSpacing: \"length\", lineHeight: \"length\" },\n layout: { spacing: \"length\", gutters: \"length\", sizes: \"length\" },\n borders: { width: \"length\", offset: \"length\", radius: \"length\" },\n effects: { blur: \"length\", shadow: \"shadow\" },\n};\n\n// ---------------------------------------------------------------------------\n// Model pass\n// ---------------------------------------------------------------------------\n\n/**\n * Map a `field → Ref` record, returning the SAME reference when no entry changed (so an already-resolved\n * branch preserves object identity — `override`'s structural-sharing guarantee survives the re-run).\n */\nconst mapRefs = (record: Record<string, Ref>, map: (ref: Ref) => Ref): Record<string, Ref> => {\n let changed = false;\n const out: Record<string, Ref> = {};\n for (const [key, ref] of Object.entries(record)) {\n const next = map(ref);\n if (next !== ref) changed = true;\n out[key] = next;\n }\n return changed ? out : record;\n};\n\n/** dec.3 — map a property's variants (`variant → { base, extras }`), preserving identity when unchanged. */\nconst mapVariants = (\n variants: Record<string, VariantModel>,\n map: (ref: Ref) => Ref,\n): Record<string, VariantModel> => {\n let changed = false;\n const out: Record<string, VariantModel> = {};\n for (const [key, v] of Object.entries(variants)) {\n const base = map(v.base);\n const extras = v.extras ? mapRefs(v.extras, map) : undefined;\n if (base !== v.base || extras !== v.extras) changed = true;\n out[key] = extras ? { base, extras } : { base };\n }\n return changed ? out : variants;\n};\n\n/** Map a property's appearance modes (`mode → field → Ref`), preserving identity when nothing changed. */\nconst mapModes = (\n modes: PropertyModel[\"modes\"] & {},\n map: (ref: Ref) => Ref,\n): PropertyModel[\"modes\"] => {\n let changed = false;\n const next = modes.map(entry => {\n if (!entry.overrides) return entry;\n const overrides = mapRefs(entry.overrides, map);\n if (overrides === entry.overrides) return entry;\n changed = true;\n return { ...entry, overrides };\n });\n return changed ? next : modes;\n};\n\n/** Map a property's responsive overrides through `map`, preserving identity when nothing changed. */\nconst mapResponsive = (\n model: PropertyModel,\n map: (ref: Ref) => Ref,\n): PropertyModel[\"responsive\"] => {\n if (!model.responsive) return undefined;\n let changed = false;\n const next = model.responsive.map(entry => {\n if (!entry.overrides) return entry;\n const overrides = mapRefs(entry.overrides, map);\n if (overrides === entry.overrides) return entry;\n changed = true;\n return { ...entry, overrides };\n });\n return changed ? next : model.responsive;\n};\n\n/**\n * Apply a per-leaf `Ref → Ref` map across a property's leaves (base / variants / extras / modes /\n * responsive), returning the SAME `PropertyModel` when no leaf changed. Both the scalar-length and the\n * shadow-struct passes share this walk — they differ only in the leaf map (`scalar` vs `struct`).\n */\nconst mapPropertyLeaves = (\n model: PropertyModel,\n map: (ref: Ref) => Ref,\n includeExtras: boolean,\n): PropertyModel => {\n const base = map(model.base);\n const variants = model.variants ? mapVariants(model.variants, map) : undefined;\n const extras = includeExtras && model.extras ? mapRefs(model.extras, map) : model.extras;\n const modes = model.modes ? mapModes(model.modes, map) : undefined;\n const responsive = mapResponsive(model, map);\n\n if (\n base === model.base &&\n variants === model.variants &&\n extras === model.extras &&\n modes === model.modes &&\n responsive === model.responsive\n ) {\n return model;\n }\n const out: PropertyModel = { ...model, base };\n if (variants !== undefined) out.variants = variants;\n if (extras !== undefined) out.extras = extras;\n if (modes !== undefined) out.modes = modes;\n if (responsive !== undefined) out.responsive = responsive;\n return out;\n};\n\n/** Resolve a whole `PropertyModel`'s length leaves — scalar leaves, or a shadow's struct geometry. */\nconst resolvePropertyModel = (\n model: PropertyModel,\n kind: LengthKind,\n role: RoleUnit,\n baseFontSize: number,\n): PropertyModel => {\n const map =\n kind === \"shadow\"\n ? (ref: Ref): Ref => {\n if (!ref.struct) return ref;\n const layers = ref.struct as ShadowLayer[];\n let changed = false;\n const struct = layers.map(layer => {\n const next = resolveShadowLayer(layer, role, baseFontSize);\n if (next !== layer) changed = true;\n return next;\n });\n return changed ? { ...ref, struct } : ref;\n }\n : (ref: Ref): Ref => resolveLengthRef(ref, role, baseFontSize);\n // Shadow struct never lives in `extras`; scalar length extras are meaningless — skip extras for both.\n return mapPropertyLeaves(model, map, false);\n};\n\n/**\n * Resolve every length leaf in the {@link ThemeModel} to a concrete `{ value, unit }` (§21 D3). Pure and\n * **reference-preserving**: a subsystem / property / leaf that gains no unit keeps its object identity, so\n * the default px path stays byte-identical AND `override`'s structural sharing survives the re-run\n * (already-resolved parent branches are returned as-is). The single point where `units` is consulted.\n */\nexport const resolveModelUnits = (model: ThemeModel, config: UnitResolutionConfig = {}): ThemeModel => {\n const baseFontSize = config.baseFontSize ?? DEFAULT_BASE_FONT_SIZE;\n let anySubChanged = false;\n const subsystems: Record<string, SubsystemModel> = {};\n for (const [subKey, subModel] of Object.entries(model.subsystems)) {\n const fields = LENGTH_REGISTRY[subKey];\n if (!fields || !subModel.properties) {\n subsystems[subKey] = subModel;\n continue;\n }\n let anyPropChanged = false;\n const properties: Record<string, PropertyModel> = {};\n for (const [prop, pm] of Object.entries(subModel.properties)) {\n const kind = fields[prop];\n if (!kind) {\n properties[prop] = pm;\n continue;\n }\n const role = resolveRoleUnit(`${subKey}.${prop}`, config.units);\n const next = resolvePropertyModel(pm, kind, role, baseFontSize);\n if (next !== pm) anyPropChanged = true;\n properties[prop] = next;\n }\n if (anyPropChanged) {\n subsystems[subKey] = { ...subModel, properties };\n anySubChanged = true;\n } else {\n subsystems[subKey] = subModel;\n }\n }\n return anySubChanged ? { ...model, subsystems } : model;\n};\n","/**\n * Responsive-override normalization + reference validation.\n *\n * Normalizes a property's `responsive[]` entries (defaulting each `query`) and\n * validates their `breakpoint` / `variant` / `target` references against the\n * allowed sets threaded in via the normalization context.\n */\n\nimport type {\n NormalizedPropertyValue,\n NormalizedResponsiveOverride,\n PropertyNormalizationOptions,\n ResponsiveOverride,\n ResponsiveQuery,\n} from \"./types\";\nimport { RefractError } from \"../errors\";\n\n/** The `query` a responsive entry gets when none is authored — an exact-width media match. */\nexport const DEFAULT_RESPONSIVE_QUERY: ResponsiveQuery = \"exact\";\n\ntype AllowedValues<T> = ReadonlyArray<T> | ReadonlySet<T>;\n\ntype ResponsiveNormalizationContext<TBreakpoint extends string> = Pick<\n PropertyNormalizationOptions<unknown, TBreakpoint>,\n \"propertyPath\" | \"allowedBreakpoints\"\n> & {\n allowedTargets?: AllowedValues<string>;\n allowedVariants?: AllowedValues<string>;\n};\n\n/** Build the ` for \"<path>\"` suffix used in error messages (empty when no path is known). */\nconst formatContextLabel = (context?: { propertyPath?: string }): string =>\n context?.propertyPath ? ` for \"${context.propertyPath}\"` : \"\";\n\n/** Membership test that treats a missing `allowed` set as \"anything goes\". */\nconst isAllowedValue = <T>(value: T, allowed?: AllowedValues<T>): boolean => {\n if (!allowed) {\n return true;\n }\n\n if (Array.isArray(allowed)) {\n return allowed.includes(value);\n }\n\n return (allowed as ReadonlySet<T>).has(value);\n};\n\n/**\n * Normalize a property's `responsive[]` list: default each entry's `query` and\n * validate its references against the context's allowed sets.\n *\n * @param overrides The authored responsive entries (or `undefined` / empty → `[]`).\n * @param context Optional allowed sets — `allowedBreakpoints` / `allowedVariants`\n * / `allowedTargets` — plus `propertyPath` for error labels.\n * @throws If an entry is missing a `breakpoint`, or references an unknown\n * breakpoint / variant / target.\n */\nexport function normalizeResponsiveOverrides<\n TValue,\n TExtra extends Record<string, unknown> = Record<string, never>,\n TBreakpoint extends string = string,\n>(\n overrides: ResponsiveOverride<TValue, TExtra, TBreakpoint>[] | undefined,\n context?: ResponsiveNormalizationContext<TBreakpoint>,\n): NormalizedResponsiveOverride<TValue, TExtra, TBreakpoint>[] {\n if (!overrides?.length) {\n return [];\n }\n\n return overrides.map(override => {\n if (!override.breakpoint) {\n throw new RefractError(\n \"REFRACT_E_BREAKPOINT\",\n `Responsive entry${formatContextLabel(context)} is missing a \"breakpoint\" value.`,\n );\n }\n\n if (\n context?.allowedBreakpoints &&\n !isAllowedValue(override.breakpoint, context.allowedBreakpoints)\n ) {\n throw new RefractError(\n \"REFRACT_E_BREAKPOINT\",\n `Responsive entry${formatContextLabel(context)} references unknown breakpoint \"${override.breakpoint}\".`,\n );\n }\n\n // NB: on the PROPERTY side, `ref` + `target` is a supported *compose* (read a variant's value,\n // write it into another variant's token — see responsive-ref.test.ts), NOT a conflict. The\n // variant/target mutual-exclusion applies only to a RECIPE entry (a whole-recipe swap vs a scope),\n // enforced in normalizeRecipeResponsive.\n if (override.ref && !isAllowedValue(override.ref, context?.allowedVariants)) {\n throw new RefractError(\n \"REFRACT_E_RESPONSIVE\",\n `Responsive entry${formatContextLabel(context)} references unknown variant \"${override.ref}\" (ref).`,\n );\n }\n\n if (override.target && !isAllowedValue(override.target, context?.allowedTargets)) {\n throw new RefractError(\n \"REFRACT_E_RESPONSIVE\",\n `Responsive entry${formatContextLabel(context)} references unknown target \"${override.target}\".`,\n );\n }\n\n const { query, ...rest } = override;\n\n return {\n ...rest,\n query: query ?? DEFAULT_RESPONSIVE_QUERY,\n };\n });\n}\n\n/**\n * Second-pass validation: once a property is fully normalized, confirm every\n * responsive `variant` / `target` names a variant that actually exists on it.\n *\n * Complements {@link normalizeResponsiveOverrides}, which can't see the property's\n * own variant set during the first pass (variants are normalized in parallel).\n * A no-op when the property declares no variants.\n *\n * @throws If a responsive entry references a variant/target with no matching definition.\n */\nexport function validateNormalizedResponsiveRefs<\n TValue,\n TExtra extends Record<string, unknown> = Record<string, never>,\n TBreakpoint extends string = string,\n>(\n normalized: NormalizedPropertyValue<TValue, TExtra, TBreakpoint>,\n options?: { propertyPath?: string },\n): void {\n const variantNames = normalized.variants ? Object.keys(normalized.variants) : [];\n if (!variantNames.length) return;\n\n const allowed = new Set(variantNames);\n const label = options?.propertyPath ? ` for \"${options.propertyPath}\"` : \"\";\n\n for (const entry of normalized.responsive) {\n if (entry.ref && !allowed.has(entry.ref)) {\n throw new RefractError(\n \"REFRACT_E_RESPONSIVE\",\n `Responsive entry${label} references unknown variant \"${entry.ref}\" (ref).`,\n );\n }\n if (entry.target && !allowed.has(entry.target)) {\n throw new RefractError(\n \"REFRACT_E_RESPONSIVE\",\n `Responsive entry${label} references unknown target \"${entry.target}\".`,\n );\n }\n }\n}\n","/**\n * Property normalization — the entry point that turns any authored property value\n * into the canonical {@link NormalizedPropertyValue} shape.\n *\n * Collapses the three authoring forms (a bare value, or an extended object with\n * `base` / `variants` / `responsive`, plus subsystem `extra` fields) into one shape:\n * a resolved `base`, a normalized `variants` map, and a normalized `responsive` list.\n */\n\nimport {\n ExtendedProperty,\n ModeDerivation,\n ModeOverride,\n NormalizedModeValue,\n NormalizedModeOverride,\n NormalizedPropertyValue,\n NormalizedVariantValue,\n PropertyNormalizationOptions,\n PropertyValue,\n VariantValue,\n} from \"./types\";\nimport { normalizeResponsiveOverrides } from \"./responsive\";\nimport { RefractError } from \"../errors\";\n\n/** dec.2 — a `{ ref?, modifiers }` derivation (vs a literal or a multi-field mode object). */\nconst isModeDerivation = (value: unknown): value is ModeDerivation =>\n typeof value === \"object\" &&\n value !== null &&\n Array.isArray((value as { modifiers?: unknown }).modifiers);\n\n/**\n * dec.2 — parse an authored `modifiers` chain of single-key `{ [fn]: args }` dials into the\n * canonical `{ fn, arg }[]` the subsystem hook folds. Each element must have exactly one key (the\n * fn name), its value the arg (`{ darken: 10 }` → `{ fn: \"darken\", arg: 10 }`).\n */\nconst parseModifiers = (modifiers: unknown, path: string): Array<{ fn: string; arg?: unknown }> => {\n if (!Array.isArray(modifiers) || modifiers.length === 0) {\n throw new RefractError(\"REFRACT_E_VARIANT\", `Derivation \"${path}\" needs a non-empty \"modifiers\" array.`);\n }\n return modifiers.map((m, i) => {\n if (typeof m !== \"object\" || m === null || Array.isArray(m)) {\n throw new RefractError(\"REFRACT_E_VARIANT\", `Modifier ${i} of \"${path}\" must be a single-key object like { darken: 10 }.`);\n }\n const keys = Object.keys(m as Record<string, unknown>);\n if (keys.length !== 1) {\n throw new RefractError(\"REFRACT_E_VARIANT\", `Modifier ${i} of \"${path}\" must have exactly one fn key; got [${keys.join(\", \")}].`);\n }\n return { fn: keys[0], arg: (m as Record<string, unknown>)[keys[0]] };\n });\n};\n\n/**\n * Normalize one authored appearance-mode override ENTRY (§10.3) into a {@link NormalizedModeOverride}.\n * An entry is `{ mode, target?, …value }`: the `mode` name (WHEN) + optional `target` (WHERE) are\n * peeled off, and the value payload (WHAT) is normalized like a variant — a `{ ref?, modifiers }`\n * derivation (dec.2, unbaked by core), a flat object-leaf (§15), or a `{ base?, …extra }` object.\n */\nconst normalizeMode = <TValue, TExtra extends Record<string, unknown>, TBreakpoint extends string>(\n entry: ModeOverride<TValue, TExtra>,\n options: PropertyNormalizationOptions<TValue, TBreakpoint>,\n): NormalizedModeOverride<TValue, TExtra> => {\n const { mode: name, target, ...value } = entry as { mode: string; target?: string } & Record<string, unknown>;\n const modePath = options.propertyPath ? `${options.propertyPath}.modes.${name}` : `modes.${name}`;\n\n const normalizedValue = ((): NormalizedModeValue<TValue, TExtra> => {\n // §15: object-leaf subsystems — a flat leaf object (no `base` key, not a derivation) assembles its\n // leaf fields into the base; an explicit `base:` (incl. a multi-layer array) passes through below.\n if (options.leafFields?.length && !(\"base\" in value) && !isModeDerivation(value)) {\n const { base: assembled, extra } = partitionLeafBase(value, options.leafFields);\n if (assembled !== undefined) {\n const normalized: NormalizedModeValue<TValue, TExtra> = { ...(extra as Partial<TExtra>) };\n normalized.base = options.coerceValue ? options.coerceValue(assembled as TValue) : (assembled as TValue);\n return normalized;\n }\n }\n // dec.2 — `{ ref?, modifiers, …extra }` derivation → derived base (unbaked by core) + literal extras.\n if (isModeDerivation(value)) {\n const { ref, modifiers, ...rest } = value as ModeDerivation & Record<string, unknown>;\n const normalized: NormalizedModeValue<TValue, TExtra> = { ...(rest as Partial<TExtra>) };\n normalized.derive = {\n ...(ref !== undefined ? { ref } : {}),\n modifiers: parseModifiers(modifiers, modePath),\n };\n return normalized;\n }\n // Multi-field object: literal `base` (or a struct array) + literal extras.\n const { base, ...rest } = value as { base?: TValue } & Record<string, unknown>;\n const normalized: NormalizedModeValue<TValue, TExtra> = { ...(rest as Partial<TExtra>) };\n if (base !== undefined) {\n normalized.base = Array.isArray(base) || !options.coerceValue ? (base as TValue) : options.coerceValue(base as TValue);\n }\n if (normalized.base === undefined && !normalized.derive && !Object.keys(rest).length) {\n throw new RefractError(\"REFRACT_E_MODE\", `Appearance mode \"${modePath}\" overrides nothing.`);\n }\n return normalized;\n })();\n\n return { mode: name, ...(target !== undefined ? { target } : {}), ...normalizedValue };\n};\n\n/** Build the ` for \"<path>\"` suffix used in error messages (empty when no path is known). */\nconst formatPropertyLabel = (path?: string): string =>\n path ? ` for \"${path}\"` : \"\";\n\n/** Condition axes on a property responsive override (everything else is a value / leaf / extra field). */\nconst RESPONSIVE_CONDITION_KEYS: ReadonlySet<string> = new Set([\n \"breakpoint\",\n \"query\",\n \"ref\", // dec.5 — swap source (was `variant`)\n \"modifiers\", // dec.5 — derivation chain on `ref` (subsystem bakes it; never a plain field)\n \"mode\", // dec.9 — appearance-mode condition\n \"target\",\n \"orientation\",\n]);\n\n/** Discriminate the extended object form (`{ base, … }`) from a bare property value. */\nconst isExtendedProperty = <\n TValue,\n TExtra extends Record<string, unknown>,\n TBreakpoint extends string,\n>(value: PropertyValue<TValue, TExtra, TBreakpoint>): value is ExtendedProperty<TValue, TExtra, TBreakpoint> =>\n typeof value === \"object\" && value !== null && !Array.isArray(value);\n\n/**\n * Resolve a property's base value, falling back `providedBase → fallback →\n * options.fallbackBase`, applying `coerceValue` if provided. Throws when none resolve.\n */\nconst resolveBaseValue = <TValue, TBreakpoint extends string>(\n providedBase: TValue | undefined,\n fallback: TValue | undefined,\n options: PropertyNormalizationOptions<TValue, TBreakpoint>,\n): TValue => {\n const candidate = providedBase ?? fallback ?? options.fallbackBase;\n\n if (candidate === undefined) {\n throw new RefractError(\"REFRACT_E_PROPERTY\", `Unable to resolve base value${formatPropertyLabel(options.propertyPath)}.`);\n }\n\n return options.coerceValue ? options.coerceValue(candidate) : candidate;\n};\n\n/**\n * Partition an object into its assembled leaf-base value + remaining `TExtra` siblings (§15). When\n * `leafFields` carries at least one key present in `source`, those keys are collected into a base\n * object and the rest returned as `extra`; otherwise `base` is `undefined` (no leaf fields → the\n * caller uses the normal base path). Never fires without `leafFields` (scalar subsystems untouched).\n */\nconst partitionLeafBase = (\n source: Record<string, unknown>,\n leafFields: readonly string[],\n): { base: Record<string, unknown> | undefined; extra: Record<string, unknown> } => {\n const leafSet = new Set(leafFields);\n const base: Record<string, unknown> = {};\n const extra: Record<string, unknown> = {};\n let hasLeaf = false;\n for (const [key, value] of Object.entries(source)) {\n if (leafSet.has(key)) {\n base[key] = value;\n hasLeaf = true;\n } else {\n extra[key] = value;\n }\n }\n return { base: hasLeaf ? base : undefined, extra };\n};\n\n/**\n * Resolve a base value honoring the §15 leaf-field escape hatch. An explicit `base` wins (coerced\n * via {@link resolveBaseValue}); otherwise, when `options.leafFields` is set and `rest` carries leaf\n * fields, the base is assembled from them (coerced) and the remaining keys returned as `extra`.\n * With no `leafFields` (scalar subsystems) this is exactly `resolveBaseValue` + `rest` as extra.\n */\nconst resolveBaseAndExtra = <TValue, TBreakpoint extends string>(\n base: TValue | undefined,\n rest: Record<string, unknown>,\n fallback: TValue | undefined,\n options: PropertyNormalizationOptions<TValue, TBreakpoint>,\n): { base: TValue; extra: Record<string, unknown> } => {\n if (base === undefined && options.leafFields?.length) {\n const partitioned = partitionLeafBase(rest, options.leafFields);\n if (partitioned.base !== undefined) {\n const assembled = partitioned.base as TValue;\n return {\n base: options.coerceValue ? options.coerceValue(assembled) : assembled,\n extra: partitioned.extra,\n };\n }\n }\n return { base: resolveBaseValue(base, fallback, options), extra: rest };\n};\n\n/**\n * Assemble an object-leaf subsystem's responsive override (§15). A responsive entry that carries leaf\n * fields (or an explicit `base`) REPLACES the property's value at that breakpoint — its leaf fields\n * are assembled + coerced into `base` (whole-value replacement, like a variant swap sets the var). A\n * pure condition entry (a `variant`/`target` swap with no leaf fields) is returned untouched. Only\n * runs for `leafFields` subsystems; scalar subsystems keep their responsive entries verbatim.\n */\nconst assembleResponsiveLeaf = <TValue, TBreakpoint extends string>(\n entry: Record<string, unknown>,\n options: PropertyNormalizationOptions<TValue, TBreakpoint>,\n): Record<string, unknown> => {\n const condition: Record<string, unknown> = {};\n const others: Record<string, unknown> = {};\n let explicitBase: TValue | undefined;\n for (const [key, value] of Object.entries(entry)) {\n if (RESPONSIVE_CONDITION_KEYS.has(key)) condition[key] = value;\n else if (key === \"base\") explicitBase = value as TValue;\n else others[key] = value;\n }\n\n const hasLeaf = options.leafFields!.some(field => field in others);\n if (explicitBase === undefined && !hasLeaf) return entry; // pure swap / condition — nothing to assemble\n\n const { base: assembled, extra } = resolveBaseAndExtra(explicitBase, others, undefined, options);\n return { ...condition, ...extra, base: assembled };\n};\n\n/**\n * Normalize one named variant into `{ base, …extra }`. Accepts both the bare form\n * (`muted: \"#999\"`) and the extended form (`muted: { base: \"#999\", … }`). dec.3 — `fallbackBase`\n * is the property's own base: a variant that omits `base` (overriding only an extra) INHERITS it.\n */\nconst normalizeVariant = <\n TValue,\n TExtra extends Record<string, unknown>,\n TBreakpoint extends string,\n>(\n name: string,\n variant: VariantValue<TValue, TExtra, TBreakpoint>,\n options: PropertyNormalizationOptions<TValue, TBreakpoint>,\n fallbackBase?: TValue,\n): NormalizedVariantValue<TValue, TExtra, TBreakpoint> => {\n const variantPath = options.propertyPath\n ? `${options.propertyPath}.variants.${name}`\n : `variants.${name}`;\n\n const extended = isExtendedProperty<TValue, TExtra, TBreakpoint>(variant)\n ? variant\n : ({ base: variant } as ExtendedProperty<TValue, TExtra, TBreakpoint>);\n\n const { base, ...rest } = extended;\n const { base: resolvedBase, extra } = resolveBaseAndExtra(\n base,\n rest as Record<string, unknown>,\n fallbackBase, // dec.3 — inherit the property base when the variant omits its own.\n { ...options, propertyPath: variantPath },\n );\n\n return {\n ...(extra as unknown as TExtra),\n base: resolvedBase,\n };\n};\n\n/**\n * Normalize any authored property value into the canonical {@link NormalizedPropertyValue}.\n *\n * @param value A bare value or an extended `{ base, variants?, responsive?, …extra }` object.\n * @param options `propertyPath` (error labels), `fallbackBase`, `coerceValue`, and\n * `allowedBreakpoints` (responsive breakpoint validation).\n * @returns `{ base, responsive, variants?, …extra }` — `responsive` always an array,\n * each entry with its `query` defaulted; `variants` normalized or `undefined`.\n * @throws If no base value can be resolved, or a responsive entry fails validation.\n */\nexport const normalizePropertyValue = <\n TValue,\n TExtra extends Record<string, unknown> = Record<string, never>,\n TBreakpoint extends string = string,\n>(\n value: PropertyValue<TValue, TExtra, TBreakpoint>,\n options: PropertyNormalizationOptions<TValue, TBreakpoint> = {},\n): NormalizedPropertyValue<TValue, TExtra, TBreakpoint> => {\n const extended = isExtendedProperty<TValue, TExtra, TBreakpoint>(value)\n ? value\n : ({ base: value } as ExtendedProperty<TValue, TExtra, TBreakpoint>);\n\n const { base, responsive, variants, modes, ...rest } = extended;\n const { base: resolvedBase, extra } = resolveBaseAndExtra(\n base,\n rest as Record<string, unknown>,\n options.fallbackBase,\n options,\n );\n const normalizedVariants = variants\n ? Object.fromEntries(\n Object.entries(variants).map(([name, definition]) => [\n name,\n normalizeVariant(name, definition, options, resolvedBase), // dec.3 — property base = variant fallback.\n ]),\n )\n : undefined;\n const normalizedModes = modes ? modes.map(entry => normalizeMode(entry, options)) : undefined;\n const responsiveContext = {\n propertyPath: options.propertyPath,\n allowedBreakpoints: options.allowedBreakpoints,\n } as const;\n const normalizedResponsive = normalizeResponsiveOverrides(responsive, responsiveContext);\n // §15: object-leaf subsystems assemble a responsive entry's inline leaf fields into a `base` value\n // (whole-value replacement). Gated on `leafFields`, so scalar subsystems keep entries verbatim.\n const finalResponsive = options.leafFields?.length\n ? normalizedResponsive.map(\n entry =>\n assembleResponsiveLeaf(entry as Record<string, unknown>, options) as typeof entry,\n )\n : normalizedResponsive;\n\n return {\n ...(extra as unknown as TExtra),\n base: resolvedBase,\n responsive: finalResponsive,\n variants: normalizedVariants,\n modes: normalizedModes,\n };\n};\n","/**\n * Recipe-group normalization.\n *\n * A recipe authors its base declarations inline, plus two optional condition axes — a\n * grouped `states` map and a `responsive[]` list. Normalization splits both off the base\n * and flattens them into one unified `overrides` list, each entry carrying an optional\n * `state` and/or `breakpoint` (both present = the cross-product). References\n * (`breakpoint` / `state` / `variant` / `target`) are validated against the allowed sets.\n *\n * §7A — before any of that, a pre-pass expands an optional `variants` modifier map on any\n * recipe into flat sibling recipes (`<recipe>-<variant>`), so the rest of this module — the\n * resolver, `interpretRecipe`, reference extraction, the Model, and every adapter — sees the\n * same `RecipeGroupDefinition` authored today. Gated on the `variants` key: a group with no\n * `variants` is returned by reference, byte-identical.\n */\n\nimport type {\n RecipeGroupDefinition,\n NormalizedRecipeGroup,\n RecipeVariantDefinition,\n RecipeVariantModifier,\n RecipeResponsiveOverride,\n} from \"./types\";\nimport { RefractError } from \"../errors\";\n\n/** Allowed-reference sets threaded into recipe normalization for validation. */\nexport type RecipeNormalizationOptions<TBreakpoint extends string> = {\n propertyPath?: string;\n allowedBreakpoints?: ReadonlyArray<TBreakpoint> | ReadonlySet<TBreakpoint>;\n /** The adapter's known-state set; `state` values are validated against it (throw on unknown). */\n allowedStates?: ReadonlyArray<string> | ReadonlySet<string>;\n /** Container queries (§10.5): container name → its allowed size-names, validated on container overrides. */\n allowedContainers?: ReadonlyMap<string, ReadonlySet<string>>;\n};\n\nconst DEFAULT_QUERY = \"exact\" as const;\n/** Container conditions default to `min` (container-first idiom, §10.5 D1), unlike the viewport `exact` default. */\nconst DEFAULT_CONTAINER_QUERY = \"min\" as const;\n/** Condition fields that are meaningless on a container override (§10.5 D5) — they throw if present. */\nconst CONTAINER_INVALID_FIELDS = [\"orientation\", \"height\", \"aspectRatio\"] as const;\n\ntype AllowedValues<T> = ReadonlyArray<T> | ReadonlySet<T>;\n\nconst isAllowedValue = <T>(value: T, allowed?: AllowedValues<T>): boolean => {\n if (!allowed) {\n return true;\n }\n\n if (Array.isArray(allowed)) {\n return allowed.includes(value);\n }\n\n return (allowed as ReadonlySet<T>).has(value);\n};\n\n/** Build the ` for \"<path>\"` suffix used in error messages (empty when no path is known). */\nconst formatContextLabel = (path?: string): string => (path ? ` for \"${path}\"` : \"\");\n\n/** §7A — the single-dash join between a recipe and one of its variants (`primary` + `sm` → `primary-sm`). */\nconst VARIANT_NAME_SEPARATOR = \"-\";\n\n/** Recipe-leaf keys with bespoke merge rules; every other key is a ref/scalar prop (delta replaces). */\nconst RESPONSIVE_KEY = \"responsive\";\nconst STATES_KEY = \"states\";\nconst CSS_KEY = \"css\";\nconst VARIANTS_KEY = \"variants\";\n\n/**\n * `states` is a LIST of `{ state, target?, ...deltas }` entries (dec.8). Coerce whatever was authored\n * to that array — an array passes through; a legacy `{ state: {…delta} }` map is expanded to entries\n * (defensive: keeps untyped `.mjs` authoring working). Anything else → empty.\n */\ntype StateEntry = { state: string; target?: string } & Record<string, unknown>;\nconst toStateArray = (states: unknown): StateEntry[] => {\n if (Array.isArray(states)) return states as StateEntry[];\n if (states && typeof states === \"object\") {\n return Object.entries(states as Record<string, Record<string, unknown>>).map(\n ([state, delta]) => ({ state, ...delta }),\n );\n }\n return [];\n};\n\n/** The identity of a state override — `state` + its optional `target` (two same-state entries with\n * different targets are distinct; same-state same-target entries merge, delta winning). */\nconst stateEntryKey = (e: StateEntry): string => `${e.state}\u0000${e.target ?? \"\"}`;\n\n/**\n * Merge one variant's `states` list onto the recipe's (§7A). Entries with the same `(state, target)`\n * shallow-merge (delta wins per property, preserving the base entry's position); a new `(state,\n * target)` appends. Reproduces the old map-merge for the common (un-targeted) case while supporting\n * multiple same-state entries scoped to different targets.\n */\nconst mergeRecipeStates = (base: unknown, delta: unknown): StateEntry[] => {\n const out = toStateArray(base).map(e => ({ ...e }));\n const index = new Map(out.map((e, i) => [stateEntryKey(e), i]));\n for (const d of toStateArray(delta)) {\n const key = stateEntryKey(d);\n const at = index.get(key);\n if (at !== undefined) out[at] = { ...out[at], ...d };\n else {\n index.set(key, out.length);\n out.push({ ...d });\n }\n }\n return out;\n};\n\n/**\n * §7A `mergeRecipe(base, delta)` — layer a variant delta onto the recipe's own props:\n * - a ref / scalar prop → **delta replaces** (a ref is one atomic pointer);\n * - `css` → **shallow merge by property** (`{ ...base.css, ...delta.css }`);\n * - `states` → **merge by state name** (union; shared state shallow-merges, delta wins);\n * - `responsive[]` → **concatenate** (`base ++ delta`, delta last = higher source order);\n * - a prop set to `null` → **removal sentinel**, drops the inherited key (`\"none\"` stays a value).\n */\nconst mergeRecipe = (\n base: Record<string, unknown>,\n delta: Record<string, unknown>,\n): Record<string, unknown> => {\n const merged: Record<string, unknown> = { ...base };\n\n for (const [key, value] of Object.entries(delta)) {\n if (value === null) {\n delete merged[key];\n continue;\n }\n\n if (key === RESPONSIVE_KEY) {\n merged[RESPONSIVE_KEY] = [\n ...((base[RESPONSIVE_KEY] as unknown[] | undefined) ?? []),\n ...(value as unknown[]),\n ];\n } else if (key === STATES_KEY) {\n merged[STATES_KEY] = mergeRecipeStates(\n base[STATES_KEY] as Record<string, Record<string, unknown>> | undefined,\n value as Record<string, Record<string, unknown>>,\n );\n } else if (key === CSS_KEY) {\n merged[CSS_KEY] = {\n ...((base[CSS_KEY] as Record<string, unknown> | undefined) ?? {}),\n ...(value as Record<string, unknown>),\n };\n } else {\n merged[key] = value;\n }\n }\n\n return merged;\n};\n\n/**\n * §7A pre-pass — desugar every recipe's optional `variants` modifier map into flat sibling\n * recipes, returning a plain {@link RecipeGroupDefinition} the existing normalizer consumes.\n *\n * The bare recipe still emits (its own props, `variants` peeled off) **plus** one merged\n * sibling per variant, named `<recipe>-<variant>`. Opt-in and additive: if no recipe in the\n * group carries a `variants` key, the group is returned **by reference** so downstream output\n * is byte-identical. A desugared name colliding with any other sibling in the group throws.\n */\nconst expandRecipeVariants = <\n TProps extends Record<string, unknown>,\n TBreakpoint extends string,\n>(\n group: RecipeGroupDefinition<TProps, TBreakpoint>,\n path?: string,\n): RecipeGroupDefinition<TProps, TBreakpoint> => {\n const hasVariants = Object.values(group).some(\n recipe =>\n recipe != null &&\n typeof recipe === \"object\" &&\n (recipe as Record<string, unknown>)[VARIANTS_KEY] != null,\n );\n if (!hasVariants) {\n return group;\n }\n\n const expanded = {} as Record<string, RecipeVariantDefinition<TProps, TBreakpoint>>;\n\n const emit = (name: string, definition: RecipeVariantDefinition<TProps, TBreakpoint>) => {\n if (name in expanded) {\n throw new RefractError(\n \"REFRACT_E_VARIANT\",\n `Recipe variant expansion${formatContextLabel(path)} produced a duplicate recipe name \"${name}\" ` +\n `— a desugared \"<recipe>-<variant>\" collides with an existing sibling recipe.`,\n );\n }\n expanded[name] = definition;\n };\n\n for (const [recipeName, recipeDef] of Object.entries(group)) {\n const { [VARIANTS_KEY]: variants, ...base } = recipeDef as Record<string, unknown>;\n emit(recipeName, base as RecipeVariantDefinition<TProps, TBreakpoint>);\n\n if (variants != null) {\n // dec.8 — a `target`ed state on the base item scopes ONE-WAY onto its named sibling (emitted\n // during the base item's own lowering). A desugared sibling must NOT re-inherit those targeted\n // entries (they'd re-target a `<sibling>-<target>` class that doesn't exist); it inherits only\n // the un-targeted base states + its own delta.\n const baseForSibling =\n base[STATES_KEY] != null\n ? { ...base, [STATES_KEY]: toStateArray(base[STATES_KEY]).filter(e => !e.target) }\n : base;\n for (const [variantName, delta] of Object.entries(\n variants as Record<string, RecipeVariantModifier<TProps, TBreakpoint>>,\n )) {\n emit(\n `${recipeName}${VARIANT_NAME_SEPARATOR}${variantName}`,\n mergeRecipe(baseForSibling, delta as Record<string, unknown>) as RecipeVariantDefinition<\n TProps,\n TBreakpoint\n >,\n );\n }\n }\n }\n\n return expanded as RecipeGroupDefinition<TProps, TBreakpoint>;\n};\n\n/**\n * Normalize a whole recipe group (variant name → variant definition).\n *\n * Sibling variant names become the group's `allowedVariants` / `allowedTargets` set,\n * so a variant's responsive `variant` / `target` refs are validated against its peers.\n *\n * @param group The authored group — `{ primary: {…}, danger: {…} }`.\n * @param options `allowedBreakpoints` / `allowedStates` + `propertyPath` for error labels.\n * @returns Each variant normalized to `{ base, responsive }` (states + responsive flattened).\n * @throws If any entry references an unknown breakpoint / state / variant / target,\n * or a responsive entry is missing its breakpoint.\n */\nexport const normalizeRecipeGroup = <\n TProps extends Record<string, unknown>,\n TBreakpoint extends string,\n>(\n group: RecipeGroupDefinition<TProps, TBreakpoint>,\n options: RecipeNormalizationOptions<TBreakpoint> = {},\n): NormalizedRecipeGroup<TProps, TBreakpoint> => {\n // §7A — desugar any `variants` modifier maps into flat sibling recipes first, so everything\n // below (and downstream) sees the plain group shape authored today. No-op when unused.\n const expandedGroup = expandRecipeVariants(group, options.propertyPath);\n const variantNames = Object.keys(expandedGroup);\n const allowedVariantSet = variantNames.length\n ? (new Set(variantNames) as ReadonlySet<string>)\n : undefined;\n\n const normalized = {} as NormalizedRecipeGroup<TProps, TBreakpoint>;\n\n variantNames.forEach(variantName => {\n const variant = expandedGroup[variantName];\n normalized[variantName] = normalizeRecipeVariant(\n `${options.propertyPath ?? \"recipes\"}.${variantName}`,\n variant,\n {\n allowedBreakpoints: options.allowedBreakpoints,\n allowedStates: options.allowedStates,\n allowedTargets: allowedVariantSet,\n allowedVariants: allowedVariantSet,\n allowedContainers: options.allowedContainers,\n recipeName: variantName,\n },\n );\n });\n\n return normalized;\n};\n\ntype RecipeResponsiveContext<TBreakpoint extends string> = {\n allowedBreakpoints?: AllowedValues<TBreakpoint>;\n allowedStates?: AllowedValues<string>;\n allowedTargets?: AllowedValues<string>;\n allowedVariants?: AllowedValues<string>;\n allowedContainers?: ReadonlyMap<string, ReadonlySet<string>>;\n /** The current recipe item's name — a state `target` names a VARIANT key, so the sibling it scopes\n * onto is `<recipeName>-<target>`, validated against the group's members (dec.8). */\n recipeName?: string;\n};\n\n/** Normalize one recipe variant: peel off `states` + `responsive`, flatten both into `overrides`. */\nconst normalizeRecipeVariant = <\n TProps extends Record<string, unknown>,\n TBreakpoint extends string,\n>(\n path: string,\n variant: RecipeVariantDefinition<TProps, TBreakpoint>,\n context: RecipeResponsiveContext<TBreakpoint>,\n) => {\n const { responsive, states, ...base } = variant;\n\n // States + responsive flatten into ONE `overrides` list: each entry carries an optional\n // `state` and/or `breakpoint` (both present = the cross-product, e.g. `:hover` at `md`).\n // Pure-state entries come from the `states` map (no breakpoint); breakpoint entries come\n // from `responsive` (and may themselves carry a `state`).\n const normalizedStates = normalizeRecipeStates<TProps, TBreakpoint>(states, path, context);\n const normalizedResponsive = normalizeRecipeResponsive(responsive, path, context);\n\n return {\n base: base as TProps,\n responsive: [...normalizedStates, ...normalizedResponsive],\n };\n};\n\n/** Flatten the `states` LIST into override entries, each carrying its `state` + optional `target`\n * (dec.8 — `target` scopes the state onto the `<item>-<target>` sibling). */\nconst normalizeRecipeStates = <\n TProps extends Record<string, unknown>,\n TBreakpoint extends string,\n>(\n states: unknown,\n path: string,\n context: RecipeResponsiveContext<TBreakpoint>,\n): RecipeResponsiveOverride<TProps, TBreakpoint>[] => {\n return toStateArray(states).map(entry => {\n const { state: stateName, ...rest } = entry;\n if (context.allowedStates && !isAllowedValue(stateName, context.allowedStates)) {\n throw new RefractError(\n \"REFRACT_E_STATE\",\n `Recipe state entry${formatContextLabel(path)} references unknown state \"${stateName}\".`,\n );\n }\n // dec.8 — a `target` names a VARIANT key of THIS item; the sibling it scopes onto is\n // `<recipeName>-<target>` (the §7A-desugared class). Validate that sibling exists in the group.\n if (rest.target && context.allowedTargets) {\n const sibling = context.recipeName ? `${context.recipeName}-${rest.target}` : (rest.target as string);\n if (!isAllowedValue(sibling, context.allowedTargets)) {\n throw new RefractError(\n \"REFRACT_E_RESPONSIVE\",\n `Recipe state entry${formatContextLabel(path)} references unknown target \"${rest.target}\".`,\n );\n }\n }\n\n return {\n ...(rest as Partial<TProps>),\n state: stateName,\n } as RecipeResponsiveOverride<TProps, TBreakpoint>;\n });\n};\n\n/** Normalize the `responsive[]` list: require a breakpoint, default the `query`, validate refs. */\nconst normalizeRecipeResponsive = <\n TProps extends Record<string, unknown>,\n TBreakpoint extends string,\n>(\n overrides: RecipeResponsiveOverride<TProps, TBreakpoint>[] | undefined,\n path: string,\n context: RecipeResponsiveContext<TBreakpoint>,\n): RecipeResponsiveOverride<TProps, TBreakpoint>[] => {\n if (!overrides?.length) {\n return [];\n }\n\n return overrides.map(entry => {\n // `variant` (adopt a sibling's base) and `target` (scope this override onto a variant's token) are\n // opposites — a source vs a destination. Setting both on one entry is contradictory; fail loud\n // rather than silently honouring one. (Documented on the Errors page + Variants & targets concept.)\n if (entry.variant !== undefined && entry.target !== undefined) {\n throw new RefractError(\n \"REFRACT_E_RESPONSIVE\",\n `Responsive entry${formatContextLabel(path)} cannot set both \"variant\" and \"target\".`,\n );\n }\n\n // Container-query override (§10.5): keyed by `container` + `size` instead of `breakpoint`.\n if (entry.container !== undefined) {\n return normalizeContainerEntry(entry, path, context);\n }\n\n if (!entry.breakpoint) {\n throw new RefractError(\n \"REFRACT_E_BREAKPOINT\",\n `Responsive recipe entry${formatContextLabel(path)} is missing a \"breakpoint\" value.`,\n );\n }\n\n if (\n context.allowedBreakpoints &&\n !isAllowedValue(entry.breakpoint, context.allowedBreakpoints)\n ) {\n throw new RefractError(\n \"REFRACT_E_BREAKPOINT\",\n `Responsive recipe entry${formatContextLabel(path)} references unknown breakpoint \"${entry.breakpoint}\".`,\n );\n }\n\n if (entry.state && context.allowedStates && !isAllowedValue(entry.state, context.allowedStates)) {\n throw new RefractError(\n \"REFRACT_E_STATE\",\n `Responsive recipe entry${formatContextLabel(path)} references unknown state \"${entry.state}\".`,\n );\n }\n\n if (entry.variant && !isAllowedValue(entry.variant, context.allowedVariants)) {\n throw new RefractError(\n \"REFRACT_E_RESPONSIVE\",\n `Responsive recipe entry${formatContextLabel(path)} references unknown variant \"${entry.variant}\".`,\n );\n }\n\n if (entry.target && !isAllowedValue(entry.target, context.allowedTargets)) {\n throw new RefractError(\n \"REFRACT_E_RESPONSIVE\",\n `Responsive recipe entry${formatContextLabel(path)} references unknown target \"${entry.target}\".`,\n );\n }\n\n return {\n ...entry,\n query: entry.query ?? DEFAULT_QUERY,\n };\n });\n};\n\n/**\n * Normalize one container-query override (§10.5): validate the `container` name + its `size` against\n * the theme's `containers` config, reject the fields that can't work under `container-type: inline-size`\n * (`orientation`/`height`/`aspect-ratio` — D5), and default `query` to `min` (D1, not the viewport `exact`).\n */\nconst normalizeContainerEntry = <\n TProps extends Record<string, unknown>,\n TBreakpoint extends string,\n>(\n entry: RecipeResponsiveOverride<TProps, TBreakpoint>,\n path: string,\n context: RecipeResponsiveContext<TBreakpoint>,\n): RecipeResponsiveOverride<TProps, TBreakpoint> => {\n const name = entry.container as string;\n\n for (const field of CONTAINER_INVALID_FIELDS) {\n if ((entry as Record<string, unknown>)[field] !== undefined) {\n throw new RefractError(\n \"REFRACT_E_CONTAINER\",\n `Container recipe entry${formatContextLabel(path)} cannot use \"${field}\" — container queries ` +\n `respond to a container's inline size, not orientation/height/aspect-ratio.`,\n );\n }\n }\n\n const sizes = context.allowedContainers?.get(name);\n if (context.allowedContainers && !sizes) {\n throw new RefractError(\n \"REFRACT_E_CONTAINER\",\n `Container recipe entry${formatContextLabel(path)} references unknown container \"${name}\".`,\n );\n }\n\n if (entry.size === undefined) {\n throw new RefractError(\n \"REFRACT_E_CONTAINER\",\n `Container recipe entry${formatContextLabel(path)} for container \"${name}\" is missing a \"size\" value.`,\n );\n }\n\n if (sizes && !sizes.has(entry.size)) {\n throw new RefractError(\n \"REFRACT_E_CONTAINER\",\n `Container recipe entry${formatContextLabel(path)} references unknown size \"${entry.size}\" ` +\n `on container \"${name}\".`,\n );\n }\n\n return {\n ...entry,\n query: entry.query ?? DEFAULT_CONTAINER_QUERY,\n };\n};\n","/**\n * Lazy, memoized, cycle-safe recipe-variant resolver (clean-room port of\n * `core/common/recipeResolver.ts`).\n *\n * A recipe variant may reference a sibling variant (responsive `variant:` swaps). The\n * resolver interprets each variant on demand, caches the result, and detects cycles\n * (throwing with the offending chain). The interpret callback receives a `resolve`\n * function so it can pull a sibling's already-interpreted form.\n */\nimport type { NormalizedRecipeGroup, NormalizedRecipeVariant } from \"./types\";\nimport { RefractError } from \"../errors\";\n\nexport type RecipeInterpreter<\n TProps extends Record<string, unknown>,\n TBreakpoint extends string,\n TInterpreted,\n> = (\n variantName: string,\n variant: NormalizedRecipeVariant<TProps, TBreakpoint>,\n resolve: (variantName: string) => TInterpreted,\n) => TInterpreted;\n\nexport type RecipeVariantResolver<TInterpreted> = {\n resolve: (variantName: string) => TInterpreted;\n resolveAll: () => Record<string, TInterpreted>;\n};\n\nexport type CreateRecipeVariantResolverOptions = {\n groupPath?: string;\n};\n\nexport const createRecipeVariantResolver = <\n TProps extends Record<string, unknown>,\n TBreakpoint extends string,\n TInterpreted,\n>(\n group: NormalizedRecipeGroup<TProps, TBreakpoint>,\n interpret: RecipeInterpreter<TProps, TBreakpoint, TInterpreted>,\n options: CreateRecipeVariantResolverOptions = {},\n): RecipeVariantResolver<TInterpreted> => {\n const cache = new Map<string, TInterpreted>();\n const inProgress: string[] = [];\n const groupPath = options.groupPath ?? \"recipes\";\n\n const resolve = (variantName: string): TInterpreted => {\n if (cache.has(variantName)) {\n return cache.get(variantName) as TInterpreted;\n }\n\n if (inProgress.includes(variantName)) {\n const cycle = [...inProgress, variantName].join(\" -> \");\n throw new RefractError(\"REFRACT_E_CYCLE\", `Cyclic recipe reference in \"${groupPath}\": ${cycle}`);\n }\n\n const variant = group[variantName];\n if (!variant) {\n throw new RefractError(\"REFRACT_E_REFERENCE\", `Recipe variant \"${variantName}\" is not defined in \"${groupPath}\".`);\n }\n\n inProgress.push(variantName);\n try {\n const result = interpret(variantName, variant, resolve);\n cache.set(variantName, result);\n return result;\n } finally {\n inProgress.pop();\n }\n };\n\n const resolveAll = (): Record<string, TInterpreted> => {\n const out: Record<string, TInterpreted> = {};\n for (const name of Object.keys(group)) {\n out[name] = resolve(name);\n }\n return out;\n };\n\n return { resolve, resolveAll };\n};\n","/**\n * Derivation resolver (model-first).\n *\n * Resolves a `path -> Ref` token map to concrete literals, running **value derivations** — a\n * `Ref` of the form `{ ref, fn, arg }` means `value = registry[fn](resolve(ref), arg)`. Plain\n * `{ ref }` is an alias (`= resolve(ref)`), `{ value }` is a terminal literal. Recursive (so\n * chained derivations like `darker = darken(dark)` resolve), memoized per pass, and cycle-safe.\n *\n * Subsystems contribute derivation fns (colors → `lighten`/`darken`, typography → `scale`);\n * core assembles them into one {@link DerivationRegistry}. Used by `theme.tokens` (resolved\n * view) and by the CSS adapter's lowering (concrete `:root` / inline values). See\n * `.notes/reference/derivation-resolver-and-merge.md`.\n */\nimport type { Literal, Ref } from \"../model\";\nimport { RefractError } from \"../errors\";\n\n/** A value-derivation: derive a literal from a source literal + optional argument. */\nexport type DerivationFn = (value: Literal, arg?: unknown) => Literal;\n\n/** `fn name -> DerivationFn`, assembled from the subsystems (unique names; collisions throw). */\nexport type DerivationRegistry = Record<string, DerivationFn>;\n\n/** Merge subsystem derivation-fn maps into one registry; a duplicate name is a hard error. */\nexport const buildDerivationRegistry = (\n contributions: ReadonlyArray<Readonly<DerivationRegistry>>,\n): DerivationRegistry => {\n const registry: DerivationRegistry = {};\n for (const contribution of contributions) {\n for (const [name, fn] of Object.entries(contribution)) {\n if (name in registry) {\n throw new RefractError(\"REFRACT_E_TOKEN_PATH\", `Duplicate derivation fn \"${name}\" registered by two subsystems.`);\n }\n registry[name] = fn;\n }\n }\n return registry;\n};\n\n/**\n * Resolve one token `path` in `map` to a concrete literal, running any derivation. `cache` and\n * `resolving` are threaded through recursion (chaining + cycle detection); callers may omit them.\n */\nexport const resolveToken = (\n map: Record<string, Ref>,\n registry: DerivationRegistry,\n path: string,\n cache: Map<string, Literal> = new Map(),\n resolving: Set<string> = new Set(),\n): Literal => {\n const cached = cache.get(path);\n if (cached !== undefined) return cached;\n\n const entry = map[path];\n if (!entry) throw new RefractError(\"REFRACT_E_TOKEN_PATH\", `Unknown token path \"${path}\".`);\n\n // §W6b — external token: resolves to its parent-theme CSS variable, never derived.\n if (entry.external !== undefined) {\n const v = `var(${entry.external})`;\n cache.set(path, v);\n return v;\n }\n\n // Terminal literal — no ref to follow.\n if (entry.ref === undefined) {\n if (entry.value === undefined) {\n throw new RefractError(\"REFRACT_E_TOKEN_PATH\", `Token \"${path}\" has neither \"ref\" nor \"value\".`);\n }\n cache.set(path, entry.value);\n return entry.value;\n }\n\n if (resolving.has(path)) {\n throw new RefractError(\"REFRACT_E_CYCLE\", `Cyclic token reference: ${[...resolving, path].join(\" -> \")}`);\n }\n resolving.add(path);\n const base = resolveToken(map, registry, entry.ref, cache, resolving);\n let result: Literal;\n if (entry.modifiers !== undefined) {\n // dec.2 — fold the ordered derivation chain over the resolved source.\n result = entry.modifiers.reduce((value, mod) => {\n const fn = registry[mod.fn];\n if (!fn) throw new RefractError(\"REFRACT_E_TOKEN_PATH\", `Unknown derivation fn \"${mod.fn}\" for token \"${path}\".`);\n return fn(value, mod.arg);\n }, base);\n } else if (entry.fn !== undefined) {\n const fn = registry[entry.fn];\n if (!fn) throw new RefractError(\"REFRACT_E_TOKEN_PATH\", `Unknown derivation fn \"${entry.fn}\" for token \"${path}\".`);\n result = fn(base, entry.arg);\n } else {\n result = base; // plain alias\n }\n resolving.delete(path);\n cache.set(path, result);\n return result;\n};\n\n/** Resolve every entry in a token `map` to its concrete literal (one shared memo pass). */\nexport const resolveTokenMap = (\n map: Record<string, Ref>,\n registry: DerivationRegistry,\n): Record<string, Literal> => {\n const cache = new Map<string, Literal>();\n const out: Record<string, Literal> = {};\n for (const path of Object.keys(map)) {\n out[path] = resolveToken(map, registry, path, cache);\n }\n return out;\n};\n","/**\n * dec.4 — cross-property derivation resolve pass.\n *\n * A variant / mode value may derive from ANOTHER property (`surface.modes.dark =\n * { ref: \"colors.brand\", modifiers: [{ adjust: { l: 12 } }] }`). Colours bakes derivations one\n * property at a time, so a cross-property source isn't available at bake time — the owning subsystem\n * emits such a derivation **unbaked** (a `Ref` carrying `ref` + `modifiers`/`fn` but no cached\n * `value`). This post-build pass runs once the full `path -> Ref` token map exists and fills each\n * cross-property derived `Ref`'s `.value` by resolving its source and folding its chain.\n *\n * - **Variants** are addressable tokens, so their source resolves through `resolveToken` (which itself\n * follows the ref + folds modifiers across the whole map — chains of cross-property derivations\n * resolve for free, no ordering needed).\n * - **Modes are NOT tokens** (they're emit-only), so a mode's source is resolved via `resolveToken`\n * on its `ref` and the chain folded here by hand, rather than through a mode token that doesn't exist.\n *\n * The pass is **structural, not value-based**: it re-bakes any derived Ref whose source property\n * differs from the owner, regardless of whether a value is already present. That makes it correct on\n * `override()` too — re-running it against the merged token map re-derives a child's cross-property\n * values when the source changed, exactly like intra-property derivations. It rebuilds immutably\n * (new `Ref`s only where it re-bakes; every untouched branch keeps its reference), so a shared parent\n * Model is never mutated, and a Model with no cross-property derivation is returned by reference\n * (goldens byte-identical).\n */\nimport type { Literal, Ref, ThemeModel, PropertyModel, VariantModel } from \"../model\";\nimport { buildTokenMap } from \"../model\";\nimport { RefractError } from \"../errors\";\nimport { resolveToken, type DerivationRegistry } from \"./resolveTokens\";\n\n/** The `<subsystem>.<property>` prefix of a token path (the first two dotted segments). */\nconst propertyPrefix = (path: string): string => {\n const [seg0, seg1] = path.split(\".\");\n return `${seg0}.${seg1}`;\n};\n\n/** A derived Ref (carries `ref` + a chain) whose source lives in a DIFFERENT property than `owner`. */\nconst isCrossPropertyDerived = (ref: Ref | undefined, owner: string): boolean => {\n if (!ref?.ref) return false;\n if (ref.modifiers === undefined && ref.fn === undefined) return false; // a plain alias, not a derivation\n return propertyPrefix(ref.ref) !== owner;\n};\n\n/**\n * Re-bake one cross-property derived Ref: resolve its source value against the token map, fold its\n * modifier chain (or legacy `fn`/`arg`), and return a fresh Ref carrying the baked `.value`. The\n * derivation metadata (`ref` + chain) is preserved so `override()` re-derives it again.\n */\nconst rebake = (\n ref: Ref,\n tokens: Record<string, Ref>,\n registry: DerivationRegistry,\n cache: Map<string, Literal>,\n where: string,\n): Ref => {\n let value: Literal;\n try {\n value = resolveToken(tokens, registry, ref.ref as string, cache);\n } catch {\n throw new RefractError(\n \"REFRACT_E_VALIDATION\",\n `${where}: cross-property derivation references unknown token '${ref.ref}'.`,\n );\n }\n const apply = (fn: string, arg: unknown): Literal => {\n const derive = registry[fn];\n if (!derive) {\n throw new RefractError(\"REFRACT_E_VALIDATION\", `${where}: unknown derivation fn '${fn}'.`);\n }\n return derive(value, arg);\n };\n if (ref.modifiers !== undefined) {\n for (const mod of ref.modifiers) value = apply(mod.fn, mod.arg);\n } else if (ref.fn !== undefined) {\n value = apply(ref.fn, ref.arg);\n }\n return { ...ref, value };\n};\n\n/** Re-bake any cross-property derived Ref in a `field -> Ref` map (mode fields / variant extras). */\nconst rebakeFields = (\n fields: Record<string, Ref>,\n owner: string,\n tokens: Record<string, Ref>,\n registry: DerivationRegistry,\n cache: Map<string, Literal>,\n where: string,\n): Record<string, Ref> | undefined => {\n let next: Record<string, Ref> | undefined;\n for (const [name, ref] of Object.entries(fields)) {\n if (!isCrossPropertyDerived(ref, owner)) continue;\n next = next ?? { ...fields };\n next[name] = rebake(ref, tokens, registry, cache, `${where}.${name}`);\n }\n return next;\n};\n\n/** Re-bake a property's cross-property variants (base + extras). Returns undefined when none changed. */\nconst rebakeVariants = (\n variants: Record<string, VariantModel>,\n owner: string,\n tokens: Record<string, Ref>,\n registry: DerivationRegistry,\n cache: Map<string, Literal>,\n): Record<string, VariantModel> | undefined => {\n let next: Record<string, VariantModel> | undefined;\n for (const [name, variant] of Object.entries(variants)) {\n const at = `${owner}.variants.${name}`;\n const base = isCrossPropertyDerived(variant.base, owner)\n ? rebake(variant.base, tokens, registry, cache, at)\n : variant.base;\n const extras = variant.extras\n ? rebakeFields(variant.extras, owner, tokens, registry, cache, `${at} extra`)\n : undefined;\n if (base === variant.base && !extras) continue;\n next = next ?? { ...variants };\n next[name] = extras ? { base, extras } : { ...variant, base };\n }\n return next;\n};\n\n/** Re-bake a single property's cross-property variants + modes. Returns undefined when none changed. */\nconst rebakeProperty = (\n pm: PropertyModel,\n owner: string,\n tokens: Record<string, Ref>,\n registry: DerivationRegistry,\n cache: Map<string, Literal>,\n): PropertyModel | undefined => {\n const variants = pm.variants\n ? rebakeVariants(pm.variants, owner, tokens, registry, cache)\n : undefined;\n\n let modes: PropertyModel[\"modes\"] | undefined;\n if (pm.modes) {\n for (let i = 0; i < pm.modes.length; i++) {\n const entry = pm.modes[i];\n if (!entry.overrides) continue;\n const nextFields = rebakeFields(entry.overrides, owner, tokens, registry, cache, `${owner}.modes.${entry.mode}`);\n if (!nextFields) continue;\n modes = modes ?? [...pm.modes];\n modes[i] = { ...entry, overrides: nextFields };\n }\n }\n\n if (!variants && !modes) return undefined;\n const next: PropertyModel = { ...pm };\n if (variants) next.variants = variants;\n if (modes) next.modes = modes;\n return next;\n};\n\n/**\n * Fill every cross-property derived variant / mode Ref's `.value` against the Model's token map.\n * Immutable — returns the Model by reference when nothing is cross-property (byte-identical output).\n */\nexport const bakeCrossPropertyDerivations = (\n model: ThemeModel,\n registry: DerivationRegistry,\n): ThemeModel => {\n const tokens = buildTokenMap(model);\n const cache = new Map<string, Literal>();\n let modelChanged = false;\n const nextSubsystems: ThemeModel[\"subsystems\"] = {};\n\n for (const [subKey, sub] of Object.entries(model.subsystems)) {\n let subChanged = false;\n let nextProps: Record<string, PropertyModel> | undefined;\n for (const [propName, pm] of Object.entries(sub.properties ?? {})) {\n const owner = `${subKey}.${propName}`;\n const nextPm = rebakeProperty(pm, owner, tokens, registry, cache);\n if (!nextPm) continue;\n nextProps = nextProps ?? { ...sub.properties };\n nextProps[propName] = nextPm;\n subChanged = true;\n }\n if (subChanged) {\n nextSubsystems[subKey] = { ...sub, properties: nextProps };\n modelChanged = true;\n } else {\n nextSubsystems[subKey] = sub;\n }\n }\n\n return modelChanged ? { ...model, subsystems: nextSubsystems } : model;\n};\n","import type { MediaQueryOptions } from \"./queries\";\nimport { RefractError } from \"../errors\";\n\nexport const BREAKPOINT_EPSILON = 0.02;\n\nconst RESERVED_BREAKPOINT_KEYS = [\"min\", \"max\", \"exact\", \"between\"] as const;\n\nexport type MediaVariant = \"min\" | \"max\" | \"exact\";\n\nexport type MediaGroupDescriptor = Record<MediaVariant, string>;\n\nexport type MediaDescriptor<TBreakpoint extends string> = {\n min: (key: TBreakpoint, options?: MediaQueryOptions) => string;\n max: (key: TBreakpoint, options?: MediaQueryOptions) => string;\n exact: (key: TBreakpoint, options?: MediaQueryOptions) => string;\n between: (\n from: TBreakpoint,\n to: TBreakpoint,\n options?: MediaQueryOptions,\n ) => string;\n} & Record<TBreakpoint, MediaGroupDescriptor>;\n\nexport const sortBreakpointKeys = <T extends string>(\n breakpoints: Record<T, number>,\n): T[] => (Object.keys(breakpoints) as T[]).sort(\n (a, b) => breakpoints[a] - breakpoints[b],\n);\n\nconst maxValueForNext = (next?: number): number | undefined =>\n next === undefined ? undefined : next - BREAKPOINT_EPSILON;\n\nconst assertNoReservedBreakpointNames = (keys: readonly string[]): void => {\n const conflicts = keys.filter(key =>\n (RESERVED_BREAKPOINT_KEYS as readonly string[]).includes(key),\n );\n if (conflicts.length) {\n throw new RefractError(\n \"REFRACT_E_BREAKPOINT\",\n `Breakpoint names conflict with reserved keys: ${conflicts\n .map(k => `\"${k}\"`)\n .join(\", \")}. Reserved: ${RESERVED_BREAKPOINT_KEYS.map(k => `\"${k}\"`).join(\", \")}.`,\n );\n }\n};\n\nexport const buildMediaDescriptor = <TBreakpoint extends string>(\n breakpoints: Record<TBreakpoint, number>,\n resolveQuery: (\n options: MediaQueryOptions,\n ) => string,\n): MediaDescriptor<TBreakpoint> => {\n const keys = sortBreakpointKeys(breakpoints);\n assertNoReservedBreakpointNames(keys);\n\n const nextOf = (key: TBreakpoint): TBreakpoint | undefined =>\n keys[keys.indexOf(key) + 1];\n\n const groups = keys.reduce<Record<TBreakpoint, MediaGroupDescriptor>>(\n (acc, key) => {\n const own = breakpoints[key];\n const nextKey = nextOf(key);\n const next = nextKey !== undefined ? breakpoints[nextKey] : undefined;\n\n acc[key] = buildGroupDescriptor({ own, next }, resolveQuery);\n return acc;\n },\n {} as Record<TBreakpoint, MediaGroupDescriptor>,\n );\n\n const resolveKey = (key: TBreakpoint): MediaGroupDescriptor => {\n const group = groups[key];\n if (!group) {\n throw new RefractError(\"REFRACT_E_BREAKPOINT\", `Breakpoint \"${key}\" is not defined.`);\n }\n return group;\n };\n\n const between = (\n from: TBreakpoint,\n to: TBreakpoint,\n options?: MediaQueryOptions,\n ): string => {\n const min = breakpoints[from];\n const toValue = breakpoints[to];\n\n if (min === undefined || toValue === undefined) {\n throw new RefractError(\n \"REFRACT_E_BREAKPOINT\",\n `Cannot build media query between \"${from}\" and \"${to}\" breakpoints.`,\n );\n }\n\n return resolveQuery({ min, max: toValue - BREAKPOINT_EPSILON, ...options });\n };\n\n const descriptor = {\n ...groups,\n min: (key: TBreakpoint, options?: MediaQueryOptions) => {\n const group = resolveKey(key);\n if (!options) {\n return group.min;\n }\n return resolveQuery({ min: breakpoints[key], ...options });\n },\n max: (key: TBreakpoint, options?: MediaQueryOptions) => {\n const group = resolveKey(key);\n if (!options) {\n return group.max;\n }\n const nextKey = nextOf(key);\n const next = nextKey !== undefined ? breakpoints[nextKey] : undefined;\n return resolveQuery({ max: maxValueForNext(next), ...options });\n },\n exact: (key: TBreakpoint, options?: MediaQueryOptions) => {\n const group = resolveKey(key);\n if (!options) {\n return group.exact;\n }\n const nextKey = nextOf(key);\n const next = nextKey !== undefined ? breakpoints[nextKey] : undefined;\n return resolveQuery({ min: breakpoints[key], max: maxValueForNext(next), ...options });\n },\n between,\n } as MediaDescriptor<TBreakpoint>;\n\n return descriptor;\n};\n\nconst buildGroupDescriptor = (\n { own, next }: { own: number; next?: number },\n resolveQuery: (options: MediaQueryOptions) => string,\n): MediaGroupDescriptor => {\n const maxValue = maxValueForNext(next);\n return {\n min: resolveQuery({ min: own }),\n max: maxValue === undefined ? \"\" : resolveQuery({ max: maxValue }),\n exact: resolveQuery({ min: own, max: maxValue }),\n };\n};\n","import { RefractError } from \"../errors\";\n\nexport type MediaUnit = \"px\" | \"em\" | \"rem\";\n\nexport type MediaConfig = {\n unit?: MediaUnit;\n baseFontSize?: number;\n};\n\nexport type MediaQueryOptions = {\n min?: number;\n max?: number;\n orientation?: \"landscape\" | \"portrait\";\n};\n\nconst DEFAULT_MEDIA_CONFIG: Required<MediaConfig> = {\n unit: \"px\",\n baseFontSize: 16,\n};\n\nexport const resolveMediaConfig = (\n config?: MediaConfig,\n): Required<MediaConfig> => ({\n unit: config?.unit ?? DEFAULT_MEDIA_CONFIG.unit,\n baseFontSize:\n config?.baseFontSize && config.baseFontSize > 0\n ? config.baseFontSize\n : DEFAULT_MEDIA_CONFIG.baseFontSize,\n});\n\nexport const formatWidth = (value: number, config: Required<MediaConfig>): string => {\n if (config.unit === \"px\") {\n return `${value}px`;\n }\n\n const converted = value / config.baseFontSize;\n const trimmed = Number(converted.toFixed(4));\n return `${trimmed}${config.unit}`;\n};\n\nexport const mediaQueryString = (\n { min, max, orientation }: MediaQueryOptions,\n config: Required<MediaConfig>,\n): string => {\n const clauses: string[] = [];\n\n if (min !== undefined && max !== undefined && min > max) {\n throw new RefractError(\"REFRACT_E_MEDIA\", \"Invalid media query: `min` cannot be greater than `max`.\");\n }\n\n if (min !== undefined) {\n clauses.push(`(min-width: ${formatWidth(min, config)})`);\n }\n\n if (max !== undefined) {\n clauses.push(`(max-width: ${formatWidth(max, config)})`);\n }\n\n if (orientation) {\n clauses.push(`(orientation: ${orientation})`);\n }\n\n if (!clauses.length) {\n return \"\";\n }\n\n return `@media ${clauses.join(\" and \")}`;\n};\n\nexport const mediaQuery = (\n options: MediaQueryOptions,\n config?: MediaConfig,\n): string => mediaQueryString(options, resolveMediaConfig(config));\n\n/**\n * Container-query prelude (§10.5) — the `@container <name> (…)` twin of {@link mediaQueryString}.\n * Shares the width formatting (so container thresholds honor the same px/em/rem unit config), but\n * has no `orientation` clause (invalid under `container-type: inline-size`; rejected in normalize).\n */\nexport const containerQueryString = (\n name: string,\n { min, max }: Pick<MediaQueryOptions, \"min\" | \"max\">,\n config: Required<MediaConfig>,\n): string => {\n const clauses: string[] = [];\n if (min !== undefined && max !== undefined && min > max) {\n throw new RefractError(\"REFRACT_E_MEDIA\", \"Invalid container query: `min` cannot be greater than `max`.\");\n }\n if (min !== undefined) clauses.push(`(min-width: ${formatWidth(min, config)})`);\n if (max !== undefined) clauses.push(`(max-width: ${formatWidth(max, config)})`);\n if (!clauses.length) return \"\";\n return `@container ${name} ${clauses.join(\" and \")}`;\n};\n","export type DefaultBreakpointKey = \"xs\" | \"sm\" | \"md\" | \"lg\" | \"xl\";\nexport type DefaultBreakpoints = Record<DefaultBreakpointKey, number>;\n\nexport const DEFAULT_BREAKPOINTS: DefaultBreakpoints = {\n xs: 0,\n sm: 576,\n md: 768,\n lg: 992,\n xl: 1280,\n};\n","/**\n * Container-query descriptors (§10.5).\n *\n * A named query container has a *size* scale (`sizeName → px`), exactly the shape a breakpoint scale\n * has — so each container reuses {@link buildMediaDescriptor} with an `@container`-prefixing resolver.\n * The result is a per-container descriptor whose `.min/.max/.exact(sizeName)` (and `[sizeName][kind]`)\n * yield `@container <name> (…)` preludes with the same min/max/exact + band-to-next semantics the\n * viewport axis uses. Threshold widths honor the shared media unit config (px default, em/rem).\n */\nimport { buildMediaDescriptor, type MediaDescriptor } from \"./descriptors\";\nimport { containerQueryString, resolveMediaConfig, type MediaConfig } from \"./queries\";\nimport type { ContainerModel } from \"../model/model\";\n\n/** One descriptor per named container: `containerName → MediaDescriptor` over that container's size scale. */\nexport type ContainerDescriptors = Record<string, MediaDescriptor<string>>;\n\n/**\n * Build a {@link ContainerDescriptors} map from the theme's `containers` config. Each container's\n * `sizes` become the descriptor's \"breakpoints\"; the resolver emits `@container <name> (…)`. The\n * width unit follows `config` (shared with the viewport media descriptor).\n */\nexport const buildContainerDescriptors = (\n containers: Record<string, ContainerModel> | undefined,\n config?: MediaConfig,\n): ContainerDescriptors => {\n const resolved = resolveMediaConfig(config);\n const out: ContainerDescriptors = {};\n for (const [name, container] of Object.entries(containers ?? {})) {\n out[name] = buildMediaDescriptor(container.sizes, opts =>\n containerQueryString(name, { min: opts.min, max: opts.max }, resolved),\n );\n }\n return out;\n};\n","/**\n * Pure colour math for palette step + variant synthesis.\n *\n * Lightness / hue / chroma work runs in **OKLCH** (a perceptual space) via Björn Ottosson's\n * public-domain matrices — parse → sRGB → linear → OKLab → OKLCH → apply → gamut-map → linear →\n * sRGB → quantize → serialize — so equal lightness steps look even and one lightness reads the same\n * across hues. hex / `rgba()` strings are only touched at the boundary (`parseColor` in,\n * `serializeColor` out). `lighten` / `darken` shift OKLCH lightness by ΔL points; `setL` places an\n * absolute lightness; `rotateHue` / `complement` turn the hue; `alpha` sets opacity. All are\n * string-in / string-out so the same fns run at normalize time (baking the cached value) and later\n * in the derivation registry — AND are vendored to consumers (see `build/vendor.ts`) so a value\n * computed live in the app matches the emitted CSS variable. Kept dependency-free for that vendoring.\n */\n\n/** An `[r, g, b]` channel triple, each `0–255`. */\nexport type RGBTuple = readonly [number, number, number];\n\n/** An `[r, g, b, a]` quad — channels `0–255`, alpha `0–1`. */\nexport type RGBATuple = readonly [number, number, number, number];\n\n/** A colour authored/worked as a tuple — opaque `[r,g,b]` or translucent `[r,g,b,a]`. */\nexport type ColorTuple = RGBTuple | RGBATuple;\n\nconst HEX_LENGTHS = new Set([3, 6]);\n\nconst clamp = (value: number, min: number, max: number): number => Math.min(max, Math.max(min, value));\nconst clampChannel = (value: number): number => clamp(value, 0, 255);\nconst clampAlpha = (value: number): number => clamp(value, 0, 1);\nconst clampPercent = (percent: number): number => clamp(percent, 0, 100);\n\n/** Round to `dp` decimal places (tidy CSS output — `71.8`, not `71.79999`). */\nconst roundTo = (value: number, dp: number): number => {\n const f = 10 ** dp;\n return Math.round(value * f) / f;\n};\n\n/** Round an alpha to 3 decimals so serialized `rgba()` stays tidy (`0.4`, not `0.4000001`). */\nconst roundAlpha = (a: number): number => Math.round(clampAlpha(a) * 1000) / 1000;\n\n/** Parse a 3- or 6-digit hex string (with or without `#`) into an `[r, g, b]` tuple. */\nexport const convertHexToRGB = (hex: string): RGBTuple => {\n const sanitized = hex.replace(/^\\s*#|\\s*$/g, \"\");\n\n if (!HEX_LENGTHS.has(sanitized.length)) {\n // Plain Error on purpose: this module is vendored import-free (build/vendor.ts) so it can be\n // transpiled standalone into consumer bundles — it cannot import RefractError. Its parse errors are\n // re-thrown as REFRACT_E_COLOR_INPUT by colors/normalize.ts, which is the coded authoring surface.\n throw new Error(`Unsupported hex length: \"${sanitized}\". Use 3 or 6 digits.`);\n }\n\n const normalized = sanitized.length === 3 ? sanitized.replace(/(.)/g, \"$1$1\") : sanitized;\n\n return [\n parseInt(normalized.substring(0, 2), 16),\n parseInt(normalized.substring(2, 4), 16),\n parseInt(normalized.substring(4, 6), 16),\n ] as RGBTuple;\n};\n\n/** Serialize an `[r, g, b]` tuple back to a `#rrggbb` string, clamping each channel to `0–255`. */\nexport const convertRgbToHex = (rgb: RGBTuple): string => {\n if (rgb.length !== 3) {\n throw new Error(`Expected RGB tuple of length 3, received ${rgb.length}`);\n }\n\n const hex = rgb\n .map(value => {\n const next = clampChannel(Math.round(value)).toString(16);\n return next.length === 1 ? `0${next}` : next;\n })\n .join(\"\");\n\n return `#${hex}`;\n};\n\nconst RGB_FN = /^rgba?\\(\\s*([\\d.]+)\\s*,\\s*([\\d.]+)\\s*,\\s*([\\d.]+)\\s*(?:,\\s*([\\d.]+)\\s*)?\\)$/i;\n\n/**\n * Parse any canonical colour string this subsystem produces — a 3/6-digit hex **or** an\n * `rgb()` / `rgba()` string — into `{ rgb, a }` (alpha defaults to `1`). This is the boundary\n * gate; a value that isn't parseable rgb (e.g. a bare CSS keyword or `var(--…)`) throws, so\n * callers can surface a friendly \"this colour can't be derived from\" error.\n */\nexport const parseColor = (value: string): { rgb: RGBTuple; a: number } => {\n const trimmed = value.trim();\n\n const fn = RGB_FN.exec(trimmed);\n if (fn) {\n return {\n rgb: [Number(fn[1]), Number(fn[2]), Number(fn[3])] as RGBTuple,\n a: fn[4] === undefined ? 1 : roundAlpha(Number(fn[4])),\n };\n }\n\n return { rgb: convertHexToRGB(trimmed), a: 1 };\n};\n\n/**\n * Serialize `[r, g, b]` (+ optional alpha) to the canonical CSS string — always `rgb(r, g, b)`\n * when fully opaque, else `rgba(r, g, b, a)`. The single serialization point for the subsystem, so\n * the Model (and every adapter + `resolveToken`) always carries one canonical `rgb()/rgba()` form\n * per colour — never hex. (`convertRgbToHex` remains for the vendored consumer helper + input parsing.)\n */\nexport const serializeColor = (rgb: RGBTuple, a = 1): string => {\n const alpha = roundAlpha(a);\n const [r, g, b] = rgb;\n const R = clampChannel(Math.round(r));\n const G = clampChannel(Math.round(g));\n const B = clampChannel(Math.round(b));\n return alpha >= 1 ? `rgb(${R}, ${G}, ${B})` : `rgba(${R}, ${G}, ${B}, ${alpha})`;\n};\n\nconst HEX_RE = /^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/;\n\n/** Whether a string is a 3- or 6-digit `#`-prefixed hex colour. */\nexport const isHexColor = (value: string): boolean => HEX_RE.test(value.trim());\n\n\n// ─── OKLCH synthesis (Björn Ottosson public-domain matrices) ──────────────────────────────────\n// Lightness / hue / chroma adjustments happen here, in a perceptual space, so equal ΔL steps look\n// even and one lightness reads consistently across hues. `L` is carried on a 0–100 scale (matching\n// the authoring dials); OKLab's native `L` is 0–1. sRGB channels are 0–255 only at the boundary.\n\n/** An OKLCH colour — perceptual lightness `L` (0–100), chroma `C` (≥ 0), hue `h` (degrees, 0–360). */\nexport type OKLCH = { L: number; C: number; h: number };\n\nconst DEG = 180 / Math.PI;\nconst GAMUT_EPS = 1e-6;\nconst GAMUT_ITERATIONS = 24;\n\n/** sRGB channel (0–1) → linear-light (0–1). */\nconst srgbToLinear = (c: number): number =>\n c <= 0.04045 ? c / 12.92 : Math.pow((c + 0.055) / 1.055, 2.4);\n\n/** Linear-light channel (0–1) → sRGB (0–1). */\nconst linearToSrgb = (c: number): number =>\n c >= 0.0031308 ? 1.055 * Math.pow(c, 1 / 2.4) - 0.055 : 12.92 * c;\n\n/** Linear-sRGB `[r, g, b]` (0–1) → OKLab `{ L: 0–1, a, b }`. */\nconst linearRgbToOklab = (\n lr: number,\n lg: number,\n lb: number,\n): { L: number; a: number; b: number } => {\n const l = 0.4122214708 * lr + 0.5363325363 * lg + 0.0514459929 * lb;\n const m = 0.2119034982 * lr + 0.6806995451 * lg + 0.1073969566 * lb;\n const s = 0.0883024619 * lr + 0.2817188376 * lg + 0.6299787005 * lb;\n const l_ = Math.cbrt(l);\n const m_ = Math.cbrt(m);\n const s_ = Math.cbrt(s);\n return {\n L: 0.2104542553 * l_ + 0.793617785 * m_ - 0.0040720468 * s_,\n a: 1.9779984951 * l_ - 2.428592205 * m_ + 0.4505937099 * s_,\n b: 0.0259040371 * l_ + 0.7827717662 * m_ - 0.808675766 * s_,\n };\n};\n\n/** OKLab `{ L: 0–1, a, b }` → linear-sRGB `[r, g, b]` (may fall outside 0–1 when out of gamut). */\nconst oklabToLinearRgb = (L: number, a: number, b: number): [number, number, number] => {\n const l_ = L + 0.3963377774 * a + 0.2158037573 * b;\n const m_ = L - 0.1055613458 * a - 0.0638541728 * b;\n const s_ = L - 0.0894841775 * a - 1.291485548 * b;\n const l = l_ * l_ * l_;\n const m = m_ * m_ * m_;\n const s = s_ * s_ * s_;\n return [\n 4.0767416621 * l - 3.3077115913 * m + 0.2309699292 * s,\n -1.2684380046 * l + 2.6097574011 * m - 0.3413193965 * s,\n -0.0041960863 * l - 0.7034186147 * m + 1.707614701 * s,\n ];\n};\n\n/** Convert an sRGB `[r, g, b]` (0–255) triple to OKLCH (`L` on a 0–100 scale). */\nexport const rgbToOklch = (rgb: RGBTuple): OKLCH => {\n const [r, g, b] = rgb;\n const lab = linearRgbToOklab(srgbToLinear(r / 255), srgbToLinear(g / 255), srgbToLinear(b / 255));\n const C = Math.sqrt(lab.a * lab.a + lab.b * lab.b);\n let h = Math.atan2(lab.b, lab.a) * DEG;\n if (h < 0) h += 360;\n return { L: lab.L * 100, C, h };\n};\n\n/**\n * Convert OKLCH back to an sRGB `[r, g, b]` triple (**unquantized** 0–255 floats). Holds `L` and\n * `h`; when the requested chroma is outside sRGB it binary-searches `C` downward — fixed iterations,\n * no data-dependent early exit, so build- and runtime-computed values agree (§20.8) — until the\n * linear result is in `[0, 1]`. Lightness and hue are never adjusted, so a synthesized ramp keeps\n * its hue and even lightness spacing; only saturation gives way at the gamut boundary. The floats\n * are quantized exactly once, later, by `serializeColor`, so the 0–255 channel clamp never fires.\n */\nexport const oklchToRgb = (color: OKLCH): RGBTuple => {\n const L = clamp(color.L, 0, 100) / 100;\n const hr = color.h / DEG;\n const cosh = Math.cos(hr);\n const sinh = Math.sin(hr);\n\n const linearAt = (c: number): [number, number, number] => oklabToLinearRgb(L, c * cosh, c * sinh);\n const inGamut = (lin: [number, number, number]): boolean =>\n lin.every(v => v >= -GAMUT_EPS && v <= 1 + GAMUT_EPS);\n\n let lin = linearAt(color.C);\n if (!inGamut(lin)) {\n // `C = 0` (a neutral grey at this L) is always in gamut, so `lo` starts from a valid floor.\n let lo = 0;\n let hi = color.C;\n for (let i = 0; i < GAMUT_ITERATIONS; i++) {\n const mid = (lo + hi) / 2;\n if (inGamut(linearAt(mid))) lo = mid;\n else hi = mid;\n }\n lin = linearAt(lo);\n }\n\n return [\n linearToSrgb(clamp(lin[0], 0, 1)) * 255,\n linearToSrgb(clamp(lin[1], 0, 1)) * 255,\n linearToSrgb(clamp(lin[2], 0, 1)) * 255,\n ] as RGBTuple;\n};\n\n/** Run a colour string through OKLCH, apply `transform`, and re-serialize (alpha preserved). */\nconst withOklch = (value: string, transform: (lch: OKLCH) => OKLCH): string => {\n const { rgb, a } = parseColor(value);\n return serializeColor(oklchToRgb(transform(rgbToOklch(rgb))), a);\n};\n\n/** Lighten a colour by `delta` OKLCH lightness points (0–100 scale); hue, chroma, alpha preserved. */\nexport const lighten = (value: string, delta: number): string =>\n withOklch(value, lch => ({ ...lch, L: clamp(lch.L + delta, 0, 100) }));\n\n/** Darken a colour by `delta` OKLCH lightness points (0–100 scale); hue, chroma, alpha preserved. */\nexport const darken = (value: string, delta: number): string =>\n withOklch(value, lch => ({ ...lch, L: clamp(lch.L - delta, 0, 100) }));\n\n/** Set a colour's absolute OKLCH lightness to `L` (0–100); hue, chroma, alpha preserved. */\nexport const setL = (value: string, L: number): string =>\n withOklch(value, lch => ({ ...lch, L: clamp(L, 0, 100) }));\n\n/** Rotate a colour's OKLCH hue by `deg` (signed) around the perceptual wheel; L, C, alpha preserved. */\nexport const rotateHue = (value: string, deg: number): string =>\n withOklch(value, lch => ({ ...lch, h: (((lch.h + deg) % 360) + 360) % 360 }));\n\n/** The perceptual complement — a 180° hue rotation at the same lightness and chroma. */\nexport const complement = (value: string): string => rotateHue(value, 180);\n\n/**\n * An `adjust` dial set — any subset. `l` = **absolute** OKLCH lightness target (0–100, raw L, the\n * opposite direction from a numeric-`steps` label); `c` = chroma **multiplier** (`1` keep, `0` grey,\n * `>1` more saturated where the gamut allows); `h` = **signed** hue rotation in degrees. Numbers\n * only — keeps the vendored math string-free.\n */\nexport type AdjustDials = { l?: number; c?: number; h?: number };\n\n/**\n * One-shot OKLCH placement — set an absolute lightness, scale chroma, and/or rotate hue in a single\n * derivation (each dial optional; an omitted dial leaves that component untouched). Alpha preserved.\n */\nexport const adjust = (value: string, dials: AdjustDials): string =>\n withOklch(value, lch => ({\n L: dials.l === undefined ? lch.L : clamp(dials.l, 0, 100),\n C: dials.c === undefined ? lch.C : Math.max(0, lch.C * dials.c),\n h: dials.h === undefined ? lch.h : (((lch.h + dials.h) % 360) + 360) % 360,\n }));\n\n/**\n * Convert any canonical colour string (the subsystem's `rgb()` / `rgba()` form, or a hex string)\n * to hex — 6-digit `#rrggbb` when opaque, 8-digit `#rrggbbaa` when translucent. Used by the DTCG\n * exporter, whose `color` token type is conventionally hex (every other output stays `rgb()`).\n */\nexport const toHexColor = (value: string): string => {\n const { rgb, a } = parseColor(value);\n const hex = convertRgbToHex(rgb);\n if (a >= 1) return hex;\n const aa = clampChannel(Math.round(a * 255)).toString(16).padStart(2, \"0\");\n return `${hex}${aa}`;\n};\n\n/**\n * Convert any canonical colour string (the subsystem's `rgb()` / `rgba()` form, or a hex string) to\n * a CSS Color 4 `oklch(L% C H)` string — `oklch(L% C H / a)` when translucent. `L` is a percentage\n * (0–100), `C` the absolute chroma, `H` in degrees, derived from the stored (quantized) rgb. Used by\n * the CSS adapter's `colorFormat: \"oklch\"` output; the colour is identical to the `rgb()` form.\n */\nexport const toOklchColor = (value: string): string => {\n const { rgb, a } = parseColor(value);\n const { L, C, h } = rgbToOklch(rgb);\n const body = `${roundTo(L, 2)}% ${roundTo(C, 4)} ${roundTo(h, 2)}`;\n return a >= 1 ? `oklch(${body})` : `oklch(${body} / ${roundAlpha(a)})`;\n};\n\n/**\n * Set a colour's opacity to `percent` (0–100) — an **absolute** alpha, not a relative fade\n * (`alpha(x, 40)` ⇒ 40% opaque). The rgb channels are untouched; only the alpha channel is\n * replaced. Result serializes to `rgba(…)` (or hex when `percent` is 100).\n */\nexport const alpha = (value: string, percent: number): string => {\n const { rgb } = parseColor(value);\n return serializeColor(rgb, clampPercent(percent) / 100);\n};\n","/**\n * The CSS named colours (CSS Color Module Level 4 `<named-color>` list), mapped to their canonical\n * 6-digit hex. Authored colours may be given by keyword (`rebeccapurple`, `tomato`, …); the input\n * gate normalizes them to the subsystem's canonical `rgb()` form like any other input.\n *\n * `transparent` and `currentColor` are intentionally absent — neither is an opaque, tonally-derivable\n * colour, so they fall through to the input gate's rejection with a clear message.\n */\nexport const CSS_COLOR_KEYWORDS: Record<string, string> = {\n aliceblue: \"#f0f8ff\", antiquewhite: \"#faebd7\", aqua: \"#00ffff\", aquamarine: \"#7fffd4\",\n azure: \"#f0ffff\", beige: \"#f5f5dc\", bisque: \"#ffe4c4\", black: \"#000000\",\n blanchedalmond: \"#ffebcd\", blue: \"#0000ff\", blueviolet: \"#8a2be2\", brown: \"#a52a2a\",\n burlywood: \"#deb887\", cadetblue: \"#5f9ea0\", chartreuse: \"#7fff00\", chocolate: \"#d2691e\",\n coral: \"#ff7f50\", cornflowerblue: \"#6495ed\", cornsilk: \"#fff8dc\", crimson: \"#dc143c\",\n cyan: \"#00ffff\", darkblue: \"#00008b\", darkcyan: \"#008b8b\", darkgoldenrod: \"#b8860b\",\n darkgray: \"#a9a9a9\", darkgreen: \"#006400\", darkgrey: \"#a9a9a9\", darkkhaki: \"#bdb76b\",\n darkmagenta: \"#8b008b\", darkolivegreen: \"#556b2f\", darkorange: \"#ff8c00\", darkorchid: \"#9932cc\",\n darkred: \"#8b0000\", darksalmon: \"#e9967a\", darkseagreen: \"#8fbc8f\", darkslateblue: \"#483d8b\",\n darkslategray: \"#2f4f4f\", darkslategrey: \"#2f4f4f\", darkturquoise: \"#00ced1\", darkviolet: \"#9400d3\",\n deeppink: \"#ff1493\", deepskyblue: \"#00bfff\", dimgray: \"#696969\", dimgrey: \"#696969\",\n dodgerblue: \"#1e90ff\", firebrick: \"#b22222\", floralwhite: \"#fffaf0\", forestgreen: \"#228b22\",\n fuchsia: \"#ff00ff\", gainsboro: \"#dcdcdc\", ghostwhite: \"#f8f8ff\", gold: \"#ffd700\",\n goldenrod: \"#daa520\", gray: \"#808080\", green: \"#008000\", greenyellow: \"#adff2f\",\n grey: \"#808080\", honeydew: \"#f0fff0\", hotpink: \"#ff69b4\", indianred: \"#cd5c5c\",\n indigo: \"#4b0082\", ivory: \"#fffff0\", khaki: \"#f0e68c\", lavender: \"#e6e6fa\",\n lavenderblush: \"#fff0f5\", lawngreen: \"#7cfc00\", lemonchiffon: \"#fffacd\", lightblue: \"#add8e6\",\n lightcoral: \"#f08080\", lightcyan: \"#e0ffff\", lightgoldenrodyellow: \"#fafad2\", lightgray: \"#d3d3d3\",\n lightgreen: \"#90ee90\", lightgrey: \"#d3d3d3\", lightpink: \"#ffb6c1\", lightsalmon: \"#ffa07a\",\n lightseagreen: \"#20b2aa\", lightskyblue: \"#87cefa\", lightslategray: \"#778899\", lightslategrey: \"#778899\",\n lightsteelblue: \"#b0c4de\", lightyellow: \"#ffffe0\", lime: \"#00ff00\", limegreen: \"#32cd32\",\n linen: \"#faf0e6\", magenta: \"#ff00ff\", maroon: \"#800000\", mediumaquamarine: \"#66cdaa\",\n mediumblue: \"#0000cd\", mediumorchid: \"#ba55d3\", mediumpurple: \"#9370db\", mediumseagreen: \"#3cb371\",\n mediumslateblue: \"#7b68ee\", mediumspringgreen: \"#00fa9a\", mediumturquoise: \"#48d1cc\",\n mediumvioletred: \"#c71585\", midnightblue: \"#191970\", mintcream: \"#f5fffa\", mistyrose: \"#ffe4e1\",\n moccasin: \"#ffe4b5\", navajowhite: \"#ffdead\", navy: \"#000080\", oldlace: \"#fdf5e6\",\n olive: \"#808000\", olivedrab: \"#6b8e23\", orange: \"#ffa500\", orangered: \"#ff4500\",\n orchid: \"#da70d6\", palegoldenrod: \"#eee8aa\", palegreen: \"#98fb98\", paleturquoise: \"#afeeee\",\n palevioletred: \"#db7093\", papayawhip: \"#ffefd5\", peachpuff: \"#ffdab9\", peru: \"#cd853f\",\n pink: \"#ffc0cb\", plum: \"#dda0dd\", powderblue: \"#b0e0e6\", purple: \"#800080\",\n rebeccapurple: \"#663399\", red: \"#ff0000\", rosybrown: \"#bc8f8f\", royalblue: \"#4169e1\",\n saddlebrown: \"#8b4513\", salmon: \"#fa8072\", sandybrown: \"#f4a460\", seagreen: \"#2e8b57\",\n seashell: \"#fff5ee\", sienna: \"#a0522d\", silver: \"#c0c0c0\", skyblue: \"#87ceeb\",\n slateblue: \"#6a5acd\", slategray: \"#708090\", slategrey: \"#708090\", snow: \"#fffafa\",\n springgreen: \"#00ff7f\", steelblue: \"#4682b4\", tan: \"#d2b48c\", teal: \"#008080\",\n thistle: \"#d8bfd8\", tomato: \"#ff6347\", turquoise: \"#40e0d0\", violet: \"#ee82ee\",\n wheat: \"#f5deb3\", white: \"#ffffff\", whitesmoke: \"#f5f5f5\", yellow: \"#ffff00\",\n yellowgreen: \"#9acd32\",\n};\n","/**\n * Build-time colour **input** parsing.\n *\n * Kept out of `utils.ts` on purpose: `utils.ts` is vendored to consumers (see `build/vendor.ts`) and\n * must stay import-free, but input parsing needs the CSS-keyword table. `coerceColorInput` normalizes\n * any authored colour — hex, `[r, g, b]`, `oklch()`, `hsl()/hsla()`, `rgb()/rgba()`, or a CSS named\n * keyword — to the subsystem's canonical `rgb()` / `rgba()` form (derivation still runs in OKLCH). A\n * `var(--…)` (and `currentColor` / `transparent`) is rejected — none can be tonally derived at build.\n */\nimport { convertHexToRGB, oklchToRgb, parseColor, serializeColor, type RGBTuple } from \"./utils\";\nimport { CSS_COLOR_KEYWORDS } from \"./keywords\";\nimport { RefractError } from \"../../core/errors\";\n\nconst roundAlpha = (a: number): number => Math.round(Math.min(1, Math.max(0, a)) * 1000) / 1000;\n\n/** Convert HSL (`h` in degrees, `s` and `l` on `0–1`) to an sRGB `[r, g, b]` triple (0–255). */\nconst hslToRgb = (h: number, s: number, l: number): RGBTuple => {\n const hue = (((h % 360) + 360) % 360) / 60;\n const c = (1 - Math.abs(2 * Math.min(1, Math.max(0, l)) - 1)) * Math.min(1, Math.max(0, s));\n const x = c * (1 - Math.abs((hue % 2) - 1));\n const m = Math.min(1, Math.max(0, l)) - c / 2;\n const [r, g, b] =\n hue < 1 ? [c, x, 0] :\n hue < 2 ? [x, c, 0] :\n hue < 3 ? [0, c, x] :\n hue < 4 ? [0, x, c] :\n hue < 5 ? [x, 0, c] : [c, 0, x];\n return [(r + m) * 255, (g + m) * 255, (b + m) * 255] as RGBTuple;\n};\n\nconst OKLCH_STR = /^oklch\\(\\s*([\\d.]+)(%?)\\s+([\\d.]+)\\s+([\\d.]+)(?:deg)?\\s*(?:\\/\\s*([\\d.]+)(%?)\\s*)?\\)$/i;\nconst HSL_STR = /^hsla?\\(\\s*([\\d.]+)(?:deg)?\\s*[, ]\\s*([\\d.]+)%\\s*[, ]\\s*([\\d.]+)%\\s*(?:[,/]\\s*([\\d.]+)(%?)\\s*)?\\)$/i;\n\n/**\n * Parse an authored colour string into `{ rgb, a }`, or `null` if it isn't a colour this subsystem can\n * derive from. Tries `oklch()`, `hsl()/hsla()`, and CSS keywords, then falls back to {@link parseColor}\n * for hex / `rgb()/rgba()`. `oklch`/`hsl`/`rgba` alpha is preserved.\n */\nconst parseColorInput = (raw: string): { rgb: RGBTuple; a: number } | null => {\n const value = raw.trim();\n\n const ok = OKLCH_STR.exec(value);\n if (ok) {\n const L = ok[2] === \"%\" ? Number(ok[1]) : Number(ok[1]) * 100;\n const a = ok[5] === undefined ? 1 : roundAlpha(ok[6] === \"%\" ? Number(ok[5]) / 100 : Number(ok[5]));\n return { rgb: oklchToRgb({ L, C: Number(ok[3]), h: Number(ok[4]) }), a };\n }\n\n const hs = HSL_STR.exec(value);\n if (hs) {\n const a = hs[4] === undefined ? 1 : roundAlpha(hs[5] === \"%\" ? Number(hs[4]) / 100 : Number(hs[4]));\n return { rgb: hslToRgb(Number(hs[1]), Number(hs[2]) / 100, Number(hs[3]) / 100), a };\n }\n\n const keyword = CSS_COLOR_KEYWORDS[value.toLowerCase()];\n if (keyword) return { rgb: convertHexToRGB(keyword), a: 1 };\n\n // hex / rgb() / rgba() — parseColor throws on anything else, so a non-colour returns null.\n try {\n return parseColor(value);\n } catch {\n return null;\n }\n};\n\n/**\n * Coerce an authored colour value to the canonical `rgb(r, g, b)` / `rgba(…)` string. A colour may be a\n * hex string (`\"#4dabf7\"` / `\"#4af\"`), an `[r, g, b]` tuple (0–255), or any CSS colour — `oklch()`,\n * `hsl()/hsla()`, `rgb()/rgba()`, or a named keyword (`\"rebeccapurple\"`). Only a `var(--…)` (and\n * `currentColor` / `transparent`) is rejected. Applies to base + `text` + literal variants/modes.\n */\nexport const coerceColorInput = (value: string | RGBTuple): string => {\n if (typeof value === \"string\") {\n const parsed = parseColorInput(value);\n if (!parsed) {\n throw new RefractError(\n \"REFRACT_E_COLOR_INPUT\",\n `Invalid colour \"${value}\". Author a colour as a hex string (\"#4dabf7\"), an [r, g, b] tuple, ` +\n `or a CSS colour — oklch(), hsl()/hsla(), rgb()/rgba(), or a named keyword (e.g. \"rebeccapurple\"). ` +\n `A var(--…) can't be tonally derived at build time.`,\n );\n }\n return serializeColor(parsed.rgb, parsed.a);\n }\n\n if (!Array.isArray(value) || value.length !== 3 || value.some(n => typeof n !== \"number\")) {\n throw new RefractError(\n \"REFRACT_E_COLOR_TUPLE\",\n `Invalid colour tuple ${JSON.stringify(value)}. Use an [r, g, b] tuple with 0–255 channels (alpha comes from an \\`alpha\\` variant, not the base).`,\n );\n }\n\n const [r, g, b] = value;\n return serializeColor([r, g, b] as RGBTuple);\n};\n","/**\n * Colors' `normalizeProperty` hook — palette variant synthesis (§13).\n *\n * After the shared normalize pass, each palette colour synthesizes its variants:\n * - **auto variants** — numeric tonal `steps` (`100…900`) when declared, else the default named\n * set (`light` / `lighter` / `dark` / `darker`);\n * - **derivation-spec variants** — authored `{ darken | lighten | alpha, ref? }` (§13.3), each\n * resolved against its source (base by default, or another variant via `ref`).\n *\n * Every generated variant carries both its baked value (for the CSS lowering today) and `derive`\n * metadata (`{ ref, fn, arg }`) so the Model stores it as a derived `Ref` that re-resolves for free\n * when its source is overridden. All colour maths runs in rgb space (see `./utils`); a colour that\n * carries derivations must have a parseable rgb base (hex or `[r,g,b]`).\n */\n\nimport type {\n AdjustDials,\n HarmonyOption,\n NormalizedPaletteValue,\n PaletteDerivationSpec,\n PalettePropertyExtras,\n} from \"./types\";\nimport type { NormalizedModeOverride, NormalizedVariantValue } from \"../../core/normalize\";\nimport { lighten, darken, alpha, setL, rotateHue, adjust, parseColor } from \"./utils\";\nimport { coerceColorInput } from \"./colorInput\";\nimport { RefractError } from \"../../core/errors\";\n\ntype PaletteVariant = NormalizedVariantValue<string, PalettePropertyExtras>;\ntype PaletteMode = NormalizedModeOverride<string, PalettePropertyExtras>;\n\n/** Colors' derivation fns, by name — the same string-in/string-out fns the Model derivations use.\n * Each takes the opaque `arg` off the derivation Ref and coerces it (a number for the lightness/\n * hue/alpha fns; an {@link AdjustDials} object for `adjust`). */\nconst DERIVE_FNS: Record<string, (value: string, arg: unknown) => string> = {\n lighten: (v, a) => lighten(v, Number(a)),\n darken: (v, a) => darken(v, Number(a)),\n alpha: (v, a) => alpha(v, Number(a)),\n setL: (v, a) => setL(v, Number(a)),\n rotateHue: (v, a) => rotateHue(v, Number(a)),\n adjust: (v, a) => adjust(v, a as AdjustDials),\n};\n\n// Named-set steps are OKLCH ΔL points (§20.3). 10 keeps `lighter` a real tinted colour even on\n// already-light bases (Δ20 collapsed it to pure white) while still spanning a clear ±20 L ramp\n// across `lighter…darker` on mid-tone bases. Authors override per-colour via `lightenBy`/`darkenBy`.\nconst DEFAULT_LIGHTEN_BY = 10;\nconst DEFAULT_DARKEN_BY = 10;\n\nconst NAMED_LIGHTER_ORDER = [\"light\", \"lighter\"];\nconst NAMED_DARKER_ORDER = [\"dark\", \"darker\"];\n\n/**\n * dec.4 — whether a derivation `ref` sources ANOTHER property (a dotted `<subsystem>.<property>…`\n * path whose property prefix differs from the owning `colors.<propertyName>`). Such a source isn't\n * available during this property's single normalize pass, so it's deferred to the post-build\n * `bakeCrossPropertyDerivations` resolve pass. A bare name or a same-property dotted path is intra.\n */\nconst isCrossPropertyRef = (ref: string | undefined, propertyName: string): boolean => {\n if (!ref || !ref.includes(\".\")) return false;\n const [seg0, seg1] = ref.split(\".\");\n return `${seg0}.${seg1}` !== `colors.${propertyName}`;\n};\n\n/** Whether a value is a colour this subsystem can derive from (parseable as hex or `rgb(a)`). */\nconst isParseableColor = (value: string): boolean => {\n try {\n parseColor(value);\n return true;\n } catch {\n return false;\n }\n};\n\n/** Coerce+validate one `text` colour value, re-labelling the error with its token path. */\nconst coerceText = (value: unknown, path: string): string => {\n try {\n return coerceColorInput(value as string);\n } catch (error) {\n throw new RefractError(\"REFRACT_E_COLOR_INPUT\", `colors.${path}.text — ${(error as Error).message}`);\n }\n};\n\n/**\n * Coerce every `text` colour value on a normalized colour — the property itself, and any `text`\n * sibling on a literal variant or mode — to the canonical hex form (§13.1), so `text` obeys the\n * same hex/`[r,g,b]` rule as the base. Returns a structurally-shared copy (untouched fields keep\n * their references) so a colour with no `text` stays byte-identical.\n */\nconst coerceTextFields = (\n name: string,\n normalized: NormalizedPaletteValue,\n): NormalizedPaletteValue => {\n let next = normalized;\n\n if (normalized.text !== undefined) {\n next = { ...next, text: coerceText(normalized.text, name) };\n }\n\n if (normalized.variants) {\n let changed = false;\n const variants: Record<string, PaletteVariant> = {};\n for (const [key, variant] of Object.entries(normalized.variants)) {\n if (variant.text !== undefined) {\n variants[key] = { ...variant, text: coerceText(variant.text, `${name}.variants.${key}`) };\n changed = true;\n } else {\n variants[key] = variant;\n }\n }\n if (changed) next = { ...next, variants };\n }\n\n if (normalized.modes) {\n let changed = false;\n const modes = normalized.modes.map(mode => {\n if (mode.text !== undefined) {\n changed = true;\n return { ...mode, text: coerceText(mode.text, `${name}.modes.${mode.mode}`) };\n }\n return mode;\n });\n if (changed) next = { ...next, modes };\n }\n\n return next;\n};\n\n/**\n * Merge synthesized variants (auto + derivation-spec) and baked modes into a normalized palette\n * colour. Author-declared variants win over generated ones on name collision. Returns the input\n * unchanged when nothing is produced (a plain non-derivable colour stays byte-identical).\n *\n * @param name The colour's property name — used to build token paths (`colors.<name>.<v>`).\n * @param normalized The colour after the shared property normalize pass (base already coerced).\n * @param derivationSpecs Authored `{ darken|lighten|alpha, ref? }` variants, split out upstream\n * (core normalize can't interpret them — they have no `base`).\n */\nexport const finalizePaletteNormalization = (\n name: string,\n normalized0: NormalizedPaletteValue,\n derivationSpecs: Record<string, PaletteDerivationSpec> = {},\n): NormalizedPaletteValue => {\n // `text` is a colour value too — run it through the same input gate as the base (core doesn't\n // coerce extras). hex / tuple / oklch() / hsl() / rgb() / keyword all normalize to canonical rgb;\n // only a var(--…) throws with a path-labelled error.\n const normalized = coerceTextFields(name, normalized0);\n const baseParseable = isParseableColor(normalized.base);\n const hasSteps = !!(normalized.steps && normalized.steps.length);\n const hasDerivations = Object.keys(derivationSpecs).length > 0;\n const hasHarmony = normalized.harmony !== undefined;\n\n if ((hasSteps || hasDerivations || hasHarmony) && !baseParseable) {\n throw new RefractError(\n \"REFRACT_E_STEPS\",\n `colors.${name} declares derived steps/variants but its base \"${normalized.base}\" is not a hex or [r,g,b] colour.`,\n );\n }\n\n const autoVariants = baseParseable ? generateAutoVariants(normalized, name) : {};\n const harmonyVariants = baseParseable ? generateHarmonyVariants(normalized, name) : {};\n const plainVariants = normalized.variants ?? {};\n const known = { ...autoVariants, ...harmonyVariants, ...plainVariants };\n const derivedVariants = bakeDerivationVariants(name, normalized.base, known, derivationSpecs);\n\n // Precedence: generated auto + harmony variants first, then author variants (plain + derivation) win.\n const variants = { ...autoVariants, ...harmonyVariants, ...plainVariants, ...derivedVariants };\n const bakedModes = bakeDerivedModes(normalized, name, variants);\n const bakedResponsive = bakeResponsiveDerivations(normalized, name, variants);\n\n if (!Object.keys(variants).length && !bakedModes && !bakedResponsive) {\n return normalized;\n }\n\n return {\n ...normalized,\n ...(Object.keys(variants).length ? { variants } : {}),\n ...(bakedModes ? { modes: bakedModes } : {}),\n ...(bakedResponsive ? { responsive: bakedResponsive } : {}),\n };\n};\n\n/**\n * dec.5 — bake a colour's **responsive `ref` + `modifiers`** entries (swap-and-transform). A plain\n * `{ ref }` swap stays a var reference (untouched, handled by the CSS lowering). A `{ ref, modifiers }`\n * entry is folded here into a literal `base` override + `derive` metadata (source = the same-property\n * variant named by `ref`), exactly like a derivation-spec variant — so `override()` re-bakes it, and\n * the lowering writes the baked value (to `target`, default the base var) instead of a swap. Returns\n * `undefined` when nothing needed baking (so the property stays byte-identical).\n */\nconst bakeResponsiveDerivations = (\n normalized: NormalizedPaletteValue,\n propertyName: string,\n variants: Record<string, PaletteVariant>,\n): NormalizedPaletteValue[\"responsive\"] | undefined => {\n const responsive = normalized.responsive as unknown as Array<Record<string, unknown>> | undefined;\n if (!responsive || !responsive.length) return undefined;\n\n let changed = false;\n const out = responsive.map((entry, i) => {\n const ref = entry.ref as string | undefined;\n const rawModifiers = entry.modifiers;\n if (!ref || !Array.isArray(rawModifiers) || !rawModifiers.length) {\n // Coercion fix — a colour responsive override's literal value fields (`base` / `text`) go through\n // the same colour input gate as the property base/variants/modes (hex/tuple/keyword → canonical rgb).\n let coerced: Record<string, unknown> | undefined;\n for (const key of [\"base\", \"text\"]) {\n const v = entry[key];\n if (typeof v === \"string\" || Array.isArray(v)) {\n const next = coerceColorInput(v as string);\n if (next !== v) {\n coerced = coerced ?? { ...entry };\n coerced[key] = next;\n }\n }\n }\n if (coerced) changed = true;\n return coerced ?? entry;\n }\n\n const variant = variants[ref];\n if (!variant) {\n throw new RefractError(\"REFRACT_E_VARIANT_REF\", `colors.${propertyName}.responsive[${i}] references unknown variant \"${ref}\".`);\n }\n if (variant.base === undefined) {\n throw new RefractError(\"REFRACT_E_VARIANT_REF\", `colors.${propertyName}.responsive[${i}] references \"${ref}\", a cross-property derivation — not supported.`);\n }\n const modifiers = parseSpecModifiers({ modifiers: rawModifiers } as PaletteDerivationSpec, propertyName, `responsive[${i}]`);\n let value = variant.base;\n for (const mod of modifiers) value = DERIVE_FNS[mod.fn](value, mod.arg);\n\n changed = true;\n const { ref: _ref, modifiers: _mods, ...rest } = entry;\n return { ...rest, base: value, derive: { ref: `colors.${propertyName}.${ref}`, modifiers } };\n });\n\n return (changed ? out : responsive) as unknown as NormalizedPaletteValue[\"responsive\"];\n};\n\n/**\n * Bake a palette colour's **derived** appearance modes (§10.3). Core normalize records a derived\n * mode base as `{ derive: { fn, arg } }` (no source, unbaked); colors resolves it against the\n * colour's OWN base — `value = fn(base, arg)`, `ref = colors.<name>` — exactly like a tonal step,\n * so `override()` of the base re-bakes the mode for free. Literal modes pass through untouched.\n * Returns `undefined` when the colour has no modes (so the property stays byte-identical).\n */\nconst bakeDerivedModes = (\n normalized: NormalizedPaletteValue,\n propertyName: string,\n variants: Record<string, PaletteVariant>,\n): PaletteMode[] | undefined => {\n const modes = normalized.modes;\n if (!modes || !modes.length) return undefined;\n\n // dec.4 — resolve a mode derivation's SAME-PROPERTY source: the own base (default), or a variant /\n // step, addressed by bare name or by the fully-qualified `colors.<propertyName>.<name>` path.\n // A *cross-property* ref is intercepted upstream (baked post-build), so it never reaches here.\n const resolveSource = (ref: string | undefined, modeName: string): { value: string; path: string } => {\n if (!ref || ref === `colors.${propertyName}`) return { value: normalized.base, path: `colors.${propertyName}` };\n const name = ref.includes(\".\") ? ref.slice(`colors.${propertyName}.`.length) : ref;\n const variant = variants[name];\n if (!variant || variant.base === undefined) {\n throw new RefractError(\"REFRACT_E_VARIANT_REF\", `colors.${propertyName}.modes.${modeName} references unknown variant \"${ref}\".`);\n }\n return { value: variant.base, path: `colors.${propertyName}.${name}` };\n };\n\n return modes.map(mode => {\n const modeName = mode.mode;\n const derive = mode.derive;\n if (!derive) return mode; // literal mode (base and/or extras) — nothing to bake.\n\n // dec.2 — fold the modifier chain over the resolved source (dec.4). A legacy single `{ fn, arg }`\n // derive is treated as a one-element chain.\n const modifiers = derive.modifiers ?? (derive.fn ? [{ fn: derive.fn, arg: derive.arg }] : []);\n\n // dec.4 — a CROSS-property source (a dotted path outside this colour) can't be resolved during\n // this property's single normalize pass. Emit the mode UNBAKED (its `base` absent, `derive`\n // carrying the dotted ref + chain); the post-build `bakeCrossPropertyDerivations` pass fills the\n // value against the full token map. `buildModeFields` tolerates a base-less derived mode.\n if (isCrossPropertyRef(derive.ref, propertyName)) {\n const { base: _base, derive: _derive, ...rest } = mode;\n return { ...rest, derive: { ref: derive.ref, modifiers } } as PaletteMode;\n }\n\n const source = resolveSource(derive.ref, modeName);\n let value = source.value;\n for (const mod of modifiers) {\n const fn = DERIVE_FNS[mod.fn];\n if (!fn) {\n throw new RefractError(\n \"REFRACT_E_VARIANT_REF\",\n `Unknown derivation fn \"${mod.fn}\" for appearance mode \"colors.${propertyName}.modes.${modeName}\".`,\n );\n }\n value = fn(value, mod.arg);\n }\n return { ...mode, base: value, derive: { ref: source.path, modifiers } };\n });\n};\n\n/** Auto variants: numeric tonal `steps` when declared, else the default named tonal set. */\nconst generateAutoVariants = (\n palette: NormalizedPaletteValue,\n propertyName: string,\n): Record<string, PaletteVariant> => {\n if (palette.steps && palette.steps.length) {\n return generateNumericSteps(palette, propertyName);\n }\n return generateDefaultVariants(palette, propertyName);\n};\n\n/**\n * The built-in harmony schemes (§20.5) — each a list of `{ name, deg }` members, `deg` the signed\n * hue rotation off the base. Singular schemes get a real name (`complement`); symmetric pairs get\n * bare-numbered names ordered by rotation (a warm/cool label would lie — the temperature↔direction\n * mapping flips with the base hue). Tetradic reuses `complement` for its 180° member.\n */\nconst HARMONY_SCHEMES: Record<string, ReadonlyArray<{ name: string; deg: number }>> = {\n complement: [{ name: \"complement\", deg: 180 }],\n analogous: [\n { name: \"analogous1\", deg: -30 },\n { name: \"analogous2\", deg: 30 },\n ],\n \"split-complement\": [\n { name: \"split1\", deg: 150 },\n { name: \"split2\", deg: 210 },\n ],\n triadic: [\n { name: \"triadic1\", deg: 120 },\n { name: \"triadic2\", deg: 240 },\n ],\n tetradic: [\n { name: \"tetradic1\", deg: 90 },\n { name: \"complement\", deg: 180 },\n { name: \"tetradic2\", deg: 270 },\n ],\n};\n\n/**\n * Harmony variants (§20.5) — rotate the base's hue around the perceptual wheel to synthesize related\n * colours, each holding the base's lightness and chroma (only the hue turns, gamut-mapped by\n * `rotateHue`). The string form uses default member names; the object form renames them positionally\n * (`{ triadic: [\"mint\", \"coral\"] }`). Each variant is a re-derivable `{ ref, fn:\"rotateHue\", arg }`,\n * so `override()` of the base re-generates the set for free. Returns `{}` when no `harmony`.\n */\nconst generateHarmonyVariants = (\n palette: NormalizedPaletteValue,\n propertyName: string,\n): Record<string, PaletteVariant> => {\n const harmony = palette.harmony as HarmonyOption | undefined;\n if (harmony === undefined) return {};\n\n let scheme: string;\n let renames: string[] | undefined;\n if (typeof harmony === \"string\") {\n scheme = harmony;\n } else if (typeof harmony === \"object\" && harmony !== null && !Array.isArray(harmony)) {\n const keys = Object.keys(harmony);\n if (keys.length !== 1) {\n throw new RefractError(\n \"REFRACT_E_HARMONY\",\n `colors.${propertyName}.harmony object form must name exactly one scheme; got [${keys.join(\", \")}].`,\n );\n }\n scheme = keys[0];\n renames = (harmony as Record<string, string[]>)[scheme];\n } else {\n throw new RefractError(\"REFRACT_E_HARMONY\", `colors.${propertyName}.harmony must be a scheme name or a { scheme: [names] } object.`);\n }\n\n const members = HARMONY_SCHEMES[scheme];\n if (!members) {\n throw new RefractError(\n \"REFRACT_E_HARMONY\",\n `colors.${propertyName}.harmony: unknown scheme \"${scheme}\". Use one of ${Object.keys(HARMONY_SCHEMES).join(\", \")}.`,\n );\n }\n\n const result: Record<string, PaletteVariant> = {};\n members.forEach((member, i) => {\n const variantName = renames?.[i] ?? member.name;\n result[variantName] = {\n base: rotateHue(palette.base, member.deg),\n derive: { ref: `colors.${propertyName}`, fn: \"rotateHue\", arg: member.deg },\n } as PaletteVariant;\n });\n return result;\n};\n\n/** A single lighten/darken chain — each step compounds from the previous (base for the first). */\nconst buildChain = (\n result: Record<string, PaletteVariant>,\n palette: NormalizedPaletteValue,\n propertyName: string,\n existingVariants: Record<string, PaletteVariant>,\n chainSteps: string[],\n fn: (value: string, percent: number) => string,\n fnName: string,\n amount: number,\n): void => {\n const tokenPath = (variant?: string): string =>\n variant ? `colors.${propertyName}.${variant}` : `colors.${propertyName}`;\n\n let prev = palette.base;\n let prevName: string | undefined; // undefined = the base token\n for (const step of chainSteps) {\n if (existingVariants[step]?.base !== undefined) {\n prev = existingVariants[step].base as string;\n prevName = step;\n continue;\n }\n const value = fn(prev, amount);\n result[step] = {\n base: value,\n derive: { ref: tokenPath(prevName), fn: fnName, arg: amount },\n } as PaletteVariant;\n prev = value;\n prevName = step;\n }\n};\n\n/** The default named tonal variants (`light`/`lighter` + `dark`/`darker`), each compounding. */\nconst generateDefaultVariants = (\n palette: NormalizedPaletteValue,\n propertyName: string,\n): Record<string, PaletteVariant> => {\n const existingVariants = palette.variants ?? {};\n const result: Record<string, PaletteVariant> = {};\n\n const lightenAmount = palette.lightenBy ?? DEFAULT_LIGHTEN_BY;\n const darkenAmount = palette.darkenBy ?? DEFAULT_DARKEN_BY;\n\n buildChain(result, palette, propertyName, existingVariants, NAMED_LIGHTER_ORDER, lighten, \"lighten\", lightenAmount);\n buildChain(result, palette, propertyName, existingVariants, NAMED_DARKER_ORDER, darken, \"darken\", darkenAmount);\n\n return result;\n};\n\n/**\n * Map a numeric ladder label to an absolute OKLCH lightness (§20.2): `L = (1000 − label) / 10`, so\n * low labels are light and high labels dark. `0` / `1000` are reserved for pure white / black; every\n * other label clamps to `[5, 98]` so a mid-ladder rung never collapses to pure white or black.\n */\nconst labelToL = (label: number): number => {\n if (label <= 0) return 100;\n if (label >= 1000) return 0;\n return Math.min(98, Math.max(5, (1000 - label) / 10));\n};\n\n/**\n * Numeric tonal steps — an **absolute** OKLCH lightness ladder (§20.2). Each Tailwind-style label\n * maps to a fixed lightness via {@link labelToL}; the rung holds the base's hue and chroma (chroma\n * gamut-mapped) and sets that lightness, recorded as `{ ref, fn: \"setL\", arg: L }` so `override()`\n * of the base re-bakes the whole ladder for free. Because the lightness is absolute, the same label\n * reads at the same lightness across every palette. The exact authored colour stays at the\n * unnumbered `colors.<name>` token — a rung is never aliased to it, and `lightenBy`/`darkenBy` do\n * not apply. An author-declared variant of the same name wins over the generated rung. Throws on a\n * non-numeric or out-of-range (`0–1000`) label.\n */\nconst generateNumericSteps = (\n palette: NormalizedPaletteValue,\n propertyName: string,\n): Record<string, PaletteVariant> => {\n const steps = palette.steps ?? [];\n const bad = steps.find(s => typeof s !== \"number\" || isNaN(s) || s < 0 || s > 1000);\n if (bad !== undefined) {\n throw new RefractError(\n \"REFRACT_E_STEPS\",\n `colors.${propertyName}.steps must be numbers in 0–1000 (e.g. [50, …, 950]); got ${JSON.stringify(bad)}.`,\n );\n }\n\n const existingVariants = palette.variants ?? {};\n const result: Record<string, PaletteVariant> = {};\n\n for (const step of steps) {\n const label = step.toString();\n if (existingVariants[label]) continue; // an author-declared variant wins over the generated rung.\n const L = labelToL(step);\n result[label] = {\n base: setL(palette.base, L),\n derive: { ref: `colors.${propertyName}`, fn: \"setL\", arg: L },\n } as PaletteVariant;\n }\n\n return result;\n};\n\n/**\n * Validate + normalize an `adjust` dial set (§20.4). All dials optional and numeric: `l` absolute\n * lightness `0–100`; `c` a non-negative chroma multiplier; `h` a signed hue rotation. Returns a\n * clean `{ l?, c?, h? }` (dropping `undefined`s) so the stored `arg` is minimal.\n */\nconst parseAdjust = (raw: unknown, propertyName: string, variantName: string): AdjustDials => {\n const at = `colors.${propertyName}.variants.${variantName}.adjust`;\n if (typeof raw !== \"object\" || raw === null || Array.isArray(raw)) {\n throw new RefractError(\"REFRACT_E_ADJUST\", `${at} must be an object with numeric l / c / h dials.`);\n }\n const { l, c, h } = raw as Record<string, unknown>;\n const dials: AdjustDials = {};\n if (l !== undefined) {\n if (typeof l !== \"number\" || isNaN(l) || l < 0 || l > 100) {\n throw new RefractError(\"REFRACT_E_ADJUST\", `${at}.l must be an absolute OKLCH lightness in 0–100; got ${JSON.stringify(l)}.`);\n }\n dials.l = l;\n }\n if (c !== undefined) {\n if (typeof c !== \"number\" || isNaN(c) || c < 0) {\n throw new RefractError(\"REFRACT_E_ADJUST\", `${at}.c must be a non-negative chroma multiplier (1 keeps, 0 greys); got ${JSON.stringify(c)}.`);\n }\n dials.c = c;\n }\n if (h !== undefined) {\n if (typeof h !== \"number\" || isNaN(h)) {\n throw new RefractError(\"REFRACT_E_ADJUST\", `${at}.h must be a numeric hue rotation in degrees; got ${JSON.stringify(h)}.`);\n }\n dials.h = h;\n }\n return dials;\n};\n\n/**\n * dec.2 — parse a spec's `modifiers` chain into canonical `{ fn, arg }[]`. Each dial is a single-key\n * object (`{ darken: 10 }` → `{ fn: \"darken\", arg: 10 }`); `adjust` validates its dial object, the\n * scalar fns coerce to a number. An unknown fn is rejected against the colour-math registry.\n */\nconst parseSpecModifiers = (\n spec: PaletteDerivationSpec,\n propertyName: string,\n variantName: string,\n): Array<{ fn: string; arg: unknown }> => {\n const at = `colors.${propertyName}.variants.${variantName}`;\n const modifiers = spec.modifiers;\n if (!Array.isArray(modifiers) || modifiers.length === 0) {\n throw new RefractError(\"REFRACT_E_VARIANT\", `${at} needs a non-empty \"modifiers\" array (e.g. [{ darken: 10 }]).`);\n }\n return modifiers.map((m, i) => {\n if (typeof m !== \"object\" || m === null || Array.isArray(m)) {\n throw new RefractError(\"REFRACT_E_VARIANT\", `${at}.modifiers[${i}] must be a single-key object like { darken: 10 }.`);\n }\n const keys = Object.keys(m as Record<string, unknown>);\n if (keys.length !== 1) {\n throw new RefractError(\"REFRACT_E_VARIANT\", `${at}.modifiers[${i}] must have exactly one fn key; got [${keys.join(\", \")}].`);\n }\n const fn = keys[0];\n if (!DERIVE_FNS[fn]) {\n throw new RefractError(\"REFRACT_E_VARIANT\", `${at}.modifiers[${i}] unknown fn \"${fn}\"; use ${Object.keys(DERIVE_FNS).join(\" / \")}.`);\n }\n const raw = (m as Record<string, unknown>)[fn];\n const arg = fn === \"adjust\" ? parseAdjust(raw, propertyName, variantName) : Number(raw);\n return { fn, arg };\n });\n};\n\n/**\n * Bake authored derivation-spec variants (§13.3). Each resolves its source (`ref` → another\n * variant/step, or the base by default), applies the colour fn, and records `{ ref, fn, arg }`.\n * Specs may reference each other (a chain); resolution is lazy with cycle detection.\n */\nconst bakeDerivationVariants = (\n propertyName: string,\n base: string,\n known: Record<string, PaletteVariant>,\n specs: Record<string, PaletteDerivationSpec>,\n): Record<string, PaletteVariant> => {\n const result: Record<string, PaletteVariant> = {};\n const baking = new Set<string>();\n\n // A same-property source must have a baked base value; a cross-property-deferred variant (no base)\n // can't be a chain source in this single pass — surface that as a clear error rather than `undefined`.\n const baseOf = (variant: PaletteVariant, ref: string): string => {\n if (variant.base === undefined) {\n throw new RefractError(\n \"REFRACT_E_VARIANT_REF\",\n `colors.${propertyName} variant chains off \"${ref}\", which is a cross-property derivation — not supported.`,\n );\n }\n return variant.base;\n };\n const sourceOf = (ref: string | undefined): { value: string; path: string } => {\n if (!ref) return { value: base, path: `colors.${propertyName}` };\n if (result[ref]) return { value: baseOf(result[ref], ref), path: `colors.${propertyName}.${ref}` };\n if (known[ref]) return { value: baseOf(known[ref], ref), path: `colors.${propertyName}.${ref}` };\n if (specs[ref]) {\n bakeOne(ref, specs[ref]);\n return { value: baseOf(result[ref] as PaletteVariant, ref), path: `colors.${propertyName}.${ref}` };\n }\n throw new RefractError(\"REFRACT_E_VARIANT_REF\", `colors.${propertyName} variant references unknown source \"${ref}\".`);\n };\n\n function bakeOne(variantName: string, spec: PaletteDerivationSpec): void {\n if (result[variantName]) return;\n if (baking.has(variantName)) {\n throw new RefractError(\"REFRACT_E_CYCLE\", `Cyclic colour variant derivation at colors.${propertyName}.${variantName}.`);\n }\n baking.add(variantName);\n const modifiers = parseSpecModifiers(spec, propertyName, variantName);\n // dec.4 — a CROSS-property source is deferred: emit UNBAKED (no `base`), carrying the dotted ref\n // + chain. The post-build `bakeCrossPropertyDerivations` pass fills the value; `buildPropertyModel`\n // tolerates a base-less variant that carries a `derive.ref`.\n if (isCrossPropertyRef(spec.ref, propertyName)) {\n result[variantName] = { derive: { ref: spec.ref as string, modifiers } } as PaletteVariant;\n baking.delete(variantName);\n return;\n }\n const source = sourceOf(spec.ref);\n // dec.2 — fold the chain over the resolved source, in author order.\n let value = source.value;\n for (const m of modifiers) value = DERIVE_FNS[m.fn](value, m.arg);\n result[variantName] = { base: value, derive: { ref: source.path, modifiers } } as PaletteVariant;\n baking.delete(variantName);\n }\n\n for (const [variantName, spec] of Object.entries(specs)) bakeOne(variantName, spec);\n return result;\n};\n","/**\n * The set of known CSS property names, in kebab-case — the allow-list behind refract's fail-loud\n * recipe check. A recipe declaration whose key isn't a reserved recipe key (`variant`/`target`/…) and\n * isn't a known CSS property is almost always a typo (`ref:` for a variant swap, `colr:` for `color`)\n * that would otherwise pass through as literal CSS and ship silently. Rejecting it at build time turns\n * that class of mistake into an error — and the same predicate lets the docs pipeline reject an emitted\n * declaration whose property is not real CSS.\n *\n * Compact on purpose (a space-delimited string, split once) because this list rides in the runtime\n * `createTheme` path and counts toward the core size budget. Coverage is generous — standard properties\n * plus common logical/flex/grid/scroll/font families — so legitimate authoring never trips it. Custom\n * properties (`--*`) and vendor-prefixed names (`-webkit-…`) are accepted structurally by\n * {@link isKnownCssProperty}, so they need not appear here.\n */\nconst CSS_PROPERTY_NAMES =\n // layout / box model\n \"display position top right bottom left inset inset-block inset-block-start inset-block-end \" +\n \"inset-inline inset-inline-start inset-inline-end float clear z-index visibility overflow overflow-x \" +\n \"overflow-y overflow-block overflow-inline overflow-clip-margin overflow-anchor box-sizing \" +\n \"width height min-width min-height max-width max-height block-size inline-size min-block-size \" +\n \"min-inline-size max-block-size max-inline-size aspect-ratio \" +\n \"margin margin-top margin-right margin-bottom margin-left margin-block margin-block-start \" +\n \"margin-block-end margin-inline margin-inline-start margin-inline-end margin-trim \" +\n \"padding padding-top padding-right padding-bottom padding-left padding-block padding-block-start \" +\n \"padding-block-end padding-inline padding-inline-start padding-inline-end \" +\n // flexbox / grid\n \"flex flex-grow flex-shrink flex-basis flex-direction flex-flow flex-wrap order \" +\n \"justify-content justify-items justify-self align-content align-items align-self place-content \" +\n \"place-items place-self gap row-gap column-gap grid grid-area grid-template grid-template-areas \" +\n \"grid-template-columns grid-template-rows grid-auto-columns grid-auto-rows grid-auto-flow \" +\n \"grid-column grid-column-start grid-column-end grid-row grid-row-start grid-row-end \" +\n \"columns column-count column-width column-gap column-rule column-rule-color column-rule-style \" +\n \"column-rule-width column-span column-fill \" +\n // color / background\n \"color opacity accent-color caret-color color-scheme forced-color-adjust print-color-adjust \" +\n \"background background-color background-image background-position background-position-x \" +\n \"background-position-y background-size background-repeat background-origin background-clip \" +\n \"background-attachment background-blend-mode mix-blend-mode isolation \" +\n // border / outline\n \"border border-width border-style border-color border-top border-top-width border-top-style \" +\n \"border-top-color border-right border-right-width border-right-style border-right-color \" +\n \"border-bottom border-bottom-width border-bottom-style border-bottom-color border-left \" +\n \"border-left-width border-left-style border-left-color border-block border-block-width \" +\n \"border-block-style border-block-color border-block-start border-block-start-width \" +\n \"border-block-start-style border-block-start-color border-block-end border-block-end-width \" +\n \"border-block-end-style border-block-end-color border-inline border-inline-width \" +\n \"border-inline-style border-inline-color border-inline-start border-inline-start-width \" +\n \"border-inline-start-style border-inline-start-color border-inline-end border-inline-end-width \" +\n \"border-inline-end-style border-inline-end-color border-radius border-top-left-radius \" +\n \"border-top-right-radius border-bottom-right-radius border-bottom-left-radius \" +\n \"border-start-start-radius border-start-end-radius border-end-start-radius border-end-end-radius \" +\n \"border-image border-image-source border-image-slice border-image-width border-image-outset \" +\n \"border-image-repeat border-collapse border-spacing \" +\n \"outline outline-width outline-style outline-color outline-offset \" +\n // effects\n \"box-shadow filter backdrop-filter clip-path mask mask-image mask-mode mask-repeat mask-position \" +\n \"mask-clip mask-origin mask-size mask-composite mask-type opacity transform transform-origin \" +\n \"transform-box transform-style perspective perspective-origin backface-visibility rotate scale \" +\n \"translate \" +\n // transitions / animation\n \"transition transition-property transition-duration transition-timing-function transition-delay \" +\n \"transition-behavior animation animation-name animation-duration animation-timing-function \" +\n \"animation-delay animation-iteration-count animation-direction animation-fill-mode \" +\n \"animation-play-state animation-composition animation-timeline will-change \" +\n // typography\n \"font font-family font-size font-size-adjust font-weight font-style font-variant \" +\n \"font-variant-caps font-variant-numeric font-variant-ligatures font-variant-east-asian \" +\n \"font-variant-alternates font-variant-position font-feature-settings font-variation-settings \" +\n \"font-kerning font-stretch font-optical-sizing font-synthesis font-display line-height \" +\n \"letter-spacing word-spacing text-align text-align-last text-decoration text-decoration-line \" +\n \"text-decoration-color text-decoration-style text-decoration-thickness text-decoration-skip-ink \" +\n \"text-underline-offset text-underline-position text-transform text-indent text-overflow \" +\n \"text-shadow text-rendering text-wrap text-wrap-mode text-wrap-style text-emphasis \" +\n \"text-emphasis-color text-emphasis-style text-emphasis-position text-orientation text-combine-upright \" +\n \"text-justify white-space white-space-collapse word-break word-wrap overflow-wrap hyphens \" +\n \"hyphenate-character line-break tab-size vertical-align writing-mode direction unicode-bidi \" +\n \"quotes content list-style list-style-type list-style-position list-style-image counter-reset \" +\n \"counter-increment counter-set \" +\n // interactivity / ui\n \"cursor pointer-events user-select touch-action resize appearance caret scroll-behavior \" +\n \"scroll-margin scroll-margin-top scroll-margin-right scroll-margin-bottom scroll-margin-left \" +\n \"scroll-padding scroll-padding-top scroll-padding-right scroll-padding-bottom scroll-padding-left \" +\n \"scroll-snap-type scroll-snap-align scroll-snap-stop overscroll-behavior overscroll-behavior-x \" +\n \"overscroll-behavior-y scrollbar-width scrollbar-color scrollbar-gutter \" +\n // tables / svg / misc\n \"table-layout caption-side empty-cells vertical-align object-fit object-position image-rendering \" +\n \"fill fill-opacity fill-rule stroke stroke-width stroke-opacity stroke-linecap stroke-linejoin \" +\n \"stroke-dasharray stroke-dashoffset stroke-miterlimit paint-order shape-rendering stop-color \" +\n \"flood-color lighting-color \" +\n \"container container-type container-name contain content-visibility \" +\n \"break-before break-after break-inside page-break-before page-break-after page-break-inside orphans widows \" +\n \"all cx cy r rx ry d\";\n\n/** Known CSS property names (kebab-case). Membership test drives {@link isKnownCssProperty}. */\nexport const KNOWN_CSS_PROPERTIES: ReadonlySet<string> = new Set(CSS_PROPERTY_NAMES.split(\" \"));\n\nconst VENDOR_PREFIX = /^-(webkit|moz|ms|o)-/;\n\n/**\n * Is `name` a real CSS property? Accepts camelCase or kebab-case (`borderColor` / `border-color`),\n * custom properties (`--brand`), and vendor-prefixed names (`-webkit-mask`). Everything else — a\n * reserved recipe key that leaked, or a typo — is rejected so the caller can fail loud.\n */\nexport const isKnownCssProperty = (name: string): boolean => {\n if (name.startsWith(\"--\")) return true;\n const kebab = name\n .replace(/_/g, \"-\")\n .replace(/([a-z0-9])([A-Z])/g, \"$1-$2\")\n .toLowerCase();\n if (VENDOR_PREFIX.test(kebab)) return true;\n return KNOWN_CSS_PROPERTIES.has(kebab);\n};\n","/**\n * Colors' `interpretRecipe` hook — resolves palette recipe declarations to Refs.\n *\n * A palette recipe prop value either **names a palette reference** (`\"primary\"`,\n * `\"primary.text\"`, `\"neutral.light\"`) or is a literal. This interpreter emits a\n * format-neutral {@link Ref} for each declaration — a **canonical token path**\n * (`{ ref: \"colors.primary\", value: \"#4dabf7\" }`) for a reference, or `{ value }` for a\n * literal. It emits refs **directly** (no `var(--…)` strings); the CSS adapter maps the\n * token path to a `var(--…)` at render time. So `theme.model` carries no CSS syntax.\n */\nimport type { InterpretedRecipeVariant, InterpretedRecipeOverride, Ref } from \"../../core/model\";\nimport type { NormalizedRecipeVariant } from \"../../core/normalize\";\nimport type { RecipeInterpretContext } from \"../../core/subsystem\";\nimport { RefractError } from \"../../core/errors\";\nimport { isKnownCssProperty } from \"../../core/cssProperties\";\nimport type { NormalizedPaletteValue, PaletteRecipeProps, PaletteRecipeValue } from \"./types\";\n\nconst RESERVED_RECIPE_KEYS: ReadonlySet<string> = new Set([\n \"breakpoint\",\n \"query\",\n \"state\",\n \"variant\",\n \"target\",\n \"orientation\",\n]);\n\n/**\n * Interpret one palette recipe variant into base + responsive/state override declarations,\n * each a token-path {@link Ref}. Sibling `variant:` swaps inherit the sibling's base\n * declarations (via `ctx.resolveRecipeVariant`); a `target` may only scope to the variant\n * itself.\n */\nexport const interpretPaletteRecipeVariant = (\n variantName: string,\n variant: NormalizedRecipeVariant<PaletteRecipeProps, string>,\n ctx: RecipeInterpretContext,\n): InterpretedRecipeVariant<string> => {\n const path = `${ctx.groupPath}.${variantName}`;\n\n const base = interpretProps(variant.base, ctx, path);\n\n const responsive: InterpretedRecipeOverride<string>[] = variant.responsive.map(entry => {\n const { breakpoint, query, state, variant: swap, target, orientation, container, size, ...rawDecls } =\n entry as PaletteRecipeProps & {\n breakpoint?: string;\n query?: \"min\" | \"max\" | \"exact\";\n state?: string;\n variant?: string;\n target?: string;\n orientation?: \"landscape\" | \"portrait\";\n container?: string;\n size?: string;\n };\n\n const inherited = swap ? { ...ctx.resolveRecipeVariant(swap).base } : {};\n const overrides = interpretProps(rawDecls as PaletteRecipeProps, ctx, `${path}.responsive`);\n\n const override: InterpretedRecipeOverride<string> = {\n declarations: { ...inherited, ...overrides },\n };\n if (breakpoint) {\n override.breakpoint = breakpoint;\n override.query = query ?? \"exact\";\n }\n if (container) {\n override.container = container;\n if (size) override.size = size;\n override.query = query ?? \"min\";\n }\n if (state) override.state = state;\n if (orientation) override.orientation = orientation;\n if (target) override.target = target; // dec.8 — scope this override onto the `<item>-<target>` sibling\n return override;\n });\n\n return { base, responsive };\n};\n\n/** Interpret a flat declaration block → `formattedProperty → Ref`, skipping empty resolves. */\nconst interpretProps = (\n props: PaletteRecipeProps | undefined,\n ctx: RecipeInterpretContext,\n path: string,\n): Record<string, Ref> => {\n const declarations: Record<string, Ref> = {};\n if (!props) return declarations;\n\n for (const [property, value] of Object.entries(props)) {\n if (value === undefined || RESERVED_RECIPE_KEYS.has(property)) continue;\n // Fail loud on a key that is neither a reserved recipe key nor a real CSS property — otherwise a\n // typo (`ref:` meant as a `variant:` swap, `colr:` for `color`) would pass through as literal CSS\n // and ship silently. See {@link isKnownCssProperty}.\n if (!isKnownCssProperty(property)) {\n throw new RefractError(\n \"REFRACT_E_RECIPE_PROPERTY\",\n `Unknown recipe property \"${property}\" in ${path} — expected a CSS property or a reserved key ` +\n `(variant, target, state, breakpoint, query, orientation, container, size).`,\n );\n }\n const ref = resolvePaletteReference(value, ctx, path, property);\n if (ref === undefined) continue;\n declarations[formatPropertyName(property)] = ref;\n }\n\n return declarations;\n};\n\n/**\n * Resolve one palette recipe value to a {@link Ref}. Numbers + non-palette strings pass\n * through as literals; a `<name>[.<variant|text>]` reference resolves to a canonical token\n * path with its baked value alongside (for inline delivery). Throws on an unknown variant.\n */\nconst resolvePaletteReference = (\n value: PaletteRecipeValue,\n ctx: RecipeInterpretContext,\n path: string,\n property: string,\n): Ref | undefined => {\n if (typeof value === \"number\") return { value };\n\n const trimmed = value.trim();\n if (!trimmed) return undefined;\n\n const segments = trimmed.split(\".\");\n const name = segments[0];\n const palette = ctx.properties[name] as NormalizedPaletteValue | undefined;\n\n // Not a known palette colour → a literal declaration (passes through unchanged).\n if (!palette) return { value: trimmed };\n\n const subKey = segments.length > 1 ? segments.slice(1).join(\".\") : undefined;\n\n if (!subKey) return { ref: `colors.${name}` };\n\n if (subKey === \"text\") {\n return { ref: `colors.${name}.text` };\n }\n\n if (!palette.variants?.[subKey]) {\n throw new RefractError(\n \"REFRACT_E_VARIANT_REF\",\n `Unknown palette variant reference \"${name}.${subKey}\" in ${path}.${property}.`,\n );\n }\n\n return { ref: `colors.${name}.${subKey}` };\n};\n\n/** Format an authored property name to its CSS declaration name (`borderColor` → `border-color`). */\nconst formatPropertyName = (property: string): string => {\n if (property.startsWith(\"--\")) return property;\n return property\n .replace(/_/g, \"-\")\n .replace(/([a-z0-9])([A-Z])/g, \"$1-$2\")\n .toLowerCase();\n};\n","/**\n * Contrast audit (opt-in) — scores a built theme's colour pairings for **WCAG 2** contrast ratio\n * (the compliance standard) plus an **advisory APCA** Lc reading. It reports; it never mutates the\n * theme and never \"fixes\" a colour. `audit()` returns structured results by default; a caller (or the\n * `refract audit --strict` CLI) can throw on failures.\n *\n * Which pairings: every palette's `base` ↔ `text`, and every recipe's foreground (`color`) ↔\n * background (`background-color` / `background`) across all subsystems' rule-sets (base + state\n * overrides). A side that isn't a derivable colour (`transparent`, a `var()`, a keyword literal) is\n * reported as `skipped`, not a failure.\n *\n * Colour math is inlined here on purpose: `utils.ts` is vendored to consumers (`build/vendor.ts`) and\n * kept dependency-free / minimal, so we don't widen its export surface for a non-vendored sibling. We\n * reuse only the already-exported {@link parseColor}.\n */\nimport type { Theme, Ref } from \"../../core\";\nimport { RefractError } from \"../../core/errors\";\nimport { parseColor, type RGBTuple } from \"./utils\";\n\n// ── WCAG 2.x ──────────────────────────────────────────────────────────────\n// Relative luminance per WCAG 2: linearize each sRGB channel, weight by the luma coefficients.\nconst srgbToLinear = (c: number): number => (c <= 0.04045 ? c / 12.92 : Math.pow((c + 0.055) / 1.055, 2.4));\nconst relLuminance = ([r, g, b]: RGBTuple): number =>\n 0.2126 * srgbToLinear(r / 255) + 0.7152 * srgbToLinear(g / 255) + 0.0722 * srgbToLinear(b / 255);\n\n/** WCAG 2 contrast ratio (1–21) between two sRGB colours; order-independent. */\nconst wcagRatio = (a: RGBTuple, b: RGBTuple): number => {\n const la = relLuminance(a);\n const lb = relLuminance(b);\n const hi = Math.max(la, lb);\n const lo = Math.min(la, lb);\n return (hi + 0.05) / (lo + 0.05);\n};\n\nexport type WcagLevel = \"AAA\" | \"AA\" | \"AA-large\" | \"fail\";\nconst LEVEL_RANK: Record<WcagLevel, number> = { fail: 0, \"AA-large\": 1, AA: 2, AAA: 3 };\n\n/** Map a ratio to a level. For normal text 3–4.5 is \"AA-large\" (passes only at large sizes). */\nconst wcagLevel = (ratio: number, large: boolean): WcagLevel => {\n if (large) return ratio >= 4.5 ? \"AAA\" : ratio >= 3 ? \"AA\" : \"fail\";\n return ratio >= 7 ? \"AAA\" : ratio >= 4.5 ? \"AA\" : ratio >= 3 ? \"AA-large\" : \"fail\";\n};\n\n// ── APCA (advisory) ───────────────────────────────────────────────────────\n// APCA 0.1.9 / formula 0.98G-4g (SAPC). Advisory only — NOT a WCAG substitute — and the draft may\n// still shift, so the constants are pinned here. Returns a signed Lc (polarity-aware).\nconst APCA = {\n mainTRC: 2.4,\n sRco: 0.2126729, sGco: 0.7151522, sBco: 0.072175,\n normBG: 0.56, normTXT: 0.57, revTXT: 0.62, revBG: 0.65,\n blkThrs: 0.022, blkClmp: 1.414,\n scaleBoW: 1.14, loBoWoffset: 0.027,\n scaleWoB: 1.14, loWoBoffset: 0.027,\n deltaYmin: 0.0005, loClip: 0.1,\n} as const;\n\nconst apcaY = ([r, g, b]: RGBTuple): number =>\n APCA.sRco * Math.pow(r / 255, APCA.mainTRC) +\n APCA.sGco * Math.pow(g / 255, APCA.mainTRC) +\n APCA.sBco * Math.pow(b / 255, APCA.mainTRC);\n\n/** Signed APCA lightness contrast (Lc) of `text` over `bg`. Positive = dark-on-light, negative = light-on-dark. */\nconst apcaLc = (text: RGBTuple, bg: RGBTuple): number => {\n const clamp = (y: number): number => (y > APCA.blkThrs ? y : y + Math.pow(APCA.blkThrs - y, APCA.blkClmp));\n const yTxt = clamp(apcaY(text));\n const yBg = clamp(apcaY(bg));\n if (Math.abs(yBg - yTxt) < APCA.deltaYmin) return 0;\n let out: number;\n if (yBg > yTxt) {\n const sapc = (Math.pow(yBg, APCA.normBG) - Math.pow(yTxt, APCA.normTXT)) * APCA.scaleBoW;\n out = sapc < APCA.loClip ? 0 : sapc - APCA.loBoWoffset;\n } else {\n const sapc = (Math.pow(yBg, APCA.revBG) - Math.pow(yTxt, APCA.revTXT)) * APCA.scaleWoB;\n out = sapc > -APCA.loClip ? 0 : sapc + APCA.loWoBoffset;\n }\n return out * 100;\n};\n\n// ── audit ─────────────────────────────────────────────────────────────────\n\nexport type PairingKind = \"palette\" | \"recipe\";\n\nexport interface PairingScore {\n kind: PairingKind;\n /** Human label, e.g. `colors.brand` or `components.buttons.primary (:hover)`. */\n label: string;\n /** Resolved foreground colour string, or `undefined` when it isn't a derivable colour. */\n fg?: string;\n /** Resolved background colour string, or `undefined` when it isn't a derivable colour. */\n bg?: string;\n /** WCAG 2 contrast ratio (1–21, 2 dp). Absent when skipped. */\n wcagRatio?: number;\n /** WCAG level at the configured text size. Absent when skipped. */\n wcagLevel?: WcagLevel;\n /** Advisory APCA Lc (signed, 1 dp). Absent when skipped. */\n apcaLc?: number;\n /** Whether this pairing met the pass bar (`minWcag`). Absent when skipped. */\n pass?: boolean;\n /** Set when a side isn't a derivable colour — then the score fields are absent. */\n skipped?: string;\n}\n\nexport interface AuditOptions {\n /** Throw an aggregated error when any pairing fails, instead of only reporting. Default `false`. */\n strict?: boolean;\n /** Treat the foreground as large text (relaxed WCAG thresholds). Default `false`. */\n largeText?: boolean;\n /** The pass bar. Default `\"AA\"`. `\"AA-large\"` accepts the 3:1 tier. */\n minWcag?: WcagLevel;\n /** Audit component/recipe fg↔bg pairs. Default `true`. */\n includeRecipes?: boolean;\n /** Audit palette base↔text pairs. Default `true`. */\n includePalettes?: boolean;\n}\n\nexport interface AuditResult {\n pairings: PairingScore[];\n summary: {\n total: number;\n passed: number;\n failed: number;\n skipped: number;\n /** The lowest-ratio scored pairing (the worst offender), if any were scored. */\n worst?: PairingScore;\n };\n /** `true` when no scored pairing failed the pass bar. */\n ok: boolean;\n}\n\nconst round = (n: number, dp: number): number => {\n const f = 10 ** dp;\n return Math.round(n * f) / f;\n};\n\n/** Resolve a rule-set declaration `Ref` to a colour string, or `undefined` if it isn't one. */\nconst refToColor = (theme: Theme, ref: Ref): string | undefined => {\n if (ref.ref !== undefined) {\n try {\n return String(theme.resolveToken(ref.ref));\n } catch {\n return undefined;\n }\n }\n if (typeof ref.value === \"string\") return ref.value;\n return undefined;\n};\n\nconst FG_KEY = \"color\";\nconst BG_KEYS = [\"background-color\", \"background\"] as const;\nconst pickBg = (decls: Record<string, Ref> | undefined): Ref | undefined => {\n if (!decls) return undefined;\n for (const k of BG_KEYS) if (decls[k]) return decls[k];\n return undefined;\n};\n\n/** Score one fg/bg pairing (colours already resolved to strings), or a skipped record. */\nconst scorePair = (\n kind: PairingKind,\n label: string,\n fg: string | undefined,\n bg: string | undefined,\n options: Required<Pick<AuditOptions, \"largeText\" | \"minWcag\">>,\n): PairingScore => {\n let fgRgb: RGBTuple | undefined;\n let bgRgb: RGBTuple | undefined;\n try {\n if (fg !== undefined) fgRgb = parseColor(fg).rgb;\n } catch { /* not a derivable colour */ }\n try {\n if (bg !== undefined) bgRgb = parseColor(bg).rgb;\n } catch { /* not a derivable colour */ }\n\n if (!fgRgb || !bgRgb) {\n return { kind, label, fg, bg, skipped: !fgRgb && !bgRgb ? \"no derivable fg/bg\" : !fgRgb ? \"fg not a colour\" : \"bg not a colour\" };\n }\n\n const ratio = wcagRatio(fgRgb, bgRgb);\n const level = wcagLevel(ratio, options.largeText);\n const pass = LEVEL_RANK[level] >= LEVEL_RANK[options.minWcag];\n return {\n kind, label, fg, bg,\n wcagRatio: round(ratio, 2),\n wcagLevel: level,\n apcaLc: round(apcaLc(fgRgb, bgRgb), 1),\n pass,\n };\n};\n\n/**\n * Audit a built theme's colour pairings. Pure — reads `theme.tokens` / `theme.resolveToken` /\n * `theme.model` only. In `strict` mode, throws one aggregated error listing every failing pairing.\n */\nexport const audit = (theme: Theme, options: AuditOptions = {}): AuditResult => {\n const opts = {\n largeText: options.largeText ?? false,\n minWcag: options.minWcag ?? (\"AA\" as WcagLevel),\n };\n const includeRecipes = options.includeRecipes ?? true;\n const includePalettes = options.includePalettes ?? true;\n const pairings: PairingScore[] = [];\n\n // Palettes: base ↔ text. A palette advertises a pairing by having a `colors.<name>.text` token.\n if (includePalettes) {\n for (const path of Object.keys(theme.tokens)) {\n const m = /^colors\\.([^.]+)\\.text$/.exec(path);\n if (!m) continue;\n const base = `colors.${m[1]}`;\n let fg: string | undefined, bg: string | undefined;\n try { fg = String(theme.resolveToken(path)); } catch { /* skip */ }\n try { bg = String(theme.resolveToken(base)); } catch { /* skip */ }\n pairings.push(scorePair(\"palette\", base, fg, bg, opts));\n }\n }\n\n // Recipes: every subsystem's rule-sets — the base declarations + each state/breakpoint override.\n if (includeRecipes) {\n for (const [subsystem, subModel] of Object.entries(theme.model.subsystems)) {\n if (!subModel.ruleSets) continue;\n for (const [group, ruleSetGroup] of Object.entries(subModel.ruleSets)) {\n for (const [variant, ruleSet] of Object.entries(ruleSetGroup)) {\n const baseFg = ruleSet.declarations[FG_KEY];\n const baseBg = pickBg(ruleSet.declarations);\n const label = `${subsystem}.${group}.${variant}`;\n if (baseFg && baseBg) {\n pairings.push(scorePair(\"recipe\", label, refToColor(theme, baseFg), refToColor(theme, baseBg), opts));\n }\n // Overrides (e.g. :hover) can swap bg or fg — score the effective pairing at that condition.\n for (const override of ruleSet.overrides ?? []) {\n const oFg = override.declarations?.[FG_KEY] ?? baseFg;\n const oBg = pickBg(override.declarations) ?? baseBg;\n if (!override.declarations || (!override.declarations[FG_KEY] && !pickBg(override.declarations))) continue;\n if (!oFg || !oBg) continue;\n const cond = override.state ?? override.breakpoint ?? override.query ?? \"override\";\n pairings.push(scorePair(\"recipe\", `${label} (${cond})`, refToColor(theme, oFg), refToColor(theme, oBg), opts));\n }\n }\n }\n }\n }\n\n const scored = pairings.filter(p => !p.skipped);\n const failed = scored.filter(p => p.pass === false);\n const worst = scored.reduce<PairingScore | undefined>(\n (w, p) => (w === undefined || (p.wcagRatio ?? Infinity) < (w.wcagRatio ?? Infinity) ? p : w),\n undefined,\n );\n const result: AuditResult = {\n pairings,\n summary: {\n total: scored.length,\n passed: scored.length - failed.length,\n failed: failed.length,\n skipped: pairings.length - scored.length,\n worst,\n },\n ok: failed.length === 0,\n };\n\n if (options.strict && failed.length > 0) {\n const list = failed.map(p => `${p.label} (${p.wcagRatio}:1, ${p.wcagLevel})`).join(\", \");\n throw new RefractError(\n \"REFRACT_E_AUDIT\",\n `refract audit: ${failed.length} pairing(s) fail WCAG ${opts.minWcag} — ${list}. ` +\n `Adjust the colour(s), lower --min-wcag, or drop --strict to report without failing.`,\n failed.map(p => `${p.label} (${p.wcagRatio}:1, ${p.wcagLevel})`),\n );\n }\n\n return result;\n};\n","/**\n * The colors subsystem (Step 0d — properties only).\n *\n * Iterates `raw.colors` (skipping the reserved `recipes` key), running the shared\n * property normalize + colors' palette-step synthesis per colour. Recipes / CSS\n * lowering land in Step 1; this file grows a hook, never the spine.\n */\n\nimport type { Subsystem, NormalizedProperties } from \"../../core/subsystem\";\nimport type {\n NormalizedPropertyValue,\n NormalizedRecipeVariant,\n PropertyValue,\n} from \"../../core/normalize\";\nimport {\n normalizePropertyValue,\n validateNormalizedResponsiveRefs,\n} from \"../../core/normalize\";\nimport type {\n NormalizedPaletteValue,\n PaletteDerivationSpec,\n PalettePropertyExtras,\n PaletteRecipeProps,\n} from \"./types\";\nimport { finalizePaletteNormalization } from \"./normalize\";\nimport { interpretPaletteRecipeVariant } from \"./recipes\";\nimport type { AdjustDials } from \"./utils\";\nimport { lighten, darken, alpha, setL, rotateHue, adjust } from \"./utils\";\nimport { coerceColorInput } from \"./colorInput\";\n\n/** Sub-keys of `raw.colors` that are not palette properties. */\nconst RESERVED_KEYS: ReadonlySet<string> = new Set([\"recipes\"]);\n\n/** dec.2 — a `{ ref?, modifiers }` variant spec — must be split out before core normalize (no `base`). */\nconst isDerivationSpec = (value: unknown): value is PaletteDerivationSpec =>\n typeof value === \"object\" &&\n value !== null &&\n !Array.isArray(value) &&\n !(\"base\" in value) &&\n Array.isArray((value as { modifiers?: unknown }).modifiers);\n\n/**\n * Peel derivation-spec variants (`{ darken|lighten|alpha, ref? }`) out of an authored colour so\n * core normalize sees only literal/extended variants (it can't interpret a spec — it has no `base`).\n * Returns the colour with those variants removed, plus the extracted specs for colors to bake.\n */\nconst splitDerivationVariants = (\n value: unknown,\n): { value: unknown; specs: Record<string, PaletteDerivationSpec> } => {\n if (\n typeof value !== \"object\" ||\n value === null ||\n Array.isArray(value) ||\n !(value as { variants?: unknown }).variants\n ) {\n return { value, specs: {} };\n }\n\n const variants = (value as { variants: Record<string, unknown> }).variants;\n const specs: Record<string, PaletteDerivationSpec> = {};\n const plain: Record<string, unknown> = {};\n for (const [key, variant] of Object.entries(variants)) {\n if (isDerivationSpec(variant)) specs[key] = variant;\n else plain[key] = variant;\n }\n\n if (!Object.keys(specs).length) return { value, specs };\n\n const nextVariants = Object.keys(plain).length ? plain : undefined;\n return { value: { ...(value as object), variants: nextVariants }, specs };\n};\n\nexport const colorsSubsystem: Subsystem = {\n key: \"colors\",\n // The derivation fns colors records on its synthesized variants (`light`/`dark`/`ghost`/…). The\n // resolver hands each `(literal, arg)`; adapt to the colour-math `(value, percent)` signature.\n derivations: {\n lighten: (value, arg) => lighten(String(value), Number(arg)),\n darken: (value, arg) => darken(String(value), Number(arg)),\n alpha: (value, arg) => alpha(String(value), Number(arg)),\n setL: (value, arg) => setL(String(value), Number(arg)),\n rotateHue: (value, arg) => rotateHue(String(value), Number(arg)),\n adjust: (value, arg) => adjust(String(value), arg as AdjustDials),\n },\n normalizeProperties(rawSlice, ctx): NormalizedProperties {\n const out: NormalizedProperties = {};\n if (!rawSlice) return out;\n\n for (const [name, value] of Object.entries(rawSlice)) {\n if (RESERVED_KEYS.has(name)) continue;\n\n const { value: plainValue, specs } = splitDerivationVariants(value);\n // Specs are stripped above and a tuple base is coerced by `coerceValue`, so the residual is\n // core-shaped — cast to the core authoring type at this boundary.\n const normalized = normalizePropertyValue<string, PalettePropertyExtras>(\n plainValue as PropertyValue<string, PalettePropertyExtras>,\n {\n propertyPath: `colors.${name}`,\n allowedBreakpoints: ctx.allowedBreakpoints,\n coerceValue: coerceColorInput,\n },\n );\n const finalized = finalizePaletteNormalization(\n name,\n normalized as NormalizedPaletteValue,\n specs,\n );\n validateNormalizedResponsiveRefs(finalized as NormalizedPropertyValue<unknown>, {\n propertyPath: `colors.${name}`,\n });\n\n out[name] = finalized as NormalizedPropertyValue<unknown, Record<string, unknown>>;\n }\n\n return out;\n },\n interpretRecipe(variantName, variant, ctx) {\n return interpretPaletteRecipeVariant(\n variantName,\n variant as NormalizedRecipeVariant<PaletteRecipeProps, string>,\n ctx,\n );\n },\n};\n\nexport type { ColorsRaw } from \"./types\";\nexport { audit } from \"./audit\";\nexport type { AuditResult, AuditOptions, PairingScore, PairingKind, WcagLevel } from \"./audit\";\n","/**\n * Typography's `normalizeProperty` hook — modular font-size scale synthesis.\n *\n * When `fontSize` is authored with a `ratio`, this generates the scale steps\n * (`xs`…`4xl`) as variants — each `base * ratio^step` (or a custom `algorithm`),\n * rounded to `precision`. Author-declared steps are preserved and seed the chain.\n * Non-`fontSize` properties and ratio-less `fontSize` pass through untouched.\n */\n\nimport type { NormalizedPropertyValue, NormalizedVariantValue } from \"../../core/normalize\";\nimport type { FontSizeExtras, TypographyRatioKey, TypographyScaleKey } from \"./types\";\n\nconst TYPOGRAPHY_RATIOS: Record<TypographyRatioKey, number> = {\n \"minor-second\": 1.067,\n \"major-second\": 1.125,\n \"minor-third\": 1.2,\n \"major-third\": 1.25,\n \"perfect-fourth\": 1.333,\n \"augmented-fourth\": 1.414,\n \"perfect-fifth\": 1.5,\n golden: 1.618,\n};\n\nconst DEFAULT_SCALE_STEPS: Record<TypographyScaleKey, number> = {\n xs: -2,\n sm: -1,\n md: 0,\n lg: 1,\n xl: 2,\n \"2xl\": 3,\n \"3xl\": 4,\n \"4xl\": 5,\n};\n\nconst DEFAULT_PRECISION = 4;\n\ntype FontSizeVariant = NormalizedVariantValue<number, FontSizeExtras>;\n\n/**\n * The typography `normalizeProperty` hook. Synthesizes the modular scale for\n * `fontSize`; a pass-through for every other typography property.\n *\n * @param propertyKey The property being normalized (only `\"fontSize\"` is transformed).\n * @param normalized The property after the shared property normalize pass.\n */\nexport const finalizeTypographyNormalization = (\n propertyKey: string,\n normalized: NormalizedPropertyValue<unknown>,\n): NormalizedPropertyValue<unknown> => {\n if (propertyKey !== \"fontSize\") return normalized;\n return generateFontSizeScaleVariants(\n normalized as unknown as NormalizedPropertyValue<number, FontSizeExtras>,\n ) as unknown as NormalizedPropertyValue<unknown>;\n};\n\n/**\n * Build the `xs`…`4xl` scale variants from `base`, `ratio`, and `precision`.\n * Returns the input unchanged when there is no (recognized) `ratio`.\n */\nconst generateFontSizeScaleVariants = (\n normalized: NormalizedPropertyValue<number, FontSizeExtras>,\n): NormalizedPropertyValue<number, FontSizeExtras> => {\n const ratio = normalized.ratio;\n if (!ratio) return normalized;\n\n const ratioValue = TYPOGRAPHY_RATIOS[ratio];\n if (!ratioValue) return normalized;\n\n const baseFontSize = normalized.baseFontSize ?? normalized.base;\n const precision = normalized.precision ?? DEFAULT_PRECISION;\n const algorithm = normalized.algorithm;\n const existingVariants = normalized.variants ?? {};\n const generated: Record<string, FontSizeVariant> = {};\n\n let previousValue: number | null = null;\n\n for (const [key, step] of Object.entries(DEFAULT_SCALE_STEPS) as [TypographyScaleKey, number][]) {\n if (existingVariants[key]) {\n previousValue = existingVariants[key].base ?? null;\n continue;\n }\n\n let value: number;\n if (algorithm) {\n value = algorithm(baseFontSize, key, step, previousValue);\n } else {\n value = baseFontSize * Math.pow(ratioValue, step);\n }\n\n const rounded = Number(value.toFixed(precision));\n previousValue = rounded;\n generated[key] = { base: rounded } as FontSizeVariant;\n }\n\n return {\n ...normalized,\n variants: {\n ...generated,\n ...existingVariants,\n },\n };\n};\n","/**\n * Typography's `interpretRecipe` hook â resolves recipe declarations to token-path Refs.\n *\n * A typography recipe prop value names a **variant** of the matching property (`fontSize:\n * \"3xl\"`, `fontWeight: \"bold\"`), or the base value (`fontSize: \"base\"`). This interpreter\n * emits a format-neutral {@link Ref} carrying the canonical token path â `typography.fontSize.3xl`\n * for a variant, `typography.fontSize` for the base. It emits refs **directly** (no `var(--â¦)`\n * strings); the CSS adapter maps each path to a `var(--â¦)` at render time, so `theme.model`\n * carries no CSS syntax. Ported + reshaped from the old `subsystems/typography/recipes.ts`\n * (which produced `var(--â¦)` strings via a prefix resolver).\n */\nimport type { InterpretedRecipeVariant, InterpretedRecipeOverride, Ref } from \"../../core/model\";\nimport type { NormalizedRecipeVariant } from \"../../core/normalize\";\nimport type { RecipeInterpretContext } from \"../../core/subsystem\";\nimport type { TypographyRecipeProps } from \"./types\";\n\nconst RESERVED_KEYS: ReadonlySet<string> = new Set([\n \"breakpoint\",\n \"query\",\n \"state\",\n \"variant\",\n \"target\",\n \"orientation\",\n]);\n\n/** Recipe prop key â CSS declaration property name. Only these keys are lowered. */\nconst PROPERTY_CSS_MAP: Record<string, string> = {\n fontFamily: \"font-family\",\n fontSize: \"font-size\",\n fontWeight: \"font-weight\",\n lineHeight: \"line-height\",\n letterSpacing: \"letter-spacing\",\n fontStyle: \"font-style\",\n textTransform: \"text-transform\",\n textDecoration: \"text-decoration\",\n textAlign: \"text-align\",\n};\n\n/**\n * Interpret one typography recipe variant into base + responsive/state override declarations,\n * each a token-path {@link Ref}. A responsive `variant:` swap inherits the sibling's base\n * declarations (via `ctx.resolveRecipeVariant`).\n */\nexport const interpretTypographyRecipeVariant = (\n variantName: string,\n variant: NormalizedRecipeVariant<TypographyRecipeProps, string>,\n ctx: RecipeInterpretContext,\n): InterpretedRecipeVariant<string> => {\n const base = interpretProps(variant.base);\n\n const responsive: InterpretedRecipeOverride<string>[] = variant.responsive.map(entry => {\n const { breakpoint, query, state, variant: swap, target, orientation, container, size, ...rawDecls } =\n entry as TypographyRecipeProps & {\n breakpoint?: string;\n query?: \"min\" | \"max\" | \"exact\";\n state?: string;\n variant?: string;\n target?: string;\n orientation?: \"landscape\" | \"portrait\";\n container?: string;\n size?: string;\n };\n\n const inherited = swap ? { ...ctx.resolveRecipeVariant(swap).base } : {};\n const overrides = interpretProps(rawDecls as TypographyRecipeProps);\n\n const override: InterpretedRecipeOverride<string> = {\n declarations: { ...inherited, ...overrides },\n };\n if (breakpoint) {\n override.breakpoint = breakpoint;\n override.query = query ?? \"exact\";\n }\n if (container) {\n override.container = container;\n if (size) override.size = size;\n override.query = query ?? \"min\";\n }\n if (state) override.state = state;\n if (target) override.target = target; // dec.8 — scope onto the `<item>-<target>` sibling\n if (orientation) override.orientation = orientation;\n return override;\n });\n\n return { base, responsive };\n};\n\n/** Interpret a flat declaration block â `cssProperty â { ref }`, skipping empty / unknown keys. */\nconst interpretProps = (props: TypographyRecipeProps | undefined): Record<string, Ref> => {\n const declarations: Record<string, Ref> = {};\n if (!props) return declarations;\n\n for (const [key, value] of Object.entries(props)) {\n if (!value || RESERVED_KEYS.has(key)) continue;\n const cssProperty = PROPERTY_CSS_MAP[key];\n if (!cssProperty) continue;\n declarations[cssProperty] = { ref: variantPath(key, value) };\n }\n\n return declarations;\n};\n\n/** The token path for a property variant: `typography.<key>` for `\"base\"`, else `typography.<key>.<variant>`. */\nconst variantPath = (propertyKey: string, variant: string): string =>\n variant === \"base\" ? `typography.${propertyKey}` : `typography.${propertyKey}.${variant}`;\n","/**\n * The typography subsystem — a \"regular\" subsystem (no synthesized-ref derivations,\n * unlike colors' tonal steps). Iterates `raw.typography` (skipping the reserved `recipes`\n * key), runs the shared property normalize + the fontSize modular-scale synthesis per\n * property, and interprets recipes into token-path refs. It grows a hook, never the spine.\n */\n\nimport type { Subsystem, NormalizedProperties } from \"../../core/subsystem\";\nimport type { NormalizedPropertyValue, NormalizedRecipeVariant } from \"../../core/normalize\";\nimport {\n normalizePropertyValue,\n validateNormalizedResponsiveRefs,\n} from \"../../core/normalize\";\nimport type { FontSizeExtras, TypographyRecipeProps } from \"./types\";\nimport { finalizeTypographyNormalization } from \"./normalize\";\nimport { interpretTypographyRecipeVariant } from \"./recipes\";\n\n/** Sub-keys of `raw.typography` that are not properties. */\nconst RESERVED_KEYS: ReadonlySet<string> = new Set([\"recipes\"]);\n\nexport const typographySubsystem: Subsystem = {\n key: \"typography\",\n normalizeProperties(rawSlice, ctx): NormalizedProperties {\n const out: NormalizedProperties = {};\n if (!rawSlice) return out;\n\n for (const [name, value] of Object.entries(rawSlice)) {\n if (RESERVED_KEYS.has(name)) continue;\n\n const normalized = normalizePropertyValue<unknown, FontSizeExtras>(\n value as never,\n { propertyPath: `typography.${name}`, allowedBreakpoints: ctx.allowedBreakpoints },\n );\n const finalized = finalizeTypographyNormalization(\n name,\n normalized as NormalizedPropertyValue<unknown>,\n );\n validateNormalizedResponsiveRefs(finalized, { propertyPath: `typography.${name}` });\n\n out[name] = finalized as NormalizedPropertyValue<unknown, Record<string, unknown>>;\n }\n\n return out;\n },\n interpretRecipe(variantName, variant, ctx) {\n return interpretTypographyRecipeVariant(\n variantName,\n variant as NormalizedRecipeVariant<TypographyRecipeProps, string>,\n ctx,\n );\n },\n};\n\nexport type { TypographyRaw, TypographyPropertyValue } from \"./types\";\n","/**\n * Layout subsystem types (clean-room).\n *\n * Regular property keys (`spacing` / `gutters` / `aspectRatio`) normalize like any other\n * subsystem; the structural keys (`columns` / `grids` / `stacks` / `container`) drive the\n * structural generators (see `structural.ts`); `recipes` are ordinary token-path recipes.\n */\n\nimport type { PropertyValue, RecipeBlock } from \"../../core/normalize\";\n\nexport type ResponsiveQuery = \"min\" | \"max\" | \"exact\";\n\n/** The whitelisted \"regular\" layout property keys (the ones that become `PropertyModel`s). */\nexport const LAYOUT_PROPERTY_KEYS: readonly string[] = [\"spacing\", \"gutters\", \"aspectRatio\", \"sizes\"];\n\n/**\n * Scale-synthesis authoring keys (§10.6) for a length scale (`spacing`/`gutters`/`sizes`). Declare\n * one curve — `ratio` (geometric `base × ratio^n`, `steps` an ordered name array) or `step` (linear\n * `step × n`, `steps` a name→multiplier map) — to synthesize the variant ramp instead of hand-listing\n * it. Opt-in: absent both, the property behaves exactly as before. The same keys inside a `responsive`\n * entry regenerate the whole named scale at that breakpoint (D6). Authored `variants` still win.\n */\nexport type LayoutScaleExtras = {\n ratio?: number;\n step?: number;\n steps?: readonly string[] | Record<string, number>;\n};\n\n// --- Columns ---\n\nexport type ColumnsConfig = { size: number; gutter?: string; inset?: string };\nexport type ColumnsValue = number | ColumnsConfig;\n\n// --- Grids ---\n\nexport type GridDefinition = {\n templateColumns?: string;\n templateRows?: string;\n autoRows?: string;\n autoColumns?: string;\n justifyItems?: string;\n alignItems?: string;\n justifyContent?: string;\n alignContent?: string;\n gap?: string;\n responsive?: Array<{\n breakpoint: string;\n query?: ResponsiveQuery;\n templateColumns?: string;\n templateRows?: string;\n autoRows?: string;\n autoColumns?: string;\n justifyItems?: string;\n alignItems?: string;\n justifyContent?: string;\n alignContent?: string;\n gap?: string;\n }>;\n};\nexport type GridsDefinition = Record<string, GridDefinition>;\n\n// --- Stacks ---\n\nexport type StackDefinition = {\n direction?: \"row\" | \"column\";\n align?: string;\n justify?: string;\n wrap?: string;\n inline?: boolean;\n gap?: string;\n responsive?: Array<{\n breakpoint: string;\n query?: ResponsiveQuery;\n direction?: \"row\" | \"column\";\n align?: string;\n justify?: string;\n wrap?: string;\n inline?: boolean;\n }>;\n};\nexport type StacksDefinition = Record<string, StackDefinition>;\n\n// --- Container ---\n\nexport type ContainerConfig = {\n /** The resolved mode: `\"fixed\"` / `\"fluid\"` / a custom width string. */\n mode: string;\n inset?: string;\n gutter?: string;\n direction?: string;\n align?: string;\n justify?: string;\n maxWidth?: string | number;\n};\n\n// --- Container (authored) ---\n\n/**\n * One authored container variant (§8a) — a mode string (`\"fixed\"` / `\"fluid\"` / a width) or a\n * config object. Distinct from {@link ContainerConfig}, which is the resolved `{ mode }` shape the\n * structural generator produces.\n */\nexport type ContainerVariantRaw =\n | string\n | {\n base?: string;\n inset?: string;\n gutter?: string;\n direction?: string;\n align?: string;\n justify?: string;\n maxWidth?: string | number;\n };\n\n/** The authored `layout.container` value (§8a) — a mode string or a config with variants/responsive. */\nexport type ContainerRaw =\n | string\n | {\n base?: string;\n inset?: string;\n gutter?: string;\n direction?: string;\n align?: string;\n justify?: string;\n maxWidth?: string | number;\n variants?: Record<string, ContainerVariantRaw>;\n responsive?: Array<{\n breakpoint: string;\n query?: ResponsiveQuery;\n target?: string;\n direction?: string;\n align?: string;\n justify?: string;\n inset?: string;\n gutter?: string;\n }>;\n };\n\n// --- Recipes ---\n\nexport type LayoutRecipeProps = {\n paddingY?: string;\n paddingX?: string;\n marginY?: string;\n marginX?: string;\n gap?: string;\n background?: string;\n /**\n * Sizing verbs (§22) — each names a `layout.sizes` variant and routes to its CSS longhand\n * (`maxWidth` → `max-width`, no fan-out). A verb exists because it consumes a themed scale (`sizes`);\n * dimensional CSS with no scale (`display`, `position`, …) stays in a component `css` delta.\n */\n width?: string;\n minWidth?: string;\n maxWidth?: string;\n height?: string;\n minHeight?: string;\n maxHeight?: string;\n [property: string]: string | undefined;\n};\n\n/**\n * The authored `raw.layout` slice (§8a). The only **closed** subsystem — its keys are fixed:\n * the regular property tokens (`spacing`/`gutters`/`aspectRatio`), the four structural generators\n * (`columns`/`grids`/`stacks`/`container`), and the `recipes` block. Authoring type only.\n */\nexport interface LayoutRaw {\n spacing?: PropertyValue<string | number, LayoutScaleExtras>;\n gutters?: PropertyValue<string | number, LayoutScaleExtras>;\n aspectRatio?: PropertyValue<string | number>;\n /** The sizing scale (§22) — one length scale for width/height/min/max, chosen at the recipe verb. */\n sizes?: PropertyValue<string | number, LayoutScaleExtras>;\n columns?: ColumnsValue;\n grids?: GridsDefinition;\n stacks?: StacksDefinition;\n container?: ContainerRaw;\n recipes?: RecipeBlock<LayoutRecipeProps>;\n}\n","/**\n * Layout's `normalizeProperty` hook — numeric scale synthesis (§10.6) + the forced `none` variant.\n *\n * `spacing` / `gutters` / `sizes` can synthesize their variant ramp from a base + a curve, the same\n * way colors generates tonal steps and typography the type scale:\n * - **geometric** (`ratio`) — `base × ratio^n`, `steps` an ordered name array (index = exponent);\n * - **linear** (`step`) — `step × n`, `steps` a name→multiplier map (the 4/8-pt grid).\n *\n * Each synthesized step is stored as a **derived** variant (`{ base, derive:{ ref, fn:\"scaleStep\",\n * arg } }`) so the Model carries it as a re-resolving `Ref` — `override()` of the base re-synthesizes\n * every step (mirror colors, NOT typography's frozen literals). A ramp entry inside a property's\n * `responsive` list (D6) regenerates the WHOLE named scale at that breakpoint, expanding into one\n * `target` override per step — the already-existing responsive channel, no new Model member.\n *\n * Synthesis is **opt-in + additive**: absent a `ratio`/`step`, behaviour is byte-identical to before\n * (spacing/gutters still get the forced `none`; sizes/aspectRatio pass through). Authored `variants`\n * always win over synthesized ones — the way sizes' semantic caps (`prose`) and pinned values\n * (`full: \"100%\"`, no magnitude → never synthesized) coexist with the ramp.\n */\n\nimport type { NormalizedPropertyValue } from \"../../core/normalize\";\nimport type { Literal } from \"../../core/model\";\nimport { RefractError } from \"../../core/errors\";\n\n/** Layout properties eligible for scale synthesis (`aspectRatio` is not a length ramp). */\nconst SCALE_PROPERTIES: ReadonlySet<string> = new Set([\"spacing\", \"gutters\", \"sizes\"]);\n\n/** Properties that always expose a `none` variant (`base: 0`), synthesized or not. */\nconst FORCE_NONE_PROPERTIES: ReadonlySet<string> = new Set([\"spacing\", \"gutters\"]);\n\n/** Decimal places every synthesized step is rounded to — fixed so `scaleStep` re-derives exactly. */\nconst SCALE_PRECISION = 4;\n\n/** The default step ladder used when a curve is declared without an explicit `steps`. */\nconst DEFAULT_LADDER: readonly string[] = [\"xs\", \"sm\", \"md\", \"lg\", \"xl\", \"2xl\", \"3xl\", \"4xl\"];\n\nconst round = (n: number): number => Number(n.toFixed(SCALE_PRECISION));\n\n/**\n * The `scaleStep` derivation fn (registered by the layout subsystem). Re-derives a synthesized step\n * from its curve config: **geometric** `base × ratio^exp` (from the resolved base token, so an\n * `override()` of the base rescales it), **linear** `step × mult` (a fixed grid, self-contained in\n * `arg`). A responsive ramp step with an explicit breakpoint base carries it on `arg.base`, so it\n * derives from its own breakpoint base (precedent: colors' appearance modes). Mirrors the way the\n * derivation registry hands every fn `(resolvedValue, arg)`.\n */\nexport const scaleStep = (value: Literal, arg?: unknown): Literal => {\n const a = (arg ?? {}) as {\n curve?: string;\n ratio?: number;\n exp?: number;\n step?: number;\n mult?: number;\n base?: number;\n };\n if (a.curve === \"linear\") {\n return round(Number(a.step) * Number(a.mult));\n }\n const base = a.base !== undefined ? Number(a.base) : Number(value);\n return round(base * Math.pow(Number(a.ratio), Number(a.exp)));\n};\n\n/** One synthesized step's position — `exp` (ordinal, geometric exponent), `mult` (linear multiplier). */\ntype StepSpec = { name: string; exp: number; mult?: number };\n\n/** The resolved curve for a property — its kind, its parameters, and the ordered step list. */\ntype ScaleConfig =\n | { curve: \"geometric\"; ratio: number; specs: StepSpec[] }\n | { curve: \"linear\"; step: number; specs: StepSpec[] };\n\n/**\n * Read the top-level curve config off a normalized property. `ratio` selects geometric, `step`\n * selects linear (never both). `steps` is the naming source — an ordered name array for geometric,\n * a name→multiplier map for linear — falling back to {@link DEFAULT_LADDER} when omitted. Returns\n * `undefined` when no curve is declared (the additive, byte-identical path).\n */\nconst readScaleConfig = (\n propertyKey: string,\n normalized: NormalizedPropertyValue<unknown>,\n): ScaleConfig | undefined => {\n const n = normalized as Record<string, unknown>;\n const hasRatio = n.ratio !== undefined;\n const hasStep = n.step !== undefined;\n if (!hasRatio && !hasStep) return undefined;\n if (hasRatio && hasStep) {\n throw new RefractError(\n \"REFRACT_E_LAYOUT\",\n `layout.${propertyKey}: declare only one of \"ratio\" (geometric) or \"step\" (linear) scale, not both.`,\n );\n }\n const steps = n.steps;\n\n if (hasRatio) {\n let names: readonly string[];\n if (steps === undefined) names = DEFAULT_LADDER;\n else if (Array.isArray(steps)) names = steps.map(String);\n else {\n throw new RefractError(\n \"REFRACT_E_LAYOUT\",\n `layout.${propertyKey}: a geometric scale (\"ratio\") needs \"steps\" as an ordered name array, e.g. [\"sm\",\"md\",\"lg\"].`,\n );\n }\n const specs = names.map((name, i): StepSpec => ({ name, exp: i }));\n return { curve: \"geometric\", ratio: Number(n.ratio), specs };\n }\n\n let specs: StepSpec[];\n if (steps === undefined) {\n specs = DEFAULT_LADDER.map((name, i): StepSpec => ({ name, exp: i, mult: i + 1 }));\n } else if (Array.isArray(steps) || typeof steps !== \"object\" || steps === null) {\n throw new RefractError(\n \"REFRACT_E_LAYOUT\",\n `layout.${propertyKey}: a linear scale (\"step\") needs \"steps\" as a name→multiplier map, e.g. { sm:1, md:2, lg:3 }.`,\n );\n } else {\n specs = Object.entries(steps as Record<string, unknown>).map(\n ([name, mult], i): StepSpec => ({ name, exp: i, mult: Number(mult) }),\n );\n }\n return { curve: \"linear\", step: Number(n.step), specs };\n};\n\n/** Build the derived variant refs for a curve's steps — each a `{ base, derive }` re-resolving step. */\nconst synthesizeVariants = (\n propertyKey: string,\n base: unknown,\n config: ScaleConfig,\n): Record<string, { base: Literal; derive: { ref: string; fn: string; arg: unknown } }> => {\n const ref = `layout.${propertyKey}`;\n const out: Record<string, { base: Literal; derive: { ref: string; fn: string; arg: unknown } }> = {};\n for (const spec of config.specs) {\n if (config.curve === \"geometric\") {\n const value = round(Number(base) * Math.pow(config.ratio, spec.exp));\n out[spec.name] = {\n base: value,\n derive: { ref, fn: \"scaleStep\", arg: { curve: \"geometric\", ratio: config.ratio, exp: spec.exp } },\n };\n } else {\n const value = round(config.step * (spec.mult as number));\n out[spec.name] = {\n base: value,\n derive: { ref, fn: \"scaleStep\", arg: { curve: \"linear\", step: config.step, mult: spec.mult } },\n };\n }\n }\n return out;\n};\n\n/**\n * Expand ramp entries in a property's `responsive` list (D6). A responsive entry carrying `ratio`\n * (geometric) or `step` (linear) regenerates the whole named scale at that breakpoint, emitting one\n * `target` override per synthesized step — each a derived `{ base, derive }` so the JSON/DTCG output\n * carries the recipe and `override()` re-runs the ramp. Non-ramp entries (plain value / variant /\n * target swaps) pass through untouched. A geometric ramp uses each step's ordinal exponent (so a\n * `ratio:1` flattens every step to the base); a linear ramp needs the base scale's multipliers.\n */\nconst expandResponsive = (\n propertyKey: string,\n propBase: unknown,\n responsive: NormalizedPropertyValue<unknown>[\"responsive\"],\n config: ScaleConfig | undefined,\n): NormalizedPropertyValue<unknown>[\"responsive\"] => {\n if (!responsive?.length) return responsive;\n const ref = `layout.${propertyKey}`;\n\n const out: Record<string, unknown>[] = [];\n let expandedAny = false;\n\n for (const entry of responsive) {\n const e = entry as Record<string, unknown>;\n const isRamp = e.ratio !== undefined || e.step !== undefined;\n if (!isRamp) {\n out.push(e);\n continue;\n }\n expandedAny = true;\n if (e.ratio !== undefined && e.step !== undefined) {\n throw new RefractError(\n \"REFRACT_E_LAYOUT\",\n `layout.${propertyKey}: a responsive ramp entry may set only \"ratio\" or \"step\", not both.`,\n );\n }\n if (!config) {\n throw new RefractError(\n \"REFRACT_E_LAYOUT\",\n `layout.${propertyKey}: a responsive ramp entry needs a base scale — declare a top-level \"ratio\"/\"step\" (+ \"steps\") first.`,\n );\n }\n\n const { breakpoint, query, orientation } = e;\n const geometric = e.ratio !== undefined;\n\n for (const spec of config.specs) {\n let value: number;\n let arg: Record<string, unknown>;\n if (geometric) {\n const ratio = Number(e.ratio);\n const hasBase = e.base !== undefined;\n const b = hasBase ? Number(e.base) : Number(propBase);\n value = round(b * Math.pow(ratio, spec.exp));\n arg = { curve: \"geometric\", ratio, exp: spec.exp, ...(hasBase ? { base: b } : {}) };\n } else {\n if (spec.mult === undefined) {\n throw new RefractError(\n \"REFRACT_E_LAYOUT\",\n `layout.${propertyKey}: a linear responsive ramp (\"step\") requires a linear base scale (a name→multiplier \"steps\").`,\n );\n }\n const step = Number(e.step);\n value = round(step * spec.mult);\n arg = { curve: \"linear\", step, mult: spec.mult };\n }\n const expanded: Record<string, unknown> = {\n breakpoint,\n query,\n target: spec.name,\n base: value,\n derive: { ref, fn: \"scaleStep\", arg },\n };\n if (orientation !== undefined) expanded.orientation = orientation;\n out.push(expanded);\n }\n }\n\n return (expandedAny ? out : responsive) as NormalizedPropertyValue<unknown>[\"responsive\"];\n};\n\n/** Strip the curve-config keys off a normalized property so they never leak as Model extras. */\nconst stripScaleKeys = (\n normalized: NormalizedPropertyValue<unknown>,\n): NormalizedPropertyValue<unknown> => {\n const { ratio, step, steps, ...rest } = normalized as Record<string, unknown>;\n void ratio;\n void step;\n void steps;\n return rest as unknown as NormalizedPropertyValue<unknown>;\n};\n\n/**\n * @param propertyKey The layout property being normalized.\n * @param normalized The property after the shared property normalize pass.\n */\nexport const finalizeLayoutNormalization = (\n propertyKey: string,\n normalized: NormalizedPropertyValue<unknown>,\n): NormalizedPropertyValue<unknown> => {\n if (!SCALE_PROPERTIES.has(propertyKey)) return normalized;\n\n const config = readScaleConfig(propertyKey, normalized);\n\n // Additive: no curve declared → the exact legacy behaviour (byte-identical goldens).\n if (!config) {\n return FORCE_NONE_PROPERTIES.has(propertyKey) ? forceNoneVariant(normalized) : normalized;\n }\n\n // Synthesized steps are the base layer; authored `variants` win on name collision (sizes' semantic\n // caps / pinned `%` ride here); the forced `none` (spacing/gutters) wins over everything.\n const synthesized = synthesizeVariants(propertyKey, normalized.base, config);\n const authored = normalized.variants ?? {};\n let variants: Record<string, unknown> = { ...synthesized, ...authored };\n if (FORCE_NONE_PROPERTIES.has(propertyKey)) variants = { ...variants, none: { base: 0 } };\n\n const responsive = expandResponsive(propertyKey, normalized.base, normalized.responsive, config);\n\n return stripScaleKeys({\n ...normalized,\n variants,\n responsive,\n } as unknown as NormalizedPropertyValue<unknown>);\n};\n\n/** Force a `none` variant (`base: 0`) onto the property, overriding any author-declared `none`. */\nconst forceNoneVariant = (\n normalized: NormalizedPropertyValue<unknown>,\n): NormalizedPropertyValue<unknown> => {\n const variants = normalized.variants ?? {};\n return {\n ...normalized,\n variants: {\n ...variants,\n none: { base: 0 },\n },\n } as unknown as NormalizedPropertyValue<unknown>;\n};\n","/**\n * Layout's `interpretRecipe` hook â resolves recipe declarations to token-path Refs.\n *\n * A layout recipe prop names a **spacing variant** (`paddingY: \"xl\"`, `gap: \"relaxed\"`),\n * which this interpreter emits as a `layout.spacing.<variant>` token-path {@link Ref}\n * (`layout.spacing` for the base). `background` passes through as a literal. One recipe prop\n * can fan out to several CSS declarations (`paddingY` â `padding-top` + `padding-bottom`).\n * Emits refs **directly** â no `var(--â¦)` strings; the CSS adapter maps each path to a\n * `var(--â¦)` at render time. Ported + reshaped from the old `subsystems/layout/recipes.ts`.\n */\nimport type { InterpretedRecipeVariant, InterpretedRecipeOverride, Ref } from \"../../core/model\";\nimport type { NormalizedRecipeVariant } from \"../../core/normalize\";\nimport type { RecipeInterpretContext } from \"../../core/subsystem\";\nimport type { LayoutRecipeProps } from \"./types\";\nimport { RefractError } from \"../../core/errors\";\n\nconst RESERVED_KEYS: ReadonlySet<string> = new Set([\n \"breakpoint\",\n \"query\",\n \"state\",\n \"variant\",\n \"target\",\n \"orientation\",\n]);\n\n/** Recipe verb â the CSS declaration property names it expands to. Spacing verbs fan out (Y â top+bottom);\n * sizing verbs (§22) are 1:1 with their longhand; `background` is the one literal verb. */\nconst PROPERTY_CSS_MAP: Record<string, string[]> = {\n paddingY: [\"padding-top\", \"padding-bottom\"],\n paddingX: [\"padding-left\", \"padding-right\"],\n marginY: [\"margin-top\", \"margin-bottom\"],\n marginX: [\"margin-left\", \"margin-right\"],\n gap: [\"gap\"],\n background: [\"background\"],\n // §22 sizing verbs â resolve against `layout.sizes`, one longhand each.\n width: [\"width\"],\n minWidth: [\"min-width\"],\n maxWidth: [\"max-width\"],\n height: [\"height\"],\n minHeight: [\"min-height\"],\n maxHeight: [\"max-height\"],\n};\n\n/**\n * Which themed scale a verb's value names (§22 governing principle: a verb exists because it consumes a\n * themed scale). Spacing verbs â `layout.spacing`, sizing verbs â `layout.sizes`; `background` is the one\n * `\"literal\"` verb (a raw CSS value, no scale).\n */\nconst PROPERTY_DOMAIN: Record<string, \"spacing\" | \"sizes\" | \"literal\"> = {\n paddingY: \"spacing\", paddingX: \"spacing\", marginY: \"spacing\", marginX: \"spacing\", gap: \"spacing\",\n width: \"sizes\", minWidth: \"sizes\", maxWidth: \"sizes\", height: \"sizes\", minHeight: \"sizes\", maxHeight: \"sizes\",\n background: \"literal\",\n};\n\n/** A `layout.<domain>` token path for a variant: the base token for `\"base\"`, else `.<variant>`. */\nconst tokenPath = (domain: \"spacing\" | \"sizes\", variant: string): string =>\n variant === \"base\" ? `layout.${domain}` : `layout.${domain}.${variant}`;\n\n/**\n * Interpret one flat declaration block â `cssProperty â Ref`. Each verb resolves against its themed\n * scale ({@link PROPERTY_DOMAIN}); `background` stays a literal. An **unknown** verb throws (§22 D5) â\n * the map used to silently drop it, so a typo (`pading`) or an unsupported property vanished with no error.\n */\nconst interpretProps = (props: LayoutRecipeProps | undefined, label: string): Record<string, Ref> => {\n const declarations: Record<string, Ref> = {};\n if (!props) return declarations;\n\n for (const [key, value] of Object.entries(props)) {\n if (RESERVED_KEYS.has(key)) continue;\n if (!value) continue;\n const cssProperties = PROPERTY_CSS_MAP[key];\n if (!cssProperties) {\n throw new RefractError(\n \"REFRACT_E_LAYOUT\",\n `Unknown layout recipe property \"${key}\" in ${label}. Known verbs: ` +\n `${Object.keys(PROPERTY_CSS_MAP).join(\", \")}. For arbitrary CSS use a component \\`css\\` delta.`,\n );\n }\n const domain = PROPERTY_DOMAIN[key];\n for (const cssProperty of cssProperties) {\n declarations[cssProperty] = domain === \"literal\" ? { value } : { ref: tokenPath(domain, value) };\n }\n }\n\n return declarations;\n};\n\n/** Interpret one layout recipe variant into base + responsive/state override declarations. */\nexport const interpretLayoutRecipeVariant = (\n variantName: string,\n variant: NormalizedRecipeVariant<LayoutRecipeProps, string>,\n ctx: RecipeInterpretContext,\n): InterpretedRecipeVariant<string> => {\n const label = `${ctx.groupPath ?? \"layout.recipes\"}.${variantName}`;\n const base = interpretProps(variant.base, label);\n\n const responsive: InterpretedRecipeOverride<string>[] = variant.responsive.map(entry => {\n const { breakpoint, query, state, variant: swap, target, orientation, container, size, ...rawDecls } =\n entry as LayoutRecipeProps & {\n breakpoint?: string;\n query?: \"min\" | \"max\" | \"exact\";\n state?: string;\n variant?: string;\n target?: string;\n orientation?: \"landscape\" | \"portrait\";\n container?: string;\n size?: string;\n };\n\n const inherited = swap ? { ...ctx.resolveRecipeVariant(swap).base } : {};\n const overrides = interpretProps(rawDecls as LayoutRecipeProps, label);\n\n const override: InterpretedRecipeOverride<string> = {\n declarations: { ...inherited, ...overrides },\n };\n if (breakpoint) {\n override.breakpoint = breakpoint;\n override.query = query ?? \"exact\";\n }\n if (container) {\n override.container = container;\n if (size) override.size = size;\n override.query = query ?? \"min\";\n }\n if (state) override.state = state;\n if (target) override.target = target; // dec.8 — scope onto the `<item>-<target>` sibling\n if (orientation) override.orientation = orientation;\n return override;\n });\n\n return { base, responsive };\n};\n","/**\n * Layout structural generators → **Model rule-sets** (the clean-room payoff).\n *\n * `columns` / `grids` / `stacks` / `container` used to emit `CssNode[]` that a lossless\n * node↔rule-set codec (`routeLayoutStructuralThroughModel`) round-tripped into the Model.\n * Here the generators emit {@link RuleSetGroup}s **natively** — declarations carry token-path\n * {@link Ref}s (`layout.spacing.relaxed`), never `var(--…)` — so the codec never exists. The CSS\n * adapter lowers these rule-sets to `CssRuleNode[]` (columns/grids/stacks via `lowerRecipeGroup`,\n * container via the two-pass `lowerContainerGroup`, matching the old unshift-bases/push-medias order).\n *\n * The columns/container config knobs (`--…-columns--size`, `--…-container--inset`, …) ride along as\n * **layout property tokens** (`configProperties`, merged as `extraProperties` in the Model); the\n * structural rule declarations reference those config tokens by path (`layout.container--inset`),\n * exactly the two-level indirection the old generators produced. Math ported verbatim from the old\n * `subsystems/layout/tokens.ts`; only the output shape (rule-sets, not CSS) differs.\n *\n * The math forms variant keys from raw breakpoint keys + span numbers (`col-sm-3`); the adapter\n * prepends the class prefix + sanitizes. No CSS syntax is produced here — core stays format-neutral.\n */\nimport type { PropertyModel, Ref, RuleSet, RuleSetGroup, RuleSetOverride } from \"../../core/model\";\nimport { type MediaConfig, formatWidth, resolveMediaConfig } from \"../../core/media\";\nimport type {\n ColumnsValue,\n ContainerConfig,\n GridsDefinition,\n StacksDefinition,\n} from \"./types\";\n\n/** The structural output: rule-set groups (for the Model + CSS) + config `:root` tokens. */\nexport type LayoutStructuralOutput = {\n ruleSetGroups: Record<string, RuleSetGroup>;\n configProperties: Record<string, PropertyModel>;\n};\n\n// --- token-path ref helpers (no CSS) ---\n\n/** A spacing token ref: `layout.spacing` for `\"base\"`, else `layout.spacing.<variant>`. */\nconst spacingRef = (variant: string): Ref => ({\n ref: variant === \"base\" ? \"layout.spacing\" : `layout.spacing.${variant}`,\n});\n/** A gutters token ref: `layout.gutters` for `\"base\"`, else `layout.gutters.<variant>`. */\nconst guttersRef = (variant: string): Ref => ({\n ref: variant === \"base\" ? \"layout.gutters\" : `layout.gutters.${variant}`,\n});\n/** A sizes token ref (§22): `layout.sizes` for `\"base\"`, else `layout.sizes.<variant>`. */\nconst sizesRef = (variant: string): Ref => ({\n ref: variant === \"base\" ? \"layout.sizes\" : `layout.sizes.${variant}`,\n});\n/** A ref to a structural config token (`layout.<key>`, e.g. `layout.container--inset`). */\nconst configRef = (key: string): Ref => ({ ref: `layout.${key}` });\nconst literal = (value: string | number): Ref => ({ value });\n\nconst sortByWidth = (breakpoints: Record<string, number>): string[] =>\n Object.keys(breakpoints).sort((a, b) => breakpoints[a] - breakpoints[b]);\n\n// ---------------------------------------------------------------------------\n// Columns — `kind: \"utility\"`, one rule-set per (span × breakpoint)\n// ---------------------------------------------------------------------------\n\nexport const buildColumns = (\n input: ColumnsValue | undefined,\n breakpoints: Record<string, number>,\n): LayoutStructuralOutput | undefined => {\n if (!input) return undefined;\n const config = typeof input === \"number\" ? { size: input } : input;\n const size = config.size;\n const gutterRef = config.gutter ?? \"base\";\n const insetRef = config.inset ?? \"none\";\n\n const configProperties: Record<string, PropertyModel> = {\n \"columns--size\": { base: literal(String(size)) },\n \"columns--gutter\": { base: guttersRef(gutterRef) },\n \"columns--inset\": { base: spacingRef(insetRef) },\n };\n\n const group: RuleSetGroup = {};\n const spans = Array.from({ length: size }, (_, i) => i + 1);\n for (const key of sortByWidth(breakpoints)) {\n for (const span of spans) {\n const colVariant = `col-${key}-${span}`;\n const offsetVariant = `offset-${key}-${span}`;\n const colDecl: Record<string, Ref> = { \"grid-column-end\": literal(`span ${span}`) };\n const offsetDecl: Record<string, Ref> = { \"grid-column-start\": literal(String(span + 1)) };\n\n if (breakpoints[key] === 0) {\n group[colVariant] = { kind: \"utility\", declarations: colDecl, overrides: [] };\n group[offsetVariant] = { kind: \"utility\", declarations: offsetDecl, overrides: [] };\n } else {\n group[colVariant] = {\n kind: \"utility\",\n declarations: {},\n overrides: [{ breakpoint: key, query: \"min\", declarations: colDecl }],\n };\n group[offsetVariant] = {\n kind: \"utility\",\n declarations: {},\n overrides: [{ breakpoint: key, query: \"min\", declarations: offsetDecl }],\n };\n }\n }\n }\n\n return { ruleSetGroups: { columns: group }, configProperties };\n};\n\n// ---------------------------------------------------------------------------\n// Grids — `kind: \"recipe\"`, one rule-set per grid\n// ---------------------------------------------------------------------------\n\n/** The grid declaration props (in emission order) that pass through as literals. */\nconst GRID_LITERAL_PROPS: ReadonlyArray<[keyof GridsDefinition[string], string]> = [\n [\"templateColumns\", \"grid-template-columns\"],\n [\"templateRows\", \"grid-template-rows\"],\n [\"autoRows\", \"grid-auto-rows\"],\n [\"autoColumns\", \"grid-auto-columns\"],\n [\"justifyItems\", \"justify-items\"],\n [\"alignItems\", \"align-items\"],\n [\"justifyContent\", \"justify-content\"],\n [\"alignContent\", \"align-content\"],\n];\n\nconst gridDeclarations = (\n grid: Record<string, unknown>,\n includeDisplay: boolean,\n): Record<string, Ref> => {\n const decls: Record<string, Ref> = {};\n if (includeDisplay) decls[\"display\"] = literal(\"grid\");\n for (const [key, cssProperty] of GRID_LITERAL_PROPS) {\n const value = grid[key as string];\n if (value) decls[cssProperty] = literal(value as string);\n }\n if (grid.gap) decls[\"gap\"] = spacingRef(grid.gap as string);\n return decls;\n};\n\nexport const buildGrids = (\n grids: GridsDefinition | undefined,\n): LayoutStructuralOutput | undefined => {\n if (!grids || !Object.keys(grids).length) return undefined;\n const group: RuleSetGroup = {};\n\n for (const [name, grid] of Object.entries(grids)) {\n const declarations = gridDeclarations(grid, true);\n const overrides: RuleSetOverride[] = [];\n for (const entry of grid.responsive ?? []) {\n const respDecls = gridDeclarations(entry, false);\n if (Object.keys(respDecls).length) {\n overrides.push({ breakpoint: entry.breakpoint, query: entry.query ?? \"exact\", declarations: respDecls });\n }\n }\n group[`grid-${name}`] = { kind: \"recipe\", declarations, overrides };\n }\n\n return { ruleSetGroups: { grids: group }, configProperties: {} };\n};\n\n// ---------------------------------------------------------------------------\n// Stacks — `kind: \"recipe\"`, one rule-set per stack\n// ---------------------------------------------------------------------------\n\nexport const buildStacks = (\n stacks: StacksDefinition | undefined,\n): LayoutStructuralOutput | undefined => {\n if (!stacks || !Object.keys(stacks).length) return undefined;\n const group: RuleSetGroup = {};\n\n for (const [name, stack] of Object.entries(stacks)) {\n const declarations: Record<string, Ref> = {\n display: literal(stack.inline ? \"inline-flex\" : \"flex\"),\n \"flex-direction\": literal(stack.direction ?? \"column\"),\n };\n if (stack.align) declarations[\"align-items\"] = literal(stack.align);\n if (stack.justify) declarations[\"justify-content\"] = literal(stack.justify);\n if (stack.wrap) declarations[\"flex-wrap\"] = literal(stack.wrap);\n if (stack.gap) declarations[\"gap\"] = spacingRef(stack.gap);\n\n const overrides: RuleSetOverride[] = [];\n for (const entry of stack.responsive ?? []) {\n const respDecls: Record<string, Ref> = {};\n if (entry.inline !== undefined) respDecls[\"display\"] = literal(entry.inline ? \"inline-flex\" : \"flex\");\n if (entry.direction) respDecls[\"flex-direction\"] = literal(entry.direction);\n if (entry.align) respDecls[\"align-items\"] = literal(entry.align);\n if (entry.justify) respDecls[\"justify-content\"] = literal(entry.justify);\n if (entry.wrap) respDecls[\"flex-wrap\"] = literal(entry.wrap);\n if (Object.keys(respDecls).length) {\n overrides.push({ breakpoint: entry.breakpoint, query: entry.query ?? \"exact\", declarations: respDecls });\n }\n }\n group[`stack-${name}`] = { kind: \"recipe\", declarations, overrides };\n }\n\n return { ruleSetGroups: { stacks: group }, configProperties: {} };\n};\n\n// ---------------------------------------------------------------------------\n// Container — `kind: \"recipe\"`; always emits a default container (matches the old generator)\n// ---------------------------------------------------------------------------\n\nconst resolveContainerConfig = (raw: unknown): ContainerConfig => {\n if (!raw || typeof raw === \"string\") return { mode: (raw as string) ?? \"fixed\" };\n const obj = raw as Record<string, unknown>;\n return {\n mode: (obj.base as string) ?? \"fixed\",\n inset: obj.inset as string | undefined,\n gutter: obj.gutter as string | undefined,\n direction: obj.direction as string | undefined,\n align: obj.align as string | undefined,\n justify: obj.justify as string | undefined,\n maxWidth: obj.maxWidth as string | number | undefined,\n };\n};\n\n/**\n * Container rule-sets + config tokens. Emitted in **processing order** (base first, then each\n * variant); the adapter's `lowerContainerGroup` reverses for bases and keeps medias forward, which\n * reproduces the old generator's `unshift`(bases)/`push`(medias) node stream byte-for-byte.\n * Runs even with no `container` config (defaults to `\"fixed\"`) — the old generator did too.\n */\n/**\n * Resolve a **fluid** container's max-width cap (§22 D4). A string naming an authored `sizes` variant →\n * a unit-aware `layout.sizes.*` ref (the recommended path — flip the theme to rem and the cap follows);\n * a breakpoint name → that breakpoint's px width; any other string → a raw literal (`\"80rem\"`, `calc()`).\n * A bare **number** stays a `${n}px` literal — an intentional \"exactly this\" escape (reference a `sizes`\n * token for unit-awareness). Size names win over breakpoint names on collision (a cap is a size concept).\n */\nconst resolveFluidMaxWidth = (\n value: string | number,\n sizeNames: ReadonlySet<string>,\n breakpoints: Record<string, number>,\n): Ref => {\n if (typeof value === \"number\") return literal(`${value}px`);\n if (sizeNames.has(value)) return sizesRef(value);\n if (breakpoints[value] !== undefined) return literal(`${breakpoints[value]}px`);\n return literal(value);\n};\n\n/** The authored `sizes` variant names (plus `base`) — for disambiguating a fluid container cap (§22 D4). */\nconst collectSizeNames = (sizes: unknown): Set<string> => {\n const names = new Set<string>();\n if (sizes && typeof sizes === \"object\" && !Array.isArray(sizes)) {\n const obj = sizes as Record<string, unknown>;\n if (\"base\" in obj) names.add(\"base\");\n const variants = obj.variants as Record<string, unknown> | undefined;\n if (variants && typeof variants === \"object\") for (const k of Object.keys(variants)) names.add(k);\n }\n return names;\n};\n\nexport const buildContainer = (\n containerInput: unknown,\n breakpoints: Record<string, number>,\n sizeNames: ReadonlySet<string> = new Set(),\n mediaConfig?: MediaConfig,\n): LayoutStructuralOutput => {\n // Fixed-container max-widths are breakpoint-DERIVED, so they format in the same px/em/rem unit the\n // `@media` thresholds use (§10.5) — NOT the §21 declaration-`units` axis. `formatWidth` is the shared\n // threshold formatter, so a fixed container stays aligned with where its breakpoints fire.\n const resolvedMedia = resolveMediaConfig(mediaConfig);\n const mediaLen = (value: number): string => formatWidth(value, resolvedMedia);\n const configProperties: Record<string, PropertyModel> = {};\n const group: RuleSetGroup = {};\n const sortedKeys = sortByWidth(breakpoints);\n\n const extended =\n containerInput && typeof containerInput === \"object\"\n ? (containerInput as Record<string, unknown>)\n : undefined;\n\n const baseConfig: ContainerConfig = extended\n ? {\n mode: (extended.base as string) ?? \"fixed\",\n inset: extended.inset as string | undefined,\n gutter: extended.gutter as string | undefined,\n direction: extended.direction as string | undefined,\n align: extended.align as string | undefined,\n justify: extended.justify as string | undefined,\n maxWidth: extended.maxWidth as string | number | undefined,\n }\n : resolveContainerConfig(containerInput ?? \"fixed\");\n const variants = (extended?.variants as Record<string, unknown>) ?? {};\n const responsiveEntries = (extended?.responsive as Array<Record<string, unknown>>) ?? [];\n\n const variantKeyFor = (name: string | null): string =>\n name ? `container-${name}` : \"container\";\n\n const buildSingleContainer = (name: string | null, config: ContainerConfig): void => {\n const suffix = name ? `--${name}` : \"\";\n const insetKey = `container${suffix}--inset`;\n const gutterKey = `container${suffix}--gutter`;\n\n const insetRef = config.inset ?? baseConfig.inset ?? \"base\";\n const gutterRef = config.gutter ?? baseConfig.gutter;\n const mode = config.mode ?? baseConfig.mode ?? \"fixed\";\n const direction = config.direction ?? baseConfig.direction;\n const align = config.align ?? baseConfig.align;\n const justify = config.justify ?? baseConfig.justify;\n const maxWidthValue = config.maxWidth ?? (name ? baseConfig.maxWidth : undefined);\n\n configProperties[insetKey] = { base: spacingRef(insetRef) };\n if (gutterRef) configProperties[gutterKey] = { base: guttersRef(gutterRef) };\n\n const declarations: Record<string, Ref> = {\n \"box-sizing\": literal(\"border-box\"),\n width: literal(\"100%\"),\n \"margin-left\": literal(\"auto\"),\n \"margin-right\": literal(\"auto\"),\n \"padding-left\": configRef(insetKey),\n \"padding-right\": configRef(insetKey),\n };\n if (gutterRef) declarations[\"gap\"] = configRef(gutterKey);\n if (direction) {\n declarations[\"display\"] = literal(\"flex\");\n declarations[\"flex-direction\"] = literal(direction);\n }\n if (align) declarations[\"align-items\"] = literal(align);\n if (justify) declarations[\"justify-content\"] = literal(justify);\n\n const overrides: RuleSetOverride[] = [];\n if (mode === \"fixed\") {\n const maxBp =\n typeof maxWidthValue === \"string\" && breakpoints[maxWidthValue] !== undefined\n ? maxWidthValue\n : undefined;\n const maxBpIndex = maxBp ? sortedKeys.indexOf(maxBp) : -1;\n\n for (let i = 0; i < sortedKeys.length; i++) {\n const key = sortedKeys[i];\n const refKey = maxBpIndex >= 0 && i > maxBpIndex ? maxBp! : key;\n const width = breakpoints[refKey];\n if (width === 0) {\n if (i === 0) declarations[\"max-width\"] = literal(\"none\");\n continue;\n }\n if (i === 0) {\n declarations[\"max-width\"] = literal(mediaLen(width));\n } else {\n overrides.push({ breakpoint: key, query: \"min\", declarations: { \"max-width\": literal(mediaLen(width)) } });\n }\n }\n } else if (mode === \"fluid\") {\n if (maxWidthValue !== undefined) {\n declarations[\"max-width\"] = resolveFluidMaxWidth(maxWidthValue, sizeNames, breakpoints);\n }\n } else {\n declarations[\"max-width\"] = literal(typeof mode === \"number\" ? `${mode}px` : mode);\n }\n\n group[variantKeyFor(name)] = { kind: \"recipe\", declarations, overrides };\n };\n\n buildSingleContainer(null, baseConfig);\n for (const [name, raw] of Object.entries(variants)) {\n buildSingleContainer(name, resolveContainerConfig(raw));\n }\n\n // Top-level responsive entries layer media overrides onto the base/target container.\n // (Not exercised by the current fixtures; kept for parity with the old generator.)\n for (const entry of responsiveEntries) {\n const target = entry.target as string | undefined;\n const variantKey = variantKeyFor(target ?? null);\n const ruleSet = group[variantKey];\n if (!ruleSet) continue;\n\n const declarations: Record<string, Ref> = {};\n if (entry.direction) declarations[\"flex-direction\"] = literal(entry.direction as string);\n if (entry.align) declarations[\"align-items\"] = literal(entry.align as string);\n if (entry.justify) declarations[\"justify-content\"] = literal(entry.justify as string);\n if (entry.inset) {\n const insetKey = target ? `container--${target}--inset` : \"container--inset\";\n declarations[\"padding-left\"] = configRef(insetKey);\n declarations[\"padding-right\"] = configRef(insetKey);\n }\n if (entry.gutter) {\n const gutterKey = target ? `container--${target}--gutter` : \"container--gutter\";\n declarations[\"gap\"] = configRef(gutterKey);\n }\n if (Object.keys(declarations).length) {\n ruleSet.overrides.push({\n breakpoint: entry.breakpoint as string,\n query: (entry.query as \"min\" | \"max\" | \"exact\") ?? \"exact\",\n declarations,\n });\n }\n }\n\n return { ruleSetGroups: { container: group }, configProperties };\n};\n\n// ---------------------------------------------------------------------------\n// Orchestration\n// ---------------------------------------------------------------------------\n\n/**\n * Run all four structural generators over the raw layout slice, merging their rule-set groups\n * (structural order: columns → grids → stacks → container) and config tokens. Container always\n * runs; the rest run only when their raw key is present.\n */\nexport const buildLayoutStructural = (\n rawSlice: Record<string, unknown>,\n breakpoints: Record<string, number>,\n mediaConfig?: MediaConfig,\n): LayoutStructuralOutput => {\n const ruleSetGroups: Record<string, RuleSetGroup> = {};\n const configProperties: Record<string, PropertyModel> = {};\n\n const merge = (out: LayoutStructuralOutput | undefined): void => {\n if (!out) return;\n Object.assign(ruleSetGroups, out.ruleSetGroups);\n Object.assign(configProperties, out.configProperties);\n };\n\n merge(buildColumns(rawSlice.columns as ColumnsValue | undefined, breakpoints));\n merge(buildGrids(rawSlice.grids as GridsDefinition | undefined));\n merge(buildStacks(rawSlice.stacks as StacksDefinition | undefined));\n merge(buildContainer(rawSlice.container, breakpoints, collectSizeNames(rawSlice.sizes), mediaConfig));\n\n return { ruleSetGroups, configProperties };\n};\n","/**\n * The layout subsystem — the biggest one, with three parts:\n * 1. Regular property tokens (`spacing` / `gutters` / `aspectRatio`) — like typography/effects,\n * plus the forced `none` variant on spacing/gutters (`finalizeLayoutNormalization`).\n * 2. Recipes (`padding` / `section`) — ordinary token-path recipes (`interpretRecipe`).\n * 3. Structural generators (`columns` / `grids` / `stacks` / `container`) — emitted as native\n * Model rule-sets via the `buildStructural` hook (see `structural.ts`), with the columns/\n * container config knobs riding along as `configProperties` (Model `extraProperties`).\n *\n * It grows the spine's hooks (`interpretRecipe`, `buildStructural`), never the spine's control flow.\n */\n\nimport type { Subsystem, NormalizedProperties } from \"../../core/subsystem\";\nimport type { NormalizedPropertyValue, NormalizedRecipeVariant } from \"../../core/normalize\";\nimport {\n normalizePropertyValue,\n validateNormalizedResponsiveRefs,\n} from \"../../core/normalize\";\nimport type { LayoutRecipeProps } from \"./types\";\nimport { LAYOUT_PROPERTY_KEYS } from \"./types\";\nimport { finalizeLayoutNormalization, scaleStep } from \"./normalize\";\nimport { interpretLayoutRecipeVariant } from \"./recipes\";\nimport { buildLayoutStructural } from \"./structural\";\n\n/** The \"regular\" property keys layout normalizes (the rest are structural / recipes). */\nconst PROPERTY_KEYS: ReadonlySet<string> = new Set(LAYOUT_PROPERTY_KEYS);\n\nexport const layoutSubsystem: Subsystem = {\n key: \"layout\",\n // §10.6 numeric scale synthesis: the fn its synthesized spacing/gutters/sizes steps derive through,\n // so `override()` of a base re-resolves the ramp (mirror colors' `darken`/`lighten`).\n derivations: {\n scaleStep: (value, arg) => scaleStep(value, arg),\n },\n normalizeProperties(rawSlice, ctx): NormalizedProperties {\n const out: NormalizedProperties = {};\n if (!rawSlice) return out;\n\n for (const name of LAYOUT_PROPERTY_KEYS) {\n const value = rawSlice[name];\n if (value === undefined || !PROPERTY_KEYS.has(name)) continue;\n\n const normalized = normalizePropertyValue<unknown, Record<string, unknown>>(value as never, {\n propertyPath: `layout.${name}`,\n allowedBreakpoints: ctx.allowedBreakpoints,\n });\n const finalized = finalizeLayoutNormalization(name, normalized as NormalizedPropertyValue<unknown>);\n validateNormalizedResponsiveRefs(finalized, { propertyPath: `layout.${name}` });\n\n out[name] = finalized as NormalizedPropertyValue<unknown, Record<string, unknown>>;\n }\n\n return out;\n },\n interpretRecipe(variantName, variant, ctx) {\n return interpretLayoutRecipeVariant(\n variantName,\n variant as NormalizedRecipeVariant<LayoutRecipeProps, string>,\n ctx,\n );\n },\n buildStructural(rawSlice, ctx) {\n return buildLayoutStructural(rawSlice, ctx.breakpoints, ctx.mediaConfig);\n },\n};\n\nexport type { LayoutRaw, ContainerRaw, ContainerVariantRaw } from \"./types\";\n","/**\n * Effects' `interpretRecipe` hook â resolves recipe declarations to token-path Refs.\n *\n * An effects recipe prop names a **variant** of the matching property, but the recipe key\n * differs from the token key (`boxShadow` â `shadow`, `transition` â `transitions`) â the\n * resolve-key map bridges them. Each declaration lowers to a format-neutral {@link Ref}\n * carrying the canonical token path (`effects.shadow.lg`, `effects.shadow` for the base) â\n * **no `var(--â¦)` strings**; the CSS adapter maps the path to a `var(--â¦)` at render time.\n *\n * The `blur` compound is the notable reshape: the old `effects/recipes.ts` baked\n * `filter: blur(var(--â¦))` as a `{ value }` literal that **embedded** `var()` â not format-\n * neutral. Here it emits `{ ref: \"effects.blur\", wrap: \"blur\" }`; the adapter's `refToStyleValue`\n * renders `ref.wrap` â `blur(var(--â¦))`, so the wrap lives in the adapter, not the Model.\n */\nimport type { InterpretedRecipeVariant, InterpretedRecipeOverride, Ref } from \"../../core/model\";\nimport type { NormalizedRecipeVariant } from \"../../core/normalize\";\nimport type { RecipeInterpretContext } from \"../../core/subsystem\";\nimport type { EffectsRecipeProps } from \"./types\";\n\nconst RESERVED_KEYS: ReadonlySet<string> = new Set([\n \"breakpoint\",\n \"query\",\n \"state\",\n \"variant\",\n \"target\",\n \"orientation\",\n]);\n\n/** Recipe prop key â CSS declaration property name. `blur` â `filter` (rendered via a wrap). */\nconst PROPERTY_CSS_MAP: Record<string, string> = {\n boxShadow: \"box-shadow\",\n opacity: \"opacity\",\n blur: \"filter\",\n transition: \"transition\",\n zIndex: \"z-index\",\n};\n\n/** Recipe prop key â the effects **property name** (token key) it references. */\nconst RESOLVE_KEY_MAP: Record<string, string> = {\n boxShadow: \"shadow\",\n opacity: \"opacity\",\n blur: \"blur\",\n transition: \"transitions\",\n zIndex: \"zIndex\",\n};\n\n/**\n * Interpret one effects recipe variant into base + responsive/state override declarations,\n * each a token-path {@link Ref}. A responsive `variant:` swap inherits the sibling's base\n * declarations (via `ctx.resolveRecipeVariant`).\n */\nexport const interpretEffectsRecipeVariant = (\n variantName: string,\n variant: NormalizedRecipeVariant<EffectsRecipeProps, string>,\n ctx: RecipeInterpretContext,\n): InterpretedRecipeVariant<string> => {\n const base = interpretProps(variant.base);\n\n const responsive: InterpretedRecipeOverride<string>[] = variant.responsive.map(entry => {\n const { breakpoint, query, state, variant: swap, target, orientation, container, size, ...rawDecls } =\n entry as EffectsRecipeProps & {\n breakpoint?: string;\n query?: \"min\" | \"max\" | \"exact\";\n state?: string;\n variant?: string;\n target?: string;\n orientation?: \"landscape\" | \"portrait\";\n container?: string;\n size?: string;\n };\n\n const inherited = swap ? { ...ctx.resolveRecipeVariant(swap).base } : {};\n const overrides = interpretProps(rawDecls as EffectsRecipeProps);\n\n const override: InterpretedRecipeOverride<string> = {\n declarations: { ...inherited, ...overrides },\n };\n if (breakpoint) {\n override.breakpoint = breakpoint;\n override.query = query ?? \"exact\";\n }\n if (container) {\n override.container = container;\n if (size) override.size = size;\n override.query = query ?? \"min\";\n }\n if (state) override.state = state;\n if (target) override.target = target; // dec.8 — scope onto the `<item>-<target>` sibling\n if (orientation) override.orientation = orientation;\n return override;\n });\n\n return { base, responsive };\n};\n\n/** Interpret a flat declaration block â `cssProperty â Ref`, skipping empty / unknown keys. */\nconst interpretProps = (props: EffectsRecipeProps | undefined): Record<string, Ref> => {\n const declarations: Record<string, Ref> = {};\n if (!props) return declarations;\n\n for (const [key, value] of Object.entries(props)) {\n if (!value || RESERVED_KEYS.has(key)) continue;\n const cssProperty = PROPERTY_CSS_MAP[key];\n const propertyName = RESOLVE_KEY_MAP[key];\n if (!cssProperty || !propertyName) continue;\n\n const ref: Ref = { ref: variantPath(propertyName, value) };\n // The `blur` compound renders as `filter: blur(var(--â¦))` â carried as an adapter wrap,\n // never an embedded `var()` literal (the format-neutrality constraint).\n if (key === \"blur\") ref.wrap = \"blur\";\n declarations[cssProperty] = ref;\n }\n\n return declarations;\n};\n\n/** The token path for a property variant: `effects.<name>` for `\"base\"`, else `effects.<name>.<variant>`. */\nconst variantPath = (propertyName: string, variant: string): string =>\n variant === \"base\" ? `effects.${propertyName}` : `effects.${propertyName}.${variant}`;\n","/**\n * Effects value coercion (§15) — parse/validate authored shadow / transition leaves into the\n * canonical, **format-neutral** Model form.\n *\n * Modeled on `colors/utils.ts`: a single boundary that runs at normalize time (via the subsystem's\n * `coerceValue`) and turns the ergonomic authoring shapes — a flat single leaf or an array of leaves\n * — into ONE canonical representation the Model carries on `Ref.struct`:\n *\n * - **shadow** → {@link ShadowLayer}`[]` (always an array, even single-layer); `color` kept as its\n * `colors.*` token-path string (never an embedded `rgba()` — §15.1), resolved late by the adapter.\n * A translucent shadow references a translucent colour (an `alpha` colour variant — §13.3).\n * - **transitions** → {@link TransitionPart}`[]`; `duration`/`delay` in ms.\n *\n * **Structured-only (§15.2, amended 2026-07-16):** raw CSS strings are REJECTED — the ONLY accepted\n * string is the keyword `\"none\"` (no shadow / no transition). Every other string throws a path-labelled\n * error. Serialization to CSS text stays in the adapter; this module holds structure, not format. Its\n * only core dependency is the shared length parser (`parseLength`, §21) — so a pinned geometry string\n * (`offsetY: \"1px\"`) is parsed by the same grammar every length uses, rather than a duplicate here.\n */\n\nimport { RefractError } from \"../../core/errors\";\nimport type { ShadowLayer, TransitionPart } from \"../../core/model\";\nimport { parseLength, type ShadowDimension } from \"../../core/units\";\n\n/** A single authored shadow layer (flat leaf object) — geometry as a bare number (deferred, resolved by\n * the §21 unit pass) or a pinned length string (`\"1px\"`, `\"0.5rem\"`) + a `colors.*` color ref\n * (translucency comes from an `alpha` colour variant, not a shadow field). */\nexport type ShadowLayerInput = {\n offsetX?: number | string;\n offsetY?: number | string;\n blur?: number | string;\n spread?: number | string;\n color?: string;\n inset?: boolean;\n};\n\n/** An authored shadow value: a flat single layer, an array of layers, or the `\"none\"` keyword. */\nexport type ShadowInput = \"none\" | ShadowLayerInput | ShadowLayerInput[];\n\n/** A single authored transition part — `property` (required) + ms durations + timing keyword. */\nexport type TransitionPartInput = {\n property?: string;\n duration?: number;\n timingFunction?: string;\n delay?: number;\n};\n\n/** An authored transition value: a flat single part, an array of parts, or the `\"none\"` keyword. */\nexport type TransitionInput = \"none\" | TransitionPartInput | TransitionPartInput[];\n\n/** The canonical Model form of a shadow value — an array of layers, or the `\"none\"` keyword. */\nexport type ShadowCanonical = \"none\" | ShadowLayer[];\n\n/** The canonical Model form of a transition value — an array of parts, or the `\"none\"` keyword. */\nexport type TransitionCanonical = \"none\" | TransitionPart[];\n\nconst isPlainObject = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null && !Array.isArray(value);\n\n/** Assert a leaf field is a number (or absent), with a path-labelled friendly error. */\nconst numberField = (value: unknown, label: string): number | undefined => {\n if (value === undefined) return undefined;\n if (typeof value !== \"number\" || Number.isNaN(value)) {\n throw new RefractError(\"REFRACT_E_EFFECTS\", `${label} must be a number, received ${JSON.stringify(value)}.`);\n }\n return value;\n};\n\n/**\n * A shadow-geometry length field (§21/§22) — a bare number stays **deferred** (the unit pass resolves\n * it against the `effects.shadow` role); a `<number><unit>` string is **pinned** (`\"1px\"` → `{value,unit}`,\n * trusted verbatim). A bare numeric string is deferred. Functions/keywords (no unit grammar) throw.\n */\nconst dimensionField = (value: unknown, label: string): ShadowDimension | undefined => {\n if (value === undefined) return undefined;\n if (typeof value === \"number\") {\n if (Number.isNaN(value)) throw new RefractError(\"REFRACT_E_EFFECTS\", `${label} must be a number or length string, received ${JSON.stringify(value)}.`);\n return value;\n }\n if (typeof value === \"string\") {\n const parsed = parseLength(value);\n if (\"raw\" in parsed) {\n throw new RefractError(\"REFRACT_E_EFFECTS\", `${label} must be a number or a <number><unit> length (received ${JSON.stringify(value)}).`);\n }\n return parsed.unit === undefined ? parsed.value : { value: parsed.value, unit: parsed.unit };\n }\n throw new RefractError(\"REFRACT_E_EFFECTS\", `${label} must be a number or length string, received ${JSON.stringify(value)}.`);\n};\n\n// ---------------------------------------------------------------------------\n// Shadow\n// ---------------------------------------------------------------------------\n\nconst SHADOW_FIELDS: ReadonlySet<string> = new Set([\n \"offsetX\",\n \"offsetY\",\n \"blur\",\n \"spread\",\n \"color\",\n \"inset\",\n]);\n\n/** Validate + normalize one authored shadow layer into a canonical {@link ShadowLayer}. */\nconst coerceShadowLayer = (layer: ShadowLayerInput, label: string): ShadowLayer => {\n if (!isPlainObject(layer)) {\n throw new RefractError(\"REFRACT_E_EFFECTS\", `${label} must be a shadow-layer object, received ${JSON.stringify(layer)}.`);\n }\n for (const key of Object.keys(layer)) {\n if (!SHADOW_FIELDS.has(key)) {\n throw new RefractError(\n \"REFRACT_E_EFFECTS\",\n `${label} has unknown shadow field \"${key}\" (allowed: ${[...SHADOW_FIELDS].join(\", \")}).`,\n );\n }\n }\n\n const out: ShadowLayer = {};\n const offsetX = dimensionField(layer.offsetX, `${label}.offsetX`);\n const offsetY = dimensionField(layer.offsetY, `${label}.offsetY`);\n const blur = dimensionField(layer.blur, `${label}.blur`);\n const spread = dimensionField(layer.spread, `${label}.spread`);\n if (offsetX !== undefined) out.offsetX = offsetX;\n if (offsetY !== undefined) out.offsetY = offsetY;\n if (blur !== undefined) out.blur = blur;\n if (spread !== undefined) out.spread = spread;\n if (layer.color !== undefined) {\n if (typeof layer.color !== \"string\" || !layer.color) {\n throw new RefractError(\"REFRACT_E_EFFECTS\", `${label}.color must be a \"colors.*\" token-path string.`);\n }\n out.color = layer.color;\n }\n if (layer.inset !== undefined) {\n if (typeof layer.inset !== \"boolean\") {\n throw new RefractError(\"REFRACT_E_EFFECTS\", `${label}.inset must be a boolean.`);\n }\n if (layer.inset) out.inset = true;\n }\n return out;\n};\n\n/**\n * Coerce an authored shadow value into its canonical Model form. A string passes through (escape\n * hatch); a flat leaf becomes a one-element `ShadowLayer[]`; an array becomes a multi-layer\n * `ShadowLayer[]`. `label` is the property path for friendly errors.\n */\nexport const coerceShadowValue = (input: ShadowInput, label = \"effects.shadow\"): ShadowCanonical => {\n if (typeof input === \"string\") {\n if (input === \"none\") return \"none\";\n throw new RefractError(\n \"REFRACT_E_EFFECTS\",\n `${label} must be structured shadow layer(s) or \"none\" — raw CSS strings are not accepted (received ${JSON.stringify(input)}).`,\n );\n }\n if (Array.isArray(input)) {\n if (!input.length) throw new RefractError(\"REFRACT_E_EFFECTS\", `${label} is an empty shadow-layer array.`);\n return input.map((layer, i) => coerceShadowLayer(layer, `${label}[${i}]`));\n }\n return [coerceShadowLayer(input, label)];\n};\n\n// ---------------------------------------------------------------------------\n// Transitions\n// ---------------------------------------------------------------------------\n\nconst TRANSITION_FIELDS: ReadonlySet<string> = new Set([\n \"property\",\n \"duration\",\n \"timingFunction\",\n \"delay\",\n]);\n\n/** Validate + normalize one authored transition part into a canonical {@link TransitionPart}. */\nconst coerceTransitionPart = (part: TransitionPartInput, label: string): TransitionPart => {\n if (!isPlainObject(part)) {\n throw new RefractError(\"REFRACT_E_EFFECTS\", `${label} must be a transition-part object, received ${JSON.stringify(part)}.`);\n }\n for (const key of Object.keys(part)) {\n if (!TRANSITION_FIELDS.has(key)) {\n throw new RefractError(\n \"REFRACT_E_EFFECTS\",\n `${label} has unknown transition field \"${key}\" (allowed: ${[...TRANSITION_FIELDS].join(\", \")}).`,\n );\n }\n }\n if (typeof part.property !== \"string\" || !part.property) {\n throw new RefractError(\"REFRACT_E_EFFECTS\", `${label}.property is required (the CSS property to transition).`);\n }\n\n const out: TransitionPart = { property: part.property };\n const duration = numberField(part.duration, `${label}.duration`);\n const delay = numberField(part.delay, `${label}.delay`);\n if (duration !== undefined) out.duration = duration;\n if (part.timingFunction !== undefined) {\n if (typeof part.timingFunction !== \"string\" || !part.timingFunction) {\n throw new RefractError(\"REFRACT_E_EFFECTS\", `${label}.timingFunction must be a keyword or cubic-bezier(...) string.`);\n }\n out.timingFunction = part.timingFunction;\n }\n if (delay !== undefined) out.delay = delay;\n return out;\n};\n\n/**\n * Coerce an authored transition value into its canonical Model form. A string passes through; a flat\n * part becomes a one-element `TransitionPart[]`; an array becomes a multi-part `TransitionPart[]`.\n */\nexport const coerceTransitionValue = (\n input: TransitionInput,\n label = \"effects.transitions\",\n): TransitionCanonical => {\n if (typeof input === \"string\") {\n if (input === \"none\") return \"none\";\n throw new RefractError(\n \"REFRACT_E_EFFECTS\",\n `${label} must be structured transition part(s) or \"none\" — raw CSS strings are not accepted (received ${JSON.stringify(input)}).`,\n );\n }\n if (Array.isArray(input)) {\n if (!input.length) throw new RefractError(\"REFRACT_E_EFFECTS\", `${label} is an empty transition-part array.`);\n return input.map((part, i) => coerceTransitionPart(part, `${label}[${i}]`));\n }\n return [coerceTransitionPart(input, label)];\n};\n","/**\n * The effects subsystem — a \"regular\" subsystem with no property finalize hook (values\n * pass straight through the shared normalize). Iterates `raw.effects` (skipping the\n * reserved `recipes` key) and interprets recipes into token-path refs (incl. the `blur`\n * compound as a `{ ref, wrap: \"blur\" }` ref). It grows a hook, never the spine.\n */\n\nimport type { Subsystem, NormalizedProperties } from \"../../core/subsystem\";\nimport type { NormalizedPropertyValue, NormalizedRecipeVariant } from \"../../core/normalize\";\nimport {\n normalizePropertyValue,\n validateNormalizedResponsiveRefs,\n} from \"../../core/normalize\";\nimport type { EffectsRecipeProps } from \"./types\";\nimport { interpretEffectsRecipeVariant } from \"./recipes\";\nimport { coerceShadowValue, coerceTransitionValue } from \"./utils\";\nimport type { ShadowInput, TransitionInput } from \"./utils\";\n\n/** Sub-keys of `raw.effects` that are not properties. */\nconst RESERVED_KEYS: ReadonlySet<string> = new Set([\"recipes\"]);\n\n/**\n * §15 object-leaf properties: the value-field set the core assembles into the base (vs `TExtra`\n * siblings), plus a per-property `coerceValue` that canonicalizes each leaf into the Model's\n * structured form (or passes a raw string through). Scalar properties (blur/opacity/zIndex) appear\n * here NOT at all → they take the plain primitive path (no `leafFields`, no coerce).\n */\nconst SHADOW_LEAF_FIELDS = [\"offsetX\", \"offsetY\", \"blur\", \"spread\", \"color\", \"inset\"] as const;\nconst TRANSITION_LEAF_FIELDS = [\"property\", \"duration\", \"timingFunction\", \"delay\"] as const;\n\nconst LEAF_FIELDS: Record<string, readonly string[]> = {\n shadow: SHADOW_LEAF_FIELDS,\n transitions: TRANSITION_LEAF_FIELDS,\n};\n\n/** Per-property value coercion (§15). A property absent here is a plain scalar (no coercion). */\nconst coerceFor = (name: string): ((value: unknown) => unknown) | undefined => {\n if (name === \"shadow\") return value => coerceShadowValue(value as ShadowInput, `effects.${name}`);\n if (name === \"transitions\") return value => coerceTransitionValue(value as TransitionInput, `effects.${name}`);\n return undefined;\n};\n\nexport const effectsSubsystem: Subsystem = {\n key: \"effects\",\n normalizeProperties(rawSlice, ctx): NormalizedProperties {\n const out: NormalizedProperties = {};\n if (!rawSlice) return out;\n\n for (const [name, value] of Object.entries(rawSlice)) {\n if (RESERVED_KEYS.has(name)) continue;\n\n const leafFields = LEAF_FIELDS[name];\n const coerceValue = coerceFor(name);\n const normalized = normalizePropertyValue<unknown>(value as never, {\n propertyPath: `effects.${name}`,\n allowedBreakpoints: ctx.allowedBreakpoints,\n ...(leafFields ? { leafFields } : {}),\n ...(coerceValue ? { coerceValue } : {}),\n // §15.2 (amended): no `base` key — a property with only variants/modes (no top-level leaves)\n // has an implicit `\"none\"` base (the coerce keyword), instead of failing base resolution.\n ...(leafFields ? { fallbackBase: \"none\" } : {}),\n });\n validateNormalizedResponsiveRefs(normalized, { propertyPath: `effects.${name}` });\n\n out[name] = normalized as NormalizedPropertyValue<unknown, Record<string, unknown>>;\n }\n\n return out;\n },\n interpretRecipe(variantName, variant, ctx) {\n return interpretEffectsRecipeVariant(\n variantName,\n variant as NormalizedRecipeVariant<EffectsRecipeProps, string>,\n ctx,\n );\n },\n};\n\nexport type { EffectsRaw, EffectsPropertyValue } from \"./types\";\n","/**\n * Borders' `interpretRecipe` hook (§14.2) — resolves recipe declarations to token-path Refs.\n *\n * The novel logic vs a fixed prop→css map: the CSS property is **computed** from\n * `(as, side, aspect)`. `as` (the render target, default `\"border\"`) + the optional per-side\n * modifier route each geometry aspect to its longhand:\n * - `border` + `left` + `width` → `border-left-width`\n * - `outline` + `width` → `outline-width`\n * - `border` + `radius` → `border-radius` (radius is border-only edge geometry)\n * - `outline` + `offset` → `outline-offset` (offset is outline-only)\n * - `outline` + `color` → `outline-color`\n *\n * Geometry aspects (`width`/`style`/`offset`/`radius`) name a **variant** of the matching borders\n * property by bare name — lowered to a `borders.<aspect>[.<variant>]` {@link Ref}. `color` is the\n * value-level exception (§14.4): its value is already a `colors.*` **token** path, passed straight\n * through as `{ ref: \"colors.*\" }` — the CSS adapter resolves it against the global path→var map\n * (colors is processed first). No `var(--…)` strings — the adapter maps paths to vars at render.\n */\nimport type { InterpretedRecipeVariant, InterpretedRecipeOverride, Ref } from \"../../core/model\";\nimport type { NormalizedRecipeVariant } from \"../../core/normalize\";\nimport type { RecipeInterpretContext } from \"../../core/subsystem\";\nimport type { BordersRecipeProps } from \"./types\";\n\nconst RESERVED_KEYS: ReadonlySet<string> = new Set([\n \"breakpoint\",\n \"query\",\n \"state\",\n \"variant\",\n \"target\",\n \"orientation\",\n \"container\",\n \"size\",\n]);\n\n/** The recipe modifiers (not geometry aspects) — stripped before interpreting declarations. */\nconst MODIFIER_KEYS: ReadonlySet<string> = new Set([\"as\", \"side\"]);\n\n/** The geometry aspects a borders recipe can declare (plus the value-level `color`). */\nconst ASPECT_KEYS: ReadonlySet<string> = new Set([\"width\", \"style\", \"offset\", \"radius\", \"color\"]);\n\ntype RenderTarget = \"border\" | \"outline\";\ntype Side = \"top\" | \"right\" | \"bottom\" | \"left\";\n\n/**\n * Compute the CSS declaration property for one aspect from the render target + side (§14.2).\n * `radius` is always `border-radius` (border-only edge geometry); `offset` is always\n * `outline-offset` (outline-only). The rest fan out per `(as, side)`.\n */\nconst cssPropertyFor = (as: RenderTarget, side: Side | undefined, aspect: string): string => {\n if (aspect === \"radius\") return \"border-radius\";\n if (aspect === \"offset\") return \"outline-offset\";\n if (as === \"outline\") return `outline-${aspect}`;\n return side ? `border-${side}-${aspect}` : `border-${aspect}`;\n};\n\n/** The token-path Ref for one aspect value: a `colors.*` passthrough for `color`, else a borders variant path. */\nconst refFor = (aspect: string, value: string): Ref => {\n if (aspect === \"color\") return { ref: value }; // value is already a `colors.*` token path\n return { ref: value === \"base\" ? `borders.${aspect}` : `borders.${aspect}.${value}` };\n};\n\n/** Interpret a flat declaration block → `cssProperty → Ref`, given the variant's `as`/`side` modifiers. */\nconst interpretProps = (\n props: BordersRecipeProps | undefined,\n as: RenderTarget,\n side: Side | undefined,\n): Record<string, Ref> => {\n const declarations: Record<string, Ref> = {};\n if (!props) return declarations;\n\n for (const [key, value] of Object.entries(props)) {\n if (!value || RESERVED_KEYS.has(key) || MODIFIER_KEYS.has(key) || !ASPECT_KEYS.has(key)) continue;\n declarations[cssPropertyFor(as, side, key)] = refFor(key, value);\n }\n\n return declarations;\n};\n\n/**\n * Interpret one borders recipe variant into base + responsive/state override declarations, each a\n * token-path {@link Ref}. `as`/`side` are read from the variant base (the render target is a\n * variant-level identity); a responsive entry may override them, else it inherits the base's. A\n * responsive `variant:` swap inherits the sibling's already-interpreted base declarations.\n */\nexport const interpretBordersRecipeVariant = (\n variantName: string,\n variant: NormalizedRecipeVariant<BordersRecipeProps, string>,\n ctx: RecipeInterpretContext,\n): InterpretedRecipeVariant<string> => {\n const baseAs = (variant.base.as as RenderTarget) ?? \"border\";\n const baseSide = variant.base.side as Side | undefined;\n const base = interpretProps(variant.base, baseAs, baseSide);\n\n const responsive: InterpretedRecipeOverride<string>[] = variant.responsive.map(entry => {\n const {\n breakpoint,\n query,\n state,\n variant: swap,\n target,\n orientation,\n container,\n size,\n as: entryAs,\n side: entrySide,\n ...rawDecls\n } = entry as BordersRecipeProps & {\n breakpoint?: string;\n query?: \"min\" | \"max\" | \"exact\";\n state?: string;\n variant?: string;\n target?: string;\n orientation?: \"landscape\" | \"portrait\";\n container?: string;\n size?: string;\n };\n\n const as = (entryAs as RenderTarget) ?? baseAs;\n const side = (entrySide as Side | undefined) ?? baseSide;\n\n const inherited = swap ? { ...ctx.resolveRecipeVariant(swap).base } : {};\n const overrides = interpretProps(rawDecls as BordersRecipeProps, as, side);\n\n const override: InterpretedRecipeOverride<string> = {\n declarations: { ...inherited, ...overrides },\n };\n if (breakpoint) {\n override.breakpoint = breakpoint;\n override.query = query ?? \"exact\";\n }\n if (container) {\n override.container = container;\n if (size) override.size = size;\n override.query = query ?? \"min\";\n }\n if (state) override.state = state;\n if (orientation) override.orientation = orientation;\n if (target) override.target = target; // dec.8 — scope onto the `<item>-<target>` sibling\n return override;\n });\n\n return { base, responsive };\n};\n","/**\n * The borders subsystem (§14) — a \"regular\" subsystem (no property finalize hook; values pass\n * straight through the shared normalize) carved out of effects. Owns the stroke geometry\n * vocabulary (width / style / offset / radius) and interprets border/outline recipes via the\n * `(as, side, aspect)` → css-property computation, with `color` a value-level `colors.*` ref.\n * It grows a hook, never the spine.\n */\n\nimport type { Subsystem, NormalizedProperties } from \"../../core/subsystem\";\nimport type { NormalizedPropertyValue, NormalizedRecipeVariant } from \"../../core/normalize\";\nimport {\n normalizePropertyValue,\n validateNormalizedResponsiveRefs,\n} from \"../../core/normalize\";\nimport type { BordersRecipeProps } from \"./types\";\nimport { interpretBordersRecipeVariant } from \"./recipes\";\n\n/** Sub-keys of `raw.borders` that are not properties. */\nconst RESERVED_KEYS: ReadonlySet<string> = new Set([\"recipes\"]);\n\nexport const bordersSubsystem: Subsystem = {\n key: \"borders\",\n normalizeProperties(rawSlice, ctx): NormalizedProperties {\n const out: NormalizedProperties = {};\n if (!rawSlice) return out;\n\n for (const [name, value] of Object.entries(rawSlice)) {\n if (RESERVED_KEYS.has(name)) continue;\n\n const normalized = normalizePropertyValue<unknown>(value as never, {\n propertyPath: `borders.${name}`,\n allowedBreakpoints: ctx.allowedBreakpoints,\n });\n validateNormalizedResponsiveRefs(normalized, { propertyPath: `borders.${name}` });\n\n out[name] = normalized as NormalizedPropertyValue<unknown, Record<string, unknown>>;\n }\n\n return out;\n },\n interpretRecipe(variantName, variant, ctx) {\n return interpretBordersRecipeVariant(\n variantName,\n variant as NormalizedRecipeVariant<BordersRecipeProps, string>,\n ctx,\n );\n },\n};\n\nexport type { BordersRaw, BordersPropertyValue } from \"./types\";\n","/**\n * Animation's `interpretRecipe` hook (§10.2) â resolves an animation recipe variant into the\n * `animation-*` longhand {@link Ref}s the CSS adapter composes into an `animation:` shorthand.\n *\n * `duration`/`easing`/`delay` name a **variant** of the matching motion-token property (mirrors the\n * effects interpreter's variant-path resolution) â `animation.<prop>[.<variant>]` token-path refs.\n * `keyframes` names a keyframe â an `animation.keyframes.<name>` ref the adapter resolves to the bare\n * keyframe identifier. Remaining `animation-*` literals pass through as `{ value }`. No `var(--â¦)`\n * strings â the adapter maps paths to vars (and the keyframe ref to a name) at render time.\n */\nimport type { InterpretedRecipeVariant, InterpretedRecipeOverride, Ref } from \"../../core/model\";\nimport type { NormalizedRecipeVariant } from \"../../core/normalize\";\nimport type { RecipeInterpretContext } from \"../../core/subsystem\";\nimport type { AnimationRecipeProps } from \"./types\";\n\nconst RESERVED_KEYS: ReadonlySet<string> = new Set([\n \"breakpoint\",\n \"query\",\n \"state\",\n \"variant\",\n \"target\",\n \"orientation\",\n]);\n\n/** Recipe prop key â the `animation-*` longhand CSS property it contributes to the shorthand. */\nconst PROPERTY_CSS_MAP: Record<string, string> = {\n keyframes: \"animation-name\",\n duration: \"animation-duration\",\n easing: \"animation-timing-function\",\n delay: \"animation-delay\",\n iterationCount: \"animation-iteration-count\",\n direction: \"animation-direction\",\n fillMode: \"animation-fill-mode\",\n playState: \"animation-play-state\",\n};\n\n/** Recipe prop key â the motion-token **property name** whose variant it references. */\nconst RESOLVE_KEY_MAP: Record<string, string> = {\n duration: \"duration\",\n easing: \"easing\",\n delay: \"delay\",\n};\n\n/** The token path for a motion-token variant: `animation.<name>` for `\"base\"`, else `animation.<name>.<variant>`. */\nconst variantPath = (propertyName: string, variant: string): string =>\n variant === \"base\" ? `animation.${propertyName}` : `animation.${propertyName}.${variant}`;\n\n/** Interpret a flat animation-recipe declaration block â `animation-* â Ref`, skipping empty/unknown keys. */\nconst interpretProps = (props: AnimationRecipeProps | undefined): Record<string, Ref> => {\n const declarations: Record<string, Ref> = {};\n if (!props) return declarations;\n\n for (const [key, value] of Object.entries(props)) {\n if (value === undefined || value === \"\" || RESERVED_KEYS.has(key)) continue;\n const cssProperty = PROPERTY_CSS_MAP[key];\n if (!cssProperty) continue;\n\n if (key === \"keyframes\") {\n declarations[cssProperty] = { ref: `animation.keyframes.${value}` };\n } else if (RESOLVE_KEY_MAP[key]) {\n declarations[cssProperty] = { ref: variantPath(RESOLVE_KEY_MAP[key], String(value)) };\n } else {\n // Literal `animation-*` sub-property (iteration-count / direction / fill-mode / play-state).\n declarations[cssProperty] = { value: value as string | number };\n }\n }\n\n return declarations;\n};\n\n/**\n * Interpret one animation recipe variant into base + responsive/state override declarations, each an\n * `animation-*` longhand {@link Ref}. A responsive `variant:` swap inherits the sibling's base\n * declarations (via `ctx.resolveRecipeVariant`), exactly like the effects interpreter.\n */\nexport const interpretAnimationRecipeVariant = (\n variantName: string,\n variant: NormalizedRecipeVariant<AnimationRecipeProps, string>,\n ctx: RecipeInterpretContext,\n): InterpretedRecipeVariant<string> => {\n const base = interpretProps(variant.base);\n\n const responsive: InterpretedRecipeOverride<string>[] = variant.responsive.map(entry => {\n const { breakpoint, query, state, variant: swap, target, orientation, container, size, ...rawDecls } =\n entry as AnimationRecipeProps & {\n breakpoint?: string;\n query?: \"min\" | \"max\" | \"exact\";\n state?: string;\n variant?: string;\n target?: string;\n orientation?: \"landscape\" | \"portrait\";\n container?: string;\n size?: string;\n };\n\n const inherited = swap ? { ...ctx.resolveRecipeVariant(swap).base } : {};\n const overrides = interpretProps(rawDecls as AnimationRecipeProps);\n\n const override: InterpretedRecipeOverride<string> = {\n declarations: { ...inherited, ...overrides },\n };\n if (breakpoint) {\n override.breakpoint = breakpoint;\n override.query = query ?? \"exact\";\n }\n if (container) {\n override.container = container;\n if (size) override.size = size;\n override.query = query ?? \"min\";\n }\n if (state) override.state = state;\n if (target) override.target = target; // dec.8 — scope onto the `<item>-<target>` sibling\n if (orientation) override.orientation = orientation;\n return override;\n });\n\n return { base, responsive };\n};\n","/**\n * The animation subsystem (§10.2).\n *\n * Owns three things: **motion tokens** (`duration`/`easing`/`delay`) via the shared property\n * normalize (like effects — no finalize hook), **animation-shorthand recipes** via `interpretRecipe`,\n * and **keyframes** via the generic `buildStructural` hook (the third `buildStructural` user, after\n * layout + reset). Keyframes are the new Model primitive: a named, ordered `{ stop, declarations }`\n * step list carried on `SubsystemModel.keyframes` — neither a token nor a rule-set. It grows a hook,\n * never the spine. Transitions stay in `effects` (golden-locked).\n */\nimport type { NormalizedProperties, StructuralOutput, Subsystem } from \"../../core/subsystem\";\nimport type { NormalizedPropertyValue, NormalizedRecipeVariant } from \"../../core/normalize\";\nimport {\n normalizePropertyValue,\n validateNormalizedResponsiveRefs,\n} from \"../../core/normalize\";\nimport type { Keyframe, KeyframeStep, Ref } from \"../../core/model\";\nimport type { AnimationRecipeProps, KeyframeDefinition, KeyframeStepDeclarations } from \"./types\";\nimport { interpretAnimationRecipeVariant } from \"./recipes\";\n\n/** Sub-keys of `raw.animation` that are not motion-token properties. */\nconst RESERVED_KEYS: ReadonlySet<string> = new Set([\"keyframes\", \"recipes\"]);\n\n/** A keyframe step declaration value → a {@link Ref}: `{ ref }` for a token reference, else a literal. */\nconst declarationRef = (value: unknown): Ref | undefined => {\n if (value && typeof value === \"object\" && \"ref\" in (value as Record<string, unknown>)) {\n return { ref: String((value as { ref: unknown }).ref) };\n }\n if (typeof value === \"string\" || typeof value === \"number\") return { value };\n return undefined;\n};\n\n/** Parse one step's declarations (`property → literal | { ref }`) into `property → Ref`. */\nconst parseStepDeclarations = (raw: KeyframeStepDeclarations): Record<string, Ref> => {\n const out: Record<string, Ref> = {};\n for (const [property, value] of Object.entries(raw)) {\n const ref = declarationRef(value);\n if (ref) out[property] = ref;\n }\n return out;\n};\n\n/** Parse one keyframe definition (stop → declarations) into an ordered {@link Keyframe}. */\nconst parseKeyframe = (raw: KeyframeDefinition): Keyframe => {\n const steps: KeyframeStep[] = [];\n for (const [stop, declarations] of Object.entries(raw)) {\n steps.push({ stop, declarations: parseStepDeclarations(declarations) });\n }\n return { steps };\n};\n\n/** The `animation.keyframes` slice → `name → {@link Keyframe}`. */\nconst buildKeyframes = (raw: unknown): Record<string, Keyframe> => {\n if (!raw || typeof raw !== \"object\") return {};\n const out: Record<string, Keyframe> = {};\n for (const [name, definition] of Object.entries(raw as Record<string, KeyframeDefinition>)) {\n if (definition && typeof definition === \"object\") out[name] = parseKeyframe(definition);\n }\n return out;\n};\n\nexport const animationSubsystem: Subsystem = {\n key: \"animation\",\n normalizeProperties(rawSlice, ctx): NormalizedProperties {\n const out: NormalizedProperties = {};\n if (!rawSlice) return out;\n\n for (const [name, value] of Object.entries(rawSlice)) {\n if (RESERVED_KEYS.has(name)) continue;\n\n const normalized = normalizePropertyValue<unknown>(value as never, {\n propertyPath: `animation.${name}`,\n allowedBreakpoints: ctx.allowedBreakpoints,\n });\n validateNormalizedResponsiveRefs(normalized, { propertyPath: `animation.${name}` });\n\n out[name] = normalized as NormalizedPropertyValue<unknown, Record<string, unknown>>;\n }\n\n return out;\n },\n interpretRecipe(variantName, variant, ctx) {\n return interpretAnimationRecipeVariant(\n variantName,\n variant as NormalizedRecipeVariant<AnimationRecipeProps, string>,\n ctx,\n );\n },\n buildStructural(rawSlice): StructuralOutput {\n return {\n ruleSetGroups: {},\n configProperties: {},\n keyframes: buildKeyframes((rawSlice as { keyframes?: unknown }).keyframes),\n };\n },\n};\n\nexport type { AnimationRaw } from \"./types\";\n","/**\n * Components' `interpretRecipe` hook — the composition interpreter.\n *\n * A component variant carries cross-subsystem references (`colors: \"solid.primary\"`) that are\n * NOT declarations (they're extracted separately as Model `references` pointers) plus an own\n * `css` delta. This interpreter emits ONLY the own-delta declarations, each a format-neutral\n * {@link Ref}. The delta is **literal-first**: a bare string / number value is a raw CSS literal\n * → `{ value }`; a `ref(\"…\")` / `{ ref: \"…\" }` marker is a token path → `{ ref }` (the adapter lowers\n * it to `var(--…)` against the global token union). The\n * referenced recipes' own states ride along on their shared classes (via the `references`\n * pointers), so the component only emits its own delta + own states — which win at equal\n * specificity by later source order.\n */\nimport type { InterpretedRecipeVariant, InterpretedRecipeOverride, Ref } from \"../../core/model\";\nimport type { NormalizedRecipeVariant } from \"../../core/normalize\";\nimport type { RecipeInterpretContext } from \"../../core/subsystem\";\nimport type { ComponentsRecipeProps, CssDeltaValue } from \"./types\";\n\n/**\n * Interpret one component variant into base + state/responsive override declarations from its\n * `css` delta. Cross-subsystem references are handled by `extractComponentReferences`, not here.\n */\nexport const interpretComponentsRecipeVariant = (\n _variantName: string,\n variant: NormalizedRecipeVariant<ComponentsRecipeProps, string>,\n _ctx: RecipeInterpretContext,\n): InterpretedRecipeVariant<string> => {\n const base = interpretCssDelta((variant.base as ComponentsRecipeProps).css);\n\n const responsive: InterpretedRecipeOverride<string>[] = variant.responsive.map(entry => {\n const e = entry as ComponentsRecipeProps & {\n breakpoint?: string;\n query?: \"min\" | \"max\" | \"exact\";\n state?: string;\n orientation?: \"landscape\" | \"portrait\";\n container?: string;\n size?: string;\n target?: string;\n };\n const override: InterpretedRecipeOverride<string> = {\n declarations: interpretCssDelta(e.css),\n };\n if (e.breakpoint) {\n override.breakpoint = e.breakpoint;\n override.query = e.query ?? \"exact\";\n }\n if (e.container) {\n override.container = e.container;\n if (e.size) override.size = e.size;\n override.query = e.query ?? \"min\";\n }\n if (e.state) override.state = e.state;\n if (e.orientation) override.orientation = e.orientation;\n if (e.target) override.target = e.target; // dec.8 — scope onto the `<item>-<target>` sibling\n return override;\n });\n\n return { base, responsive };\n};\n\n/** A component `css` delta (`{ color, boxShadow }`) → `formattedProperty → Ref` (ref-first, §19). */\nconst interpretCssDelta = (\n css: Record<string, CssDeltaValue> | undefined,\n): Record<string, Ref> => {\n const declarations: Record<string, Ref> = {};\n if (!css) return declarations;\n for (const [property, value] of Object.entries(css)) {\n declarations[formatPropertyName(property)] = cssValueToRef(value);\n }\n return declarations;\n};\n\n/**\n * One `css` delta value → a {@link Ref} (literal-first): a bare `string` or `number` is a raw literal\n * → `{ value }`; the `{ ref: \"…\" }` object (produced by the `ref()` helper or authored directly in JSON)\n * is a token path → `{ ref }`, lowered to `var(--…)` by the adapter.\n */\nconst cssValueToRef = (value: CssDeltaValue): Ref => {\n if (typeof value === \"object\") return { ref: value.ref };\n return { value };\n};\n\n/** Format an authored CSS property name to its declaration name (`boxShadow` → `box-shadow`). */\nconst formatPropertyName = (property: string): string => {\n if (property.startsWith(\"--\")) return property;\n return property\n .replace(/_/g, \"-\")\n .replace(/([a-z0-9])([A-Z])/g, \"$1-$2\")\n .toLowerCase();\n};\n","/**\n * The components (composition) subsystem.\n *\n * Owns **no primitive properties** (the property pipeline never runs — `normalizeProperties`\n * returns empty). It contributes only recipes that reference other subsystems' recipes plus an\n * own `css` delta. The generic recipe path drives `interpretRecipe` (own delta → refs) and, via\n * the `extractReferences` hook, keeps each variant's cross-subsystem references as Model pointers\n * (`\"colors:solid.primary\"`) so the referenced recipe's states ride along on its shared class.\n * It grows a hook, never the spine.\n */\n\nimport type { Subsystem, NormalizedProperties } from \"../../core/subsystem\";\nimport type { NormalizedRecipeVariant } from \"../../core/normalize\";\nimport { extractComponentReferences } from \"../../core/model\";\nimport type { ComponentsRecipeProps } from \"./types\";\nimport { interpretComponentsRecipeVariant } from \"./recipes\";\n\nexport const componentsSubsystem: Subsystem = {\n key: \"components\",\n // No property pipeline — components own no primitive tokens.\n normalizeProperties(): NormalizedProperties {\n return {};\n },\n interpretRecipe(variantName, variant, ctx) {\n return interpretComponentsRecipeVariant(\n variantName,\n variant as NormalizedRecipeVariant<ComponentsRecipeProps, string>,\n ctx,\n );\n },\n extractReferences(normalizedVariantBase) {\n return extractComponentReferences(normalizedVariantBase);\n },\n};\n\nexport type { ComponentsRecipeProps, ResolvedComponentClass, ComponentsRaw } from \"./types\";\n","/**\n * The globals preset library (§9, formerly §10.1 reset) — the single, format-neutral source for the\n * static normalization rule-sets and the default `h1`–`h6` → type-scale map.\n *\n * These produce Model {@link RuleSet}s (declarations are `{ value }` literals for the static\n * layer, `{ ref }` token paths for the default heading map), so every web adapter shares one\n * source (à la `color-math`) and lowers them itself. No CSS strings here — the adapter wraps\n * each `selector` in `:where(…)` (specificity-0) and orders reset ahead of recipes.\n *\n * Layers:\n * - **static** — literal-declaration rule-sets that strip UA opinions (box model, margins,\n * heading sizing, list markers, form typography, media block/max-width, anchor colour).\n * - **default headings** — themed rule-sets binding `h1`–`h6` to typography's ratio-generated\n * `fontSize` scale variants (`typography.fontSize.4xl` …). Opportunistic: the adapter drops a\n * heading whose scale step wasn't generated (a theme with a ratio-less `fontSize`).\n */\n\nimport { RefractError } from \"../../core/errors\";\nimport type { Ref, RuleSet, RuleSetGroup } from \"../../core/model\";\nimport type { GlobalsPreset } from \"./types\";\n\nconst literal = (value: string | number): Ref => ({ value });\nconst tokenRef = (path: string): Ref => ({ ref: path });\n\n/** A preset rule-set: an explicit raw `selector` + literal/ref declarations, no overrides. Stays\n * `kind:\"reset\"` — the normalization layer renders at specificity-0 `:where(sel)`, unlike the themed\n * `kind:\"globals\"` element rules. */\nconst resetRuleSet = (selector: string, declarations: Record<string, Ref>): RuleSet => ({\n kind: \"reset\",\n selector,\n declarations,\n overrides: [],\n});\n\n/** Build a `RuleSetGroup` (variant key → rule-set) from an ordered `[key, selector, decls]` list. */\nconst staticGroup = (\n entries: ReadonlyArray<readonly [string, string, Record<string, string | number>]>,\n): RuleSetGroup => {\n const group: RuleSetGroup = {};\n for (const [key, selector, decls] of entries) {\n const declarations: Record<string, Ref> = {};\n for (const [property, value] of Object.entries(decls)) declarations[property] = literal(value);\n group[key] = resetRuleSet(selector, declarations);\n }\n return group;\n};\n\n// ---------------------------------------------------------------------------\n// Static layers (literal declarations, kebab-case CSS keys)\n// ---------------------------------------------------------------------------\n\n/** Preflight — opinionated, token-first: strip UA styling so the design tokens are the sole source. */\nconst PREFLIGHT_STATIC: ReadonlyArray<readonly [string, string, Record<string, string | number>]> = [\n [\"box\", \"*,::before,::after\", { \"box-sizing\": \"border-box\", \"border-width\": \"0\", \"border-style\": \"solid\" }],\n [\"body\", \"body\", { margin: \"0\", \"line-height\": \"inherit\" }],\n [\"headings\", \"h1,h2,h3,h4,h5,h6\", { \"font-size\": \"inherit\", \"font-weight\": \"inherit\", margin: \"0\" }],\n [\"blocks\", \"p,figure,blockquote,dl,dd\", { margin: \"0\" }],\n [\"lists\", \"ul,ol\", { \"list-style\": \"none\", margin: \"0\", padding: \"0\" }],\n [\"media\", \"img,picture,video,canvas,svg\", { display: \"block\", \"max-width\": \"100%\" }],\n [\"forms\", \"button,input,select,textarea\", { font: \"inherit\", color: \"inherit\" }],\n [\"anchors\", \"a\", { color: \"inherit\", \"text-decoration\": \"inherit\" }],\n];\n\n/** Normalize — light: fix cross-browser bugs, preserve UA defaults (no margin zeroing / heading strip). */\nconst NORMALIZE_STATIC: ReadonlyArray<readonly [string, string, Record<string, string | number>]> = [\n [\"box\", \"*,::before,::after\", { \"box-sizing\": \"border-box\" }],\n [\"body\", \"body\", { margin: \"0\" }],\n [\"media\", \"img,picture,video,canvas,svg\", { \"max-width\": \"100%\" }],\n];\n\n/** Reset — aggressive classic reset: zero the box on everything, unstyle headings and lists. */\nconst RESET_STATIC: ReadonlyArray<readonly [string, string, Record<string, string | number>]> = [\n [\"box\", \"*,::before,::after\", { \"box-sizing\": \"border-box\" }],\n [\"all\", \"*\", { margin: \"0\", padding: \"0\", border: \"0\", font: \"inherit\", \"vertical-align\": \"baseline\" }],\n [\"headings\", \"h1,h2,h3,h4,h5,h6\", { \"font-size\": \"inherit\", \"font-weight\": \"inherit\" }],\n [\"lists\", \"ul,ol\", { \"list-style\": \"none\" }],\n [\"media\", \"img,picture,video,canvas,svg\", { display: \"block\", \"max-width\": \"100%\" }],\n];\n\n// ---------------------------------------------------------------------------\n// Default themed heading map (h1–h6 → typography's ratio-generated scale variants)\n// ---------------------------------------------------------------------------\n\n/** `h<n>` → the `fontSize` scale variant it binds to (largest heading = top of the scale). */\nconst DEFAULT_HEADINGS: ReadonlyArray<readonly [string, string]> = [\n [\"h1\", \"4xl\"],\n [\"h2\", \"3xl\"],\n [\"h3\", \"2xl\"],\n [\"h4\", \"xl\"],\n [\"h5\", \"lg\"],\n [\"h6\", \"md\"],\n];\n\n/** The default `h1`–`h6` themed group — each binds `font-size` to `typography.fontSize.<step>`. */\nexport const buildDefaultHeadingGroup = (): RuleSetGroup => {\n const group: RuleSetGroup = {};\n for (const [tag, step] of DEFAULT_HEADINGS) {\n group[tag] = resetRuleSet(tag, { \"font-size\": tokenRef(`typography.fontSize.${step}`) });\n }\n return group;\n};\n\n// ---------------------------------------------------------------------------\n// Preset resolution\n// ---------------------------------------------------------------------------\n\ntype PresetConfig = {\n static: ReadonlyArray<readonly [string, string, Record<string, string | number>]>;\n /** Whether the preset also emits the default `h1`–`h6` themed map. */\n headings: boolean;\n};\n\nconst PRESETS: Record<Exclude<GlobalsPreset, false>, PresetConfig> = {\n preflight: { static: PREFLIGHT_STATIC, headings: true },\n normalize: { static: NORMALIZE_STATIC, headings: false },\n reset: { static: RESET_STATIC, headings: true },\n};\n\n/** The recommended default preset (what `refract init` scaffolds). */\nexport const DEFAULT_GLOBALS_PRESET: Exclude<GlobalsPreset, false> = \"preflight\";\n\n/** The known preset names — for validation / error messages. */\nexport const GLOBALS_PRESET_NAMES = Object.keys(PRESETS) as ReadonlyArray<Exclude<GlobalsPreset, false>>;\n\n/**\n * Expand a preset name into its `{ static, defaults? }` rule-set groups. `false` yields no groups\n * (elements-only). An unknown name throws (typo detection). The default heading group is included\n * only when the preset opts into it (`preflight` / `reset`, not `normalize`).\n */\nexport const expandPreset = (preset: GlobalsPreset): { static?: RuleSetGroup; defaults?: RuleSetGroup } => {\n if (preset === false) return {};\n const config = PRESETS[preset];\n if (!config) {\n throw new RefractError(\n \"REFRACT_E_PRESET\",\n `globals: unknown preset \"${preset}\" — expected one of ${GLOBALS_PRESET_NAMES.join(\", \")} or false`,\n );\n }\n const groups: { static?: RuleSetGroup; defaults?: RuleSetGroup } = {\n static: staticGroup(config.static),\n };\n if (config.headings) groups.defaults = buildDefaultHeadingGroup();\n return groups;\n};\n","/**\n * The globals subsystem (§9 — formerly `reset`).\n *\n * Owns **no primitive properties** and **no minted-class recipes** — it fills the Model with two\n * kinds of selector-targeting rule-set:\n *\n * - **preset layers** (`static` + default `defaults`) — `kind:\"reset\"`, literal/opportunistic\n * normalization the adapters render at specificity-0 (`:where(sel)`). Unchanged from `reset`.\n * - **themed elements** (`elements`) — `kind:\"globals\"`, one rule-set per selector, carrying base\n * declarations + `states`/`responsive` overrides + delta-only `variants`. The adapters render\n * these at a higher tier (bare `a { }`, variant `a.subtle` / nested `&.subtle`).\n *\n * Element rules reuse the shared recipe normalization (`normalizeRecipeGroup`) for the genuinely\n * common part — flattening `states` + `responsive` into one `overrides` list — but stay *structural*\n * (a base selector + a named-variant map), not §7A recipe-sibling classes: they're elements, not\n * recipes. Their token refs resolve late in each adapter and are validated up-front in `createTheme`\n * (`validateGlobalsRefs`), like `components`. It grows a hook, never the spine.\n */\n\nimport type { NormalizedProperties, StructuralContext, StructuralOutput, Subsystem } from \"../../core/subsystem\";\nimport type { Ref, RuleSet, RuleSetGroup, RuleSetOverride, GlobalsVariant } from \"../../core/model\";\nimport { normalizeRecipeGroup } from \"../../core/normalize\";\nimport type {\n NormalizedRecipeVariant,\n RecipeNormalizationOptions,\n RecipeResponsiveOverride,\n} from \"../../core/normalize\";\nimport type { GlobalsDeclValue, GlobalsDeclarations, GlobalsElement, GlobalsRaw } from \"./types\";\nimport { expandPreset } from \"./presets\";\n\n/** The condition-axis keys carried on a normalized recipe override — never declarations. */\nconst CONDITION_KEYS = new Set([\n \"state\",\n \"breakpoint\",\n \"query\",\n \"orientation\",\n \"container\",\n \"size\",\n \"variant\",\n \"target\",\n]);\n\n/** A globals leaf value → a Model {@link Ref} (literal-first, §9): a bare `string` / `number` is a raw\n * literal → `{ value }`; a `ref(\"…\")` / `{ ref: \"…\" }` marker is a token path → `{ ref }` (lowered to\n * `var(--…)` / theme read by the adapter). Mirrors the components `css` delta grammar. */\nconst leafToRef = (value: GlobalsDeclValue): Ref => {\n if (value !== null && typeof value === \"object\") return { ref: value.ref };\n return { value };\n};\n\n/** Format an authored CSS property name to its declaration name (`textDecoration` → `text-decoration`). */\nconst formatProperty = (property: string): string => {\n if (property.startsWith(\"--\")) return property;\n return property\n .replace(/_/g, \"-\")\n .replace(/([a-z0-9])([A-Z])/g, \"$1-$2\")\n .toLowerCase();\n};\n\n/** A flat declaration map (a normalized base or one override entry) → `formattedProperty → Ref`,\n * skipping the condition axes (present on override entries) — everything else is a leaf. */\nconst interpretDeclarations = (props: Record<string, unknown>): Record<string, Ref> => {\n const declarations: Record<string, Ref> = {};\n for (const [property, value] of Object.entries(props)) {\n if (value == null || CONDITION_KEYS.has(property)) continue;\n declarations[formatProperty(property)] = leafToRef(value as GlobalsDeclValue);\n }\n return declarations;\n};\n\n/** One normalized override entry → a Model {@link RuleSetOverride} (condition axes copied, delta\n * props interpreted into declarations). */\nconst interpretOverride = (entry: RecipeResponsiveOverride<GlobalsDeclarations>): RuleSetOverride => {\n const override: RuleSetOverride = { declarations: interpretDeclarations(entry as Record<string, unknown>) };\n const e = entry as Record<string, unknown>;\n for (const key of CONDITION_KEYS) {\n if (e[key] !== undefined) (override as Record<string, unknown>)[key] = e[key];\n }\n return override;\n};\n\n/** A normalized recipe variant → `{ declarations, overrides }` (the shared base/override interpret). */\nconst interpretItem = (\n normalized: NormalizedRecipeVariant<GlobalsDeclarations>,\n): { declarations: Record<string, Ref>; overrides: RuleSetOverride[] } => ({\n declarations: interpretDeclarations(normalized.base as Record<string, unknown>),\n overrides: normalized.responsive.map(interpretOverride),\n});\n\n/**\n * Normalize one authored element def as a single-item recipe group and interpret it. `variants` is\n * peeled off first, so `normalizeRecipeGroup` sees no `variants` key (§7A stays a no-op) and just\n * flattens `states` + `responsive`. The one-item group keys the result by the name we passed.\n */\nconst normalizeElementItem = (\n name: string,\n def: Record<string, unknown>,\n options: RecipeNormalizationOptions<string>,\n): { declarations: Record<string, Ref>; overrides: RuleSetOverride[] } => {\n // dec.7 — globals element variants keep the rich (states/responsive) modifier, a superset of the\n // flat recipe modifier `normalizeRecipeGroup` is typed for; the runtime (`mergeRecipe`) is generic,\n // so this cast is structurally safe.\n const normalized = normalizeRecipeGroup<GlobalsDeclarations, string>(\n { [name]: def } as unknown as Parameters<typeof normalizeRecipeGroup<GlobalsDeclarations, string>>[0],\n options,\n );\n return interpretItem(normalized[name]);\n};\n\n/** `globals.elements` (selector → themed element rule) → the `kind:\"globals\"` `elements` rule-set group. */\nconst buildElementsGroup = (\n elements: Record<string, GlobalsElement> | undefined,\n ctx: StructuralContext,\n): RuleSetGroup | undefined => {\n if (!elements || !Object.keys(elements).length) return undefined;\n const allowedBreakpoints = Object.keys(ctx.breakpoints);\n const group: RuleSetGroup = {};\n\n for (const [selector, element] of Object.entries(elements)) {\n if (!element || typeof element !== \"object\") continue;\n const options: RecipeNormalizationOptions<string> = {\n propertyPath: `globals.elements.${selector}`,\n allowedBreakpoints,\n allowedStates: ctx.allowedStates,\n allowedContainers: ctx.allowedContainers,\n };\n\n // Peel `variants` so the base normalizes without §7A desugaring; variants stay structural.\n const { variants, ...baseDef } = element as Record<string, unknown>;\n const base = normalizeElementItem(selector, baseDef, options);\n\n const ruleSet: RuleSet = {\n kind: \"globals\",\n selector,\n declarations: base.declarations,\n overrides: base.overrides,\n };\n\n if (variants && typeof variants === \"object\" && Object.keys(variants).length) {\n const variantMap: Record<string, GlobalsVariant> = {};\n for (const [variantName, delta] of Object.entries(variants as Record<string, unknown>)) {\n if (!delta || typeof delta !== \"object\") continue;\n variantMap[variantName] = normalizeElementItem(variantName, delta as Record<string, unknown>, {\n ...options,\n propertyPath: `${options.propertyPath}.variants.${variantName}`,\n });\n }\n if (Object.keys(variantMap).length) ruleSet.variants = variantMap;\n }\n\n group[selector] = ruleSet;\n }\n\n return Object.keys(group).length ? group : undefined;\n};\n\n/**\n * Normalize a `rawTheme.globals` slice into its `{ static?, defaults?, elements? }` rule-set groups.\n *\n * The **preset** must be explicit for the static + default layers to emit — a bare `{ elements }`\n * produces only the themed element group, so an `override` delta inherits the parent's preset instead\n * of reverting to the default.\n */\nconst buildGlobalsRuleSets = (\n rawSlice: unknown,\n ctx: StructuralContext,\n): Record<string, RuleSetGroup> => {\n const parsed = (rawSlice ?? {}) as GlobalsRaw;\n const groups: Record<string, RuleSetGroup> = {};\n\n // Static + default heading layers only when the preset is explicitly authored.\n if (parsed.preset !== undefined) {\n const expanded = expandPreset(parsed.preset);\n if (expanded.static) groups.static = expanded.static;\n if (expanded.defaults) groups.defaults = expanded.defaults;\n }\n\n // Themed element rules always apply (the delta a preset-less slice carries).\n const elements = buildElementsGroup(parsed.elements, ctx);\n if (elements) groups.elements = elements;\n\n return groups;\n};\n\nexport const globalsSubsystem: Subsystem = {\n key: \"globals\",\n // No property pipeline — globals owns no primitive tokens.\n normalizeProperties(): NormalizedProperties {\n return {};\n },\n buildStructural(rawSlice, ctx): StructuralOutput {\n return { ruleSetGroups: buildGlobalsRuleSets(rawSlice, ctx), configProperties: {} };\n },\n};\n\nexport type { GlobalsRaw, GlobalsPreset, GlobalsDeclValue, GlobalsDeclarations, GlobalsElement } from \"./types\";\n","/**\n * The clean-room `createTheme` — the public entry point.\n *\n * A **walking skeleton** (Step 0d): a live spine that grows one seam per step, so every\n * later step is reviewed through the real entry point rather than isolated unit tests.\n * The control flow is fixed; coverage grows by pushing a {@link Subsystem} onto `SUBSYSTEMS`\n * or filling a hook — never by editing the spine.\n *\n * `adapter` is a **required** option (no `createCssAdapter()` default), which is what lets\n * this module stay in core importing nothing but the `ThemeAdapter` interface.\n *\n * Flow: read breakpoints → build the media descriptor → normalize each subsystem's slice\n * into a per-subsystem Model input (`buildSubsystemInput`) → `buildThemeModel` → assemble the\n * theme surface (`assembleTheme`: token map + `resolveToken` + `adapter.bind` + `extend`).\n *\n * `theme.override(partial)` (Step 5) is a **delta merge**, not a re-run: it normalizes ONLY the\n * partial's changed subsystem slices (through the very same `buildSubsystemInput`), immutably\n * merges those Model fragments into the current Model at property / rule-set-group granularity,\n * and re-assembles onto the **new** Model. The parent Model (and its bound outputs) are untouched\n * — real child themes. There is no raw retention: the Model is the only held state, and the\n * reference-resolution context recipe interpretation needs is reconstructed from it\n * (`reconstructNormalizedProperties`). Synthesized steps are derived refs, so overriding a base\n * re-derives its steps for free; the merge code itself carries no subsystem-specific logic.\n */\n\nimport type { ThemeAdapter, RenderContext } from \"./ThemeAdapter\";\nimport { RefractError } from \"./errors\";\nimport type { Subsystem, RecipeInterpretContext, NormalizedProperties } from \"./subsystem\";\nimport type {\n Literal,\n Ref,\n ThemeModel,\n SubsystemModel,\n PropertyModel,\n RuleSetGroup,\n Keyframe,\n ContainerModel,\n SubsystemModelInput,\n BuildThemeModelInput,\n} from \"./model\";\nimport type { InterpretedRecipeVariant } from \"./model\";\nimport {\n buildThemeModel,\n buildSubsystemModel,\n buildTokenMap,\n buildRuleSetFromInterpreted,\n buildComponentRuleSetFromInterpreted,\n} from \"./model\";\nimport { resolveModelUnits, type UnitsConfig, type UnitResolutionConfig } from \"./units\";\nimport type { NormalizedPropertyValue } from \"./normalize\";\nimport type { RawTheme } from \"./rawTheme\";\nimport { normalizeRecipeGroup, createRecipeVariantResolver } from \"./normalize\";\nimport { buildDerivationRegistry, resolveToken, bakeCrossPropertyDerivations } from \"./derive\";\nimport {\n buildMediaDescriptor,\n buildContainerDescriptors,\n mediaQueryString,\n resolveMediaConfig,\n DEFAULT_BREAKPOINTS,\n type MediaDescriptor,\n type MediaConfig,\n} from \"./media\";\nimport { colorsSubsystem } from \"../subsystems/colors\";\nimport { typographySubsystem } from \"../subsystems/typography\";\nimport { layoutSubsystem } from \"../subsystems/layout\";\nimport { effectsSubsystem } from \"../subsystems/effects\";\nimport { bordersSubsystem } from \"../subsystems/borders\";\nimport { animationSubsystem } from \"../subsystems/animation\";\nimport { componentsSubsystem } from \"../subsystems/components\";\nimport { globalsSubsystem } from \"../subsystems/globals\";\n\n/**\n * The subsystems the spine drives, in order. Grows as later steps port each subsystem.\n * `globals` is last: its themed element refs resolve late against every subsystem's tokens (like\n * `components`), so it only needs the others' Model present, not their array position.\n */\nconst SUBSYSTEMS: readonly Subsystem[] = [\n colorsSubsystem,\n typographySubsystem,\n layoutSubsystem,\n effectsSubsystem,\n bordersSubsystem,\n animationSubsystem,\n componentsSubsystem,\n globalsSubsystem,\n];\n\n/**\n * The generic recipe path — normalize each `<subsystem>.recipes.<group>`, drive the shared\n * cycle-safe resolver through the subsystem's `interpretRecipe` hook, and build the Model\n * rule-set group from the interpreted (ref-carrying) output. Subsystem-agnostic: the only\n * subsystem-specific knowledge is the `interpretRecipe` hook itself.\n */\nfunction buildSubsystemRuleSets(\n subsystem: Subsystem,\n rawRecipes: Record<string, unknown> | undefined,\n ctx: {\n breakpoints: Record<string, number>;\n media: MediaDescriptor<string>;\n properties: RecipeInterpretContext[\"properties\"];\n allowedBreakpoints: string[];\n allowedStates?: ReadonlyArray<string>;\n allowedContainers?: ReadonlyMap<string, ReadonlySet<string>>;\n },\n): Record<string, RuleSetGroup> {\n if (!subsystem.interpretRecipe || !rawRecipes || !Object.keys(rawRecipes).length) {\n return {};\n }\n\n const groups: Record<string, RuleSetGroup> = {};\n for (const [groupName, groupDef] of Object.entries(rawRecipes)) {\n const groupPath = `${subsystem.key}.recipes.${groupName}`;\n const normalized = normalizeRecipeGroup(groupDef as Record<string, Record<string, unknown>>, {\n propertyPath: groupPath,\n allowedBreakpoints: ctx.allowedBreakpoints,\n allowedStates: ctx.allowedStates,\n allowedContainers: ctx.allowedContainers,\n });\n\n const resolver = createRecipeVariantResolver<\n Record<string, unknown>,\n string,\n InterpretedRecipeVariant<string>\n >(\n normalized,\n (variantName, variant, resolve) =>\n subsystem.interpretRecipe!(variantName, variant, {\n breakpoints: ctx.breakpoints,\n media: ctx.media,\n properties: ctx.properties,\n resolveRecipeVariant: resolve,\n groupPath,\n }),\n { groupPath },\n );\n\n // Build each variant's rule-set. When the subsystem extracts cross-subsystem references\n // (composition), keep them as Model pointers via `buildComponentRuleSetFromInterpreted`; else\n // a plain structural copy. Per-variant so the reference extraction reads the normalized base.\n const interpreted = resolver.resolveAll();\n const group: RuleSetGroup = {};\n for (const [variantName, interpretedVariant] of Object.entries(interpreted)) {\n if (subsystem.extractReferences) {\n const references = subsystem.extractReferences(normalized[variantName]?.base ?? {});\n group[variantName] = buildComponentRuleSetFromInterpreted(interpretedVariant, references);\n } else {\n group[variantName] = buildRuleSetFromInterpreted(interpretedVariant);\n }\n }\n groups[groupName] = group;\n }\n return groups;\n}\n\n/** Breakpoints → the core media descriptor. `mediaConfig` controls the emitted unit (px default, em/rem — §10.5 D6). */\nconst buildMedia = (\n breakpoints: Record<string, number>,\n mediaConfig?: MediaConfig,\n): MediaDescriptor<string> =>\n buildMediaDescriptor(breakpoints, opts => mediaQueryString(opts, resolveMediaConfig(mediaConfig)));\n\n/**\n * Normalize the authored `containers` config (§10.5) → the Model container map: default each\n * `container-type` to `inline-size` (D2), keep the `sizes` scale. Returns `undefined` for an absent /\n * empty config (additive — no `containers` field on the Model → byte-identical output).\n */\nconst normalizeContainers = (raw: unknown): Record<string, ContainerModel> | undefined => {\n if (!raw || typeof raw !== \"object\") return undefined;\n const out: Record<string, ContainerModel> = {};\n for (const [name, def] of Object.entries(\n raw as Record<string, { type?: \"inline-size\" | \"size\"; sizes?: Record<string, number> }>,\n )) {\n if (!def || typeof def !== \"object\" || !def.sizes || !Object.keys(def.sizes).length) continue;\n out[name] = { type: def.type ?? \"inline-size\", sizes: { ...def.sizes } };\n }\n return Object.keys(out).length ? out : undefined;\n};\n\n/** Container model → `name → Set(sizeNames)`, the allowed-set recipe normalization validates container refs against. */\nconst containerSizeSets = (\n containers?: Record<string, ContainerModel>,\n): ReadonlyMap<string, ReadonlySet<string>> | undefined => {\n if (!containers) return undefined;\n const map = new Map<string, ReadonlySet<string>>();\n for (const [name, c] of Object.entries(containers)) map.set(name, new Set(Object.keys(c.sizes)));\n return map;\n};\n\n/**\n * §W6b — resolve an authored `external` string to the literal parent CSS-variable name. A leading\n * `--` is a literal var (verbatim, any naming); otherwise it's a refract token path lowered to\n * `--<prefix>-<dashed-path>` — the parent's *default* naming (document that assumption).\n */\nconst resolveExternalVar = (external: string, prefix: string): string => {\n if (external.startsWith(\"--\")) return external;\n const dashed = external.split(\".\").join(\"-\").toLowerCase();\n return prefix ? `--${prefix}-${dashed}` : `--${dashed}`;\n};\n\n/**\n * §W6b — split a raw subsystem slice into its external-token properties (a value with a string\n * `external` key) and the remaining slice. The externals are pulled out BEFORE the subsystem runs, so\n * a `var(…)` passthrough never hits colour coercion / scale synthesis / unit tagging; they re-join as\n * normalized properties carrying `external` (the resolved parent var name).\n */\nconst extractExternals = (\n slice: Record<string, unknown> | undefined,\n prefix: string,\n): { clean: Record<string, unknown> | undefined; externals: NormalizedProperties } => {\n if (!slice) return { clean: slice, externals: {} };\n const clean: Record<string, unknown> = {};\n const externals: NormalizedProperties = {};\n for (const [key, value] of Object.entries(slice)) {\n if (\n value !== null &&\n typeof value === \"object\" &&\n !Array.isArray(value) &&\n typeof (value as { external?: unknown }).external === \"string\"\n ) {\n const varName = resolveExternalVar((value as { external: string }).external, prefix);\n externals[key] = { base: `var(${varName})`, external: varName, responsive: [] } as NormalizedProperties[string];\n } else {\n clean[key] = value;\n }\n }\n return { clean, externals };\n};\n\n/** Context threaded into {@link buildSubsystemInput}. */\ninterface SubsystemBuildContext {\n readonly breakpoints: Record<string, number>;\n /** §W6b — the parent theme's var prefix (from `raw.extends.prefix`, default `\"dt\"`). */\n readonly extendsPrefix: string;\n readonly media: MediaDescriptor<string>;\n /** Media unit config (§10.5) — threaded to `buildStructural` for breakpoint-derived container widths. */\n readonly mediaConfig?: MediaConfig;\n readonly allowedBreakpoints: string[];\n readonly allowedStates?: ReadonlyArray<string>;\n /** Container queries (§10.5): `name → allowed size-names`, validated on container recipe overrides. */\n readonly allowedContainers?: ReadonlyMap<string, ReadonlySet<string>>;\n /**\n * Override only: the parent subsystem's reconstructed normalized properties. The partial's own\n * freshly-normalized properties are overlaid on top, and the union is the reference-resolution\n * context recipe interpretation reads (so a delta that touches only a recipe still resolves refs\n * against the inherited palette). Absent on the initial build (a subsystem's own props suffice).\n */\n readonly inheritedProperties?: NormalizedProperties;\n}\n\n/**\n * The per-subsystem \"raw slice → {@link SubsystemModelInput}\" build, extracted so BOTH the initial\n * build and `override` run the exact same normalization. Pure: normalize the slice's properties,\n * drive the generic recipe path (interpret against the inherited⊕own properties), and run the\n * structural generator hook. No spine control flow — a subsystem is data.\n */\nfunction buildSubsystemInput(\n subsystem: Subsystem,\n rawSlice: Record<string, unknown> | undefined,\n ctx: SubsystemBuildContext,\n): SubsystemModelInput {\n // §W6b — external-token properties are pulled out of the slice so the subsystem never coerces or\n // synthesizes a `var(…)` passthrough; they re-join as normalized properties carrying `external`.\n const { clean, externals } = extractExternals(rawSlice, ctx.extendsPrefix);\n const properties = subsystem.normalizeProperties(clean, {\n allowedBreakpoints: ctx.allowedBreakpoints,\n });\n Object.assign(properties, externals);\n // Recipe interpretation resolves refs against the subsystem's properties. On override the parent's\n // (reconstructed) properties are the base, the partial's fresh ones win on collision.\n const interpretProperties = ctx.inheritedProperties\n ? { ...ctx.inheritedProperties, ...properties }\n : properties;\n\n const recipeGroups = buildSubsystemRuleSets(\n subsystem,\n rawSlice?.recipes as Record<string, unknown> | undefined,\n {\n breakpoints: ctx.breakpoints,\n media: ctx.media,\n properties: interpretProperties,\n allowedBreakpoints: ctx.allowedBreakpoints,\n allowedStates: ctx.allowedStates,\n allowedContainers: ctx.allowedContainers,\n },\n );\n\n // Generator-driven rule-sets (layout's columns/grids/stacks/container). Structural groups insert\n // **ahead of** recipe groups; the config knobs merge into the subsystem's tokens as extraProperties.\n let ruleSetGroups = recipeGroups;\n let extraProperties: Record<string, PropertyModel> | undefined;\n let keyframes: Record<string, Keyframe> | undefined;\n if (subsystem.buildStructural && rawSlice) {\n const structural = subsystem.buildStructural(rawSlice, {\n breakpoints: ctx.breakpoints,\n media: ctx.media,\n mediaConfig: ctx.mediaConfig,\n // §9: a structural subsystem whose rule-sets carry recipe-style conditions (globals element\n // `states` / container `responsive`) validates them against the same sets the recipe path uses.\n allowedStates: ctx.allowedStates,\n allowedContainers: ctx.allowedContainers,\n });\n ruleSetGroups = { ...structural.ruleSetGroups, ...recipeGroups };\n if (Object.keys(structural.configProperties).length) {\n extraProperties = structural.configProperties;\n }\n // Keyframes (§10.2, animation) ride their own Model slot — neither rule-set nor token.\n if (structural.keyframes && Object.keys(structural.keyframes).length) {\n keyframes = structural.keyframes;\n }\n }\n\n const input: SubsystemModelInput = {};\n if (Object.keys(properties).length) input.properties = properties;\n if (Object.keys(ruleSetGroups).length) input.ruleSetGroups = ruleSetGroups;\n if (extraProperties) input.extraProperties = extraProperties;\n if (keyframes) input.keyframes = keyframes;\n return input;\n}\n\n/**\n * Reconstruct a subsystem's normalized-property view from its Model {@link PropertyModel}s — base\n * value + variant keys + scalar extras. This is the \"everything override needs is in the Model\"\n * principle: no raw retention. It only needs to be faithful enough for recipe **reference\n * resolution** (a name existing, its variant keys), which this shape provides. Subsystem-generic.\n */\nfunction reconstructNormalizedProperties(\n subModel: SubsystemModel | undefined,\n): NormalizedProperties {\n const out: NormalizedProperties = {};\n if (!subModel?.properties) return out;\n for (const [name, pm] of Object.entries(subModel.properties)) {\n const normalized: Record<string, unknown> = { base: pm.base.value };\n if (pm.variants && Object.keys(pm.variants).length) {\n const variants: Record<string, unknown> = {};\n for (const [vname, v] of Object.entries(pm.variants)) {\n // dec.3 — reconstruct the variant's base + its own extras for recipe reference resolution.\n const reconstructed: Record<string, unknown> = { base: v.base.value };\n if (v.extras) for (const [ename, ref] of Object.entries(v.extras)) reconstructed[ename] = ref.value;\n variants[vname] = reconstructed;\n }\n normalized.variants = variants;\n }\n if (pm.extras) {\n for (const [ename, ref] of Object.entries(pm.extras)) normalized[ename] = ref.value;\n }\n out[name] = normalized as NormalizedPropertyValue<unknown, Record<string, unknown>>;\n }\n return out;\n}\n\n/**\n * Immutable per-subsystem merge — **property-level replace** (a property in the partial replaces\n * the whole {@link PropertyModel}; untouched properties keep their reference) + **rule-set\n * variant-level replace within a group** (a variant in the partial replaces that variant; untouched\n * variants and untouched groups keep their references). New objects only at the touched levels;\n * everything else is shared. No per-subsystem branch — the shape is the same for all five.\n */\nfunction mergeSubsystemModel(\n current: SubsystemModel | undefined,\n partial: SubsystemModel,\n): SubsystemModel {\n if (!current) return partial;\n const merged: SubsystemModel = { ...current };\n if (partial.properties) {\n merged.properties = { ...(current.properties ?? {}), ...partial.properties };\n }\n if (partial.ruleSets) {\n const ruleSets: Record<string, RuleSetGroup> = { ...(current.ruleSets ?? {}) };\n for (const [group, groupRuleSets] of Object.entries(partial.ruleSets)) {\n ruleSets[group] = { ...(current.ruleSets?.[group] ?? {}), ...groupRuleSets };\n }\n merged.ruleSets = ruleSets;\n }\n // Keyframes (§10.2): name-level replace — a keyframe in the partial replaces that keyframe;\n // untouched ones keep their reference. Same rule as rule-set variants; additive when absent.\n if (partial.keyframes) {\n merged.keyframes = { ...(current.keyframes ?? {}), ...partial.keyframes };\n }\n return merged;\n}\n\n/**\n * DTCG round-trip: splice a prebuilt IR overlay (rule-sets / keyframes / containers) into a resolved\n * Model, reusing {@link mergeSubsystemModel} for the per-subsystem merge (no new merge logic). Returns\n * the model unchanged when no overlay option is set, so the standard build path stays byte-identical.\n */\nfunction applyModelOverlay(model: ThemeModel, options: CreateThemeOptions): ThemeModel {\n const { propertiesOverlay, ruleSetsOverlay, keyframesOverlay, containersOverlay } = options;\n if (!propertiesOverlay && !ruleSetsOverlay && !keyframesOverlay && !containersOverlay) return model;\n const subsystems = { ...model.subsystems };\n const keys = new Set([\n ...Object.keys(propertiesOverlay ?? {}),\n ...Object.keys(ruleSetsOverlay ?? {}),\n ...Object.keys(keyframesOverlay ?? {}),\n ]);\n for (const key of keys) {\n subsystems[key] = mergeSubsystemModel(subsystems[key], {\n properties: propertiesOverlay?.[key],\n ruleSets: ruleSetsOverlay?.[key],\n keyframes: keyframesOverlay?.[key],\n });\n }\n const next: ThemeModel = { ...model, subsystems };\n if (containersOverlay) next.containers = { ...(model.containers ?? {}), ...containersOverlay };\n return next;\n}\n\n/** The stable engine an initial theme and every child derived from it share. */\ninterface ThemeEngine {\n readonly adapter: ThemeAdapter;\n readonly derivationRegistry: ReturnType<typeof buildDerivationRegistry>;\n readonly allowedStates?: ReadonlyArray<string>;\n /** Media unit config (§10.5 D6) — shared by the viewport `@media` + container `@container` descriptors. */\n readonly mediaConfig?: MediaConfig;\n /** Length-unit resolution config (§21) — `units` role map + `baseFontSize`. Stable across children. */\n readonly unitConfig?: UnitResolutionConfig;\n}\n\nexport interface CreateThemeOptions<TAdapter extends ThemeAdapter = ThemeAdapter> {\n /** Required — the format target. Core ships no default adapter. */\n readonly adapter: TAdapter;\n /**\n * Media-query output config (§10.5) — `{ unit: \"px\" | \"em\" | \"rem\"; baseFontSize }`. Breakpoint and\n * container thresholds are authored as px numbers; `unit` controls the emitted unit (em/rem = value ÷\n * baseFontSize). Defaults to px. Stable across `override()` children.\n */\n readonly media?: MediaConfig;\n /**\n * Declaration-value length units (§21) — a token-path-prefix role map. `units.default` (global),\n * `units[\"<subsystem>\"]`, `units[\"<subsystem>.<property>\"]`; most-specific wins, over a built-in seed\n * (length subsystems → px, `lineHeight` → none, `letterSpacing` → em). A bare authored number is\n * deferred (resolved here); an explicit unit (`\"1.5rem\"`) is pinned. Unit intent is a theme fact, so it\n * lives here (not on the adapter): every adapter receives a Model with fully-resolved `{ value, unit }`.\n */\n readonly units?: UnitsConfig;\n /** Divisor for a deferred length resolving to `rem` (§21). Defaults to 16. */\n readonly baseFontSize?: number;\n /**\n * DTCG round-trip (§12 Phase 2) — prebuilt property Model to splice in **after** property build,\n * keyed `subsystem → property`. Carries the lossless bits the resolved DTCG token surface can't\n * (appearance `modes` / `responsive` / derivation refs / `external`); a property present here\n * REPLACES the one the standard tokens rebuilt (property-level merge). `fromDTCGTheme` sets it from\n * the `com.theme-registry.refract` extension. Absent → the standard build is untouched.\n */\n readonly propertiesOverlay?: Record<string, Record<string, PropertyModel>>;\n /**\n * DTCG round-trip — prebuilt, already-interpreted rule-set IR to splice into the Model **after**\n * property build, keyed `subsystem → group → variant`. Bypasses authoring/normalization (the IR is\n * a built Model slice, lengths already resolved), then flows through the normal `{ ref }` validation.\n * `fromDTCGTheme` sets this to restore recipes a DTCG document carried in its\n * `com.theme-registry.refract` extension. Rarely set by hand. Absent → the standard build is untouched.\n */\n readonly ruleSetsOverlay?: Record<string, Record<string, RuleSetGroup>>;\n /** DTCG round-trip — prebuilt keyframes to splice in, keyed `subsystem → name`. See {@link ruleSetsOverlay}. */\n readonly keyframesOverlay?: Record<string, Record<string, Keyframe>>;\n /** DTCG round-trip — prebuilt query containers to splice into the Model root. See {@link ruleSetsOverlay}. */\n readonly containersOverlay?: Record<string, ContainerModel>;\n}\n\n/** The public theme surface. Grows: `css`/recipe helpers (step 1). */\nexport interface Theme {\n /** The format-neutral held state — the single source of truth. */\n readonly model: ThemeModel;\n /**\n * Flat, lazy, cached `path -> Ref` view of the Model's property tokens\n * (`\"<subsystem>.<property>[.<variant|extra>]\"`). Aliases / derived steps stay as refs\n * (`{ ref }` / `{ ref, fn, arg }`), so the map is override-safe. Rule-sets are excluded.\n */\n readonly tokens: Record<string, Ref>;\n /**\n * Resolve one token path to its concrete literal — following aliases and running derivations\n * (`lighten` / `darken` / …) through the subsystem derivation registry. Throws on unknown paths.\n */\n readonly resolveToken: (path: string) => Literal;\n /**\n * Derive a **child** theme by immutably merging `partial` (a partial raw theme) into this theme's\n * Model. Only the partial's subsystem slices are re-normalized; the merge is a property /\n * rule-set-variant replace. The parent theme (Model, tokens, css) is untouched — call it again to\n * derive siblings. Overriding a colour base re-derives its synthesized steps automatically.\n *\n * Accepts a (partial) {@link RawTheme} — every key is already optional, so a delta touching one\n * subsystem slice is a valid `RawTheme`.\n */\n readonly override: (partial: RawTheme) => Theme;\n}\n\nexport function createTheme(\n rawTheme: RawTheme,\n options: CreateThemeOptions,\n): Theme {\n const { adapter } = options;\n\n // Bridge the strict authoring type to the loose spine once, at the boundary: subsystem hooks\n // still consume each `raw[key]` slice as `Record<string, unknown>` (types-only, no runtime change).\n const raw = rawTheme as Record<string, unknown>;\n const breakpoints = (raw.breakpoints as Record<string, number> | undefined) ?? DEFAULT_BREAKPOINTS;\n const allowedBreakpoints = Object.keys(breakpoints);\n // §W6b — the parent theme's var prefix for external-token passthroughs (default `\"dt\"`).\n const extendsPrefix = (raw.extends as { prefix?: string } | undefined)?.prefix ?? \"dt\";\n // The adapter owns the known-state set; core validates recipe `state:` refs against it (no CSS import).\n const allowedStates = adapter.allowedStates;\n // dec.1 — the appearance-mode registry. Property `modes` keys are validated against it (typo-detection).\n // Default `[\"dark\", \"light\"]`; declaring `modes` is how a custom mode (e.g. `hc`) becomes valid.\n const allowedModes = new Set((raw.modes as string[] | undefined) ?? [\"dark\", \"light\"]);\n const mediaConfig = options.media;\n const media = buildMedia(breakpoints, mediaConfig);\n\n // Named query containers (§10.5): normalize the config, derive the allowed-size sets container\n // recipe overrides validate against. Absent → additive (no `containers` on the Model).\n const containers = normalizeContainers(raw.containers);\n const allowedContainers = containerSizeSets(containers);\n\n // Loop the subsystem list into per-subsystem Model inputs. Generic by construction:\n // a new subsystem is a push onto SUBSYSTEMS, never a change here.\n const subsystemInputs: Record<string, SubsystemModelInput> = {};\n for (const subsystem of SUBSYSTEMS) {\n const input = buildSubsystemInput(subsystem, raw[subsystem.key] as Record<string, unknown> | undefined, {\n breakpoints,\n extendsPrefix,\n media,\n mediaConfig,\n allowedBreakpoints,\n allowedStates,\n allowedContainers,\n });\n if (Object.keys(input).length) subsystemInputs[subsystem.key] = input;\n }\n\n const built = buildThemeModel({ breakpoints, containers, ...subsystemInputs } as BuildThemeModelInput);\n\n // §21: resolve every length leaf to a concrete `{ value, unit }` — the single format-neutral pass\n // that consults the `units` role map. Adapters downstream never see a deferred length. Default (no\n // `units`) tags px only → CSS/SCSS byte-identical. `unitConfig` is stable across `override()` children.\n const unitConfig: UnitResolutionConfig = { units: options.units, baseFontSize: options.baseFontSize };\n const resolved = resolveModelUnits(built, unitConfig);\n\n // DTCG round-trip: splice any prebuilt IR overlay (recipes/keyframes/containers a DTCG document\n // carried in its `com.theme-registry.refract` extension) into the Model AFTER unit resolution (the\n // overlay came from a built Model, so its lengths are already resolved) and BEFORE the ref-validation\n // below — so a restored rule-set's `{ ref }`s are validated exactly like an authored one.\n const overlaid = applyModelOverlay(resolved, options);\n\n // One derivation registry, collected generically from each subsystem's `derivations` map —\n // no subsystem-specific import here (spine stays control-flow-generic). Stable across children.\n const derivationRegistry = buildDerivationRegistry(\n SUBSYSTEMS.flatMap(subsystem => (subsystem.derivations ? [subsystem.derivations] : [])),\n );\n\n // dec.4 — fill every CROSS-property derived variant / mode value (a `{ ref, modifiers }` sourcing\n // another property) against the full token map, now that it exists. Byte-identical for a Model with\n // no cross-property derivation (returned by reference). Runs before validation so an unknown-source\n // ref fails loud here.\n const model = bakeCrossPropertyDerivations(overlaid, derivationRegistry);\n\n // §19 / §9 — post-build ref validation, collect-all (P2-3). A component `css` delta and a globals\n // element declaration are literal-first: a bare string is raw CSS; a `ref(\"…\")` / `{ ref }` marks a\n // token path. Every marked `{ ref }` must resolve to a real token BEFORE any adapter runs, so a\n // mistyped path fails loud here instead of lowering to a dangling `var(--…)`. Both passes ACCUMULATE\n // their failures so an invalid theme reports every bad ref at once, as one `REFRACT_E_VALIDATION`.\n const validationErrors = [\n ...collectComponentReferenceErrors(model),\n ...collectComponentCssRefErrors(model),\n ...collectGlobalsRefErrors(model),\n ...collectModeErrors(model, allowedModes),\n ];\n if (validationErrors.length > 0) {\n const list = validationErrors.map(e => ` - ${e}`).join(\"\\n\");\n throw new RefractError(\n \"REFRACT_E_VALIDATION\",\n `refract: ${validationErrors.length} validation error(s):\\n${list}`,\n validationErrors,\n );\n }\n\n return assembleTheme(model, { adapter, derivationRegistry, allowedStates, mediaConfig, unitConfig });\n}\n\n/**\n * dec.1 — validate every property `modes` key against the declared `modes` registry (default\n * `[\"dark\", \"light\"]`). A mode name not in the registry is a typo or an undeclared custom mode; throw\n * so it fails loud (like an unknown breakpoint) instead of silently emitting a dead `[data-theme]` block.\n * Walks the built Model's per-subsystem property `modes` — the same post-build shape the other\n * collectors use. Initial-build only (mirrors the existing collect-* passes).\n */\nfunction collectModeErrors(model: ThemeModel, allowedModes: ReadonlySet<string>): string[] {\n const errors: string[] = [];\n const report = (subKey: string, propName: string, mode: string, where: string): void => {\n if (!allowedModes.has(mode)) {\n errors.push(\n `${subKey}.${propName}${where}: unknown appearance mode '${mode}' — declare it in the top-level ` +\n `'modes' registry (known: ${[...allowedModes].join(\", \")})`,\n );\n }\n };\n for (const [subKey, sub] of Object.entries(model.subsystems)) {\n for (const [propName, pm] of Object.entries(sub.properties ?? {})) {\n for (const entry of pm.modes ?? []) {\n if (entry.mode) report(subKey, propName, entry.mode, \"\");\n }\n // dec.9 — a responsive entry's `mode` condition is validated against the same registry.\n for (const entry of pm.responsive ?? []) {\n if (entry.mode) report(subKey, propName, entry.mode, \" (responsive)\");\n }\n }\n }\n return errors;\n}\n\n/**\n * A component variant references sibling recipes cross-subsystem (`colors: \"solid.primary\"` → stored as\n * `\"colors:solid.primary\"`). Those pointers are what compose the class-list at emit time — a reference\n * to a recipe that doesn't exist would silently drop from the composition and ship a button missing its\n * colours. Assert each `subsystem:group.variant` reference resolves to a real recipe in the built Model,\n * collect-all so every dangling reference is reported at once.\n */\nfunction collectComponentReferenceErrors(model: ThemeModel): string[] {\n const ruleSets = model.subsystems.components?.ruleSets;\n if (!ruleSets) return [];\n const errors: string[] = [];\n for (const [group, ruleSetGroup] of Object.entries(ruleSets)) {\n for (const [variant, ruleSet] of Object.entries(ruleSetGroup)) {\n for (const reference of ruleSet.references ?? []) {\n const [subsystem, rest = \"\"] = reference.split(\":\");\n const dot = rest.indexOf(\".\");\n const refGroup = dot >= 0 ? rest.slice(0, dot) : rest;\n const refVariant = dot >= 0 ? rest.slice(dot + 1) : \"\";\n if (!model.subsystems[subsystem]?.ruleSets?.[refGroup]?.[refVariant]) {\n errors.push(\n `components.${group}.${variant}: Recipe variant \"${refVariant}\" is not defined in ` +\n `\"${subsystem}:${refGroup}\". Check the subsystem:group.variant reference against what the ` +\n `subsystem declares.`,\n );\n }\n }\n }\n }\n return errors;\n}\n\n/**\n * §19: validate every component `css`-delta reference. A component's own rule-set declarations are\n * literal-first — a bare authored string stays a literal; only a `ref(\"…\")` / `{ ref }` marker becomes\n * a `{ ref }`. Assert each such `{ ref }` points at a real token in the flat global namespace\n * (`buildTokenMap`); an unknown path is a typo in the marked token path (a raw CSS value needs no\n * marker — it's just a bare string). Rule-set-only (components own no property tokens),\n * so this walks just the component `ruleSets` base declarations + their condition overrides.\n */\nfunction collectComponentCssRefErrors(model: ThemeModel): string[] {\n const ruleSets = model.subsystems.components?.ruleSets;\n if (!ruleSets) return [];\n const tokens = buildTokenMap(model);\n const errors: string[] = [];\n const checkDecls = (\n declarations: Record<string, Ref> | undefined,\n group: string,\n variant: string,\n where: string,\n ): void => {\n for (const [property, ref] of Object.entries(declarations ?? {})) {\n if (ref.ref !== undefined && !(ref.ref in tokens)) {\n errors.push(\n `components.${group}.${variant}: css '${property}'${where} references unknown token ` +\n `'${ref.ref}' — check the token path, or use a bare string / number for a raw CSS value`,\n );\n }\n }\n };\n for (const [group, ruleSetGroup] of Object.entries(ruleSets)) {\n for (const [variant, ruleSet] of Object.entries(ruleSetGroup)) {\n checkDecls(ruleSet.declarations, group, variant, \"\");\n for (const override of ruleSet.overrides ?? []) {\n checkDecls(override.declarations, group, variant, \" (override)\");\n }\n }\n }\n return errors;\n}\n\n/**\n * §9: validate every `globals` themed-element reference. An element declaration is literal-first — a\n * `ref(\"…\")` / `{ ref: \"…\" }` marker became `{ ref }`. Assert each `{ ref }` in the `kind:\"globals\"`\n * element rule-sets (base declarations, condition overrides, and each variant's delta) points at a real\n * token, throwing on an unknown path (a typo in the marked token path).\n * Only `kind:\"globals\"` is checked — the preset `static`/`defaults` layers (`kind:\"reset\"`) keep\n * their opportunistic drop policy (a ratio-less theme drops missing heading scale steps).\n */\nfunction collectGlobalsRefErrors(model: ThemeModel): string[] {\n const ruleSets = model.subsystems.globals?.ruleSets;\n if (!ruleSets) return [];\n const tokens = buildTokenMap(model);\n const errors: string[] = [];\n const checkDecls = (\n declarations: Record<string, Ref> | undefined,\n selector: string,\n where: string,\n ): void => {\n for (const [property, ref] of Object.entries(declarations ?? {})) {\n if (ref.ref !== undefined && !(ref.ref in tokens)) {\n errors.push(\n `globals element '${selector}'${where}: '${property}' references unknown token ` +\n `'${ref.ref}' — check the token path, or use a bare string / number for a raw CSS value`,\n );\n }\n }\n };\n for (const ruleSetGroup of Object.values(ruleSets)) {\n for (const ruleSet of Object.values(ruleSetGroup)) {\n if (ruleSet.kind !== \"globals\") continue;\n const selector = ruleSet.selector ?? \"\";\n checkDecls(ruleSet.declarations, selector, \"\");\n for (const override of ruleSet.overrides ?? []) {\n checkDecls(override.declarations, selector, \" (override)\");\n }\n for (const [variantName, variant] of Object.entries(ruleSet.variants ?? {})) {\n const where = ` (variant '${variantName}')`;\n checkDecls(variant.declarations, selector, where);\n for (const override of variant.overrides ?? []) {\n checkDecls(override.declarations, selector, `${where} (override)`);\n }\n }\n }\n }\n return errors;\n}\n\n/**\n * Assemble the public theme surface over a Model — the token map, `resolveToken`, `adapter.bind`,\n * and the `override` seam. Called once for the initial Model and once per child (a fresh surface\n * over the merged Model), so parent and child never share mutable derived state — only the\n * immutable Model branches the merge left untouched.\n */\nfunction assembleTheme(model: ThemeModel, engine: ThemeEngine): Theme {\n const media = buildMedia(model.breakpoints, engine.mediaConfig);\n // Per-named-container `@container` descriptors (§10.5), sharing the media unit config.\n const containers = buildContainerDescriptors(model.containers, engine.mediaConfig);\n\n // Flat `path -> Ref` token map, derived lazily from the Model and cached on the Model reference\n // (the locked caching principle). A child's new Model is a new WeakMap key → a fresh, un-stale map.\n const tokenMapCache = new WeakMap<ThemeModel, Record<string, Ref>>();\n const getTokens = (): Record<string, Ref> => {\n let map = tokenMapCache.get(model);\n if (!map) {\n map = buildTokenMap(model);\n tokenMapCache.set(model, map);\n }\n return map;\n };\n\n // Resolve one token path to a literal via the 0e resolver (also fills RenderContext.resolve).\n const resolve = (path: string): Literal =>\n resolveToken(getTokens(), engine.derivationRegistry, path);\n const ctx: RenderContext = { media, containers, resolve };\n\n // Bind the adapter once (curries Model + ctx onto the render surface). Its `extend` attaches the\n // adapter's own output surface (the CSS adapter → `css` / `variablesCss` / `recipesCss` / `nodes`\n // / `classes`, computed on demand). Core stays format-agnostic.\n const bound = engine.adapter.bind(model, ctx);\n\n const theme: Theme = {\n model,\n get tokens() {\n return getTokens();\n },\n resolveToken: resolve,\n override: partial => overrideTheme(model, partial as Record<string, unknown>, engine),\n };\n\n const extensions = bound.extend?.(theme as unknown as Record<string, unknown>);\n if (extensions) {\n Object.defineProperties(theme, Object.getOwnPropertyDescriptors(extensions));\n }\n\n return theme;\n}\n\n/**\n * `theme.override(partial)` — the delta merge. Normalize ONLY the partial's changed subsystem\n * slices through {@link buildSubsystemInput}, immutably merge those fragments into the current\n * Model ({@link mergeSubsystemModel}), and re-assemble onto the new Model. The parent Model is left\n * byte-identical (structural sharing for untouched branches). Recipe interpretation in the delta\n * resolves refs against the parent's reconstructed properties overlaid with the partial's own.\n */\nfunction overrideTheme(\n currentModel: ThemeModel,\n partial: Record<string, unknown>,\n engine: ThemeEngine,\n): Theme {\n const partialBreakpoints = partial.breakpoints as Record<string, number> | undefined;\n const nextBreakpoints = partialBreakpoints\n ? { ...currentModel.breakpoints, ...partialBreakpoints }\n : currentModel.breakpoints;\n const allowedBreakpoints = Object.keys(nextBreakpoints);\n const media = buildMedia(nextBreakpoints, engine.mediaConfig);\n\n // Containers (§10.5): a partial `containers` config merges by name into the parent's (like breakpoints).\n const partialContainers = normalizeContainers(partial.containers);\n const nextContainers = partialContainers\n ? { ...(currentModel.containers ?? {}), ...partialContainers }\n : currentModel.containers;\n const allowedContainers = containerSizeSets(nextContainers);\n\n // Shallow copy of the subsystem map; only the touched keys get a new SubsystemModel (the rest keep\n // their reference → real structural sharing, parent stays byte-identical).\n const nextSubsystems: Record<string, SubsystemModel> = { ...currentModel.subsystems };\n for (const subsystem of SUBSYSTEMS) {\n const rawSlice = partial[subsystem.key] as Record<string, unknown> | undefined;\n if (rawSlice === undefined) continue; // untouched subsystem → shared reference\n\n const inheritedProperties = reconstructNormalizedProperties(currentModel.subsystems[subsystem.key]);\n const partialInput = buildSubsystemInput(subsystem, rawSlice, {\n breakpoints: nextBreakpoints,\n // Parent externals survive via mergeSubsystemModel; this prefix only resolves a NEW external the\n // override partial itself introduces (partial `extends` wins, else the default `\"dt\"`).\n extendsPrefix: (partial.extends as { prefix?: string } | undefined)?.prefix ?? \"dt\",\n media,\n mediaConfig: engine.mediaConfig,\n allowedBreakpoints,\n allowedStates: engine.allowedStates,\n allowedContainers,\n inheritedProperties,\n });\n const partialSubModel = buildSubsystemModel(partialInput);\n if (!partialSubModel) continue; // the delta contributed nothing to this subsystem\n\n nextSubsystems[subsystem.key] = mergeSubsystemModel(currentModel.subsystems[subsystem.key], partialSubModel);\n }\n\n const nextModel: ThemeModel = { breakpoints: nextBreakpoints, subsystems: nextSubsystems };\n if (nextContainers && Object.keys(nextContainers).length) nextModel.containers = nextContainers;\n // §21: re-resolve length units on the merged Model. Idempotent — already-resolved parent branches\n // (units baked) are skipped; only the partial's freshly-built fragments get resolved.\n const resolved = resolveModelUnits(nextModel, engine.unitConfig);\n // dec.4 — re-bake cross-property derived values against the MERGED token map, so a child re-derives\n // them when the source property changed (even if the deriving property wasn't in the partial). The\n // pass is immutable, so the parent's shared Refs are never mutated.\n const baked = bakeCrossPropertyDerivations(resolved, engine.derivationRegistry);\n return assembleTheme(baked, engine);\n}\n","/**\n * `resolveEmitPlan` — normalize the authored `Emit` directive into a discriminated `NormalizedEmit`\n * with every default filled (§9, 9a). This is the build layer's light normalization; the *vocabulary*\n * (`Emit`/`NormalizedEmit`) lives in core (`src/core/ThemeAdapter.ts`), and each adapter decides which\n * modes it actually honors — `resolveEmitPlan` never renders anything.\n *\n * Discriminator inference (only `single`/`split` may omit `type`):\n * - `undefined` / `{}` / `{ file }` → `single` (`file` renames the one file; default theme.css)\n * - the `variables` key present → `split` (that key is what tips `{ file, variables }` in)\n * - `subsystem` / `components` → require an explicit `type` (or the string shorthand)\n *\n * Per-type filename/name defaults:\n * - single → `theme.css`\n * - split → `styles.css` + `variables.css`\n * - subsystem → `<sub>.css` / `<sub>.variables.css`\n * - components→ `${group}-${variant}.css`, `inline: true`, `variables` on (a filename)\n */\nimport type { Emit, NormalizedEmit } from \"../core/ThemeAdapter\";\n\nconst DEFAULT_SINGLE_FILE = \"theme.css\";\nconst DEFAULT_SPLIT_STYLES = \"styles.css\";\nconst DEFAULT_SPLIT_VARIABLES = \"variables.css\";\nconst DEFAULT_SUBSYSTEM_FILENAME = (subsystem: string, kind: \"styles\" | \"variables\"): string =>\n kind === \"variables\" ? `${subsystem}.variables.css` : `${subsystem}.css`;\nconst DEFAULT_COMPONENTS_FILENAME = (c: { group: string; variant: string }): string =>\n `${c.group}-${c.variant}.css`;\nconst DEFAULT_COMPONENTS_VARIABLES = \"variables.css\";\n\n/** Normalize an authored {@link Emit} directive into a fully-defaulted {@link NormalizedEmit}. */\nexport function resolveEmitPlan(emit: Emit): NormalizedEmit {\n // String shorthands.\n if (emit === undefined) return { type: \"single\", file: DEFAULT_SINGLE_FILE };\n if (typeof emit === \"string\") {\n switch (emit) {\n case \"single\":\n return { type: \"single\", file: DEFAULT_SINGLE_FILE };\n case \"split\":\n return {\n type: \"split\",\n file: DEFAULT_SPLIT_STYLES,\n variables: DEFAULT_SPLIT_VARIABLES,\n };\n case \"subsystem\":\n return { type: \"subsystem\", filename: DEFAULT_SUBSYSTEM_FILENAME };\n case \"components\":\n return {\n type: \"components\",\n inline: true,\n filename: DEFAULT_COMPONENTS_FILENAME,\n variables: DEFAULT_COMPONENTS_VARIABLES,\n };\n }\n }\n\n // Object forms. Infer the discriminator when omitted: `variables` key ⇒ split, else single.\n const type = emit.type ?? (\"variables\" in emit ? \"split\" : \"single\");\n\n switch (type) {\n case \"single\": {\n const o = emit as { type?: \"single\"; file?: string };\n return { type: \"single\", file: o.file ?? DEFAULT_SINGLE_FILE };\n }\n case \"split\": {\n const o = emit as { type?: \"split\"; file?: string; variables?: string };\n return {\n type: \"split\",\n file: o.file ?? DEFAULT_SPLIT_STYLES,\n variables: o.variables ?? DEFAULT_SPLIT_VARIABLES,\n };\n }\n case \"subsystem\": {\n const o = emit as {\n type: \"subsystem\";\n filename?: (subsystem: string, kind: \"styles\" | \"variables\") => string;\n };\n return { type: \"subsystem\", filename: o.filename ?? DEFAULT_SUBSYSTEM_FILENAME };\n }\n case \"components\": {\n const o = emit as {\n type: \"components\";\n inline?: boolean;\n filename?: (c: { group: string; variant: string }) => string;\n variables?: string | false;\n };\n return {\n type: \"components\",\n inline: o.inline ?? true,\n filename: o.filename ?? DEFAULT_COMPONENTS_FILENAME,\n variables: o.variables ?? DEFAULT_COMPONENTS_VARIABLES,\n };\n }\n }\n\n // Unreachable — the union is exhausted above; keeps the compiler's return-path check happy.\n throw new Error(`resolveEmitPlan: unrecognized emit directive.`);\n}\n","/**\n * W3C Design Tokens Community Group (DTCG) format types.\n * Based on Second Editors' Draft (2024).\n */\n\n// --- Primitive token value types ---\n\nexport type DTCGColorValue = string;\n\nexport type DTCGDimensionValue = string; // e.g. \"16px\", \"1rem\"\n\nexport type DTCGFontFamilyValue = string | string[];\n\nexport type DTCGFontWeightValue = number | string; // 400 or \"bold\"\n\nexport type DTCGDurationValue = string; // \"200ms\", \"0.3s\"\n\nexport type DTCGCubicBezierValue = [number, number, number, number];\n\nexport type DTCGNumberValue = number;\n\n// --- Composite token value types ---\n\nexport type DTCGTypographyValue = {\n fontFamily: string | string[];\n fontSize: string;\n fontWeight: number | string;\n lineHeight: number | string;\n letterSpacing?: string;\n};\n\nexport type DTCGShadowLayerValue = {\n offsetX: string;\n offsetY: string;\n blur: string;\n spread: string;\n color: string;\n inset?: boolean;\n};\n\nexport type DTCGShadowValue = DTCGShadowLayerValue | DTCGShadowLayerValue[];\n\nexport type DTCGBorderValue = {\n color: string;\n width: string;\n style: string;\n};\n\nexport type DTCGTransitionValue = {\n duration: string;\n delay?: string;\n timingFunction: DTCGCubicBezierValue;\n};\n\n// --- Token types enum ---\n\nexport type DTCGTokenType =\n | \"color\"\n | \"dimension\"\n | \"fontFamily\"\n | \"fontWeight\"\n | \"duration\"\n | \"cubicBezier\"\n | \"number\"\n | \"typography\"\n | \"shadow\"\n | \"border\"\n | \"transition\"\n | \"strokeStyle\"\n | \"gradient\";\n\n// --- Token node ---\n\nexport type DTCGToken = {\n $value: unknown;\n $type?: DTCGTokenType;\n $description?: string;\n $extensions?: Record<string, unknown>;\n};\n\nexport type DTCGGroup = {\n $type?: DTCGTokenType;\n $description?: string;\n $extensions?: Record<string, unknown>;\n [key: string]: DTCGToken | DTCGGroup | DTCGTokenType | string | Record<string, unknown> | undefined;\n};\n\nexport type DTCGDocument = DTCGGroup & {\n $name?: string;\n};\n\n// --- Resolved token (after reference resolution) ---\n\nexport type ResolvedDTCGToken = {\n path: string[];\n type: DTCGTokenType;\n value: unknown;\n description?: string;\n extensions?: Record<string, unknown>;\n};\n\n// --- refract round-trip extension ---\n\n/**\n * The reverse-DNS `$extensions` key under which `toDTCG(theme, { includeRecipes: true })` stashes the\n * built rule-set / keyframe / container IR so a document round-trips `refract → DTCG → refract` without\n * loss. Standard DTCG tools ignore unknown extensions, so the payload is **refract-specific and not\n * portable** — property tokens are the interoperable surface; recipes ride here.\n */\nexport const REFRACT_DTCG_EXTENSION = \"com.theme-registry.refract\";\n\n/** The payload schema version under {@link REFRACT_DTCG_EXTENSION}; bumped on a breaking shape change. */\nexport const REFRACT_DTCG_EXTENSION_VERSION = 1;\n","import type { DTCGDocument, DTCGTokenType, ResolvedDTCGToken } from \"./types\";\nimport { RefractError } from \"../core/errors\";\n\nconst SPEC_KEYS = new Set([\"$value\", \"$type\", \"$description\", \"$extensions\", \"$name\"]);\n\nconst isToken = (node: unknown): boolean =>\n typeof node === \"object\" && node !== null && \"$value\" in (node as Record<string, unknown>);\n\n/**\n * Walk a DTCG document and extract all tokens with resolved types and paths.\n * References (`{path.to.token}`) are resolved recursively.\n */\nexport const parseDTCGDocument = (doc: DTCGDocument): ResolvedDTCGToken[] => {\n const tokens: ResolvedDTCGToken[] = [];\n const tokensByPath = new Map<string, ResolvedDTCGToken>();\n\n // First pass: collect all tokens with their raw values\n const walk = (node: Record<string, unknown>, path: string[], inheritedType?: DTCGTokenType) => {\n const groupType = (node.$type as DTCGTokenType | undefined) ?? inheritedType;\n\n for (const [key, child] of Object.entries(node)) {\n if (key.startsWith(\"$\")) continue;\n if (typeof child !== \"object\" || child === null) continue;\n\n const childPath = [...path, key];\n\n if (isToken(child)) {\n const token = child as Record<string, unknown>;\n const resolved: ResolvedDTCGToken = {\n path: childPath,\n type: (token.$type as DTCGTokenType) ?? groupType ?? \"color\",\n value: token.$value,\n description: token.$description as string | undefined,\n extensions: token.$extensions as Record<string, unknown> | undefined,\n };\n tokens.push(resolved);\n tokensByPath.set(childPath.join(\".\"), resolved);\n } else {\n walk(child as Record<string, unknown>, childPath, groupType);\n }\n }\n };\n\n walk(doc, []);\n\n // Second pass: resolve references\n for (const token of tokens) {\n token.value = resolveReferences(token.value, tokensByPath);\n }\n\n return tokens;\n};\n\nconst REFERENCE_PATTERN = /^\\{([^}]+)\\}$/;\n\nconst resolveReferences = (\n value: unknown,\n tokensByPath: Map<string, ResolvedDTCGToken>,\n visited = new Set<string>(),\n): unknown => {\n if (typeof value === \"string\") {\n const match = value.match(REFERENCE_PATTERN);\n if (match) {\n const refPath = match[1];\n if (visited.has(refPath)) {\n throw new RefractError(\"REFRACT_E_CYCLE\", `Circular token reference: ${refPath}`);\n }\n const referenced = tokensByPath.get(refPath);\n if (!referenced) {\n return value; // unresolved reference — leave as-is\n }\n visited.add(refPath);\n return resolveReferences(referenced.value, tokensByPath, visited);\n }\n return value;\n }\n\n if (Array.isArray(value)) {\n return value.map(item => resolveReferences(item, tokensByPath, new Set(visited)));\n }\n\n if (typeof value === \"object\" && value !== null) {\n const result: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(value)) {\n result[k] = resolveReferences(v, tokensByPath, new Set(visited));\n }\n return result;\n }\n\n return value;\n};\n","/**\n * `defineAdapter` — turns an `AdapterSpec` (identity + a `bind` returning the four\n * required primitives) into a full `ThemeAdapter` whose `bind` yields a complete\n * `BoundAdapter` with the DEFAULTED aggregators supplied.\n *\n * The defaults are pure Model walks: the Model enumerates every subsystem and every\n * (group, variant), so core loops it, calls the author's per-unit renderers, and\n * `join`s the results. Model/ctx are already bound, so the aggregators take no args.\n * An author can still override any aggregator (a format whose full document isn't a\n * flat concatenation).\n */\n\nimport type { ThemeModel } from \"./model\";\nimport type {\n AdapterSpec,\n ThemeAdapter,\n BoundAdapter,\n RenderContext,\n UsageDescriptor,\n} from \"./ThemeAdapter\";\n\n/** Every rule-set address in the Model — `(subsystem, group, variant)` triples. */\nfunction eachRuleSet(model: ThemeModel): Array<{ subsystem: string; group: string; variant: string }> {\n const out: Array<{ subsystem: string; group: string; variant: string }> = [];\n for (const [subsystem, sub] of Object.entries(model.subsystems)) {\n for (const [group, ruleSet] of Object.entries(sub.ruleSets ?? {})) {\n for (const variant of Object.keys(ruleSet)) {\n out.push({ subsystem, group, variant });\n }\n }\n }\n return out;\n}\n\n/**\n * Complete an `AdapterSpec` into a `ThemeAdapter`.\n *\n * Wraps the author's `bind` so the returned `BoundAdapter` gains the defaulted\n * aggregators (`renderAllRecipes` / `renderAllVariables` / `renderAll`) built from\n * the required primitives — unless the spec already provides its own override.\n * `name` / `version` pass through unchanged.\n *\n * @param spec identity (`name`/`version`) + a `bind(model, ctx)` returning the\n * required render primitives (and any optional overrides).\n * @returns a full adapter whose `bind(model, ctx)` yields a complete `BoundAdapter`.\n */\nexport function defineAdapter<TUnit>(spec: AdapterSpec<TUnit>): ThemeAdapter<TUnit> {\n return {\n name: spec.name,\n version: spec.version,\n allowedStates: spec.allowedStates,\n bind(model: ThemeModel, ctx: RenderContext): BoundAdapter<TUnit> {\n const b = spec.bind(model, ctx);\n\n const renderAllRecipes =\n b.renderAllRecipes ??\n ((): TUnit =>\n b.join(\n eachRuleSet(model).map(({ subsystem, group, variant }) =>\n b.renderRecipe(subsystem, group, variant),\n ),\n ));\n\n const renderAllVariables =\n b.renderAllVariables ??\n ((): TUnit => b.join(Object.keys(model.subsystems).map(subsystem => b.renderVariables(subsystem))));\n\n const renderAll =\n b.renderAll ?? ((): TUnit => b.join([renderAllVariables(), renderAllRecipes()]));\n\n // Generic self-documentation: the recipe identities are format-correct via `recipeName`; an\n // adapter overrides `describeUsage` to add format-specific import prose to `summary`.\n const describeUsage =\n b.describeUsage ??\n ((): UsageDescriptor => ({\n format: spec.name,\n summary: [`This theme was built with the \"${spec.name}\" refract adapter.`],\n recipes: eachRuleSet(model).map(({ subsystem, group, variant }) => ({\n subsystem,\n group,\n variant,\n name: b.recipeName(subsystem, group, variant),\n })),\n }));\n\n return { ...b, renderAllRecipes, renderAllVariables, renderAll, describeUsage };\n },\n };\n}\n","/**\n * `createNoopAdapter` — the trivial, built-in null adapter (monorepo split, friction 2).\n *\n * `createTheme` requires an `adapter`, but some consumers of the built `Theme` never touch\n * adapter-produced strings — they read only the format-neutral `theme.tokens` / `theme.resolveToken`\n * / `theme.model` (the DTCG export is the canonical example: `toDTCG` walks the flat token map and the\n * breakpoints, never a rendered rule). Those callers need *a* valid adapter purely to satisfy the\n * contract; the output is discarded.\n *\n * Before the split the CLI's `tokens` command reached for `createCssAdapter` as that throwaway builder\n * — which forced a core→adapter dependency (`src/build` importing `src/adapters/css`). The monorepo\n * guiding rule is that the dependency arrow points ONLY into core, so core now ships its own null\n * object: `createNoopAdapter()` emits nothing (empty strings, an empty `emit()`), lets `createTheme`\n * build the Model + token map exactly as any adapter would, and keeps `src/build` free of every\n * adapter package.\n *\n * It's a `ThemeAdapter` like any other (built through {@link defineAdapter}, so it gets the defaulted\n * aggregators for free), just with render primitives that produce empty output.\n */\n\nimport { defineAdapter } from \"./defineAdapter\";\nimport type { ThemeAdapter } from \"./ThemeAdapter\";\n\n/**\n * A no-op adapter: every render primitive returns an empty string and `emit()` writes no files. Use it\n * whenever a `Theme` is needed only for its format-neutral data (`tokens` / `resolveToken` / `model`)\n * and the rendered output is irrelevant — e.g. the `refract tokens` DTCG export.\n */\nexport function createNoopAdapter(): ThemeAdapter<string> {\n return defineAdapter<string>({\n name: \"noop\",\n version: 1,\n bind: () => ({\n recipeName: () => \"\",\n renderRecipe: () => \"\",\n renderVariables: () => \"\",\n join: parts => parts.join(\"\"),\n emit: () => ({ files: {} }),\n }),\n });\n}\n","import type { DTCGDocument, DTCGShadowLayerValue, DTCGTypographyValue, DTCGBorderValue, DTCGTransitionValue, ResolvedDTCGToken } from \"./types\";\nimport { REFRACT_DTCG_EXTENSION, REFRACT_DTCG_EXTENSION_VERSION } from \"./types\";\nimport type { RefractDTCGExtension } from \"./export\";\nimport { parseDTCGDocument } from \"./parse\";\nimport { createTheme, RefractError } from \"../core\";\nimport type { Theme, ThemeAdapter } from \"../core\";\n\ntype RawThemeInput = Record<string, unknown>;\n\nexport type FromDTCGOptions = {\n /**\n * How to map DTCG groups to refract subsystems.\n * Default: auto-detect from $type and group name.\n */\n groupMapping?: Record<string, \"colors\" | \"typography\" | \"effects\" | \"borders\" | \"layout\" | \"ignore\">;\n\n /**\n * Breakpoints as { name: pixelValue } — DTCG has no breakpoint type,\n * so these must be provided separately or mapped from dimension tokens.\n */\n breakpoints?: Record<string, number>;\n\n /**\n * DTCG group path to use as breakpoints source (e.g. \"breakpoint\").\n * Dimension values are parsed to pixels.\n */\n breakpointGroup?: string;\n};\n\n/**\n * Convert a DTCG token document into a `createTheme` raw input.\n *\n * Returns a plain object — modify it freely before passing to `createTheme`.\n */\nexport const fromDTCG = (doc: DTCGDocument, options?: FromDTCGOptions): RawThemeInput => {\n const tokens = parseDTCGDocument(doc);\n const groupMapping = options?.groupMapping ?? {};\n\n const colors: Record<string, unknown> = {};\n const typography: Record<string, unknown> = {};\n const effects: Record<string, unknown> = {};\n const borders: Record<string, unknown> = {};\n const layout: Record<string, unknown> = {};\n let breakpoints: Record<string, number> = options?.breakpoints ?? {};\n\n // Group tokens by their top-level path segment\n const grouped = new Map<string, ResolvedDTCGToken[]>();\n for (const token of tokens) {\n const topGroup = token.path[0];\n if (!grouped.has(topGroup)) grouped.set(topGroup, []);\n grouped.get(topGroup)!.push(token);\n }\n\n // Extract breakpoints if a breakpoint group is specified\n const bpGroup = options?.breakpointGroup;\n if (bpGroup && grouped.has(bpGroup)) {\n breakpoints = {};\n for (const token of grouped.get(bpGroup)!) {\n const name = token.path[token.path.length - 1];\n breakpoints[name] = parseDimension(token.value as string);\n }\n grouped.delete(bpGroup);\n }\n\n for (const [groupName, groupTokens] of grouped) {\n const mapping = groupMapping[groupName] ?? detectSubsystem(groupName, groupTokens);\n if (mapping === \"ignore\") continue;\n\n switch (mapping) {\n case \"colors\":\n mapColorTokens(groupTokens, groupName, colors);\n break;\n case \"typography\":\n mapTypographyTokens(groupTokens, groupName, typography);\n break;\n case \"effects\":\n mapEffectsTokens(groupTokens, groupName, effects);\n break;\n case \"borders\":\n mapBordersTokens(groupTokens, groupName, borders);\n break;\n case \"layout\":\n mapLayoutTokens(groupTokens, groupName, layout);\n break;\n }\n }\n\n const result: RawThemeInput = {};\n if (Object.keys(breakpoints).length) result.breakpoints = breakpoints;\n if (Object.keys(colors).length) result.colors = colors;\n if (Object.keys(typography).length) result.typography = typography;\n if (Object.keys(effects).length) result.effects = effects;\n if (Object.keys(borders).length) result.borders = borders;\n if (Object.keys(layout).length) result.layout = layout;\n\n return result;\n};\n\n// --- Auto-detection ---\n\nconst detectSubsystem = (\n groupName: string,\n tokens: ResolvedDTCGToken[],\n): \"colors\" | \"typography\" | \"effects\" | \"borders\" | \"layout\" | \"ignore\" => {\n const firstType = tokens[0]?.type;\n\n // By type\n if (firstType === \"color\") return \"colors\";\n if (firstType === \"typography\") return \"typography\";\n if (firstType === \"shadow\") return \"effects\";\n if (firstType === \"border\") return \"borders\"; // §14 — border geometry lives in `borders` now\n if (firstType === \"strokeStyle\") return \"borders\";\n if (firstType === \"transition\") return \"effects\";\n\n // By name convention\n const lower = groupName.toLowerCase();\n if (lower.includes(\"color\") || lower.includes(\"palette\")) return \"colors\";\n if (lower.includes(\"font\") || lower.includes(\"typo\") || lower.includes(\"text\")) return \"typography\";\n if (lower.includes(\"spacing\") || lower.includes(\"space\") || lower.includes(\"gutter\")) return \"layout\";\n // Borders keywords take precedence over effects (radius/border/outline moved out of effects).\n if (lower.includes(\"radius\") || lower.includes(\"border\") || lower.includes(\"outline\")) return \"borders\";\n if (lower.includes(\"shadow\") || lower.includes(\"blur\") || lower.includes(\"opacity\") ||\n lower.includes(\"z-index\") || lower.includes(\"zindex\") || lower.includes(\"transition\") ||\n lower.includes(\"effect\")) return \"effects\";\n\n // Dimension tokens: check naming\n if (firstType === \"dimension\") {\n if (lower.includes(\"spacing\") || lower.includes(\"gap\")) return \"layout\";\n if (lower.includes(\"radius\") || lower.includes(\"border\")) return \"borders\";\n if (lower.includes(\"font\") || lower.includes(\"size\")) return \"typography\";\n }\n\n return \"ignore\";\n};\n\n// --- External aliases (dec.6 / §12 Phase 2) ---\n\n/** A DTCG value left as `\"{group.token}\"` after parse — an alias whose target is ABSENT from the\n * document (`parseDTCGDocument` leaves an unresolvable reference verbatim). */\nconst UNRESOLVED_ALIAS = /^\\{([^}]+)\\}$/;\n\n/**\n * Map a genuinely-external DTCG alias (target absent from the doc) to a refract `external` token path\n * — the refract analog of \"this references a token another (parent) theme owns.\" The DTCG `color`\n * group renames to the `colors` subsystem; other groups pass through best-effort. Returns `undefined`\n * for a non-alias / resolved value (which stays a normal literal). A resolvable same-doc alias never\n * reaches here — `parseDTCGDocument` already flattened it to its literal.\n */\nconst aliasToExternalPath = (value: unknown): string | undefined => {\n if (typeof value !== \"string\") return undefined;\n const match = value.match(UNRESOLVED_ALIAS);\n if (!match) return undefined;\n const inner = match[1];\n const dot = inner.indexOf(\".\");\n const group = dot < 0 ? inner : inner.slice(0, dot);\n const rest = dot < 0 ? \"\" : inner.slice(dot + 1);\n const subsystem = group === \"color\" ? \"colors\" : group;\n return rest ? `${subsystem}.${rest}` : subsystem;\n};\n\n// --- Color mapping ---\n\nconst mapColorTokens = (tokens: ResolvedDTCGToken[], groupName: string, colors: Record<string, unknown>) => {\n // Group by second path segment (e.g. color.brand.primary → \"brand\")\n const subgroups = new Map<string, ResolvedDTCGToken[]>();\n const topLevel: ResolvedDTCGToken[] = [];\n\n for (const token of tokens) {\n if (token.path.length <= 2) {\n topLevel.push(token);\n } else {\n const sub = token.path[1];\n if (!subgroups.has(sub)) subgroups.set(sub, []);\n subgroups.get(sub)!.push(token);\n }\n }\n\n // Top-level color tokens → flat colors with base. A genuinely-external alias (absent target) →\n // a refract `external` passthrough (dec.6) rather than a literal `{ base }` (which would reject `{…}`).\n for (const token of topLevel) {\n const name = token.path[token.path.length - 1];\n if (!colors[name]) {\n const external = aliasToExternalPath(token.value);\n colors[name] = external ? { external } : { base: String(token.value) };\n }\n }\n\n // Subgroups → colors with variants\n for (const [subName, subTokens] of subgroups) {\n if (subTokens.length === 1) {\n const token = subTokens[0];\n const name = token.path[token.path.length - 1];\n if (name === subName) {\n colors[subName] = { base: String(token.value) };\n } else {\n if (!colors[subName]) colors[subName] = { base: String(subTokens[0].value) };\n (colors[subName] as Record<string, unknown>).variants = {\n [name]: String(token.value),\n };\n }\n } else {\n // Multiple tokens in subgroup → first or \"base\"/\"default\"/\"500\" is base, rest are variants\n const baseToken = subTokens.find(t => {\n const last = t.path[t.path.length - 1];\n return last === \"base\" || last === \"default\" || last === \"500\";\n }) ?? subTokens[0];\n\n const variants: Record<string, string> = {};\n for (const t of subTokens) {\n if (t === baseToken) continue;\n const variantName = t.path.slice(2).join(\"-\");\n variants[variantName] = String(t.value);\n }\n\n colors[subName] = {\n base: String(baseToken.value),\n ...(Object.keys(variants).length ? { variants } : {}),\n };\n }\n }\n};\n\n// --- Typography mapping ---\n\nconst TYPO_PROPERTY_MAP: Record<string, string> = {\n fontfamily: \"fontFamily\",\n fontsize: \"fontSize\",\n fontweight: \"fontWeight\",\n lineheight: \"lineHeight\",\n letterspacing: \"letterSpacing\",\n fontstyle: \"fontStyle\",\n texttransform: \"textTransform\",\n textdecoration: \"textDecoration\",\n textalign: \"textAlign\",\n};\n\nconst mapTypographyTokens = (tokens: ResolvedDTCGToken[], groupName: string, typography: Record<string, unknown>) => {\n for (const token of tokens) {\n if (token.type === \"typography\") {\n // Composite typography token → decompose into individual properties\n const value = token.value as DTCGTypographyValue;\n const variantName = token.path.slice(1).join(\"-\") || token.path[token.path.length - 1];\n\n if (value.fontFamily) {\n addTypographyVariant(typography, \"fontFamily\",\n Array.isArray(value.fontFamily) ? value.fontFamily.join(\", \") : value.fontFamily, variantName);\n }\n if (value.fontSize) {\n addTypographyVariant(typography, \"fontSize\", parseDimensionOrKeep(value.fontSize), variantName);\n }\n if (value.fontWeight !== undefined) {\n addTypographyVariant(typography, \"fontWeight\", value.fontWeight, variantName);\n }\n if (value.lineHeight !== undefined) {\n addTypographyVariant(typography, \"lineHeight\", value.lineHeight, variantName);\n }\n if (value.letterSpacing) {\n addTypographyVariant(typography, \"letterSpacing\", value.letterSpacing, variantName);\n }\n } else {\n // Individual token (fontFamily, fontSize, fontWeight, dimension)\n const propertyKey = detectTypoProperty(token, groupName);\n if (!propertyKey) continue;\n const variantName = token.path[token.path.length - 1];\n const value = token.type === \"fontFamily\" && Array.isArray(token.value)\n ? (token.value as string[]).join(\", \")\n : token.type === \"dimension\"\n ? parseDimensionOrKeep(token.value as string)\n : token.value;\n addTypographyVariant(typography, propertyKey, value as string | number, variantName);\n }\n }\n};\n\nconst addTypographyVariant = (\n typography: Record<string, unknown>,\n property: string,\n value: string | number,\n variantName: string,\n) => {\n if (!typography[property]) {\n typography[property] = { base: value, variants: {} };\n return;\n }\n const prop = typography[property] as { base: unknown; variants: Record<string, unknown> };\n if (variantName === \"base\" || variantName === \"default\" || variantName === \"md\") {\n prop.base = value;\n } else {\n prop.variants[variantName] = value;\n }\n};\n\nconst detectTypoProperty = (token: ResolvedDTCGToken, groupName: string): string | null => {\n // Check token type\n if (token.type === \"fontFamily\") return \"fontFamily\";\n if (token.type === \"fontWeight\") return \"fontWeight\";\n\n // Check group or parent path naming\n const fullPath = token.path.join(\".\").toLowerCase();\n for (const [key, prop] of Object.entries(TYPO_PROPERTY_MAP)) {\n if (fullPath.includes(key)) return prop;\n }\n\n // Check group name\n const lower = groupName.toLowerCase();\n for (const [key, prop] of Object.entries(TYPO_PROPERTY_MAP)) {\n if (lower.includes(key)) return prop;\n }\n\n return null;\n};\n\n// --- Effects mapping ---\n\nconst mapEffectsTokens = (tokens: ResolvedDTCGToken[], groupName: string, effects: Record<string, unknown>) => {\n for (const token of tokens) {\n const variantName = token.path[token.path.length - 1];\n\n switch (token.type) {\n case \"shadow\": {\n const shadowStr = formatShadowValue(token.value);\n addEffectsVariant(effects, \"shadow\", shadowStr, variantName);\n break;\n }\n case \"transition\": {\n const transition = token.value as DTCGTransitionValue;\n const bezier = transition.timingFunction\n ? `cubic-bezier(${transition.timingFunction.join(\", \")})`\n : \"ease\";\n const transStr = `all ${transition.duration} ${bezier}`;\n addEffectsVariant(effects, \"transitions\", transStr, variantName);\n break;\n }\n case \"dimension\": {\n const lower = token.path.join(\".\").toLowerCase();\n if (lower.includes(\"blur\")) {\n addEffectsVariant(effects, \"blur\", parseDimensionOrKeep(token.value as string), variantName);\n }\n break;\n }\n case \"number\": {\n const lower = token.path.join(\".\").toLowerCase();\n if (lower.includes(\"opacity\")) {\n addEffectsVariant(effects, \"opacity\", token.value as number, variantName);\n } else if (lower.includes(\"z-index\") || lower.includes(\"zindex\")) {\n addEffectsVariant(effects, \"zIndex\", token.value as number, variantName);\n }\n break;\n }\n }\n }\n};\n\nconst addEffectsVariant = (\n effects: Record<string, unknown>,\n property: string,\n value: string | number,\n variantName: string,\n) => {\n if (!effects[property]) {\n effects[property] = { base: value, variants: {} };\n return;\n }\n const prop = effects[property] as { base: unknown; variants: Record<string, unknown> };\n if (variantName === \"base\" || variantName === \"default\" || variantName === \"md\") {\n prop.base = value;\n } else {\n prop.variants[variantName] = value;\n }\n};\n\n// --- Borders mapping (§14) ---\n\nconst mapBordersTokens = (tokens: ResolvedDTCGToken[], groupName: string, borders: Record<string, unknown>) => {\n for (const token of tokens) {\n const variantName = token.path[token.path.length - 1];\n\n switch (token.type) {\n case \"border\": {\n // The DTCG `border` composite carries width + style + color; only the geometry maps to\n // borders tokens (§14.4 — color is never a borders token, so it is dropped on import).\n const border = token.value as DTCGBorderValue;\n addBordersVariant(borders, \"width\", parseDimensionOrKeep(border.width), variantName);\n if (border.style) addBordersVariant(borders, \"style\", border.style, variantName);\n break;\n }\n case \"strokeStyle\": {\n addBordersVariant(borders, \"style\", String(token.value), variantName);\n break;\n }\n case \"dimension\": {\n const lower = token.path.join(\".\").toLowerCase();\n if (lower.includes(\"radius\")) {\n addBordersVariant(borders, \"radius\", parseDimensionOrKeep(token.value as string), variantName);\n } else if (lower.includes(\"offset\")) {\n addBordersVariant(borders, \"offset\", parseDimensionOrKeep(token.value as string), variantName);\n } else if (lower.includes(\"width\")) {\n addBordersVariant(borders, \"width\", parseDimensionOrKeep(token.value as string), variantName);\n }\n break;\n }\n }\n }\n};\n\nconst addBordersVariant = (\n borders: Record<string, unknown>,\n property: string,\n value: string | number,\n variantName: string,\n) => {\n if (!borders[property]) {\n borders[property] = { base: value, variants: {} };\n return;\n }\n const prop = borders[property] as { base: unknown; variants: Record<string, unknown> };\n if (variantName === \"base\" || variantName === \"default\" || variantName === \"md\") {\n prop.base = value;\n } else {\n prop.variants[variantName] = value;\n }\n};\n\n// --- Layout mapping ---\n\nconst mapLayoutTokens = (tokens: ResolvedDTCGToken[], groupName: string, layout: Record<string, unknown>) => {\n for (const token of tokens) {\n if (token.type !== \"dimension\") continue;\n const variantName = token.path[token.path.length - 1];\n const value = parseDimension(token.value as string);\n\n if (!layout.spacing) {\n layout.spacing = { base: value, variants: {} };\n }\n\n const spacing = layout.spacing as { base: number; variants: Record<string, number> };\n if (variantName === \"base\" || variantName === \"default\" || variantName === \"4\") {\n spacing.base = value;\n } else {\n spacing.variants[variantName] = value;\n }\n }\n};\n\n// --- Helpers ---\n\nconst formatShadowValue = (value: unknown): string => {\n if (Array.isArray(value)) {\n return value.map(layer => formatSingleShadow(layer as DTCGShadowLayerValue)).join(\", \");\n }\n return formatSingleShadow(value as DTCGShadowLayerValue);\n};\n\nconst formatSingleShadow = (layer: DTCGShadowLayerValue): string => {\n const parts: string[] = [];\n if (layer.inset) parts.push(\"inset\");\n parts.push(layer.offsetX, layer.offsetY, layer.blur, layer.spread, layer.color);\n return parts.join(\" \");\n};\n\nconst parseDimension = (value: string | number): number => {\n if (typeof value === \"number\") return value;\n const num = parseFloat(value);\n if (isNaN(num)) return 0;\n // Convert rem to px (assume 16px base)\n if (value.endsWith(\"rem\")) return Math.round(num * 16);\n return num;\n};\n\nconst parseDimensionOrKeep = (value: string | number): string | number => {\n if (typeof value === \"number\") return value;\n const num = parseFloat(value);\n if (isNaN(num)) return value;\n if (value.endsWith(\"px\")) return num;\n return value;\n};\n\n// --- refract round-trip (recipes via the com.theme-registry.refract extension) ---\n\n/**\n * Read the refract round-trip payload from a DTCG document's top-level `$extensions`, or `undefined`\n * when it carries none. `parseDTCGDocument` intentionally drops top-level `$extensions`, so this reads\n * `doc.$extensions` directly. Throws on a payload from a newer, unreadable schema version.\n */\nexport const readRefractExtension = (doc: DTCGDocument): RefractDTCGExtension | undefined => {\n const ext = doc.$extensions?.[REFRACT_DTCG_EXTENSION] as RefractDTCGExtension | undefined;\n if (!ext) return undefined;\n if (ext.version !== REFRACT_DTCG_EXTENSION_VERSION) {\n throw new RefractError(\n \"REFRACT_E_DTCG_VERSION\",\n `Unsupported refract DTCG extension version ${ext.version} (this build reads version ` +\n `${REFRACT_DTCG_EXTENSION_VERSION}). Upgrade @theme-registry/refract to import this document's recipes.`,\n );\n }\n return ext;\n};\n\n/**\n * Lossless `DTCG → refract` round-trip entry: {@link fromDTCG} for the property tokens, plus the\n * recipes / keyframes / containers the document stashed under `com.theme-registry.refract` reinjected\n * through createTheme's overlay. A plain DTCG document (no refract extension) round-trips to a\n * recipe-less theme — identical to `createTheme(fromDTCG(doc), { adapter })`.\n */\nexport const fromDTCGTheme = (\n doc: DTCGDocument,\n options: FromDTCGOptions & { adapter: ThemeAdapter },\n): Theme => {\n const raw = fromDTCG(doc, options);\n const ext = readRefractExtension(doc);\n return createTheme(raw, {\n adapter: options.adapter,\n propertiesOverlay: ext?.properties,\n ruleSetsOverlay: ext?.ruleSets,\n keyframesOverlay: ext?.keyframes,\n containersOverlay: ext?.containers,\n });\n};\n","import type { Theme } from \"../core\";\nimport type { Literal, ShadowDimension, ShadowLayer, TransitionPart } from \"../core\";\nimport type { ThemeModel, RuleSetGroup, Keyframe, ContainerModel, PropertyModel } from \"../core\";\nimport type { DTCGDocument, DTCGTokenType } from \"./types\";\nimport { REFRACT_DTCG_EXTENSION, REFRACT_DTCG_EXTENSION_VERSION } from \"./types\";\nimport { toHexColor } from \"../subsystems/colors/utils\";\n\n/** The refract round-trip payload stashed under {@link REFRACT_DTCG_EXTENSION}. Built IR, verbatim. */\nexport type RefractDTCGExtension = {\n version: number;\n /**\n * Per-subsystem property Model verbatim (§12 Phase 2) — the lossless channel for what the portable\n * DTCG token surface can't carry: appearance `modes` (a `PropertyOverride[]` list), `responsive`\n * overrides, derivation metadata (`{ ref, modifiers }`), and `external` passthroughs. Reinjected on\n * import via createTheme's `propertiesOverlay`. The standard resolved-literal tokens still emit\n * alongside for portability; this is refract-only (other tools ignore the extension).\n */\n properties?: Record<string, Record<string, PropertyModel>>;\n ruleSets?: Record<string, Record<string, RuleSetGroup>>;\n keyframes?: Record<string, Record<string, Keyframe>>;\n containers?: Record<string, ContainerModel>;\n};\n\n/**\n * Collect a theme's built property / rule-set / keyframe / container IR into the round-trip payload, or\n * `undefined` when the theme has none (so `includeRecipes` on an empty theme still emits no\n * `$extensions`, keeping standard output byte-identical). The Model is \"serializable as-is\", a plain walk.\n */\nconst buildRefractExtension = (model: ThemeModel): RefractDTCGExtension | undefined => {\n const properties: Record<string, Record<string, PropertyModel>> = {};\n const ruleSets: Record<string, Record<string, RuleSetGroup>> = {};\n const keyframes: Record<string, Record<string, Keyframe>> = {};\n for (const [sub, subModel] of Object.entries(model.subsystems)) {\n if (subModel.properties && Object.keys(subModel.properties).length) properties[sub] = subModel.properties;\n if (subModel.ruleSets && Object.keys(subModel.ruleSets).length) ruleSets[sub] = subModel.ruleSets;\n if (subModel.keyframes && Object.keys(subModel.keyframes).length) keyframes[sub] = subModel.keyframes;\n }\n const hasProperties = Object.keys(properties).length > 0;\n const hasRuleSets = Object.keys(ruleSets).length > 0;\n const hasKeyframes = Object.keys(keyframes).length > 0;\n const hasContainers = !!model.containers && Object.keys(model.containers).length > 0;\n if (!hasProperties && !hasRuleSets && !hasKeyframes && !hasContainers) return undefined;\n return {\n version: REFRACT_DTCG_EXTENSION_VERSION,\n ...(hasProperties ? { properties } : {}),\n ...(hasRuleSets ? { ruleSets } : {}),\n ...(hasKeyframes ? { keyframes } : {}),\n ...(hasContainers ? { containers: model.containers } : {}),\n };\n};\n\nexport type ToDTCGOptions = {\n /** Name for the DTCG document. */\n name?: string;\n\n /** Whether to include breakpoints as dimension tokens. Default: true. */\n includeBreakpoints?: boolean;\n\n /**\n * Stash the theme's built Model IR — **property tokens (incl. modes / responsive / derivation refs /\n * external), rule-sets, keyframes, containers** — under the reverse-DNS `com.theme-registry.refract`\n * `$extensions` key, so the document round-trips `refract → DTCG → refract` **losslessly** via\n * {@link fromDTCGTheme} (§12 Phase 2 widened this from recipes-only to the whole Model). **Not\n * portable** — other DTCG tools ignore the extension and see the resolved property tokens only.\n * Default `false` (standard output stays byte-identical).\n */\n includeRecipes?: boolean;\n};\n\n/**\n * Convert a built theme's tokens into a DTCG-compliant JSON document.\n *\n * **Model-first re-port:** this walks the flat, format-neutral `theme.tokens` map\n * (`\"<subsystem>.<property>[.<variant>]\" -> Ref`) — the single source of truth that\n * replaced the retired per-subsystem `theme.<sub>.tokens` shape. Each token path is\n * resolved to a concrete literal via `theme.resolveToken` (following aliases and\n * running `lighten` / `darken` derivations), then re-grouped into DTCG groups.\n *\n * DTCG carries **property tokens only** — recipes / composition are out of scope, and\n * layout structural-config knobs (property names containing `--`) are skipped.\n *\n * Returns a plain object — modify it freely before writing to a file.\n */\nexport const toDTCG = (theme: Theme, options?: ToDTCGOptions): DTCGDocument => {\n const doc: DTCGDocument = {};\n\n if (options?.name) {\n doc.$name = options.name;\n }\n\n // Breakpoints — read from the Model, emitted as dimension tokens.\n const breakpoints = theme.model.breakpoints;\n if (options?.includeBreakpoints !== false && breakpoints && Object.keys(breakpoints).length) {\n const bp: Record<string, unknown> = { $type: \"dimension\" as DTCGTokenType };\n for (const [name, value] of Object.entries(breakpoints)) {\n bp[name] = { $value: `${value}px` };\n }\n doc.breakpoint = bp;\n }\n\n // Group the flat token map by subsystem → property, resolving each path to a literal.\n const grouped = groupTokens(theme);\n\n // Resolve a `colors.*` (or any) token path to its literal for embedding in a composed shadow\n // string; falls back to the raw path if unresolvable (defensive).\n const resolveColor = (path: string): string => {\n try {\n return String(theme.resolveToken(path));\n } catch {\n return path;\n }\n };\n\n // Colors — { $type: color, <name>: { base, text?, <variant> } }\n const colors = grouped.get(\"colors\");\n if (colors) {\n const group: Record<string, unknown> = { $type: \"color\" as DTCGTokenType };\n for (const [name, prop] of colors) {\n const node: Record<string, unknown> = {};\n if (prop.base !== undefined) {\n node.base = { $value: toHexColor(String(prop.base)) };\n }\n for (const [member, value] of Object.entries(prop.members)) {\n node[member] = { $value: toHexColor(String(value)) };\n }\n group[name] = node;\n }\n doc.color = group;\n }\n\n // Typography — nested under `doc.typography`, one group per property.\n const typography = grouped.get(\"typography\");\n if (typography) {\n const typo: Record<string, unknown> = {};\n for (const [propName, prop] of typography) {\n const type = getTypographyTokenType(propName);\n const group: Record<string, unknown> = { $type: type };\n if (prop.base !== undefined) {\n group.base = { $value: formatTypoValue(prop.base, prop.baseUnit) };\n }\n for (const [variant, value] of Object.entries(prop.members)) {\n group[variant] = { $value: formatTypoValue(value, prop.memberUnits[variant]) };\n }\n typo[propName] = group;\n }\n doc.typography = typo;\n }\n\n // Effects — one top-level group per property, named/typed by getEffectsGroupInfo.\n const effects = grouped.get(\"effects\");\n if (effects) {\n for (const [propName, prop] of effects) {\n const { groupName, type } = getEffectsGroupInfo(propName);\n if (!doc[groupName]) {\n doc[groupName] = { $type: type };\n }\n const group = doc[groupName] as Record<string, unknown>;\n // §15: a structured shadow/transition token composes to a CSS string at the DTCG boundary\n // (its `colors.*` color ref resolved to a literal) — consistent with how a string-authored\n // shadow already exports. A fully-structured DTCG composite round-trip is a future enhancement.\n if (prop.base !== undefined) {\n group.base = { $value: formatEffectsValue(propName, prop.base, resolveColor, prop.baseUnit) };\n }\n for (const [variant, value] of Object.entries(prop.members)) {\n group[variant] = { $value: formatEffectsValue(propName, value, resolveColor, prop.memberUnits[variant]) };\n }\n }\n }\n\n // Borders (§14) — one top-level group per property (radius/width/offset → dimension px,\n // style → strokeStyle). Border geometry moved out of effects; color is never a borders token.\n const borders = grouped.get(\"borders\");\n if (borders) {\n for (const [propName, prop] of borders) {\n const { groupName, type } = getBordersGroupInfo(propName);\n if (!doc[groupName]) {\n doc[groupName] = { $type: type };\n }\n const group = doc[groupName] as Record<string, unknown>;\n if (prop.base !== undefined) {\n group.base = { $value: formatBordersValue(prop.base, prop.baseUnit) };\n }\n for (const [variant, value] of Object.entries(prop.members)) {\n group[variant] = { $value: formatBordersValue(value, prop.memberUnits[variant]) };\n }\n }\n }\n\n // Layout (spacing / gutters / aspectRatio) — dimension tokens. Structural-config\n // knobs (`columns--*` / `container--*`) are internal, not interchange tokens.\n const layout = grouped.get(\"layout\");\n if (layout) {\n for (const [propName, prop] of layout) {\n if (propName.includes(\"--\")) continue;\n const groupName = propName;\n if (!doc[groupName]) {\n doc[groupName] = { $type: \"dimension\" as DTCGTokenType };\n }\n const group = doc[groupName] as Record<string, unknown>;\n if (prop.base !== undefined) {\n group.base = { $value: formatDimensionValue(prop.base, prop.baseUnit) };\n }\n for (const [variant, value] of Object.entries(prop.members)) {\n group[variant] = { $value: formatDimensionValue(value, prop.memberUnits[variant]) };\n }\n }\n }\n\n // §DTCG round-trip — opt-in: stash the built rule-set/keyframe/container IR under the refract\n // extension key. Only touched when `includeRecipes` is set AND the theme actually has recipes, so\n // the standard property-token document stays byte-identical by default.\n if (options?.includeRecipes) {\n const ext = buildRefractExtension(theme.model);\n if (ext) doc.$extensions = { ...(doc.$extensions ?? {}), [REFRACT_DTCG_EXTENSION]: ext };\n }\n\n return doc;\n};\n\n// --- Flat-token grouping ---\n\ntype PropTokens = {\n /** the `<sub>.<prop>` base token, if present. */\n base?: Literal;\n /** the `<sub>.<prop>.<member>` variants / extras (e.g. colors' `text`). */\n members: Record<string, Literal>;\n /** §21 resolved length unit for `base` (absent = unit-less / non-length / raw string). */\n baseUnit?: string;\n /** §21 resolved length unit per member. */\n memberUnits: Record<string, string>;\n};\n\n/** A resolved dimension → DTCG text: append the §21 unit baked on the Model leaf; a unit-less value\n * (lineHeight, opacity, aspectRatio) or a raw string passes through untouched. */\nconst dimText = (value: Literal, unit?: string): string | number =>\n unit !== undefined ? `${value}${unit}` : value;\n\n/**\n * Group the flat `theme.tokens` map into `subsystem -> property -> { base, members }`,\n * resolving each path to a concrete literal via `theme.resolveToken`. Unresolvable\n * paths are skipped (defensive — a well-formed Model resolves everything).\n */\nconst groupTokens = (theme: Theme): Map<string, Map<string, PropTokens>> => {\n const out = new Map<string, Map<string, PropTokens>>();\n for (const path of Object.keys(theme.tokens)) {\n const dot = path.indexOf(\".\");\n if (dot < 0) continue;\n const subsystem = path.slice(0, dot);\n const rest = path.slice(dot + 1);\n const dot2 = rest.indexOf(\".\");\n const property = dot2 < 0 ? rest : rest.slice(0, dot2);\n const member = dot2 < 0 ? undefined : rest.slice(dot2 + 1);\n\n // §W6b / §12 Phase 2: an EXTERNAL token is a passthrough to a parent-owned var (`var(--…)`); it\n // has no value this document owns. Skip it from the portable token surface — emitting it as a\n // `var(--…)` colour would break re-import (colours reject `var()`). The lossless refract extension\n // carries it verbatim (its `PropertyModel.base` keeps `external`), so the round-trip restores it.\n const ref = theme.tokens[path];\n if (ref?.external !== undefined) continue;\n let value: Literal;\n if (ref?.struct !== undefined) {\n value = ref.struct as unknown as Literal;\n } else {\n try {\n value = theme.resolveToken(path);\n } catch {\n continue;\n }\n }\n const unit = ref?.unit; // §21 resolved length unit (absent for unit-less / raw / struct tokens)\n\n let subMap = out.get(subsystem);\n if (!subMap) {\n subMap = new Map<string, PropTokens>();\n out.set(subsystem, subMap);\n }\n let prop = subMap.get(property);\n if (!prop) {\n prop = { members: {}, memberUnits: {} };\n subMap.set(property, prop);\n }\n if (member === undefined) {\n prop.base = value;\n if (unit !== undefined) prop.baseUnit = unit;\n } else {\n prop.members[member] = value;\n if (unit !== undefined) prop.memberUnits[member] = unit;\n }\n }\n return out;\n};\n\n// --- Value formatting (per subsystem/property) ---\n\nconst getTypographyTokenType = (propName: string): DTCGTokenType => {\n switch (propName) {\n case \"fontFamily\": return \"fontFamily\";\n case \"fontWeight\": return \"fontWeight\";\n case \"fontSize\":\n case \"letterSpacing\": return \"dimension\";\n default: return \"number\";\n }\n};\n\n/** Typography value → DTCG. Length props (fontSize, letterSpacing) carry a resolved unit; the rest\n * (fontFamily string, fontWeight/lineHeight numbers) are unit-less → pass through. */\nconst formatTypoValue = (value: Literal, unit?: string): string | number => dimText(value, unit);\n\nconst getEffectsGroupInfo = (propName: string): { groupName: string; type: DTCGTokenType } => {\n switch (propName) {\n case \"shadow\": return { groupName: \"shadow\", type: \"shadow\" };\n case \"transitions\": return { groupName: \"transition\", type: \"transition\" };\n case \"blur\": return { groupName: propName, type: \"dimension\" };\n case \"opacity\":\n case \"zIndex\": return { groupName: propName, type: \"number\" };\n default: return { groupName: propName, type: \"dimension\" };\n }\n};\n\n/** A resolved shadow geometry field (§21 `{value,unit}`, or a bare number) → CSS text. */\nconst dtcgShadowDim = (dim: ShadowDimension): string =>\n typeof dim === \"number\" ? `${dim}px` : `${dim.value}${dim.unit}`;\n\n/** The layer's shared length unit — from the first resolved geometry field; `px` if none resolved. */\nconst dtcgLayerUnit = (layer: ShadowLayer): string => {\n for (const field of [layer.offsetX, layer.offsetY, layer.blur, layer.spread]) {\n if (field !== undefined && typeof field !== \"number\") return field.unit;\n }\n return \"px\";\n};\n\n/** Compose a structured shadow value (§15) → a CSS `box-shadow` string with color refs resolved\n * (translucency is carried by the referenced colour — an `alpha` colour variant, §13.3). Geometry\n * fields carry a resolved unit (§21); an absent (required) offset defaults to `0` in the layer's unit. */\nconst composeDtcgShadow = (layers: ShadowLayer[], resolveColor: (path: string) => string): string =>\n layers\n .map(layer => {\n const zero = `0${dtcgLayerUnit(layer)}`;\n const len = (dim: ShadowDimension | undefined): string => (dim === undefined ? zero : dtcgShadowDim(dim));\n const parts: string[] = [];\n if (layer.inset) parts.push(\"inset\");\n parts.push(len(layer.offsetX), len(layer.offsetY));\n if (layer.spread != null) parts.push(len(layer.blur), len(layer.spread));\n else if (layer.blur != null) parts.push(len(layer.blur));\n if (layer.color) parts.push(resolveColor(layer.color));\n return parts.join(\" \");\n })\n .join(\", \");\n\n/** Compose a structured transition value (§15) → a CSS `transition` string. */\nconst composeDtcgTransition = (parts: TransitionPart[]): string =>\n parts\n .map(part => {\n const segs: string[] = [part.property];\n if (part.duration != null || part.delay != null) segs.push(`${part.duration ?? 0}ms`);\n if (part.timingFunction) segs.push(part.timingFunction);\n if (part.delay != null) segs.push(`${part.delay}ms`);\n return segs.join(\" \");\n })\n .join(\", \");\n\nconst formatEffectsValue = (\n propName: string,\n value: Literal,\n resolveColor: (path: string) => string,\n unit?: string,\n): string | number => {\n // §15: shadow/transitions arrive as a structured array (cast to `Literal` in groupTokens).\n if (Array.isArray(value)) {\n return propName === \"transitions\"\n ? composeDtcgTransition(value as TransitionPart[])\n : composeDtcgShadow(value as ShadowLayer[], resolveColor);\n }\n // `blur` carries a resolved length unit (§21); `opacity`/`zIndex` are unit-less → pass through.\n return dimText(value, unit);\n};\n\nconst getBordersGroupInfo = (propName: string): { groupName: string; type: DTCGTokenType } => {\n switch (propName) {\n case \"radius\": return { groupName: \"radius\", type: \"dimension\" };\n case \"width\": return { groupName: \"borderWidth\", type: \"dimension\" };\n case \"offset\": return { groupName: \"outlineOffset\", type: \"dimension\" };\n case \"style\": return { groupName: \"borderStyle\", type: \"strokeStyle\" };\n default: return { groupName: propName, type: \"dimension\" };\n }\n};\n\n/** Borders geometry: radius/width/offset carry a resolved length unit (§21); `style` is a raw\n * strokeStyle string (no unit → passes through). */\nconst formatBordersValue = (value: Literal, unit?: string): string | number => dimText(value, unit);\n\n/** Layout dimension: spacing/gutters/sizes carry a resolved unit (§21); aspectRatio is unit-less. */\nconst formatDimensionValue = (value: Literal, unit?: string): string | number => dimText(value, unit);\n","/**\n * `emitTheme` — the programmatic build API (Node-only, §7 Step 10b).\n *\n * The build-time delivery method (alongside runtime `createTheme`): build a theme, ask the adapter\n * to `emit()` its self-contained static output, and write it to disk. After this a consuming app\n * imports the emitted files and drops refract at runtime.\n *\n * Adapter-agnostic by construction — it takes the fully-constructed adapter *object* (the config's\n * `import` is the extensibility seam; `emitTheme` imports zero adapters itself). It orchestrates ONLY\n * over the public surface (`createTheme`) + the `emit()` / `VENDOR_HELPERS` seams; no reach-in.\n *\n * Two vendoring lanes (Option A, locked 2026-07-11):\n * - `emit().vendorHelpers` — *theme-specific* live helpers the adapter generates (e.g. the SC media\n * module with baked `@media` strings). Always written when present.\n * - `helpers` opt-in — *shared static* helpers (color-math) materialized here from their single\n * source via `VENDOR_HELPERS`. Explicit opt-in — a target names which it wants; never auto-emitted.\n */\nimport { mkdirSync, writeFileSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport type { ThemeAdapter, Emit } from \"../core/ThemeAdapter\";\nimport type { RawTheme } from \"../core/rawTheme\";\nimport type { MediaConfig } from \"../core/media\";\nimport type { UnitsConfig } from \"../core/units\";\nimport { createTheme } from \"../core/createTheme\";\nimport { buildMediaDescriptor, buildContainerDescriptors, mediaQueryString, resolveMediaConfig } from \"../core/media\";\nimport { VENDOR_HELPERS, findVendorHelper } from \"./vendor\";\nimport { readVendorSource, transpileToEsm } from \"./paths\";\nimport { resolveEmitPlan } from \"./emit\";\nimport { buildGuide } from \"./guide\";\nimport { toDTCG } from \"../dtcg\";\n\n/** Opt-in self-documenting output config (§C). `true` uses defaults; the object tunes names/overlay. */\nexport type GuideConfig = {\n /** Published package specifier — adds a by-specifier import overlay to the guide (else relative-only). */\n readonly packageName?: string;\n /** Narrative guide filename (default `\"llms.txt\"`). */\n readonly llmsFile?: string;\n /** Machine index filename (default `\"manifest.json\"`); `false` suppresses it. */\n readonly manifestFile?: string | false;\n};\n\nexport interface EmitThemeOptions {\n /** The raw theme config (same shape `createTheme` consumes). */\n readonly raw: RawTheme;\n /** The fully-constructed adapter object (`createCssAdapter(...)`, an SC adapter, …). */\n readonly adapter: ThemeAdapter;\n /** Directory to write the emitted files into (created recursively). */\n readonly outDir: string;\n /** Shared vendorable helper ids to materialize from `VENDOR_HELPERS` (e.g. `[\"color-math\"]`). */\n readonly helpers?: readonly string[];\n /** Output-shape directive (§9); normalized to a plan and passed to the adapter's `emit(plan)`. */\n readonly emit?: Emit;\n /** Media unit config (§10.5) — threaded into `createTheme` + the emit rebind so em/rem reaches disk. */\n readonly media?: MediaConfig;\n /** Declaration-value length units (§21) — threaded into `createTheme` so built output honors the role map. */\n readonly units?: UnitsConfig;\n /** Divisor when a deferred length resolves to `rem` (§21). Defaults to 16. */\n readonly baseFontSize?: number;\n /** §C — emit a self-documenting `llms.txt` + `manifest.json` into `outDir`. Off by default. */\n readonly guide?: boolean | GuideConfig;\n}\n\nexport interface EmitThemeResult {\n readonly outDir: string;\n /** Absolute paths of every file written, in write order. */\n readonly files: string[];\n}\n\nexport async function emitTheme(options: EmitThemeOptions): Promise<EmitThemeResult> {\n const { raw, adapter, outDir, helpers = [], emit, media: mediaConfig, units, baseFontSize, guide } = options;\n\n const theme = createTheme(raw, { adapter, media: mediaConfig, units, baseFontSize });\n\n // Re-bind with the PLAIN core media descriptor: `emit()` isn't on the theme surface, and an\n // adapter may decorate `theme.media` (SC → tagged templates), whereas emitted vendored helpers\n // (SC's media.ts) need the plain `@media` query strings. This mirrors the 10a gate.\n const media = buildMediaDescriptor(theme.model.breakpoints, o =>\n mediaQueryString(o, resolveMediaConfig(mediaConfig)),\n );\n const containers = buildContainerDescriptors(theme.model.containers, mediaConfig);\n const bound = adapter.bind(theme.model, { media, containers, resolve: theme.resolveToken });\n\n if (!bound.emit) {\n throw new Error(`Adapter \"${adapter.name}\" does not implement emit(); it cannot build to disk.`);\n }\n const emitted = bound.emit(resolveEmitPlan(emit));\n\n const written: string[] = [];\n mkdirSync(outDir, { recursive: true });\n const write = (name: string, contents: string): void => {\n const dest = join(outDir, name);\n mkdirSync(dirname(dest), { recursive: true });\n writeFileSync(dest, contents, \"utf8\");\n written.push(dest);\n };\n\n // Static consume-as-is artifacts (theme.css, …).\n for (const [name, contents] of Object.entries(emitted.files)) write(name, contents);\n // Theme-specific vendored helpers (SC media.ts) — always ride along with the adapter's output.\n for (const [name, contents] of Object.entries(emitted.vendorHelpers ?? {})) write(name, contents);\n\n // Shared static vendored helpers — materialized from their single source (no adapter re-embed).\n for (const id of helpers) {\n const helper = findVendorHelper(id);\n if (!helper) {\n throw new Error(\n `Unknown vendor helper \"${id}\". Known: ${VENDOR_HELPERS.map(h => h.id).join(\", \")}.`,\n );\n }\n // `transpileToEsm` lazy-loads the optional `typescript` peer (Step 10e) — reached only here, on\n // an explicit `helpers` opt-in, so a helper-free CSS build never needs `typescript` installed.\n write(helper.outfile, await transpileToEsm(readVendorSource(helper.source)));\n }\n\n // §C — self-documenting output: an llms.txt guide + manifest.json describing THIS theme's real\n // names, written beside the artifacts so they travel with any distribution form. Opt-in.\n if (guide) {\n const cfg: GuideConfig = guide === true ? {} : guide;\n const built = buildGuide(bound.describeUsage(), toDTCG(theme), {\n files: Object.keys(emitted.files),\n packageName: cfg.packageName,\n llmsFile: cfg.llmsFile,\n manifestFile: cfg.manifestFile,\n });\n for (const [name, contents] of Object.entries(built.files)) write(name, contents);\n }\n\n return { outDir, files: written };\n}\n","/**\n * `theme.config.(ts|js|mjs)` — the primary build interface + the adapter seam (Node-only, §7 10b).\n *\n * The config is USER CODE in the user's project: it `import`s the adapter from wherever it lives\n * (refract for CSS, an external package for SC/third-party) and hands the CLI a fully-constructed\n * adapter object per target. That `import` IS the extensibility seam — same model as\n * Rollup/Vite/PostCSS/Jest — so adapter *options* (`prefix`/…) are passed at construction in the\n * config, not as CLI flags. Multiple targets let one theme emit CSS + SC at once.\n *\n * Loader (chosen 2026-07-11 — NO new dep): reuse `typescript` (an OPTIONAL peer, lazy-loaded as of\n * Step 10e — only a `.ts` config pays for it). A `.ts` config is compiled via a `ts.createProgram`\n * **graph compile** (§8b): the config **and its local relative `.ts` graph** are type-stripped to\n * adjacent hidden `.mjs` files, so a `.ts` config can `import` a sibling `theme.raw.ts` (the 8a\n * `RawTheme` payoff). Bare specifiers and relative `.mjs`/`.js`/`.json` stay external (resolved at\n * their original adjacent location). `.mjs`/`.js` configs import directly. See {@link compileTsConfigGraph}\n * for the emit-location + specifier-rewrite details. Rejected jiti/esbuild (both absent → a new dep).\n */\nimport { existsSync } from \"node:fs\";\nimport { extname, join, resolve } from \"node:path\";\nimport { pathToFileURL } from \"node:url\";\nimport type { ThemeAdapter, Emit } from \"../core/ThemeAdapter\";\nimport type { RawTheme } from \"../core/rawTheme\";\nimport type { MediaConfig } from \"../core/media\";\nimport type { UnitsConfig } from \"../core/units\";\nimport type { GuideConfig } from \"./emitTheme\";\nimport { compileTsConfigGraph } from \"./paths\";\n\n/** One emit target: an adapter + where to write it, plus which shared vendored helpers it wants. */\nexport interface EmitTarget {\n readonly adapter: ThemeAdapter;\n readonly outDir: string;\n readonly helpers?: readonly string[];\n /** Optional label — lets `refract build --target <name>` select this target (else index/outDir). */\n readonly name?: string;\n /** Optional output-shape directive (§9): single / split / subsystem / components. Default = single. */\n readonly emit?: Emit;\n /**\n * §C — emit a self-documenting `llms.txt` + `manifest.json` into this target's `outDir`, so a\n * published/zipped theme carries its own AI consumption guide (real class names / token paths) for\n * a downstream dev who has neither refract nor its skills. `true` uses defaults; an object tunes the\n * file names or adds a `packageName` for a by-specifier import overlay. Off by default.\n */\n readonly guide?: boolean | GuideConfig;\n}\n\n/** The `theme.config` shape: the raw theme + one or more emit targets. */\nexport interface ThemeConfig {\n readonly raw: RawTheme;\n readonly targets: readonly EmitTarget[];\n /**\n * Media-query output config (§10.5) — `{ unit: \"px\" | \"em\" | \"rem\"; baseFontSize }`. Applies to\n * both the viewport `@media` and container `@container` widths (breakpoints/container thresholds are\n * authored as px numbers; `unit` controls the emitted unit). Defaults to px.\n */\n readonly media?: MediaConfig;\n /**\n * Declaration-value length units (§21) — a token-path role map (`units.default`, `units[\"<subsystem>\"]`,\n * `units[\"<subsystem>.<property>\"]`), most-specific wins over the built-in seed. Resolved once, format-\n * neutrally, so every target emits the same unit. The build-time twin of `createTheme`'s `units` option.\n */\n readonly units?: UnitsConfig;\n /** Divisor when a deferred length resolves to `rem` (§21). Defaults to 16. */\n readonly baseFontSize?: number;\n}\n\n/** Identity fn — types the config authored in `theme.config.(ts|js|mjs)`. */\nexport const defineConfig = (config: ThemeConfig): ThemeConfig => config;\n\nconst CONFIG_BASENAME = \"theme.config\";\nconst EXT_ORDER = [\".ts\", \".mjs\", \".js\"] as const;\n\n/** Find `theme.config.{ts,mjs,js}` in `fromDir`, honoring the ts→mjs→js resolution order. */\nexport const findConfigFile = (fromDir: string = process.cwd()): string | undefined => {\n for (const ext of EXT_ORDER) {\n const candidate = join(fromDir, `${CONFIG_BASENAME}${ext}`);\n if (existsSync(candidate)) return candidate;\n }\n return undefined;\n};\n\n/**\n * Import a config module. A `.ts` file is graph-compiled (config + its relative `.ts` graph → adjacent\n * hidden `.mjs` files; see {@link compileTsConfigGraph}) then the emitted entry is dynamically imported\n * and every temp file removed; `.mjs`/`.js` are imported directly.\n */\nlet importCounter = 0;\nasync function importConfigModule(path: string): Promise<Record<string, unknown>> {\n if (extname(path) !== \".ts\") {\n // Cache-bust the ESM import: Node caches modules by URL, so a repeated `loadConfig` on an *edited*\n // config (e.g. a long-lived MCP server watching `theme.config.mjs`) would otherwise re-get the stale\n // module. A fresh query key forces a re-read. Harmless for one-shot CLI use. (A `.ts` config already\n // re-reads: `compileTsConfigGraph` emits a fresh temp file each call.)\n const url = `${pathToFileURL(path).href}?v=${++importCounter}`;\n return (await import(url)) as Record<string, unknown>;\n }\n const { entry, cleanup } = await compileTsConfigGraph(path);\n try {\n return (await import(pathToFileURL(entry).href)) as Record<string, unknown>;\n } finally {\n cleanup();\n }\n}\n\nexport interface LoadedConfig {\n readonly config: ThemeConfig;\n /** Absolute path the config was loaded from. */\n readonly path: string;\n}\n\n/**\n * Resolve + load a `theme.config`. `configPath` (a CLI `--config` override) wins; otherwise the\n * ts→mjs→js search in `cwd`. Returns the `defineConfig(...)` object (default or named `config` export).\n */\nexport async function loadConfig(\n options: { cwd?: string; configPath?: string } = {},\n): Promise<LoadedConfig> {\n const cwd = options.cwd ?? process.cwd();\n const path = options.configPath ? resolve(cwd, options.configPath) : findConfigFile(cwd);\n if (!path || !existsSync(path)) {\n const where = options.configPath ? `\"${options.configPath}\"` : `${CONFIG_BASENAME}.(ts|mjs|js) in \"${cwd}\"`;\n throw new Error(`No theme config found at ${where}.`);\n }\n\n const mod = await importConfigModule(path);\n const config = (mod.default ?? mod.config ?? mod) as ThemeConfig;\n if (!config || typeof config !== \"object\" || !Array.isArray(config.targets)) {\n throw new Error(`\"${path}\" must export (default) a defineConfig({ raw, targets }) object.`);\n }\n return { config, path };\n}\n","/**\n * `refract init` — scaffold a runnable `theme.config.(ts|js|mjs)` (Node-only, §7 Step 10c).\n *\n * The config is the primary build interface + the adapter seam (10b): it is USER CODE that `import`s\n * the adapter it wants. `init` writes a starter that is runnable out of the box — it uses the CSS\n * adapter package (`@theme-registry/refract-css`) + `defineConfig` (refract's `./build` subpath), a\n * minimal inline `raw`, and one CSS target — plus commented lines showing how to add another adapter\n * target (e.g. an SC package) once installed. Post monorepo split every adapter lives in its own\n * sibling package, so the scaffold imports the CSS adapter from `refract-css`, not from core. Adapter\n * *options* are passed at construction in the config (`createCssAdapter({ … })`), never as CLI flags\n * (a flag can't carry an imported object).\n *\n * Default variant is `.ts`; `--js` / `--mjs` pick the ESM variants. All three share one ESM body\n * (the `.ts` file only differs by extension — it lets the author add types later); the difference is\n * purely Node's module-resolution semantics (`.mjs` is always ESM; `.js` follows the project type).\n * `init` refuses to clobber an existing config unless `--force`.\n */\nimport { existsSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { findPackageRoot } from \"./paths\";\n\nexport type ConfigVariant = \"ts\" | \"js\" | \"mjs\";\n\n/**\n * The sibling package the CSS adapter ships from post monorepo split. `defineConfig`/`RawTheme` still\n * come from core (`${packageName}/build`); only the adapter itself moved to its own package.\n */\nexport const CSS_ADAPTER_PACKAGE = \"@theme-registry/refract-css\";\n\nexport interface InitOptions {\n /** Project dir to scaffold into (default `process.cwd()`). */\n readonly cwd?: string;\n /** Which config flavor to write (default `\"ts\"`). */\n readonly variant?: ConfigVariant;\n /** Overwrite an existing config instead of refusing (default `false`). */\n readonly force?: boolean;\n /** Package name to import from in the scaffold (default: this package's own `name`). */\n readonly packageName?: string;\n}\n\nexport interface InitResult {\n /** Absolute path of the written config. */\n readonly path: string;\n readonly variant: ConfigVariant;\n /** The package name the scaffold imports from. */\n readonly packageName: string;\n}\n\n/** Read this package's own `name` (so the scaffold imports the currently-installed package name). */\nexport function readOwnPackageName(): string {\n const pkgPath = join(findPackageRoot(), \"package.json\");\n const pkg = JSON.parse(readFileSync(pkgPath, \"utf8\")) as { name?: string };\n return pkg.name ?? \"@theme-registry/refract\";\n}\n\n/** The scaffolded config body — one shared ESM template across ts/js/mjs. */\nexport function scaffoldConfig(packageName: string): string {\n return `import { defineConfig } from \"${packageName}/build\";\nimport { createCssAdapter } from \"${CSS_ADAPTER_PACKAGE}\";\n\n// refract build config. \\`refract build\\` reads this file, builds the theme once, and writes\n// each target's emitted files into that target's \\`outDir\\`. The config is your code: it \\`import\\`s\n// the adapters it wants and passes their options at construction (not via CLI flags).\nexport default defineConfig({\n // The raw theme — authored in refract's nested slices. Extend with typography/effects/layout.\n raw: {\n breakpoints: { sm: 576, md: 768, lg: 1024, xl: 1280 },\n colors: {\n // Starter palette passes its own contrast audit (WCAG AA): white text clears 4.5:1 on both\n // bases. Keep that when you retune — the auditor is a shipped feature; the default should model it.\n primary: { base: \"#1864ab\", text: \"#fff\", variants: { dark: \"#0b4a86\", light: \"#a5d8ff\" } },\n neutral: { base: \"#495057\", text: \"#fff\", variants: { light: \"#f1f3f5\", dark: \"#212529\" } },\n recipes: {\n solid: {\n primary: { background: \"primary\", color: \"primary.text\" },\n neutral: { background: \"neutral.light\", color: \"neutral.dark\" },\n },\n },\n },\n },\n targets: [\n // The CSS adapter (from @theme-registry/refract-css). Pass its options here, at construction.\n { adapter: createCssAdapter(/* { colors: { prefix: \"app\" } } */), outDir: \"dist/theme\" },\n\n // Add another adapter target once its package is installed, e.g.:\n // import { createStyledComponentsAdapter } from \"@theme-registry/refract-styled-components\";\n // { adapter: createStyledComponentsAdapter(), outDir: \"dist/theme-sc\" },\n ],\n});\n`;\n}\n\n/**\n * Scaffold `theme.config.<variant>` into `cwd`. Throws if the file exists and `force` is not set\n * (never silently clobbers a user's config).\n */\nexport function runInit(options: InitOptions = {}): InitResult {\n const cwd = options.cwd ?? process.cwd();\n const variant = options.variant ?? \"ts\";\n const packageName = options.packageName ?? readOwnPackageName();\n\n const path = join(cwd, `theme.config.${variant}`);\n if (existsSync(path) && !options.force) {\n throw new Error(\n `theme.config.${variant} already exists at \"${path}\". Pass --force to overwrite it.`,\n );\n }\n\n writeFileSync(path, scaffoldConfig(packageName), \"utf8\");\n return { path, variant, packageName };\n}\n","/**\n * `refract import` — seed a theme from a DTCG `tokens.json` (Node-only, §7 Step 10f).\n *\n * DTCG is edge interchange, NOT a build input: rather than load `tokens.json` on every build, this\n * runs `fromDTCG` ONCE and writes a `theme.raw.ts` the user then owns and edits — the same ownership\n * model as `init` (blank template), just seeded from a DTCG document instead. Two reasons it must be a\n * one-shot scaffold, not a live loader:\n * - `fromDTCG` is heuristic + lossy (guesses subsystem mapping, drops the DTCG `border` composite's\n * color, rounds rem→px). Baking those guesses in on every build would hide them; as generated\n * source they land as an editor-reviewable diff.\n * - DTCG carries **property tokens only** — recipes / composition / states / components have no DTCG\n * representation, so the seed is always incomplete and needs hand-authoring on top.\n *\n * Emits a typed `theme.raw.ts` (`export const raw: RawTheme = …`) and, unless `--raw-only`, a runnable\n * `theme.config.ts` that imports it (the §8b sibling-`.ts` graph-compile makes the extensionless\n * `./theme.raw` import resolve). Refuses to clobber either file unless `--force`.\n *\n * `fromDTCG` is imported as a relative `../dtcg` static import (NOT the `./dtcg` package subpath) so the\n * in-repo gate resolves with no dist build — the same pattern as the rest of `src/build/`.\n */\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { basename, dirname, isAbsolute, join, resolve } from \"node:path\";\nimport { fromDTCG, type DTCGDocument, type FromDTCGOptions } from \"../dtcg\";\nimport { readOwnPackageName, CSS_ADAPTER_PACKAGE } from \"./init\";\n\nconst DEFAULT_RAW_OUT = \"theme.raw.ts\";\nconst DEFAULT_CONFIG_OUT = \"theme.config.ts\";\n\nexport interface ImportOptions {\n /** Project dir to scaffold into (default `process.cwd()`). */\n readonly cwd?: string;\n /** Path to the DTCG `tokens.json` to import (relative to cwd or absolute). Required. */\n readonly input: string;\n /** `--out` — the raw-theme file to write (default `theme.raw.ts`, resolved against cwd). */\n readonly out?: string;\n /** `--raw-only` — write only `theme.raw.ts`, skip the companion `theme.config.ts` (default false). */\n readonly rawOnly?: boolean;\n /** `--force` — overwrite existing files instead of refusing (default false). */\n readonly force?: boolean;\n /** `--breakpoint-group` — DTCG group whose dimension tokens seed the breakpoints. */\n readonly breakpointGroup?: string;\n /** `--breakpoints` — explicit `{ name: px }` fallback when the doc carries no breakpoint group. */\n readonly breakpoints?: Record<string, number>;\n /** Package name the generated files import from (default: this package's own `name`). */\n readonly packageName?: string;\n}\n\nexport interface ImportResult {\n /** Absolute path of the DTCG document read. */\n readonly inputFile: string;\n /** Absolute path of the written `theme.raw.ts`. */\n readonly rawFile: string;\n /** Absolute path of the written `theme.config.ts`, or `undefined` when `--raw-only`. */\n readonly configFile?: string;\n /** Top-level raw keys produced (e.g. `[\"breakpoints\", \"colors\", \"typography\"]`). */\n readonly sections: readonly string[];\n /** Per-subsystem property count seeded from the document (excludes `breakpoints`). */\n readonly counts: Readonly<Record<string, number>>;\n}\n\n/** Parse a `--breakpoints \"sm:576,md:768\"` flag into `{ sm: 576, md: 768 }`. Ignores malformed pairs. */\nexport function parseBreakpointsFlag(spec: string): Record<string, number> {\n const out: Record<string, number> = {};\n for (const pair of spec.split(\",\")) {\n const [name, raw] = pair.split(\":\");\n const key = name?.trim();\n const value = Number.parseFloat((raw ?? \"\").trim());\n if (key && Number.isFinite(value)) out[key] = value;\n }\n return out;\n}\n\n/** The generated `theme.raw.ts` body — a typed `RawTheme` the user then owns and extends. */\nexport function scaffoldRaw(packageName: string, raw: unknown, sourceLabel: string): string {\n const body = JSON.stringify(raw, null, 2);\n return `// Generated by \\`refract import\\` from ${sourceLabel}.\n// DTCG carries property tokens ONLY — recipes, components, composition, and states are not imported.\n// The mapping is heuristic (subsystem inferred from \\`$type\\`/name; \\`border\\` composite colors dropped;\n// rem rounded to px). Review the seeded tokens, then hand-author the rest of your theme below.\nimport type { RawTheme } from \"${packageName}/build\";\n\nexport const raw: RawTheme = ${body};\n`;\n}\n\n/** The generated companion `theme.config.ts` — a runnable build config importing the seeded raw. */\nexport function scaffoldImportConfig(packageName: string, rawImportSpec: string): string {\n return `import { defineConfig } from \"${packageName}/build\";\nimport { createCssAdapter } from \"${CSS_ADAPTER_PACKAGE}\";\nimport { raw } from \"${rawImportSpec}\";\n\n// Generated by \\`refract import\\`. This is your build config — edit it freely. Add adapter options at\n// construction (\\`createCssAdapter({ … })\\`) and extra targets (SC/JSON/…) as their packages install.\nexport default defineConfig({\n raw,\n targets: [\n { adapter: createCssAdapter(), outDir: \"dist/theme\" },\n ],\n});\n`;\n}\n\n/** Count seeded properties per subsystem for the summary (each subsystem value is a `{ prop: … }` map). */\nfunction summarizeCounts(raw: Record<string, unknown>): Record<string, number> {\n const counts: Record<string, number> = {};\n for (const [key, value] of Object.entries(raw)) {\n if (key === \"breakpoints\") continue;\n counts[key] = value && typeof value === \"object\" ? Object.keys(value).length : 0;\n }\n return counts;\n}\n\n/**\n * Read the DTCG document at `input`, convert it via `fromDTCG`, and write a `theme.raw.ts` (plus, unless\n * `rawOnly`, a companion `theme.config.ts`) into `cwd`. Returns a summary of what was seeded. Throws on a\n * missing/unparseable input or when an output file exists and `force` is not set (never clobbers).\n */\nexport function runImport(options: ImportOptions): ImportResult {\n const cwd = options.cwd ?? process.cwd();\n const packageName = options.packageName ?? readOwnPackageName();\n\n // --- Read + parse the DTCG document ---\n const inputFile = isAbsolute(options.input) ? options.input : resolve(cwd, options.input);\n if (!existsSync(inputFile)) {\n throw new Error(`No DTCG document found at \"${options.input}\" (resolved to \"${inputFile}\").`);\n }\n let doc: unknown;\n try {\n doc = JSON.parse(readFileSync(inputFile, \"utf8\"));\n } catch (err) {\n throw new Error(`\"${inputFile}\" is not valid JSON: ${(err as Error).message}`);\n }\n\n // --- Convert (heuristic, lossy — one-shot at import time only) ---\n const fromOpts: FromDTCGOptions = {};\n if (options.breakpointGroup) fromOpts.breakpointGroup = options.breakpointGroup;\n if (options.breakpoints && Object.keys(options.breakpoints).length) {\n fromOpts.breakpoints = options.breakpoints;\n }\n const raw = fromDTCG(doc as DTCGDocument, fromOpts) as Record<string, unknown>;\n\n // --- Write theme.raw.ts (refuse to clobber unless --force) ---\n const rawFile = options.out\n ? isAbsolute(options.out)\n ? options.out\n : resolve(cwd, options.out)\n : resolve(cwd, DEFAULT_RAW_OUT);\n if (existsSync(rawFile) && !options.force) {\n throw new Error(`${basename(rawFile)} already exists at \"${rawFile}\". Pass --force to overwrite it.`);\n }\n mkdirSync(dirname(rawFile), { recursive: true });\n writeFileSync(rawFile, scaffoldRaw(packageName, raw, JSON.stringify(basename(inputFile))), \"utf8\");\n\n // --- Write the companion theme.config.ts (unless --raw-only; refuse to clobber unless --force) ---\n let configFile: string | undefined;\n if (!options.rawOnly) {\n configFile = resolve(dirname(rawFile), DEFAULT_CONFIG_OUT);\n if (existsSync(configFile) && !options.force) {\n throw new Error(\n `${DEFAULT_CONFIG_OUT} already exists at \"${configFile}\". Pass --force to overwrite it, or ` +\n `--raw-only to skip writing a config.`,\n );\n }\n // Extensionless sibling spec — the §8b graph-compile rewrites it to the emitted `.mjs`.\n const rawImportSpec = `./${basename(rawFile).replace(/\\.(ts|mts|cts|tsx)$/, \"\")}`;\n writeFileSync(configFile, scaffoldImportConfig(packageName, rawImportSpec), \"utf8\");\n }\n\n return {\n inputFile,\n rawFile,\n configFile,\n sections: Object.keys(raw),\n counts: summarizeCounts(raw),\n };\n}\n","/**\n * `refract build` — load the config, emit every target to disk (Node-only, §7 Step 10c).\n *\n * The config is the adapter seam (10b): `loadConfig` returns fully-constructed adapter objects, and\n * this command drives each through the adapter-agnostic `emitTheme` (10b). The CLI imports zero\n * adapters itself. A target's `outDir` is resolved relative to the config file's directory (so a\n * config is portable regardless of the invoking cwd); an absolute `outDir` is used as-is.\n *\n * Overrides (flags): `--config <path>` picks the config; `--target <name|index|outDir>` limits the\n * build to one target; `--out <dir>` overrides the selected target's `outDir`. `--out` without\n * `--target` is only allowed when the config has exactly one target (otherwise it is ambiguous).\n * Per-target `helpers` are always honored.\n */\nimport { dirname, isAbsolute, resolve } from \"node:path\";\nimport { loadConfig, type EmitTarget } from \"./config\";\nimport { emitTheme } from \"./emitTheme\";\n\nexport interface BuildOptions {\n readonly cwd?: string;\n /** `--config` override — a path to the config file. */\n readonly configPath?: string;\n /** `--target` override — a target name, numeric index, or outDir to build in isolation. */\n readonly target?: string;\n /** `--out` override — replaces the selected target's outDir. */\n readonly out?: string;\n}\n\nexport interface BuildTargetSummary {\n readonly name?: string;\n readonly adapter: string;\n /** Absolute outDir the target was written to. */\n readonly outDir: string;\n /** Absolute paths of every file written for this target. */\n readonly files: string[];\n}\n\nexport interface BuildResult {\n readonly configPath: string;\n readonly targets: BuildTargetSummary[];\n}\n\n/** Select the target(s) to build. `--target` matches by name, then numeric index, then outDir. */\nfunction selectTargets(targets: readonly EmitTarget[], selector?: string): EmitTarget[] {\n if (selector === undefined) return [...targets];\n\n const byName = targets.filter(t => t.name === selector);\n if (byName.length) return byName;\n\n if (/^\\d+$/.test(selector)) {\n const idx = Number(selector);\n if (idx >= 0 && idx < targets.length) return [targets[idx]];\n }\n\n const byOutDir = targets.filter(t => t.outDir === selector);\n if (byOutDir.length) return byOutDir;\n\n throw new Error(\n `No target matched \"${selector}\". Config has ${targets.length} target(s): ` +\n targets.map((t, i) => t.name ?? `#${i} (${t.outDir})`).join(\", \") + \".\",\n );\n}\n\n/** Load the config and emit every (selected) target to disk. */\nexport async function runBuild(options: BuildOptions = {}): Promise<BuildResult> {\n const cwd = options.cwd ?? process.cwd();\n const { config, path } = await loadConfig({ cwd, configPath: options.configPath });\n\n if (!config.targets.length) {\n throw new Error(`\"${path}\" has no targets to build.`);\n }\n\n const selected = selectTargets(config.targets, options.target);\n\n if (options.out !== undefined && selected.length > 1) {\n throw new Error(\n `--out is ambiguous across ${selected.length} targets; pass --target to pick one first.`,\n );\n }\n\n const configDir = dirname(path);\n const summaries: BuildTargetSummary[] = [];\n for (const target of selected) {\n // A config-relative `outDir` resolves against the config file (portable); a `--out` override is\n // relative to the invoking cwd (it's a command-line path). Absolute paths pass through.\n const outDir =\n options.out !== undefined\n ? isAbsolute(options.out)\n ? options.out\n : resolve(cwd, options.out)\n : isAbsolute(target.outDir)\n ? target.outDir\n : resolve(configDir, target.outDir);\n const result = await emitTheme({\n raw: config.raw,\n adapter: target.adapter,\n outDir,\n helpers: target.helpers,\n emit: target.emit,\n media: config.media,\n units: config.units,\n baseFontSize: config.baseFontSize,\n guide: target.guide,\n });\n summaries.push({\n name: target.name,\n adapter: target.adapter.name,\n outDir: result.outDir,\n files: result.files,\n });\n }\n\n return { configPath: path, targets: summaries };\n}\n","/**\n * `refract tokens` — export the theme as a DTCG `tokens.json` (Node-only, §7 Step 10d).\n *\n * A SEPARATE command from `build`, not part of it: DTCG is adapter-free data-interchange, not an\n * output adapter. So this reads ONLY the config's `raw` (never its `targets`/`emitTheme`) and writes a\n * single JSON document — no `theme.css`, no vendored helpers.\n *\n * `toDTCG` needs a *built* `Theme` (it walks the flat `theme.tokens` + `theme.resolveToken` +\n * `theme.model.breakpoints`), so we `createTheme(raw, { adapter })` first. The adapter choice is\n * IMMATERIAL to the output — `toDTCG` never touches adapter-produced strings — so we use core's own\n * built-in `createNoopAdapter` as the trivial builder. (Before the monorepo split this reached for\n * `createCssAdapter`, which forced a core→adapter dependency; the null adapter keeps `src/build` free\n * of every adapter package — the guiding rule is the dependency arrow points ONLY into core.)\n *\n * `toDTCG` is imported as a relative `../dtcg` static import (NOT the `./dtcg` package subpath) so the\n * in-repo gate resolves with no dist build — the same pattern as everything else in `src/build/`.\n */\nimport { mkdirSync, writeFileSync } from \"node:fs\";\nimport { dirname, isAbsolute, resolve } from \"node:path\";\nimport { createTheme } from \"../core/createTheme\";\nimport { createNoopAdapter } from \"../core/noopAdapter\";\nimport { toDTCG } from \"../dtcg\";\nimport { loadConfig } from \"./config\";\n\nconst DEFAULT_OUT = \"tokens.json\";\n\nexport interface TokensOptions {\n readonly cwd?: string;\n /** `--config` override — a path to the config file. */\n readonly configPath?: string;\n /** `--out` override — the JSON file to write (default `tokens.json`, resolved against cwd). */\n readonly out?: string;\n}\n\nexport interface TokensResult {\n /** Absolute path the config was loaded from. */\n readonly configPath: string;\n /** Absolute path of the written `tokens.json`. */\n readonly outFile: string;\n /** Number of top-level DTCG groups written (excludes `$`-prefixed document keys). */\n readonly groupCount: number;\n}\n\n/** Load the config, build the theme, and write its DTCG document to disk. Returns a summary. */\nexport async function runTokens(options: TokensOptions = {}): Promise<TokensResult> {\n const cwd = options.cwd ?? process.cwd();\n const { config, path } = await loadConfig({ cwd, configPath: options.configPath });\n\n // Adapter choice is immaterial — `toDTCG` reads only `theme.tokens`/`resolveToken`/`model`.\n const theme = createTheme(config.raw, { adapter: createNoopAdapter() });\n const doc = toDTCG(theme);\n\n // `--out` is a command-line path (relative to cwd); absolute passes through.\n const outFile = options.out\n ? isAbsolute(options.out)\n ? options.out\n : resolve(cwd, options.out)\n : resolve(cwd, DEFAULT_OUT);\n\n mkdirSync(dirname(outFile), { recursive: true });\n writeFileSync(outFile, `${JSON.stringify(doc, null, 2)}\\n`, \"utf8\");\n\n const groupCount = Object.keys(doc).filter(k => !k.startsWith(\"$\")).length;\n return { configPath: path, outFile, groupCount };\n}\n","/**\n * `refract audit` — score the theme's colour pairings for WCAG 2 contrast (+ advisory APCA).\n *\n * Adapter-free like `refract tokens`: the audit reads only `theme.tokens` / `theme.resolveToken` /\n * `theme.model`, so we build with core's `createNoopAdapter`. Reports by default; `--strict` makes the\n * command exit non-zero (via an aggregated throw from `audit`). Returns a serializable summary so the\n * gate test can drive it directly.\n *\n * `audit` is imported as a relative `../subsystems/colors/audit` (not a package subpath) so the in-repo\n * gate resolves with no dist build — the same pattern as the rest of `src/build/`.\n */\nimport { createTheme } from \"../core/createTheme\";\nimport { createNoopAdapter } from \"../core/noopAdapter\";\nimport { audit, type AuditResult, type WcagLevel } from \"../subsystems/colors/audit\";\nimport { loadConfig } from \"./config\";\n\nexport interface AuditCommandOptions {\n readonly cwd?: string;\n /** `--config` override — a path to the config file. */\n readonly configPath?: string;\n /** `--strict` — throw (non-zero exit) when any pairing fails. */\n readonly strict?: boolean;\n /** `--min-wcag` — pass bar (`\"AA\"` default). */\n readonly minWcag?: WcagLevel;\n /** `--large` — score against large-text thresholds. */\n readonly largeText?: boolean;\n}\n\nexport interface AuditCommandResult {\n /** Absolute path the config was loaded from. */\n readonly configPath: string;\n readonly result: AuditResult;\n}\n\n/** Load the config, build the theme (adapter-free), and audit its colour pairings. */\nexport async function runAudit(options: AuditCommandOptions = {}): Promise<AuditCommandResult> {\n const cwd = options.cwd ?? process.cwd();\n const { config, path } = await loadConfig({ cwd, configPath: options.configPath });\n\n const theme = createTheme(config.raw, { adapter: createNoopAdapter() });\n const result = audit(theme, {\n strict: options.strict,\n minWcag: options.minWcag,\n largeText: options.largeText,\n });\n return { configPath: path, result };\n}\n","/**\n * `diffThemes` — the blast radius of a candidate theme edit, computed against a base (§5 agent-native).\n *\n * refract stores every synthesized rung/variant as a `{ ref, fn, arg }` graph, not a frozen literal, so\n * a candidate theme can be *built and compared* before it's applied — the claim no token file can make:\n * see what a change does before you make it. This is the shared engine behind `refract diff <candidate>`\n * (a human CLI + a CI gate) and the MCP `diffTheme` tool (an agent's plan-then-apply guardrail).\n *\n * Three axes, each adapter-independent except `classes`:\n * - `tokens` — which resolved token values moved (added / removed / changed).\n * - `classes` — which emitted recipe classes changed CSS (only when the themes emit classes, e.g. the\n * CSS adapter — read via the duck-typed `renderRecipe` / `getClass`).\n * - `contrast` — which WCAG pairings crossed a pass/level threshold (via {@link audit}).\n */\nimport type { Theme } from \"../core\";\nimport { audit, type PairingScore } from \"../subsystems/colors/audit\";\n\nexport type ChangeKind = \"added\" | \"removed\" | \"changed\";\n\nexport interface TokenChange {\n path: string;\n before: string | null;\n after: string | null;\n kind: ChangeKind;\n}\n\nexport interface ClassChange {\n /** The emitted class name (or the `subsystem.group.variant` id when no adapter names it). */\n name: string;\n kind: ChangeKind;\n}\n\nexport interface ContrastScore {\n ratio?: number;\n level?: string;\n pass?: boolean;\n}\n\nexport interface ContrastChange {\n label: string;\n before: ContrastScore | null;\n after: ContrastScore | null;\n /** True when the pass verdict or the WCAG level changed — the threshold-crossing an agent cares about. */\n crossed: boolean;\n}\n\nexport interface ThemeDiff {\n tokens: TokenChange[];\n classes: ClassChange[];\n contrast: ContrastChange[];\n summary: {\n tokensChanged: number;\n classesChanged: number;\n /** Pairings whose pass verdict or level crossed a threshold. */\n pairingsCrossed: number;\n };\n}\n\n/** The CSS-style surface a class-emitting adapter attaches to the theme (duck-typed — absent on noop). */\ntype ClassEmittingTheme = Theme & {\n renderRecipe?: (subsystem: string, group: string, variant: string) => string;\n getClass?: (subsystem: string, group: string, variant: string) => string | undefined;\n};\n\nconst resolvedValue = (theme: Theme, path: string): string | null => {\n try {\n return String(theme.resolveToken(path));\n } catch {\n return null;\n }\n};\n\nconst diffTokens = (base: Theme, candidate: Theme): TokenChange[] => {\n const paths = new Set([...Object.keys(base.tokens), ...Object.keys(candidate.tokens)]);\n const out: TokenChange[] = [];\n for (const path of paths) {\n const inBase = path in base.tokens;\n const inCandidate = path in candidate.tokens;\n const before = inBase ? resolvedValue(base, path) : null;\n const after = inCandidate ? resolvedValue(candidate, path) : null;\n if (inBase && !inCandidate) out.push({ path, before, after: null, kind: \"removed\" });\n else if (!inBase && inCandidate) out.push({ path, before: null, after, kind: \"added\" });\n else if (before !== after) out.push({ path, before, after, kind: \"changed\" });\n }\n return out.sort((a, b) => a.path.localeCompare(b.path));\n};\n\n/** Enumerate every recipe identity a theme's Model declares (`subsystem.group.variant`). */\nconst recipeIds = (theme: Theme): Array<{ subsystem: string; group: string; variant: string }> => {\n const out: Array<{ subsystem: string; group: string; variant: string }> = [];\n for (const [subsystem, sub] of Object.entries(theme.model.subsystems)) {\n for (const [group, ruleSetGroup] of Object.entries(sub.ruleSets ?? {})) {\n for (const variant of Object.keys(ruleSetGroup)) out.push({ subsystem, group, variant });\n }\n }\n return out;\n};\nconst hasRecipe = (theme: Theme, s: string, g: string, v: string): boolean =>\n Boolean(theme.model.subsystems[s]?.ruleSets?.[g]?.[v]);\n\nconst diffClasses = (base: Theme, candidate: Theme): ClassChange[] => {\n const b = base as ClassEmittingTheme;\n const c = candidate as ClassEmittingTheme;\n // Class-level diff needs an adapter that emits classes on at least one side; otherwise there's nothing\n // to compare (noop themes have no CSS). Report empty rather than inventing names.\n if (!b.renderRecipe && !c.renderRecipe) return [];\n const seen = new Set<string>();\n const ids = [...recipeIds(base), ...recipeIds(candidate)].filter((id) => {\n const key = `${id.subsystem}.${id.group}.${id.variant}`;\n if (seen.has(key)) return false;\n seen.add(key);\n return true;\n });\n const out: ClassChange[] = [];\n for (const { subsystem, group, variant } of ids) {\n const inBase = hasRecipe(base, subsystem, group, variant);\n const inCandidate = hasRecipe(candidate, subsystem, group, variant);\n const name =\n c.getClass?.(subsystem, group, variant) ??\n b.getClass?.(subsystem, group, variant) ??\n `${subsystem}.${group}.${variant}`;\n if (inBase && !inCandidate) out.push({ name, kind: \"removed\" });\n else if (!inBase && inCandidate) out.push({ name, kind: \"added\" });\n else {\n const before = b.renderRecipe?.(subsystem, group, variant) ?? \"\";\n const after = c.renderRecipe?.(subsystem, group, variant) ?? \"\";\n if (before !== after) out.push({ name, kind: \"changed\" });\n }\n }\n return out.sort((a, b2) => a.name.localeCompare(b2.name));\n};\n\nconst diffContrast = (base: Theme, candidate: Theme): ContrastChange[] => {\n const score = (p?: PairingScore): ContrastScore | null =>\n p ? { ratio: p.wcagRatio, level: p.wcagLevel, pass: p.pass } : null;\n const byLabel = (pairings: readonly PairingScore[]): Map<string, PairingScore> =>\n new Map(pairings.map((p) => [p.label, p]));\n const before = byLabel(audit(base).pairings);\n const after = byLabel(audit(candidate).pairings);\n const labels = new Set([...before.keys(), ...after.keys()]);\n const out: ContrastChange[] = [];\n for (const label of labels) {\n const b = before.get(label);\n const a = after.get(label);\n const bs = score(b);\n const as = score(a);\n const changed = bs?.ratio !== as?.ratio || bs?.level !== as?.level || Boolean(b) !== Boolean(a);\n if (!changed) continue;\n const crossed = (b?.pass ?? null) !== (a?.pass ?? null) || (b?.wcagLevel ?? null) !== (a?.wcagLevel ?? null);\n out.push({ label, before: bs, after: as, crossed });\n }\n return out.sort((a, b) => a.label.localeCompare(b.label));\n};\n\n/**\n * Diff a candidate theme against a base. Both should be built with the same adapter; pass a\n * class-emitting adapter (e.g. CSS) on both sides to populate `classes`, or any adapter for the\n * adapter-independent `tokens` / `contrast` axes.\n */\nexport function diffThemes(base: Theme, candidate: Theme): ThemeDiff {\n const tokens = diffTokens(base, candidate);\n const classes = diffClasses(base, candidate);\n const contrast = diffContrast(base, candidate);\n return {\n tokens,\n classes,\n contrast,\n summary: {\n tokensChanged: tokens.length,\n classesChanged: classes.length,\n pairingsCrossed: contrast.filter((c) => c.crossed).length,\n },\n };\n}\n","/**\n * `refract diff <candidate>` — build the project's theme and a candidate, and report the blast radius\n * (tokens moved, classes changed, contrast crossings). Optional thresholds make it a CI gate: fail the\n * PR if a token change alters more than N classes or drops a pairing below a WCAG bar.\n *\n * Adapter-free like `tokens`/`audit`: it builds against the config's own target adapters (whatever the\n * config imported), picking a class-emitting one so the class axis is populated. The candidate is a\n * module (default-exported raw theme) or a `.json` raw theme.\n */\nimport { existsSync, readFileSync } from \"node:fs\";\nimport { extname, resolve } from \"node:path\";\nimport { pathToFileURL } from \"node:url\";\nimport type { RawTheme } from \"../core/rawTheme\";\nimport type { Theme, ThemeAdapter } from \"../core\";\nimport { createTheme } from \"../core/createTheme\";\nimport { assertRawTheme } from \"../core/assertRawTheme\";\nimport { createNoopAdapter } from \"../core/noopAdapter\";\nimport { loadConfig } from \"./config\";\nimport { compileTsConfigGraph } from \"./paths\";\nimport { diffThemes, type ThemeDiff } from \"./diff\";\n\nconst WCAG_RANK: Record<string, number> = { fail: 0, \"AA-large\": 1, AA: 2, AAA: 3 };\n\nexport interface DiffCommandOptions {\n cwd?: string;\n configPath?: string;\n /** Path to the candidate theme (`.ts` / `.mjs` / `.js` default-export, or `.json`). */\n candidatePath: string;\n /** CI gate: fail if more than this many classes changed. */\n maxClassChanges?: number;\n /** CI gate: fail if more than this many tokens changed. */\n maxTokenChanges?: number;\n /** CI gate: fail if any pairing's `after` level drops below this WCAG bar. */\n failBelow?: string;\n}\n\nexport interface TargetStatus {\n name: string;\n ok: boolean;\n errors: string[];\n}\n\nexport interface DiffCommandResult {\n configPath: string;\n candidatePath: string;\n diff: ThemeDiff;\n /** Per configured target: does the candidate still build? */\n targets: TargetStatus[];\n /** CI-gate verdict: false when any threshold was breached (or a target stopped building). */\n ok: boolean;\n violations: string[];\n}\n\nlet counter = 0;\n\n/**\n * Load a candidate raw theme from a module (default export) or a `.json` file, and assert it's actually\n * theme-shaped before returning — a mis-shaped candidate (e.g. a `defineConfig`) must fail loud here,\n * not silently diff as \"everything removed\" (see {@link assertRawTheme}).\n */\nasync function loadCandidate(path: string): Promise<RawTheme> {\n if (!existsSync(path)) throw new Error(`candidate theme not found at \"${path}\".`);\n let candidate: unknown;\n if (extname(path) === \".json\") {\n candidate = JSON.parse(readFileSync(path, \"utf8\"));\n } else if (extname(path) === \".ts\") {\n const { entry, cleanup } = await compileTsConfigGraph(path);\n try {\n const mod = (await import(pathToFileURL(entry).href)) as Record<string, unknown>;\n candidate = mod.default ?? mod.raw ?? mod;\n } finally {\n cleanup();\n }\n } else {\n const mod = (await import(`${pathToFileURL(path).href}?v=${++counter}`)) as Record<string, unknown>;\n candidate = mod.default ?? mod.raw ?? mod;\n }\n assertRawTheme(candidate, path);\n return candidate;\n}\n\n/** Does this built theme expose the class-emitting surface (CSS-style adapter)? */\nconst emitsClasses = (theme: Theme): boolean => typeof (theme as { renderRecipe?: unknown }).renderRecipe === \"function\";\n\nexport async function runDiff(options: DiffCommandOptions): Promise<DiffCommandResult> {\n const cwd = options.cwd ?? process.cwd();\n const { config, path: configPath } = await loadConfig({ cwd, configPath: options.configPath });\n const candidatePath = resolve(cwd, options.candidatePath);\n const candidateRaw = await loadCandidate(candidatePath);\n const buildOpts = { units: config.units, baseFontSize: config.baseFontSize, media: config.media };\n\n const adapters: Array<{ name: string; adapter: ThemeAdapter }> = config.targets.map((t, i) => ({\n name: t.name ?? t.outDir ?? `target-${i}`,\n adapter: t.adapter,\n }));\n\n // Per-target: does the candidate still build? (a \"targets now fail\" signal for CI).\n const targets: TargetStatus[] = adapters.map(({ name, adapter }) => {\n try {\n createTheme(candidateRaw, { adapter, ...buildOpts });\n return { name, ok: true, errors: [] };\n } catch (e) {\n const err = e as { failures?: readonly string[]; message?: string };\n return { name, ok: false, errors: err.failures ? [...err.failures] : [err.message ?? String(e)] };\n }\n });\n\n // Choose the adapter to diff through: a class-emitting target if any, else the first target, else noop.\n const pick =\n adapters.find(({ adapter }) => emitsClasses(createTheme(config.raw, { adapter, ...buildOpts }))) ??\n adapters[0] ?? { name: \"noop\", adapter: createNoopAdapter() };\n const base = createTheme(config.raw, { adapter: pick.adapter, ...buildOpts });\n // The candidate may not build (that's a real, reportable outcome — see `targets`). When it doesn't,\n // there's nothing to diff; return the empty diff and let the target-failure violation carry the news.\n const EMPTY_DIFF: ThemeDiff = { tokens: [], classes: [], contrast: [], summary: { tokensChanged: 0, classesChanged: 0, pairingsCrossed: 0 } };\n let diff = EMPTY_DIFF;\n try {\n diff = diffThemes(base, createTheme(candidateRaw, { adapter: pick.adapter, ...buildOpts }));\n } catch {\n /* candidate doesn't build — captured in `targets` below */\n }\n\n // CI-gate evaluation.\n const violations: string[] = [];\n if (options.maxClassChanges !== undefined && diff.summary.classesChanged > options.maxClassChanges) {\n violations.push(`${diff.summary.classesChanged} classes changed (max ${options.maxClassChanges})`);\n }\n if (options.maxTokenChanges !== undefined && diff.summary.tokensChanged > options.maxTokenChanges) {\n violations.push(`${diff.summary.tokensChanged} tokens changed (max ${options.maxTokenChanges})`);\n }\n if (options.failBelow) {\n const bar = WCAG_RANK[options.failBelow] ?? 0;\n for (const c of diff.contrast) {\n const afterRank = c.after?.level ? (WCAG_RANK[c.after.level] ?? 0) : 0;\n const beforeRank = c.before?.level ? (WCAG_RANK[c.before.level] ?? 0) : 0;\n if (c.after && afterRank < bar && afterRank < beforeRank) {\n violations.push(`${c.label} drops to ${c.after.level} (below ${options.failBelow})`);\n }\n }\n }\n const failedTargets = targets.filter((t) => !t.ok).map((t) => t.name);\n if (failedTargets.length) violations.push(`candidate no longer builds for: ${failedTargets.join(\", \")}`);\n\n return { configPath, candidatePath, diff, targets, ok: violations.length === 0, violations };\n}\n","/**\n * Fail-loud shape guard for a value that is *supposed* to be a {@link RawTheme}.\n *\n * `createTheme` accepts a bare object, and an empty `{}` is a valid (empty) theme — so a value of the\n * *wrong* shape doesn't necessarily throw during a build. That's the trap `refract diff` fell into: hand\n * it a `defineConfig({ raw, targets })` where it wanted the raw theme and it built the config as an\n * (effectively empty) theme, then reported a nonsense \"every token removed\" diff and exited 0. A\n * governance tool must not quietly mis-report. This guard is the loud, coded gate for that class of\n * mistake — used by `diff` (and available to `validate` / the MCP server) before anything is compared.\n *\n * It is deliberately narrow: it rejects only values that cannot be a RawTheme (non-objects, arrays,\n * `null`) or that are affirmatively something else (a `defineConfig`, spotted by its `targets` array).\n * A bare `{}` still passes — an empty theme is legitimately empty.\n */\nimport { RefractError } from \"./errors\";\nimport type { RawTheme } from \"./rawTheme\";\n\nexport function assertRawTheme(value: unknown, source?: string): asserts value is RawTheme {\n const at = source ? ` (${source})` : \"\";\n\n if (value === null || typeof value !== \"object\" || Array.isArray(value)) {\n const got = Array.isArray(value) ? \"an array\" : value === null ? \"null\" : typeof value;\n throw new RefractError(\n \"REFRACT_E_RAW_SHAPE\",\n `Expected a RawTheme object${at}, got ${got}. Pass the raw theme (a module's default export, or a .json raw theme).`,\n );\n }\n\n // The documented mistake: a defineConfig({ raw, targets }) passed where the bare RawTheme was wanted.\n // A RawTheme never has a top-level `targets`; a config always does.\n if (Array.isArray((value as { targets?: unknown }).targets)) {\n throw new RefractError(\n \"REFRACT_E_RAW_SHAPE\",\n `Expected a RawTheme object${at}, but got what looks like a defineConfig({ raw, targets }). Pass its \\`raw\\` (or a module that default-exports the raw theme), not the whole config.`,\n );\n }\n}\n","/**\n * `refract skills` — install the bundled AI skills into a project's agent CLI(s) (Node-only).\n *\n * The canonical skill sources ship *inside this package* (`skills/<name>/SKILL.md`, added to\n * `package.json#files`), so `node_modules/@theme-registry/refract/skills/` is the version-locked\n * source of truth — upgrade refract, re-run `skills update`, and the skills match the installed API.\n *\n * One source, many agent formats (the same one-model-many-adapters idea refract is built on):\n * - **claude** natively loads `.claude/skills/<name>/SKILL.md`, so we copy each file verbatim.\n * - Every other agent (codex, opencode, github-copilot, cursor, generic) loads a flat instructions\n * file on *every* request, so inlining a dozen skill bodies would bloat each turn. Instead we\n * write a small **router** into that agent's instructions file (a table pointing at\n * `.refract/skills/<name>.md`) and drop the full bodies as on-demand files — reconstructing\n * Claude's progressive disclosure manually.\n *\n * The command implementations return data (`runSkillsInstall`/`List`/`Update`), so tests drive them\n * directly; the CLI wrapper (`cli.ts`) maps argv + interactive prompts onto them.\n */\nimport { existsSync, mkdirSync, readFileSync, readdirSync, writeFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\nimport { findPackageRoot } from \"./paths\";\n\nexport type SkillTier = \"core\" | \"optional\";\n\n/** One skill's parsed metadata + content. */\nexport interface SkillMeta {\n readonly name: string;\n readonly description: string;\n readonly tier: SkillTier;\n /** The full file (frontmatter + body) — what the claude target copies verbatim. */\n readonly raw: string;\n /** The markdown body after the frontmatter — what the agents-md targets drop as an on-demand file. */\n readonly body: string;\n readonly sourcePath: string;\n}\n\nexport type AgentTarget = \"claude\" | \"codex\" | \"opencode\" | \"github-copilot\" | \"cursor\" | \"generic\";\nexport type InstallScope = \"local\" | \"global\";\n\nexport const AGENT_TARGETS: readonly AgentTarget[] = [\n \"claude\",\n \"codex\",\n \"opencode\",\n \"github-copilot\",\n \"cursor\",\n \"generic\",\n];\n\n/**\n * How each agent consumes skills. `claude` gets native per-skill directories; every other agent\n * shares the \"agents-md\" shape (a router in its instructions file + on-demand body files), differing\n * only in *which* file it reads. Adding a bespoke per-agent adapter later means one more entry here.\n */\nconst AGENT_ROUTER: Record<AgentTarget, { kind: \"claude\" | \"agents-md\"; routerFile: string }> = {\n claude: { kind: \"claude\", routerFile: \".claude/skills\" },\n codex: { kind: \"agents-md\", routerFile: \"AGENTS.md\" },\n opencode: { kind: \"agents-md\", routerFile: \"AGENTS.md\" },\n \"github-copilot\": { kind: \"agents-md\", routerFile: \".github/copilot-instructions.md\" },\n cursor: { kind: \"agents-md\", routerFile: \".cursor/rules/refract-skills.mdc\" },\n generic: { kind: \"agents-md\", routerFile: \"AGENTS.md\" },\n};\n\nconst ROUTER_START = \"<!-- refract-skills:start -->\";\nconst ROUTER_END = \"<!-- refract-skills:end -->\";\nconst MANIFEST_REL = join(\".refract\", \"skills.lock\");\nconst BODY_DIR_REL = join(\".refract\", \"skills\");\n\n/** Locate the bundled catalog. Defaults to `<packageRoot>/skills` (ships via package.json#files). */\nexport function skillsCatalogDir(override?: string): string {\n return override ?? join(findPackageRoot(), \"skills\");\n}\n\n/** Read this package's `name` + `version` (recorded in the manifest so `update` matches the API). */\nfunction readOwnPackageMeta(): { name: string; version: string } {\n const pkg = JSON.parse(readFileSync(join(findPackageRoot(), \"package.json\"), \"utf8\")) as {\n name?: string;\n version?: string;\n };\n return { name: pkg.name ?? \"@theme-registry/refract\", version: pkg.version ?? \"0.0.0\" };\n}\n\n/** Parse the leading `--- … ---` frontmatter for the fields we need; body is everything after. */\nfunction parseSkillFile(raw: string, sourcePath: string): SkillMeta {\n const match = /^---\\r?\\n([\\s\\S]*?)\\r?\\n---\\r?\\n?/.exec(raw);\n const front = match ? match[1] : \"\";\n const body = match ? raw.slice(match[0].length).replace(/^\\s+/, \"\") : raw;\n const field = (key: string): string | undefined => {\n const line = new RegExp(`^${key}:\\\\s*(.*)$`, \"m\").exec(front);\n return line ? line[1].trim() : undefined;\n };\n const name = field(\"name\") ?? dirname(sourcePath).split(/[\\\\/]/).pop() ?? \"unnamed\";\n const tier = field(\"tier\") === \"optional\" ? \"optional\" : \"core\";\n return { name, description: field(\"description\") ?? \"\", tier, raw, body, sourcePath };\n}\n\n/** Read every `<catalog>/<name>/SKILL.md`, sorted by name. */\nexport function listSkills(catalogDir?: string): SkillMeta[] {\n const dir = skillsCatalogDir(catalogDir);\n if (!existsSync(dir)) {\n throw new Error(`Skills catalog not found at \"${dir}\". Reinstall @theme-registry/refract.`);\n }\n return readdirSync(dir, { withFileTypes: true })\n .filter(entry => entry.isDirectory())\n .map(entry => join(dir, entry.name, \"SKILL.md\"))\n .filter(existsSync)\n .map(path => parseSkillFile(readFileSync(path, \"utf8\"), path))\n .sort((a, b) => a.name.localeCompare(b.name));\n}\n\n/** The one-line \"use it for\" cell — the description up to (but not including) its `Triggers:` list. */\nfunction shortDescription(skill: SkillMeta): string {\n const beforeTriggers = skill.description.split(/\\s*Triggers:/)[0].trim();\n const firstSentence = beforeTriggers.split(/\\.\\s/)[0].trim();\n return (firstSentence || beforeTriggers).replace(/\\|/g, \"\\\\|\");\n}\n\n/** Render the shared router block (identical content for every agents-md target). */\nfunction renderRouter(skills: SkillMeta[]): string {\n const rows = skills\n .map(s => `| [${s.name}](${BODY_DIR_REL}/${s.name}.md) | ${shortDescription(s)} |`)\n .join(\"\\n\");\n return [\n ROUTER_START,\n \"\",\n \"## refract theme skills\",\n \"\",\n \"These skills document the [refract](https://github.com/theme-registry/refract) theme toolkit.\",\n \"When a task matches a row below, read the linked file before working.\",\n \"\",\n \"| Skill | Use it for |\",\n \"| --- | --- |\",\n rows,\n \"\",\n ROUTER_END,\n ].join(\"\\n\");\n}\n\n/** Insert or replace the marked router block in an existing instructions file (idempotent). */\nfunction upsertRouterBlock(existing: string, block: string): string {\n const start = existing.indexOf(ROUTER_START);\n const end = existing.indexOf(ROUTER_END);\n if (start !== -1 && end !== -1 && end > start) {\n return existing.slice(0, start) + block + existing.slice(end + ROUTER_END.length);\n }\n const trimmed = existing.replace(/\\s+$/, \"\");\n return trimmed ? `${trimmed}\\n\\n${block}\\n` : `${block}\\n`;\n}\n\nfunction writeFileEnsuring(path: string, content: string): void {\n mkdirSync(dirname(path), { recursive: true });\n writeFileSync(path, content, \"utf8\");\n}\n\nexport interface SkillsInstallOptions {\n readonly agents: readonly AgentTarget[];\n /** `local` (default) writes into the project; `global` into the user's home dir. */\n readonly scope?: InstallScope;\n /** Explicit skill names to install. Omit to install all `core` skills (+ optional if `includeOptional`). */\n readonly skills?: readonly string[];\n /** When `skills` is omitted, also install `optional`-tier skills. Default `false`. */\n readonly includeOptional?: boolean;\n /** Project dir for `local` scope (default `process.cwd()`). */\n readonly cwd?: string;\n /** Home dir for `global` scope (default `os.homedir()`); injectable for tests. */\n readonly home?: string;\n /** Override the bundled catalog dir (tests). */\n readonly catalogDir?: string;\n}\n\nexport interface SkillsInstallResult {\n readonly scope: InstallScope;\n readonly agents: readonly AgentTarget[];\n readonly skills: readonly string[];\n readonly files: readonly string[];\n readonly manifestPath: string;\n}\n\ninterface SkillsManifest {\n readonly schema: 1;\n readonly packageName: string;\n readonly refractVersion: string;\n readonly scope: InstallScope;\n readonly agents: readonly AgentTarget[];\n readonly skills: readonly string[];\n}\n\n/** Resolve the selection from options: explicit names, or all core (+ optional). */\nfunction selectSkills(catalog: SkillMeta[], options: SkillsInstallOptions): SkillMeta[] {\n if (options.skills && options.skills.length > 0) {\n const byName = new Map(catalog.map(s => [s.name, s]));\n const chosen: SkillMeta[] = [];\n for (const name of options.skills) {\n const skill = byName.get(name);\n if (!skill) {\n throw new Error(\n `Unknown skill \"${name}\". Available: ${catalog.map(s => s.name).join(\", \")}.`,\n );\n }\n chosen.push(skill);\n }\n return chosen;\n }\n return catalog.filter(s => s.tier === \"core\" || options.includeOptional);\n}\n\n/**\n * Install (or re-sync) the selected skills for the selected agents. Pure w.r.t. its options — the CLI\n * layer handles prompting; this does the filesystem work and returns what it wrote.\n */\nexport function runSkillsInstall(options: SkillsInstallOptions): SkillsInstallResult {\n const scope: InstallScope = options.scope ?? \"local\";\n const base = scope === \"global\" ? (options.home ?? homedir()) : (options.cwd ?? process.cwd());\n const catalog = listSkills(options.catalogDir);\n const selected = selectSkills(catalog, options);\n if (options.agents.length === 0) throw new Error(\"Pick at least one agent target.\");\n\n const files = new Set<string>();\n const needsAgentsMd = options.agents.some(a => AGENT_ROUTER[a].kind === \"agents-md\");\n\n // Shared on-demand body files (written once, referenced by every agents-md router).\n if (needsAgentsMd) {\n for (const skill of selected) {\n const path = join(base, BODY_DIR_REL, `${skill.name}.md`);\n writeFileEnsuring(path, skill.body);\n files.add(path);\n }\n }\n\n for (const agent of options.agents) {\n const target = AGENT_ROUTER[agent];\n if (target.kind === \"claude\") {\n // Native: one directory per skill, the file copied verbatim.\n for (const skill of selected) {\n const path = join(base, target.routerFile, skill.name, \"SKILL.md\");\n writeFileEnsuring(path, skill.raw);\n files.add(path);\n }\n } else {\n // Router into this agent's instructions file (idempotent via the marker block).\n const routerPath = join(base, target.routerFile);\n const existing = existsSync(routerPath) ? readFileSync(routerPath, \"utf8\") : \"\";\n writeFileEnsuring(routerPath, upsertRouterBlock(existing, renderRouter(selected)));\n files.add(routerPath);\n }\n }\n\n const { name: packageName, version: refractVersion } = readOwnPackageMeta();\n const manifest: SkillsManifest = {\n schema: 1,\n packageName,\n refractVersion,\n scope,\n agents: [...options.agents],\n skills: selected.map(s => s.name),\n };\n const manifestPath = join(base, MANIFEST_REL);\n writeFileEnsuring(manifestPath, `${JSON.stringify(manifest, null, 2)}\\n`);\n\n return {\n scope,\n agents: [...options.agents],\n skills: selected.map(s => s.name),\n files: [...files].sort(),\n manifestPath,\n };\n}\n\n/** Re-sync a prior install from its `.refract/skills.lock` (upgrades the skill bodies to this version). */\nexport function runSkillsUpdate(\n options: { scope?: InstallScope; cwd?: string; home?: string; catalogDir?: string } = {},\n): SkillsInstallResult {\n const scope: InstallScope = options.scope ?? \"local\";\n const base = scope === \"global\" ? (options.home ?? homedir()) : (options.cwd ?? process.cwd());\n const manifestPath = join(base, MANIFEST_REL);\n if (!existsSync(manifestPath)) {\n throw new Error(\n `No skills manifest at \"${manifestPath}\". Run \\`refract skills install\\` first.`,\n );\n }\n const manifest = JSON.parse(readFileSync(manifestPath, \"utf8\")) as SkillsManifest;\n return runSkillsInstall({\n agents: manifest.agents,\n scope,\n skills: manifest.skills,\n cwd: options.cwd,\n home: options.home,\n catalogDir: options.catalogDir,\n });\n}\n","/**\n * `refract` CLI (Node-only, §7 Step 10c) — a thin subcommand dispatcher over the build layer.\n *\n * Arg parsing is hand-wired on `node:util`'s `parseArgs` (no new dep). Commands:\n * - `init` — scaffold a runnable `theme.config.(ts|js|mjs)` (`--js`/`--mjs`/`--force`).\n * - `import` — seed a `theme.raw.ts` (+ config) from a DTCG `tokens.json` (`--out`/`--raw-only`/…).\n * - `build` — load the config → `emitTheme` per target (`--config`/`--out`/`--target`).\n * - `tokens` — DTCG export (`toDTCG` → `tokens.json`); adapter-free, reads only the config's `raw`.\n *\n * The command implementations (`runInit`/`runImport`/`runBuild`/`runTokens`) live in their own modules and\n * return data, so the gate test drives them directly; this file only maps argv → those calls + prints\n * summaries. It imports zero adapters — the config's own `import` is the adapter seam (10b).\n */\nimport { createInterface } from \"node:readline/promises\";\nimport { parseArgs } from \"node:util\";\nimport { runBuild } from \"./buildCommand\";\nimport { runImport, parseBreakpointsFlag } from \"./importCommand\";\nimport { runInit, type ConfigVariant } from \"./init\";\nimport {\n AGENT_TARGETS,\n listSkills,\n runSkillsInstall,\n runSkillsUpdate,\n type AgentTarget,\n type InstallScope,\n} from \"./skillsCommand\";\nimport { runTokens } from \"./tokensCommand\";\nimport { runAudit } from \"./auditCommand\";\nimport { runDiff } from \"./diffCommand\";\nimport type { WcagLevel } from \"../subsystems/colors/audit\";\n\nconst HELP = `refract — build a refract theme to disk.\n\nUsage:\n refract init [--js | --mjs] [--force]\n refract import <tokens.json> [--out <file>] [--raw-only] [--force]\n [--breakpoint-group <name>] [--breakpoints <n:px,…>]\n refract build [--config <path>] [--target <name|index>] [--out <dir>]\n refract tokens [--config <path>] [--out <file>]\n refract diff <candidate> [--config <path>] [--max-class-changes <n>]\n [--max-token-changes <n>] [--fail-below <AA|AAA|AA-large>]\n refract audit [--config <path>] [--strict] [--min-wcag <AA|AAA|AA-large>] [--large]\n refract skills <install|list|update> [--agent <a,b|all>] [--global|--local]\n [--only <names>] [--optional]\n refract help\n\nCommands:\n init Scaffold a runnable theme.config.(ts|js|mjs) in the current directory.\n import Seed a theme.raw.ts (+ theme.config.ts) from a DTCG tokens.json (one-shot).\n build Load the config and emit every target's files to its outDir.\n tokens Export the theme's tokens as a DTCG tokens.json (adapter-free).\n diff Show a candidate theme's blast radius vs the config (tokens/classes/contrast); thresholds gate CI.\n audit Score colour pairings for WCAG-2 contrast (+ advisory APCA). Reports; --strict fails.\n skills Install the bundled AI skills into your agent CLI(s) (claude/codex/…).\n`;\n\n/**\n * Uniform error reporter for a command's catch block. Surfaces a `RefractError`'s stable `code`\n * (`[REFRACT_E_…] message`) so an agent or CI log sees the machine-readable code, and lists each\n * collect-all `failure` — a plain `Error` just prints its message. Returns the exit code (1).\n */\nfunction reportError(cmd: string, err: unknown): number {\n const e = err as { code?: string; message?: string; failures?: readonly string[] };\n const code = typeof e.code === \"string\" && e.code.startsWith(\"REFRACT_E_\") ? `[${e.code}] ` : \"\";\n process.stderr.write(`refract ${cmd}: ${code}${e.message ?? String(err)}\\n`);\n if (e.failures) for (const f of e.failures) process.stderr.write(` - ${f}\\n`);\n return 1;\n}\n\nasync function cmdInit(argv: string[]): Promise<number> {\n const { values } = parseArgs({\n args: argv,\n options: {\n js: { type: \"boolean\", default: false },\n mjs: { type: \"boolean\", default: false },\n force: { type: \"boolean\", default: false },\n },\n allowPositionals: false,\n });\n\n if (values.js && values.mjs) {\n process.stderr.write(\"refract init: pass at most one of --js / --mjs.\\n\");\n return 1;\n }\n const variant: ConfigVariant = values.mjs ? \"mjs\" : values.js ? \"js\" : \"ts\";\n\n try {\n const result = runInit({ variant, force: Boolean(values.force) });\n process.stdout.write(`Created ${result.path}\\n`);\n process.stdout.write(`Next: edit the raw theme, then run \\`refract build\\`.\\n`);\n return 0;\n } catch (err) {\n return reportError(\"init\", err);\n }\n}\n\nasync function cmdImport(argv: string[]): Promise<number> {\n const { values, positionals } = parseArgs({\n args: argv,\n options: {\n out: { type: \"string\" },\n \"raw-only\": { type: \"boolean\", default: false },\n force: { type: \"boolean\", default: false },\n \"breakpoint-group\": { type: \"string\" },\n breakpoints: { type: \"string\" },\n },\n allowPositionals: true,\n });\n\n const input = positionals[0];\n if (!input) {\n process.stderr.write(\"refract import: pass the DTCG document to import, e.g. `refract import tokens.json`.\\n\");\n return 1;\n }\n if (positionals.length > 1) {\n process.stderr.write(`refract import: unexpected extra argument \"${positionals[1]}\".\\n`);\n return 1;\n }\n\n try {\n const result = runImport({\n input,\n out: values.out,\n rawOnly: Boolean(values[\"raw-only\"]),\n force: Boolean(values.force),\n breakpointGroup: values[\"breakpoint-group\"],\n breakpoints: values.breakpoints ? parseBreakpointsFlag(values.breakpoints) : undefined,\n });\n process.stdout.write(`Imported ${result.inputFile}\\n`);\n process.stdout.write(` raw → ${result.rawFile}\\n`);\n if (result.configFile) process.stdout.write(` config → ${result.configFile}\\n`);\n const seeded = Object.entries(result.counts).map(([k, n]) => `${k} (${n})`).join(\", \");\n if (seeded) process.stdout.write(` seeded: ${seeded}\\n`);\n process.stdout.write(`Next: review the inferred tokens, then add recipes/components and run \\`refract build\\`.\\n`);\n return 0;\n } catch (err) {\n return reportError(\"import\", err);\n }\n}\n\nasync function cmdBuild(argv: string[]): Promise<number> {\n const { values } = parseArgs({\n args: argv,\n options: {\n config: { type: \"string\" },\n target: { type: \"string\" },\n out: { type: \"string\" },\n },\n allowPositionals: false,\n });\n\n try {\n const result = await runBuild({\n configPath: values.config,\n target: values.target,\n out: values.out,\n });\n process.stdout.write(`Built from ${result.configPath}\\n`);\n for (const t of result.targets) {\n const label = t.name ? `${t.name} [${t.adapter}]` : t.adapter;\n process.stdout.write(` ${label} → ${t.outDir} (${t.files.length} file(s))\\n`);\n for (const f of t.files) process.stdout.write(` ${f}\\n`);\n }\n return 0;\n } catch (err) {\n return reportError(\"build\", err);\n }\n}\n\nasync function cmdTokens(argv: string[]): Promise<number> {\n const { values } = parseArgs({\n args: argv,\n options: {\n config: { type: \"string\" },\n out: { type: \"string\" },\n },\n allowPositionals: false,\n });\n\n try {\n const result = await runTokens({\n configPath: values.config,\n out: values.out,\n });\n process.stdout.write(`Exported tokens from ${result.configPath}\\n`);\n process.stdout.write(` ${result.groupCount} group(s) → ${result.outFile}\\n`);\n return 0;\n } catch (err) {\n return reportError(\"tokens\", err);\n }\n}\n\nconst WCAG_LEVELS: ReadonlySet<string> = new Set([\"AAA\", \"AA\", \"AA-large\"]);\n\nasync function cmdDiff(argv: string[]): Promise<number> {\n const { values, positionals } = parseArgs({\n args: argv,\n options: {\n config: { type: \"string\" },\n \"max-class-changes\": { type: \"string\" },\n \"max-token-changes\": { type: \"string\" },\n \"fail-below\": { type: \"string\" },\n },\n allowPositionals: true,\n });\n\n const candidate = positionals[0];\n if (!candidate) {\n process.stderr.write(\"refract diff: pass the candidate theme, e.g. `refract diff candidate.ts`.\\n\");\n return 1;\n }\n const failBelow = values[\"fail-below\"];\n if (failBelow !== undefined && !WCAG_LEVELS.has(failBelow)) {\n process.stderr.write(`refract diff: --fail-below must be one of AAA | AA | AA-large (got \"${failBelow}\").\\n`);\n return 1;\n }\n\n try {\n const result = await runDiff({\n configPath: values.config,\n candidatePath: candidate,\n maxClassChanges: values[\"max-class-changes\"] !== undefined ? Number(values[\"max-class-changes\"]) : undefined,\n maxTokenChanges: values[\"max-token-changes\"] !== undefined ? Number(values[\"max-token-changes\"]) : undefined,\n failBelow,\n });\n const { diff } = result;\n process.stdout.write(`Diffed ${result.candidatePath}\\n vs ${result.configPath}\\n`);\n process.stdout.write(\n ` ${diff.summary.tokensChanged} token(s), ${diff.summary.classesChanged} class(es), ${diff.summary.pairingsCrossed} pairing(s) crossed a threshold\\n`,\n );\n for (const t of diff.tokens.slice(0, 20)) {\n const arrow = t.kind === \"changed\" ? `${t.before} → ${t.after}` : t.kind === \"added\" ? `+ ${t.after}` : `- ${t.before}`;\n process.stdout.write(` token ${t.path}: ${arrow}\\n`);\n }\n if (diff.tokens.length > 20) process.stdout.write(` … +${diff.tokens.length - 20} more token(s)\\n`);\n for (const c of diff.classes) process.stdout.write(` class ${c.kind.padEnd(7)} ${c.name}\\n`);\n for (const c of diff.contrast.filter((x) => x.crossed)) {\n process.stdout.write(` contrast ${c.label}: ${c.before?.level ?? \"—\"} → ${c.after?.level ?? \"—\"}\\n`);\n }\n if (result.violations.length) {\n process.stderr.write(`✗ diff gate failed:\\n`);\n for (const v of result.violations) process.stderr.write(` ${v}\\n`);\n return 1;\n }\n return 0;\n } catch (err) {\n return reportError(\"diff\", err);\n }\n}\n\nasync function cmdAudit(argv: string[]): Promise<number> {\n const { values } = parseArgs({\n args: argv,\n options: {\n config: { type: \"string\" },\n strict: { type: \"boolean\", default: false },\n \"min-wcag\": { type: \"string\" },\n large: { type: \"boolean\", default: false },\n },\n allowPositionals: false,\n });\n\n const minWcag = values[\"min-wcag\"];\n if (minWcag !== undefined && !WCAG_LEVELS.has(minWcag)) {\n process.stderr.write(`refract audit: --min-wcag must be one of AAA | AA | AA-large (got \"${minWcag}\").\\n`);\n return 1;\n }\n\n try {\n const { configPath, result } = await runAudit({\n configPath: values.config,\n strict: values.strict,\n minWcag: minWcag as WcagLevel | undefined,\n largeText: values.large,\n });\n process.stdout.write(`Audited ${configPath}\\n`);\n for (const p of result.pairings) {\n if (p.skipped) {\n process.stdout.write(` ~ ${p.label} — skipped (${p.skipped})\\n`);\n } else {\n const flag = p.pass ? \"✓\" : \"✗\";\n process.stdout.write(` ${flag} ${p.label} — ${p.wcagRatio}:1 ${p.wcagLevel} · APCA Lc ${p.apcaLc}\\n`);\n }\n }\n const s = result.summary;\n process.stdout.write(`${s.passed}/${s.total} pass, ${s.failed} fail, ${s.skipped} skipped\\n`);\n // Report mode: a failing audit is not a CLI error (exit 0). --strict makes `runAudit` throw first.\n return 0;\n } catch (err) {\n return reportError(\"audit\", err);\n }\n}\n\n/** Parse an `--agent` value (`\"all\"` or a comma list) into validated targets. */\nfunction parseAgents(raw: string): AgentTarget[] {\n if (raw.trim() === \"all\") return [...AGENT_TARGETS];\n const names = raw.split(\",\").map(s => s.trim()).filter(Boolean);\n const bad = names.filter(n => !AGENT_TARGETS.includes(n as AgentTarget));\n if (bad.length > 0) {\n throw new Error(\n `unknown agent(s) ${bad.map(b => `\"${b}\"`).join(\", \")}. Known: ${AGENT_TARGETS.join(\", \")}.`,\n );\n }\n return names as AgentTarget[];\n}\n\n/** Interactively gather install options when none were passed and a TTY is attached. */\nasync function promptSkillsInstall(): Promise<{\n agents: AgentTarget[];\n scope: InstallScope;\n includeOptional: boolean;\n}> {\n const rl = createInterface({ input: process.stdin, output: process.stdout });\n try {\n process.stdout.write(\"Install refract skills for which agent(s)?\\n\");\n AGENT_TARGETS.forEach((a, i) => process.stdout.write(` ${i + 1}) ${a}\\n`));\n const pick = await rl.question(\"Enter numbers (comma-separated), or 'all': \");\n const agents =\n pick.trim() === \"all\" || pick.trim() === \"\"\n ? [...AGENT_TARGETS]\n : pick\n .split(\",\")\n .map(s => AGENT_TARGETS[Number(s.trim()) - 1])\n .filter((a): a is AgentTarget => Boolean(a));\n if (agents.length === 0) throw new Error(\"no agents selected.\");\n\n const scopeAns = (await rl.question(\"Scope — [l]ocal (project) or [g]lobal (home)? [l]: \"))\n .trim()\n .toLowerCase();\n const scope: InstallScope = scopeAns.startsWith(\"g\") ? \"global\" : \"local\";\n\n const optAns = (await rl.question(\"Include optional skills (adapter-scaffold, troubleshooting)? [y/N]: \"))\n .trim()\n .toLowerCase();\n return { agents, scope, includeOptional: optAns.startsWith(\"y\") };\n } finally {\n rl.close();\n }\n}\n\nasync function cmdSkills(argv: string[]): Promise<number> {\n const [sub, ...rest] = argv;\n\n if (sub === \"list\") {\n try {\n for (const s of listSkills()) {\n process.stdout.write(` ${s.name.padEnd(26)} [${s.tier}] ${s.description.split(/\\s*Triggers:/)[0].trim().slice(0, 80)}\\n`);\n }\n return 0;\n } catch (err) {\n return reportError(\"skills list\", err);\n }\n }\n\n const { values } = parseArgs({\n args: rest,\n options: {\n agent: { type: \"string\" },\n global: { type: \"boolean\", default: false },\n local: { type: \"boolean\", default: false },\n only: { type: \"string\" },\n optional: { type: \"boolean\", default: false },\n },\n allowPositionals: false,\n });\n\n if (values.global && values.local) {\n process.stderr.write(\"refract skills: pass at most one of --global / --local.\\n\");\n return 1;\n }\n const scope: InstallScope = values.global ? \"global\" : \"local\";\n\n try {\n if (sub === \"update\") {\n const result = runSkillsUpdate({ scope });\n process.stdout.write(`Updated ${result.skills.length} skill(s) for ${result.agents.join(\", \")} (${result.scope}).\\n`);\n return 0;\n }\n\n if (sub === \"install\" || sub === undefined) {\n let agents: AgentTarget[];\n let includeOptional = Boolean(values.optional);\n let installScope = scope;\n\n if (values.agent) {\n agents = parseAgents(values.agent);\n } else if (process.stdin.isTTY) {\n const answers = await promptSkillsInstall();\n agents = answers.agents;\n includeOptional = answers.includeOptional;\n if (!values.global && !values.local) installScope = answers.scope;\n } else {\n process.stderr.write(\"refract skills install: pass --agent <a,b|all> (no TTY for prompts).\\n\");\n return 1;\n }\n\n const result = runSkillsInstall({\n agents,\n scope: installScope,\n skills: values.only ? values.only.split(\",\").map(s => s.trim()).filter(Boolean) : undefined,\n includeOptional,\n });\n process.stdout.write(\n `Installed ${result.skills.length} skill(s) for ${result.agents.join(\", \")} (${result.scope}):\\n`,\n );\n for (const f of result.files) process.stdout.write(` ${f}\\n`);\n process.stdout.write(` manifest → ${result.manifestPath}\\n`);\n return 0;\n }\n\n process.stderr.write(`refract skills: unknown subcommand \"${sub}\". Use install | list | update.\\n`);\n return 1;\n } catch (err) {\n return reportError(\"skills\", err);\n }\n}\n\n/** Dispatch a parsed argv (without the node/script prefix). Returns a process exit code. */\nexport async function main(argv: string[]): Promise<number> {\n const [command, ...rest] = argv;\n switch (command) {\n case \"init\":\n return cmdInit(rest);\n case \"import\":\n return cmdImport(rest);\n case \"build\":\n return cmdBuild(rest);\n case \"tokens\":\n return cmdTokens(rest);\n case \"diff\":\n return cmdDiff(rest);\n case \"audit\":\n return cmdAudit(rest);\n case \"skills\":\n return cmdSkills(rest);\n case undefined:\n case \"help\":\n case \"--help\":\n case \"-h\":\n process.stdout.write(HELP);\n return 0;\n default:\n process.stderr.write(`refract: unknown command \"${command}\".\\n\\n${HELP}`);\n return 1;\n }\n}\n\n// Executed as the `bin` entry: run and map the exit code. Guarded so importing this module (tests)\n// doesn't trigger a run. `require.main === module` is the CJS \"am I the entry\" check; the CLI bundle\n// ships as CJS (see rollup.config.mjs), where `require`/`module` are the real CommonJS globals.\nif (typeof require !== \"undefined\" && typeof module !== \"undefined\" && require.main === module) {\n main(process.argv.slice(2)).then(\n code => process.exit(code),\n err => {\n process.stderr.write(`refract: ${(err as Error).stack ?? err}\\n`);\n process.exit(1);\n },\n );\n}\n"],"names":["VENDOR_HELPERS","id","outfile","source","exports","description","findVendorHelper","find","h","findPackageRoot","startDir","__dirname","dir","existsSync","join","parent","dirname","Error","readVendorSource","path","readFileSync","async","loadTypescript","mod","import","default","_a","transpileToEsm","sourceText","tsc","transpileModule","compilerOptions","module","ModuleKind","ESNext","target","ScriptTarget","ES2020","outputText","graphCounter","graphKey","p","resolve","replace","compileTsConfigGraph","configPath","options","moduleResolution","ModuleResolutionKind","Bundler","resolveJsonModule","allowJs","noLib","skipLibCheck","noEmitOnError","declaration","sourceMap","types","host","createCompilerHost","program","createProgram","tempFor","Map","isCompiledTs","sf","isDeclarationFile","fileName","includes","test","getSourceFiles","abs","base","basename","set","process","pid","rewrite","context","sourceFile","containing","factory","specFor","text","temp","spec","containingFile","startsWith","resolved","resolveModuleName","resolvedModule","resolvedFileName","get","undefined","rewriteTarget","createStringLiteral","visit","node","isImportDeclaration","isStringLiteral","moduleSpecifier","next","updateImportDeclaration","modifiers","importClause","attributes","isExportDeclaration","updateExportDeclaration","isTypeOnly","exportClause","isCallExpression","expression","kind","SyntaxKind","ImportKeyword","arguments","length","updateCallExpression","typeArguments","slice","visitEachChild","visitNode","written","writeFile","writeFileSync","push","cleanup","file","rmSync","force","emit","before","err","entry","escapeCell","s","renderLlms","descriptor","manifestName","lines","format","files","f","summary","packageName","recipes","shown","r","subsystem","group","variant","name","rest","buildGuide","tokens","llmsName","llmsFile","manifestFile","manifest","schema","JSON","stringify","RefractError","constructor","code","message","failures","super","this","Object","setPrototypeOf","prototype","isLiteral","value","isStructuredValue","Array","isArray","toRef","variantToRef","derive","ref","fn","arg","MODE_STRUCTURAL_KEYS","Set","buildModeFields","mode","propertyName","modeName","fields","struct","key","entries","has","collectScalarRefs","obj","exclude","out","VARIANT_STRUCTURAL_KEYS","PROPERTY_STRUCTURAL_KEYS","RESPONSIVE_CONDITION_KEYS","buildPropertyModel","normalized","model","external","extras","keys","variants","variantDerive","variantExtras","normalizedModes","modes","override","overrides","responsive","map","e","breakpoint","query","orientation","collectFieldRefs","buildRuleSetFromInterpreted","declarations","state","container","size","buildComponentRuleSetFromInterpreted","references","ruleSet","COMPONENT_SUBSYSTEM_KEYS","hasEntries","buildSubsystemModel","properties","collection","buildPropertiesModel","extraProperties","ruleSetGroups","ruleSets","keyframes","buildTokenMap","subModel","subsystems","property","propertyModel","v","_b","field","_c","_d","UNIT_SET","NUMERIC_RE","LENGTH_RE","parseLength","input","trimmed","trim","Number","m","exec","unit","toLowerCase","raw","SEED","resolveRoleUnit","pathKey","units","indexOf","roundRem","baseFontSize","toFixed","resolveDeferred","role","resolveShadowDimension","dim","LENGTH_REGISTRY","typography","fontSize","letterSpacing","lineHeight","layout","spacing","gutters","sizes","borders","width","offset","radius","effects","blur","shadow","mapRefs","record","changed","mapPropertyLeaves","includeExtras","mapVariants","mapModes","mapResponsive","resolvePropertyModel","layers","layer","resolveShadowLayer","parsed","resolveLengthRef","resolveModelUnits","config","anySubChanged","subKey","anyPropChanged","prop","pm","formatContextLabel","propertyPath","isAllowedValue","allowed","validateNormalizedResponsiveRefs","variantNames","label","isModeDerivation","parseModifiers","i","isExtendedProperty","resolveBaseValue","providedBase","fallback","candidate","fallbackBase","coerceValue","partitionLeafBase","leafFields","leafSet","extra","hasLeaf","resolveBaseAndExtra","partitioned","assembled","normalizeVariant","variantPath","extended","resolvedBase","normalizePropertyValue","normalizedVariants","fromEntries","definition","modePath","normalizeMode","responsiveContext","allowedBreakpoints","normalizedResponsive","allowedVariants","allowedTargets","finalResponsive","condition","others","explicitBase","some","assembleResponsiveLeaf","CONTAINER_INVALID_FIELDS","RESPONSIVE_KEY","STATES_KEY","CSS_KEY","VARIANTS_KEY","toStateArray","states","delta","stateEntryKey","mergeRecipeStates","index","d","at","mergeRecipe","merged","normalizeRecipeGroup","expandedGroup","values","recipe","expanded","recipeName","recipeDef","baseForSibling","filter","variantName","expandRecipeVariants","allowedVariantSet","forEach","normalizeRecipeVariant","allowedStates","allowedContainers","normalizeRecipeStates","normalizeRecipeResponsive","stateName","sibling","normalizeContainerEntry","createRecipeVariantResolver","interpret","cache","inProgress","groupPath","cycle","result","pop","resolveAll","resolveToken","registry","resolving","cached","add","reduce","delete","isCrossPropertyDerived","owner","seg0","seg1","split","propertyPrefix","rebake","where","apply","rebakeFields","rebakeProperty","rebakeVariants","nextFields","bakeCrossPropertyDerivations","modelChanged","nextSubsystems","sub","nextProps","subChanged","propName","nextPm","RESERVED_BREAKPOINT_KEYS","maxValueForNext","buildMediaDescriptor","breakpoints","resolveQuery","sort","a","b","sortBreakpointKeys","conflicts","k","assertNoReservedBreakpointNames","nextOf","groups","acc","own","nextKey","buildGroupDescriptor","resolveKey","min","max","exact","between","from","to","toValue","maxValue","DEFAULT_MEDIA_CONFIG","resolveMediaConfig","formatWidth","converted","mediaQueryString","clauses","containerQueryString","DEFAULT_BREAKPOINTS","xs","sm","md","lg","xl","buildContainerDescriptors","containers","opts","HEX_LENGTHS","clamp","Math","clampChannel","roundAlpha","round","convertHexToRGB","hex","sanitized","parseInt","substring","RGB_FN","parseColor","rgb","serializeColor","alpha","g","R","G","B","DEG","PI","srgbToLinear","c","pow","linearToSrgb","rgbToOklch","lab","lr","lb","l","l_","cbrt","m_","s_","L","linearRgbToOklab","C","sqrt","atan2","oklchToRgb","color","hr","cosh","cos","sinh","sin","linearAt","oklabToLinearRgb","inGamut","lin","every","lo","hi","mid","withOklch","transform","lighten","lch","darken","setL","rotateHue","deg","adjust","dials","toHexColor","toString","convertRgbToHex","padStart","percent","clampPercent","CSS_COLOR_KEYWORDS","aliceblue","antiquewhite","aqua","aquamarine","azure","beige","bisque","black","blanchedalmond","blue","blueviolet","brown","burlywood","cadetblue","chartreuse","chocolate","coral","cornflowerblue","cornsilk","crimson","cyan","darkblue","darkcyan","darkgoldenrod","darkgray","darkgreen","darkgrey","darkkhaki","darkmagenta","darkolivegreen","darkorange","darkorchid","darkred","darksalmon","darkseagreen","darkslateblue","darkslategray","darkslategrey","darkturquoise","darkviolet","deeppink","deepskyblue","dimgray","dimgrey","dodgerblue","firebrick","floralwhite","forestgreen","fuchsia","gainsboro","ghostwhite","gold","goldenrod","gray","green","greenyellow","grey","honeydew","hotpink","indianred","indigo","ivory","khaki","lavender","lavenderblush","lawngreen","lemonchiffon","lightblue","lightcoral","lightcyan","lightgoldenrodyellow","lightgray","lightgreen","lightgrey","lightpink","lightsalmon","lightseagreen","lightskyblue","lightslategray","lightslategrey","lightsteelblue","lightyellow","lime","limegreen","linen","magenta","maroon","mediumaquamarine","mediumblue","mediumorchid","mediumpurple","mediumseagreen","mediumslateblue","mediumspringgreen","mediumturquoise","mediumvioletred","midnightblue","mintcream","mistyrose","moccasin","navajowhite","navy","oldlace","olive","olivedrab","orange","orangered","orchid","palegoldenrod","palegreen","paleturquoise","palevioletred","papayawhip","peachpuff","peru","pink","plum","powderblue","purple","rebeccapurple","red","rosybrown","royalblue","saddlebrown","salmon","sandybrown","seagreen","seashell","sienna","silver","skyblue","slateblue","slategray","slategrey","snow","springgreen","steelblue","tan","teal","thistle","tomato","turquoise","violet","wheat","white","whitesmoke","yellow","yellowgreen","hslToRgb","hue","x","OKLCH_STR","HSL_STR","coerceColorInput","ok","hs","keyword","parseColorInput","n","DERIVE_FNS","NAMED_LIGHTER_ORDER","NAMED_DARKER_ORDER","isCrossPropertyRef","coerceText","error","finalizePaletteNormalization","normalized0","derivationSpecs","coerceTextFields","baseParseable","isParseableColor","hasSteps","steps","hasDerivations","hasHarmony","harmony","autoVariants","generateAutoVariants","harmonyVariants","generateHarmonyVariants","plainVariants","known","derivedVariants","bakeDerivationVariants","bakedModes","bakeDerivedModes","bakedResponsive","bakeResponsiveDerivations","rawModifiers","coerced","parseSpecModifiers","_ref","_mods","_base","_derive","resolveSource","palette","generateNumericSteps","generateDefaultVariants","HARMONY_SCHEMES","complement","analogous","triadic","tetradic","scheme","renames","members","member","buildChain","existingVariants","chainSteps","fnName","amount","tokenPath","prevName","prev","step","lightenAmount","lightenBy","darkenAmount","darkenBy","labelToL","bad","isNaN","parseAdjust","specs","baking","baseOf","bakeOne","sourceOf","KNOWN_CSS_PROPERTIES","VENDOR_PREFIX","isKnownCssProperty","kebab","RESERVED_RECIPE_KEYS","interpretProps","props","ctx","resolvePaletteReference","formatPropertyName","segments","relLuminance","LEVEL_RANK","fail","AA","AAA","APCA","apcaY","apcaLc","bg","y","yTxt","yBg","sapc","dp","refToColor","theme","String","FG_KEY","BG_KEYS","pickBg","decls","scorePair","fg","fgRgb","bgRgb","skipped","ratio","la","wcagRatio","level","large","wcagLevel","largeText","pass","minWcag","audit","includeRecipes","pairings","includePalettes","ruleSetGroup","baseFg","baseBg","_e","oFg","_g","_f","oBg","_h","cond","_l","_j","_k","scored","failed","worst","w","Infinity","total","passed","strict","list","RESERVED_KEYS","isDerivationSpec","splitDerivationVariants","plain","nextVariants","colorsSubsystem","derivations","normalizeProperties","rawSlice","plainValue","finalized","interpretRecipe","swap","rawDecls","resolveRecipeVariant","interpretPaletteRecipeVariant","TYPOGRAPHY_RATIOS","golden","DEFAULT_SCALE_STEPS","finalizeTypographyNormalization","propertyKey","generateFontSizeScaleVariants","ratioValue","precision","algorithm","generated","previousValue","rounded","PROPERTY_CSS_MAP","fontFamily","fontWeight","fontStyle","textTransform","textDecoration","textAlign","cssProperty","typographySubsystem","interpretTypographyRecipeVariant","LAYOUT_PROPERTY_KEYS","SCALE_PROPERTIES","FORCE_NONE_PROPERTIES","DEFAULT_LADDER","finalizeLayoutNormalization","hasRatio","hasStep","names","exp","curve","mult","readScaleConfig","forceNoneVariant","synthesized","synthesizeVariants","none","propBase","expandedAny","geometric","hasBase","expandResponsive","stripScaleKeys","paddingY","paddingX","marginY","marginX","gap","background","minWidth","maxWidth","height","minHeight","maxHeight","PROPERTY_DOMAIN","domain","cssProperties","spacingRef","guttersRef","configRef","literal","sortByWidth","GRID_LITERAL_PROPS","gridDeclarations","grid","includeDisplay","resolveContainerConfig","inset","gutter","direction","align","justify","buildContainer","containerInput","sizeNames","mediaConfig","resolvedMedia","mediaLen","configProperties","sortedKeys","baseConfig","responsiveEntries","variantKeyFor","buildSingleContainer","suffix","insetKey","gutterKey","insetRef","gutterRef","maxWidthValue","maxBp","maxBpIndex","resolveFluidMaxWidth","variantKey","buildLayoutStructural","merge","assign","spans","_","span","colVariant","offsetVariant","colDecl","offsetDecl","columns","buildColumns","grids","respDecls","buildGrids","stacks","stack","display","inline","wrap","buildStacks","collectSizeNames","PROPERTY_KEYS","layoutSubsystem","scaleStep","interpretLayoutRecipeVariant","buildStructural","boxShadow","opacity","transition","zIndex","RESOLVE_KEY_MAP","isPlainObject","numberField","dimensionField","SHADOW_FIELDS","coerceShadowLayer","offsetX","offsetY","spread","TRANSITION_FIELDS","coerceTransitionPart","part","duration","delay","timingFunction","LEAF_FIELDS","transitions","coerceFor","coerceShadowValue","coerceTransitionValue","effectsSubsystem","interpretEffectsRecipeVariant","MODIFIER_KEYS","ASPECT_KEYS","cssPropertyFor","as","side","aspect","refFor","bordersSubsystem","baseAs","baseSide","entryAs","entrySide","interpretBordersRecipeVariant","easing","iterationCount","fillMode","playState","declarationRef","parseStepDeclarations","parseKeyframe","stop","buildKeyframes","animationSubsystem","interpretAnimationRecipeVariant","interpretCssDelta","css","cssValueToRef","componentsSubsystem","_variantName","interpretComponentsRecipeVariant","extractReferences","normalizedVariantBase","rawVariantBase","extractComponentReferences","tokenRef","resetRuleSet","selector","staticGroup","DEFAULT_HEADINGS","PRESETS","preflight","static","margin","padding","font","headings","normalize","reset","border","GLOBALS_PRESET_NAMES","expandPreset","preset","defaults","tag","buildDefaultHeadingGroup","CONDITION_KEYS","leafToRef","formatProperty","interpretDeclarations","interpretOverride","normalizeElementItem","def","interpretItem","buildGlobalsRuleSets","elements","element","baseDef","variantMap","buildElementsGroup","SUBSYSTEMS","buildMedia","normalizeContainers","type","containerSizeSets","resolveExternalVar","prefix","dashed","buildSubsystemInput","clean","externals","varName","extractExternals","extendsPrefix","interpretProperties","inheritedProperties","recipeGroups","rawRecipes","groupName","groupDef","resolver","media","interpreted","interpretedVariant","buildSubsystemRuleSets","structural","reconstructNormalizedProperties","vname","reconstructed","ename","mergeSubsystemModel","current","partial","groupRuleSets","createTheme","rawTheme","adapter","extends","allowedModes","subsystemInputs","built","colors","animation","components","globals","buildThemeModel","unitConfig","overlaid","propertiesOverlay","ruleSetsOverlay","keyframesOverlay","containersOverlay","applyModelOverlay","derivationRegistry","contributions","contribution","buildDerivationRegistry","flatMap","validationErrors","collectComponentReferenceErrors","collectComponentCssRefErrors","collectGlobalsRefErrors","collectModeErrors","assembleTheme","errors","report","reference","dot","refGroup","refVariant","checkDecls","engine","tokenMapCache","WeakMap","getTokens","bound","bind","currentModel","partialBreakpoints","nextBreakpoints","partialContainers","nextContainers","partialInput","partialSubModel","nextModel","baked","overrideTheme","extensions","extend","call","defineProperties","getOwnPropertyDescriptors","DEFAULT_SINGLE_FILE","DEFAULT_SPLIT_STYLES","DEFAULT_SPLIT_VARIABLES","DEFAULT_SUBSYSTEM_FILENAME","DEFAULT_COMPONENTS_FILENAME","DEFAULT_COMPONENTS_VARIABLES","resolveEmitPlan","variables","filename","o","REFRACT_DTCG_EXTENSION","isToken","REFERENCE_PATTERN","resolveReferences","tokensByPath","visited","match","refPath","referenced","item","eachRuleSet","createNoopAdapter","version","renderRecipe","renderVariables","parts","renderAllRecipes","renderAllVariables","renderAll","describeUsage","fromDTCG","doc","walk","inheritedType","groupType","$type","child","childPath","token","$value","$description","$extensions","parseDTCGDocument","groupMapping","grouped","topGroup","bpGroup","breakpointGroup","parseDimension","groupTokens","mapping","detectSubsystem","mapColorTokens","mapTypographyTokens","mapEffectsTokens","mapBordersTokens","mapLayoutTokens","firstType","lower","UNRESOLVED_ALIAS","aliasToExternalPath","inner","subgroups","topLevel","subName","subTokens","baseToken","t","last","TYPO_PROPERTY_MAP","fontfamily","fontsize","fontweight","lineheight","letterspacing","fontstyle","texttransform","textdecoration","textalign","addTypographyVariant","parseDimensionOrKeep","detectTypoProperty","fullPath","shadowStr","formatShadowValue","addEffectsVariant","bezier","transStr","addBordersVariant","style","formatSingleShadow","num","parseFloat","endsWith","toDTCG","$name","includeBreakpoints","bp","resolveColor","typo","getTypographyTokenType","formatTypoValue","baseUnit","memberUnits","getEffectsGroupInfo","formatEffectsValue","getBordersGroupInfo","formatBordersValue","formatDimensionValue","ext","hasProperties","hasRuleSets","hasKeyframes","hasContainers","buildRefractExtension","dimText","dot2","subMap","segs","zero","dtcgLayerUnit","len","dtcgShadowDim","composeDtcgShadow","emitTheme","outDir","helpers","guide","emitted","mkdirSync","recursive","write","contents","dest","vendorHelpers","helper","cfg","defineConfig","CONFIG_BASENAME","EXT_ORDER","findConfigFile","fromDir","cwd","importCounter","loadConfig","extname","url","pathToFileURL","href","importConfigModule","targets","CSS_ADAPTER_PACKAGE","readOwnPackageName","pkgPath","parse","scaffoldConfig","runInit","DEFAULT_CONFIG_OUT","parseBreakpointsFlag","pair","isFinite","scaffoldRaw","sourceLabel","scaffoldImportConfig","rawImportSpec","summarizeCounts","counts","runImport","inputFile","isAbsolute","fromOpts","rawFile","configFile","rawOnly","sections","runBuild","selected","byName","idx","byOutDir","selectTargets","configDir","summaries","runTokens","outFile","groupCount","runAudit","resolvedValue","recipeIds","hasRecipe","Boolean","diffThemes","paths","inBase","inCandidate","after","localeCompare","diffTokens","classes","seen","ids","getClass","b2","diffClasses","contrast","score","byLabel","labels","bs","crossed","diffContrast","tokensChanged","classesChanged","pairingsCrossed","WCAG_RANK","counter","loadCandidate","got","assertRawTheme","runDiff","candidatePath","candidateRaw","buildOpts","adapters","pick","diff","violations","maxClassChanges","maxTokenChanges","failBelow","bar","afterRank","beforeRank","failedTargets","AGENT_TARGETS","AGENT_ROUTER","claude","routerFile","codex","opencode","cursor","generic","ROUTER_START","ROUTER_END","MANIFEST_REL","BODY_DIR_REL","skillsCatalogDir","listSkills","catalogDir","readdirSync","withFileTypes","isDirectory","sourcePath","front","body","line","RegExp","tier","parseSkillFile","renderRouter","skills","rows","skill","beforeTriggers","shortDescription","upsertRouterBlock","existing","block","start","end","writeFileEnsuring","content","runSkillsInstall","scope","home","homedir","catalog","chosen","includeOptional","selectSkills","agents","agent","routerPath","refractVersion","pkg","readOwnPackageMeta","manifestPath","runSkillsUpdate","HELP","reportError","cmd","stderr","WCAG_LEVELS","cmdSkills","argv","stdout","padEnd","parseArgs","args","global","local","only","optional","allowPositionals","installScope","parseAgents","stdin","isTTY","answers","rl","createInterface","output","question","close","promptSkillsInstall","main","command","js","mjs","cmdInit","positionals","seeded","cmdImport","cmdBuild","cmdTokens","arrow","cmdDiff","flag","cmdAudit","require","then","exit"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"build.esm.js","sources":["../src/build/vendor.ts","../src/build/paths.ts","../src/build/guide.ts","../src/core/errors.ts","../src/core/model/buildModel.ts","../src/core/units.ts","../src/core/normalize/responsive.ts","../src/core/normalize/properties.ts","../src/core/normalize/recipes.ts","../src/core/normalize/recipeResolver.ts","../src/core/derive/resolveTokens.ts","../src/core/derive/crossProperty.ts","../src/core/media/descriptors.ts","../src/core/media/queries.ts","../src/core/media/defaults.ts","../src/core/media/containers.ts","../src/subsystems/colors/utils.ts","../src/subsystems/colors/keywords.ts","../src/subsystems/colors/colorInput.ts","../src/subsystems/colors/normalize.ts","../src/core/cssProperties.ts","../src/subsystems/colors/recipes.ts","../src/subsystems/colors/audit.ts","../src/subsystems/colors/index.ts","../src/subsystems/typography/normalize.ts","../src/subsystems/typography/recipes.ts","../src/subsystems/typography/index.ts","../src/subsystems/layout/types.ts","../src/subsystems/layout/normalize.ts","../src/subsystems/layout/recipes.ts","../src/subsystems/layout/structural.ts","../src/subsystems/layout/index.ts","../src/subsystems/effects/recipes.ts","../src/subsystems/effects/utils.ts","../src/subsystems/effects/index.ts","../src/subsystems/borders/recipes.ts","../src/subsystems/borders/index.ts","../src/subsystems/animation/recipes.ts","../src/subsystems/animation/index.ts","../src/subsystems/components/recipes.ts","../src/subsystems/components/index.ts","../src/subsystems/globals/presets.ts","../src/subsystems/globals/index.ts","../src/core/createTheme.ts","../src/build/emit.ts","../src/dtcg/types.ts","../src/dtcg/parse.ts","../src/core/defineAdapter.ts","../src/core/noopAdapter.ts","../src/dtcg/import.ts","../src/dtcg/export.ts","../src/build/emitTheme.ts","../src/build/config.ts","../src/build/init.ts","../src/build/scaffold.ts","../src/build/createCommand.ts","../src/build/prompt.ts","../src/build/createInterview.ts","../src/build/importCommand.ts","../src/build/buildCommand.ts","../src/build/tokensCommand.ts","../src/build/auditCommand.ts","../src/build/diff.ts","../src/build/diffCommand.ts","../src/core/assertRawTheme.ts","../src/build/skillsCommand.ts","../src/build/cli.ts"],"sourcesContent":["/**\n * Vendorable-helper registry (build-time, Node-only) — the SINGLE source of truth for which live\n * helper modules get shipped into a consumer's build output.\n *\n * Option A vendoring (locked 2026-07-11): a helper is authored ONCE in its natural home (e.g.\n * `lighten`/`darken` in `src/subsystems/colors/utils.ts`) and stays there for refract's own\n * runtime use. This registry merely POINTS at that source; the build layer (`src/build/`, added in\n * 10b) transpiles it (type-strip) and writes the standalone result to the consumer's output. There\n * is NO second copy of the function bodies anywhere, so drift is structurally impossible.\n *\n * Requirement on a listed source: it must be **self-contained** (import-free, or its imports are\n * themselves vendored) so the transpiled artifact is standalone — the \"package not needed at\n * runtime\" promise. `test/color-math.test.ts` asserts this for `color-math`.\n *\n * This module is build metadata (plain data, no `node:fs`), deliberately NOT re-exported from the\n * runtime `.` barrel — it belongs to the Node-only build/CLI surface (the `./build` subpath, 10e).\n *\n * NOTE (packaging, resolved in 10b): `source` is repo-relative. The published package ships only\n * `dist/`, so the build layer will either ship these helper sources or read a built standalone\n * artifact; that resolution detail is 10b's, not baked in here.\n */\n\n/** A shared, static helper refract can vendor into a consumer's build output. */\nexport interface VendorHelperSource {\n /** Stable id — also the key a build target opts in by. */\n readonly id: string;\n /** Filename written into the consumer's output directory. */\n readonly outfile: string;\n /** Repo-relative path to the single-source module whose transpiled output is the vendored artifact. */\n readonly source: string;\n /** The named exports the vendored module provides (for docs / validation). */\n readonly exports: readonly string[];\n /** What the helper is for. */\n readonly description: string;\n}\n\n/** The shared vendorable helpers. Theme-specific helpers (e.g. the SC media module with baked\n * `@media` strings) are NOT here — those are generated per-theme by the owning adapter's `emit()`. */\nexport const VENDOR_HELPERS: readonly VendorHelperSource[] = [\n {\n id: \"color-math\",\n outfile: \"color-math.js\",\n source: \"src/subsystems/colors/utils.ts\",\n exports: [\n \"lighten\",\n \"darken\",\n \"alpha\",\n \"setL\",\n \"rotateHue\",\n \"complement\",\n \"adjust\",\n \"rgbToOklch\",\n \"oklchToRgb\",\n \"toHexColor\",\n \"toOklchColor\",\n \"convertHexToRGB\",\n \"convertRgbToHex\",\n ],\n description:\n \"Pure OKLCH colour math — the exact lighten/darken/setL/rotateHue/complement/adjust (+ OKLCH and hex converters) refract synthesizes palette steps/variants with, so a value computed live in the consumer matches the emitted CSS variables.\",\n },\n];\n\n/** Look up a vendorable helper by id. */\nexport const findVendorHelper = (id: string): VendorHelperSource | undefined =>\n VENDOR_HELPERS.find(h => h.id === id);\n","/**\n * Build-layer path + transpile helpers (Node-only).\n *\n * Two jobs, both needed to materialize Option-A vendored helpers (§7 10a/10b): locate a\n * vendorable source's single origin (which lives in the package, NOT a second copy) and\n * type-strip it to a standalone ES module the consumer's build output can drop in.\n *\n * Packaging (resolved 2026-07-11): `VENDOR_HELPERS[].source` is package-root-relative. The\n * published package ships only `dist/`, so the vendorable sources are added to `package.json#files`\n * and this module resolves them against the discovered package root — working the SAME way in-repo\n * (root = repo root) and installed (root = the installed package dir).\n */\nimport { existsSync, readFileSync, rmSync, writeFileSync } from \"node:fs\";\nimport { basename, dirname, join, resolve } from \"node:path\";\nimport type ts from \"typescript\";\n\n/** Walk up from `startDir` to the first ancestor that contains a `package.json`. */\nexport const findPackageRoot = (startDir: string = __dirname): string => {\n let dir = startDir;\n for (;;) {\n if (existsSync(join(dir, \"package.json\"))) return dir;\n const parent = dirname(dir);\n if (parent === dir) {\n throw new Error(`No package.json found walking up from \"${startDir}\".`);\n }\n dir = parent;\n }\n};\n\n/** Read a package-root-relative vendorable source (must ship via `package.json#files`). */\nexport const readVendorSource = (source: string): string => {\n const path = join(findPackageRoot(), source);\n if (!existsSync(path)) {\n throw new Error(\n `Vendor helper source \"${source}\" not found at \"${path}\". ` +\n `Ensure it is listed in package.json \"files\" so it ships with the package.`,\n );\n }\n return readFileSync(path, \"utf8\");\n};\n\n/**\n * Lazily resolve the `typescript` peer (Step 10e). `typescript` is an OPTIONAL peer dependency — a\n * consumer who only uses the runtime (`createTheme` + adapters), `./dtcg`, or a `.mjs`/`.js` config\n * with the CSS `emit()` never needs it. It's pulled in ONLY on the two paths that actually transpile\n * TS: loading a `.ts` config and vendoring a shared helper module. If it's absent when one of those\n * runs, we throw a clear, actionable error instead of an opaque module-resolution failure.\n */\nasync function loadTypescript(): Promise<typeof ts> {\n try {\n const mod = (await import(\"typescript\")) as unknown as { default?: typeof ts } & typeof ts;\n return mod.default ?? mod;\n } catch {\n throw new Error(\n 'refract: the optional peer dependency \"typescript\" is required to transpile a `.ts` ' +\n \"theme.config or vendor a shared helper module, but it could not be resolved. Install it \" +\n \"(`npm i -D typescript`), or use a `.mjs`/`.js` config and avoid the `helpers` opt-in.\",\n );\n }\n}\n\n/**\n * Type-strip a self-contained TS module to standalone ESM — exactly what the 10a gate proves the\n * vendored artifact does. Reused for the `.ts` config loader (types stripped, `import`s preserved).\n *\n * Async because it lazy-loads the optional `typescript` peer (see {@link loadTypescript}); the\n * `.mjs`/`.js` config + CSS `emit()` paths never call it, so those work with `typescript` absent.\n */\nexport const transpileToEsm = async (sourceText: string): Promise<string> => {\n const tsc = await loadTypescript();\n return tsc.transpileModule(sourceText, {\n compilerOptions: { module: tsc.ModuleKind.ESNext, target: tsc.ScriptTarget.ES2020 },\n }).outputText;\n};\n\n/** The result of a graph compile: the emitted entry to import + a cleanup that unlinks every temp file. */\nexport interface CompiledTsGraph {\n /** Absolute path of the emitted config entry (an adjacent hidden `.mjs`) to dynamically import. */\n readonly entry: string;\n /** Remove every emitted temp file — call in a `finally` after importing `entry`. */\n readonly cleanup: () => void;\n}\n\n// Module-local counter keeps concurrent emit-file names unique without Date/Math.random.\nlet graphCounter = 0;\n\n/** Extension-stripped absolute key so a source `.ts` and its emitted `.js` name map to one entry. */\nconst graphKey = (p: string): string =>\n resolve(p).replace(/\\.(ts|tsx|mts|cts|js|jsx|mjs|cjs)$/, \"\");\n\n/**\n * Compile a `.ts` theme config **and its local relative `.ts` graph** to standalone ESM so a `.ts`\n * config can `import` a sibling `theme.raw.ts` (§8b — the 8a `RawTheme` payoff). Upgrades the old\n * single-file `transpileToEsm` path to a `ts.createProgram` compile: relative `.ts`/`.tsx`/`.mts`/\n * `.cts` imports are followed + compiled; **bare specifiers and relative `.mjs`/`.js`/`.json` stay\n * external** (untouched — resolved at their original location).\n *\n * **Adjacent-per-file emit** (settled 2026-07-11, supersedes the kickoff's temp-subdir): each compiled\n * source emits to a hidden unique `.<base>.<pid>-<n>.mjs` **next to its own source**. That's the one\n * layout where a mixed graph resolves — the emitted config sits in the original dir, so bare imports\n * resolve up to the project's `node_modules`, uncompiled relative siblings (`./adapter.mjs`,\n * `./tokens.json`) resolve adjacent, and compiled siblings resolve to their emitted `.mjs`. Parent-dir\n * imports (`../shared/theme.raw`) need no `rootDir`→`outDir` mapping — each file emits by its own source.\n *\n * A `before` transformer rewrites relative specifiers that resolve to a **compiled** source to its\n * emitted `.mjs` (so extensionless `./theme.raw` → `./.theme.raw.<pid>-<n>.mjs`); `.json` / `.mjs` /\n * `.js` / bare specifiers are left untouched (their `with { type: \"json\" }` attributes preserved).\n * No type-checking — diagnostics are ignored (`noEmitOnError: false`); this is a transpile, not a build.\n *\n * `paths`/tsconfig aliases are **NOT** resolved in v1 (a fixed `compilerOptions` set; the user's\n * tsconfig is ignored) — documented limitation.\n */\nexport const compileTsConfigGraph = async (configPath: string): Promise<CompiledTsGraph> => {\n const tsc = await loadTypescript();\n const options: ts.CompilerOptions = {\n module: tsc.ModuleKind.ESNext,\n target: tsc.ScriptTarget.ES2020,\n moduleResolution: tsc.ModuleResolutionKind.Bundler,\n resolveJsonModule: true,\n allowJs: false,\n noLib: true,\n skipLibCheck: true,\n noEmitOnError: false,\n declaration: false,\n sourceMap: false,\n types: [],\n };\n\n const host = tsc.createCompilerHost(options);\n const program = tsc.createProgram([configPath], options, host);\n\n // Map each compiled TS source (config + its relative `.ts` graph) → an adjacent hidden temp `.mjs`.\n const tempFor = new Map<string, string>();\n const isCompiledTs = (sf: ts.SourceFile): boolean =>\n !sf.isDeclarationFile &&\n !sf.fileName.includes(\"/node_modules/\") &&\n /\\.(ts|tsx|mts|cts)$/.test(sf.fileName);\n for (const sf of program.getSourceFiles()) {\n if (!isCompiledTs(sf)) continue;\n const abs = resolve(sf.fileName);\n const base = basename(abs).replace(/\\.(ts|tsx|mts|cts)$/, \"\");\n tempFor.set(graphKey(abs), join(dirname(abs), `.${base}.${process.pid}-${graphCounter++}.mjs`));\n }\n\n // Does this relative specifier resolve to one of the compiled sources? → its emitted `.mjs`, else undefined.\n const rewriteTarget = (spec: string, containingFile: string): string | undefined => {\n if (!spec.startsWith(\".\")) return undefined; // bare → external\n const resolved = tsc.resolveModuleName(spec, containingFile, options, host).resolvedModule\n ?.resolvedFileName;\n return resolved ? tempFor.get(graphKey(resolved)) : undefined;\n };\n\n // Rewrite relative import/export/dynamic-import specifiers that point at a compiled source.\n const rewrite: ts.TransformerFactory<ts.SourceFile> = context => sourceFile => {\n const containing = resolve(sourceFile.fileName);\n const factory = context.factory;\n const specFor = (text: string): ts.StringLiteral | undefined => {\n const temp = rewriteTarget(text, containing);\n return temp ? factory.createStringLiteral(`./${basename(temp)}`) : undefined;\n };\n const visit = (node: ts.Node): ts.Node => {\n if (tsc.isImportDeclaration(node) && tsc.isStringLiteral(node.moduleSpecifier)) {\n const next = specFor(node.moduleSpecifier.text);\n if (next) {\n return factory.updateImportDeclaration(\n node,\n node.modifiers,\n node.importClause,\n next,\n node.attributes,\n );\n }\n } else if (\n tsc.isExportDeclaration(node) &&\n node.moduleSpecifier &&\n tsc.isStringLiteral(node.moduleSpecifier)\n ) {\n const next = specFor(node.moduleSpecifier.text);\n if (next) {\n return factory.updateExportDeclaration(\n node,\n node.modifiers,\n node.isTypeOnly,\n node.exportClause,\n next,\n node.attributes,\n );\n }\n } else if (\n tsc.isCallExpression(node) &&\n node.expression.kind === tsc.SyntaxKind.ImportKeyword &&\n node.arguments.length &&\n tsc.isStringLiteral(node.arguments[0])\n ) {\n const next = specFor(node.arguments[0].text);\n if (next) {\n return factory.updateCallExpression(node, node.expression, node.typeArguments, [\n next,\n ...node.arguments.slice(1),\n ]);\n }\n }\n return tsc.visitEachChild(node, visit, context);\n };\n return tsc.visitNode(sourceFile, visit) as ts.SourceFile;\n };\n\n // Redirect TS's computed `<source>.js` emit to the adjacent hidden `.mjs` (forces ESM regardless of\n // the project's `package.json#type`); ignore anything unexpected.\n const written: string[] = [];\n const writeFile: ts.WriteFileCallback = (fileName, text) => {\n const target = tempFor.get(graphKey(fileName));\n if (!target) return;\n writeFileSync(target, text, \"utf8\");\n written.push(target);\n };\n\n const cleanup = (): void => {\n for (const file of written) rmSync(file, { force: true });\n };\n\n try {\n program.emit(undefined, writeFile, undefined, false, { before: [rewrite] });\n } catch (err) {\n cleanup();\n throw err;\n }\n\n const entry = tempFor.get(graphKey(configPath));\n if (!entry || !existsSync(entry)) {\n cleanup();\n throw new Error(`refract: failed to compile the \\`.ts\\` config graph for \"${configPath}\".`);\n }\n return { entry, cleanup };\n};\n","/**\n * Self-documenting theme output (Node-only) — render an `llms.txt` consumption guide + a\n * `manifest.json` index from an adapter's {@link UsageDescriptor} and a DTCG token export.\n *\n * The point: a theme built by refract is often shipped onward as a published package, a zip / CI\n * artifact, or a vendored folder to developers who have **neither refract nor its skills** (and may\n * not know refract exists). These two files travel *inside* `outDir`, so they accompany any\n * distribution form, and they name the theme's REAL class names / export ids / token paths — a\n * downstream agent consumes the theme from the folder alone, never guessing an identifier.\n *\n * Distribution-agnostic by construction: references are **relative** by default (`./theme.css`); the\n * `@scope/name` import form is added only as an overlay when a package name is configured (a zip has\n * no package specifier, so it must not be assumed).\n */\nimport type { UsageDescriptor } from \"../core/ThemeAdapter\";\n\n/** How many recipe rows to inline into `llms.txt` before deferring the rest to `manifest.json`. */\nconst LLMS_RECIPE_CAP = 60;\n\nexport interface GuideOptions {\n /** The static file names emitted for this target (relative), so the guide points at real artifacts. */\n readonly files: readonly string[];\n /** The published package specifier, if any — adds an import-by-specifier overlay to the prose. */\n readonly packageName?: string;\n /** Output name for the narrative guide (default `\"llms.txt\"`). */\n readonly llmsFile?: string;\n /** Output name for the machine index (default `\"manifest.json\"`); `false` suppresses it. */\n readonly manifestFile?: string | false;\n}\n\nexport interface GuideOutput {\n /** filename → contents, ready for the build layer to write into `outDir`. */\n readonly files: Record<string, string>;\n}\n\nconst escapeCell = (s: string): string => s.replace(/\\|/g, \"\\\\|\");\n\n/** Render the `llms.txt` narrative. */\nfunction renderLlms(descriptor: UsageDescriptor, options: GuideOptions, manifestName: string | false): string {\n const lines: string[] = [];\n lines.push(`# Theme consumption guide (${descriptor.format})`);\n lines.push(\"\");\n lines.push(\n \"This folder is a self-contained theme built with refract. You do NOT need refract to use it —\",\n \"everything below refers to files in THIS folder (relative paths), so it works whether the theme\",\n \"was installed as a package, unzipped from an artifact, or vendored into a repo.\",\n );\n lines.push(\"\");\n\n if (options.files.length > 0) {\n lines.push(\"## Files\");\n lines.push(\"\");\n for (const f of options.files) lines.push(`- \\`./${f}\\``);\n lines.push(\"\");\n }\n\n lines.push(\"## How to use\");\n lines.push(\"\");\n for (const s of descriptor.summary) lines.push(s);\n if (options.packageName) {\n lines.push(\"\");\n lines.push(\n `If this theme is installed as the \\`${options.packageName}\\` package, you may import the same`,\n `files by specifier (e.g. \\`${options.packageName}/${options.files[0] ?? \"theme.css\"}\\`) instead of by relative path.`,\n );\n }\n lines.push(\"\");\n\n const { recipes } = descriptor;\n if (recipes.length > 0) {\n lines.push(\"## Recipes — real names\");\n lines.push(\"\");\n lines.push(\"Use these exact identities; do not invent names.\");\n lines.push(\"\");\n lines.push(\"| Recipe | Identity |\");\n lines.push(\"| --- | --- |\");\n const shown = recipes.slice(0, LLMS_RECIPE_CAP);\n for (const r of shown) {\n lines.push(`| \\`${escapeCell(`${r.subsystem}.${r.group}.${r.variant}`)}\\` | \\`${escapeCell(r.name)}\\` |`);\n }\n if (recipes.length > shown.length) {\n const rest = recipes.length - shown.length;\n lines.push(\"\");\n lines.push(\n `_(+${rest} more recipe(s) — the complete list is in ${manifestName ? `\\`./${manifestName}\\`` : \"the manifest\"}.)_`,\n );\n }\n lines.push(\"\");\n }\n\n if (manifestName) {\n lines.push(\"## Machine-readable index\");\n lines.push(\"\");\n lines.push(`See \\`./${manifestName}\\` for the full recipe index and the theme's tokens (DTCG format).`);\n lines.push(\"\");\n }\n\n return lines.join(\"\\n\");\n}\n\n/**\n * Build the guide artifacts. `tokens` is a DTCG document (from `toDTCG`) embedded verbatim into the\n * manifest so the machine index carries every token path + value beside the recipe identities.\n */\nexport function buildGuide(\n descriptor: UsageDescriptor,\n tokens: unknown,\n options: GuideOptions,\n): GuideOutput {\n const llmsName = options.llmsFile ?? \"llms.txt\";\n const manifestName = options.manifestFile === undefined ? \"manifest.json\" : options.manifestFile;\n\n const files: Record<string, string> = {\n [llmsName]: renderLlms(descriptor, options, manifestName),\n };\n\n if (manifestName) {\n const manifest = {\n schema: 1,\n format: descriptor.format,\n files: options.files,\n packageName: options.packageName,\n recipes: descriptor.recipes,\n tokens,\n };\n files[manifestName] = `${JSON.stringify(manifest, null, 2)}\\n`;\n }\n\n return { files };\n}\n","/**\n * Stable, machine-readable error codes (§P2-3). Every error refract throws for a theme authoring /\n * build problem — everything reachable from {@link createTheme} (subsystem normalization, token\n * derivation, DTCG parsing) — is a {@link RefractError} carrying a `code` from {@link RefractErrorCode}:\n * a stable identifier an agent (or a catch block) can branch on without string-matching the human\n * message. The message text stays human-first and unchanged; the code is additive.\n *\n * Scope: authoring/build errors. Pure CLI-tooling failures in `src/build/*` (bad arguments, a missing\n * file, an unknown command) stay plain `Error`s — they're usage errors from `refract <cmd>`, not a\n * problem with the theme an agent is editing. The one build-layer exception is `REFRACT_E_RAW_SHAPE`:\n * a value handed to `diff` / `validate` (or the MCP server) where a `RawTheme` is required but the\n * value isn't theme-shaped — that IS a theme problem, and a governance tool must fail loud + coded on\n * it (see {@link assertRawTheme}) rather than emit a nonsense \"everything removed\" diff at exit 0.\n *\n * Dependency-free leaf on purpose, so any module (including the standalone `adapter-kit`) can throw one\n * without pulling in the core graph.\n */\nexport type RefractErrorCode =\n | \"REFRACT_E_COLOR_INPUT\" // a colour value wasn't a derivable colour\n | \"REFRACT_E_COLOR_TUPLE\" // an [r,g,b] tuple was malformed\n | \"REFRACT_E_STEPS\" // colors.<name>.steps out of range / non-numeric\n | \"REFRACT_E_VARIANT\" // a derivation-spec variant / modifier chain was malformed\n | \"REFRACT_E_VARIANT_REF\" // a variant referenced an unknown source\n | \"REFRACT_E_CYCLE\" // a cyclic reference (colour variant, token, recipe, DTCG alias)\n | \"REFRACT_E_ADJUST\" // an adjust dial was out of range\n | \"REFRACT_E_HARMONY\" // an invalid harmony scheme\n | \"REFRACT_E_VALIDATION\" // aggregate: one or more post-build ref-validation failures (see `failures`)\n | \"REFRACT_E_RECIPE_PROPERTY\" // a recipe declaration key is neither a known CSS property nor a reserved key\n | \"REFRACT_E_TOKEN_PATH\" // a token path is unknown / malformed / uses an unknown derivation fn\n | \"REFRACT_E_BREAKPOINT\" // a responsive entry omitted or named an unknown breakpoint\n | \"REFRACT_E_STATE\" // a recipe state entry named a state the adapter doesn't know\n | \"REFRACT_E_CONTAINER\" // a container-query entry named an unknown container / size / unsupported axis\n | \"REFRACT_E_RESPONSIVE\" // a responsive/mode override was malformed (variant+target conflict, unknown ref)\n | \"REFRACT_E_MEDIA\" // an invalid media / container query range (min > max)\n | \"REFRACT_E_MODE\" // an appearance-mode override with no base to override\n | \"REFRACT_E_PRESET\" // an unknown globals preset name\n | \"REFRACT_E_EFFECTS\" // a malformed effects value (shadow / transition layer)\n | \"REFRACT_E_LAYOUT\" // a malformed layout scale (ratio+step, bad rung)\n | \"REFRACT_E_UNITS\" // a malformed units config\n | \"REFRACT_E_PROPERTY\" // a property couldn't be normalized (no resolvable base value)\n | \"REFRACT_E_REFERENCE\" // a composition / rule-set reference didn't resolve\n | \"REFRACT_E_NAMING\" // a naming override / default path produced a collision\n | \"REFRACT_E_DTCG_VERSION\" // an unreadable DTCG refract-extension version\n | \"REFRACT_E_AUDIT\" // a strict contrast audit failed\n | \"REFRACT_E_RAW_SHAPE\"; // a value passed where a RawTheme is required isn't theme-shaped (e.g. a defineConfig, an array, null)\n\n/**\n * An authoring / build error with a stable {@link RefractErrorCode}. For an aggregate (collect-all)\n * error, `failures` lists each individual message so a caller can report them all at once.\n */\nexport class RefractError extends Error {\n readonly code: RefractErrorCode;\n readonly failures?: readonly string[];\n\n constructor(code: RefractErrorCode, message: string, failures?: readonly string[]) {\n super(message);\n this.name = \"RefractError\";\n this.code = code;\n if (failures) this.failures = failures;\n // Keep `instanceof RefractError` working after transpilation to ES5-ish targets.\n Object.setPrototypeOf(this, RefractError.prototype);\n }\n}\n","/**\n * Model builder (clean-room port of `core/common/buildModel.ts`).\n *\n * Pure functions that assemble the format-neutral {@link ThemeModel} from data the\n * pipeline computes — the normalized property collections and the interpreted recipe\n * groups. `buildThemeModel` consumes each subsystem's already-interpreted rule-set\n * groups (see `buildRuleSetGroupFromInterpreted`), whose declarations already carry\n * format-neutral {@link Ref}s (`{ ref: \"colors.primary\" }` for a token-path reference,\n * `{ value }` for a literal). The builder is a structural copy — it never string-parses\n * `var(--…)`; the interpreter emits canonical token paths directly.\n *\n * `pathify*` rewrites refs via a supplied map (used by later subsystems that still emit\n * var-name refs); `buildTokenMap` flattens the property tokens into a `path -> Ref` map.\n */\nimport type { NormalizedPropertyValue } from \"../normalize\";\nimport type { InterpretedRecipeGroup, InterpretedRecipeVariant } from \"./interpreted\";\nimport type {\n ContainerModel,\n Keyframe,\n Literal,\n PropertyModel,\n PropertyOverride,\n Ref,\n RuleSet,\n RuleSetGroup,\n RuleSetOverride,\n StructuredValue,\n SubsystemModel,\n ThemeModel,\n VariantModel,\n} from \"./model\";\nimport { RefractError } from \"../errors\";\n\nconst isLiteral = (value: unknown): value is Literal =>\n typeof value === \"string\" || typeof value === \"number\";\n\n/**\n * A structured compound value (§15) reaches the Model as an **array** of layers/parts (the owning\n * subsystem canonicalizes it in `coerceValue`). Colors serialize to a string before the Model, so\n * an array base here is unambiguously a §15 effects value → carried on `Ref.struct`.\n */\nconst isStructuredValue = (value: unknown): value is StructuredValue => Array.isArray(value);\n\nconst toRef = (value: Literal): Ref => ({ value });\n\n/**\n * A base/variant value → its `Ref`: a `Literal` becomes the `value` cache; a structured compound\n * value (§15 shadow/transition) is carried on `struct` (no single literal to cache). Used wherever\n * a value may now be structured rather than scalar.\n */\nconst valueToRef = (value: unknown): Ref =>\n isStructuredValue(value) ? { struct: value } : toRef(value as Literal);\n\n/** Build a variant `Ref`: a derived `{ ref, fn?, arg?, value }` when the normalized variant carries\n * a `derive`, else a plain literal. `value` is kept as the cached resolution (the lowering reads it). */\nconst variantToRef = (\n value: Literal | undefined,\n derive?: { ref: string; fn?: string; arg?: unknown; modifiers?: Array<{ fn: string; arg?: unknown }> },\n): Ref => {\n if (!derive) return toRef(value as Literal);\n const ref: Ref = { ref: derive.ref };\n if (derive.fn !== undefined) ref.fn = derive.fn;\n if (derive.arg !== undefined) ref.arg = derive.arg;\n if (derive.modifiers !== undefined) ref.modifiers = derive.modifiers; // dec.2 — carry the chain\n // dec.4 — a cross-property derivation arrives UNBAKED (`value` undefined); the post-build\n // `bakeCrossPropertyDerivations` pass fills it. Omit the key rather than set `value: undefined`.\n if (value !== undefined) ref.value = value;\n return ref;\n};\n\n/** Structural keys of a normalized appearance-mode override entry (`{ mode, target, base, derive,\n * …literalExtras }`) — the condition/target keys + base/derive are NOT extras. */\nconst MODE_STRUCTURAL_KEYS: ReadonlySet<string> = new Set([\"mode\", \"target\", \"base\", \"derive\"]);\n\n/**\n * One normalized appearance mode (`{ base?, derive?, …literalExtras }`) → its `field → Ref` map\n * (§10.3). `base` becomes a literal or derived `Ref` (a derived base must have been baked by the\n * owning subsystem hook — colors — so `base` and `derive.ref` are present); literal extras (e.g.\n * colors' `text`) each become a literal `Ref`. Field-keyed, mirroring a responsive override.\n */\nconst buildModeFields = (\n mode: Record<string, unknown>,\n propertyName: string,\n modeName: string,\n): Record<string, Ref> => {\n const fields: Record<string, Ref> = {};\n const derive = mode.derive as\n | { ref?: string; fn?: string; arg?: unknown; modifiers?: Array<{ fn: string; arg?: unknown }> }\n | undefined;\n const base = mode.base;\n\n if (derive) {\n // A derived mode must name a source (`derive.ref`) so it can be baked — by the owning subsystem\n // (colors) for a same-property source, or by the post-build cross-property pass for a dotted one.\n // A derive WITHOUT a ref never got a baker (e.g. a non-colors subsystem) → fail loud.\n if (derive.ref === undefined) {\n throw new RefractError(\n \"REFRACT_E_REFERENCE\",\n `Derived appearance mode \"${propertyName}.modes.${modeName}\" was not baked — derived ` +\n `modes require a subsystem that resolves them (colors). Use a literal value instead.`,\n );\n }\n // `base` is the cached resolution for a same-property source; ABSENT for a dec.4 cross-property\n // source (filled post-build by `bakeCrossPropertyDerivations`). `variantToRef` omits the value key.\n fields.base = variantToRef(\n isLiteral(base) ? base : undefined,\n derive as { ref: string; fn?: string; arg?: unknown; modifiers?: Array<{ fn: string; arg?: unknown }> },\n );\n } else if (isLiteral(base)) {\n fields.base = toRef(base);\n } else if (isStructuredValue(base)) {\n fields.base = { struct: base };\n }\n\n for (const [key, value] of Object.entries(mode)) {\n if (MODE_STRUCTURAL_KEYS.has(key)) continue;\n if (isLiteral(value)) fields[key] = toRef(value);\n }\n return fields;\n};\n\n/** Own scalar (string/number) properties of `obj`, minus `exclude`, each wrapped as a `Ref`. */\nconst collectScalarRefs = (\n obj: Record<string, unknown>,\n exclude: ReadonlySet<string>,\n): Record<string, Ref> => {\n const out: Record<string, Ref> = {};\n for (const [key, value] of Object.entries(obj)) {\n if (exclude.has(key)) continue;\n if (isLiteral(value)) out[key] = toRef(value);\n }\n return out;\n};\n\n/**\n * Like {@link collectScalarRefs} but also carries a structured field value (§15) onto `Ref.struct`.\n * Used for responsive override fields, where a `base` may now be a structured shadow/transition value\n * (whole-value replacement) rather than a scalar.\n */\nconst collectFieldRefs = (\n obj: Record<string, unknown>,\n exclude: ReadonlySet<string>,\n): Record<string, Ref> => {\n const out: Record<string, Ref> = {};\n for (const [key, value] of Object.entries(obj)) {\n if (exclude.has(key)) continue;\n if (isLiteral(value)) out[key] = toRef(value);\n else if (isStructuredValue(value)) out[key] = { struct: value };\n }\n return out;\n};\n\n// ---------------------------------------------------------------------------\n// Properties → PropertyModel\n// ---------------------------------------------------------------------------\n\n/** dec.3 — keys of a normalized variant that are NOT extras (the base value + its derivation meta). */\nconst VARIANT_STRUCTURAL_KEYS: ReadonlySet<string> = new Set([\"base\", \"derive\"]);\n\nconst PROPERTY_STRUCTURAL_KEYS: ReadonlySet<string> = new Set([\n \"base\",\n \"responsive\",\n \"variants\",\n \"modes\",\n // §W6b — an external property's `external` (the parent var name) rides on the base Ref, not as a\n // token extra; excluding it here prevents a spurious `<prop>.external` token leaking into the map.\n \"external\",\n]);\n\nconst RESPONSIVE_CONDITION_KEYS: ReadonlySet<string> = new Set([\n \"breakpoint\",\n \"query\",\n \"state\",\n \"orientation\",\n \"ref\", // dec.5 — property-responsive swap source\n \"modifiers\", // dec.5 — derivation chain on `ref` (subsystem-baked; never a field)\n \"mode\", // dec.9 — property-responsive appearance-mode condition\n \"variant\", // recipe-responsive scope (recipe path still uses `variant`)\n \"target\",\n // §10.6 D6: a synthesized responsive ramp step carries derivation metadata (`derive`) alongside its\n // baked `base` value — excluded from plain field collection; the `base` override is rebuilt as a\n // derived Ref below. Ramp-config keys (`ratio`/`step`/`steps`) never reach here — the layout hook\n // expands a ramp entry into per-step `target` overrides during normalize.\n \"derive\",\n \"ratio\",\n \"step\",\n \"steps\",\n]);\n\n/**\n * One normalized property (`{ base, responsive, variants?, ...extras }`) → a\n * {@link PropertyModel}. `base` and each variant become value refs; scalar sibling\n * extras (e.g. colors' `text`) go in `extras`; the responsive list maps entry-for-entry.\n */\nexport const buildPropertyModel = (\n normalized: NormalizedPropertyValue<unknown, Record<string, unknown>>,\n propertyName = \"property\",\n): PropertyModel => {\n const model: PropertyModel = {\n // §W6b — an external property carries the literal parent var name on its base Ref; the `value`\n // is the resolved `var(…)` string so raw `.value` readers (JSON, SC) stay happy.\n base:\n normalized.external !== undefined\n ? { value: `var(${normalized.external})`, external: normalized.external }\n : valueToRef(normalized.base),\n };\n\n const extras = collectScalarRefs(\n normalized as Record<string, unknown>,\n PROPERTY_STRUCTURAL_KEYS,\n );\n if (Object.keys(extras).length) model.extras = extras;\n\n if (normalized.variants && Object.keys(normalized.variants).length) {\n const variants: Record<string, VariantModel> = {};\n for (const [name, variant] of Object.entries(normalized.variants)) {\n let base: Ref | undefined;\n const variantDerive = (variant as {\n derive?: { ref: string; fn?: string; arg?: unknown; modifiers?: Array<{ fn: string; arg?: unknown }> };\n }).derive;\n if (isLiteral(variant.base)) {\n base = variantToRef(variant.base, variantDerive);\n } else if (isStructuredValue(variant.base)) {\n // §15: a structured shadow/transition variant (no derivation — those are colors-only).\n base = { struct: variant.base };\n } else if (variantDerive?.ref !== undefined) {\n // dec.4 — an UNBAKED cross-property derivation (base absent): carry the derived Ref with no\n // cached value; `bakeCrossPropertyDerivations` fills `.value` against the full token map.\n base = variantToRef(undefined, variantDerive);\n }\n if (!base) continue;\n // dec.3 — collect the variant's OWN extras (any non-structural leaf, e.g. colours' `text`) →\n // `--<prop>-<variant>-<extra>`, exactly like the property-level extras above.\n const variantExtras = collectScalarRefs(variant as Record<string, unknown>, VARIANT_STRUCTURAL_KEYS);\n variants[name] = Object.keys(variantExtras).length ? { base, extras: variantExtras } : { base };\n }\n if (Object.keys(variants).length) model.variants = variants;\n }\n\n // Appearance modes — a LIST of `PropertyOverride`s (each `{ mode, target?, overrides }`), so one\n // mode can carry several targeted entries. `buildModeFields` builds the field-map; `mode`/`target`\n // are structural (excluded from the extras it collects).\n const normalizedModes = (normalized as { modes?: Array<Record<string, unknown>> }).modes;\n if (normalizedModes && normalizedModes.length) {\n const modes: PropertyOverride[] = [];\n for (const entry of normalizedModes) {\n const modeName = entry.mode as string;\n const fields = buildModeFields(entry, propertyName, modeName);\n if (!Object.keys(fields).length) continue;\n const override: PropertyOverride = { mode: modeName, overrides: fields };\n if (typeof entry.target === \"string\") override.target = entry.target;\n modes.push(override);\n }\n if (modes.length) model.modes = modes;\n }\n\n if (normalized.responsive?.length) {\n const responsive: PropertyOverride[] = normalized.responsive.map(entry => {\n const e = entry as Record<string, unknown>;\n const override: PropertyOverride = { breakpoint: e.breakpoint as string };\n if (typeof e.query === \"string\") override.query = e.query as PropertyOverride[\"query\"];\n if (typeof e.orientation === \"string\") override.orientation = e.orientation as PropertyOverride[\"orientation\"];\n if (typeof e.ref === \"string\") override.ref = e.ref; // dec.5 — swap source (was `variant`)\n if (typeof e.mode === \"string\") override.mode = e.mode; // dec.9 — appearance-mode condition\n if (typeof e.target === \"string\") override.target = e.target;\n const overrides = collectFieldRefs(e, RESPONSIVE_CONDITION_KEYS);\n // §10.6 D6: a synthesized ramp step's `base` is a derived Ref (`{ ref, fn:\"scaleStep\", arg }`),\n // so `theme.tokens` / adapters carry the recipe just like a variant step. `value` stays the\n // cached resolution the lowering reads.\n const derive = e.derive as\n | { ref: string; fn?: string; arg?: unknown; modifiers?: Array<{ fn: string; arg?: unknown }> }\n | undefined;\n if (derive && overrides.base && overrides.base.value !== undefined) {\n overrides.base = variantToRef(overrides.base.value as Literal, derive);\n }\n if (Object.keys(overrides).length) override.overrides = overrides;\n return override;\n });\n model.responsive = responsive;\n }\n\n return model;\n};\n\n/** A whole normalized collection (`name → normalized property`) → `name → PropertyModel`. */\nexport const buildPropertiesModel = (\n collection: Record<string, NormalizedPropertyValue<unknown, Record<string, unknown>>>,\n): Record<string, PropertyModel> => {\n const out: Record<string, PropertyModel> = {};\n for (const [name, normalized] of Object.entries(collection)) {\n out[name] = buildPropertyModel(normalized, name);\n }\n return out;\n};\n\n// ---------------------------------------------------------------------------\n// Interpreted recipes → RuleSet (declarations carry refs)\n// ---------------------------------------------------------------------------\n\n/**\n * One *interpreted* recipe variant → a {@link RuleSet}. The interpreter has already\n * resolved every declaration to a {@link Ref} (`{ ref }` for token references, `{ value }`\n * for literals) and separated the condition axes from the declarations, so this is a\n * structural copy — **no string-parsing of `var(…)`**. Format-neutral by construction:\n * refs are token paths, not var names.\n */\nexport const buildRuleSetFromInterpreted = (\n variant: InterpretedRecipeVariant<string>,\n): RuleSet => {\n const declarations = { ...variant.base };\n\n const overrides: RuleSetOverride[] = variant.responsive.map(entry => {\n const override: RuleSetOverride = {};\n if (entry.state !== undefined) override.state = entry.state;\n if (entry.breakpoint !== undefined) override.breakpoint = entry.breakpoint;\n if (entry.query !== undefined) override.query = entry.query;\n if (entry.orientation !== undefined) override.orientation = entry.orientation;\n if (entry.container !== undefined) override.container = entry.container;\n if (entry.size !== undefined) override.size = entry.size;\n if (entry.variant !== undefined) override.variant = entry.variant;\n if (entry.target !== undefined) override.target = entry.target;\n if (Object.keys(entry.declarations).length) override.declarations = { ...entry.declarations };\n return override;\n });\n\n return { kind: \"recipe\", declarations, overrides };\n};\n\n/** An interpreted recipe group (`variant → interpreted`) → a {@link RuleSetGroup} with refs. */\nexport const buildRuleSetGroupFromInterpreted = (\n group: InterpretedRecipeGroup<string>,\n): RuleSetGroup => {\n const out: RuleSetGroup = {};\n for (const [name, variant] of Object.entries(group)) {\n out[name] = buildRuleSetFromInterpreted(variant);\n }\n return out;\n};\n\n/**\n * Rewrite a rule-set group's declaration refs from CSS var names to canonical **token paths**\n * (e.g. `--dt-color--primary` → `colors.primary`) using `varToPath`. Refs already absent from the\n * map are left untouched (var name preserved). Pure — returns a new group. Applied to the Model\n * copy so `theme.model` is format-neutral; the CSS adapter's own lowering is unaffected.\n */\nexport const pathifyRuleSetGroup = (\n group: RuleSetGroup,\n varToPath: Record<string, string>,\n): RuleSetGroup => {\n const mapRef = (ref: Ref): Ref =>\n ref.ref !== undefined && varToPath[ref.ref] !== undefined\n ? { ...ref, ref: varToPath[ref.ref] }\n : ref;\n const mapDecls = (decls: Record<string, Ref>): Record<string, Ref> => {\n const out: Record<string, Ref> = {};\n for (const [prop, ref] of Object.entries(decls)) out[prop] = mapRef(ref);\n return out;\n };\n const out: RuleSetGroup = {};\n for (const [name, ruleSet] of Object.entries(group)) {\n out[name] = {\n ...ruleSet,\n declarations: mapDecls(ruleSet.declarations),\n overrides: ruleSet.overrides.map(override =>\n override.declarations\n ? { ...override, declarations: mapDecls(override.declarations) }\n : override,\n ),\n };\n }\n return out;\n};\n\n/**\n * Rewrite property tokens' refs from CSS var names to canonical token paths using `varToPath`\n * (base / variants / extras). Refs absent from the map are left untouched. Pure — returns a new\n * map. Used to pathify layout's structural-config `extraProperties` in the Model.\n */\nexport const pathifyProperties = (\n properties: Record<string, PropertyModel>,\n varToPath: Record<string, string>,\n): Record<string, PropertyModel> => {\n const mapRef = (ref: Ref): Ref =>\n ref.ref !== undefined && varToPath[ref.ref] !== undefined\n ? { ...ref, ref: varToPath[ref.ref] }\n : ref;\n const mapRecord = (rec: Record<string, Ref>): Record<string, Ref> => {\n const out: Record<string, Ref> = {};\n for (const [key, ref] of Object.entries(rec)) out[key] = mapRef(ref);\n return out;\n };\n // dec.3 — a variant carries a base Ref + its own extras; map each.\n const mapVariants = (rec: Record<string, VariantModel>): Record<string, VariantModel> => {\n const out: Record<string, VariantModel> = {};\n for (const [key, v] of Object.entries(rec)) {\n out[key] = v.extras ? { base: mapRef(v.base), extras: mapRecord(v.extras) } : { base: mapRef(v.base) };\n }\n return out;\n };\n const out: Record<string, PropertyModel> = {};\n for (const [name, model] of Object.entries(properties)) {\n out[name] = {\n ...model,\n base: mapRef(model.base),\n ...(model.variants ? { variants: mapVariants(model.variants) } : {}),\n ...(model.extras ? { extras: mapRecord(model.extras) } : {}),\n };\n }\n return out;\n};\n\n/**\n * Extract `\"subsystem:group.variant\"` references from a component variant's normalized base, in\n * **authored order** — the order the composition references were written (`{ effects, layout }` →\n * `[\"effects:…\", \"layout:…\"]`). The CSS adapter renders this ordered list into the className, so the\n * Model `references` array IS the canonical composition order (the referenced recipe classes precede\n * the component's own delta class). Only the cross-subsystem keys are recognised; other base keys\n * (`css`, literals) are skipped.\n */\nexport const extractComponentReferences = (\n rawVariantBase: Record<string, unknown>,\n): string[] => {\n const references: string[] = [];\n for (const [key, value] of Object.entries(rawVariantBase)) {\n if (!COMPONENT_SUBSYSTEM_KEYS.has(key)) continue;\n if (typeof value === \"string\" && value.includes(\".\")) references.push(`${key}:${value}`);\n }\n return references;\n};\n\n/**\n * An interpreted component variant (its `css` delta) + its cross-subsystem `references`\n * → a component {@link RuleSet} (`kind: \"recipe\"`, own delta declarations carry refs,\n * cross-subsystem pointers kept as `references`).\n */\nexport const buildComponentRuleSetFromInterpreted = (\n variant: InterpretedRecipeVariant<string>,\n references: string[],\n): RuleSet => {\n const ruleSet = buildRuleSetFromInterpreted(variant);\n ruleSet.kind = \"recipe\";\n if (references.length) ruleSet.references = references;\n return ruleSet;\n};\n\n// ---------------------------------------------------------------------------\n// Components → RuleSet (cross-subsystem references + css delta)\n// ---------------------------------------------------------------------------\n\nconst COMPONENT_SUBSYSTEM_KEYS: ReadonlySet<string> = new Set([\n \"colors\",\n \"typography\",\n \"layout\",\n \"effects\",\n \"borders\",\n]);\n\n// ---------------------------------------------------------------------------\n// Assembly\n// ---------------------------------------------------------------------------\n\n/**\n * One subsystem's Model input. `ruleSetGroups` carries the already-interpreted rule-sets\n * (declarations with refs) that `createTheme` produces.\n */\nexport type SubsystemModelInput = {\n properties?: Record<string, NormalizedPropertyValue<unknown, Record<string, unknown>>>;\n ruleSetGroups?: Record<string, RuleSetGroup>;\n /**\n * Already-built {@link PropertyModel}s to merge into `properties` (after the normalized ones).\n * Layout uses this to carry its structural config knobs (columns/container size, gutter, inset)\n * as tokens — the subsystem's `buildStructural` hook emits them (see `subsystems/layout/structural.ts`).\n */\n extraProperties?: Record<string, PropertyModel>;\n /**\n * Named keyframe definitions (§10.2) — the animation subsystem's `buildStructural` output. Neither\n * property nor rule-set; attached to {@link SubsystemModel.keyframes} verbatim.\n */\n keyframes?: Record<string, Keyframe>;\n};\n\n/** Everything `buildThemeModel` needs — read from `createTheme`'s live caches/sources. */\nexport type BuildThemeModelInput = {\n breakpoints: Record<string, number>;\n /** Named query containers (§10.5) — carried onto the Model verbatim. Additive (absent → no field). */\n containers?: Record<string, ContainerModel>;\n colors?: SubsystemModelInput;\n typography?: SubsystemModelInput;\n layout?: SubsystemModelInput;\n effects?: SubsystemModelInput;\n /** Borders (§14): stroke geometry (width/style/offset/radius) + border/outline recipes. */\n borders?: SubsystemModelInput;\n animation?: SubsystemModelInput;\n components?: {\n ruleSetGroups?: Record<string, RuleSetGroup>;\n };\n globals?: SubsystemModelInput;\n};\n\nconst hasEntries = (obj: Record<string, unknown> | undefined): boolean =>\n !!obj && Object.keys(obj).length > 0;\n\n/**\n * One subsystem's Model input → a {@link SubsystemModel} (normalized properties built into\n * {@link PropertyModel}s, `extraProperties` merged in, rule-set groups attached). Returns\n * `undefined` when the slice contributes nothing. Exported so `override` can turn a *partial*\n * subsystem input into a Model fragment with the exact same shape the initial build produces.\n */\nexport const buildSubsystemModel = (\n slice: SubsystemModelInput | undefined,\n): SubsystemModel | undefined => {\n if (!slice) return undefined;\n const model: SubsystemModel = {};\n if (slice.properties && Object.keys(slice.properties).length) {\n model.properties = buildPropertiesModel(slice.properties);\n }\n if (slice.extraProperties && Object.keys(slice.extraProperties).length) {\n model.properties = { ...(model.properties ?? {}), ...slice.extraProperties };\n }\n if (hasEntries(slice.ruleSetGroups)) model.ruleSets = slice.ruleSetGroups;\n if (hasEntries(slice.keyframes)) model.keyframes = slice.keyframes;\n return Object.keys(model).length ? model : undefined;\n};\n\n/** Assemble the whole {@link ThemeModel} from the pipeline's normalized data + rule-set groups. */\nexport const buildThemeModel = (input: BuildThemeModelInput): ThemeModel => {\n const subsystems: Record<string, SubsystemModel> = {};\n\n const colors = buildSubsystemModel(input.colors);\n if (colors) subsystems.colors = colors;\n\n const typography = buildSubsystemModel(input.typography);\n if (typography) subsystems.typography = typography;\n\n const layout = buildSubsystemModel(input.layout);\n if (layout) subsystems.layout = layout;\n\n const effects = buildSubsystemModel(input.effects);\n if (effects) subsystems.effects = effects;\n\n // Borders (§14): stroke geometry + border/outline recipes. Positioned after effects (matching the\n // SUBSYSTEMS order); a theme with no `borders` slice yields none → byte-identical for such themes.\n const borders = buildSubsystemModel(input.borders);\n if (borders) subsystems.borders = borders;\n\n // Animation (§10.2): motion tokens (duration/easing/delay) + keyframes + animation-shorthand\n // recipes. Positioned after effects; a theme with no `animation` slice yields none → byte-identical.\n const animation = buildSubsystemModel(input.animation);\n if (animation) subsystems.animation = animation;\n\n if (hasEntries(input.components?.ruleSetGroups)) {\n subsystems.components = { ruleSets: input.components!.ruleSetGroups };\n }\n\n // Globals is last (§9): a selector-targeting rule-set subsystem (no properties) — the `kind:\"reset\"`\n // preset layers + `kind:\"globals\"` themed elements. Its refs resolve late in the adapter, so its\n // Model position is immaterial — the adapter hoists the preset layer ahead.\n const globals = buildSubsystemModel(input.globals);\n if (globals) subsystems.globals = globals;\n\n const model: ThemeModel = { breakpoints: input.breakpoints, subsystems };\n if (input.containers && Object.keys(input.containers).length) model.containers = input.containers;\n return model;\n};\n\n// ---------------------------------------------------------------------------\n// Token map (flat `path -> Ref` view of the Model's property tokens)\n// ---------------------------------------------------------------------------\n\n/**\n * Flatten a {@link ThemeModel} into one `path -> Ref` map — one entry per property token:\n * `\"<subsystem>.<property>\"` (base), `\"<subsystem>.<property>.<variant>\"`, and\n * `\"<subsystem>.<property>.<extra>\"`. Rule-sets are not tokens and are excluded. Each entry is\n * the Model's own `Ref` — `{ value }` for a literal, `{ ref }` for a reference. Additive source\n * for `theme.tokens`; the flat, format-neutral replacement for the per-subsystem `tokens` shape.\n */\nexport const buildTokenMap = (model: ThemeModel): Record<string, Ref> => {\n const out: Record<string, Ref> = {};\n for (const [subsystem, subModel] of Object.entries(model.subsystems)) {\n for (const [property, propertyModel] of Object.entries(subModel.properties ?? {})) {\n const base = `${subsystem}.${property}`;\n out[base] = propertyModel.base;\n for (const [variant, v] of Object.entries(propertyModel.variants ?? {})) {\n out[`${base}.${variant}`] = v.base;\n // dec.3 — a variant's extras are addressable tokens too: `<prop>.<variant>.<extra>`.\n for (const [field, ref] of Object.entries(v.extras ?? {})) {\n out[`${base}.${variant}.${field}`] = ref;\n }\n }\n for (const [field, ref] of Object.entries(propertyModel.extras ?? {})) {\n out[`${base}.${field}`] = ref;\n }\n }\n }\n return out;\n};\n","/**\n * Length units as a property of the value (§21).\n *\n * A length's unit belongs to the value, not to one global adapter switch. This module owns the whole\n * length-unit story: the CSS unit set, parsing an authored length input into a canonical dimension,\n * the three-layer role resolution, and the format-neutral **Model pass** that bakes a fully-resolved\n * `{ value, unit }` onto every length leaf. Adapters downstream only stringify (`value + unit`).\n *\n * Resolution order for a length leaf's unit (most-specific wins):\n * ① value-level unit — the token pinned `\"1px\"`; trusted verbatim, never converted\n * ② role default — `units[\"<sub>.<prop>\"]` → `units[\"<sub>\"]` → `units.default`\n * ③ built-in seed — length subsystems seed `px`; `lineHeight` → none; `letterSpacing` → em\n *\n * A bare number is **deferred** (px-intended magnitude, unit resolved by ②/③); `rem` is the one unit\n * whose resolution divides (`value ÷ baseFontSize`). An explicit unit is **pinned** — passed through.\n * Functions / keywords (`calc(…)`, `clamp(…)`, `var(…)`, `none`) are raw-string escapes, never parsed.\n */\n\nimport type { PropertyModel, Ref, ShadowLayer, SubsystemModel, ThemeModel, VariantModel } from \"./model\";\nimport { RefractError } from \"./errors\";\n\n// ---------------------------------------------------------------------------\n// Unit set\n// ---------------------------------------------------------------------------\n\n/**\n * The CSS length / relative unit set we parse + validate (§21 D2 — support every unit, exclude only\n * functions). A `<number><unit>` whose suffix is here becomes a pinned dimension; an unknown suffix is\n * an authoring error; anything with parens / whitespace / no digits is a raw-string escape.\n */\nexport const CSS_UNITS = [\n // absolute\n \"px\", \"cm\", \"mm\", \"q\", \"in\", \"pc\", \"pt\",\n // font-relative\n \"rem\", \"em\", \"ex\", \"cap\", \"ch\", \"ic\", \"lh\", \"rlh\",\n // percentage\n \"%\",\n // viewport\n \"vw\", \"vh\", \"vi\", \"vb\", \"vmin\", \"vmax\",\n \"svw\", \"svh\", \"lvw\", \"lvh\", \"dvw\", \"dvh\",\n // container-query\n \"cqw\", \"cqh\", \"cqi\", \"cqb\", \"cqmin\", \"cqmax\",\n] as const;\n\nexport type Unit = (typeof CSS_UNITS)[number];\n\n/** A resolved role: a concrete unit, or `\"none\"` (a length leaf that stays unit-less, e.g. lineHeight). */\nexport type RoleUnit = Unit | \"none\";\n\nconst UNIT_SET: ReadonlySet<string> = new Set(CSS_UNITS);\n\n// ---------------------------------------------------------------------------\n// Parse\n// ---------------------------------------------------------------------------\n\n/** A parsed length: a magnitude + optional unit (absent ⇒ deferred), or a raw escape string. */\nexport type ParsedLength = { value: number; unit?: Unit } | { raw: string };\n\nconst NUMERIC_RE = /^-?(?:\\d+\\.?\\d*|\\.\\d+)(?:e-?\\d+)?$/i;\nconst LENGTH_RE = /^(-?(?:\\d+\\.?\\d*|\\.\\d+)(?:e-?\\d+)?)([a-z%]+)$/i;\n\n/**\n * Parse one authored length input into a {@link ParsedLength}. A number, or a bare numeric string, is\n * deferred (`{ value }`). A `<number><unit>` with a known CSS unit is pinned (`{ value, unit }`). A\n * `<number><unknown>` is an authoring error (a typo — real functions/keywords carry parens or letters\n * with no leading number and fall through to `{ raw }`).\n */\nexport const parseLength = (input: number | string): ParsedLength => {\n if (typeof input === \"number\") return { value: input };\n const trimmed = input.trim();\n if (NUMERIC_RE.test(trimmed)) return { value: Number(trimmed) };\n const m = LENGTH_RE.exec(trimmed);\n if (m) {\n const unit = m[2].toLowerCase();\n if (UNIT_SET.has(unit)) return { value: Number(m[1]), unit: unit as Unit };\n throw new RefractError(\n \"REFRACT_E_UNITS\",\n `Unknown length unit \"${m[2]}\" in \"${input}\". Use a CSS unit, or wrap functions/keywords ` +\n `(calc(), clamp(), var(), a keyword) — those pass through as raw strings.`,\n );\n }\n return { raw: input };\n};\n\n// ---------------------------------------------------------------------------\n// Role resolution\n// ---------------------------------------------------------------------------\n\n/**\n * The build/theme-level unit config (§21 D3). Keys are token-path prefixes — `units.default` (global),\n * `units[\"<subsystem>\"]` (subsystem grain), `units[\"<subsystem>.<property>\"]` (property grain). Values\n * are a concrete unit or `\"none\"`. Most-specific wins; falls back to the built-in seed, then `px`.\n */\nexport type UnitsConfig = { default?: RoleUnit } & Record<string, RoleUnit | undefined>;\n\nexport type UnitResolutionConfig = {\n units?: UnitsConfig;\n /** Divisor for a deferred magnitude resolving to `rem` (matches typography + media). Default `16`. */\n baseFontSize?: number;\n};\n\nexport const DEFAULT_BASE_FONT_SIZE = 16;\n\n/**\n * The built-in seed (§21 D1) — the zero-config role default per length path. Length subsystems seed\n * `px` (the implicit fallback below, so they need no entry); the only entries are the two exceptions\n * whose natural unit differs: `lineHeight` is unit-less, `letterSpacing` is font-relative. Keeping the\n * px subsystems un-seeded is what makes default output byte-identical to the pre-§21 px-everywhere path.\n */\nconst SEED: Record<string, RoleUnit> = {\n \"typography.lineHeight\": \"none\",\n \"typography.letterSpacing\": \"em\",\n};\n\n/**\n * Resolve the role unit for a length leaf at `pathKey` (`\"typography.letterSpacing\"`). Precedence is\n * by **grain**, most-specific first, with the built-in property-grain seed slotted at its own grain —\n * so `SEED[\"typography.lineHeight\"] = \"none\"` beats a blunt subsystem-grain `units.typography = \"rem\"`\n * (§21 D1: property grain beats subsystem grain), while a user can still force it with the property key.\n */\nexport const resolveRoleUnit = (pathKey: string, units: UnitsConfig | undefined): RoleUnit => {\n const subsystem = pathKey.slice(0, pathKey.indexOf(\".\"));\n return (\n units?.[pathKey] ?? // ① user property grain\n SEED[pathKey] ?? // ② built-in property grain\n units?.[subsystem] ?? // ③ user subsystem grain\n units?.default ?? // ④ user global\n \"px\" // ⑤ built-in fallback\n );\n};\n\n/** Round a rem conversion to 4 dp, trailing zeros trimmed (matches the pre-§21 `formatLength`). */\nconst roundRem = (value: number, baseFontSize: number): number =>\n Number((value / baseFontSize).toFixed(4));\n\n/**\n * Resolve a deferred magnitude against its role unit → a concrete `{ value, unit? }`. `\"none\"` keeps\n * the value unit-less; `rem` divides by `baseFontSize`; every other unit is a straight tag.\n */\nconst resolveDeferred = (\n value: number,\n role: RoleUnit,\n baseFontSize: number,\n): { value: number; unit?: Unit } => {\n if (role === \"none\") return { value };\n if (role === \"rem\") return { value: roundRem(value, baseFontSize), unit: \"rem\" };\n return { value, unit: role };\n};\n\n// ---------------------------------------------------------------------------\n// Leaf resolution\n// ---------------------------------------------------------------------------\n\n/**\n * Resolve one length leaf {@link Ref} against its role. A pure token reference (`{ ref }`, no baked\n * value) is left untouched (its unit resolves at its own address). A **derived** length leaf\n * (`{ ref, fn, arg, value }` — §10.6 scale steps) carries its own baked `value`, emitted as a literal,\n * so its unit IS resolved here. A numeric or numeric-string value is deferred → resolved via the role;\n * a `<number><unit>` string is pinned → carried verbatim onto `{ value, unit }`; a raw escape\n * (`calc()`, keyword) is left as its string value. Returns a NEW ref when anything changed, else the\n * original (structural sharing preserved for byte-identical untouched branches).\n */\nexport const resolveLengthRef = (\n ref: Ref,\n role: RoleUnit,\n baseFontSize: number,\n): Ref => {\n if (ref.unit !== undefined) return ref; // already resolved (idempotent — `override` re-runs the pass)\n if (ref.ref !== undefined && ref.value === undefined) return ref; // pure alias — resolved at its own token\n const v = ref.value;\n\n if (typeof v === \"number\") {\n const { value, unit } = resolveDeferred(v, role, baseFontSize);\n return unit === undefined ? ref : { ...ref, value, unit };\n }\n\n if (typeof v === \"string\") {\n const parsed = parseLength(v);\n if (\"raw\" in parsed) return ref; // keyword / function — untouched\n if (parsed.unit !== undefined) return { ...ref, value: parsed.value, unit: parsed.unit }; // pinned\n const { value, unit } = resolveDeferred(parsed.value, role, baseFontSize); // numeric string → deferred\n return unit === undefined ? { ...ref, value } : { ...ref, value, unit };\n }\n\n return ref;\n};\n\n/** Resolve every geometry field of a structured shadow layer (§15) against the `effects.shadow` role. */\nconst resolveShadowLayer = (\n layer: ShadowLayer,\n role: RoleUnit,\n baseFontSize: number,\n): ShadowLayer => {\n const out: ShadowLayer = { ...layer };\n let changed = false;\n for (const field of [\"offsetX\", \"offsetY\", \"blur\", \"spread\"] as const) {\n const dim = layer[field];\n if (dim === undefined) continue;\n const resolved = resolveShadowDimension(dim, role, baseFontSize);\n if (resolved !== dim) {\n out[field] = resolved;\n changed = true;\n }\n }\n return changed ? out : layer;\n};\n\n/**\n * Resolve one shadow geometry field — a bare number (deferred) or a `{ value, unit }` (pinned, e.g.\n * authored `\"1px\"`). Deferred resolves via the role; pinned passes through. Mirrors {@link resolveLengthRef}\n * for the struct case, where the field is a {@link ShadowDimension} rather than a {@link Ref}.\n */\nconst resolveShadowDimension = (\n dim: ShadowDimension,\n role: RoleUnit,\n baseFontSize: number,\n): ShadowDimension => {\n if (typeof dim === \"number\") {\n const { value, unit } = resolveDeferred(dim, role, baseFontSize);\n return unit === undefined ? dim : { value, unit };\n }\n return dim; // already a pinned { value, unit }\n};\n\n/** A shadow geometry field after §21 widening — a deferred magnitude or a pinned `{ value, unit }`. */\nexport type ShadowDimension = number | { value: number; unit: Unit };\n\n// ---------------------------------------------------------------------------\n// Length-field registry\n// ---------------------------------------------------------------------------\n\n/** How a length-bearing property carries its value: a scalar leaf, or the shadow struct geometry. */\nexport type LengthKind = \"length\" | \"shadow\";\n\n/**\n * The length-field declaration (formalizes the scattered `PX_*_KEYS` of §16). Which `<subsystem>.<property>`\n * tokens are length-valued, and how they carry it. Anything absent (opacity, zIndex, aspectRatio, easing,\n * durations) is left untouched by the resolver. `lineHeight` is a length that seeds to `none` — listed so a\n * theme CAN opt it into a unit, resolving to unit-less by default.\n */\nexport const LENGTH_REGISTRY: Record<string, Record<string, LengthKind>> = {\n typography: { fontSize: \"length\", letterSpacing: \"length\", lineHeight: \"length\" },\n layout: { spacing: \"length\", gutters: \"length\", sizes: \"length\" },\n borders: { width: \"length\", offset: \"length\", radius: \"length\" },\n effects: { blur: \"length\", shadow: \"shadow\" },\n};\n\n// ---------------------------------------------------------------------------\n// Model pass\n// ---------------------------------------------------------------------------\n\n/**\n * Map a `field → Ref` record, returning the SAME reference when no entry changed (so an already-resolved\n * branch preserves object identity — `override`'s structural-sharing guarantee survives the re-run).\n */\nconst mapRefs = (record: Record<string, Ref>, map: (ref: Ref) => Ref): Record<string, Ref> => {\n let changed = false;\n const out: Record<string, Ref> = {};\n for (const [key, ref] of Object.entries(record)) {\n const next = map(ref);\n if (next !== ref) changed = true;\n out[key] = next;\n }\n return changed ? out : record;\n};\n\n/** dec.3 — map a property's variants (`variant → { base, extras }`), preserving identity when unchanged. */\nconst mapVariants = (\n variants: Record<string, VariantModel>,\n map: (ref: Ref) => Ref,\n): Record<string, VariantModel> => {\n let changed = false;\n const out: Record<string, VariantModel> = {};\n for (const [key, v] of Object.entries(variants)) {\n const base = map(v.base);\n const extras = v.extras ? mapRefs(v.extras, map) : undefined;\n if (base !== v.base || extras !== v.extras) changed = true;\n out[key] = extras ? { base, extras } : { base };\n }\n return changed ? out : variants;\n};\n\n/** Map a property's appearance modes (`mode → field → Ref`), preserving identity when nothing changed. */\nconst mapModes = (\n modes: PropertyModel[\"modes\"] & {},\n map: (ref: Ref) => Ref,\n): PropertyModel[\"modes\"] => {\n let changed = false;\n const next = modes.map(entry => {\n if (!entry.overrides) return entry;\n const overrides = mapRefs(entry.overrides, map);\n if (overrides === entry.overrides) return entry;\n changed = true;\n return { ...entry, overrides };\n });\n return changed ? next : modes;\n};\n\n/** Map a property's responsive overrides through `map`, preserving identity when nothing changed. */\nconst mapResponsive = (\n model: PropertyModel,\n map: (ref: Ref) => Ref,\n): PropertyModel[\"responsive\"] => {\n if (!model.responsive) return undefined;\n let changed = false;\n const next = model.responsive.map(entry => {\n if (!entry.overrides) return entry;\n const overrides = mapRefs(entry.overrides, map);\n if (overrides === entry.overrides) return entry;\n changed = true;\n return { ...entry, overrides };\n });\n return changed ? next : model.responsive;\n};\n\n/**\n * Apply a per-leaf `Ref → Ref` map across a property's leaves (base / variants / extras / modes /\n * responsive), returning the SAME `PropertyModel` when no leaf changed. Both the scalar-length and the\n * shadow-struct passes share this walk — they differ only in the leaf map (`scalar` vs `struct`).\n */\nconst mapPropertyLeaves = (\n model: PropertyModel,\n map: (ref: Ref) => Ref,\n includeExtras: boolean,\n): PropertyModel => {\n const base = map(model.base);\n const variants = model.variants ? mapVariants(model.variants, map) : undefined;\n const extras = includeExtras && model.extras ? mapRefs(model.extras, map) : model.extras;\n const modes = model.modes ? mapModes(model.modes, map) : undefined;\n const responsive = mapResponsive(model, map);\n\n if (\n base === model.base &&\n variants === model.variants &&\n extras === model.extras &&\n modes === model.modes &&\n responsive === model.responsive\n ) {\n return model;\n }\n const out: PropertyModel = { ...model, base };\n if (variants !== undefined) out.variants = variants;\n if (extras !== undefined) out.extras = extras;\n if (modes !== undefined) out.modes = modes;\n if (responsive !== undefined) out.responsive = responsive;\n return out;\n};\n\n/** Resolve a whole `PropertyModel`'s length leaves — scalar leaves, or a shadow's struct geometry. */\nconst resolvePropertyModel = (\n model: PropertyModel,\n kind: LengthKind,\n role: RoleUnit,\n baseFontSize: number,\n): PropertyModel => {\n const map =\n kind === \"shadow\"\n ? (ref: Ref): Ref => {\n if (!ref.struct) return ref;\n const layers = ref.struct as ShadowLayer[];\n let changed = false;\n const struct = layers.map(layer => {\n const next = resolveShadowLayer(layer, role, baseFontSize);\n if (next !== layer) changed = true;\n return next;\n });\n return changed ? { ...ref, struct } : ref;\n }\n : (ref: Ref): Ref => resolveLengthRef(ref, role, baseFontSize);\n // Shadow struct never lives in `extras`; scalar length extras are meaningless — skip extras for both.\n return mapPropertyLeaves(model, map, false);\n};\n\n/**\n * Resolve every length leaf in the {@link ThemeModel} to a concrete `{ value, unit }` (§21 D3). Pure and\n * **reference-preserving**: a subsystem / property / leaf that gains no unit keeps its object identity, so\n * the default px path stays byte-identical AND `override`'s structural sharing survives the re-run\n * (already-resolved parent branches are returned as-is). The single point where `units` is consulted.\n */\nexport const resolveModelUnits = (model: ThemeModel, config: UnitResolutionConfig = {}): ThemeModel => {\n const baseFontSize = config.baseFontSize ?? DEFAULT_BASE_FONT_SIZE;\n let anySubChanged = false;\n const subsystems: Record<string, SubsystemModel> = {};\n for (const [subKey, subModel] of Object.entries(model.subsystems)) {\n const fields = LENGTH_REGISTRY[subKey];\n if (!fields || !subModel.properties) {\n subsystems[subKey] = subModel;\n continue;\n }\n let anyPropChanged = false;\n const properties: Record<string, PropertyModel> = {};\n for (const [prop, pm] of Object.entries(subModel.properties)) {\n const kind = fields[prop];\n if (!kind) {\n properties[prop] = pm;\n continue;\n }\n const role = resolveRoleUnit(`${subKey}.${prop}`, config.units);\n const next = resolvePropertyModel(pm, kind, role, baseFontSize);\n if (next !== pm) anyPropChanged = true;\n properties[prop] = next;\n }\n if (anyPropChanged) {\n subsystems[subKey] = { ...subModel, properties };\n anySubChanged = true;\n } else {\n subsystems[subKey] = subModel;\n }\n }\n return anySubChanged ? { ...model, subsystems } : model;\n};\n","/**\n * Responsive-override normalization + reference validation.\n *\n * Normalizes a property's `responsive[]` entries (defaulting each `query`) and\n * validates their `breakpoint` / `variant` / `target` references against the\n * allowed sets threaded in via the normalization context.\n */\n\nimport type {\n NormalizedPropertyValue,\n NormalizedResponsiveOverride,\n PropertyNormalizationOptions,\n ResponsiveOverride,\n ResponsiveQuery,\n} from \"./types\";\nimport { RefractError } from \"../errors\";\n\n/** The `query` a responsive entry gets when none is authored — an exact-width media match. */\nexport const DEFAULT_RESPONSIVE_QUERY: ResponsiveQuery = \"exact\";\n\ntype AllowedValues<T> = ReadonlyArray<T> | ReadonlySet<T>;\n\ntype ResponsiveNormalizationContext<TBreakpoint extends string> = Pick<\n PropertyNormalizationOptions<unknown, TBreakpoint>,\n \"propertyPath\" | \"allowedBreakpoints\"\n> & {\n allowedTargets?: AllowedValues<string>;\n allowedVariants?: AllowedValues<string>;\n};\n\n/** Build the ` for \"<path>\"` suffix used in error messages (empty when no path is known). */\nconst formatContextLabel = (context?: { propertyPath?: string }): string =>\n context?.propertyPath ? ` for \"${context.propertyPath}\"` : \"\";\n\n/** Membership test that treats a missing `allowed` set as \"anything goes\". */\nconst isAllowedValue = <T>(value: T, allowed?: AllowedValues<T>): boolean => {\n if (!allowed) {\n return true;\n }\n\n if (Array.isArray(allowed)) {\n return allowed.includes(value);\n }\n\n return (allowed as ReadonlySet<T>).has(value);\n};\n\n/**\n * Normalize a property's `responsive[]` list: default each entry's `query` and\n * validate its references against the context's allowed sets.\n *\n * @param overrides The authored responsive entries (or `undefined` / empty → `[]`).\n * @param context Optional allowed sets — `allowedBreakpoints` / `allowedVariants`\n * / `allowedTargets` — plus `propertyPath` for error labels.\n * @throws If an entry is missing a `breakpoint`, or references an unknown\n * breakpoint / variant / target.\n */\nexport function normalizeResponsiveOverrides<\n TValue,\n TExtra extends Record<string, unknown> = Record<string, never>,\n TBreakpoint extends string = string,\n>(\n overrides: ResponsiveOverride<TValue, TExtra, TBreakpoint>[] | undefined,\n context?: ResponsiveNormalizationContext<TBreakpoint>,\n): NormalizedResponsiveOverride<TValue, TExtra, TBreakpoint>[] {\n if (!overrides?.length) {\n return [];\n }\n\n return overrides.map(override => {\n if (!override.breakpoint) {\n throw new RefractError(\n \"REFRACT_E_BREAKPOINT\",\n `Responsive entry${formatContextLabel(context)} is missing a \"breakpoint\" value.`,\n );\n }\n\n if (\n context?.allowedBreakpoints &&\n !isAllowedValue(override.breakpoint, context.allowedBreakpoints)\n ) {\n throw new RefractError(\n \"REFRACT_E_BREAKPOINT\",\n `Responsive entry${formatContextLabel(context)} references unknown breakpoint \"${override.breakpoint}\".`,\n );\n }\n\n // NB: on the PROPERTY side, `ref` + `target` is a supported *compose* (read a variant's value,\n // write it into another variant's token — see responsive-ref.test.ts), NOT a conflict. The\n // variant/target mutual-exclusion applies only to a RECIPE entry (a whole-recipe swap vs a scope),\n // enforced in normalizeRecipeResponsive.\n if (override.ref && !isAllowedValue(override.ref, context?.allowedVariants)) {\n throw new RefractError(\n \"REFRACT_E_RESPONSIVE\",\n `Responsive entry${formatContextLabel(context)} references unknown variant \"${override.ref}\" (ref).`,\n );\n }\n\n if (override.target && !isAllowedValue(override.target, context?.allowedTargets)) {\n throw new RefractError(\n \"REFRACT_E_RESPONSIVE\",\n `Responsive entry${formatContextLabel(context)} references unknown target \"${override.target}\".`,\n );\n }\n\n const { query, ...rest } = override;\n\n return {\n ...rest,\n query: query ?? DEFAULT_RESPONSIVE_QUERY,\n };\n });\n}\n\n/**\n * Second-pass validation: once a property is fully normalized, confirm every\n * responsive `variant` / `target` names a variant that actually exists on it.\n *\n * Complements {@link normalizeResponsiveOverrides}, which can't see the property's\n * own variant set during the first pass (variants are normalized in parallel).\n * A no-op when the property declares no variants.\n *\n * @throws If a responsive entry references a variant/target with no matching definition.\n */\nexport function validateNormalizedResponsiveRefs<\n TValue,\n TExtra extends Record<string, unknown> = Record<string, never>,\n TBreakpoint extends string = string,\n>(\n normalized: NormalizedPropertyValue<TValue, TExtra, TBreakpoint>,\n options?: { propertyPath?: string },\n): void {\n const variantNames = normalized.variants ? Object.keys(normalized.variants) : [];\n if (!variantNames.length) return;\n\n const allowed = new Set(variantNames);\n const label = options?.propertyPath ? ` for \"${options.propertyPath}\"` : \"\";\n\n for (const entry of normalized.responsive) {\n if (entry.ref && !allowed.has(entry.ref)) {\n throw new RefractError(\n \"REFRACT_E_RESPONSIVE\",\n `Responsive entry${label} references unknown variant \"${entry.ref}\" (ref).`,\n );\n }\n if (entry.target && !allowed.has(entry.target)) {\n throw new RefractError(\n \"REFRACT_E_RESPONSIVE\",\n `Responsive entry${label} references unknown target \"${entry.target}\".`,\n );\n }\n }\n}\n","/**\n * Property normalization — the entry point that turns any authored property value\n * into the canonical {@link NormalizedPropertyValue} shape.\n *\n * Collapses the three authoring forms (a bare value, or an extended object with\n * `base` / `variants` / `responsive`, plus subsystem `extra` fields) into one shape:\n * a resolved `base`, a normalized `variants` map, and a normalized `responsive` list.\n */\n\nimport {\n ExtendedProperty,\n ModeDerivation,\n ModeOverride,\n NormalizedModeValue,\n NormalizedModeOverride,\n NormalizedPropertyValue,\n NormalizedVariantValue,\n PropertyNormalizationOptions,\n PropertyValue,\n VariantValue,\n} from \"./types\";\nimport { normalizeResponsiveOverrides } from \"./responsive\";\nimport { RefractError } from \"../errors\";\n\n/** dec.2 — a `{ ref?, modifiers }` derivation (vs a literal or a multi-field mode object). */\nconst isModeDerivation = (value: unknown): value is ModeDerivation =>\n typeof value === \"object\" &&\n value !== null &&\n Array.isArray((value as { modifiers?: unknown }).modifiers);\n\n/**\n * dec.2 — parse an authored `modifiers` chain of single-key `{ [fn]: args }` dials into the\n * canonical `{ fn, arg }[]` the subsystem hook folds. Each element must have exactly one key (the\n * fn name), its value the arg (`{ darken: 10 }` → `{ fn: \"darken\", arg: 10 }`).\n */\nconst parseModifiers = (modifiers: unknown, path: string): Array<{ fn: string; arg?: unknown }> => {\n if (!Array.isArray(modifiers) || modifiers.length === 0) {\n throw new RefractError(\"REFRACT_E_VARIANT\", `Derivation \"${path}\" needs a non-empty \"modifiers\" array.`);\n }\n return modifiers.map((m, i) => {\n if (typeof m !== \"object\" || m === null || Array.isArray(m)) {\n throw new RefractError(\"REFRACT_E_VARIANT\", `Modifier ${i} of \"${path}\" must be a single-key object like { darken: 10 }.`);\n }\n const keys = Object.keys(m as Record<string, unknown>);\n if (keys.length !== 1) {\n throw new RefractError(\"REFRACT_E_VARIANT\", `Modifier ${i} of \"${path}\" must have exactly one fn key; got [${keys.join(\", \")}].`);\n }\n return { fn: keys[0], arg: (m as Record<string, unknown>)[keys[0]] };\n });\n};\n\n/**\n * Normalize one authored appearance-mode override ENTRY (§10.3) into a {@link NormalizedModeOverride}.\n * An entry is `{ mode, target?, …value }`: the `mode` name (WHEN) + optional `target` (WHERE) are\n * peeled off, and the value payload (WHAT) is normalized like a variant — a `{ ref?, modifiers }`\n * derivation (dec.2, unbaked by core), a flat object-leaf (§15), or a `{ base?, …extra }` object.\n */\nconst normalizeMode = <TValue, TExtra extends Record<string, unknown>, TBreakpoint extends string>(\n entry: ModeOverride<TValue, TExtra>,\n options: PropertyNormalizationOptions<TValue, TBreakpoint>,\n): NormalizedModeOverride<TValue, TExtra> => {\n const { mode: name, target, ...value } = entry as { mode: string; target?: string } & Record<string, unknown>;\n const modePath = options.propertyPath ? `${options.propertyPath}.modes.${name}` : `modes.${name}`;\n\n const normalizedValue = ((): NormalizedModeValue<TValue, TExtra> => {\n // §15: object-leaf subsystems — a flat leaf object (no `base` key, not a derivation) assembles its\n // leaf fields into the base; an explicit `base:` (incl. a multi-layer array) passes through below.\n if (options.leafFields?.length && !(\"base\" in value) && !isModeDerivation(value)) {\n const { base: assembled, extra } = partitionLeafBase(value, options.leafFields);\n if (assembled !== undefined) {\n const normalized: NormalizedModeValue<TValue, TExtra> = { ...(extra as Partial<TExtra>) };\n normalized.base = options.coerceValue ? options.coerceValue(assembled as TValue) : (assembled as TValue);\n return normalized;\n }\n }\n // dec.2 — `{ ref?, modifiers, …extra }` derivation → derived base (unbaked by core) + literal extras.\n if (isModeDerivation(value)) {\n const { ref, modifiers, ...rest } = value as ModeDerivation & Record<string, unknown>;\n const normalized: NormalizedModeValue<TValue, TExtra> = { ...(rest as Partial<TExtra>) };\n normalized.derive = {\n ...(ref !== undefined ? { ref } : {}),\n modifiers: parseModifiers(modifiers, modePath),\n };\n return normalized;\n }\n // Multi-field object: literal `base` (or a struct array) + literal extras.\n const { base, ...rest } = value as { base?: TValue } & Record<string, unknown>;\n const normalized: NormalizedModeValue<TValue, TExtra> = { ...(rest as Partial<TExtra>) };\n if (base !== undefined) {\n normalized.base = Array.isArray(base) || !options.coerceValue ? (base as TValue) : options.coerceValue(base as TValue);\n }\n if (normalized.base === undefined && !normalized.derive && !Object.keys(rest).length) {\n throw new RefractError(\"REFRACT_E_MODE\", `Appearance mode \"${modePath}\" overrides nothing.`);\n }\n return normalized;\n })();\n\n return { mode: name, ...(target !== undefined ? { target } : {}), ...normalizedValue };\n};\n\n/** Build the ` for \"<path>\"` suffix used in error messages (empty when no path is known). */\nconst formatPropertyLabel = (path?: string): string =>\n path ? ` for \"${path}\"` : \"\";\n\n/** Condition axes on a property responsive override (everything else is a value / leaf / extra field). */\nconst RESPONSIVE_CONDITION_KEYS: ReadonlySet<string> = new Set([\n \"breakpoint\",\n \"query\",\n \"ref\", // dec.5 — swap source (was `variant`)\n \"modifiers\", // dec.5 — derivation chain on `ref` (subsystem bakes it; never a plain field)\n \"mode\", // dec.9 — appearance-mode condition\n \"target\",\n \"orientation\",\n]);\n\n/** Discriminate the extended object form (`{ base, … }`) from a bare property value. */\nconst isExtendedProperty = <\n TValue,\n TExtra extends Record<string, unknown>,\n TBreakpoint extends string,\n>(value: PropertyValue<TValue, TExtra, TBreakpoint>): value is ExtendedProperty<TValue, TExtra, TBreakpoint> =>\n typeof value === \"object\" && value !== null && !Array.isArray(value);\n\n/**\n * Resolve a property's base value, falling back `providedBase → fallback →\n * options.fallbackBase`, applying `coerceValue` if provided. Throws when none resolve.\n */\nconst resolveBaseValue = <TValue, TBreakpoint extends string>(\n providedBase: TValue | undefined,\n fallback: TValue | undefined,\n options: PropertyNormalizationOptions<TValue, TBreakpoint>,\n): TValue => {\n const candidate = providedBase ?? fallback ?? options.fallbackBase;\n\n if (candidate === undefined) {\n throw new RefractError(\"REFRACT_E_PROPERTY\", `Unable to resolve base value${formatPropertyLabel(options.propertyPath)}.`);\n }\n\n return options.coerceValue ? options.coerceValue(candidate) : candidate;\n};\n\n/**\n * Partition an object into its assembled leaf-base value + remaining `TExtra` siblings (§15). When\n * `leafFields` carries at least one key present in `source`, those keys are collected into a base\n * object and the rest returned as `extra`; otherwise `base` is `undefined` (no leaf fields → the\n * caller uses the normal base path). Never fires without `leafFields` (scalar subsystems untouched).\n */\nconst partitionLeafBase = (\n source: Record<string, unknown>,\n leafFields: readonly string[],\n): { base: Record<string, unknown> | undefined; extra: Record<string, unknown> } => {\n const leafSet = new Set(leafFields);\n const base: Record<string, unknown> = {};\n const extra: Record<string, unknown> = {};\n let hasLeaf = false;\n for (const [key, value] of Object.entries(source)) {\n if (leafSet.has(key)) {\n base[key] = value;\n hasLeaf = true;\n } else {\n extra[key] = value;\n }\n }\n return { base: hasLeaf ? base : undefined, extra };\n};\n\n/**\n * Resolve a base value honoring the §15 leaf-field escape hatch. An explicit `base` wins (coerced\n * via {@link resolveBaseValue}); otherwise, when `options.leafFields` is set and `rest` carries leaf\n * fields, the base is assembled from them (coerced) and the remaining keys returned as `extra`.\n * With no `leafFields` (scalar subsystems) this is exactly `resolveBaseValue` + `rest` as extra.\n */\nconst resolveBaseAndExtra = <TValue, TBreakpoint extends string>(\n base: TValue | undefined,\n rest: Record<string, unknown>,\n fallback: TValue | undefined,\n options: PropertyNormalizationOptions<TValue, TBreakpoint>,\n): { base: TValue; extra: Record<string, unknown> } => {\n if (base === undefined && options.leafFields?.length) {\n const partitioned = partitionLeafBase(rest, options.leafFields);\n if (partitioned.base !== undefined) {\n const assembled = partitioned.base as TValue;\n return {\n base: options.coerceValue ? options.coerceValue(assembled) : assembled,\n extra: partitioned.extra,\n };\n }\n }\n return { base: resolveBaseValue(base, fallback, options), extra: rest };\n};\n\n/**\n * Assemble an object-leaf subsystem's responsive override (§15). A responsive entry that carries leaf\n * fields (or an explicit `base`) REPLACES the property's value at that breakpoint — its leaf fields\n * are assembled + coerced into `base` (whole-value replacement, like a variant swap sets the var). A\n * pure condition entry (a `variant`/`target` swap with no leaf fields) is returned untouched. Only\n * runs for `leafFields` subsystems; scalar subsystems keep their responsive entries verbatim.\n */\nconst assembleResponsiveLeaf = <TValue, TBreakpoint extends string>(\n entry: Record<string, unknown>,\n options: PropertyNormalizationOptions<TValue, TBreakpoint>,\n): Record<string, unknown> => {\n const condition: Record<string, unknown> = {};\n const others: Record<string, unknown> = {};\n let explicitBase: TValue | undefined;\n for (const [key, value] of Object.entries(entry)) {\n if (RESPONSIVE_CONDITION_KEYS.has(key)) condition[key] = value;\n else if (key === \"base\") explicitBase = value as TValue;\n else others[key] = value;\n }\n\n const hasLeaf = options.leafFields!.some(field => field in others);\n if (explicitBase === undefined && !hasLeaf) return entry; // pure swap / condition — nothing to assemble\n\n const { base: assembled, extra } = resolveBaseAndExtra(explicitBase, others, undefined, options);\n return { ...condition, ...extra, base: assembled };\n};\n\n/**\n * Normalize one named variant into `{ base, …extra }`. Accepts both the bare form\n * (`muted: \"#999\"`) and the extended form (`muted: { base: \"#999\", … }`). dec.3 — `fallbackBase`\n * is the property's own base: a variant that omits `base` (overriding only an extra) INHERITS it.\n */\nconst normalizeVariant = <\n TValue,\n TExtra extends Record<string, unknown>,\n TBreakpoint extends string,\n>(\n name: string,\n variant: VariantValue<TValue, TExtra, TBreakpoint>,\n options: PropertyNormalizationOptions<TValue, TBreakpoint>,\n fallbackBase?: TValue,\n): NormalizedVariantValue<TValue, TExtra, TBreakpoint> => {\n const variantPath = options.propertyPath\n ? `${options.propertyPath}.variants.${name}`\n : `variants.${name}`;\n\n const extended = isExtendedProperty<TValue, TExtra, TBreakpoint>(variant)\n ? variant\n : ({ base: variant } as ExtendedProperty<TValue, TExtra, TBreakpoint>);\n\n const { base, ...rest } = extended;\n const { base: resolvedBase, extra } = resolveBaseAndExtra(\n base,\n rest as Record<string, unknown>,\n fallbackBase, // dec.3 — inherit the property base when the variant omits its own.\n { ...options, propertyPath: variantPath },\n );\n\n return {\n ...(extra as unknown as TExtra),\n base: resolvedBase,\n };\n};\n\n/**\n * Normalize any authored property value into the canonical {@link NormalizedPropertyValue}.\n *\n * @param value A bare value or an extended `{ base, variants?, responsive?, …extra }` object.\n * @param options `propertyPath` (error labels), `fallbackBase`, `coerceValue`, and\n * `allowedBreakpoints` (responsive breakpoint validation).\n * @returns `{ base, responsive, variants?, …extra }` — `responsive` always an array,\n * each entry with its `query` defaulted; `variants` normalized or `undefined`.\n * @throws If no base value can be resolved, or a responsive entry fails validation.\n */\nexport const normalizePropertyValue = <\n TValue,\n TExtra extends Record<string, unknown> = Record<string, never>,\n TBreakpoint extends string = string,\n>(\n value: PropertyValue<TValue, TExtra, TBreakpoint>,\n options: PropertyNormalizationOptions<TValue, TBreakpoint> = {},\n): NormalizedPropertyValue<TValue, TExtra, TBreakpoint> => {\n const extended = isExtendedProperty<TValue, TExtra, TBreakpoint>(value)\n ? value\n : ({ base: value } as ExtendedProperty<TValue, TExtra, TBreakpoint>);\n\n const { base, responsive, variants, modes, ...rest } = extended;\n const { base: resolvedBase, extra } = resolveBaseAndExtra(\n base,\n rest as Record<string, unknown>,\n options.fallbackBase,\n options,\n );\n const normalizedVariants = variants\n ? Object.fromEntries(\n Object.entries(variants).map(([name, definition]) => [\n name,\n normalizeVariant(name, definition, options, resolvedBase), // dec.3 — property base = variant fallback.\n ]),\n )\n : undefined;\n const normalizedModes = modes ? modes.map(entry => normalizeMode(entry, options)) : undefined;\n const responsiveContext = {\n propertyPath: options.propertyPath,\n allowedBreakpoints: options.allowedBreakpoints,\n } as const;\n const normalizedResponsive = normalizeResponsiveOverrides(responsive, responsiveContext);\n // §15: object-leaf subsystems assemble a responsive entry's inline leaf fields into a `base` value\n // (whole-value replacement). Gated on `leafFields`, so scalar subsystems keep entries verbatim.\n const finalResponsive = options.leafFields?.length\n ? normalizedResponsive.map(\n entry =>\n assembleResponsiveLeaf(entry as Record<string, unknown>, options) as typeof entry,\n )\n : normalizedResponsive;\n\n return {\n ...(extra as unknown as TExtra),\n base: resolvedBase,\n responsive: finalResponsive,\n variants: normalizedVariants,\n modes: normalizedModes,\n };\n};\n","/**\n * Recipe-group normalization.\n *\n * A recipe authors its base declarations inline, plus two optional condition axes — a\n * grouped `states` map and a `responsive[]` list. Normalization splits both off the base\n * and flattens them into one unified `overrides` list, each entry carrying an optional\n * `state` and/or `breakpoint` (both present = the cross-product). References\n * (`breakpoint` / `state` / `variant` / `target`) are validated against the allowed sets.\n *\n * §7A — before any of that, a pre-pass expands an optional `variants` modifier map on any\n * recipe into flat sibling recipes (`<recipe>-<variant>`), so the rest of this module — the\n * resolver, `interpretRecipe`, reference extraction, the Model, and every adapter — sees the\n * same `RecipeGroupDefinition` authored today. Gated on the `variants` key: a group with no\n * `variants` is returned by reference, byte-identical.\n */\n\nimport type {\n RecipeGroupDefinition,\n NormalizedRecipeGroup,\n RecipeVariantDefinition,\n RecipeVariantModifier,\n RecipeResponsiveOverride,\n} from \"./types\";\nimport { RefractError } from \"../errors\";\n\n/** Allowed-reference sets threaded into recipe normalization for validation. */\nexport type RecipeNormalizationOptions<TBreakpoint extends string> = {\n propertyPath?: string;\n allowedBreakpoints?: ReadonlyArray<TBreakpoint> | ReadonlySet<TBreakpoint>;\n /** The adapter's known-state set; `state` values are validated against it (throw on unknown). */\n allowedStates?: ReadonlyArray<string> | ReadonlySet<string>;\n /** Container queries (§10.5): container name → its allowed size-names, validated on container overrides. */\n allowedContainers?: ReadonlyMap<string, ReadonlySet<string>>;\n};\n\nconst DEFAULT_QUERY = \"exact\" as const;\n/** Container conditions default to `min` (container-first idiom, §10.5 D1), unlike the viewport `exact` default. */\nconst DEFAULT_CONTAINER_QUERY = \"min\" as const;\n/** Condition fields that are meaningless on a container override (§10.5 D5) — they throw if present. */\nconst CONTAINER_INVALID_FIELDS = [\"orientation\", \"height\", \"aspectRatio\"] as const;\n\ntype AllowedValues<T> = ReadonlyArray<T> | ReadonlySet<T>;\n\nconst isAllowedValue = <T>(value: T, allowed?: AllowedValues<T>): boolean => {\n if (!allowed) {\n return true;\n }\n\n if (Array.isArray(allowed)) {\n return allowed.includes(value);\n }\n\n return (allowed as ReadonlySet<T>).has(value);\n};\n\n/** Build the ` for \"<path>\"` suffix used in error messages (empty when no path is known). */\nconst formatContextLabel = (path?: string): string => (path ? ` for \"${path}\"` : \"\");\n\n/** §7A — the single-dash join between a recipe and one of its variants (`primary` + `sm` → `primary-sm`). */\nconst VARIANT_NAME_SEPARATOR = \"-\";\n\n/** Recipe-leaf keys with bespoke merge rules; every other key is a ref/scalar prop (delta replaces). */\nconst RESPONSIVE_KEY = \"responsive\";\nconst STATES_KEY = \"states\";\nconst CSS_KEY = \"css\";\nconst VARIANTS_KEY = \"variants\";\n\n/**\n * `states` is a LIST of `{ state, target?, ...deltas }` entries (dec.8). Coerce whatever was authored\n * to that array — an array passes through; a legacy `{ state: {…delta} }` map is expanded to entries\n * (defensive: keeps untyped `.mjs` authoring working). Anything else → empty.\n */\ntype StateEntry = { state: string; target?: string } & Record<string, unknown>;\nconst toStateArray = (states: unknown): StateEntry[] => {\n if (Array.isArray(states)) return states as StateEntry[];\n if (states && typeof states === \"object\") {\n return Object.entries(states as Record<string, Record<string, unknown>>).map(\n ([state, delta]) => ({ state, ...delta }),\n );\n }\n return [];\n};\n\n/** The identity of a state override — `state` + its optional `target` (two same-state entries with\n * different targets are distinct; same-state same-target entries merge, delta winning). */\nconst stateEntryKey = (e: StateEntry): string => `${e.state}\u0000${e.target ?? \"\"}`;\n\n/**\n * Merge one variant's `states` list onto the recipe's (§7A). Entries with the same `(state, target)`\n * shallow-merge (delta wins per property, preserving the base entry's position); a new `(state,\n * target)` appends. Reproduces the old map-merge for the common (un-targeted) case while supporting\n * multiple same-state entries scoped to different targets.\n */\nconst mergeRecipeStates = (base: unknown, delta: unknown): StateEntry[] => {\n const out = toStateArray(base).map(e => ({ ...e }));\n const index = new Map(out.map((e, i) => [stateEntryKey(e), i]));\n for (const d of toStateArray(delta)) {\n const key = stateEntryKey(d);\n const at = index.get(key);\n if (at !== undefined) out[at] = { ...out[at], ...d };\n else {\n index.set(key, out.length);\n out.push({ ...d });\n }\n }\n return out;\n};\n\n/**\n * §7A `mergeRecipe(base, delta)` — layer a variant delta onto the recipe's own props:\n * - a ref / scalar prop → **delta replaces** (a ref is one atomic pointer);\n * - `css` → **shallow merge by property** (`{ ...base.css, ...delta.css }`);\n * - `states` → **merge by state name** (union; shared state shallow-merges, delta wins);\n * - `responsive[]` → **concatenate** (`base ++ delta`, delta last = higher source order);\n * - a prop set to `null` → **removal sentinel**, drops the inherited key (`\"none\"` stays a value).\n */\nconst mergeRecipe = (\n base: Record<string, unknown>,\n delta: Record<string, unknown>,\n): Record<string, unknown> => {\n const merged: Record<string, unknown> = { ...base };\n\n for (const [key, value] of Object.entries(delta)) {\n if (value === null) {\n delete merged[key];\n continue;\n }\n\n if (key === RESPONSIVE_KEY) {\n merged[RESPONSIVE_KEY] = [\n ...((base[RESPONSIVE_KEY] as unknown[] | undefined) ?? []),\n ...(value as unknown[]),\n ];\n } else if (key === STATES_KEY) {\n merged[STATES_KEY] = mergeRecipeStates(\n base[STATES_KEY] as Record<string, Record<string, unknown>> | undefined,\n value as Record<string, Record<string, unknown>>,\n );\n } else if (key === CSS_KEY) {\n merged[CSS_KEY] = {\n ...((base[CSS_KEY] as Record<string, unknown> | undefined) ?? {}),\n ...(value as Record<string, unknown>),\n };\n } else {\n merged[key] = value;\n }\n }\n\n return merged;\n};\n\n/**\n * §7A pre-pass — desugar every recipe's optional `variants` modifier map into flat sibling\n * recipes, returning a plain {@link RecipeGroupDefinition} the existing normalizer consumes.\n *\n * The bare recipe still emits (its own props, `variants` peeled off) **plus** one merged\n * sibling per variant, named `<recipe>-<variant>`. Opt-in and additive: if no recipe in the\n * group carries a `variants` key, the group is returned **by reference** so downstream output\n * is byte-identical. A desugared name colliding with any other sibling in the group throws.\n */\nconst expandRecipeVariants = <\n TProps extends Record<string, unknown>,\n TBreakpoint extends string,\n>(\n group: RecipeGroupDefinition<TProps, TBreakpoint>,\n path?: string,\n): RecipeGroupDefinition<TProps, TBreakpoint> => {\n const hasVariants = Object.values(group).some(\n recipe =>\n recipe != null &&\n typeof recipe === \"object\" &&\n (recipe as Record<string, unknown>)[VARIANTS_KEY] != null,\n );\n if (!hasVariants) {\n return group;\n }\n\n const expanded = {} as Record<string, RecipeVariantDefinition<TProps, TBreakpoint>>;\n\n const emit = (name: string, definition: RecipeVariantDefinition<TProps, TBreakpoint>) => {\n if (name in expanded) {\n throw new RefractError(\n \"REFRACT_E_VARIANT\",\n `Recipe variant expansion${formatContextLabel(path)} produced a duplicate recipe name \"${name}\" ` +\n `— a desugared \"<recipe>-<variant>\" collides with an existing sibling recipe.`,\n );\n }\n expanded[name] = definition;\n };\n\n for (const [recipeName, recipeDef] of Object.entries(group)) {\n const { [VARIANTS_KEY]: variants, ...base } = recipeDef as Record<string, unknown>;\n emit(recipeName, base as RecipeVariantDefinition<TProps, TBreakpoint>);\n\n if (variants != null) {\n // dec.8 — a `target`ed state on the base item scopes ONE-WAY onto its named sibling (emitted\n // during the base item's own lowering). A desugared sibling must NOT re-inherit those targeted\n // entries (they'd re-target a `<sibling>-<target>` class that doesn't exist); it inherits only\n // the un-targeted base states + its own delta.\n const baseForSibling =\n base[STATES_KEY] != null\n ? { ...base, [STATES_KEY]: toStateArray(base[STATES_KEY]).filter(e => !e.target) }\n : base;\n for (const [variantName, delta] of Object.entries(\n variants as Record<string, RecipeVariantModifier<TProps, TBreakpoint>>,\n )) {\n emit(\n `${recipeName}${VARIANT_NAME_SEPARATOR}${variantName}`,\n mergeRecipe(baseForSibling, delta as Record<string, unknown>) as RecipeVariantDefinition<\n TProps,\n TBreakpoint\n >,\n );\n }\n }\n }\n\n return expanded as RecipeGroupDefinition<TProps, TBreakpoint>;\n};\n\n/**\n * Normalize a whole recipe group (variant name → variant definition).\n *\n * Sibling variant names become the group's `allowedVariants` / `allowedTargets` set,\n * so a variant's responsive `variant` / `target` refs are validated against its peers.\n *\n * @param group The authored group — `{ primary: {…}, danger: {…} }`.\n * @param options `allowedBreakpoints` / `allowedStates` + `propertyPath` for error labels.\n * @returns Each variant normalized to `{ base, responsive }` (states + responsive flattened).\n * @throws If any entry references an unknown breakpoint / state / variant / target,\n * or a responsive entry is missing its breakpoint.\n */\nexport const normalizeRecipeGroup = <\n TProps extends Record<string, unknown>,\n TBreakpoint extends string,\n>(\n group: RecipeGroupDefinition<TProps, TBreakpoint>,\n options: RecipeNormalizationOptions<TBreakpoint> = {},\n): NormalizedRecipeGroup<TProps, TBreakpoint> => {\n // §7A — desugar any `variants` modifier maps into flat sibling recipes first, so everything\n // below (and downstream) sees the plain group shape authored today. No-op when unused.\n const expandedGroup = expandRecipeVariants(group, options.propertyPath);\n const variantNames = Object.keys(expandedGroup);\n const allowedVariantSet = variantNames.length\n ? (new Set(variantNames) as ReadonlySet<string>)\n : undefined;\n\n const normalized = {} as NormalizedRecipeGroup<TProps, TBreakpoint>;\n\n variantNames.forEach(variantName => {\n const variant = expandedGroup[variantName];\n normalized[variantName] = normalizeRecipeVariant(\n `${options.propertyPath ?? \"recipes\"}.${variantName}`,\n variant,\n {\n allowedBreakpoints: options.allowedBreakpoints,\n allowedStates: options.allowedStates,\n allowedTargets: allowedVariantSet,\n allowedVariants: allowedVariantSet,\n allowedContainers: options.allowedContainers,\n recipeName: variantName,\n },\n );\n });\n\n return normalized;\n};\n\ntype RecipeResponsiveContext<TBreakpoint extends string> = {\n allowedBreakpoints?: AllowedValues<TBreakpoint>;\n allowedStates?: AllowedValues<string>;\n allowedTargets?: AllowedValues<string>;\n allowedVariants?: AllowedValues<string>;\n allowedContainers?: ReadonlyMap<string, ReadonlySet<string>>;\n /** The current recipe item's name — a state `target` names a VARIANT key, so the sibling it scopes\n * onto is `<recipeName>-<target>`, validated against the group's members (dec.8). */\n recipeName?: string;\n};\n\n/** Normalize one recipe variant: peel off `states` + `responsive`, flatten both into `overrides`. */\nconst normalizeRecipeVariant = <\n TProps extends Record<string, unknown>,\n TBreakpoint extends string,\n>(\n path: string,\n variant: RecipeVariantDefinition<TProps, TBreakpoint>,\n context: RecipeResponsiveContext<TBreakpoint>,\n) => {\n const { responsive, states, ...base } = variant;\n\n // States + responsive flatten into ONE `overrides` list: each entry carries an optional\n // `state` and/or `breakpoint` (both present = the cross-product, e.g. `:hover` at `md`).\n // Pure-state entries come from the `states` map (no breakpoint); breakpoint entries come\n // from `responsive` (and may themselves carry a `state`).\n const normalizedStates = normalizeRecipeStates<TProps, TBreakpoint>(states, path, context);\n const normalizedResponsive = normalizeRecipeResponsive(responsive, path, context);\n\n return {\n base: base as TProps,\n responsive: [...normalizedStates, ...normalizedResponsive],\n };\n};\n\n/** Flatten the `states` LIST into override entries, each carrying its `state` + optional `target`\n * (dec.8 — `target` scopes the state onto the `<item>-<target>` sibling). */\nconst normalizeRecipeStates = <\n TProps extends Record<string, unknown>,\n TBreakpoint extends string,\n>(\n states: unknown,\n path: string,\n context: RecipeResponsiveContext<TBreakpoint>,\n): RecipeResponsiveOverride<TProps, TBreakpoint>[] => {\n return toStateArray(states).map(entry => {\n const { state: stateName, ...rest } = entry;\n if (context.allowedStates && !isAllowedValue(stateName, context.allowedStates)) {\n throw new RefractError(\n \"REFRACT_E_STATE\",\n `Recipe state entry${formatContextLabel(path)} references unknown state \"${stateName}\".`,\n );\n }\n // dec.8 — a `target` names a VARIANT key of THIS item; the sibling it scopes onto is\n // `<recipeName>-<target>` (the §7A-desugared class). Validate that sibling exists in the group.\n if (rest.target && context.allowedTargets) {\n const sibling = context.recipeName ? `${context.recipeName}-${rest.target}` : (rest.target as string);\n if (!isAllowedValue(sibling, context.allowedTargets)) {\n throw new RefractError(\n \"REFRACT_E_RESPONSIVE\",\n `Recipe state entry${formatContextLabel(path)} references unknown target \"${rest.target}\".`,\n );\n }\n }\n\n return {\n ...(rest as Partial<TProps>),\n state: stateName,\n } as RecipeResponsiveOverride<TProps, TBreakpoint>;\n });\n};\n\n/** Normalize the `responsive[]` list: require a breakpoint, default the `query`, validate refs. */\nconst normalizeRecipeResponsive = <\n TProps extends Record<string, unknown>,\n TBreakpoint extends string,\n>(\n overrides: RecipeResponsiveOverride<TProps, TBreakpoint>[] | undefined,\n path: string,\n context: RecipeResponsiveContext<TBreakpoint>,\n): RecipeResponsiveOverride<TProps, TBreakpoint>[] => {\n if (!overrides?.length) {\n return [];\n }\n\n return overrides.map(entry => {\n // `variant` (adopt a sibling's base) and `target` (scope this override onto a variant's token) are\n // opposites — a source vs a destination. Setting both on one entry is contradictory; fail loud\n // rather than silently honouring one. (Documented on the Errors page + Variants & targets concept.)\n if (entry.variant !== undefined && entry.target !== undefined) {\n throw new RefractError(\n \"REFRACT_E_RESPONSIVE\",\n `Responsive entry${formatContextLabel(path)} cannot set both \"variant\" and \"target\".`,\n );\n }\n\n // Container-query override (§10.5): keyed by `container` + `size` instead of `breakpoint`.\n if (entry.container !== undefined) {\n return normalizeContainerEntry(entry, path, context);\n }\n\n if (!entry.breakpoint) {\n throw new RefractError(\n \"REFRACT_E_BREAKPOINT\",\n `Responsive recipe entry${formatContextLabel(path)} is missing a \"breakpoint\" value.`,\n );\n }\n\n if (\n context.allowedBreakpoints &&\n !isAllowedValue(entry.breakpoint, context.allowedBreakpoints)\n ) {\n throw new RefractError(\n \"REFRACT_E_BREAKPOINT\",\n `Responsive recipe entry${formatContextLabel(path)} references unknown breakpoint \"${entry.breakpoint}\".`,\n );\n }\n\n if (entry.state && context.allowedStates && !isAllowedValue(entry.state, context.allowedStates)) {\n throw new RefractError(\n \"REFRACT_E_STATE\",\n `Responsive recipe entry${formatContextLabel(path)} references unknown state \"${entry.state}\".`,\n );\n }\n\n if (entry.variant && !isAllowedValue(entry.variant, context.allowedVariants)) {\n throw new RefractError(\n \"REFRACT_E_RESPONSIVE\",\n `Responsive recipe entry${formatContextLabel(path)} references unknown variant \"${entry.variant}\".`,\n );\n }\n\n if (entry.target && !isAllowedValue(entry.target, context.allowedTargets)) {\n throw new RefractError(\n \"REFRACT_E_RESPONSIVE\",\n `Responsive recipe entry${formatContextLabel(path)} references unknown target \"${entry.target}\".`,\n );\n }\n\n return {\n ...entry,\n query: entry.query ?? DEFAULT_QUERY,\n };\n });\n};\n\n/**\n * Normalize one container-query override (§10.5): validate the `container` name + its `size` against\n * the theme's `containers` config, reject the fields that can't work under `container-type: inline-size`\n * (`orientation`/`height`/`aspect-ratio` — D5), and default `query` to `min` (D1, not the viewport `exact`).\n */\nconst normalizeContainerEntry = <\n TProps extends Record<string, unknown>,\n TBreakpoint extends string,\n>(\n entry: RecipeResponsiveOverride<TProps, TBreakpoint>,\n path: string,\n context: RecipeResponsiveContext<TBreakpoint>,\n): RecipeResponsiveOverride<TProps, TBreakpoint> => {\n const name = entry.container as string;\n\n for (const field of CONTAINER_INVALID_FIELDS) {\n if ((entry as Record<string, unknown>)[field] !== undefined) {\n throw new RefractError(\n \"REFRACT_E_CONTAINER\",\n `Container recipe entry${formatContextLabel(path)} cannot use \"${field}\" — container queries ` +\n `respond to a container's inline size, not orientation/height/aspect-ratio.`,\n );\n }\n }\n\n const sizes = context.allowedContainers?.get(name);\n if (context.allowedContainers && !sizes) {\n throw new RefractError(\n \"REFRACT_E_CONTAINER\",\n `Container recipe entry${formatContextLabel(path)} references unknown container \"${name}\".`,\n );\n }\n\n if (entry.size === undefined) {\n throw new RefractError(\n \"REFRACT_E_CONTAINER\",\n `Container recipe entry${formatContextLabel(path)} for container \"${name}\" is missing a \"size\" value.`,\n );\n }\n\n if (sizes && !sizes.has(entry.size)) {\n throw new RefractError(\n \"REFRACT_E_CONTAINER\",\n `Container recipe entry${formatContextLabel(path)} references unknown size \"${entry.size}\" ` +\n `on container \"${name}\".`,\n );\n }\n\n return {\n ...entry,\n query: entry.query ?? DEFAULT_CONTAINER_QUERY,\n };\n};\n","/**\n * Lazy, memoized, cycle-safe recipe-variant resolver (clean-room port of\n * `core/common/recipeResolver.ts`).\n *\n * A recipe variant may reference a sibling variant (responsive `variant:` swaps). The\n * resolver interprets each variant on demand, caches the result, and detects cycles\n * (throwing with the offending chain). The interpret callback receives a `resolve`\n * function so it can pull a sibling's already-interpreted form.\n */\nimport type { NormalizedRecipeGroup, NormalizedRecipeVariant } from \"./types\";\nimport { RefractError } from \"../errors\";\n\nexport type RecipeInterpreter<\n TProps extends Record<string, unknown>,\n TBreakpoint extends string,\n TInterpreted,\n> = (\n variantName: string,\n variant: NormalizedRecipeVariant<TProps, TBreakpoint>,\n resolve: (variantName: string) => TInterpreted,\n) => TInterpreted;\n\nexport type RecipeVariantResolver<TInterpreted> = {\n resolve: (variantName: string) => TInterpreted;\n resolveAll: () => Record<string, TInterpreted>;\n};\n\nexport type CreateRecipeVariantResolverOptions = {\n groupPath?: string;\n};\n\nexport const createRecipeVariantResolver = <\n TProps extends Record<string, unknown>,\n TBreakpoint extends string,\n TInterpreted,\n>(\n group: NormalizedRecipeGroup<TProps, TBreakpoint>,\n interpret: RecipeInterpreter<TProps, TBreakpoint, TInterpreted>,\n options: CreateRecipeVariantResolverOptions = {},\n): RecipeVariantResolver<TInterpreted> => {\n const cache = new Map<string, TInterpreted>();\n const inProgress: string[] = [];\n const groupPath = options.groupPath ?? \"recipes\";\n\n const resolve = (variantName: string): TInterpreted => {\n if (cache.has(variantName)) {\n return cache.get(variantName) as TInterpreted;\n }\n\n if (inProgress.includes(variantName)) {\n const cycle = [...inProgress, variantName].join(\" -> \");\n throw new RefractError(\"REFRACT_E_CYCLE\", `Cyclic recipe reference in \"${groupPath}\": ${cycle}`);\n }\n\n const variant = group[variantName];\n if (!variant) {\n throw new RefractError(\"REFRACT_E_REFERENCE\", `Recipe variant \"${variantName}\" is not defined in \"${groupPath}\".`);\n }\n\n inProgress.push(variantName);\n try {\n const result = interpret(variantName, variant, resolve);\n cache.set(variantName, result);\n return result;\n } finally {\n inProgress.pop();\n }\n };\n\n const resolveAll = (): Record<string, TInterpreted> => {\n const out: Record<string, TInterpreted> = {};\n for (const name of Object.keys(group)) {\n out[name] = resolve(name);\n }\n return out;\n };\n\n return { resolve, resolveAll };\n};\n","/**\n * Derivation resolver (model-first).\n *\n * Resolves a `path -> Ref` token map to concrete literals, running **value derivations** — a\n * `Ref` of the form `{ ref, fn, arg }` means `value = registry[fn](resolve(ref), arg)`. Plain\n * `{ ref }` is an alias (`= resolve(ref)`), `{ value }` is a terminal literal. Recursive (so\n * chained derivations like `darker = darken(dark)` resolve), memoized per pass, and cycle-safe.\n *\n * Subsystems contribute derivation fns (colors → `lighten`/`darken`, typography → `scale`);\n * core assembles them into one {@link DerivationRegistry}. Used by `theme.tokens` (resolved\n * view) and by the CSS adapter's lowering (concrete `:root` / inline values). See\n * `.notes/reference/derivation-resolver-and-merge.md`.\n */\nimport type { Literal, Ref } from \"../model\";\nimport { RefractError } from \"../errors\";\n\n/** A value-derivation: derive a literal from a source literal + optional argument. */\nexport type DerivationFn = (value: Literal, arg?: unknown) => Literal;\n\n/** `fn name -> DerivationFn`, assembled from the subsystems (unique names; collisions throw). */\nexport type DerivationRegistry = Record<string, DerivationFn>;\n\n/** Merge subsystem derivation-fn maps into one registry; a duplicate name is a hard error. */\nexport const buildDerivationRegistry = (\n contributions: ReadonlyArray<Readonly<DerivationRegistry>>,\n): DerivationRegistry => {\n const registry: DerivationRegistry = {};\n for (const contribution of contributions) {\n for (const [name, fn] of Object.entries(contribution)) {\n if (name in registry) {\n throw new RefractError(\"REFRACT_E_TOKEN_PATH\", `Duplicate derivation fn \"${name}\" registered by two subsystems.`);\n }\n registry[name] = fn;\n }\n }\n return registry;\n};\n\n/**\n * Resolve one token `path` in `map` to a concrete literal, running any derivation. `cache` and\n * `resolving` are threaded through recursion (chaining + cycle detection); callers may omit them.\n */\nexport const resolveToken = (\n map: Record<string, Ref>,\n registry: DerivationRegistry,\n path: string,\n cache: Map<string, Literal> = new Map(),\n resolving: Set<string> = new Set(),\n): Literal => {\n const cached = cache.get(path);\n if (cached !== undefined) return cached;\n\n const entry = map[path];\n if (!entry) throw new RefractError(\"REFRACT_E_TOKEN_PATH\", `Unknown token path \"${path}\".`);\n\n // §W6b — external token: resolves to its parent-theme CSS variable, never derived.\n if (entry.external !== undefined) {\n const v = `var(${entry.external})`;\n cache.set(path, v);\n return v;\n }\n\n // Terminal literal — no ref to follow.\n if (entry.ref === undefined) {\n if (entry.value === undefined) {\n throw new RefractError(\"REFRACT_E_TOKEN_PATH\", `Token \"${path}\" has neither \"ref\" nor \"value\".`);\n }\n cache.set(path, entry.value);\n return entry.value;\n }\n\n if (resolving.has(path)) {\n throw new RefractError(\"REFRACT_E_CYCLE\", `Cyclic token reference: ${[...resolving, path].join(\" -> \")}`);\n }\n resolving.add(path);\n const base = resolveToken(map, registry, entry.ref, cache, resolving);\n let result: Literal;\n if (entry.modifiers !== undefined) {\n // dec.2 — fold the ordered derivation chain over the resolved source.\n result = entry.modifiers.reduce((value, mod) => {\n const fn = registry[mod.fn];\n if (!fn) throw new RefractError(\"REFRACT_E_TOKEN_PATH\", `Unknown derivation fn \"${mod.fn}\" for token \"${path}\".`);\n return fn(value, mod.arg);\n }, base);\n } else if (entry.fn !== undefined) {\n const fn = registry[entry.fn];\n if (!fn) throw new RefractError(\"REFRACT_E_TOKEN_PATH\", `Unknown derivation fn \"${entry.fn}\" for token \"${path}\".`);\n result = fn(base, entry.arg);\n } else {\n result = base; // plain alias\n }\n resolving.delete(path);\n cache.set(path, result);\n return result;\n};\n\n/** Resolve every entry in a token `map` to its concrete literal (one shared memo pass). */\nexport const resolveTokenMap = (\n map: Record<string, Ref>,\n registry: DerivationRegistry,\n): Record<string, Literal> => {\n const cache = new Map<string, Literal>();\n const out: Record<string, Literal> = {};\n for (const path of Object.keys(map)) {\n out[path] = resolveToken(map, registry, path, cache);\n }\n return out;\n};\n","/**\n * dec.4 — cross-property derivation resolve pass.\n *\n * A variant / mode value may derive from ANOTHER property (`surface.modes.dark =\n * { ref: \"colors.brand\", modifiers: [{ adjust: { l: 12 } }] }`). Colours bakes derivations one\n * property at a time, so a cross-property source isn't available at bake time — the owning subsystem\n * emits such a derivation **unbaked** (a `Ref` carrying `ref` + `modifiers`/`fn` but no cached\n * `value`). This post-build pass runs once the full `path -> Ref` token map exists and fills each\n * cross-property derived `Ref`'s `.value` by resolving its source and folding its chain.\n *\n * - **Variants** are addressable tokens, so their source resolves through `resolveToken` (which itself\n * follows the ref + folds modifiers across the whole map — chains of cross-property derivations\n * resolve for free, no ordering needed).\n * - **Modes are NOT tokens** (they're emit-only), so a mode's source is resolved via `resolveToken`\n * on its `ref` and the chain folded here by hand, rather than through a mode token that doesn't exist.\n *\n * The pass is **structural, not value-based**: it re-bakes any derived Ref whose source property\n * differs from the owner, regardless of whether a value is already present. That makes it correct on\n * `override()` too — re-running it against the merged token map re-derives a child's cross-property\n * values when the source changed, exactly like intra-property derivations. It rebuilds immutably\n * (new `Ref`s only where it re-bakes; every untouched branch keeps its reference), so a shared parent\n * Model is never mutated, and a Model with no cross-property derivation is returned by reference\n * (goldens byte-identical).\n */\nimport type { Literal, Ref, ThemeModel, PropertyModel, VariantModel } from \"../model\";\nimport { buildTokenMap } from \"../model\";\nimport { RefractError } from \"../errors\";\nimport { resolveToken, type DerivationRegistry } from \"./resolveTokens\";\n\n/** The `<subsystem>.<property>` prefix of a token path (the first two dotted segments). */\nconst propertyPrefix = (path: string): string => {\n const [seg0, seg1] = path.split(\".\");\n return `${seg0}.${seg1}`;\n};\n\n/** A derived Ref (carries `ref` + a chain) whose source lives in a DIFFERENT property than `owner`. */\nconst isCrossPropertyDerived = (ref: Ref | undefined, owner: string): boolean => {\n if (!ref?.ref) return false;\n if (ref.modifiers === undefined && ref.fn === undefined) return false; // a plain alias, not a derivation\n return propertyPrefix(ref.ref) !== owner;\n};\n\n/**\n * Re-bake one cross-property derived Ref: resolve its source value against the token map, fold its\n * modifier chain (or legacy `fn`/`arg`), and return a fresh Ref carrying the baked `.value`. The\n * derivation metadata (`ref` + chain) is preserved so `override()` re-derives it again.\n */\nconst rebake = (\n ref: Ref,\n tokens: Record<string, Ref>,\n registry: DerivationRegistry,\n cache: Map<string, Literal>,\n where: string,\n): Ref => {\n let value: Literal;\n try {\n value = resolveToken(tokens, registry, ref.ref as string, cache);\n } catch {\n throw new RefractError(\n \"REFRACT_E_VALIDATION\",\n `${where}: cross-property derivation references unknown token '${ref.ref}'.`,\n );\n }\n const apply = (fn: string, arg: unknown): Literal => {\n const derive = registry[fn];\n if (!derive) {\n throw new RefractError(\"REFRACT_E_VALIDATION\", `${where}: unknown derivation fn '${fn}'.`);\n }\n return derive(value, arg);\n };\n if (ref.modifiers !== undefined) {\n for (const mod of ref.modifiers) value = apply(mod.fn, mod.arg);\n } else if (ref.fn !== undefined) {\n value = apply(ref.fn, ref.arg);\n }\n return { ...ref, value };\n};\n\n/** Re-bake any cross-property derived Ref in a `field -> Ref` map (mode fields / variant extras). */\nconst rebakeFields = (\n fields: Record<string, Ref>,\n owner: string,\n tokens: Record<string, Ref>,\n registry: DerivationRegistry,\n cache: Map<string, Literal>,\n where: string,\n): Record<string, Ref> | undefined => {\n let next: Record<string, Ref> | undefined;\n for (const [name, ref] of Object.entries(fields)) {\n if (!isCrossPropertyDerived(ref, owner)) continue;\n next = next ?? { ...fields };\n next[name] = rebake(ref, tokens, registry, cache, `${where}.${name}`);\n }\n return next;\n};\n\n/** Re-bake a property's cross-property variants (base + extras). Returns undefined when none changed. */\nconst rebakeVariants = (\n variants: Record<string, VariantModel>,\n owner: string,\n tokens: Record<string, Ref>,\n registry: DerivationRegistry,\n cache: Map<string, Literal>,\n): Record<string, VariantModel> | undefined => {\n let next: Record<string, VariantModel> | undefined;\n for (const [name, variant] of Object.entries(variants)) {\n const at = `${owner}.variants.${name}`;\n const base = isCrossPropertyDerived(variant.base, owner)\n ? rebake(variant.base, tokens, registry, cache, at)\n : variant.base;\n const extras = variant.extras\n ? rebakeFields(variant.extras, owner, tokens, registry, cache, `${at} extra`)\n : undefined;\n if (base === variant.base && !extras) continue;\n next = next ?? { ...variants };\n next[name] = extras ? { base, extras } : { ...variant, base };\n }\n return next;\n};\n\n/** Re-bake a single property's cross-property variants + modes. Returns undefined when none changed. */\nconst rebakeProperty = (\n pm: PropertyModel,\n owner: string,\n tokens: Record<string, Ref>,\n registry: DerivationRegistry,\n cache: Map<string, Literal>,\n): PropertyModel | undefined => {\n const variants = pm.variants\n ? rebakeVariants(pm.variants, owner, tokens, registry, cache)\n : undefined;\n\n let modes: PropertyModel[\"modes\"] | undefined;\n if (pm.modes) {\n for (let i = 0; i < pm.modes.length; i++) {\n const entry = pm.modes[i];\n if (!entry.overrides) continue;\n const nextFields = rebakeFields(entry.overrides, owner, tokens, registry, cache, `${owner}.modes.${entry.mode}`);\n if (!nextFields) continue;\n modes = modes ?? [...pm.modes];\n modes[i] = { ...entry, overrides: nextFields };\n }\n }\n\n if (!variants && !modes) return undefined;\n const next: PropertyModel = { ...pm };\n if (variants) next.variants = variants;\n if (modes) next.modes = modes;\n return next;\n};\n\n/**\n * Fill every cross-property derived variant / mode Ref's `.value` against the Model's token map.\n * Immutable — returns the Model by reference when nothing is cross-property (byte-identical output).\n */\nexport const bakeCrossPropertyDerivations = (\n model: ThemeModel,\n registry: DerivationRegistry,\n): ThemeModel => {\n const tokens = buildTokenMap(model);\n const cache = new Map<string, Literal>();\n let modelChanged = false;\n const nextSubsystems: ThemeModel[\"subsystems\"] = {};\n\n for (const [subKey, sub] of Object.entries(model.subsystems)) {\n let subChanged = false;\n let nextProps: Record<string, PropertyModel> | undefined;\n for (const [propName, pm] of Object.entries(sub.properties ?? {})) {\n const owner = `${subKey}.${propName}`;\n const nextPm = rebakeProperty(pm, owner, tokens, registry, cache);\n if (!nextPm) continue;\n nextProps = nextProps ?? { ...sub.properties };\n nextProps[propName] = nextPm;\n subChanged = true;\n }\n if (subChanged) {\n nextSubsystems[subKey] = { ...sub, properties: nextProps };\n modelChanged = true;\n } else {\n nextSubsystems[subKey] = sub;\n }\n }\n\n return modelChanged ? { ...model, subsystems: nextSubsystems } : model;\n};\n","import type { MediaQueryOptions } from \"./queries\";\nimport { RefractError } from \"../errors\";\n\nexport const BREAKPOINT_EPSILON = 0.02;\n\nconst RESERVED_BREAKPOINT_KEYS = [\"min\", \"max\", \"exact\", \"between\"] as const;\n\nexport type MediaVariant = \"min\" | \"max\" | \"exact\";\n\nexport type MediaGroupDescriptor = Record<MediaVariant, string>;\n\nexport type MediaDescriptor<TBreakpoint extends string> = {\n min: (key: TBreakpoint, options?: MediaQueryOptions) => string;\n max: (key: TBreakpoint, options?: MediaQueryOptions) => string;\n exact: (key: TBreakpoint, options?: MediaQueryOptions) => string;\n between: (\n from: TBreakpoint,\n to: TBreakpoint,\n options?: MediaQueryOptions,\n ) => string;\n} & Record<TBreakpoint, MediaGroupDescriptor>;\n\nexport const sortBreakpointKeys = <T extends string>(\n breakpoints: Record<T, number>,\n): T[] => (Object.keys(breakpoints) as T[]).sort(\n (a, b) => breakpoints[a] - breakpoints[b],\n);\n\nconst maxValueForNext = (next?: number): number | undefined =>\n next === undefined ? undefined : next - BREAKPOINT_EPSILON;\n\nconst assertNoReservedBreakpointNames = (keys: readonly string[]): void => {\n const conflicts = keys.filter(key =>\n (RESERVED_BREAKPOINT_KEYS as readonly string[]).includes(key),\n );\n if (conflicts.length) {\n throw new RefractError(\n \"REFRACT_E_BREAKPOINT\",\n `Breakpoint names conflict with reserved keys: ${conflicts\n .map(k => `\"${k}\"`)\n .join(\", \")}. Reserved: ${RESERVED_BREAKPOINT_KEYS.map(k => `\"${k}\"`).join(\", \")}.`,\n );\n }\n};\n\nexport const buildMediaDescriptor = <TBreakpoint extends string>(\n breakpoints: Record<TBreakpoint, number>,\n resolveQuery: (\n options: MediaQueryOptions,\n ) => string,\n): MediaDescriptor<TBreakpoint> => {\n const keys = sortBreakpointKeys(breakpoints);\n assertNoReservedBreakpointNames(keys);\n\n const nextOf = (key: TBreakpoint): TBreakpoint | undefined =>\n keys[keys.indexOf(key) + 1];\n\n const groups = keys.reduce<Record<TBreakpoint, MediaGroupDescriptor>>(\n (acc, key) => {\n const own = breakpoints[key];\n const nextKey = nextOf(key);\n const next = nextKey !== undefined ? breakpoints[nextKey] : undefined;\n\n acc[key] = buildGroupDescriptor({ own, next }, resolveQuery);\n return acc;\n },\n {} as Record<TBreakpoint, MediaGroupDescriptor>,\n );\n\n const resolveKey = (key: TBreakpoint): MediaGroupDescriptor => {\n const group = groups[key];\n if (!group) {\n throw new RefractError(\"REFRACT_E_BREAKPOINT\", `Breakpoint \"${key}\" is not defined.`);\n }\n return group;\n };\n\n const between = (\n from: TBreakpoint,\n to: TBreakpoint,\n options?: MediaQueryOptions,\n ): string => {\n const min = breakpoints[from];\n const toValue = breakpoints[to];\n\n if (min === undefined || toValue === undefined) {\n throw new RefractError(\n \"REFRACT_E_BREAKPOINT\",\n `Cannot build media query between \"${from}\" and \"${to}\" breakpoints.`,\n );\n }\n\n return resolveQuery({ min, max: toValue - BREAKPOINT_EPSILON, ...options });\n };\n\n const descriptor = {\n ...groups,\n min: (key: TBreakpoint, options?: MediaQueryOptions) => {\n const group = resolveKey(key);\n if (!options) {\n return group.min;\n }\n return resolveQuery({ min: breakpoints[key], ...options });\n },\n max: (key: TBreakpoint, options?: MediaQueryOptions) => {\n const group = resolveKey(key);\n if (!options) {\n return group.max;\n }\n const nextKey = nextOf(key);\n const next = nextKey !== undefined ? breakpoints[nextKey] : undefined;\n return resolveQuery({ max: maxValueForNext(next), ...options });\n },\n exact: (key: TBreakpoint, options?: MediaQueryOptions) => {\n const group = resolveKey(key);\n if (!options) {\n return group.exact;\n }\n const nextKey = nextOf(key);\n const next = nextKey !== undefined ? breakpoints[nextKey] : undefined;\n return resolveQuery({ min: breakpoints[key], max: maxValueForNext(next), ...options });\n },\n between,\n } as MediaDescriptor<TBreakpoint>;\n\n return descriptor;\n};\n\nconst buildGroupDescriptor = (\n { own, next }: { own: number; next?: number },\n resolveQuery: (options: MediaQueryOptions) => string,\n): MediaGroupDescriptor => {\n const maxValue = maxValueForNext(next);\n return {\n min: resolveQuery({ min: own }),\n max: maxValue === undefined ? \"\" : resolveQuery({ max: maxValue }),\n exact: resolveQuery({ min: own, max: maxValue }),\n };\n};\n","import { RefractError } from \"../errors\";\n\nexport type MediaUnit = \"px\" | \"em\" | \"rem\";\n\nexport type MediaConfig = {\n unit?: MediaUnit;\n baseFontSize?: number;\n};\n\nexport type MediaQueryOptions = {\n min?: number;\n max?: number;\n orientation?: \"landscape\" | \"portrait\";\n};\n\nconst DEFAULT_MEDIA_CONFIG: Required<MediaConfig> = {\n unit: \"px\",\n baseFontSize: 16,\n};\n\nexport const resolveMediaConfig = (\n config?: MediaConfig,\n): Required<MediaConfig> => ({\n unit: config?.unit ?? DEFAULT_MEDIA_CONFIG.unit,\n baseFontSize:\n config?.baseFontSize && config.baseFontSize > 0\n ? config.baseFontSize\n : DEFAULT_MEDIA_CONFIG.baseFontSize,\n});\n\nexport const formatWidth = (value: number, config: Required<MediaConfig>): string => {\n if (config.unit === \"px\") {\n return `${value}px`;\n }\n\n const converted = value / config.baseFontSize;\n const trimmed = Number(converted.toFixed(4));\n return `${trimmed}${config.unit}`;\n};\n\nexport const mediaQueryString = (\n { min, max, orientation }: MediaQueryOptions,\n config: Required<MediaConfig>,\n): string => {\n const clauses: string[] = [];\n\n if (min !== undefined && max !== undefined && min > max) {\n throw new RefractError(\"REFRACT_E_MEDIA\", \"Invalid media query: `min` cannot be greater than `max`.\");\n }\n\n if (min !== undefined) {\n clauses.push(`(min-width: ${formatWidth(min, config)})`);\n }\n\n if (max !== undefined) {\n clauses.push(`(max-width: ${formatWidth(max, config)})`);\n }\n\n if (orientation) {\n clauses.push(`(orientation: ${orientation})`);\n }\n\n if (!clauses.length) {\n return \"\";\n }\n\n return `@media ${clauses.join(\" and \")}`;\n};\n\nexport const mediaQuery = (\n options: MediaQueryOptions,\n config?: MediaConfig,\n): string => mediaQueryString(options, resolveMediaConfig(config));\n\n/**\n * Container-query prelude (§10.5) — the `@container <name> (…)` twin of {@link mediaQueryString}.\n * Shares the width formatting (so container thresholds honor the same px/em/rem unit config), but\n * has no `orientation` clause (invalid under `container-type: inline-size`; rejected in normalize).\n */\nexport const containerQueryString = (\n name: string,\n { min, max }: Pick<MediaQueryOptions, \"min\" | \"max\">,\n config: Required<MediaConfig>,\n): string => {\n const clauses: string[] = [];\n if (min !== undefined && max !== undefined && min > max) {\n throw new RefractError(\"REFRACT_E_MEDIA\", \"Invalid container query: `min` cannot be greater than `max`.\");\n }\n if (min !== undefined) clauses.push(`(min-width: ${formatWidth(min, config)})`);\n if (max !== undefined) clauses.push(`(max-width: ${formatWidth(max, config)})`);\n if (!clauses.length) return \"\";\n return `@container ${name} ${clauses.join(\" and \")}`;\n};\n","export type DefaultBreakpointKey = \"xs\" | \"sm\" | \"md\" | \"lg\" | \"xl\";\nexport type DefaultBreakpoints = Record<DefaultBreakpointKey, number>;\n\nexport const DEFAULT_BREAKPOINTS: DefaultBreakpoints = {\n xs: 0,\n sm: 576,\n md: 768,\n lg: 992,\n xl: 1280,\n};\n","/**\n * Container-query descriptors (§10.5).\n *\n * A named query container has a *size* scale (`sizeName → px`), exactly the shape a breakpoint scale\n * has — so each container reuses {@link buildMediaDescriptor} with an `@container`-prefixing resolver.\n * The result is a per-container descriptor whose `.min/.max/.exact(sizeName)` (and `[sizeName][kind]`)\n * yield `@container <name> (…)` preludes with the same min/max/exact + band-to-next semantics the\n * viewport axis uses. Threshold widths honor the shared media unit config (px default, em/rem).\n */\nimport { buildMediaDescriptor, type MediaDescriptor } from \"./descriptors\";\nimport { containerQueryString, resolveMediaConfig, type MediaConfig } from \"./queries\";\nimport type { ContainerModel } from \"../model/model\";\n\n/** One descriptor per named container: `containerName → MediaDescriptor` over that container's size scale. */\nexport type ContainerDescriptors = Record<string, MediaDescriptor<string>>;\n\n/**\n * Build a {@link ContainerDescriptors} map from the theme's `containers` config. Each container's\n * `sizes` become the descriptor's \"breakpoints\"; the resolver emits `@container <name> (…)`. The\n * width unit follows `config` (shared with the viewport media descriptor).\n */\nexport const buildContainerDescriptors = (\n containers: Record<string, ContainerModel> | undefined,\n config?: MediaConfig,\n): ContainerDescriptors => {\n const resolved = resolveMediaConfig(config);\n const out: ContainerDescriptors = {};\n for (const [name, container] of Object.entries(containers ?? {})) {\n out[name] = buildMediaDescriptor(container.sizes, opts =>\n containerQueryString(name, { min: opts.min, max: opts.max }, resolved),\n );\n }\n return out;\n};\n","/**\n * Pure colour math for palette step + variant synthesis.\n *\n * Lightness / hue / chroma work runs in **OKLCH** (a perceptual space) via Björn Ottosson's\n * public-domain matrices — parse → sRGB → linear → OKLab → OKLCH → apply → gamut-map → linear →\n * sRGB → quantize → serialize — so equal lightness steps look even and one lightness reads the same\n * across hues. hex / `rgba()` strings are only touched at the boundary (`parseColor` in,\n * `serializeColor` out). `lighten` / `darken` shift OKLCH lightness by ΔL points; `setL` places an\n * absolute lightness; `rotateHue` / `complement` turn the hue; `alpha` sets opacity. All are\n * string-in / string-out so the same fns run at normalize time (baking the cached value) and later\n * in the derivation registry — AND are vendored to consumers (see `build/vendor.ts`) so a value\n * computed live in the app matches the emitted CSS variable. Kept dependency-free for that vendoring.\n */\n\n/** An `[r, g, b]` channel triple, each `0–255`. */\nexport type RGBTuple = readonly [number, number, number];\n\n/** An `[r, g, b, a]` quad — channels `0–255`, alpha `0–1`. */\nexport type RGBATuple = readonly [number, number, number, number];\n\n/** A colour authored/worked as a tuple — opaque `[r,g,b]` or translucent `[r,g,b,a]`. */\nexport type ColorTuple = RGBTuple | RGBATuple;\n\nconst HEX_LENGTHS = new Set([3, 6]);\n\nconst clamp = (value: number, min: number, max: number): number => Math.min(max, Math.max(min, value));\nconst clampChannel = (value: number): number => clamp(value, 0, 255);\nconst clampAlpha = (value: number): number => clamp(value, 0, 1);\nconst clampPercent = (percent: number): number => clamp(percent, 0, 100);\n\n/** Round to `dp` decimal places (tidy CSS output — `71.8`, not `71.79999`). */\nconst roundTo = (value: number, dp: number): number => {\n const f = 10 ** dp;\n return Math.round(value * f) / f;\n};\n\n/** Round an alpha to 3 decimals so serialized `rgba()` stays tidy (`0.4`, not `0.4000001`). */\nconst roundAlpha = (a: number): number => Math.round(clampAlpha(a) * 1000) / 1000;\n\n/** Parse a 3- or 6-digit hex string (with or without `#`) into an `[r, g, b]` tuple. */\nexport const convertHexToRGB = (hex: string): RGBTuple => {\n const sanitized = hex.replace(/^\\s*#|\\s*$/g, \"\");\n\n if (!HEX_LENGTHS.has(sanitized.length)) {\n // Plain Error on purpose: this module is vendored import-free (build/vendor.ts) so it can be\n // transpiled standalone into consumer bundles — it cannot import RefractError. Its parse errors are\n // re-thrown as REFRACT_E_COLOR_INPUT by colors/normalize.ts, which is the coded authoring surface.\n throw new Error(`Unsupported hex length: \"${sanitized}\". Use 3 or 6 digits.`);\n }\n\n const normalized = sanitized.length === 3 ? sanitized.replace(/(.)/g, \"$1$1\") : sanitized;\n\n return [\n parseInt(normalized.substring(0, 2), 16),\n parseInt(normalized.substring(2, 4), 16),\n parseInt(normalized.substring(4, 6), 16),\n ] as RGBTuple;\n};\n\n/** Serialize an `[r, g, b]` tuple back to a `#rrggbb` string, clamping each channel to `0–255`. */\nexport const convertRgbToHex = (rgb: RGBTuple): string => {\n if (rgb.length !== 3) {\n throw new Error(`Expected RGB tuple of length 3, received ${rgb.length}`);\n }\n\n const hex = rgb\n .map(value => {\n const next = clampChannel(Math.round(value)).toString(16);\n return next.length === 1 ? `0${next}` : next;\n })\n .join(\"\");\n\n return `#${hex}`;\n};\n\nconst RGB_FN = /^rgba?\\(\\s*([\\d.]+)\\s*,\\s*([\\d.]+)\\s*,\\s*([\\d.]+)\\s*(?:,\\s*([\\d.]+)\\s*)?\\)$/i;\n\n/**\n * Parse any canonical colour string this subsystem produces — a 3/6-digit hex **or** an\n * `rgb()` / `rgba()` string — into `{ rgb, a }` (alpha defaults to `1`). This is the boundary\n * gate; a value that isn't parseable rgb (e.g. a bare CSS keyword or `var(--…)`) throws, so\n * callers can surface a friendly \"this colour can't be derived from\" error.\n */\nexport const parseColor = (value: string): { rgb: RGBTuple; a: number } => {\n const trimmed = value.trim();\n\n const fn = RGB_FN.exec(trimmed);\n if (fn) {\n return {\n rgb: [Number(fn[1]), Number(fn[2]), Number(fn[3])] as RGBTuple,\n a: fn[4] === undefined ? 1 : roundAlpha(Number(fn[4])),\n };\n }\n\n return { rgb: convertHexToRGB(trimmed), a: 1 };\n};\n\n/**\n * Serialize `[r, g, b]` (+ optional alpha) to the canonical CSS string — always `rgb(r, g, b)`\n * when fully opaque, else `rgba(r, g, b, a)`. The single serialization point for the subsystem, so\n * the Model (and every adapter + `resolveToken`) always carries one canonical `rgb()/rgba()` form\n * per colour — never hex. (`convertRgbToHex` remains for the vendored consumer helper + input parsing.)\n */\nexport const serializeColor = (rgb: RGBTuple, a = 1): string => {\n const alpha = roundAlpha(a);\n const [r, g, b] = rgb;\n const R = clampChannel(Math.round(r));\n const G = clampChannel(Math.round(g));\n const B = clampChannel(Math.round(b));\n return alpha >= 1 ? `rgb(${R}, ${G}, ${B})` : `rgba(${R}, ${G}, ${B}, ${alpha})`;\n};\n\nconst HEX_RE = /^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/;\n\n/** Whether a string is a 3- or 6-digit `#`-prefixed hex colour. */\nexport const isHexColor = (value: string): boolean => HEX_RE.test(value.trim());\n\n\n// ─── OKLCH synthesis (Björn Ottosson public-domain matrices) ──────────────────────────────────\n// Lightness / hue / chroma adjustments happen here, in a perceptual space, so equal ΔL steps look\n// even and one lightness reads consistently across hues. `L` is carried on a 0–100 scale (matching\n// the authoring dials); OKLab's native `L` is 0–1. sRGB channels are 0–255 only at the boundary.\n\n/** An OKLCH colour — perceptual lightness `L` (0–100), chroma `C` (≥ 0), hue `h` (degrees, 0–360). */\nexport type OKLCH = { L: number; C: number; h: number };\n\nconst DEG = 180 / Math.PI;\nconst GAMUT_EPS = 1e-6;\nconst GAMUT_ITERATIONS = 24;\n\n/** sRGB channel (0–1) → linear-light (0–1). */\nconst srgbToLinear = (c: number): number =>\n c <= 0.04045 ? c / 12.92 : Math.pow((c + 0.055) / 1.055, 2.4);\n\n/** Linear-light channel (0–1) → sRGB (0–1). */\nconst linearToSrgb = (c: number): number =>\n c >= 0.0031308 ? 1.055 * Math.pow(c, 1 / 2.4) - 0.055 : 12.92 * c;\n\n/** Linear-sRGB `[r, g, b]` (0–1) → OKLab `{ L: 0–1, a, b }`. */\nconst linearRgbToOklab = (\n lr: number,\n lg: number,\n lb: number,\n): { L: number; a: number; b: number } => {\n const l = 0.4122214708 * lr + 0.5363325363 * lg + 0.0514459929 * lb;\n const m = 0.2119034982 * lr + 0.6806995451 * lg + 0.1073969566 * lb;\n const s = 0.0883024619 * lr + 0.2817188376 * lg + 0.6299787005 * lb;\n const l_ = Math.cbrt(l);\n const m_ = Math.cbrt(m);\n const s_ = Math.cbrt(s);\n return {\n L: 0.2104542553 * l_ + 0.793617785 * m_ - 0.0040720468 * s_,\n a: 1.9779984951 * l_ - 2.428592205 * m_ + 0.4505937099 * s_,\n b: 0.0259040371 * l_ + 0.7827717662 * m_ - 0.808675766 * s_,\n };\n};\n\n/** OKLab `{ L: 0–1, a, b }` → linear-sRGB `[r, g, b]` (may fall outside 0–1 when out of gamut). */\nconst oklabToLinearRgb = (L: number, a: number, b: number): [number, number, number] => {\n const l_ = L + 0.3963377774 * a + 0.2158037573 * b;\n const m_ = L - 0.1055613458 * a - 0.0638541728 * b;\n const s_ = L - 0.0894841775 * a - 1.291485548 * b;\n const l = l_ * l_ * l_;\n const m = m_ * m_ * m_;\n const s = s_ * s_ * s_;\n return [\n 4.0767416621 * l - 3.3077115913 * m + 0.2309699292 * s,\n -1.2684380046 * l + 2.6097574011 * m - 0.3413193965 * s,\n -0.0041960863 * l - 0.7034186147 * m + 1.707614701 * s,\n ];\n};\n\n/** Convert an sRGB `[r, g, b]` (0–255) triple to OKLCH (`L` on a 0–100 scale). */\nexport const rgbToOklch = (rgb: RGBTuple): OKLCH => {\n const [r, g, b] = rgb;\n const lab = linearRgbToOklab(srgbToLinear(r / 255), srgbToLinear(g / 255), srgbToLinear(b / 255));\n const C = Math.sqrt(lab.a * lab.a + lab.b * lab.b);\n let h = Math.atan2(lab.b, lab.a) * DEG;\n if (h < 0) h += 360;\n return { L: lab.L * 100, C, h };\n};\n\n/**\n * Convert OKLCH back to an sRGB `[r, g, b]` triple (**unquantized** 0–255 floats). Holds `L` and\n * `h`; when the requested chroma is outside sRGB it binary-searches `C` downward — fixed iterations,\n * no data-dependent early exit, so build- and runtime-computed values agree (§20.8) — until the\n * linear result is in `[0, 1]`. Lightness and hue are never adjusted, so a synthesized ramp keeps\n * its hue and even lightness spacing; only saturation gives way at the gamut boundary. The floats\n * are quantized exactly once, later, by `serializeColor`, so the 0–255 channel clamp never fires.\n */\nexport const oklchToRgb = (color: OKLCH): RGBTuple => {\n const L = clamp(color.L, 0, 100) / 100;\n const hr = color.h / DEG;\n const cosh = Math.cos(hr);\n const sinh = Math.sin(hr);\n\n const linearAt = (c: number): [number, number, number] => oklabToLinearRgb(L, c * cosh, c * sinh);\n const inGamut = (lin: [number, number, number]): boolean =>\n lin.every(v => v >= -GAMUT_EPS && v <= 1 + GAMUT_EPS);\n\n let lin = linearAt(color.C);\n if (!inGamut(lin)) {\n // `C = 0` (a neutral grey at this L) is always in gamut, so `lo` starts from a valid floor.\n let lo = 0;\n let hi = color.C;\n for (let i = 0; i < GAMUT_ITERATIONS; i++) {\n const mid = (lo + hi) / 2;\n if (inGamut(linearAt(mid))) lo = mid;\n else hi = mid;\n }\n lin = linearAt(lo);\n }\n\n return [\n linearToSrgb(clamp(lin[0], 0, 1)) * 255,\n linearToSrgb(clamp(lin[1], 0, 1)) * 255,\n linearToSrgb(clamp(lin[2], 0, 1)) * 255,\n ] as RGBTuple;\n};\n\n/** Run a colour string through OKLCH, apply `transform`, and re-serialize (alpha preserved). */\nconst withOklch = (value: string, transform: (lch: OKLCH) => OKLCH): string => {\n const { rgb, a } = parseColor(value);\n return serializeColor(oklchToRgb(transform(rgbToOklch(rgb))), a);\n};\n\n/** Lighten a colour by `delta` OKLCH lightness points (0–100 scale); hue, chroma, alpha preserved. */\nexport const lighten = (value: string, delta: number): string =>\n withOklch(value, lch => ({ ...lch, L: clamp(lch.L + delta, 0, 100) }));\n\n/** Darken a colour by `delta` OKLCH lightness points (0–100 scale); hue, chroma, alpha preserved. */\nexport const darken = (value: string, delta: number): string =>\n withOklch(value, lch => ({ ...lch, L: clamp(lch.L - delta, 0, 100) }));\n\n/** Set a colour's absolute OKLCH lightness to `L` (0–100); hue, chroma, alpha preserved. */\nexport const setL = (value: string, L: number): string =>\n withOklch(value, lch => ({ ...lch, L: clamp(L, 0, 100) }));\n\n/** Rotate a colour's OKLCH hue by `deg` (signed) around the perceptual wheel; L, C, alpha preserved. */\nexport const rotateHue = (value: string, deg: number): string =>\n withOklch(value, lch => ({ ...lch, h: (((lch.h + deg) % 360) + 360) % 360 }));\n\n/** The perceptual complement — a 180° hue rotation at the same lightness and chroma. */\nexport const complement = (value: string): string => rotateHue(value, 180);\n\n/**\n * An `adjust` dial set — any subset. `l` = **absolute** OKLCH lightness target (0–100, raw L, the\n * opposite direction from a numeric-`steps` label); `c` = chroma **multiplier** (`1` keep, `0` grey,\n * `>1` more saturated where the gamut allows); `h` = **signed** hue rotation in degrees. Numbers\n * only — keeps the vendored math string-free.\n */\nexport type AdjustDials = { l?: number; c?: number; h?: number };\n\n/**\n * One-shot OKLCH placement — set an absolute lightness, scale chroma, and/or rotate hue in a single\n * derivation (each dial optional; an omitted dial leaves that component untouched). Alpha preserved.\n */\nexport const adjust = (value: string, dials: AdjustDials): string =>\n withOklch(value, lch => ({\n L: dials.l === undefined ? lch.L : clamp(dials.l, 0, 100),\n C: dials.c === undefined ? lch.C : Math.max(0, lch.C * dials.c),\n h: dials.h === undefined ? lch.h : (((lch.h + dials.h) % 360) + 360) % 360,\n }));\n\n/**\n * Convert any canonical colour string (the subsystem's `rgb()` / `rgba()` form, or a hex string)\n * to hex — 6-digit `#rrggbb` when opaque, 8-digit `#rrggbbaa` when translucent. Used by the DTCG\n * exporter, whose `color` token type is conventionally hex (every other output stays `rgb()`).\n */\nexport const toHexColor = (value: string): string => {\n const { rgb, a } = parseColor(value);\n const hex = convertRgbToHex(rgb);\n if (a >= 1) return hex;\n const aa = clampChannel(Math.round(a * 255)).toString(16).padStart(2, \"0\");\n return `${hex}${aa}`;\n};\n\n/**\n * Convert any canonical colour string (the subsystem's `rgb()` / `rgba()` form, or a hex string) to\n * a CSS Color 4 `oklch(L% C H)` string — `oklch(L% C H / a)` when translucent. `L` is a percentage\n * (0–100), `C` the absolute chroma, `H` in degrees, derived from the stored (quantized) rgb. Used by\n * the CSS adapter's `colorFormat: \"oklch\"` output; the colour is identical to the `rgb()` form.\n */\nexport const toOklchColor = (value: string): string => {\n const { rgb, a } = parseColor(value);\n const { L, C, h } = rgbToOklch(rgb);\n const body = `${roundTo(L, 2)}% ${roundTo(C, 4)} ${roundTo(h, 2)}`;\n return a >= 1 ? `oklch(${body})` : `oklch(${body} / ${roundAlpha(a)})`;\n};\n\n/**\n * Set a colour's opacity to `percent` (0–100) — an **absolute** alpha, not a relative fade\n * (`alpha(x, 40)` ⇒ 40% opaque). The rgb channels are untouched; only the alpha channel is\n * replaced. Result serializes to `rgba(…)` (or hex when `percent` is 100).\n */\nexport const alpha = (value: string, percent: number): string => {\n const { rgb } = parseColor(value);\n return serializeColor(rgb, clampPercent(percent) / 100);\n};\n","/**\n * The CSS named colours (CSS Color Module Level 4 `<named-color>` list), mapped to their canonical\n * 6-digit hex. Authored colours may be given by keyword (`rebeccapurple`, `tomato`, …); the input\n * gate normalizes them to the subsystem's canonical `rgb()` form like any other input.\n *\n * `transparent` and `currentColor` are intentionally absent — neither is an opaque, tonally-derivable\n * colour, so they fall through to the input gate's rejection with a clear message.\n */\nexport const CSS_COLOR_KEYWORDS: Record<string, string> = {\n aliceblue: \"#f0f8ff\", antiquewhite: \"#faebd7\", aqua: \"#00ffff\", aquamarine: \"#7fffd4\",\n azure: \"#f0ffff\", beige: \"#f5f5dc\", bisque: \"#ffe4c4\", black: \"#000000\",\n blanchedalmond: \"#ffebcd\", blue: \"#0000ff\", blueviolet: \"#8a2be2\", brown: \"#a52a2a\",\n burlywood: \"#deb887\", cadetblue: \"#5f9ea0\", chartreuse: \"#7fff00\", chocolate: \"#d2691e\",\n coral: \"#ff7f50\", cornflowerblue: \"#6495ed\", cornsilk: \"#fff8dc\", crimson: \"#dc143c\",\n cyan: \"#00ffff\", darkblue: \"#00008b\", darkcyan: \"#008b8b\", darkgoldenrod: \"#b8860b\",\n darkgray: \"#a9a9a9\", darkgreen: \"#006400\", darkgrey: \"#a9a9a9\", darkkhaki: \"#bdb76b\",\n darkmagenta: \"#8b008b\", darkolivegreen: \"#556b2f\", darkorange: \"#ff8c00\", darkorchid: \"#9932cc\",\n darkred: \"#8b0000\", darksalmon: \"#e9967a\", darkseagreen: \"#8fbc8f\", darkslateblue: \"#483d8b\",\n darkslategray: \"#2f4f4f\", darkslategrey: \"#2f4f4f\", darkturquoise: \"#00ced1\", darkviolet: \"#9400d3\",\n deeppink: \"#ff1493\", deepskyblue: \"#00bfff\", dimgray: \"#696969\", dimgrey: \"#696969\",\n dodgerblue: \"#1e90ff\", firebrick: \"#b22222\", floralwhite: \"#fffaf0\", forestgreen: \"#228b22\",\n fuchsia: \"#ff00ff\", gainsboro: \"#dcdcdc\", ghostwhite: \"#f8f8ff\", gold: \"#ffd700\",\n goldenrod: \"#daa520\", gray: \"#808080\", green: \"#008000\", greenyellow: \"#adff2f\",\n grey: \"#808080\", honeydew: \"#f0fff0\", hotpink: \"#ff69b4\", indianred: \"#cd5c5c\",\n indigo: \"#4b0082\", ivory: \"#fffff0\", khaki: \"#f0e68c\", lavender: \"#e6e6fa\",\n lavenderblush: \"#fff0f5\", lawngreen: \"#7cfc00\", lemonchiffon: \"#fffacd\", lightblue: \"#add8e6\",\n lightcoral: \"#f08080\", lightcyan: \"#e0ffff\", lightgoldenrodyellow: \"#fafad2\", lightgray: \"#d3d3d3\",\n lightgreen: \"#90ee90\", lightgrey: \"#d3d3d3\", lightpink: \"#ffb6c1\", lightsalmon: \"#ffa07a\",\n lightseagreen: \"#20b2aa\", lightskyblue: \"#87cefa\", lightslategray: \"#778899\", lightslategrey: \"#778899\",\n lightsteelblue: \"#b0c4de\", lightyellow: \"#ffffe0\", lime: \"#00ff00\", limegreen: \"#32cd32\",\n linen: \"#faf0e6\", magenta: \"#ff00ff\", maroon: \"#800000\", mediumaquamarine: \"#66cdaa\",\n mediumblue: \"#0000cd\", mediumorchid: \"#ba55d3\", mediumpurple: \"#9370db\", mediumseagreen: \"#3cb371\",\n mediumslateblue: \"#7b68ee\", mediumspringgreen: \"#00fa9a\", mediumturquoise: \"#48d1cc\",\n mediumvioletred: \"#c71585\", midnightblue: \"#191970\", mintcream: \"#f5fffa\", mistyrose: \"#ffe4e1\",\n moccasin: \"#ffe4b5\", navajowhite: \"#ffdead\", navy: \"#000080\", oldlace: \"#fdf5e6\",\n olive: \"#808000\", olivedrab: \"#6b8e23\", orange: \"#ffa500\", orangered: \"#ff4500\",\n orchid: \"#da70d6\", palegoldenrod: \"#eee8aa\", palegreen: \"#98fb98\", paleturquoise: \"#afeeee\",\n palevioletred: \"#db7093\", papayawhip: \"#ffefd5\", peachpuff: \"#ffdab9\", peru: \"#cd853f\",\n pink: \"#ffc0cb\", plum: \"#dda0dd\", powderblue: \"#b0e0e6\", purple: \"#800080\",\n rebeccapurple: \"#663399\", red: \"#ff0000\", rosybrown: \"#bc8f8f\", royalblue: \"#4169e1\",\n saddlebrown: \"#8b4513\", salmon: \"#fa8072\", sandybrown: \"#f4a460\", seagreen: \"#2e8b57\",\n seashell: \"#fff5ee\", sienna: \"#a0522d\", silver: \"#c0c0c0\", skyblue: \"#87ceeb\",\n slateblue: \"#6a5acd\", slategray: \"#708090\", slategrey: \"#708090\", snow: \"#fffafa\",\n springgreen: \"#00ff7f\", steelblue: \"#4682b4\", tan: \"#d2b48c\", teal: \"#008080\",\n thistle: \"#d8bfd8\", tomato: \"#ff6347\", turquoise: \"#40e0d0\", violet: \"#ee82ee\",\n wheat: \"#f5deb3\", white: \"#ffffff\", whitesmoke: \"#f5f5f5\", yellow: \"#ffff00\",\n yellowgreen: \"#9acd32\",\n};\n","/**\n * Build-time colour **input** parsing.\n *\n * Kept out of `utils.ts` on purpose: `utils.ts` is vendored to consumers (see `build/vendor.ts`) and\n * must stay import-free, but input parsing needs the CSS-keyword table. `coerceColorInput` normalizes\n * any authored colour — hex, `[r, g, b]`, `oklch()`, `hsl()/hsla()`, `rgb()/rgba()`, or a CSS named\n * keyword — to the subsystem's canonical `rgb()` / `rgba()` form (derivation still runs in OKLCH). A\n * `var(--…)` (and `currentColor` / `transparent`) is rejected — none can be tonally derived at build.\n */\nimport { convertHexToRGB, oklchToRgb, parseColor, serializeColor, type RGBTuple } from \"./utils\";\nimport { CSS_COLOR_KEYWORDS } from \"./keywords\";\nimport { RefractError } from \"../../core/errors\";\n\nconst roundAlpha = (a: number): number => Math.round(Math.min(1, Math.max(0, a)) * 1000) / 1000;\n\n/** Convert HSL (`h` in degrees, `s` and `l` on `0–1`) to an sRGB `[r, g, b]` triple (0–255). */\nconst hslToRgb = (h: number, s: number, l: number): RGBTuple => {\n const hue = (((h % 360) + 360) % 360) / 60;\n const c = (1 - Math.abs(2 * Math.min(1, Math.max(0, l)) - 1)) * Math.min(1, Math.max(0, s));\n const x = c * (1 - Math.abs((hue % 2) - 1));\n const m = Math.min(1, Math.max(0, l)) - c / 2;\n const [r, g, b] =\n hue < 1 ? [c, x, 0] :\n hue < 2 ? [x, c, 0] :\n hue < 3 ? [0, c, x] :\n hue < 4 ? [0, x, c] :\n hue < 5 ? [x, 0, c] : [c, 0, x];\n return [(r + m) * 255, (g + m) * 255, (b + m) * 255] as RGBTuple;\n};\n\nconst OKLCH_STR = /^oklch\\(\\s*([\\d.]+)(%?)\\s+([\\d.]+)\\s+([\\d.]+)(?:deg)?\\s*(?:\\/\\s*([\\d.]+)(%?)\\s*)?\\)$/i;\nconst HSL_STR = /^hsla?\\(\\s*([\\d.]+)(?:deg)?\\s*[, ]\\s*([\\d.]+)%\\s*[, ]\\s*([\\d.]+)%\\s*(?:[,/]\\s*([\\d.]+)(%?)\\s*)?\\)$/i;\n\n/**\n * Parse an authored colour string into `{ rgb, a }`, or `null` if it isn't a colour this subsystem can\n * derive from. Tries `oklch()`, `hsl()/hsla()`, and CSS keywords, then falls back to {@link parseColor}\n * for hex / `rgb()/rgba()`. `oklch`/`hsl`/`rgba` alpha is preserved.\n */\nconst parseColorInput = (raw: string): { rgb: RGBTuple; a: number } | null => {\n const value = raw.trim();\n\n const ok = OKLCH_STR.exec(value);\n if (ok) {\n const L = ok[2] === \"%\" ? Number(ok[1]) : Number(ok[1]) * 100;\n const a = ok[5] === undefined ? 1 : roundAlpha(ok[6] === \"%\" ? Number(ok[5]) / 100 : Number(ok[5]));\n return { rgb: oklchToRgb({ L, C: Number(ok[3]), h: Number(ok[4]) }), a };\n }\n\n const hs = HSL_STR.exec(value);\n if (hs) {\n const a = hs[4] === undefined ? 1 : roundAlpha(hs[5] === \"%\" ? Number(hs[4]) / 100 : Number(hs[4]));\n return { rgb: hslToRgb(Number(hs[1]), Number(hs[2]) / 100, Number(hs[3]) / 100), a };\n }\n\n const keyword = CSS_COLOR_KEYWORDS[value.toLowerCase()];\n if (keyword) return { rgb: convertHexToRGB(keyword), a: 1 };\n\n // hex / rgb() / rgba() — parseColor throws on anything else, so a non-colour returns null.\n try {\n return parseColor(value);\n } catch {\n return null;\n }\n};\n\n/**\n * Coerce an authored colour value to the canonical `rgb(r, g, b)` / `rgba(…)` string. A colour may be a\n * hex string (`\"#4dabf7\"` / `\"#4af\"`), an `[r, g, b]` tuple (0–255), or any CSS colour — `oklch()`,\n * `hsl()/hsla()`, `rgb()/rgba()`, or a named keyword (`\"rebeccapurple\"`). Only a `var(--…)` (and\n * `currentColor` / `transparent`) is rejected. Applies to base + `text` + literal variants/modes.\n */\nexport const coerceColorInput = (value: string | RGBTuple): string => {\n if (typeof value === \"string\") {\n const parsed = parseColorInput(value);\n if (!parsed) {\n throw new RefractError(\n \"REFRACT_E_COLOR_INPUT\",\n `Invalid colour \"${value}\". Author a colour as a hex string (\"#4dabf7\"), an [r, g, b] tuple, ` +\n `or a CSS colour — oklch(), hsl()/hsla(), rgb()/rgba(), or a named keyword (e.g. \"rebeccapurple\"). ` +\n `A var(--…) can't be tonally derived at build time.`,\n );\n }\n return serializeColor(parsed.rgb, parsed.a);\n }\n\n if (!Array.isArray(value) || value.length !== 3 || value.some(n => typeof n !== \"number\")) {\n throw new RefractError(\n \"REFRACT_E_COLOR_TUPLE\",\n `Invalid colour tuple ${JSON.stringify(value)}. Use an [r, g, b] tuple with 0–255 channels (alpha comes from an \\`alpha\\` variant, not the base).`,\n );\n }\n\n const [r, g, b] = value;\n return serializeColor([r, g, b] as RGBTuple);\n};\n","/**\n * Colors' `normalizeProperty` hook — palette variant synthesis (§13).\n *\n * After the shared normalize pass, each palette colour synthesizes its variants:\n * - **auto variants** — numeric tonal `steps` (`100…900`) when declared, else the default named\n * set (`light` / `lighter` / `dark` / `darker`);\n * - **derivation-spec variants** — authored `{ darken | lighten | alpha, ref? }` (§13.3), each\n * resolved against its source (base by default, or another variant via `ref`).\n *\n * Every generated variant carries both its baked value (for the CSS lowering today) and `derive`\n * metadata (`{ ref, fn, arg }`) so the Model stores it as a derived `Ref` that re-resolves for free\n * when its source is overridden. All colour maths runs in rgb space (see `./utils`); a colour that\n * carries derivations must have a parseable rgb base (hex or `[r,g,b]`).\n */\n\nimport type {\n AdjustDials,\n HarmonyOption,\n NormalizedPaletteValue,\n PaletteDerivationSpec,\n PalettePropertyExtras,\n} from \"./types\";\nimport type { NormalizedModeOverride, NormalizedVariantValue } from \"../../core/normalize\";\nimport { lighten, darken, alpha, setL, rotateHue, adjust, parseColor } from \"./utils\";\nimport { coerceColorInput } from \"./colorInput\";\nimport { RefractError } from \"../../core/errors\";\n\ntype PaletteVariant = NormalizedVariantValue<string, PalettePropertyExtras>;\ntype PaletteMode = NormalizedModeOverride<string, PalettePropertyExtras>;\n\n/** Colors' derivation fns, by name — the same string-in/string-out fns the Model derivations use.\n * Each takes the opaque `arg` off the derivation Ref and coerces it (a number for the lightness/\n * hue/alpha fns; an {@link AdjustDials} object for `adjust`). */\nconst DERIVE_FNS: Record<string, (value: string, arg: unknown) => string> = {\n lighten: (v, a) => lighten(v, Number(a)),\n darken: (v, a) => darken(v, Number(a)),\n alpha: (v, a) => alpha(v, Number(a)),\n setL: (v, a) => setL(v, Number(a)),\n rotateHue: (v, a) => rotateHue(v, Number(a)),\n adjust: (v, a) => adjust(v, a as AdjustDials),\n};\n\n// Named-set steps are OKLCH ΔL points (§20.3). 10 keeps `lighter` a real tinted colour even on\n// already-light bases (Δ20 collapsed it to pure white) while still spanning a clear ±20 L ramp\n// across `lighter…darker` on mid-tone bases. Authors override per-colour via `lightenBy`/`darkenBy`.\nconst DEFAULT_LIGHTEN_BY = 10;\nconst DEFAULT_DARKEN_BY = 10;\n\nconst NAMED_LIGHTER_ORDER = [\"light\", \"lighter\"];\nconst NAMED_DARKER_ORDER = [\"dark\", \"darker\"];\n\n/**\n * dec.4 — whether a derivation `ref` sources ANOTHER property (a dotted `<subsystem>.<property>…`\n * path whose property prefix differs from the owning `colors.<propertyName>`). Such a source isn't\n * available during this property's single normalize pass, so it's deferred to the post-build\n * `bakeCrossPropertyDerivations` resolve pass. A bare name or a same-property dotted path is intra.\n */\nconst isCrossPropertyRef = (ref: string | undefined, propertyName: string): boolean => {\n if (!ref || !ref.includes(\".\")) return false;\n const [seg0, seg1] = ref.split(\".\");\n return `${seg0}.${seg1}` !== `colors.${propertyName}`;\n};\n\n/** Whether a value is a colour this subsystem can derive from (parseable as hex or `rgb(a)`). */\nconst isParseableColor = (value: string): boolean => {\n try {\n parseColor(value);\n return true;\n } catch {\n return false;\n }\n};\n\n/** Coerce+validate one `text` colour value, re-labelling the error with its token path. */\nconst coerceText = (value: unknown, path: string): string => {\n try {\n return coerceColorInput(value as string);\n } catch (error) {\n throw new RefractError(\"REFRACT_E_COLOR_INPUT\", `colors.${path}.text — ${(error as Error).message}`);\n }\n};\n\n/**\n * Coerce every `text` colour value on a normalized colour — the property itself, and any `text`\n * sibling on a literal variant or mode — to the canonical hex form (§13.1), so `text` obeys the\n * same hex/`[r,g,b]` rule as the base. Returns a structurally-shared copy (untouched fields keep\n * their references) so a colour with no `text` stays byte-identical.\n */\nconst coerceTextFields = (\n name: string,\n normalized: NormalizedPaletteValue,\n): NormalizedPaletteValue => {\n let next = normalized;\n\n if (normalized.text !== undefined) {\n next = { ...next, text: coerceText(normalized.text, name) };\n }\n\n if (normalized.variants) {\n let changed = false;\n const variants: Record<string, PaletteVariant> = {};\n for (const [key, variant] of Object.entries(normalized.variants)) {\n if (variant.text !== undefined) {\n variants[key] = { ...variant, text: coerceText(variant.text, `${name}.variants.${key}`) };\n changed = true;\n } else {\n variants[key] = variant;\n }\n }\n if (changed) next = { ...next, variants };\n }\n\n if (normalized.modes) {\n let changed = false;\n const modes = normalized.modes.map(mode => {\n if (mode.text !== undefined) {\n changed = true;\n return { ...mode, text: coerceText(mode.text, `${name}.modes.${mode.mode}`) };\n }\n return mode;\n });\n if (changed) next = { ...next, modes };\n }\n\n return next;\n};\n\n/**\n * Merge synthesized variants (auto + derivation-spec) and baked modes into a normalized palette\n * colour. Author-declared variants win over generated ones on name collision. Returns the input\n * unchanged when nothing is produced (a plain non-derivable colour stays byte-identical).\n *\n * @param name The colour's property name — used to build token paths (`colors.<name>.<v>`).\n * @param normalized The colour after the shared property normalize pass (base already coerced).\n * @param derivationSpecs Authored `{ darken|lighten|alpha, ref? }` variants, split out upstream\n * (core normalize can't interpret them — they have no `base`).\n */\nexport const finalizePaletteNormalization = (\n name: string,\n normalized0: NormalizedPaletteValue,\n derivationSpecs: Record<string, PaletteDerivationSpec> = {},\n): NormalizedPaletteValue => {\n // `text` is a colour value too — run it through the same input gate as the base (core doesn't\n // coerce extras). hex / tuple / oklch() / hsl() / rgb() / keyword all normalize to canonical rgb;\n // only a var(--…) throws with a path-labelled error.\n const normalized = coerceTextFields(name, normalized0);\n const baseParseable = isParseableColor(normalized.base);\n const hasSteps = !!(normalized.steps && normalized.steps.length);\n const hasDerivations = Object.keys(derivationSpecs).length > 0;\n const hasHarmony = normalized.harmony !== undefined;\n\n if ((hasSteps || hasDerivations || hasHarmony) && !baseParseable) {\n throw new RefractError(\n \"REFRACT_E_STEPS\",\n `colors.${name} declares derived steps/variants but its base \"${normalized.base}\" is not a hex or [r,g,b] colour.`,\n );\n }\n\n const autoVariants = baseParseable ? generateAutoVariants(normalized, name) : {};\n const harmonyVariants = baseParseable ? generateHarmonyVariants(normalized, name) : {};\n const plainVariants = normalized.variants ?? {};\n const known = { ...autoVariants, ...harmonyVariants, ...plainVariants };\n const derivedVariants = bakeDerivationVariants(name, normalized.base, known, derivationSpecs);\n\n // Precedence: generated auto + harmony variants first, then author variants (plain + derivation) win.\n const variants = { ...autoVariants, ...harmonyVariants, ...plainVariants, ...derivedVariants };\n const bakedModes = bakeDerivedModes(normalized, name, variants);\n const bakedResponsive = bakeResponsiveDerivations(normalized, name, variants);\n\n if (!Object.keys(variants).length && !bakedModes && !bakedResponsive) {\n return normalized;\n }\n\n return {\n ...normalized,\n ...(Object.keys(variants).length ? { variants } : {}),\n ...(bakedModes ? { modes: bakedModes } : {}),\n ...(bakedResponsive ? { responsive: bakedResponsive } : {}),\n };\n};\n\n/**\n * dec.5 — bake a colour's **responsive `ref` + `modifiers`** entries (swap-and-transform). A plain\n * `{ ref }` swap stays a var reference (untouched, handled by the CSS lowering). A `{ ref, modifiers }`\n * entry is folded here into a literal `base` override + `derive` metadata (source = the same-property\n * variant named by `ref`), exactly like a derivation-spec variant — so `override()` re-bakes it, and\n * the lowering writes the baked value (to `target`, default the base var) instead of a swap. Returns\n * `undefined` when nothing needed baking (so the property stays byte-identical).\n */\nconst bakeResponsiveDerivations = (\n normalized: NormalizedPaletteValue,\n propertyName: string,\n variants: Record<string, PaletteVariant>,\n): NormalizedPaletteValue[\"responsive\"] | undefined => {\n const responsive = normalized.responsive as unknown as Array<Record<string, unknown>> | undefined;\n if (!responsive || !responsive.length) return undefined;\n\n let changed = false;\n const out = responsive.map((entry, i) => {\n const ref = entry.ref as string | undefined;\n const rawModifiers = entry.modifiers;\n if (!ref || !Array.isArray(rawModifiers) || !rawModifiers.length) {\n // Coercion fix — a colour responsive override's literal value fields (`base` / `text`) go through\n // the same colour input gate as the property base/variants/modes (hex/tuple/keyword → canonical rgb).\n let coerced: Record<string, unknown> | undefined;\n for (const key of [\"base\", \"text\"]) {\n const v = entry[key];\n if (typeof v === \"string\" || Array.isArray(v)) {\n const next = coerceColorInput(v as string);\n if (next !== v) {\n coerced = coerced ?? { ...entry };\n coerced[key] = next;\n }\n }\n }\n if (coerced) changed = true;\n return coerced ?? entry;\n }\n\n const variant = variants[ref];\n if (!variant) {\n throw new RefractError(\"REFRACT_E_VARIANT_REF\", `colors.${propertyName}.responsive[${i}] references unknown variant \"${ref}\".`);\n }\n if (variant.base === undefined) {\n throw new RefractError(\"REFRACT_E_VARIANT_REF\", `colors.${propertyName}.responsive[${i}] references \"${ref}\", a cross-property derivation — not supported.`);\n }\n const modifiers = parseSpecModifiers({ modifiers: rawModifiers } as PaletteDerivationSpec, propertyName, `responsive[${i}]`);\n let value = variant.base;\n for (const mod of modifiers) value = DERIVE_FNS[mod.fn](value, mod.arg);\n\n changed = true;\n const { ref: _ref, modifiers: _mods, ...rest } = entry;\n return { ...rest, base: value, derive: { ref: `colors.${propertyName}.${ref}`, modifiers } };\n });\n\n return (changed ? out : responsive) as unknown as NormalizedPaletteValue[\"responsive\"];\n};\n\n/**\n * Bake a palette colour's **derived** appearance modes (§10.3). Core normalize records a derived\n * mode base as `{ derive: { fn, arg } }` (no source, unbaked); colors resolves it against the\n * colour's OWN base — `value = fn(base, arg)`, `ref = colors.<name>` — exactly like a tonal step,\n * so `override()` of the base re-bakes the mode for free. Literal modes pass through untouched.\n * Returns `undefined` when the colour has no modes (so the property stays byte-identical).\n */\nconst bakeDerivedModes = (\n normalized: NormalizedPaletteValue,\n propertyName: string,\n variants: Record<string, PaletteVariant>,\n): PaletteMode[] | undefined => {\n const modes = normalized.modes;\n if (!modes || !modes.length) return undefined;\n\n // dec.4 — resolve a mode derivation's SAME-PROPERTY source: the own base (default), or a variant /\n // step, addressed by bare name or by the fully-qualified `colors.<propertyName>.<name>` path.\n // A *cross-property* ref is intercepted upstream (baked post-build), so it never reaches here.\n const resolveSource = (ref: string | undefined, modeName: string): { value: string; path: string } => {\n if (!ref || ref === `colors.${propertyName}`) return { value: normalized.base, path: `colors.${propertyName}` };\n const name = ref.includes(\".\") ? ref.slice(`colors.${propertyName}.`.length) : ref;\n const variant = variants[name];\n if (!variant || variant.base === undefined) {\n throw new RefractError(\"REFRACT_E_VARIANT_REF\", `colors.${propertyName}.modes.${modeName} references unknown variant \"${ref}\".`);\n }\n return { value: variant.base, path: `colors.${propertyName}.${name}` };\n };\n\n return modes.map(mode => {\n const modeName = mode.mode;\n const derive = mode.derive;\n if (!derive) return mode; // literal mode (base and/or extras) — nothing to bake.\n\n // dec.2 — fold the modifier chain over the resolved source (dec.4). A legacy single `{ fn, arg }`\n // derive is treated as a one-element chain.\n const modifiers = derive.modifiers ?? (derive.fn ? [{ fn: derive.fn, arg: derive.arg }] : []);\n\n // dec.4 — a CROSS-property source (a dotted path outside this colour) can't be resolved during\n // this property's single normalize pass. Emit the mode UNBAKED (its `base` absent, `derive`\n // carrying the dotted ref + chain); the post-build `bakeCrossPropertyDerivations` pass fills the\n // value against the full token map. `buildModeFields` tolerates a base-less derived mode.\n if (isCrossPropertyRef(derive.ref, propertyName)) {\n const { base: _base, derive: _derive, ...rest } = mode;\n return { ...rest, derive: { ref: derive.ref, modifiers } } as PaletteMode;\n }\n\n const source = resolveSource(derive.ref, modeName);\n let value = source.value;\n for (const mod of modifiers) {\n const fn = DERIVE_FNS[mod.fn];\n if (!fn) {\n throw new RefractError(\n \"REFRACT_E_VARIANT_REF\",\n `Unknown derivation fn \"${mod.fn}\" for appearance mode \"colors.${propertyName}.modes.${modeName}\".`,\n );\n }\n value = fn(value, mod.arg);\n }\n return { ...mode, base: value, derive: { ref: source.path, modifiers } };\n });\n};\n\n/** Auto variants: numeric tonal `steps` when declared, else the default named tonal set. */\nconst generateAutoVariants = (\n palette: NormalizedPaletteValue,\n propertyName: string,\n): Record<string, PaletteVariant> => {\n if (palette.steps && palette.steps.length) {\n return generateNumericSteps(palette, propertyName);\n }\n return generateDefaultVariants(palette, propertyName);\n};\n\n/**\n * The built-in harmony schemes (§20.5) — each a list of `{ name, deg }` members, `deg` the signed\n * hue rotation off the base. Singular schemes get a real name (`complement`); symmetric pairs get\n * bare-numbered names ordered by rotation (a warm/cool label would lie — the temperature↔direction\n * mapping flips with the base hue). Tetradic reuses `complement` for its 180° member.\n */\nconst HARMONY_SCHEMES: Record<string, ReadonlyArray<{ name: string; deg: number }>> = {\n complement: [{ name: \"complement\", deg: 180 }],\n analogous: [\n { name: \"analogous1\", deg: -30 },\n { name: \"analogous2\", deg: 30 },\n ],\n \"split-complement\": [\n { name: \"split1\", deg: 150 },\n { name: \"split2\", deg: 210 },\n ],\n triadic: [\n { name: \"triadic1\", deg: 120 },\n { name: \"triadic2\", deg: 240 },\n ],\n tetradic: [\n { name: \"tetradic1\", deg: 90 },\n { name: \"complement\", deg: 180 },\n { name: \"tetradic2\", deg: 270 },\n ],\n};\n\n/**\n * Harmony variants (§20.5) — rotate the base's hue around the perceptual wheel to synthesize related\n * colours, each holding the base's lightness and chroma (only the hue turns, gamut-mapped by\n * `rotateHue`). The string form uses default member names; the object form renames them positionally\n * (`{ triadic: [\"mint\", \"coral\"] }`). Each variant is a re-derivable `{ ref, fn:\"rotateHue\", arg }`,\n * so `override()` of the base re-generates the set for free. Returns `{}` when no `harmony`.\n */\nconst generateHarmonyVariants = (\n palette: NormalizedPaletteValue,\n propertyName: string,\n): Record<string, PaletteVariant> => {\n const harmony = palette.harmony as HarmonyOption | undefined;\n if (harmony === undefined) return {};\n\n let scheme: string;\n let renames: string[] | undefined;\n if (typeof harmony === \"string\") {\n scheme = harmony;\n } else if (typeof harmony === \"object\" && harmony !== null && !Array.isArray(harmony)) {\n const keys = Object.keys(harmony);\n if (keys.length !== 1) {\n throw new RefractError(\n \"REFRACT_E_HARMONY\",\n `colors.${propertyName}.harmony object form must name exactly one scheme; got [${keys.join(\", \")}].`,\n );\n }\n scheme = keys[0];\n renames = (harmony as Record<string, string[]>)[scheme];\n } else {\n throw new RefractError(\"REFRACT_E_HARMONY\", `colors.${propertyName}.harmony must be a scheme name or a { scheme: [names] } object.`);\n }\n\n const members = HARMONY_SCHEMES[scheme];\n if (!members) {\n throw new RefractError(\n \"REFRACT_E_HARMONY\",\n `colors.${propertyName}.harmony: unknown scheme \"${scheme}\". Use one of ${Object.keys(HARMONY_SCHEMES).join(\", \")}.`,\n );\n }\n\n const result: Record<string, PaletteVariant> = {};\n members.forEach((member, i) => {\n const variantName = renames?.[i] ?? member.name;\n result[variantName] = {\n base: rotateHue(palette.base, member.deg),\n derive: { ref: `colors.${propertyName}`, fn: \"rotateHue\", arg: member.deg },\n } as PaletteVariant;\n });\n return result;\n};\n\n/** A single lighten/darken chain — each step compounds from the previous (base for the first). */\nconst buildChain = (\n result: Record<string, PaletteVariant>,\n palette: NormalizedPaletteValue,\n propertyName: string,\n existingVariants: Record<string, PaletteVariant>,\n chainSteps: string[],\n fn: (value: string, percent: number) => string,\n fnName: string,\n amount: number,\n): void => {\n const tokenPath = (variant?: string): string =>\n variant ? `colors.${propertyName}.${variant}` : `colors.${propertyName}`;\n\n let prev = palette.base;\n let prevName: string | undefined; // undefined = the base token\n for (const step of chainSteps) {\n if (existingVariants[step]?.base !== undefined) {\n prev = existingVariants[step].base as string;\n prevName = step;\n continue;\n }\n const value = fn(prev, amount);\n result[step] = {\n base: value,\n derive: { ref: tokenPath(prevName), fn: fnName, arg: amount },\n } as PaletteVariant;\n prev = value;\n prevName = step;\n }\n};\n\n/** The default named tonal variants (`light`/`lighter` + `dark`/`darker`), each compounding. */\nconst generateDefaultVariants = (\n palette: NormalizedPaletteValue,\n propertyName: string,\n): Record<string, PaletteVariant> => {\n const existingVariants = palette.variants ?? {};\n const result: Record<string, PaletteVariant> = {};\n\n const lightenAmount = palette.lightenBy ?? DEFAULT_LIGHTEN_BY;\n const darkenAmount = palette.darkenBy ?? DEFAULT_DARKEN_BY;\n\n buildChain(result, palette, propertyName, existingVariants, NAMED_LIGHTER_ORDER, lighten, \"lighten\", lightenAmount);\n buildChain(result, palette, propertyName, existingVariants, NAMED_DARKER_ORDER, darken, \"darken\", darkenAmount);\n\n return result;\n};\n\n/**\n * Map a numeric ladder label to an absolute OKLCH lightness (§20.2): `L = (1000 − label) / 10`, so\n * low labels are light and high labels dark. `0` / `1000` are reserved for pure white / black; every\n * other label clamps to `[5, 98]` so a mid-ladder rung never collapses to pure white or black.\n */\nconst labelToL = (label: number): number => {\n if (label <= 0) return 100;\n if (label >= 1000) return 0;\n return Math.min(98, Math.max(5, (1000 - label) / 10));\n};\n\n/**\n * Numeric tonal steps — an **absolute** OKLCH lightness ladder (§20.2). Each Tailwind-style label\n * maps to a fixed lightness via {@link labelToL}; the rung holds the base's hue and chroma (chroma\n * gamut-mapped) and sets that lightness, recorded as `{ ref, fn: \"setL\", arg: L }` so `override()`\n * of the base re-bakes the whole ladder for free. Because the lightness is absolute, the same label\n * reads at the same lightness across every palette. The exact authored colour stays at the\n * unnumbered `colors.<name>` token — a rung is never aliased to it, and `lightenBy`/`darkenBy` do\n * not apply. An author-declared variant of the same name wins over the generated rung. Throws on a\n * non-numeric or out-of-range (`0–1000`) label.\n */\nconst generateNumericSteps = (\n palette: NormalizedPaletteValue,\n propertyName: string,\n): Record<string, PaletteVariant> => {\n const steps = palette.steps ?? [];\n const bad = steps.find(s => typeof s !== \"number\" || isNaN(s) || s < 0 || s > 1000);\n if (bad !== undefined) {\n throw new RefractError(\n \"REFRACT_E_STEPS\",\n `colors.${propertyName}.steps must be numbers in 0–1000 (e.g. [50, …, 950]); got ${JSON.stringify(bad)}.`,\n );\n }\n\n const existingVariants = palette.variants ?? {};\n const result: Record<string, PaletteVariant> = {};\n\n for (const step of steps) {\n const label = step.toString();\n if (existingVariants[label]) continue; // an author-declared variant wins over the generated rung.\n const L = labelToL(step);\n result[label] = {\n base: setL(palette.base, L),\n derive: { ref: `colors.${propertyName}`, fn: \"setL\", arg: L },\n } as PaletteVariant;\n }\n\n return result;\n};\n\n/**\n * Validate + normalize an `adjust` dial set (§20.4). All dials optional and numeric: `l` absolute\n * lightness `0–100`; `c` a non-negative chroma multiplier; `h` a signed hue rotation. Returns a\n * clean `{ l?, c?, h? }` (dropping `undefined`s) so the stored `arg` is minimal.\n */\nconst parseAdjust = (raw: unknown, propertyName: string, variantName: string): AdjustDials => {\n const at = `colors.${propertyName}.variants.${variantName}.adjust`;\n if (typeof raw !== \"object\" || raw === null || Array.isArray(raw)) {\n throw new RefractError(\"REFRACT_E_ADJUST\", `${at} must be an object with numeric l / c / h dials.`);\n }\n const { l, c, h } = raw as Record<string, unknown>;\n const dials: AdjustDials = {};\n if (l !== undefined) {\n if (typeof l !== \"number\" || isNaN(l) || l < 0 || l > 100) {\n throw new RefractError(\"REFRACT_E_ADJUST\", `${at}.l must be an absolute OKLCH lightness in 0–100; got ${JSON.stringify(l)}.`);\n }\n dials.l = l;\n }\n if (c !== undefined) {\n if (typeof c !== \"number\" || isNaN(c) || c < 0) {\n throw new RefractError(\"REFRACT_E_ADJUST\", `${at}.c must be a non-negative chroma multiplier (1 keeps, 0 greys); got ${JSON.stringify(c)}.`);\n }\n dials.c = c;\n }\n if (h !== undefined) {\n if (typeof h !== \"number\" || isNaN(h)) {\n throw new RefractError(\"REFRACT_E_ADJUST\", `${at}.h must be a numeric hue rotation in degrees; got ${JSON.stringify(h)}.`);\n }\n dials.h = h;\n }\n return dials;\n};\n\n/**\n * dec.2 — parse a spec's `modifiers` chain into canonical `{ fn, arg }[]`. Each dial is a single-key\n * object (`{ darken: 10 }` → `{ fn: \"darken\", arg: 10 }`); `adjust` validates its dial object, the\n * scalar fns coerce to a number. An unknown fn is rejected against the colour-math registry.\n */\nconst parseSpecModifiers = (\n spec: PaletteDerivationSpec,\n propertyName: string,\n variantName: string,\n): Array<{ fn: string; arg: unknown }> => {\n const at = `colors.${propertyName}.variants.${variantName}`;\n const modifiers = spec.modifiers;\n if (!Array.isArray(modifiers) || modifiers.length === 0) {\n throw new RefractError(\"REFRACT_E_VARIANT\", `${at} needs a non-empty \"modifiers\" array (e.g. [{ darken: 10 }]).`);\n }\n return modifiers.map((m, i) => {\n if (typeof m !== \"object\" || m === null || Array.isArray(m)) {\n throw new RefractError(\"REFRACT_E_VARIANT\", `${at}.modifiers[${i}] must be a single-key object like { darken: 10 }.`);\n }\n const keys = Object.keys(m as Record<string, unknown>);\n if (keys.length !== 1) {\n throw new RefractError(\"REFRACT_E_VARIANT\", `${at}.modifiers[${i}] must have exactly one fn key; got [${keys.join(\", \")}].`);\n }\n const fn = keys[0];\n if (!DERIVE_FNS[fn]) {\n throw new RefractError(\"REFRACT_E_VARIANT\", `${at}.modifiers[${i}] unknown fn \"${fn}\"; use ${Object.keys(DERIVE_FNS).join(\" / \")}.`);\n }\n const raw = (m as Record<string, unknown>)[fn];\n const arg = fn === \"adjust\" ? parseAdjust(raw, propertyName, variantName) : Number(raw);\n return { fn, arg };\n });\n};\n\n/**\n * Bake authored derivation-spec variants (§13.3). Each resolves its source (`ref` → another\n * variant/step, or the base by default), applies the colour fn, and records `{ ref, fn, arg }`.\n * Specs may reference each other (a chain); resolution is lazy with cycle detection.\n */\nconst bakeDerivationVariants = (\n propertyName: string,\n base: string,\n known: Record<string, PaletteVariant>,\n specs: Record<string, PaletteDerivationSpec>,\n): Record<string, PaletteVariant> => {\n const result: Record<string, PaletteVariant> = {};\n const baking = new Set<string>();\n\n // A same-property source must have a baked base value; a cross-property-deferred variant (no base)\n // can't be a chain source in this single pass — surface that as a clear error rather than `undefined`.\n const baseOf = (variant: PaletteVariant, ref: string): string => {\n if (variant.base === undefined) {\n throw new RefractError(\n \"REFRACT_E_VARIANT_REF\",\n `colors.${propertyName} variant chains off \"${ref}\", which is a cross-property derivation — not supported.`,\n );\n }\n return variant.base;\n };\n const sourceOf = (ref: string | undefined): { value: string; path: string } => {\n if (!ref) return { value: base, path: `colors.${propertyName}` };\n if (result[ref]) return { value: baseOf(result[ref], ref), path: `colors.${propertyName}.${ref}` };\n if (known[ref]) return { value: baseOf(known[ref], ref), path: `colors.${propertyName}.${ref}` };\n if (specs[ref]) {\n bakeOne(ref, specs[ref]);\n return { value: baseOf(result[ref] as PaletteVariant, ref), path: `colors.${propertyName}.${ref}` };\n }\n throw new RefractError(\"REFRACT_E_VARIANT_REF\", `colors.${propertyName} variant references unknown source \"${ref}\".`);\n };\n\n function bakeOne(variantName: string, spec: PaletteDerivationSpec): void {\n if (result[variantName]) return;\n if (baking.has(variantName)) {\n throw new RefractError(\"REFRACT_E_CYCLE\", `Cyclic colour variant derivation at colors.${propertyName}.${variantName}.`);\n }\n baking.add(variantName);\n const modifiers = parseSpecModifiers(spec, propertyName, variantName);\n // dec.4 — a CROSS-property source is deferred: emit UNBAKED (no `base`), carrying the dotted ref\n // + chain. The post-build `bakeCrossPropertyDerivations` pass fills the value; `buildPropertyModel`\n // tolerates a base-less variant that carries a `derive.ref`.\n if (isCrossPropertyRef(spec.ref, propertyName)) {\n result[variantName] = { derive: { ref: spec.ref as string, modifiers } } as PaletteVariant;\n baking.delete(variantName);\n return;\n }\n const source = sourceOf(spec.ref);\n // dec.2 — fold the chain over the resolved source, in author order.\n let value = source.value;\n for (const m of modifiers) value = DERIVE_FNS[m.fn](value, m.arg);\n result[variantName] = { base: value, derive: { ref: source.path, modifiers } } as PaletteVariant;\n baking.delete(variantName);\n }\n\n for (const [variantName, spec] of Object.entries(specs)) bakeOne(variantName, spec);\n return result;\n};\n","/**\n * The set of known CSS property names, in kebab-case — the allow-list behind refract's fail-loud\n * recipe check. A recipe declaration whose key isn't a reserved recipe key (`variant`/`target`/…) and\n * isn't a known CSS property is almost always a typo (`ref:` for a variant swap, `colr:` for `color`)\n * that would otherwise pass through as literal CSS and ship silently. Rejecting it at build time turns\n * that class of mistake into an error — and the same predicate lets the docs pipeline reject an emitted\n * declaration whose property is not real CSS.\n *\n * Compact on purpose (a space-delimited string, split once) because this list rides in the runtime\n * `createTheme` path and counts toward the core size budget. Coverage is generous — standard properties\n * plus common logical/flex/grid/scroll/font families — so legitimate authoring never trips it. Custom\n * properties (`--*`) and vendor-prefixed names (`-webkit-…`) are accepted structurally by\n * {@link isKnownCssProperty}, so they need not appear here.\n */\nconst CSS_PROPERTY_NAMES =\n // layout / box model\n \"display position top right bottom left inset inset-block inset-block-start inset-block-end \" +\n \"inset-inline inset-inline-start inset-inline-end float clear z-index visibility overflow overflow-x \" +\n \"overflow-y overflow-block overflow-inline overflow-clip-margin overflow-anchor box-sizing \" +\n \"width height min-width min-height max-width max-height block-size inline-size min-block-size \" +\n \"min-inline-size max-block-size max-inline-size aspect-ratio \" +\n \"margin margin-top margin-right margin-bottom margin-left margin-block margin-block-start \" +\n \"margin-block-end margin-inline margin-inline-start margin-inline-end margin-trim \" +\n \"padding padding-top padding-right padding-bottom padding-left padding-block padding-block-start \" +\n \"padding-block-end padding-inline padding-inline-start padding-inline-end \" +\n // flexbox / grid\n \"flex flex-grow flex-shrink flex-basis flex-direction flex-flow flex-wrap order \" +\n \"justify-content justify-items justify-self align-content align-items align-self place-content \" +\n \"place-items place-self gap row-gap column-gap grid grid-area grid-template grid-template-areas \" +\n \"grid-template-columns grid-template-rows grid-auto-columns grid-auto-rows grid-auto-flow \" +\n \"grid-column grid-column-start grid-column-end grid-row grid-row-start grid-row-end \" +\n \"columns column-count column-width column-gap column-rule column-rule-color column-rule-style \" +\n \"column-rule-width column-span column-fill \" +\n // color / background\n \"color opacity accent-color caret-color color-scheme forced-color-adjust print-color-adjust \" +\n \"background background-color background-image background-position background-position-x \" +\n \"background-position-y background-size background-repeat background-origin background-clip \" +\n \"background-attachment background-blend-mode mix-blend-mode isolation \" +\n // border / outline\n \"border border-width border-style border-color border-top border-top-width border-top-style \" +\n \"border-top-color border-right border-right-width border-right-style border-right-color \" +\n \"border-bottom border-bottom-width border-bottom-style border-bottom-color border-left \" +\n \"border-left-width border-left-style border-left-color border-block border-block-width \" +\n \"border-block-style border-block-color border-block-start border-block-start-width \" +\n \"border-block-start-style border-block-start-color border-block-end border-block-end-width \" +\n \"border-block-end-style border-block-end-color border-inline border-inline-width \" +\n \"border-inline-style border-inline-color border-inline-start border-inline-start-width \" +\n \"border-inline-start-style border-inline-start-color border-inline-end border-inline-end-width \" +\n \"border-inline-end-style border-inline-end-color border-radius border-top-left-radius \" +\n \"border-top-right-radius border-bottom-right-radius border-bottom-left-radius \" +\n \"border-start-start-radius border-start-end-radius border-end-start-radius border-end-end-radius \" +\n \"border-image border-image-source border-image-slice border-image-width border-image-outset \" +\n \"border-image-repeat border-collapse border-spacing \" +\n \"outline outline-width outline-style outline-color outline-offset \" +\n // effects\n \"box-shadow filter backdrop-filter clip-path mask mask-image mask-mode mask-repeat mask-position \" +\n \"mask-clip mask-origin mask-size mask-composite mask-type opacity transform transform-origin \" +\n \"transform-box transform-style perspective perspective-origin backface-visibility rotate scale \" +\n \"translate \" +\n // transitions / animation\n \"transition transition-property transition-duration transition-timing-function transition-delay \" +\n \"transition-behavior animation animation-name animation-duration animation-timing-function \" +\n \"animation-delay animation-iteration-count animation-direction animation-fill-mode \" +\n \"animation-play-state animation-composition animation-timeline will-change \" +\n // typography\n \"font font-family font-size font-size-adjust font-weight font-style font-variant \" +\n \"font-variant-caps font-variant-numeric font-variant-ligatures font-variant-east-asian \" +\n \"font-variant-alternates font-variant-position font-feature-settings font-variation-settings \" +\n \"font-kerning font-stretch font-optical-sizing font-synthesis font-display line-height \" +\n \"letter-spacing word-spacing text-align text-align-last text-decoration text-decoration-line \" +\n \"text-decoration-color text-decoration-style text-decoration-thickness text-decoration-skip-ink \" +\n \"text-underline-offset text-underline-position text-transform text-indent text-overflow \" +\n \"text-shadow text-rendering text-wrap text-wrap-mode text-wrap-style text-emphasis \" +\n \"text-emphasis-color text-emphasis-style text-emphasis-position text-orientation text-combine-upright \" +\n \"text-justify white-space white-space-collapse word-break word-wrap overflow-wrap hyphens \" +\n \"hyphenate-character line-break tab-size vertical-align writing-mode direction unicode-bidi \" +\n \"quotes content list-style list-style-type list-style-position list-style-image counter-reset \" +\n \"counter-increment counter-set \" +\n // interactivity / ui\n \"cursor pointer-events user-select touch-action resize appearance caret scroll-behavior \" +\n \"scroll-margin scroll-margin-top scroll-margin-right scroll-margin-bottom scroll-margin-left \" +\n \"scroll-padding scroll-padding-top scroll-padding-right scroll-padding-bottom scroll-padding-left \" +\n \"scroll-snap-type scroll-snap-align scroll-snap-stop overscroll-behavior overscroll-behavior-x \" +\n \"overscroll-behavior-y scrollbar-width scrollbar-color scrollbar-gutter \" +\n // tables / svg / misc\n \"table-layout caption-side empty-cells vertical-align object-fit object-position image-rendering \" +\n \"fill fill-opacity fill-rule stroke stroke-width stroke-opacity stroke-linecap stroke-linejoin \" +\n \"stroke-dasharray stroke-dashoffset stroke-miterlimit paint-order shape-rendering stop-color \" +\n \"flood-color lighting-color \" +\n \"container container-type container-name contain content-visibility \" +\n \"break-before break-after break-inside page-break-before page-break-after page-break-inside orphans widows \" +\n \"all cx cy r rx ry d\";\n\n/** Known CSS property names (kebab-case). Membership test drives {@link isKnownCssProperty}. */\nexport const KNOWN_CSS_PROPERTIES: ReadonlySet<string> = new Set(CSS_PROPERTY_NAMES.split(\" \"));\n\nconst VENDOR_PREFIX = /^-(webkit|moz|ms|o)-/;\n\n/**\n * Is `name` a real CSS property? Accepts camelCase or kebab-case (`borderColor` / `border-color`),\n * custom properties (`--brand`), and vendor-prefixed names (`-webkit-mask`). Everything else — a\n * reserved recipe key that leaked, or a typo — is rejected so the caller can fail loud.\n */\nexport const isKnownCssProperty = (name: string): boolean => {\n if (name.startsWith(\"--\")) return true;\n const kebab = name\n .replace(/_/g, \"-\")\n .replace(/([a-z0-9])([A-Z])/g, \"$1-$2\")\n .toLowerCase();\n if (VENDOR_PREFIX.test(kebab)) return true;\n return KNOWN_CSS_PROPERTIES.has(kebab);\n};\n","/**\n * Colors' `interpretRecipe` hook — resolves palette recipe declarations to Refs.\n *\n * A palette recipe prop value either **names a palette reference** (`\"primary\"`,\n * `\"primary.text\"`, `\"neutral.light\"`) or is a literal. This interpreter emits a\n * format-neutral {@link Ref} for each declaration — a **canonical token path**\n * (`{ ref: \"colors.primary\", value: \"#4dabf7\" }`) for a reference, or `{ value }` for a\n * literal. It emits refs **directly** (no `var(--…)` strings); the CSS adapter maps the\n * token path to a `var(--…)` at render time. So `theme.model` carries no CSS syntax.\n */\nimport type { InterpretedRecipeVariant, InterpretedRecipeOverride, Ref } from \"../../core/model\";\nimport type { NormalizedRecipeVariant } from \"../../core/normalize\";\nimport type { RecipeInterpretContext } from \"../../core/subsystem\";\nimport { RefractError } from \"../../core/errors\";\nimport { isKnownCssProperty } from \"../../core/cssProperties\";\nimport type { NormalizedPaletteValue, PaletteRecipeProps, PaletteRecipeValue } from \"./types\";\n\nconst RESERVED_RECIPE_KEYS: ReadonlySet<string> = new Set([\n \"breakpoint\",\n \"query\",\n \"state\",\n \"variant\",\n \"target\",\n \"orientation\",\n]);\n\n/**\n * Interpret one palette recipe variant into base + responsive/state override declarations,\n * each a token-path {@link Ref}. Sibling `variant:` swaps inherit the sibling's base\n * declarations (via `ctx.resolveRecipeVariant`); a `target` may only scope to the variant\n * itself.\n */\nexport const interpretPaletteRecipeVariant = (\n variantName: string,\n variant: NormalizedRecipeVariant<PaletteRecipeProps, string>,\n ctx: RecipeInterpretContext,\n): InterpretedRecipeVariant<string> => {\n const path = `${ctx.groupPath}.${variantName}`;\n\n const base = interpretProps(variant.base, ctx, path);\n\n const responsive: InterpretedRecipeOverride<string>[] = variant.responsive.map(entry => {\n const { breakpoint, query, state, variant: swap, target, orientation, container, size, ...rawDecls } =\n entry as PaletteRecipeProps & {\n breakpoint?: string;\n query?: \"min\" | \"max\" | \"exact\";\n state?: string;\n variant?: string;\n target?: string;\n orientation?: \"landscape\" | \"portrait\";\n container?: string;\n size?: string;\n };\n\n const inherited = swap ? { ...ctx.resolveRecipeVariant(swap).base } : {};\n const overrides = interpretProps(rawDecls as PaletteRecipeProps, ctx, `${path}.responsive`);\n\n const override: InterpretedRecipeOverride<string> = {\n declarations: { ...inherited, ...overrides },\n };\n if (breakpoint) {\n override.breakpoint = breakpoint;\n override.query = query ?? \"exact\";\n }\n if (container) {\n override.container = container;\n if (size) override.size = size;\n override.query = query ?? \"min\";\n }\n if (state) override.state = state;\n if (orientation) override.orientation = orientation;\n if (target) override.target = target; // dec.8 — scope this override onto the `<item>-<target>` sibling\n return override;\n });\n\n return { base, responsive };\n};\n\n/** Interpret a flat declaration block → `formattedProperty → Ref`, skipping empty resolves. */\nconst interpretProps = (\n props: PaletteRecipeProps | undefined,\n ctx: RecipeInterpretContext,\n path: string,\n): Record<string, Ref> => {\n const declarations: Record<string, Ref> = {};\n if (!props) return declarations;\n\n for (const [property, value] of Object.entries(props)) {\n if (value === undefined || RESERVED_RECIPE_KEYS.has(property)) continue;\n // Fail loud on a key that is neither a reserved recipe key nor a real CSS property — otherwise a\n // typo (`ref:` meant as a `variant:` swap, `colr:` for `color`) would pass through as literal CSS\n // and ship silently. See {@link isKnownCssProperty}.\n if (!isKnownCssProperty(property)) {\n throw new RefractError(\n \"REFRACT_E_RECIPE_PROPERTY\",\n `Unknown recipe property \"${property}\" in ${path} — expected a CSS property or a reserved key ` +\n `(variant, target, state, breakpoint, query, orientation, container, size).`,\n );\n }\n const ref = resolvePaletteReference(value, ctx, path, property);\n if (ref === undefined) continue;\n declarations[formatPropertyName(property)] = ref;\n }\n\n return declarations;\n};\n\n/**\n * Resolve one palette recipe value to a {@link Ref}. Numbers + non-palette strings pass\n * through as literals; a `<name>[.<variant|text>]` reference resolves to a canonical token\n * path with its baked value alongside (for inline delivery). Throws on an unknown variant.\n */\nconst resolvePaletteReference = (\n value: PaletteRecipeValue,\n ctx: RecipeInterpretContext,\n path: string,\n property: string,\n): Ref | undefined => {\n if (typeof value === \"number\") return { value };\n\n const trimmed = value.trim();\n if (!trimmed) return undefined;\n\n const segments = trimmed.split(\".\");\n const name = segments[0];\n const palette = ctx.properties[name] as NormalizedPaletteValue | undefined;\n\n // Not a known palette colour → a literal declaration (passes through unchanged).\n if (!palette) return { value: trimmed };\n\n const subKey = segments.length > 1 ? segments.slice(1).join(\".\") : undefined;\n\n if (!subKey) return { ref: `colors.${name}` };\n\n if (subKey === \"text\") {\n return { ref: `colors.${name}.text` };\n }\n\n if (!palette.variants?.[subKey]) {\n throw new RefractError(\n \"REFRACT_E_VARIANT_REF\",\n `Unknown palette variant reference \"${name}.${subKey}\" in ${path}.${property}.`,\n );\n }\n\n return { ref: `colors.${name}.${subKey}` };\n};\n\n/** Format an authored property name to its CSS declaration name (`borderColor` → `border-color`). */\nconst formatPropertyName = (property: string): string => {\n if (property.startsWith(\"--\")) return property;\n return property\n .replace(/_/g, \"-\")\n .replace(/([a-z0-9])([A-Z])/g, \"$1-$2\")\n .toLowerCase();\n};\n","/**\n * Contrast audit (opt-in) — scores a built theme's colour pairings for **WCAG 2** contrast ratio\n * (the compliance standard) plus an **advisory APCA** Lc reading. It reports; it never mutates the\n * theme and never \"fixes\" a colour. `audit()` returns structured results by default; a caller (or the\n * `refract audit --strict` CLI) can throw on failures.\n *\n * Which pairings: every palette's `base` ↔ `text`, and every recipe's foreground (`color`) ↔\n * background (`background-color` / `background`) across all subsystems' rule-sets (base + state\n * overrides). A side that isn't a derivable colour (`transparent`, a `var()`, a keyword literal) is\n * reported as `skipped`, not a failure.\n *\n * Colour math is inlined here on purpose: `utils.ts` is vendored to consumers (`build/vendor.ts`) and\n * kept dependency-free / minimal, so we don't widen its export surface for a non-vendored sibling. We\n * reuse only the already-exported {@link parseColor}.\n */\nimport type { Theme, Ref } from \"../../core\";\nimport { RefractError } from \"../../core/errors\";\nimport { parseColor, type RGBTuple } from \"./utils\";\n\n// ── WCAG 2.x ──────────────────────────────────────────────────────────────\n// Relative luminance per WCAG 2: linearize each sRGB channel, weight by the luma coefficients.\nconst srgbToLinear = (c: number): number => (c <= 0.04045 ? c / 12.92 : Math.pow((c + 0.055) / 1.055, 2.4));\nconst relLuminance = ([r, g, b]: RGBTuple): number =>\n 0.2126 * srgbToLinear(r / 255) + 0.7152 * srgbToLinear(g / 255) + 0.0722 * srgbToLinear(b / 255);\n\n/** WCAG 2 contrast ratio (1–21) between two sRGB colours; order-independent. */\nconst wcagRatio = (a: RGBTuple, b: RGBTuple): number => {\n const la = relLuminance(a);\n const lb = relLuminance(b);\n const hi = Math.max(la, lb);\n const lo = Math.min(la, lb);\n return (hi + 0.05) / (lo + 0.05);\n};\n\nexport type WcagLevel = \"AAA\" | \"AA\" | \"AA-large\" | \"fail\";\nconst LEVEL_RANK: Record<WcagLevel, number> = { fail: 0, \"AA-large\": 1, AA: 2, AAA: 3 };\n\n/** Map a ratio to a level. For normal text 3–4.5 is \"AA-large\" (passes only at large sizes). */\nconst wcagLevel = (ratio: number, large: boolean): WcagLevel => {\n if (large) return ratio >= 4.5 ? \"AAA\" : ratio >= 3 ? \"AA\" : \"fail\";\n return ratio >= 7 ? \"AAA\" : ratio >= 4.5 ? \"AA\" : ratio >= 3 ? \"AA-large\" : \"fail\";\n};\n\n// ── APCA (advisory) ───────────────────────────────────────────────────────\n// APCA 0.1.9 / formula 0.98G-4g (SAPC). Advisory only — NOT a WCAG substitute — and the draft may\n// still shift, so the constants are pinned here. Returns a signed Lc (polarity-aware).\nconst APCA = {\n mainTRC: 2.4,\n sRco: 0.2126729, sGco: 0.7151522, sBco: 0.072175,\n normBG: 0.56, normTXT: 0.57, revTXT: 0.62, revBG: 0.65,\n blkThrs: 0.022, blkClmp: 1.414,\n scaleBoW: 1.14, loBoWoffset: 0.027,\n scaleWoB: 1.14, loWoBoffset: 0.027,\n deltaYmin: 0.0005, loClip: 0.1,\n} as const;\n\nconst apcaY = ([r, g, b]: RGBTuple): number =>\n APCA.sRco * Math.pow(r / 255, APCA.mainTRC) +\n APCA.sGco * Math.pow(g / 255, APCA.mainTRC) +\n APCA.sBco * Math.pow(b / 255, APCA.mainTRC);\n\n/** Signed APCA lightness contrast (Lc) of `text` over `bg`. Positive = dark-on-light, negative = light-on-dark. */\nconst apcaLc = (text: RGBTuple, bg: RGBTuple): number => {\n const clamp = (y: number): number => (y > APCA.blkThrs ? y : y + Math.pow(APCA.blkThrs - y, APCA.blkClmp));\n const yTxt = clamp(apcaY(text));\n const yBg = clamp(apcaY(bg));\n if (Math.abs(yBg - yTxt) < APCA.deltaYmin) return 0;\n let out: number;\n if (yBg > yTxt) {\n const sapc = (Math.pow(yBg, APCA.normBG) - Math.pow(yTxt, APCA.normTXT)) * APCA.scaleBoW;\n out = sapc < APCA.loClip ? 0 : sapc - APCA.loBoWoffset;\n } else {\n const sapc = (Math.pow(yBg, APCA.revBG) - Math.pow(yTxt, APCA.revTXT)) * APCA.scaleWoB;\n out = sapc > -APCA.loClip ? 0 : sapc + APCA.loWoBoffset;\n }\n return out * 100;\n};\n\n// ── audit ─────────────────────────────────────────────────────────────────\n\nexport type PairingKind = \"palette\" | \"recipe\";\n\nexport interface PairingScore {\n kind: PairingKind;\n /** Human label, e.g. `colors.brand` or `components.buttons.primary (:hover)`. */\n label: string;\n /** Resolved foreground colour string, or `undefined` when it isn't a derivable colour. */\n fg?: string;\n /** Resolved background colour string, or `undefined` when it isn't a derivable colour. */\n bg?: string;\n /** WCAG 2 contrast ratio (1–21, 2 dp). Absent when skipped. */\n wcagRatio?: number;\n /** WCAG level at the configured text size. Absent when skipped. */\n wcagLevel?: WcagLevel;\n /** Advisory APCA Lc (signed, 1 dp). Absent when skipped. */\n apcaLc?: number;\n /** Whether this pairing met the pass bar (`minWcag`). Absent when skipped. */\n pass?: boolean;\n /** Set when a side isn't a derivable colour — then the score fields are absent. */\n skipped?: string;\n}\n\nexport interface AuditOptions {\n /** Throw an aggregated error when any pairing fails, instead of only reporting. Default `false`. */\n strict?: boolean;\n /** Treat the foreground as large text (relaxed WCAG thresholds). Default `false`. */\n largeText?: boolean;\n /** The pass bar. Default `\"AA\"`. `\"AA-large\"` accepts the 3:1 tier. */\n minWcag?: WcagLevel;\n /** Audit component/recipe fg↔bg pairs. Default `true`. */\n includeRecipes?: boolean;\n /** Audit palette base↔text pairs. Default `true`. */\n includePalettes?: boolean;\n}\n\nexport interface AuditResult {\n pairings: PairingScore[];\n summary: {\n total: number;\n passed: number;\n failed: number;\n skipped: number;\n /** The lowest-ratio scored pairing (the worst offender), if any were scored. */\n worst?: PairingScore;\n };\n /** `true` when no scored pairing failed the pass bar. */\n ok: boolean;\n}\n\nconst round = (n: number, dp: number): number => {\n const f = 10 ** dp;\n return Math.round(n * f) / f;\n};\n\n/** Resolve a rule-set declaration `Ref` to a colour string, or `undefined` if it isn't one. */\nconst refToColor = (theme: Theme, ref: Ref): string | undefined => {\n if (ref.ref !== undefined) {\n try {\n return String(theme.resolveToken(ref.ref));\n } catch {\n return undefined;\n }\n }\n if (typeof ref.value === \"string\") return ref.value;\n return undefined;\n};\n\nconst FG_KEY = \"color\";\nconst BG_KEYS = [\"background-color\", \"background\"] as const;\nconst pickBg = (decls: Record<string, Ref> | undefined): Ref | undefined => {\n if (!decls) return undefined;\n for (const k of BG_KEYS) if (decls[k]) return decls[k];\n return undefined;\n};\n\n/** Score one fg/bg pairing (colours already resolved to strings), or a skipped record. */\nconst scorePair = (\n kind: PairingKind,\n label: string,\n fg: string | undefined,\n bg: string | undefined,\n options: Required<Pick<AuditOptions, \"largeText\" | \"minWcag\">>,\n): PairingScore => {\n let fgRgb: RGBTuple | undefined;\n let bgRgb: RGBTuple | undefined;\n try {\n if (fg !== undefined) fgRgb = parseColor(fg).rgb;\n } catch { /* not a derivable colour */ }\n try {\n if (bg !== undefined) bgRgb = parseColor(bg).rgb;\n } catch { /* not a derivable colour */ }\n\n if (!fgRgb || !bgRgb) {\n return { kind, label, fg, bg, skipped: !fgRgb && !bgRgb ? \"no derivable fg/bg\" : !fgRgb ? \"fg not a colour\" : \"bg not a colour\" };\n }\n\n const ratio = wcagRatio(fgRgb, bgRgb);\n const level = wcagLevel(ratio, options.largeText);\n const pass = LEVEL_RANK[level] >= LEVEL_RANK[options.minWcag];\n return {\n kind, label, fg, bg,\n wcagRatio: round(ratio, 2),\n wcagLevel: level,\n apcaLc: round(apcaLc(fgRgb, bgRgb), 1),\n pass,\n };\n};\n\n/**\n * Audit a built theme's colour pairings. Pure — reads `theme.tokens` / `theme.resolveToken` /\n * `theme.model` only. In `strict` mode, throws one aggregated error listing every failing pairing.\n */\nexport const audit = (theme: Theme, options: AuditOptions = {}): AuditResult => {\n const opts = {\n largeText: options.largeText ?? false,\n minWcag: options.minWcag ?? (\"AA\" as WcagLevel),\n };\n const includeRecipes = options.includeRecipes ?? true;\n const includePalettes = options.includePalettes ?? true;\n const pairings: PairingScore[] = [];\n\n // Palettes: base ↔ text. A palette advertises a pairing by having a `colors.<name>.text` token.\n if (includePalettes) {\n for (const path of Object.keys(theme.tokens)) {\n const m = /^colors\\.([^.]+)\\.text$/.exec(path);\n if (!m) continue;\n const base = `colors.${m[1]}`;\n let fg: string | undefined, bg: string | undefined;\n try { fg = String(theme.resolveToken(path)); } catch { /* skip */ }\n try { bg = String(theme.resolveToken(base)); } catch { /* skip */ }\n pairings.push(scorePair(\"palette\", base, fg, bg, opts));\n }\n }\n\n // Recipes: every subsystem's rule-sets — the base declarations + each state/breakpoint override.\n if (includeRecipes) {\n for (const [subsystem, subModel] of Object.entries(theme.model.subsystems)) {\n if (!subModel.ruleSets) continue;\n for (const [group, ruleSetGroup] of Object.entries(subModel.ruleSets)) {\n for (const [variant, ruleSet] of Object.entries(ruleSetGroup)) {\n const baseFg = ruleSet.declarations[FG_KEY];\n const baseBg = pickBg(ruleSet.declarations);\n const label = `${subsystem}.${group}.${variant}`;\n if (baseFg && baseBg) {\n pairings.push(scorePair(\"recipe\", label, refToColor(theme, baseFg), refToColor(theme, baseBg), opts));\n }\n // Overrides (e.g. :hover) can swap bg or fg — score the effective pairing at that condition.\n for (const override of ruleSet.overrides ?? []) {\n const oFg = override.declarations?.[FG_KEY] ?? baseFg;\n const oBg = pickBg(override.declarations) ?? baseBg;\n if (!override.declarations || (!override.declarations[FG_KEY] && !pickBg(override.declarations))) continue;\n if (!oFg || !oBg) continue;\n const cond = override.state ?? override.breakpoint ?? override.query ?? \"override\";\n pairings.push(scorePair(\"recipe\", `${label} (${cond})`, refToColor(theme, oFg), refToColor(theme, oBg), opts));\n }\n }\n }\n }\n }\n\n const scored = pairings.filter(p => !p.skipped);\n const failed = scored.filter(p => p.pass === false);\n const worst = scored.reduce<PairingScore | undefined>(\n (w, p) => (w === undefined || (p.wcagRatio ?? Infinity) < (w.wcagRatio ?? Infinity) ? p : w),\n undefined,\n );\n const result: AuditResult = {\n pairings,\n summary: {\n total: scored.length,\n passed: scored.length - failed.length,\n failed: failed.length,\n skipped: pairings.length - scored.length,\n worst,\n },\n ok: failed.length === 0,\n };\n\n if (options.strict && failed.length > 0) {\n const list = failed.map(p => `${p.label} (${p.wcagRatio}:1, ${p.wcagLevel})`).join(\", \");\n throw new RefractError(\n \"REFRACT_E_AUDIT\",\n `refract audit: ${failed.length} pairing(s) fail WCAG ${opts.minWcag} — ${list}. ` +\n `Adjust the colour(s), lower --min-wcag, or drop --strict to report without failing.`,\n failed.map(p => `${p.label} (${p.wcagRatio}:1, ${p.wcagLevel})`),\n );\n }\n\n return result;\n};\n","/**\n * The colors subsystem (Step 0d — properties only).\n *\n * Iterates `raw.colors` (skipping the reserved `recipes` key), running the shared\n * property normalize + colors' palette-step synthesis per colour. Recipes / CSS\n * lowering land in Step 1; this file grows a hook, never the spine.\n */\n\nimport type { Subsystem, NormalizedProperties } from \"../../core/subsystem\";\nimport type {\n NormalizedPropertyValue,\n NormalizedRecipeVariant,\n PropertyValue,\n} from \"../../core/normalize\";\nimport {\n normalizePropertyValue,\n validateNormalizedResponsiveRefs,\n} from \"../../core/normalize\";\nimport type {\n NormalizedPaletteValue,\n PaletteDerivationSpec,\n PalettePropertyExtras,\n PaletteRecipeProps,\n} from \"./types\";\nimport { finalizePaletteNormalization } from \"./normalize\";\nimport { interpretPaletteRecipeVariant } from \"./recipes\";\nimport type { AdjustDials } from \"./utils\";\nimport { lighten, darken, alpha, setL, rotateHue, adjust } from \"./utils\";\nimport { coerceColorInput } from \"./colorInput\";\n\n/** Sub-keys of `raw.colors` that are not palette properties. */\nconst RESERVED_KEYS: ReadonlySet<string> = new Set([\"recipes\"]);\n\n/** dec.2 — a `{ ref?, modifiers }` variant spec — must be split out before core normalize (no `base`). */\nconst isDerivationSpec = (value: unknown): value is PaletteDerivationSpec =>\n typeof value === \"object\" &&\n value !== null &&\n !Array.isArray(value) &&\n !(\"base\" in value) &&\n Array.isArray((value as { modifiers?: unknown }).modifiers);\n\n/**\n * Peel derivation-spec variants (`{ darken|lighten|alpha, ref? }`) out of an authored colour so\n * core normalize sees only literal/extended variants (it can't interpret a spec — it has no `base`).\n * Returns the colour with those variants removed, plus the extracted specs for colors to bake.\n */\nconst splitDerivationVariants = (\n value: unknown,\n): { value: unknown; specs: Record<string, PaletteDerivationSpec> } => {\n if (\n typeof value !== \"object\" ||\n value === null ||\n Array.isArray(value) ||\n !(value as { variants?: unknown }).variants\n ) {\n return { value, specs: {} };\n }\n\n const variants = (value as { variants: Record<string, unknown> }).variants;\n const specs: Record<string, PaletteDerivationSpec> = {};\n const plain: Record<string, unknown> = {};\n for (const [key, variant] of Object.entries(variants)) {\n if (isDerivationSpec(variant)) specs[key] = variant;\n else plain[key] = variant;\n }\n\n if (!Object.keys(specs).length) return { value, specs };\n\n const nextVariants = Object.keys(plain).length ? plain : undefined;\n return { value: { ...(value as object), variants: nextVariants }, specs };\n};\n\nexport const colorsSubsystem: Subsystem = {\n key: \"colors\",\n // The derivation fns colors records on its synthesized variants (`light`/`dark`/`ghost`/…). The\n // resolver hands each `(literal, arg)`; adapt to the colour-math `(value, percent)` signature.\n derivations: {\n lighten: (value, arg) => lighten(String(value), Number(arg)),\n darken: (value, arg) => darken(String(value), Number(arg)),\n alpha: (value, arg) => alpha(String(value), Number(arg)),\n setL: (value, arg) => setL(String(value), Number(arg)),\n rotateHue: (value, arg) => rotateHue(String(value), Number(arg)),\n adjust: (value, arg) => adjust(String(value), arg as AdjustDials),\n },\n normalizeProperties(rawSlice, ctx): NormalizedProperties {\n const out: NormalizedProperties = {};\n if (!rawSlice) return out;\n\n for (const [name, value] of Object.entries(rawSlice)) {\n if (RESERVED_KEYS.has(name)) continue;\n\n const { value: plainValue, specs } = splitDerivationVariants(value);\n // Specs are stripped above and a tuple base is coerced by `coerceValue`, so the residual is\n // core-shaped — cast to the core authoring type at this boundary.\n const normalized = normalizePropertyValue<string, PalettePropertyExtras>(\n plainValue as PropertyValue<string, PalettePropertyExtras>,\n {\n propertyPath: `colors.${name}`,\n allowedBreakpoints: ctx.allowedBreakpoints,\n coerceValue: coerceColorInput,\n },\n );\n const finalized = finalizePaletteNormalization(\n name,\n normalized as NormalizedPaletteValue,\n specs,\n );\n validateNormalizedResponsiveRefs(finalized as NormalizedPropertyValue<unknown>, {\n propertyPath: `colors.${name}`,\n });\n\n out[name] = finalized as NormalizedPropertyValue<unknown, Record<string, unknown>>;\n }\n\n return out;\n },\n interpretRecipe(variantName, variant, ctx) {\n return interpretPaletteRecipeVariant(\n variantName,\n variant as NormalizedRecipeVariant<PaletteRecipeProps, string>,\n ctx,\n );\n },\n};\n\nexport type { ColorsRaw } from \"./types\";\nexport { audit } from \"./audit\";\nexport type { AuditResult, AuditOptions, PairingScore, PairingKind, WcagLevel } from \"./audit\";\n","/**\n * Typography's `normalizeProperty` hook — modular font-size scale synthesis.\n *\n * When `fontSize` is authored with a `ratio`, this generates the scale steps\n * (`xs`…`4xl`) as variants — each `base * ratio^step` (or a custom `algorithm`),\n * rounded to `precision`. Author-declared steps are preserved and seed the chain.\n * Non-`fontSize` properties and ratio-less `fontSize` pass through untouched.\n */\n\nimport type { NormalizedPropertyValue, NormalizedVariantValue } from \"../../core/normalize\";\nimport type { FontSizeExtras, TypographyRatioKey, TypographyScaleKey } from \"./types\";\n\nconst TYPOGRAPHY_RATIOS: Record<TypographyRatioKey, number> = {\n \"minor-second\": 1.067,\n \"major-second\": 1.125,\n \"minor-third\": 1.2,\n \"major-third\": 1.25,\n \"perfect-fourth\": 1.333,\n \"augmented-fourth\": 1.414,\n \"perfect-fifth\": 1.5,\n golden: 1.618,\n};\n\nconst DEFAULT_SCALE_STEPS: Record<TypographyScaleKey, number> = {\n xs: -2,\n sm: -1,\n md: 0,\n lg: 1,\n xl: 2,\n \"2xl\": 3,\n \"3xl\": 4,\n \"4xl\": 5,\n};\n\nconst DEFAULT_PRECISION = 4;\n\ntype FontSizeVariant = NormalizedVariantValue<number, FontSizeExtras>;\n\n/**\n * The typography `normalizeProperty` hook. Synthesizes the modular scale for\n * `fontSize`; a pass-through for every other typography property.\n *\n * @param propertyKey The property being normalized (only `\"fontSize\"` is transformed).\n * @param normalized The property after the shared property normalize pass.\n */\nexport const finalizeTypographyNormalization = (\n propertyKey: string,\n normalized: NormalizedPropertyValue<unknown>,\n): NormalizedPropertyValue<unknown> => {\n if (propertyKey !== \"fontSize\") return normalized;\n return generateFontSizeScaleVariants(\n normalized as unknown as NormalizedPropertyValue<number, FontSizeExtras>,\n ) as unknown as NormalizedPropertyValue<unknown>;\n};\n\n/**\n * Build the `xs`…`4xl` scale variants from `base`, `ratio`, and `precision`.\n * Returns the input unchanged when there is no (recognized) `ratio`.\n */\nconst generateFontSizeScaleVariants = (\n normalized: NormalizedPropertyValue<number, FontSizeExtras>,\n): NormalizedPropertyValue<number, FontSizeExtras> => {\n const ratio = normalized.ratio;\n if (!ratio) return normalized;\n\n const ratioValue = TYPOGRAPHY_RATIOS[ratio];\n if (!ratioValue) return normalized;\n\n const baseFontSize = normalized.baseFontSize ?? normalized.base;\n const precision = normalized.precision ?? DEFAULT_PRECISION;\n const algorithm = normalized.algorithm;\n const existingVariants = normalized.variants ?? {};\n const generated: Record<string, FontSizeVariant> = {};\n\n let previousValue: number | null = null;\n\n for (const [key, step] of Object.entries(DEFAULT_SCALE_STEPS) as [TypographyScaleKey, number][]) {\n if (existingVariants[key]) {\n previousValue = existingVariants[key].base ?? null;\n continue;\n }\n\n let value: number;\n if (algorithm) {\n value = algorithm(baseFontSize, key, step, previousValue);\n } else {\n value = baseFontSize * Math.pow(ratioValue, step);\n }\n\n const rounded = Number(value.toFixed(precision));\n previousValue = rounded;\n generated[key] = { base: rounded } as FontSizeVariant;\n }\n\n return {\n ...normalized,\n variants: {\n ...generated,\n ...existingVariants,\n },\n };\n};\n","/**\n * Typography's `interpretRecipe` hook â resolves recipe declarations to token-path Refs.\n *\n * A typography recipe prop value names a **variant** of the matching property (`fontSize:\n * \"3xl\"`, `fontWeight: \"bold\"`), or the base value (`fontSize: \"base\"`). This interpreter\n * emits a format-neutral {@link Ref} carrying the canonical token path â `typography.fontSize.3xl`\n * for a variant, `typography.fontSize` for the base. It emits refs **directly** (no `var(--â¦)`\n * strings); the CSS adapter maps each path to a `var(--â¦)` at render time, so `theme.model`\n * carries no CSS syntax. Ported + reshaped from the old `subsystems/typography/recipes.ts`\n * (which produced `var(--â¦)` strings via a prefix resolver).\n */\nimport type { InterpretedRecipeVariant, InterpretedRecipeOverride, Ref } from \"../../core/model\";\nimport type { NormalizedRecipeVariant } from \"../../core/normalize\";\nimport type { RecipeInterpretContext } from \"../../core/subsystem\";\nimport type { TypographyRecipeProps } from \"./types\";\n\nconst RESERVED_KEYS: ReadonlySet<string> = new Set([\n \"breakpoint\",\n \"query\",\n \"state\",\n \"variant\",\n \"target\",\n \"orientation\",\n]);\n\n/** Recipe prop key â CSS declaration property name. Only these keys are lowered. */\nconst PROPERTY_CSS_MAP: Record<string, string> = {\n fontFamily: \"font-family\",\n fontSize: \"font-size\",\n fontWeight: \"font-weight\",\n lineHeight: \"line-height\",\n letterSpacing: \"letter-spacing\",\n fontStyle: \"font-style\",\n textTransform: \"text-transform\",\n textDecoration: \"text-decoration\",\n textAlign: \"text-align\",\n};\n\n/**\n * Interpret one typography recipe variant into base + responsive/state override declarations,\n * each a token-path {@link Ref}. A responsive `variant:` swap inherits the sibling's base\n * declarations (via `ctx.resolveRecipeVariant`).\n */\nexport const interpretTypographyRecipeVariant = (\n variantName: string,\n variant: NormalizedRecipeVariant<TypographyRecipeProps, string>,\n ctx: RecipeInterpretContext,\n): InterpretedRecipeVariant<string> => {\n const base = interpretProps(variant.base);\n\n const responsive: InterpretedRecipeOverride<string>[] = variant.responsive.map(entry => {\n const { breakpoint, query, state, variant: swap, target, orientation, container, size, ...rawDecls } =\n entry as TypographyRecipeProps & {\n breakpoint?: string;\n query?: \"min\" | \"max\" | \"exact\";\n state?: string;\n variant?: string;\n target?: string;\n orientation?: \"landscape\" | \"portrait\";\n container?: string;\n size?: string;\n };\n\n const inherited = swap ? { ...ctx.resolveRecipeVariant(swap).base } : {};\n const overrides = interpretProps(rawDecls as TypographyRecipeProps);\n\n const override: InterpretedRecipeOverride<string> = {\n declarations: { ...inherited, ...overrides },\n };\n if (breakpoint) {\n override.breakpoint = breakpoint;\n override.query = query ?? \"exact\";\n }\n if (container) {\n override.container = container;\n if (size) override.size = size;\n override.query = query ?? \"min\";\n }\n if (state) override.state = state;\n if (target) override.target = target; // dec.8 — scope onto the `<item>-<target>` sibling\n if (orientation) override.orientation = orientation;\n return override;\n });\n\n return { base, responsive };\n};\n\n/** Interpret a flat declaration block â `cssProperty â { ref }`, skipping empty / unknown keys. */\nconst interpretProps = (props: TypographyRecipeProps | undefined): Record<string, Ref> => {\n const declarations: Record<string, Ref> = {};\n if (!props) return declarations;\n\n for (const [key, value] of Object.entries(props)) {\n if (!value || RESERVED_KEYS.has(key)) continue;\n const cssProperty = PROPERTY_CSS_MAP[key];\n if (!cssProperty) continue;\n declarations[cssProperty] = { ref: variantPath(key, value) };\n }\n\n return declarations;\n};\n\n/** The token path for a property variant: `typography.<key>` for `\"base\"`, else `typography.<key>.<variant>`. */\nconst variantPath = (propertyKey: string, variant: string): string =>\n variant === \"base\" ? `typography.${propertyKey}` : `typography.${propertyKey}.${variant}`;\n","/**\n * The typography subsystem — a \"regular\" subsystem (no synthesized-ref derivations,\n * unlike colors' tonal steps). Iterates `raw.typography` (skipping the reserved `recipes`\n * key), runs the shared property normalize + the fontSize modular-scale synthesis per\n * property, and interprets recipes into token-path refs. It grows a hook, never the spine.\n */\n\nimport type { Subsystem, NormalizedProperties } from \"../../core/subsystem\";\nimport type { NormalizedPropertyValue, NormalizedRecipeVariant } from \"../../core/normalize\";\nimport {\n normalizePropertyValue,\n validateNormalizedResponsiveRefs,\n} from \"../../core/normalize\";\nimport type { FontSizeExtras, TypographyRecipeProps } from \"./types\";\nimport { finalizeTypographyNormalization } from \"./normalize\";\nimport { interpretTypographyRecipeVariant } from \"./recipes\";\n\n/** Sub-keys of `raw.typography` that are not properties. */\nconst RESERVED_KEYS: ReadonlySet<string> = new Set([\"recipes\"]);\n\nexport const typographySubsystem: Subsystem = {\n key: \"typography\",\n normalizeProperties(rawSlice, ctx): NormalizedProperties {\n const out: NormalizedProperties = {};\n if (!rawSlice) return out;\n\n for (const [name, value] of Object.entries(rawSlice)) {\n if (RESERVED_KEYS.has(name)) continue;\n\n const normalized = normalizePropertyValue<unknown, FontSizeExtras>(\n value as never,\n { propertyPath: `typography.${name}`, allowedBreakpoints: ctx.allowedBreakpoints },\n );\n const finalized = finalizeTypographyNormalization(\n name,\n normalized as NormalizedPropertyValue<unknown>,\n );\n validateNormalizedResponsiveRefs(finalized, { propertyPath: `typography.${name}` });\n\n out[name] = finalized as NormalizedPropertyValue<unknown, Record<string, unknown>>;\n }\n\n return out;\n },\n interpretRecipe(variantName, variant, ctx) {\n return interpretTypographyRecipeVariant(\n variantName,\n variant as NormalizedRecipeVariant<TypographyRecipeProps, string>,\n ctx,\n );\n },\n};\n\nexport type { TypographyRaw, TypographyPropertyValue } from \"./types\";\n","/**\n * Layout subsystem types (clean-room).\n *\n * Regular property keys (`spacing` / `gutters` / `aspectRatio`) normalize like any other\n * subsystem; the structural keys (`columns` / `grids` / `stacks` / `container`) drive the\n * structural generators (see `structural.ts`); `recipes` are ordinary token-path recipes.\n */\n\nimport type { PropertyValue, RecipeBlock } from \"../../core/normalize\";\n\nexport type ResponsiveQuery = \"min\" | \"max\" | \"exact\";\n\n/** The whitelisted \"regular\" layout property keys (the ones that become `PropertyModel`s). */\nexport const LAYOUT_PROPERTY_KEYS: readonly string[] = [\"spacing\", \"gutters\", \"aspectRatio\", \"sizes\"];\n\n/**\n * Scale-synthesis authoring keys (§10.6) for a length scale (`spacing`/`gutters`/`sizes`). Declare\n * one curve — `ratio` (geometric `base × ratio^n`, `steps` an ordered name array) or `step` (linear\n * `step × n`, `steps` a name→multiplier map) — to synthesize the variant ramp instead of hand-listing\n * it. Opt-in: absent both, the property behaves exactly as before. The same keys inside a `responsive`\n * entry regenerate the whole named scale at that breakpoint (D6). Authored `variants` still win.\n */\nexport type LayoutScaleExtras = {\n ratio?: number;\n step?: number;\n steps?: readonly string[] | Record<string, number>;\n};\n\n// --- Columns ---\n\nexport type ColumnsConfig = { size: number; gutter?: string; inset?: string };\nexport type ColumnsValue = number | ColumnsConfig;\n\n// --- Grids ---\n\nexport type GridDefinition = {\n templateColumns?: string;\n templateRows?: string;\n autoRows?: string;\n autoColumns?: string;\n justifyItems?: string;\n alignItems?: string;\n justifyContent?: string;\n alignContent?: string;\n gap?: string;\n responsive?: Array<{\n breakpoint: string;\n query?: ResponsiveQuery;\n templateColumns?: string;\n templateRows?: string;\n autoRows?: string;\n autoColumns?: string;\n justifyItems?: string;\n alignItems?: string;\n justifyContent?: string;\n alignContent?: string;\n gap?: string;\n }>;\n};\nexport type GridsDefinition = Record<string, GridDefinition>;\n\n// --- Stacks ---\n\nexport type StackDefinition = {\n direction?: \"row\" | \"column\";\n align?: string;\n justify?: string;\n wrap?: string;\n inline?: boolean;\n gap?: string;\n responsive?: Array<{\n breakpoint: string;\n query?: ResponsiveQuery;\n direction?: \"row\" | \"column\";\n align?: string;\n justify?: string;\n wrap?: string;\n inline?: boolean;\n }>;\n};\nexport type StacksDefinition = Record<string, StackDefinition>;\n\n// --- Container ---\n\nexport type ContainerConfig = {\n /** The resolved mode: `\"fixed\"` / `\"fluid\"` / a custom width string. */\n mode: string;\n inset?: string;\n gutter?: string;\n direction?: string;\n align?: string;\n justify?: string;\n maxWidth?: string | number;\n};\n\n// --- Container (authored) ---\n\n/**\n * One authored container variant (§8a) — a mode string (`\"fixed\"` / `\"fluid\"` / a width) or a\n * config object. Distinct from {@link ContainerConfig}, which is the resolved `{ mode }` shape the\n * structural generator produces.\n */\nexport type ContainerVariantRaw =\n | string\n | {\n base?: string;\n inset?: string;\n gutter?: string;\n direction?: string;\n align?: string;\n justify?: string;\n maxWidth?: string | number;\n };\n\n/** The authored `layout.container` value (§8a) — a mode string or a config with variants/responsive. */\nexport type ContainerRaw =\n | string\n | {\n base?: string;\n inset?: string;\n gutter?: string;\n direction?: string;\n align?: string;\n justify?: string;\n maxWidth?: string | number;\n variants?: Record<string, ContainerVariantRaw>;\n responsive?: Array<{\n breakpoint: string;\n query?: ResponsiveQuery;\n target?: string;\n direction?: string;\n align?: string;\n justify?: string;\n inset?: string;\n gutter?: string;\n }>;\n };\n\n// --- Recipes ---\n\nexport type LayoutRecipeProps = {\n paddingY?: string;\n paddingX?: string;\n marginY?: string;\n marginX?: string;\n gap?: string;\n background?: string;\n /**\n * Sizing verbs (§22) — each names a `layout.sizes` variant and routes to its CSS longhand\n * (`maxWidth` → `max-width`, no fan-out). A verb exists because it consumes a themed scale (`sizes`);\n * dimensional CSS with no scale (`display`, `position`, …) stays in a component `css` delta.\n */\n width?: string;\n minWidth?: string;\n maxWidth?: string;\n height?: string;\n minHeight?: string;\n maxHeight?: string;\n [property: string]: string | undefined;\n};\n\n/**\n * The authored `raw.layout` slice (§8a). The only **closed** subsystem — its keys are fixed:\n * the regular property tokens (`spacing`/`gutters`/`aspectRatio`), the four structural generators\n * (`columns`/`grids`/`stacks`/`container`), and the `recipes` block. Authoring type only.\n */\nexport interface LayoutRaw {\n spacing?: PropertyValue<string | number, LayoutScaleExtras>;\n gutters?: PropertyValue<string | number, LayoutScaleExtras>;\n aspectRatio?: PropertyValue<string | number>;\n /** The sizing scale (§22) — one length scale for width/height/min/max, chosen at the recipe verb. */\n sizes?: PropertyValue<string | number, LayoutScaleExtras>;\n columns?: ColumnsValue;\n grids?: GridsDefinition;\n stacks?: StacksDefinition;\n container?: ContainerRaw;\n recipes?: RecipeBlock<LayoutRecipeProps>;\n}\n","/**\n * Layout's `normalizeProperty` hook — numeric scale synthesis (§10.6) + the forced `none` variant.\n *\n * `spacing` / `gutters` / `sizes` can synthesize their variant ramp from a base + a curve, the same\n * way colors generates tonal steps and typography the type scale:\n * - **geometric** (`ratio`) — `base × ratio^n`, `steps` an ordered name array (index = exponent);\n * - **linear** (`step`) — `step × n`, `steps` a name→multiplier map (the 4/8-pt grid).\n *\n * Each synthesized step is stored as a **derived** variant (`{ base, derive:{ ref, fn:\"scaleStep\",\n * arg } }`) so the Model carries it as a re-resolving `Ref` — `override()` of the base re-synthesizes\n * every step (mirror colors, NOT typography's frozen literals). A ramp entry inside a property's\n * `responsive` list (D6) regenerates the WHOLE named scale at that breakpoint, expanding into one\n * `target` override per step — the already-existing responsive channel, no new Model member.\n *\n * Synthesis is **opt-in + additive**: absent a `ratio`/`step`, behaviour is byte-identical to before\n * (spacing/gutters still get the forced `none`; sizes/aspectRatio pass through). Authored `variants`\n * always win over synthesized ones — the way sizes' semantic caps (`prose`) and pinned values\n * (`full: \"100%\"`, no magnitude → never synthesized) coexist with the ramp.\n */\n\nimport type { NormalizedPropertyValue } from \"../../core/normalize\";\nimport type { Literal } from \"../../core/model\";\nimport { RefractError } from \"../../core/errors\";\n\n/** Layout properties eligible for scale synthesis (`aspectRatio` is not a length ramp). */\nconst SCALE_PROPERTIES: ReadonlySet<string> = new Set([\"spacing\", \"gutters\", \"sizes\"]);\n\n/** Properties that always expose a `none` variant (`base: 0`), synthesized or not. */\nconst FORCE_NONE_PROPERTIES: ReadonlySet<string> = new Set([\"spacing\", \"gutters\"]);\n\n/** Decimal places every synthesized step is rounded to — fixed so `scaleStep` re-derives exactly. */\nconst SCALE_PRECISION = 4;\n\n/** The default step ladder used when a curve is declared without an explicit `steps`. */\nconst DEFAULT_LADDER: readonly string[] = [\"xs\", \"sm\", \"md\", \"lg\", \"xl\", \"2xl\", \"3xl\", \"4xl\"];\n\nconst round = (n: number): number => Number(n.toFixed(SCALE_PRECISION));\n\n/**\n * The `scaleStep` derivation fn (registered by the layout subsystem). Re-derives a synthesized step\n * from its curve config: **geometric** `base × ratio^exp` (from the resolved base token, so an\n * `override()` of the base rescales it), **linear** `step × mult` (a fixed grid, self-contained in\n * `arg`). A responsive ramp step with an explicit breakpoint base carries it on `arg.base`, so it\n * derives from its own breakpoint base (precedent: colors' appearance modes). Mirrors the way the\n * derivation registry hands every fn `(resolvedValue, arg)`.\n */\nexport const scaleStep = (value: Literal, arg?: unknown): Literal => {\n const a = (arg ?? {}) as {\n curve?: string;\n ratio?: number;\n exp?: number;\n step?: number;\n mult?: number;\n base?: number;\n };\n if (a.curve === \"linear\") {\n return round(Number(a.step) * Number(a.mult));\n }\n const base = a.base !== undefined ? Number(a.base) : Number(value);\n return round(base * Math.pow(Number(a.ratio), Number(a.exp)));\n};\n\n/** One synthesized step's position — `exp` (ordinal, geometric exponent), `mult` (linear multiplier). */\ntype StepSpec = { name: string; exp: number; mult?: number };\n\n/** The resolved curve for a property — its kind, its parameters, and the ordered step list. */\ntype ScaleConfig =\n | { curve: \"geometric\"; ratio: number; specs: StepSpec[] }\n | { curve: \"linear\"; step: number; specs: StepSpec[] };\n\n/**\n * Read the top-level curve config off a normalized property. `ratio` selects geometric, `step`\n * selects linear (never both). `steps` is the naming source — an ordered name array for geometric,\n * a name→multiplier map for linear — falling back to {@link DEFAULT_LADDER} when omitted. Returns\n * `undefined` when no curve is declared (the additive, byte-identical path).\n */\nconst readScaleConfig = (\n propertyKey: string,\n normalized: NormalizedPropertyValue<unknown>,\n): ScaleConfig | undefined => {\n const n = normalized as Record<string, unknown>;\n const hasRatio = n.ratio !== undefined;\n const hasStep = n.step !== undefined;\n if (!hasRatio && !hasStep) return undefined;\n if (hasRatio && hasStep) {\n throw new RefractError(\n \"REFRACT_E_LAYOUT\",\n `layout.${propertyKey}: declare only one of \"ratio\" (geometric) or \"step\" (linear) scale, not both.`,\n );\n }\n const steps = n.steps;\n\n if (hasRatio) {\n let names: readonly string[];\n if (steps === undefined) names = DEFAULT_LADDER;\n else if (Array.isArray(steps)) names = steps.map(String);\n else {\n throw new RefractError(\n \"REFRACT_E_LAYOUT\",\n `layout.${propertyKey}: a geometric scale (\"ratio\") needs \"steps\" as an ordered name array, e.g. [\"sm\",\"md\",\"lg\"].`,\n );\n }\n const specs = names.map((name, i): StepSpec => ({ name, exp: i }));\n return { curve: \"geometric\", ratio: Number(n.ratio), specs };\n }\n\n let specs: StepSpec[];\n if (steps === undefined) {\n specs = DEFAULT_LADDER.map((name, i): StepSpec => ({ name, exp: i, mult: i + 1 }));\n } else if (Array.isArray(steps) || typeof steps !== \"object\" || steps === null) {\n throw new RefractError(\n \"REFRACT_E_LAYOUT\",\n `layout.${propertyKey}: a linear scale (\"step\") needs \"steps\" as a name→multiplier map, e.g. { sm:1, md:2, lg:3 }.`,\n );\n } else {\n specs = Object.entries(steps as Record<string, unknown>).map(\n ([name, mult], i): StepSpec => ({ name, exp: i, mult: Number(mult) }),\n );\n }\n return { curve: \"linear\", step: Number(n.step), specs };\n};\n\n/** Build the derived variant refs for a curve's steps — each a `{ base, derive }` re-resolving step. */\nconst synthesizeVariants = (\n propertyKey: string,\n base: unknown,\n config: ScaleConfig,\n): Record<string, { base: Literal; derive: { ref: string; fn: string; arg: unknown } }> => {\n const ref = `layout.${propertyKey}`;\n const out: Record<string, { base: Literal; derive: { ref: string; fn: string; arg: unknown } }> = {};\n for (const spec of config.specs) {\n if (config.curve === \"geometric\") {\n const value = round(Number(base) * Math.pow(config.ratio, spec.exp));\n out[spec.name] = {\n base: value,\n derive: { ref, fn: \"scaleStep\", arg: { curve: \"geometric\", ratio: config.ratio, exp: spec.exp } },\n };\n } else {\n const value = round(config.step * (spec.mult as number));\n out[spec.name] = {\n base: value,\n derive: { ref, fn: \"scaleStep\", arg: { curve: \"linear\", step: config.step, mult: spec.mult } },\n };\n }\n }\n return out;\n};\n\n/**\n * Expand ramp entries in a property's `responsive` list (D6). A responsive entry carrying `ratio`\n * (geometric) or `step` (linear) regenerates the whole named scale at that breakpoint, emitting one\n * `target` override per synthesized step — each a derived `{ base, derive }` so the JSON/DTCG output\n * carries the recipe and `override()` re-runs the ramp. Non-ramp entries (plain value / variant /\n * target swaps) pass through untouched. A geometric ramp uses each step's ordinal exponent (so a\n * `ratio:1` flattens every step to the base); a linear ramp needs the base scale's multipliers.\n */\nconst expandResponsive = (\n propertyKey: string,\n propBase: unknown,\n responsive: NormalizedPropertyValue<unknown>[\"responsive\"],\n config: ScaleConfig | undefined,\n): NormalizedPropertyValue<unknown>[\"responsive\"] => {\n if (!responsive?.length) return responsive;\n const ref = `layout.${propertyKey}`;\n\n const out: Record<string, unknown>[] = [];\n let expandedAny = false;\n\n for (const entry of responsive) {\n const e = entry as Record<string, unknown>;\n const isRamp = e.ratio !== undefined || e.step !== undefined;\n if (!isRamp) {\n out.push(e);\n continue;\n }\n expandedAny = true;\n if (e.ratio !== undefined && e.step !== undefined) {\n throw new RefractError(\n \"REFRACT_E_LAYOUT\",\n `layout.${propertyKey}: a responsive ramp entry may set only \"ratio\" or \"step\", not both.`,\n );\n }\n if (!config) {\n throw new RefractError(\n \"REFRACT_E_LAYOUT\",\n `layout.${propertyKey}: a responsive ramp entry needs a base scale — declare a top-level \"ratio\"/\"step\" (+ \"steps\") first.`,\n );\n }\n\n const { breakpoint, query, orientation } = e;\n const geometric = e.ratio !== undefined;\n\n for (const spec of config.specs) {\n let value: number;\n let arg: Record<string, unknown>;\n if (geometric) {\n const ratio = Number(e.ratio);\n const hasBase = e.base !== undefined;\n const b = hasBase ? Number(e.base) : Number(propBase);\n value = round(b * Math.pow(ratio, spec.exp));\n arg = { curve: \"geometric\", ratio, exp: spec.exp, ...(hasBase ? { base: b } : {}) };\n } else {\n if (spec.mult === undefined) {\n throw new RefractError(\n \"REFRACT_E_LAYOUT\",\n `layout.${propertyKey}: a linear responsive ramp (\"step\") requires a linear base scale (a name→multiplier \"steps\").`,\n );\n }\n const step = Number(e.step);\n value = round(step * spec.mult);\n arg = { curve: \"linear\", step, mult: spec.mult };\n }\n const expanded: Record<string, unknown> = {\n breakpoint,\n query,\n target: spec.name,\n base: value,\n derive: { ref, fn: \"scaleStep\", arg },\n };\n if (orientation !== undefined) expanded.orientation = orientation;\n out.push(expanded);\n }\n }\n\n return (expandedAny ? out : responsive) as NormalizedPropertyValue<unknown>[\"responsive\"];\n};\n\n/** Strip the curve-config keys off a normalized property so they never leak as Model extras. */\nconst stripScaleKeys = (\n normalized: NormalizedPropertyValue<unknown>,\n): NormalizedPropertyValue<unknown> => {\n const { ratio, step, steps, ...rest } = normalized as Record<string, unknown>;\n void ratio;\n void step;\n void steps;\n return rest as unknown as NormalizedPropertyValue<unknown>;\n};\n\n/**\n * @param propertyKey The layout property being normalized.\n * @param normalized The property after the shared property normalize pass.\n */\nexport const finalizeLayoutNormalization = (\n propertyKey: string,\n normalized: NormalizedPropertyValue<unknown>,\n): NormalizedPropertyValue<unknown> => {\n if (!SCALE_PROPERTIES.has(propertyKey)) return normalized;\n\n const config = readScaleConfig(propertyKey, normalized);\n\n // Additive: no curve declared → the exact legacy behaviour (byte-identical goldens).\n if (!config) {\n return FORCE_NONE_PROPERTIES.has(propertyKey) ? forceNoneVariant(normalized) : normalized;\n }\n\n // Synthesized steps are the base layer; authored `variants` win on name collision (sizes' semantic\n // caps / pinned `%` ride here); the forced `none` (spacing/gutters) wins over everything.\n const synthesized = synthesizeVariants(propertyKey, normalized.base, config);\n const authored = normalized.variants ?? {};\n let variants: Record<string, unknown> = { ...synthesized, ...authored };\n if (FORCE_NONE_PROPERTIES.has(propertyKey)) variants = { ...variants, none: { base: 0 } };\n\n const responsive = expandResponsive(propertyKey, normalized.base, normalized.responsive, config);\n\n return stripScaleKeys({\n ...normalized,\n variants,\n responsive,\n } as unknown as NormalizedPropertyValue<unknown>);\n};\n\n/** Force a `none` variant (`base: 0`) onto the property, overriding any author-declared `none`. */\nconst forceNoneVariant = (\n normalized: NormalizedPropertyValue<unknown>,\n): NormalizedPropertyValue<unknown> => {\n const variants = normalized.variants ?? {};\n return {\n ...normalized,\n variants: {\n ...variants,\n none: { base: 0 },\n },\n } as unknown as NormalizedPropertyValue<unknown>;\n};\n","/**\n * Layout's `interpretRecipe` hook â resolves recipe declarations to token-path Refs.\n *\n * A layout recipe prop names a **spacing variant** (`paddingY: \"xl\"`, `gap: \"relaxed\"`),\n * which this interpreter emits as a `layout.spacing.<variant>` token-path {@link Ref}\n * (`layout.spacing` for the base). `background` passes through as a literal. One recipe prop\n * can fan out to several CSS declarations (`paddingY` â `padding-top` + `padding-bottom`).\n * Emits refs **directly** â no `var(--â¦)` strings; the CSS adapter maps each path to a\n * `var(--â¦)` at render time. Ported + reshaped from the old `subsystems/layout/recipes.ts`.\n */\nimport type { InterpretedRecipeVariant, InterpretedRecipeOverride, Ref } from \"../../core/model\";\nimport type { NormalizedRecipeVariant } from \"../../core/normalize\";\nimport type { RecipeInterpretContext } from \"../../core/subsystem\";\nimport type { LayoutRecipeProps } from \"./types\";\nimport { RefractError } from \"../../core/errors\";\n\nconst RESERVED_KEYS: ReadonlySet<string> = new Set([\n \"breakpoint\",\n \"query\",\n \"state\",\n \"variant\",\n \"target\",\n \"orientation\",\n]);\n\n/** Recipe verb â the CSS declaration property names it expands to. Spacing verbs fan out (Y â top+bottom);\n * sizing verbs (§22) are 1:1 with their longhand; `background` is the one literal verb. */\nconst PROPERTY_CSS_MAP: Record<string, string[]> = {\n paddingY: [\"padding-top\", \"padding-bottom\"],\n paddingX: [\"padding-left\", \"padding-right\"],\n marginY: [\"margin-top\", \"margin-bottom\"],\n marginX: [\"margin-left\", \"margin-right\"],\n gap: [\"gap\"],\n background: [\"background\"],\n // §22 sizing verbs â resolve against `layout.sizes`, one longhand each.\n width: [\"width\"],\n minWidth: [\"min-width\"],\n maxWidth: [\"max-width\"],\n height: [\"height\"],\n minHeight: [\"min-height\"],\n maxHeight: [\"max-height\"],\n};\n\n/**\n * Which themed scale a verb's value names (§22 governing principle: a verb exists because it consumes a\n * themed scale). Spacing verbs â `layout.spacing`, sizing verbs â `layout.sizes`; `background` is the one\n * `\"literal\"` verb (a raw CSS value, no scale).\n */\nconst PROPERTY_DOMAIN: Record<string, \"spacing\" | \"sizes\" | \"literal\"> = {\n paddingY: \"spacing\", paddingX: \"spacing\", marginY: \"spacing\", marginX: \"spacing\", gap: \"spacing\",\n width: \"sizes\", minWidth: \"sizes\", maxWidth: \"sizes\", height: \"sizes\", minHeight: \"sizes\", maxHeight: \"sizes\",\n background: \"literal\",\n};\n\n/** A `layout.<domain>` token path for a variant: the base token for `\"base\"`, else `.<variant>`. */\nconst tokenPath = (domain: \"spacing\" | \"sizes\", variant: string): string =>\n variant === \"base\" ? `layout.${domain}` : `layout.${domain}.${variant}`;\n\n/**\n * Interpret one flat declaration block â `cssProperty â Ref`. Each verb resolves against its themed\n * scale ({@link PROPERTY_DOMAIN}); `background` stays a literal. An **unknown** verb throws (§22 D5) â\n * the map used to silently drop it, so a typo (`pading`) or an unsupported property vanished with no error.\n */\nconst interpretProps = (props: LayoutRecipeProps | undefined, label: string): Record<string, Ref> => {\n const declarations: Record<string, Ref> = {};\n if (!props) return declarations;\n\n for (const [key, value] of Object.entries(props)) {\n if (RESERVED_KEYS.has(key)) continue;\n if (!value) continue;\n const cssProperties = PROPERTY_CSS_MAP[key];\n if (!cssProperties) {\n throw new RefractError(\n \"REFRACT_E_LAYOUT\",\n `Unknown layout recipe property \"${key}\" in ${label}. Known verbs: ` +\n `${Object.keys(PROPERTY_CSS_MAP).join(\", \")}. For arbitrary CSS use a component \\`css\\` delta.`,\n );\n }\n const domain = PROPERTY_DOMAIN[key];\n for (const cssProperty of cssProperties) {\n declarations[cssProperty] = domain === \"literal\" ? { value } : { ref: tokenPath(domain, value) };\n }\n }\n\n return declarations;\n};\n\n/** Interpret one layout recipe variant into base + responsive/state override declarations. */\nexport const interpretLayoutRecipeVariant = (\n variantName: string,\n variant: NormalizedRecipeVariant<LayoutRecipeProps, string>,\n ctx: RecipeInterpretContext,\n): InterpretedRecipeVariant<string> => {\n const label = `${ctx.groupPath ?? \"layout.recipes\"}.${variantName}`;\n const base = interpretProps(variant.base, label);\n\n const responsive: InterpretedRecipeOverride<string>[] = variant.responsive.map(entry => {\n const { breakpoint, query, state, variant: swap, target, orientation, container, size, ...rawDecls } =\n entry as LayoutRecipeProps & {\n breakpoint?: string;\n query?: \"min\" | \"max\" | \"exact\";\n state?: string;\n variant?: string;\n target?: string;\n orientation?: \"landscape\" | \"portrait\";\n container?: string;\n size?: string;\n };\n\n const inherited = swap ? { ...ctx.resolveRecipeVariant(swap).base } : {};\n const overrides = interpretProps(rawDecls as LayoutRecipeProps, label);\n\n const override: InterpretedRecipeOverride<string> = {\n declarations: { ...inherited, ...overrides },\n };\n if (breakpoint) {\n override.breakpoint = breakpoint;\n override.query = query ?? \"exact\";\n }\n if (container) {\n override.container = container;\n if (size) override.size = size;\n override.query = query ?? \"min\";\n }\n if (state) override.state = state;\n if (target) override.target = target; // dec.8 — scope onto the `<item>-<target>` sibling\n if (orientation) override.orientation = orientation;\n return override;\n });\n\n return { base, responsive };\n};\n","/**\n * Layout structural generators → **Model rule-sets** (the clean-room payoff).\n *\n * `columns` / `grids` / `stacks` / `container` used to emit `CssNode[]` that a lossless\n * node↔rule-set codec (`routeLayoutStructuralThroughModel`) round-tripped into the Model.\n * Here the generators emit {@link RuleSetGroup}s **natively** — declarations carry token-path\n * {@link Ref}s (`layout.spacing.relaxed`), never `var(--…)` — so the codec never exists. The CSS\n * adapter lowers these rule-sets to `CssRuleNode[]` (columns/grids/stacks via `lowerRecipeGroup`,\n * container via the two-pass `lowerContainerGroup`, matching the old unshift-bases/push-medias order).\n *\n * The columns/container config knobs (`--…-columns--size`, `--…-container--inset`, …) ride along as\n * **layout property tokens** (`configProperties`, merged as `extraProperties` in the Model); the\n * structural rule declarations reference those config tokens by path (`layout.container--inset`),\n * exactly the two-level indirection the old generators produced. Math ported verbatim from the old\n * `subsystems/layout/tokens.ts`; only the output shape (rule-sets, not CSS) differs.\n *\n * The math forms variant keys from raw breakpoint keys + span numbers (`col-sm-3`); the adapter\n * prepends the class prefix + sanitizes. No CSS syntax is produced here — core stays format-neutral.\n */\nimport type { PropertyModel, Ref, RuleSet, RuleSetGroup, RuleSetOverride } from \"../../core/model\";\nimport { type MediaConfig, formatWidth, resolveMediaConfig } from \"../../core/media\";\nimport type {\n ColumnsValue,\n ContainerConfig,\n GridsDefinition,\n StacksDefinition,\n} from \"./types\";\n\n/** The structural output: rule-set groups (for the Model + CSS) + config `:root` tokens. */\nexport type LayoutStructuralOutput = {\n ruleSetGroups: Record<string, RuleSetGroup>;\n configProperties: Record<string, PropertyModel>;\n};\n\n// --- token-path ref helpers (no CSS) ---\n\n/** A spacing token ref: `layout.spacing` for `\"base\"`, else `layout.spacing.<variant>`. */\nconst spacingRef = (variant: string): Ref => ({\n ref: variant === \"base\" ? \"layout.spacing\" : `layout.spacing.${variant}`,\n});\n/** A gutters token ref: `layout.gutters` for `\"base\"`, else `layout.gutters.<variant>`. */\nconst guttersRef = (variant: string): Ref => ({\n ref: variant === \"base\" ? \"layout.gutters\" : `layout.gutters.${variant}`,\n});\n/** A sizes token ref (§22): `layout.sizes` for `\"base\"`, else `layout.sizes.<variant>`. */\nconst sizesRef = (variant: string): Ref => ({\n ref: variant === \"base\" ? \"layout.sizes\" : `layout.sizes.${variant}`,\n});\n/** A ref to a structural config token (`layout.<key>`, e.g. `layout.container--inset`). */\nconst configRef = (key: string): Ref => ({ ref: `layout.${key}` });\nconst literal = (value: string | number): Ref => ({ value });\n\nconst sortByWidth = (breakpoints: Record<string, number>): string[] =>\n Object.keys(breakpoints).sort((a, b) => breakpoints[a] - breakpoints[b]);\n\n// ---------------------------------------------------------------------------\n// Columns — `kind: \"utility\"`, one rule-set per (span × breakpoint)\n// ---------------------------------------------------------------------------\n\nexport const buildColumns = (\n input: ColumnsValue | undefined,\n breakpoints: Record<string, number>,\n): LayoutStructuralOutput | undefined => {\n if (!input) return undefined;\n const config = typeof input === \"number\" ? { size: input } : input;\n const size = config.size;\n const gutterRef = config.gutter ?? \"base\";\n const insetRef = config.inset ?? \"none\";\n\n const configProperties: Record<string, PropertyModel> = {\n \"columns--size\": { base: literal(String(size)) },\n \"columns--gutter\": { base: guttersRef(gutterRef) },\n \"columns--inset\": { base: spacingRef(insetRef) },\n };\n\n const group: RuleSetGroup = {};\n const spans = Array.from({ length: size }, (_, i) => i + 1);\n for (const key of sortByWidth(breakpoints)) {\n for (const span of spans) {\n const colVariant = `col-${key}-${span}`;\n const offsetVariant = `offset-${key}-${span}`;\n const colDecl: Record<string, Ref> = { \"grid-column-end\": literal(`span ${span}`) };\n const offsetDecl: Record<string, Ref> = { \"grid-column-start\": literal(String(span + 1)) };\n\n if (breakpoints[key] === 0) {\n group[colVariant] = { kind: \"utility\", declarations: colDecl, overrides: [] };\n group[offsetVariant] = { kind: \"utility\", declarations: offsetDecl, overrides: [] };\n } else {\n group[colVariant] = {\n kind: \"utility\",\n declarations: {},\n overrides: [{ breakpoint: key, query: \"min\", declarations: colDecl }],\n };\n group[offsetVariant] = {\n kind: \"utility\",\n declarations: {},\n overrides: [{ breakpoint: key, query: \"min\", declarations: offsetDecl }],\n };\n }\n }\n }\n\n return { ruleSetGroups: { columns: group }, configProperties };\n};\n\n// ---------------------------------------------------------------------------\n// Grids — `kind: \"recipe\"`, one rule-set per grid\n// ---------------------------------------------------------------------------\n\n/** The grid declaration props (in emission order) that pass through as literals. */\nconst GRID_LITERAL_PROPS: ReadonlyArray<[keyof GridsDefinition[string], string]> = [\n [\"templateColumns\", \"grid-template-columns\"],\n [\"templateRows\", \"grid-template-rows\"],\n [\"autoRows\", \"grid-auto-rows\"],\n [\"autoColumns\", \"grid-auto-columns\"],\n [\"justifyItems\", \"justify-items\"],\n [\"alignItems\", \"align-items\"],\n [\"justifyContent\", \"justify-content\"],\n [\"alignContent\", \"align-content\"],\n];\n\nconst gridDeclarations = (\n grid: Record<string, unknown>,\n includeDisplay: boolean,\n): Record<string, Ref> => {\n const decls: Record<string, Ref> = {};\n if (includeDisplay) decls[\"display\"] = literal(\"grid\");\n for (const [key, cssProperty] of GRID_LITERAL_PROPS) {\n const value = grid[key as string];\n if (value) decls[cssProperty] = literal(value as string);\n }\n if (grid.gap) decls[\"gap\"] = spacingRef(grid.gap as string);\n return decls;\n};\n\nexport const buildGrids = (\n grids: GridsDefinition | undefined,\n): LayoutStructuralOutput | undefined => {\n if (!grids || !Object.keys(grids).length) return undefined;\n const group: RuleSetGroup = {};\n\n for (const [name, grid] of Object.entries(grids)) {\n const declarations = gridDeclarations(grid, true);\n const overrides: RuleSetOverride[] = [];\n for (const entry of grid.responsive ?? []) {\n const respDecls = gridDeclarations(entry, false);\n if (Object.keys(respDecls).length) {\n overrides.push({ breakpoint: entry.breakpoint, query: entry.query ?? \"exact\", declarations: respDecls });\n }\n }\n group[`grid-${name}`] = { kind: \"recipe\", declarations, overrides };\n }\n\n return { ruleSetGroups: { grids: group }, configProperties: {} };\n};\n\n// ---------------------------------------------------------------------------\n// Stacks — `kind: \"recipe\"`, one rule-set per stack\n// ---------------------------------------------------------------------------\n\nexport const buildStacks = (\n stacks: StacksDefinition | undefined,\n): LayoutStructuralOutput | undefined => {\n if (!stacks || !Object.keys(stacks).length) return undefined;\n const group: RuleSetGroup = {};\n\n for (const [name, stack] of Object.entries(stacks)) {\n const declarations: Record<string, Ref> = {\n display: literal(stack.inline ? \"inline-flex\" : \"flex\"),\n \"flex-direction\": literal(stack.direction ?? \"column\"),\n };\n if (stack.align) declarations[\"align-items\"] = literal(stack.align);\n if (stack.justify) declarations[\"justify-content\"] = literal(stack.justify);\n if (stack.wrap) declarations[\"flex-wrap\"] = literal(stack.wrap);\n if (stack.gap) declarations[\"gap\"] = spacingRef(stack.gap);\n\n const overrides: RuleSetOverride[] = [];\n for (const entry of stack.responsive ?? []) {\n const respDecls: Record<string, Ref> = {};\n if (entry.inline !== undefined) respDecls[\"display\"] = literal(entry.inline ? \"inline-flex\" : \"flex\");\n if (entry.direction) respDecls[\"flex-direction\"] = literal(entry.direction);\n if (entry.align) respDecls[\"align-items\"] = literal(entry.align);\n if (entry.justify) respDecls[\"justify-content\"] = literal(entry.justify);\n if (entry.wrap) respDecls[\"flex-wrap\"] = literal(entry.wrap);\n if (Object.keys(respDecls).length) {\n overrides.push({ breakpoint: entry.breakpoint, query: entry.query ?? \"exact\", declarations: respDecls });\n }\n }\n group[`stack-${name}`] = { kind: \"recipe\", declarations, overrides };\n }\n\n return { ruleSetGroups: { stacks: group }, configProperties: {} };\n};\n\n// ---------------------------------------------------------------------------\n// Container — `kind: \"recipe\"`; always emits a default container (matches the old generator)\n// ---------------------------------------------------------------------------\n\nconst resolveContainerConfig = (raw: unknown): ContainerConfig => {\n if (!raw || typeof raw === \"string\") return { mode: (raw as string) ?? \"fixed\" };\n const obj = raw as Record<string, unknown>;\n return {\n mode: (obj.base as string) ?? \"fixed\",\n inset: obj.inset as string | undefined,\n gutter: obj.gutter as string | undefined,\n direction: obj.direction as string | undefined,\n align: obj.align as string | undefined,\n justify: obj.justify as string | undefined,\n maxWidth: obj.maxWidth as string | number | undefined,\n };\n};\n\n/**\n * Container rule-sets + config tokens. Emitted in **processing order** (base first, then each\n * variant); the adapter's `lowerContainerGroup` reverses for bases and keeps medias forward, which\n * reproduces the old generator's `unshift`(bases)/`push`(medias) node stream byte-for-byte.\n * Runs even with no `container` config (defaults to `\"fixed\"`) — the old generator did too.\n */\n/**\n * Resolve a **fluid** container's max-width cap (§22 D4). A string naming an authored `sizes` variant →\n * a unit-aware `layout.sizes.*` ref (the recommended path — flip the theme to rem and the cap follows);\n * a breakpoint name → that breakpoint's px width; any other string → a raw literal (`\"80rem\"`, `calc()`).\n * A bare **number** stays a `${n}px` literal — an intentional \"exactly this\" escape (reference a `sizes`\n * token for unit-awareness). Size names win over breakpoint names on collision (a cap is a size concept).\n */\nconst resolveFluidMaxWidth = (\n value: string | number,\n sizeNames: ReadonlySet<string>,\n breakpoints: Record<string, number>,\n): Ref => {\n if (typeof value === \"number\") return literal(`${value}px`);\n if (sizeNames.has(value)) return sizesRef(value);\n if (breakpoints[value] !== undefined) return literal(`${breakpoints[value]}px`);\n return literal(value);\n};\n\n/** The authored `sizes` variant names (plus `base`) — for disambiguating a fluid container cap (§22 D4). */\nconst collectSizeNames = (sizes: unknown): Set<string> => {\n const names = new Set<string>();\n if (sizes && typeof sizes === \"object\" && !Array.isArray(sizes)) {\n const obj = sizes as Record<string, unknown>;\n if (\"base\" in obj) names.add(\"base\");\n const variants = obj.variants as Record<string, unknown> | undefined;\n if (variants && typeof variants === \"object\") for (const k of Object.keys(variants)) names.add(k);\n }\n return names;\n};\n\nexport const buildContainer = (\n containerInput: unknown,\n breakpoints: Record<string, number>,\n sizeNames: ReadonlySet<string> = new Set(),\n mediaConfig?: MediaConfig,\n): LayoutStructuralOutput => {\n // Fixed-container max-widths are breakpoint-DERIVED, so they format in the same px/em/rem unit the\n // `@media` thresholds use (§10.5) — NOT the §21 declaration-`units` axis. `formatWidth` is the shared\n // threshold formatter, so a fixed container stays aligned with where its breakpoints fire.\n const resolvedMedia = resolveMediaConfig(mediaConfig);\n const mediaLen = (value: number): string => formatWidth(value, resolvedMedia);\n const configProperties: Record<string, PropertyModel> = {};\n const group: RuleSetGroup = {};\n const sortedKeys = sortByWidth(breakpoints);\n\n const extended =\n containerInput && typeof containerInput === \"object\"\n ? (containerInput as Record<string, unknown>)\n : undefined;\n\n const baseConfig: ContainerConfig = extended\n ? {\n mode: (extended.base as string) ?? \"fixed\",\n inset: extended.inset as string | undefined,\n gutter: extended.gutter as string | undefined,\n direction: extended.direction as string | undefined,\n align: extended.align as string | undefined,\n justify: extended.justify as string | undefined,\n maxWidth: extended.maxWidth as string | number | undefined,\n }\n : resolveContainerConfig(containerInput ?? \"fixed\");\n const variants = (extended?.variants as Record<string, unknown>) ?? {};\n const responsiveEntries = (extended?.responsive as Array<Record<string, unknown>>) ?? [];\n\n const variantKeyFor = (name: string | null): string =>\n name ? `container-${name}` : \"container\";\n\n const buildSingleContainer = (name: string | null, config: ContainerConfig): void => {\n const suffix = name ? `--${name}` : \"\";\n const insetKey = `container${suffix}--inset`;\n const gutterKey = `container${suffix}--gutter`;\n\n const insetRef = config.inset ?? baseConfig.inset ?? \"base\";\n const gutterRef = config.gutter ?? baseConfig.gutter;\n const mode = config.mode ?? baseConfig.mode ?? \"fixed\";\n const direction = config.direction ?? baseConfig.direction;\n const align = config.align ?? baseConfig.align;\n const justify = config.justify ?? baseConfig.justify;\n const maxWidthValue = config.maxWidth ?? (name ? baseConfig.maxWidth : undefined);\n\n configProperties[insetKey] = { base: spacingRef(insetRef) };\n if (gutterRef) configProperties[gutterKey] = { base: guttersRef(gutterRef) };\n\n const declarations: Record<string, Ref> = {\n \"box-sizing\": literal(\"border-box\"),\n width: literal(\"100%\"),\n \"margin-left\": literal(\"auto\"),\n \"margin-right\": literal(\"auto\"),\n \"padding-left\": configRef(insetKey),\n \"padding-right\": configRef(insetKey),\n };\n if (gutterRef) declarations[\"gap\"] = configRef(gutterKey);\n if (direction) {\n declarations[\"display\"] = literal(\"flex\");\n declarations[\"flex-direction\"] = literal(direction);\n }\n if (align) declarations[\"align-items\"] = literal(align);\n if (justify) declarations[\"justify-content\"] = literal(justify);\n\n const overrides: RuleSetOverride[] = [];\n if (mode === \"fixed\") {\n const maxBp =\n typeof maxWidthValue === \"string\" && breakpoints[maxWidthValue] !== undefined\n ? maxWidthValue\n : undefined;\n const maxBpIndex = maxBp ? sortedKeys.indexOf(maxBp) : -1;\n\n for (let i = 0; i < sortedKeys.length; i++) {\n const key = sortedKeys[i];\n const refKey = maxBpIndex >= 0 && i > maxBpIndex ? maxBp! : key;\n const width = breakpoints[refKey];\n if (width === 0) {\n if (i === 0) declarations[\"max-width\"] = literal(\"none\");\n continue;\n }\n if (i === 0) {\n declarations[\"max-width\"] = literal(mediaLen(width));\n } else {\n overrides.push({ breakpoint: key, query: \"min\", declarations: { \"max-width\": literal(mediaLen(width)) } });\n }\n }\n } else if (mode === \"fluid\") {\n if (maxWidthValue !== undefined) {\n declarations[\"max-width\"] = resolveFluidMaxWidth(maxWidthValue, sizeNames, breakpoints);\n }\n } else {\n declarations[\"max-width\"] = literal(typeof mode === \"number\" ? `${mode}px` : mode);\n }\n\n group[variantKeyFor(name)] = { kind: \"recipe\", declarations, overrides };\n };\n\n buildSingleContainer(null, baseConfig);\n for (const [name, raw] of Object.entries(variants)) {\n buildSingleContainer(name, resolveContainerConfig(raw));\n }\n\n // Top-level responsive entries layer media overrides onto the base/target container.\n // (Not exercised by the current fixtures; kept for parity with the old generator.)\n for (const entry of responsiveEntries) {\n const target = entry.target as string | undefined;\n const variantKey = variantKeyFor(target ?? null);\n const ruleSet = group[variantKey];\n if (!ruleSet) continue;\n\n const declarations: Record<string, Ref> = {};\n if (entry.direction) declarations[\"flex-direction\"] = literal(entry.direction as string);\n if (entry.align) declarations[\"align-items\"] = literal(entry.align as string);\n if (entry.justify) declarations[\"justify-content\"] = literal(entry.justify as string);\n if (entry.inset) {\n const insetKey = target ? `container--${target}--inset` : \"container--inset\";\n declarations[\"padding-left\"] = configRef(insetKey);\n declarations[\"padding-right\"] = configRef(insetKey);\n }\n if (entry.gutter) {\n const gutterKey = target ? `container--${target}--gutter` : \"container--gutter\";\n declarations[\"gap\"] = configRef(gutterKey);\n }\n if (Object.keys(declarations).length) {\n ruleSet.overrides.push({\n breakpoint: entry.breakpoint as string,\n query: (entry.query as \"min\" | \"max\" | \"exact\") ?? \"exact\",\n declarations,\n });\n }\n }\n\n return { ruleSetGroups: { container: group }, configProperties };\n};\n\n// ---------------------------------------------------------------------------\n// Orchestration\n// ---------------------------------------------------------------------------\n\n/**\n * Run all four structural generators over the raw layout slice, merging their rule-set groups\n * (structural order: columns → grids → stacks → container) and config tokens. Container always\n * runs; the rest run only when their raw key is present.\n */\nexport const buildLayoutStructural = (\n rawSlice: Record<string, unknown>,\n breakpoints: Record<string, number>,\n mediaConfig?: MediaConfig,\n): LayoutStructuralOutput => {\n const ruleSetGroups: Record<string, RuleSetGroup> = {};\n const configProperties: Record<string, PropertyModel> = {};\n\n const merge = (out: LayoutStructuralOutput | undefined): void => {\n if (!out) return;\n Object.assign(ruleSetGroups, out.ruleSetGroups);\n Object.assign(configProperties, out.configProperties);\n };\n\n merge(buildColumns(rawSlice.columns as ColumnsValue | undefined, breakpoints));\n merge(buildGrids(rawSlice.grids as GridsDefinition | undefined));\n merge(buildStacks(rawSlice.stacks as StacksDefinition | undefined));\n merge(buildContainer(rawSlice.container, breakpoints, collectSizeNames(rawSlice.sizes), mediaConfig));\n\n return { ruleSetGroups, configProperties };\n};\n","/**\n * The layout subsystem — the biggest one, with three parts:\n * 1. Regular property tokens (`spacing` / `gutters` / `aspectRatio`) — like typography/effects,\n * plus the forced `none` variant on spacing/gutters (`finalizeLayoutNormalization`).\n * 2. Recipes (`padding` / `section`) — ordinary token-path recipes (`interpretRecipe`).\n * 3. Structural generators (`columns` / `grids` / `stacks` / `container`) — emitted as native\n * Model rule-sets via the `buildStructural` hook (see `structural.ts`), with the columns/\n * container config knobs riding along as `configProperties` (Model `extraProperties`).\n *\n * It grows the spine's hooks (`interpretRecipe`, `buildStructural`), never the spine's control flow.\n */\n\nimport type { Subsystem, NormalizedProperties } from \"../../core/subsystem\";\nimport type { NormalizedPropertyValue, NormalizedRecipeVariant } from \"../../core/normalize\";\nimport {\n normalizePropertyValue,\n validateNormalizedResponsiveRefs,\n} from \"../../core/normalize\";\nimport type { LayoutRecipeProps } from \"./types\";\nimport { LAYOUT_PROPERTY_KEYS } from \"./types\";\nimport { finalizeLayoutNormalization, scaleStep } from \"./normalize\";\nimport { interpretLayoutRecipeVariant } from \"./recipes\";\nimport { buildLayoutStructural } from \"./structural\";\n\n/** The \"regular\" property keys layout normalizes (the rest are structural / recipes). */\nconst PROPERTY_KEYS: ReadonlySet<string> = new Set(LAYOUT_PROPERTY_KEYS);\n\nexport const layoutSubsystem: Subsystem = {\n key: \"layout\",\n // §10.6 numeric scale synthesis: the fn its synthesized spacing/gutters/sizes steps derive through,\n // so `override()` of a base re-resolves the ramp (mirror colors' `darken`/`lighten`).\n derivations: {\n scaleStep: (value, arg) => scaleStep(value, arg),\n },\n normalizeProperties(rawSlice, ctx): NormalizedProperties {\n const out: NormalizedProperties = {};\n if (!rawSlice) return out;\n\n for (const name of LAYOUT_PROPERTY_KEYS) {\n const value = rawSlice[name];\n if (value === undefined || !PROPERTY_KEYS.has(name)) continue;\n\n const normalized = normalizePropertyValue<unknown, Record<string, unknown>>(value as never, {\n propertyPath: `layout.${name}`,\n allowedBreakpoints: ctx.allowedBreakpoints,\n });\n const finalized = finalizeLayoutNormalization(name, normalized as NormalizedPropertyValue<unknown>);\n validateNormalizedResponsiveRefs(finalized, { propertyPath: `layout.${name}` });\n\n out[name] = finalized as NormalizedPropertyValue<unknown, Record<string, unknown>>;\n }\n\n return out;\n },\n interpretRecipe(variantName, variant, ctx) {\n return interpretLayoutRecipeVariant(\n variantName,\n variant as NormalizedRecipeVariant<LayoutRecipeProps, string>,\n ctx,\n );\n },\n buildStructural(rawSlice, ctx) {\n return buildLayoutStructural(rawSlice, ctx.breakpoints, ctx.mediaConfig);\n },\n};\n\nexport type { LayoutRaw, ContainerRaw, ContainerVariantRaw } from \"./types\";\n","/**\n * Effects' `interpretRecipe` hook â resolves recipe declarations to token-path Refs.\n *\n * An effects recipe prop names a **variant** of the matching property, but the recipe key\n * differs from the token key (`boxShadow` â `shadow`, `transition` â `transitions`) â the\n * resolve-key map bridges them. Each declaration lowers to a format-neutral {@link Ref}\n * carrying the canonical token path (`effects.shadow.lg`, `effects.shadow` for the base) â\n * **no `var(--â¦)` strings**; the CSS adapter maps the path to a `var(--â¦)` at render time.\n *\n * The `blur` compound is the notable reshape: the old `effects/recipes.ts` baked\n * `filter: blur(var(--â¦))` as a `{ value }` literal that **embedded** `var()` â not format-\n * neutral. Here it emits `{ ref: \"effects.blur\", wrap: \"blur\" }`; the adapter's `refToStyleValue`\n * renders `ref.wrap` â `blur(var(--â¦))`, so the wrap lives in the adapter, not the Model.\n */\nimport type { InterpretedRecipeVariant, InterpretedRecipeOverride, Ref } from \"../../core/model\";\nimport type { NormalizedRecipeVariant } from \"../../core/normalize\";\nimport type { RecipeInterpretContext } from \"../../core/subsystem\";\nimport type { EffectsRecipeProps } from \"./types\";\n\nconst RESERVED_KEYS: ReadonlySet<string> = new Set([\n \"breakpoint\",\n \"query\",\n \"state\",\n \"variant\",\n \"target\",\n \"orientation\",\n]);\n\n/** Recipe prop key â CSS declaration property name. `blur` â `filter` (rendered via a wrap). */\nconst PROPERTY_CSS_MAP: Record<string, string> = {\n boxShadow: \"box-shadow\",\n opacity: \"opacity\",\n blur: \"filter\",\n transition: \"transition\",\n zIndex: \"z-index\",\n};\n\n/** Recipe prop key â the effects **property name** (token key) it references. */\nconst RESOLVE_KEY_MAP: Record<string, string> = {\n boxShadow: \"shadow\",\n opacity: \"opacity\",\n blur: \"blur\",\n transition: \"transitions\",\n zIndex: \"zIndex\",\n};\n\n/**\n * Interpret one effects recipe variant into base + responsive/state override declarations,\n * each a token-path {@link Ref}. A responsive `variant:` swap inherits the sibling's base\n * declarations (via `ctx.resolveRecipeVariant`).\n */\nexport const interpretEffectsRecipeVariant = (\n variantName: string,\n variant: NormalizedRecipeVariant<EffectsRecipeProps, string>,\n ctx: RecipeInterpretContext,\n): InterpretedRecipeVariant<string> => {\n const base = interpretProps(variant.base);\n\n const responsive: InterpretedRecipeOverride<string>[] = variant.responsive.map(entry => {\n const { breakpoint, query, state, variant: swap, target, orientation, container, size, ...rawDecls } =\n entry as EffectsRecipeProps & {\n breakpoint?: string;\n query?: \"min\" | \"max\" | \"exact\";\n state?: string;\n variant?: string;\n target?: string;\n orientation?: \"landscape\" | \"portrait\";\n container?: string;\n size?: string;\n };\n\n const inherited = swap ? { ...ctx.resolveRecipeVariant(swap).base } : {};\n const overrides = interpretProps(rawDecls as EffectsRecipeProps);\n\n const override: InterpretedRecipeOverride<string> = {\n declarations: { ...inherited, ...overrides },\n };\n if (breakpoint) {\n override.breakpoint = breakpoint;\n override.query = query ?? \"exact\";\n }\n if (container) {\n override.container = container;\n if (size) override.size = size;\n override.query = query ?? \"min\";\n }\n if (state) override.state = state;\n if (target) override.target = target; // dec.8 — scope onto the `<item>-<target>` sibling\n if (orientation) override.orientation = orientation;\n return override;\n });\n\n return { base, responsive };\n};\n\n/** Interpret a flat declaration block â `cssProperty â Ref`, skipping empty / unknown keys. */\nconst interpretProps = (props: EffectsRecipeProps | undefined): Record<string, Ref> => {\n const declarations: Record<string, Ref> = {};\n if (!props) return declarations;\n\n for (const [key, value] of Object.entries(props)) {\n if (!value || RESERVED_KEYS.has(key)) continue;\n const cssProperty = PROPERTY_CSS_MAP[key];\n const propertyName = RESOLVE_KEY_MAP[key];\n if (!cssProperty || !propertyName) continue;\n\n const ref: Ref = { ref: variantPath(propertyName, value) };\n // The `blur` compound renders as `filter: blur(var(--â¦))` â carried as an adapter wrap,\n // never an embedded `var()` literal (the format-neutrality constraint).\n if (key === \"blur\") ref.wrap = \"blur\";\n declarations[cssProperty] = ref;\n }\n\n return declarations;\n};\n\n/** The token path for a property variant: `effects.<name>` for `\"base\"`, else `effects.<name>.<variant>`. */\nconst variantPath = (propertyName: string, variant: string): string =>\n variant === \"base\" ? `effects.${propertyName}` : `effects.${propertyName}.${variant}`;\n","/**\n * Effects value coercion (§15) — parse/validate authored shadow / transition leaves into the\n * canonical, **format-neutral** Model form.\n *\n * Modeled on `colors/utils.ts`: a single boundary that runs at normalize time (via the subsystem's\n * `coerceValue`) and turns the ergonomic authoring shapes — a flat single leaf or an array of leaves\n * — into ONE canonical representation the Model carries on `Ref.struct`:\n *\n * - **shadow** → {@link ShadowLayer}`[]` (always an array, even single-layer); `color` kept as its\n * `colors.*` token-path string (never an embedded `rgba()` — §15.1), resolved late by the adapter.\n * A translucent shadow references a translucent colour (an `alpha` colour variant — §13.3).\n * - **transitions** → {@link TransitionPart}`[]`; `duration`/`delay` in ms.\n *\n * **Structured-only (§15.2, amended 2026-07-16):** raw CSS strings are REJECTED — the ONLY accepted\n * string is the keyword `\"none\"` (no shadow / no transition). Every other string throws a path-labelled\n * error. Serialization to CSS text stays in the adapter; this module holds structure, not format. Its\n * only core dependency is the shared length parser (`parseLength`, §21) — so a pinned geometry string\n * (`offsetY: \"1px\"`) is parsed by the same grammar every length uses, rather than a duplicate here.\n */\n\nimport { RefractError } from \"../../core/errors\";\nimport type { ShadowLayer, TransitionPart } from \"../../core/model\";\nimport { parseLength, type ShadowDimension } from \"../../core/units\";\n\n/** A single authored shadow layer (flat leaf object) — geometry as a bare number (deferred, resolved by\n * the §21 unit pass) or a pinned length string (`\"1px\"`, `\"0.5rem\"`) + a `colors.*` color ref\n * (translucency comes from an `alpha` colour variant, not a shadow field). */\nexport type ShadowLayerInput = {\n offsetX?: number | string;\n offsetY?: number | string;\n blur?: number | string;\n spread?: number | string;\n color?: string;\n inset?: boolean;\n};\n\n/** An authored shadow value: a flat single layer, an array of layers, or the `\"none\"` keyword. */\nexport type ShadowInput = \"none\" | ShadowLayerInput | ShadowLayerInput[];\n\n/** A single authored transition part — `property` (required) + ms durations + timing keyword. */\nexport type TransitionPartInput = {\n property?: string;\n duration?: number;\n timingFunction?: string;\n delay?: number;\n};\n\n/** An authored transition value: a flat single part, an array of parts, or the `\"none\"` keyword. */\nexport type TransitionInput = \"none\" | TransitionPartInput | TransitionPartInput[];\n\n/** The canonical Model form of a shadow value — an array of layers, or the `\"none\"` keyword. */\nexport type ShadowCanonical = \"none\" | ShadowLayer[];\n\n/** The canonical Model form of a transition value — an array of parts, or the `\"none\"` keyword. */\nexport type TransitionCanonical = \"none\" | TransitionPart[];\n\nconst isPlainObject = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null && !Array.isArray(value);\n\n/** Assert a leaf field is a number (or absent), with a path-labelled friendly error. */\nconst numberField = (value: unknown, label: string): number | undefined => {\n if (value === undefined) return undefined;\n if (typeof value !== \"number\" || Number.isNaN(value)) {\n throw new RefractError(\"REFRACT_E_EFFECTS\", `${label} must be a number, received ${JSON.stringify(value)}.`);\n }\n return value;\n};\n\n/**\n * A shadow-geometry length field (§21/§22) — a bare number stays **deferred** (the unit pass resolves\n * it against the `effects.shadow` role); a `<number><unit>` string is **pinned** (`\"1px\"` → `{value,unit}`,\n * trusted verbatim). A bare numeric string is deferred. Functions/keywords (no unit grammar) throw.\n */\nconst dimensionField = (value: unknown, label: string): ShadowDimension | undefined => {\n if (value === undefined) return undefined;\n if (typeof value === \"number\") {\n if (Number.isNaN(value)) throw new RefractError(\"REFRACT_E_EFFECTS\", `${label} must be a number or length string, received ${JSON.stringify(value)}.`);\n return value;\n }\n if (typeof value === \"string\") {\n const parsed = parseLength(value);\n if (\"raw\" in parsed) {\n throw new RefractError(\"REFRACT_E_EFFECTS\", `${label} must be a number or a <number><unit> length (received ${JSON.stringify(value)}).`);\n }\n return parsed.unit === undefined ? parsed.value : { value: parsed.value, unit: parsed.unit };\n }\n throw new RefractError(\"REFRACT_E_EFFECTS\", `${label} must be a number or length string, received ${JSON.stringify(value)}.`);\n};\n\n// ---------------------------------------------------------------------------\n// Shadow\n// ---------------------------------------------------------------------------\n\nconst SHADOW_FIELDS: ReadonlySet<string> = new Set([\n \"offsetX\",\n \"offsetY\",\n \"blur\",\n \"spread\",\n \"color\",\n \"inset\",\n]);\n\n/** Validate + normalize one authored shadow layer into a canonical {@link ShadowLayer}. */\nconst coerceShadowLayer = (layer: ShadowLayerInput, label: string): ShadowLayer => {\n if (!isPlainObject(layer)) {\n throw new RefractError(\"REFRACT_E_EFFECTS\", `${label} must be a shadow-layer object, received ${JSON.stringify(layer)}.`);\n }\n for (const key of Object.keys(layer)) {\n if (!SHADOW_FIELDS.has(key)) {\n throw new RefractError(\n \"REFRACT_E_EFFECTS\",\n `${label} has unknown shadow field \"${key}\" (allowed: ${[...SHADOW_FIELDS].join(\", \")}).`,\n );\n }\n }\n\n const out: ShadowLayer = {};\n const offsetX = dimensionField(layer.offsetX, `${label}.offsetX`);\n const offsetY = dimensionField(layer.offsetY, `${label}.offsetY`);\n const blur = dimensionField(layer.blur, `${label}.blur`);\n const spread = dimensionField(layer.spread, `${label}.spread`);\n if (offsetX !== undefined) out.offsetX = offsetX;\n if (offsetY !== undefined) out.offsetY = offsetY;\n if (blur !== undefined) out.blur = blur;\n if (spread !== undefined) out.spread = spread;\n if (layer.color !== undefined) {\n if (typeof layer.color !== \"string\" || !layer.color) {\n throw new RefractError(\"REFRACT_E_EFFECTS\", `${label}.color must be a \"colors.*\" token-path string.`);\n }\n out.color = layer.color;\n }\n if (layer.inset !== undefined) {\n if (typeof layer.inset !== \"boolean\") {\n throw new RefractError(\"REFRACT_E_EFFECTS\", `${label}.inset must be a boolean.`);\n }\n if (layer.inset) out.inset = true;\n }\n return out;\n};\n\n/**\n * Coerce an authored shadow value into its canonical Model form. A string passes through (escape\n * hatch); a flat leaf becomes a one-element `ShadowLayer[]`; an array becomes a multi-layer\n * `ShadowLayer[]`. `label` is the property path for friendly errors.\n */\nexport const coerceShadowValue = (input: ShadowInput, label = \"effects.shadow\"): ShadowCanonical => {\n if (typeof input === \"string\") {\n if (input === \"none\") return \"none\";\n throw new RefractError(\n \"REFRACT_E_EFFECTS\",\n `${label} must be structured shadow layer(s) or \"none\" — raw CSS strings are not accepted (received ${JSON.stringify(input)}).`,\n );\n }\n if (Array.isArray(input)) {\n if (!input.length) throw new RefractError(\"REFRACT_E_EFFECTS\", `${label} is an empty shadow-layer array.`);\n return input.map((layer, i) => coerceShadowLayer(layer, `${label}[${i}]`));\n }\n return [coerceShadowLayer(input, label)];\n};\n\n// ---------------------------------------------------------------------------\n// Transitions\n// ---------------------------------------------------------------------------\n\nconst TRANSITION_FIELDS: ReadonlySet<string> = new Set([\n \"property\",\n \"duration\",\n \"timingFunction\",\n \"delay\",\n]);\n\n/** Validate + normalize one authored transition part into a canonical {@link TransitionPart}. */\nconst coerceTransitionPart = (part: TransitionPartInput, label: string): TransitionPart => {\n if (!isPlainObject(part)) {\n throw new RefractError(\"REFRACT_E_EFFECTS\", `${label} must be a transition-part object, received ${JSON.stringify(part)}.`);\n }\n for (const key of Object.keys(part)) {\n if (!TRANSITION_FIELDS.has(key)) {\n throw new RefractError(\n \"REFRACT_E_EFFECTS\",\n `${label} has unknown transition field \"${key}\" (allowed: ${[...TRANSITION_FIELDS].join(\", \")}).`,\n );\n }\n }\n if (typeof part.property !== \"string\" || !part.property) {\n throw new RefractError(\"REFRACT_E_EFFECTS\", `${label}.property is required (the CSS property to transition).`);\n }\n\n const out: TransitionPart = { property: part.property };\n const duration = numberField(part.duration, `${label}.duration`);\n const delay = numberField(part.delay, `${label}.delay`);\n if (duration !== undefined) out.duration = duration;\n if (part.timingFunction !== undefined) {\n if (typeof part.timingFunction !== \"string\" || !part.timingFunction) {\n throw new RefractError(\"REFRACT_E_EFFECTS\", `${label}.timingFunction must be a keyword or cubic-bezier(...) string.`);\n }\n out.timingFunction = part.timingFunction;\n }\n if (delay !== undefined) out.delay = delay;\n return out;\n};\n\n/**\n * Coerce an authored transition value into its canonical Model form. A string passes through; a flat\n * part becomes a one-element `TransitionPart[]`; an array becomes a multi-part `TransitionPart[]`.\n */\nexport const coerceTransitionValue = (\n input: TransitionInput,\n label = \"effects.transitions\",\n): TransitionCanonical => {\n if (typeof input === \"string\") {\n if (input === \"none\") return \"none\";\n throw new RefractError(\n \"REFRACT_E_EFFECTS\",\n `${label} must be structured transition part(s) or \"none\" — raw CSS strings are not accepted (received ${JSON.stringify(input)}).`,\n );\n }\n if (Array.isArray(input)) {\n if (!input.length) throw new RefractError(\"REFRACT_E_EFFECTS\", `${label} is an empty transition-part array.`);\n return input.map((part, i) => coerceTransitionPart(part, `${label}[${i}]`));\n }\n return [coerceTransitionPart(input, label)];\n};\n","/**\n * The effects subsystem — a \"regular\" subsystem with no property finalize hook (values\n * pass straight through the shared normalize). Iterates `raw.effects` (skipping the\n * reserved `recipes` key) and interprets recipes into token-path refs (incl. the `blur`\n * compound as a `{ ref, wrap: \"blur\" }` ref). It grows a hook, never the spine.\n */\n\nimport type { Subsystem, NormalizedProperties } from \"../../core/subsystem\";\nimport type { NormalizedPropertyValue, NormalizedRecipeVariant } from \"../../core/normalize\";\nimport {\n normalizePropertyValue,\n validateNormalizedResponsiveRefs,\n} from \"../../core/normalize\";\nimport type { EffectsRecipeProps } from \"./types\";\nimport { interpretEffectsRecipeVariant } from \"./recipes\";\nimport { coerceShadowValue, coerceTransitionValue } from \"./utils\";\nimport type { ShadowInput, TransitionInput } from \"./utils\";\n\n/** Sub-keys of `raw.effects` that are not properties. */\nconst RESERVED_KEYS: ReadonlySet<string> = new Set([\"recipes\"]);\n\n/**\n * §15 object-leaf properties: the value-field set the core assembles into the base (vs `TExtra`\n * siblings), plus a per-property `coerceValue` that canonicalizes each leaf into the Model's\n * structured form (or passes a raw string through). Scalar properties (blur/opacity/zIndex) appear\n * here NOT at all → they take the plain primitive path (no `leafFields`, no coerce).\n */\nconst SHADOW_LEAF_FIELDS = [\"offsetX\", \"offsetY\", \"blur\", \"spread\", \"color\", \"inset\"] as const;\nconst TRANSITION_LEAF_FIELDS = [\"property\", \"duration\", \"timingFunction\", \"delay\"] as const;\n\nconst LEAF_FIELDS: Record<string, readonly string[]> = {\n shadow: SHADOW_LEAF_FIELDS,\n transitions: TRANSITION_LEAF_FIELDS,\n};\n\n/** Per-property value coercion (§15). A property absent here is a plain scalar (no coercion). */\nconst coerceFor = (name: string): ((value: unknown) => unknown) | undefined => {\n if (name === \"shadow\") return value => coerceShadowValue(value as ShadowInput, `effects.${name}`);\n if (name === \"transitions\") return value => coerceTransitionValue(value as TransitionInput, `effects.${name}`);\n return undefined;\n};\n\nexport const effectsSubsystem: Subsystem = {\n key: \"effects\",\n normalizeProperties(rawSlice, ctx): NormalizedProperties {\n const out: NormalizedProperties = {};\n if (!rawSlice) return out;\n\n for (const [name, value] of Object.entries(rawSlice)) {\n if (RESERVED_KEYS.has(name)) continue;\n\n const leafFields = LEAF_FIELDS[name];\n const coerceValue = coerceFor(name);\n const normalized = normalizePropertyValue<unknown>(value as never, {\n propertyPath: `effects.${name}`,\n allowedBreakpoints: ctx.allowedBreakpoints,\n ...(leafFields ? { leafFields } : {}),\n ...(coerceValue ? { coerceValue } : {}),\n // §15.2 (amended): no `base` key — a property with only variants/modes (no top-level leaves)\n // has an implicit `\"none\"` base (the coerce keyword), instead of failing base resolution.\n ...(leafFields ? { fallbackBase: \"none\" } : {}),\n });\n validateNormalizedResponsiveRefs(normalized, { propertyPath: `effects.${name}` });\n\n out[name] = normalized as NormalizedPropertyValue<unknown, Record<string, unknown>>;\n }\n\n return out;\n },\n interpretRecipe(variantName, variant, ctx) {\n return interpretEffectsRecipeVariant(\n variantName,\n variant as NormalizedRecipeVariant<EffectsRecipeProps, string>,\n ctx,\n );\n },\n};\n\nexport type { EffectsRaw, EffectsPropertyValue } from \"./types\";\n","/**\n * Borders' `interpretRecipe` hook (§14.2) — resolves recipe declarations to token-path Refs.\n *\n * The novel logic vs a fixed prop→css map: the CSS property is **computed** from\n * `(as, side, aspect)`. `as` (the render target, default `\"border\"`) + the optional per-side\n * modifier route each geometry aspect to its longhand:\n * - `border` + `left` + `width` → `border-left-width`\n * - `outline` + `width` → `outline-width`\n * - `border` + `radius` → `border-radius` (radius is border-only edge geometry)\n * - `outline` + `offset` → `outline-offset` (offset is outline-only)\n * - `outline` + `color` → `outline-color`\n *\n * Geometry aspects (`width`/`style`/`offset`/`radius`) name a **variant** of the matching borders\n * property by bare name — lowered to a `borders.<aspect>[.<variant>]` {@link Ref}. `color` is the\n * value-level exception (§14.4): its value is already a `colors.*` **token** path, passed straight\n * through as `{ ref: \"colors.*\" }` — the CSS adapter resolves it against the global path→var map\n * (colors is processed first). No `var(--…)` strings — the adapter maps paths to vars at render.\n */\nimport type { InterpretedRecipeVariant, InterpretedRecipeOverride, Ref } from \"../../core/model\";\nimport type { NormalizedRecipeVariant } from \"../../core/normalize\";\nimport type { RecipeInterpretContext } from \"../../core/subsystem\";\nimport type { BordersRecipeProps } from \"./types\";\n\nconst RESERVED_KEYS: ReadonlySet<string> = new Set([\n \"breakpoint\",\n \"query\",\n \"state\",\n \"variant\",\n \"target\",\n \"orientation\",\n \"container\",\n \"size\",\n]);\n\n/** The recipe modifiers (not geometry aspects) — stripped before interpreting declarations. */\nconst MODIFIER_KEYS: ReadonlySet<string> = new Set([\"as\", \"side\"]);\n\n/** The geometry aspects a borders recipe can declare (plus the value-level `color`). */\nconst ASPECT_KEYS: ReadonlySet<string> = new Set([\"width\", \"style\", \"offset\", \"radius\", \"color\"]);\n\ntype RenderTarget = \"border\" | \"outline\";\ntype Side = \"top\" | \"right\" | \"bottom\" | \"left\";\n\n/**\n * Compute the CSS declaration property for one aspect from the render target + side (§14.2).\n * `radius` is always `border-radius` (border-only edge geometry); `offset` is always\n * `outline-offset` (outline-only). The rest fan out per `(as, side)`.\n */\nconst cssPropertyFor = (as: RenderTarget, side: Side | undefined, aspect: string): string => {\n if (aspect === \"radius\") return \"border-radius\";\n if (aspect === \"offset\") return \"outline-offset\";\n if (as === \"outline\") return `outline-${aspect}`;\n return side ? `border-${side}-${aspect}` : `border-${aspect}`;\n};\n\n/** The token-path Ref for one aspect value: a `colors.*` passthrough for `color`, else a borders variant path. */\nconst refFor = (aspect: string, value: string): Ref => {\n if (aspect === \"color\") return { ref: value }; // value is already a `colors.*` token path\n return { ref: value === \"base\" ? `borders.${aspect}` : `borders.${aspect}.${value}` };\n};\n\n/** Interpret a flat declaration block → `cssProperty → Ref`, given the variant's `as`/`side` modifiers. */\nconst interpretProps = (\n props: BordersRecipeProps | undefined,\n as: RenderTarget,\n side: Side | undefined,\n): Record<string, Ref> => {\n const declarations: Record<string, Ref> = {};\n if (!props) return declarations;\n\n for (const [key, value] of Object.entries(props)) {\n if (!value || RESERVED_KEYS.has(key) || MODIFIER_KEYS.has(key) || !ASPECT_KEYS.has(key)) continue;\n declarations[cssPropertyFor(as, side, key)] = refFor(key, value);\n }\n\n return declarations;\n};\n\n/**\n * Interpret one borders recipe variant into base + responsive/state override declarations, each a\n * token-path {@link Ref}. `as`/`side` are read from the variant base (the render target is a\n * variant-level identity); a responsive entry may override them, else it inherits the base's. A\n * responsive `variant:` swap inherits the sibling's already-interpreted base declarations.\n */\nexport const interpretBordersRecipeVariant = (\n variantName: string,\n variant: NormalizedRecipeVariant<BordersRecipeProps, string>,\n ctx: RecipeInterpretContext,\n): InterpretedRecipeVariant<string> => {\n const baseAs = (variant.base.as as RenderTarget) ?? \"border\";\n const baseSide = variant.base.side as Side | undefined;\n const base = interpretProps(variant.base, baseAs, baseSide);\n\n const responsive: InterpretedRecipeOverride<string>[] = variant.responsive.map(entry => {\n const {\n breakpoint,\n query,\n state,\n variant: swap,\n target,\n orientation,\n container,\n size,\n as: entryAs,\n side: entrySide,\n ...rawDecls\n } = entry as BordersRecipeProps & {\n breakpoint?: string;\n query?: \"min\" | \"max\" | \"exact\";\n state?: string;\n variant?: string;\n target?: string;\n orientation?: \"landscape\" | \"portrait\";\n container?: string;\n size?: string;\n };\n\n const as = (entryAs as RenderTarget) ?? baseAs;\n const side = (entrySide as Side | undefined) ?? baseSide;\n\n const inherited = swap ? { ...ctx.resolveRecipeVariant(swap).base } : {};\n const overrides = interpretProps(rawDecls as BordersRecipeProps, as, side);\n\n const override: InterpretedRecipeOverride<string> = {\n declarations: { ...inherited, ...overrides },\n };\n if (breakpoint) {\n override.breakpoint = breakpoint;\n override.query = query ?? \"exact\";\n }\n if (container) {\n override.container = container;\n if (size) override.size = size;\n override.query = query ?? \"min\";\n }\n if (state) override.state = state;\n if (orientation) override.orientation = orientation;\n if (target) override.target = target; // dec.8 — scope onto the `<item>-<target>` sibling\n return override;\n });\n\n return { base, responsive };\n};\n","/**\n * The borders subsystem (§14) — a \"regular\" subsystem (no property finalize hook; values pass\n * straight through the shared normalize) carved out of effects. Owns the stroke geometry\n * vocabulary (width / style / offset / radius) and interprets border/outline recipes via the\n * `(as, side, aspect)` → css-property computation, with `color` a value-level `colors.*` ref.\n * It grows a hook, never the spine.\n */\n\nimport type { Subsystem, NormalizedProperties } from \"../../core/subsystem\";\nimport type { NormalizedPropertyValue, NormalizedRecipeVariant } from \"../../core/normalize\";\nimport {\n normalizePropertyValue,\n validateNormalizedResponsiveRefs,\n} from \"../../core/normalize\";\nimport type { BordersRecipeProps } from \"./types\";\nimport { interpretBordersRecipeVariant } from \"./recipes\";\n\n/** Sub-keys of `raw.borders` that are not properties. */\nconst RESERVED_KEYS: ReadonlySet<string> = new Set([\"recipes\"]);\n\nexport const bordersSubsystem: Subsystem = {\n key: \"borders\",\n normalizeProperties(rawSlice, ctx): NormalizedProperties {\n const out: NormalizedProperties = {};\n if (!rawSlice) return out;\n\n for (const [name, value] of Object.entries(rawSlice)) {\n if (RESERVED_KEYS.has(name)) continue;\n\n const normalized = normalizePropertyValue<unknown>(value as never, {\n propertyPath: `borders.${name}`,\n allowedBreakpoints: ctx.allowedBreakpoints,\n });\n validateNormalizedResponsiveRefs(normalized, { propertyPath: `borders.${name}` });\n\n out[name] = normalized as NormalizedPropertyValue<unknown, Record<string, unknown>>;\n }\n\n return out;\n },\n interpretRecipe(variantName, variant, ctx) {\n return interpretBordersRecipeVariant(\n variantName,\n variant as NormalizedRecipeVariant<BordersRecipeProps, string>,\n ctx,\n );\n },\n};\n\nexport type { BordersRaw, BordersPropertyValue } from \"./types\";\n","/**\n * Animation's `interpretRecipe` hook (§10.2) â resolves an animation recipe variant into the\n * `animation-*` longhand {@link Ref}s the CSS adapter composes into an `animation:` shorthand.\n *\n * `duration`/`easing`/`delay` name a **variant** of the matching motion-token property (mirrors the\n * effects interpreter's variant-path resolution) â `animation.<prop>[.<variant>]` token-path refs.\n * `keyframes` names a keyframe â an `animation.keyframes.<name>` ref the adapter resolves to the bare\n * keyframe identifier. Remaining `animation-*` literals pass through as `{ value }`. No `var(--â¦)`\n * strings â the adapter maps paths to vars (and the keyframe ref to a name) at render time.\n */\nimport type { InterpretedRecipeVariant, InterpretedRecipeOverride, Ref } from \"../../core/model\";\nimport type { NormalizedRecipeVariant } from \"../../core/normalize\";\nimport type { RecipeInterpretContext } from \"../../core/subsystem\";\nimport type { AnimationRecipeProps } from \"./types\";\n\nconst RESERVED_KEYS: ReadonlySet<string> = new Set([\n \"breakpoint\",\n \"query\",\n \"state\",\n \"variant\",\n \"target\",\n \"orientation\",\n]);\n\n/** Recipe prop key â the `animation-*` longhand CSS property it contributes to the shorthand. */\nconst PROPERTY_CSS_MAP: Record<string, string> = {\n keyframes: \"animation-name\",\n duration: \"animation-duration\",\n easing: \"animation-timing-function\",\n delay: \"animation-delay\",\n iterationCount: \"animation-iteration-count\",\n direction: \"animation-direction\",\n fillMode: \"animation-fill-mode\",\n playState: \"animation-play-state\",\n};\n\n/** Recipe prop key â the motion-token **property name** whose variant it references. */\nconst RESOLVE_KEY_MAP: Record<string, string> = {\n duration: \"duration\",\n easing: \"easing\",\n delay: \"delay\",\n};\n\n/** The token path for a motion-token variant: `animation.<name>` for `\"base\"`, else `animation.<name>.<variant>`. */\nconst variantPath = (propertyName: string, variant: string): string =>\n variant === \"base\" ? `animation.${propertyName}` : `animation.${propertyName}.${variant}`;\n\n/** Interpret a flat animation-recipe declaration block â `animation-* â Ref`, skipping empty/unknown keys. */\nconst interpretProps = (props: AnimationRecipeProps | undefined): Record<string, Ref> => {\n const declarations: Record<string, Ref> = {};\n if (!props) return declarations;\n\n for (const [key, value] of Object.entries(props)) {\n if (value === undefined || value === \"\" || RESERVED_KEYS.has(key)) continue;\n const cssProperty = PROPERTY_CSS_MAP[key];\n if (!cssProperty) continue;\n\n if (key === \"keyframes\") {\n declarations[cssProperty] = { ref: `animation.keyframes.${value}` };\n } else if (RESOLVE_KEY_MAP[key]) {\n declarations[cssProperty] = { ref: variantPath(RESOLVE_KEY_MAP[key], String(value)) };\n } else {\n // Literal `animation-*` sub-property (iteration-count / direction / fill-mode / play-state).\n declarations[cssProperty] = { value: value as string | number };\n }\n }\n\n return declarations;\n};\n\n/**\n * Interpret one animation recipe variant into base + responsive/state override declarations, each an\n * `animation-*` longhand {@link Ref}. A responsive `variant:` swap inherits the sibling's base\n * declarations (via `ctx.resolveRecipeVariant`), exactly like the effects interpreter.\n */\nexport const interpretAnimationRecipeVariant = (\n variantName: string,\n variant: NormalizedRecipeVariant<AnimationRecipeProps, string>,\n ctx: RecipeInterpretContext,\n): InterpretedRecipeVariant<string> => {\n const base = interpretProps(variant.base);\n\n const responsive: InterpretedRecipeOverride<string>[] = variant.responsive.map(entry => {\n const { breakpoint, query, state, variant: swap, target, orientation, container, size, ...rawDecls } =\n entry as AnimationRecipeProps & {\n breakpoint?: string;\n query?: \"min\" | \"max\" | \"exact\";\n state?: string;\n variant?: string;\n target?: string;\n orientation?: \"landscape\" | \"portrait\";\n container?: string;\n size?: string;\n };\n\n const inherited = swap ? { ...ctx.resolveRecipeVariant(swap).base } : {};\n const overrides = interpretProps(rawDecls as AnimationRecipeProps);\n\n const override: InterpretedRecipeOverride<string> = {\n declarations: { ...inherited, ...overrides },\n };\n if (breakpoint) {\n override.breakpoint = breakpoint;\n override.query = query ?? \"exact\";\n }\n if (container) {\n override.container = container;\n if (size) override.size = size;\n override.query = query ?? \"min\";\n }\n if (state) override.state = state;\n if (target) override.target = target; // dec.8 — scope onto the `<item>-<target>` sibling\n if (orientation) override.orientation = orientation;\n return override;\n });\n\n return { base, responsive };\n};\n","/**\n * The animation subsystem (§10.2).\n *\n * Owns three things: **motion tokens** (`duration`/`easing`/`delay`) via the shared property\n * normalize (like effects — no finalize hook), **animation-shorthand recipes** via `interpretRecipe`,\n * and **keyframes** via the generic `buildStructural` hook (the third `buildStructural` user, after\n * layout + reset). Keyframes are the new Model primitive: a named, ordered `{ stop, declarations }`\n * step list carried on `SubsystemModel.keyframes` — neither a token nor a rule-set. It grows a hook,\n * never the spine. Transitions stay in `effects` (golden-locked).\n */\nimport type { NormalizedProperties, StructuralOutput, Subsystem } from \"../../core/subsystem\";\nimport type { NormalizedPropertyValue, NormalizedRecipeVariant } from \"../../core/normalize\";\nimport {\n normalizePropertyValue,\n validateNormalizedResponsiveRefs,\n} from \"../../core/normalize\";\nimport type { Keyframe, KeyframeStep, Ref } from \"../../core/model\";\nimport type { AnimationRecipeProps, KeyframeDefinition, KeyframeStepDeclarations } from \"./types\";\nimport { interpretAnimationRecipeVariant } from \"./recipes\";\n\n/** Sub-keys of `raw.animation` that are not motion-token properties. */\nconst RESERVED_KEYS: ReadonlySet<string> = new Set([\"keyframes\", \"recipes\"]);\n\n/** A keyframe step declaration value → a {@link Ref}: `{ ref }` for a token reference, else a literal. */\nconst declarationRef = (value: unknown): Ref | undefined => {\n if (value && typeof value === \"object\" && \"ref\" in (value as Record<string, unknown>)) {\n return { ref: String((value as { ref: unknown }).ref) };\n }\n if (typeof value === \"string\" || typeof value === \"number\") return { value };\n return undefined;\n};\n\n/** Parse one step's declarations (`property → literal | { ref }`) into `property → Ref`. */\nconst parseStepDeclarations = (raw: KeyframeStepDeclarations): Record<string, Ref> => {\n const out: Record<string, Ref> = {};\n for (const [property, value] of Object.entries(raw)) {\n const ref = declarationRef(value);\n if (ref) out[property] = ref;\n }\n return out;\n};\n\n/** Parse one keyframe definition (stop → declarations) into an ordered {@link Keyframe}. */\nconst parseKeyframe = (raw: KeyframeDefinition): Keyframe => {\n const steps: KeyframeStep[] = [];\n for (const [stop, declarations] of Object.entries(raw)) {\n steps.push({ stop, declarations: parseStepDeclarations(declarations) });\n }\n return { steps };\n};\n\n/** The `animation.keyframes` slice → `name → {@link Keyframe}`. */\nconst buildKeyframes = (raw: unknown): Record<string, Keyframe> => {\n if (!raw || typeof raw !== \"object\") return {};\n const out: Record<string, Keyframe> = {};\n for (const [name, definition] of Object.entries(raw as Record<string, KeyframeDefinition>)) {\n if (definition && typeof definition === \"object\") out[name] = parseKeyframe(definition);\n }\n return out;\n};\n\nexport const animationSubsystem: Subsystem = {\n key: \"animation\",\n normalizeProperties(rawSlice, ctx): NormalizedProperties {\n const out: NormalizedProperties = {};\n if (!rawSlice) return out;\n\n for (const [name, value] of Object.entries(rawSlice)) {\n if (RESERVED_KEYS.has(name)) continue;\n\n const normalized = normalizePropertyValue<unknown>(value as never, {\n propertyPath: `animation.${name}`,\n allowedBreakpoints: ctx.allowedBreakpoints,\n });\n validateNormalizedResponsiveRefs(normalized, { propertyPath: `animation.${name}` });\n\n out[name] = normalized as NormalizedPropertyValue<unknown, Record<string, unknown>>;\n }\n\n return out;\n },\n interpretRecipe(variantName, variant, ctx) {\n return interpretAnimationRecipeVariant(\n variantName,\n variant as NormalizedRecipeVariant<AnimationRecipeProps, string>,\n ctx,\n );\n },\n buildStructural(rawSlice): StructuralOutput {\n return {\n ruleSetGroups: {},\n configProperties: {},\n keyframes: buildKeyframes((rawSlice as { keyframes?: unknown }).keyframes),\n };\n },\n};\n\nexport type { AnimationRaw } from \"./types\";\n","/**\n * Components' `interpretRecipe` hook — the composition interpreter.\n *\n * A component variant carries cross-subsystem references (`colors: \"solid.primary\"`) that are\n * NOT declarations (they're extracted separately as Model `references` pointers) plus an own\n * `css` delta. This interpreter emits ONLY the own-delta declarations, each a format-neutral\n * {@link Ref}. The delta is **literal-first**: a bare string / number value is a raw CSS literal\n * → `{ value }`; a `ref(\"…\")` / `{ ref: \"…\" }` marker is a token path → `{ ref }` (the adapter lowers\n * it to `var(--…)` against the global token union). The\n * referenced recipes' own states ride along on their shared classes (via the `references`\n * pointers), so the component only emits its own delta + own states — which win at equal\n * specificity by later source order.\n */\nimport type { InterpretedRecipeVariant, InterpretedRecipeOverride, Ref } from \"../../core/model\";\nimport type { NormalizedRecipeVariant } from \"../../core/normalize\";\nimport type { RecipeInterpretContext } from \"../../core/subsystem\";\nimport type { ComponentsRecipeProps, CssDeltaValue } from \"./types\";\n\n/**\n * Interpret one component variant into base + state/responsive override declarations from its\n * `css` delta. Cross-subsystem references are handled by `extractComponentReferences`, not here.\n */\nexport const interpretComponentsRecipeVariant = (\n _variantName: string,\n variant: NormalizedRecipeVariant<ComponentsRecipeProps, string>,\n _ctx: RecipeInterpretContext,\n): InterpretedRecipeVariant<string> => {\n const base = interpretCssDelta((variant.base as ComponentsRecipeProps).css);\n\n const responsive: InterpretedRecipeOverride<string>[] = variant.responsive.map(entry => {\n const e = entry as ComponentsRecipeProps & {\n breakpoint?: string;\n query?: \"min\" | \"max\" | \"exact\";\n state?: string;\n orientation?: \"landscape\" | \"portrait\";\n container?: string;\n size?: string;\n target?: string;\n };\n const override: InterpretedRecipeOverride<string> = {\n declarations: interpretCssDelta(e.css),\n };\n if (e.breakpoint) {\n override.breakpoint = e.breakpoint;\n override.query = e.query ?? \"exact\";\n }\n if (e.container) {\n override.container = e.container;\n if (e.size) override.size = e.size;\n override.query = e.query ?? \"min\";\n }\n if (e.state) override.state = e.state;\n if (e.orientation) override.orientation = e.orientation;\n if (e.target) override.target = e.target; // dec.8 — scope onto the `<item>-<target>` sibling\n return override;\n });\n\n return { base, responsive };\n};\n\n/** A component `css` delta (`{ color, boxShadow }`) → `formattedProperty → Ref` (ref-first, §19). */\nconst interpretCssDelta = (\n css: Record<string, CssDeltaValue> | undefined,\n): Record<string, Ref> => {\n const declarations: Record<string, Ref> = {};\n if (!css) return declarations;\n for (const [property, value] of Object.entries(css)) {\n declarations[formatPropertyName(property)] = cssValueToRef(value);\n }\n return declarations;\n};\n\n/**\n * One `css` delta value → a {@link Ref} (literal-first): a bare `string` or `number` is a raw literal\n * → `{ value }`; the `{ ref: \"…\" }` object (produced by the `ref()` helper or authored directly in JSON)\n * is a token path → `{ ref }`, lowered to `var(--…)` by the adapter.\n */\nconst cssValueToRef = (value: CssDeltaValue): Ref => {\n if (typeof value === \"object\") return { ref: value.ref };\n return { value };\n};\n\n/** Format an authored CSS property name to its declaration name (`boxShadow` → `box-shadow`). */\nconst formatPropertyName = (property: string): string => {\n if (property.startsWith(\"--\")) return property;\n return property\n .replace(/_/g, \"-\")\n .replace(/([a-z0-9])([A-Z])/g, \"$1-$2\")\n .toLowerCase();\n};\n","/**\n * The components (composition) subsystem.\n *\n * Owns **no primitive properties** (the property pipeline never runs — `normalizeProperties`\n * returns empty). It contributes only recipes that reference other subsystems' recipes plus an\n * own `css` delta. The generic recipe path drives `interpretRecipe` (own delta → refs) and, via\n * the `extractReferences` hook, keeps each variant's cross-subsystem references as Model pointers\n * (`\"colors:solid.primary\"`) so the referenced recipe's states ride along on its shared class.\n * It grows a hook, never the spine.\n */\n\nimport type { Subsystem, NormalizedProperties } from \"../../core/subsystem\";\nimport type { NormalizedRecipeVariant } from \"../../core/normalize\";\nimport { extractComponentReferences } from \"../../core/model\";\nimport type { ComponentsRecipeProps } from \"./types\";\nimport { interpretComponentsRecipeVariant } from \"./recipes\";\n\nexport const componentsSubsystem: Subsystem = {\n key: \"components\",\n // No property pipeline — components own no primitive tokens.\n normalizeProperties(): NormalizedProperties {\n return {};\n },\n interpretRecipe(variantName, variant, ctx) {\n return interpretComponentsRecipeVariant(\n variantName,\n variant as NormalizedRecipeVariant<ComponentsRecipeProps, string>,\n ctx,\n );\n },\n extractReferences(normalizedVariantBase) {\n return extractComponentReferences(normalizedVariantBase);\n },\n};\n\nexport type { ComponentsRecipeProps, ResolvedComponentClass, ComponentsRaw } from \"./types\";\n","/**\n * The globals preset library (§9, formerly §10.1 reset) — the single, format-neutral source for the\n * static normalization rule-sets and the default `h1`–`h6` → type-scale map.\n *\n * These produce Model {@link RuleSet}s (declarations are `{ value }` literals for the static\n * layer, `{ ref }` token paths for the default heading map), so every web adapter shares one\n * source (à la `color-math`) and lowers them itself. No CSS strings here — the adapter wraps\n * each `selector` in `:where(…)` (specificity-0) and orders reset ahead of recipes.\n *\n * Layers:\n * - **static** — literal-declaration rule-sets that strip UA opinions (box model, margins,\n * heading sizing, list markers, form typography, media block/max-width, anchor colour).\n * - **default headings** — themed rule-sets binding `h1`–`h6` to typography's ratio-generated\n * `fontSize` scale variants (`typography.fontSize.4xl` …). Opportunistic: the adapter drops a\n * heading whose scale step wasn't generated (a theme with a ratio-less `fontSize`).\n */\n\nimport { RefractError } from \"../../core/errors\";\nimport type { Ref, RuleSet, RuleSetGroup } from \"../../core/model\";\nimport type { GlobalsPreset } from \"./types\";\n\nconst literal = (value: string | number): Ref => ({ value });\nconst tokenRef = (path: string): Ref => ({ ref: path });\n\n/** A preset rule-set: an explicit raw `selector` + literal/ref declarations, no overrides. Stays\n * `kind:\"reset\"` — the normalization layer renders at specificity-0 `:where(sel)`, unlike the themed\n * `kind:\"globals\"` element rules. */\nconst resetRuleSet = (selector: string, declarations: Record<string, Ref>): RuleSet => ({\n kind: \"reset\",\n selector,\n declarations,\n overrides: [],\n});\n\n/** Build a `RuleSetGroup` (variant key → rule-set) from an ordered `[key, selector, decls]` list. */\nconst staticGroup = (\n entries: ReadonlyArray<readonly [string, string, Record<string, string | number>]>,\n): RuleSetGroup => {\n const group: RuleSetGroup = {};\n for (const [key, selector, decls] of entries) {\n const declarations: Record<string, Ref> = {};\n for (const [property, value] of Object.entries(decls)) declarations[property] = literal(value);\n group[key] = resetRuleSet(selector, declarations);\n }\n return group;\n};\n\n// ---------------------------------------------------------------------------\n// Static layers (literal declarations, kebab-case CSS keys)\n// ---------------------------------------------------------------------------\n\n/** Preflight — opinionated, token-first: strip UA styling so the design tokens are the sole source. */\nconst PREFLIGHT_STATIC: ReadonlyArray<readonly [string, string, Record<string, string | number>]> = [\n [\"box\", \"*,::before,::after\", { \"box-sizing\": \"border-box\", \"border-width\": \"0\", \"border-style\": \"solid\" }],\n [\"body\", \"body\", { margin: \"0\", \"line-height\": \"inherit\" }],\n [\"headings\", \"h1,h2,h3,h4,h5,h6\", { \"font-size\": \"inherit\", \"font-weight\": \"inherit\", margin: \"0\" }],\n [\"blocks\", \"p,figure,blockquote,dl,dd\", { margin: \"0\" }],\n [\"lists\", \"ul,ol\", { \"list-style\": \"none\", margin: \"0\", padding: \"0\" }],\n [\"media\", \"img,picture,video,canvas,svg\", { display: \"block\", \"max-width\": \"100%\" }],\n [\"forms\", \"button,input,select,textarea\", { font: \"inherit\", color: \"inherit\" }],\n [\"anchors\", \"a\", { color: \"inherit\", \"text-decoration\": \"inherit\" }],\n];\n\n/** Normalize — light: fix cross-browser bugs, preserve UA defaults (no margin zeroing / heading strip). */\nconst NORMALIZE_STATIC: ReadonlyArray<readonly [string, string, Record<string, string | number>]> = [\n [\"box\", \"*,::before,::after\", { \"box-sizing\": \"border-box\" }],\n [\"body\", \"body\", { margin: \"0\" }],\n [\"media\", \"img,picture,video,canvas,svg\", { \"max-width\": \"100%\" }],\n];\n\n/** Reset — aggressive classic reset: zero the box on everything, unstyle headings and lists. */\nconst RESET_STATIC: ReadonlyArray<readonly [string, string, Record<string, string | number>]> = [\n [\"box\", \"*,::before,::after\", { \"box-sizing\": \"border-box\" }],\n [\"all\", \"*\", { margin: \"0\", padding: \"0\", border: \"0\", font: \"inherit\", \"vertical-align\": \"baseline\" }],\n [\"headings\", \"h1,h2,h3,h4,h5,h6\", { \"font-size\": \"inherit\", \"font-weight\": \"inherit\" }],\n [\"lists\", \"ul,ol\", { \"list-style\": \"none\" }],\n [\"media\", \"img,picture,video,canvas,svg\", { display: \"block\", \"max-width\": \"100%\" }],\n];\n\n// ---------------------------------------------------------------------------\n// Default themed heading map (h1–h6 → typography's ratio-generated scale variants)\n// ---------------------------------------------------------------------------\n\n/** `h<n>` → the `fontSize` scale variant it binds to (largest heading = top of the scale). */\nconst DEFAULT_HEADINGS: ReadonlyArray<readonly [string, string]> = [\n [\"h1\", \"4xl\"],\n [\"h2\", \"3xl\"],\n [\"h3\", \"2xl\"],\n [\"h4\", \"xl\"],\n [\"h5\", \"lg\"],\n [\"h6\", \"md\"],\n];\n\n/** The default `h1`–`h6` themed group — each binds `font-size` to `typography.fontSize.<step>`. */\nexport const buildDefaultHeadingGroup = (): RuleSetGroup => {\n const group: RuleSetGroup = {};\n for (const [tag, step] of DEFAULT_HEADINGS) {\n group[tag] = resetRuleSet(tag, { \"font-size\": tokenRef(`typography.fontSize.${step}`) });\n }\n return group;\n};\n\n// ---------------------------------------------------------------------------\n// Preset resolution\n// ---------------------------------------------------------------------------\n\ntype PresetConfig = {\n static: ReadonlyArray<readonly [string, string, Record<string, string | number>]>;\n /** Whether the preset also emits the default `h1`–`h6` themed map. */\n headings: boolean;\n};\n\nconst PRESETS: Record<Exclude<GlobalsPreset, false>, PresetConfig> = {\n preflight: { static: PREFLIGHT_STATIC, headings: true },\n normalize: { static: NORMALIZE_STATIC, headings: false },\n reset: { static: RESET_STATIC, headings: true },\n};\n\n/** The recommended default preset (what `refract init` scaffolds). */\nexport const DEFAULT_GLOBALS_PRESET: Exclude<GlobalsPreset, false> = \"preflight\";\n\n/** The known preset names — for validation / error messages. */\nexport const GLOBALS_PRESET_NAMES = Object.keys(PRESETS) as ReadonlyArray<Exclude<GlobalsPreset, false>>;\n\n/**\n * Expand a preset name into its `{ static, defaults? }` rule-set groups. `false` yields no groups\n * (elements-only). An unknown name throws (typo detection). The default heading group is included\n * only when the preset opts into it (`preflight` / `reset`, not `normalize`).\n */\nexport const expandPreset = (preset: GlobalsPreset): { static?: RuleSetGroup; defaults?: RuleSetGroup } => {\n if (preset === false) return {};\n const config = PRESETS[preset];\n if (!config) {\n throw new RefractError(\n \"REFRACT_E_PRESET\",\n `globals: unknown preset \"${preset}\" — expected one of ${GLOBALS_PRESET_NAMES.join(\", \")} or false`,\n );\n }\n const groups: { static?: RuleSetGroup; defaults?: RuleSetGroup } = {\n static: staticGroup(config.static),\n };\n if (config.headings) groups.defaults = buildDefaultHeadingGroup();\n return groups;\n};\n","/**\n * The globals subsystem (§9 — formerly `reset`).\n *\n * Owns **no primitive properties** and **no minted-class recipes** — it fills the Model with two\n * kinds of selector-targeting rule-set:\n *\n * - **preset layers** (`static` + default `defaults`) — `kind:\"reset\"`, literal/opportunistic\n * normalization the adapters render at specificity-0 (`:where(sel)`). Unchanged from `reset`.\n * - **themed elements** (`elements`) — `kind:\"globals\"`, one rule-set per selector, carrying base\n * declarations + `states`/`responsive` overrides + delta-only `variants`. The adapters render\n * these at a higher tier (bare `a { }`, variant `a.subtle` / nested `&.subtle`).\n *\n * Element rules reuse the shared recipe normalization (`normalizeRecipeGroup`) for the genuinely\n * common part — flattening `states` + `responsive` into one `overrides` list — but stay *structural*\n * (a base selector + a named-variant map), not §7A recipe-sibling classes: they're elements, not\n * recipes. Their token refs resolve late in each adapter and are validated up-front in `createTheme`\n * (`validateGlobalsRefs`), like `components`. It grows a hook, never the spine.\n */\n\nimport type { NormalizedProperties, StructuralContext, StructuralOutput, Subsystem } from \"../../core/subsystem\";\nimport type { Ref, RuleSet, RuleSetGroup, RuleSetOverride, GlobalsVariant } from \"../../core/model\";\nimport { normalizeRecipeGroup } from \"../../core/normalize\";\nimport type {\n NormalizedRecipeVariant,\n RecipeNormalizationOptions,\n RecipeResponsiveOverride,\n} from \"../../core/normalize\";\nimport type { GlobalsDeclValue, GlobalsDeclarations, GlobalsElement, GlobalsRaw } from \"./types\";\nimport { expandPreset } from \"./presets\";\n\n/** The condition-axis keys carried on a normalized recipe override — never declarations. */\nconst CONDITION_KEYS = new Set([\n \"state\",\n \"breakpoint\",\n \"query\",\n \"orientation\",\n \"container\",\n \"size\",\n \"variant\",\n \"target\",\n]);\n\n/** A globals leaf value → a Model {@link Ref} (literal-first, §9): a bare `string` / `number` is a raw\n * literal → `{ value }`; a `ref(\"…\")` / `{ ref: \"…\" }` marker is a token path → `{ ref }` (lowered to\n * `var(--…)` / theme read by the adapter). Mirrors the components `css` delta grammar. */\nconst leafToRef = (value: GlobalsDeclValue): Ref => {\n if (value !== null && typeof value === \"object\") return { ref: value.ref };\n return { value };\n};\n\n/** Format an authored CSS property name to its declaration name (`textDecoration` → `text-decoration`). */\nconst formatProperty = (property: string): string => {\n if (property.startsWith(\"--\")) return property;\n return property\n .replace(/_/g, \"-\")\n .replace(/([a-z0-9])([A-Z])/g, \"$1-$2\")\n .toLowerCase();\n};\n\n/** A flat declaration map (a normalized base or one override entry) → `formattedProperty → Ref`,\n * skipping the condition axes (present on override entries) — everything else is a leaf. */\nconst interpretDeclarations = (props: Record<string, unknown>): Record<string, Ref> => {\n const declarations: Record<string, Ref> = {};\n for (const [property, value] of Object.entries(props)) {\n if (value == null || CONDITION_KEYS.has(property)) continue;\n declarations[formatProperty(property)] = leafToRef(value as GlobalsDeclValue);\n }\n return declarations;\n};\n\n/** One normalized override entry → a Model {@link RuleSetOverride} (condition axes copied, delta\n * props interpreted into declarations). */\nconst interpretOverride = (entry: RecipeResponsiveOverride<GlobalsDeclarations>): RuleSetOverride => {\n const override: RuleSetOverride = { declarations: interpretDeclarations(entry as Record<string, unknown>) };\n const e = entry as Record<string, unknown>;\n for (const key of CONDITION_KEYS) {\n if (e[key] !== undefined) (override as Record<string, unknown>)[key] = e[key];\n }\n return override;\n};\n\n/** A normalized recipe variant → `{ declarations, overrides }` (the shared base/override interpret). */\nconst interpretItem = (\n normalized: NormalizedRecipeVariant<GlobalsDeclarations>,\n): { declarations: Record<string, Ref>; overrides: RuleSetOverride[] } => ({\n declarations: interpretDeclarations(normalized.base as Record<string, unknown>),\n overrides: normalized.responsive.map(interpretOverride),\n});\n\n/**\n * Normalize one authored element def as a single-item recipe group and interpret it. `variants` is\n * peeled off first, so `normalizeRecipeGroup` sees no `variants` key (§7A stays a no-op) and just\n * flattens `states` + `responsive`. The one-item group keys the result by the name we passed.\n */\nconst normalizeElementItem = (\n name: string,\n def: Record<string, unknown>,\n options: RecipeNormalizationOptions<string>,\n): { declarations: Record<string, Ref>; overrides: RuleSetOverride[] } => {\n // dec.7 — globals element variants keep the rich (states/responsive) modifier, a superset of the\n // flat recipe modifier `normalizeRecipeGroup` is typed for; the runtime (`mergeRecipe`) is generic,\n // so this cast is structurally safe.\n const normalized = normalizeRecipeGroup<GlobalsDeclarations, string>(\n { [name]: def } as unknown as Parameters<typeof normalizeRecipeGroup<GlobalsDeclarations, string>>[0],\n options,\n );\n return interpretItem(normalized[name]);\n};\n\n/** `globals.elements` (selector → themed element rule) → the `kind:\"globals\"` `elements` rule-set group. */\nconst buildElementsGroup = (\n elements: Record<string, GlobalsElement> | undefined,\n ctx: StructuralContext,\n): RuleSetGroup | undefined => {\n if (!elements || !Object.keys(elements).length) return undefined;\n const allowedBreakpoints = Object.keys(ctx.breakpoints);\n const group: RuleSetGroup = {};\n\n for (const [selector, element] of Object.entries(elements)) {\n if (!element || typeof element !== \"object\") continue;\n const options: RecipeNormalizationOptions<string> = {\n propertyPath: `globals.elements.${selector}`,\n allowedBreakpoints,\n allowedStates: ctx.allowedStates,\n allowedContainers: ctx.allowedContainers,\n };\n\n // Peel `variants` so the base normalizes without §7A desugaring; variants stay structural.\n const { variants, ...baseDef } = element as Record<string, unknown>;\n const base = normalizeElementItem(selector, baseDef, options);\n\n const ruleSet: RuleSet = {\n kind: \"globals\",\n selector,\n declarations: base.declarations,\n overrides: base.overrides,\n };\n\n if (variants && typeof variants === \"object\" && Object.keys(variants).length) {\n const variantMap: Record<string, GlobalsVariant> = {};\n for (const [variantName, delta] of Object.entries(variants as Record<string, unknown>)) {\n if (!delta || typeof delta !== \"object\") continue;\n variantMap[variantName] = normalizeElementItem(variantName, delta as Record<string, unknown>, {\n ...options,\n propertyPath: `${options.propertyPath}.variants.${variantName}`,\n });\n }\n if (Object.keys(variantMap).length) ruleSet.variants = variantMap;\n }\n\n group[selector] = ruleSet;\n }\n\n return Object.keys(group).length ? group : undefined;\n};\n\n/**\n * Normalize a `rawTheme.globals` slice into its `{ static?, defaults?, elements? }` rule-set groups.\n *\n * The **preset** must be explicit for the static + default layers to emit — a bare `{ elements }`\n * produces only the themed element group, so an `override` delta inherits the parent's preset instead\n * of reverting to the default.\n */\nconst buildGlobalsRuleSets = (\n rawSlice: unknown,\n ctx: StructuralContext,\n): Record<string, RuleSetGroup> => {\n const parsed = (rawSlice ?? {}) as GlobalsRaw;\n const groups: Record<string, RuleSetGroup> = {};\n\n // Static + default heading layers only when the preset is explicitly authored.\n if (parsed.preset !== undefined) {\n const expanded = expandPreset(parsed.preset);\n if (expanded.static) groups.static = expanded.static;\n if (expanded.defaults) groups.defaults = expanded.defaults;\n }\n\n // Themed element rules always apply (the delta a preset-less slice carries).\n const elements = buildElementsGroup(parsed.elements, ctx);\n if (elements) groups.elements = elements;\n\n return groups;\n};\n\nexport const globalsSubsystem: Subsystem = {\n key: \"globals\",\n // No property pipeline — globals owns no primitive tokens.\n normalizeProperties(): NormalizedProperties {\n return {};\n },\n buildStructural(rawSlice, ctx): StructuralOutput {\n return { ruleSetGroups: buildGlobalsRuleSets(rawSlice, ctx), configProperties: {} };\n },\n};\n\nexport type { GlobalsRaw, GlobalsPreset, GlobalsDeclValue, GlobalsDeclarations, GlobalsElement } from \"./types\";\n","/**\n * The clean-room `createTheme` — the public entry point.\n *\n * A **walking skeleton** (Step 0d): a live spine that grows one seam per step, so every\n * later step is reviewed through the real entry point rather than isolated unit tests.\n * The control flow is fixed; coverage grows by pushing a {@link Subsystem} onto `SUBSYSTEMS`\n * or filling a hook — never by editing the spine.\n *\n * `adapter` is a **required** option (no `createCssAdapter()` default), which is what lets\n * this module stay in core importing nothing but the `ThemeAdapter` interface.\n *\n * Flow: read breakpoints → build the media descriptor → normalize each subsystem's slice\n * into a per-subsystem Model input (`buildSubsystemInput`) → `buildThemeModel` → assemble the\n * theme surface (`assembleTheme`: token map + `resolveToken` + `adapter.bind` + `extend`).\n *\n * `theme.override(partial)` (Step 5) is a **delta merge**, not a re-run: it normalizes ONLY the\n * partial's changed subsystem slices (through the very same `buildSubsystemInput`), immutably\n * merges those Model fragments into the current Model at property / rule-set-group granularity,\n * and re-assembles onto the **new** Model. The parent Model (and its bound outputs) are untouched\n * — real child themes. There is no raw retention: the Model is the only held state, and the\n * reference-resolution context recipe interpretation needs is reconstructed from it\n * (`reconstructNormalizedProperties`). Synthesized steps are derived refs, so overriding a base\n * re-derives its steps for free; the merge code itself carries no subsystem-specific logic.\n */\n\nimport type { ThemeAdapter, RenderContext } from \"./ThemeAdapter\";\nimport { RefractError } from \"./errors\";\nimport type { Subsystem, RecipeInterpretContext, NormalizedProperties } from \"./subsystem\";\nimport type {\n Literal,\n Ref,\n ThemeModel,\n SubsystemModel,\n PropertyModel,\n RuleSetGroup,\n Keyframe,\n ContainerModel,\n SubsystemModelInput,\n BuildThemeModelInput,\n} from \"./model\";\nimport type { InterpretedRecipeVariant } from \"./model\";\nimport {\n buildThemeModel,\n buildSubsystemModel,\n buildTokenMap,\n buildRuleSetFromInterpreted,\n buildComponentRuleSetFromInterpreted,\n} from \"./model\";\nimport { resolveModelUnits, type UnitsConfig, type UnitResolutionConfig } from \"./units\";\nimport type { NormalizedPropertyValue } from \"./normalize\";\nimport type { RawTheme } from \"./rawTheme\";\nimport { normalizeRecipeGroup, createRecipeVariantResolver } from \"./normalize\";\nimport { buildDerivationRegistry, resolveToken, bakeCrossPropertyDerivations } from \"./derive\";\nimport {\n buildMediaDescriptor,\n buildContainerDescriptors,\n mediaQueryString,\n resolveMediaConfig,\n DEFAULT_BREAKPOINTS,\n type MediaDescriptor,\n type MediaConfig,\n} from \"./media\";\nimport { colorsSubsystem } from \"../subsystems/colors\";\nimport { typographySubsystem } from \"../subsystems/typography\";\nimport { layoutSubsystem } from \"../subsystems/layout\";\nimport { effectsSubsystem } from \"../subsystems/effects\";\nimport { bordersSubsystem } from \"../subsystems/borders\";\nimport { animationSubsystem } from \"../subsystems/animation\";\nimport { componentsSubsystem } from \"../subsystems/components\";\nimport { globalsSubsystem } from \"../subsystems/globals\";\n\n/**\n * The subsystems the spine drives, in order. Grows as later steps port each subsystem.\n * `globals` is last: its themed element refs resolve late against every subsystem's tokens (like\n * `components`), so it only needs the others' Model present, not their array position.\n */\nconst SUBSYSTEMS: readonly Subsystem[] = [\n colorsSubsystem,\n typographySubsystem,\n layoutSubsystem,\n effectsSubsystem,\n bordersSubsystem,\n animationSubsystem,\n componentsSubsystem,\n globalsSubsystem,\n];\n\n/**\n * The generic recipe path — normalize each `<subsystem>.recipes.<group>`, drive the shared\n * cycle-safe resolver through the subsystem's `interpretRecipe` hook, and build the Model\n * rule-set group from the interpreted (ref-carrying) output. Subsystem-agnostic: the only\n * subsystem-specific knowledge is the `interpretRecipe` hook itself.\n */\nfunction buildSubsystemRuleSets(\n subsystem: Subsystem,\n rawRecipes: Record<string, unknown> | undefined,\n ctx: {\n breakpoints: Record<string, number>;\n media: MediaDescriptor<string>;\n properties: RecipeInterpretContext[\"properties\"];\n allowedBreakpoints: string[];\n allowedStates?: ReadonlyArray<string>;\n allowedContainers?: ReadonlyMap<string, ReadonlySet<string>>;\n },\n): Record<string, RuleSetGroup> {\n if (!subsystem.interpretRecipe || !rawRecipes || !Object.keys(rawRecipes).length) {\n return {};\n }\n\n const groups: Record<string, RuleSetGroup> = {};\n for (const [groupName, groupDef] of Object.entries(rawRecipes)) {\n const groupPath = `${subsystem.key}.recipes.${groupName}`;\n const normalized = normalizeRecipeGroup(groupDef as Record<string, Record<string, unknown>>, {\n propertyPath: groupPath,\n allowedBreakpoints: ctx.allowedBreakpoints,\n allowedStates: ctx.allowedStates,\n allowedContainers: ctx.allowedContainers,\n });\n\n const resolver = createRecipeVariantResolver<\n Record<string, unknown>,\n string,\n InterpretedRecipeVariant<string>\n >(\n normalized,\n (variantName, variant, resolve) =>\n subsystem.interpretRecipe!(variantName, variant, {\n breakpoints: ctx.breakpoints,\n media: ctx.media,\n properties: ctx.properties,\n resolveRecipeVariant: resolve,\n groupPath,\n }),\n { groupPath },\n );\n\n // Build each variant's rule-set. When the subsystem extracts cross-subsystem references\n // (composition), keep them as Model pointers via `buildComponentRuleSetFromInterpreted`; else\n // a plain structural copy. Per-variant so the reference extraction reads the normalized base.\n const interpreted = resolver.resolveAll();\n const group: RuleSetGroup = {};\n for (const [variantName, interpretedVariant] of Object.entries(interpreted)) {\n if (subsystem.extractReferences) {\n const references = subsystem.extractReferences(normalized[variantName]?.base ?? {});\n group[variantName] = buildComponentRuleSetFromInterpreted(interpretedVariant, references);\n } else {\n group[variantName] = buildRuleSetFromInterpreted(interpretedVariant);\n }\n }\n groups[groupName] = group;\n }\n return groups;\n}\n\n/** Breakpoints → the core media descriptor. `mediaConfig` controls the emitted unit (px default, em/rem — §10.5 D6). */\nconst buildMedia = (\n breakpoints: Record<string, number>,\n mediaConfig?: MediaConfig,\n): MediaDescriptor<string> =>\n buildMediaDescriptor(breakpoints, opts => mediaQueryString(opts, resolveMediaConfig(mediaConfig)));\n\n/**\n * Normalize the authored `containers` config (§10.5) → the Model container map: default each\n * `container-type` to `inline-size` (D2), keep the `sizes` scale. Returns `undefined` for an absent /\n * empty config (additive — no `containers` field on the Model → byte-identical output).\n */\nconst normalizeContainers = (raw: unknown): Record<string, ContainerModel> | undefined => {\n if (!raw || typeof raw !== \"object\") return undefined;\n const out: Record<string, ContainerModel> = {};\n for (const [name, def] of Object.entries(\n raw as Record<string, { type?: \"inline-size\" | \"size\"; sizes?: Record<string, number> }>,\n )) {\n if (!def || typeof def !== \"object\" || !def.sizes || !Object.keys(def.sizes).length) continue;\n out[name] = { type: def.type ?? \"inline-size\", sizes: { ...def.sizes } };\n }\n return Object.keys(out).length ? out : undefined;\n};\n\n/** Container model → `name → Set(sizeNames)`, the allowed-set recipe normalization validates container refs against. */\nconst containerSizeSets = (\n containers?: Record<string, ContainerModel>,\n): ReadonlyMap<string, ReadonlySet<string>> | undefined => {\n if (!containers) return undefined;\n const map = new Map<string, ReadonlySet<string>>();\n for (const [name, c] of Object.entries(containers)) map.set(name, new Set(Object.keys(c.sizes)));\n return map;\n};\n\n/**\n * §W6b — resolve an authored `external` string to the literal parent CSS-variable name. A leading\n * `--` is a literal var (verbatim, any naming); otherwise it's a refract token path lowered to\n * `--<prefix>-<dashed-path>` — the parent's *default* naming (document that assumption).\n */\nconst resolveExternalVar = (external: string, prefix: string): string => {\n if (external.startsWith(\"--\")) return external;\n const dashed = external.split(\".\").join(\"-\").toLowerCase();\n return prefix ? `--${prefix}-${dashed}` : `--${dashed}`;\n};\n\n/**\n * §W6b — split a raw subsystem slice into its external-token properties (a value with a string\n * `external` key) and the remaining slice. The externals are pulled out BEFORE the subsystem runs, so\n * a `var(…)` passthrough never hits colour coercion / scale synthesis / unit tagging; they re-join as\n * normalized properties carrying `external` (the resolved parent var name).\n */\nconst extractExternals = (\n slice: Record<string, unknown> | undefined,\n prefix: string,\n): { clean: Record<string, unknown> | undefined; externals: NormalizedProperties } => {\n if (!slice) return { clean: slice, externals: {} };\n const clean: Record<string, unknown> = {};\n const externals: NormalizedProperties = {};\n for (const [key, value] of Object.entries(slice)) {\n if (\n value !== null &&\n typeof value === \"object\" &&\n !Array.isArray(value) &&\n typeof (value as { external?: unknown }).external === \"string\"\n ) {\n const varName = resolveExternalVar((value as { external: string }).external, prefix);\n externals[key] = { base: `var(${varName})`, external: varName, responsive: [] } as NormalizedProperties[string];\n } else {\n clean[key] = value;\n }\n }\n return { clean, externals };\n};\n\n/** Context threaded into {@link buildSubsystemInput}. */\ninterface SubsystemBuildContext {\n readonly breakpoints: Record<string, number>;\n /** §W6b — the parent theme's var prefix (from `raw.extends.prefix`, default `\"dt\"`). */\n readonly extendsPrefix: string;\n readonly media: MediaDescriptor<string>;\n /** Media unit config (§10.5) — threaded to `buildStructural` for breakpoint-derived container widths. */\n readonly mediaConfig?: MediaConfig;\n readonly allowedBreakpoints: string[];\n readonly allowedStates?: ReadonlyArray<string>;\n /** Container queries (§10.5): `name → allowed size-names`, validated on container recipe overrides. */\n readonly allowedContainers?: ReadonlyMap<string, ReadonlySet<string>>;\n /**\n * Override only: the parent subsystem's reconstructed normalized properties. The partial's own\n * freshly-normalized properties are overlaid on top, and the union is the reference-resolution\n * context recipe interpretation reads (so a delta that touches only a recipe still resolves refs\n * against the inherited palette). Absent on the initial build (a subsystem's own props suffice).\n */\n readonly inheritedProperties?: NormalizedProperties;\n}\n\n/**\n * The per-subsystem \"raw slice → {@link SubsystemModelInput}\" build, extracted so BOTH the initial\n * build and `override` run the exact same normalization. Pure: normalize the slice's properties,\n * drive the generic recipe path (interpret against the inherited⊕own properties), and run the\n * structural generator hook. No spine control flow — a subsystem is data.\n */\nfunction buildSubsystemInput(\n subsystem: Subsystem,\n rawSlice: Record<string, unknown> | undefined,\n ctx: SubsystemBuildContext,\n): SubsystemModelInput {\n // §W6b — external-token properties are pulled out of the slice so the subsystem never coerces or\n // synthesizes a `var(…)` passthrough; they re-join as normalized properties carrying `external`.\n const { clean, externals } = extractExternals(rawSlice, ctx.extendsPrefix);\n const properties = subsystem.normalizeProperties(clean, {\n allowedBreakpoints: ctx.allowedBreakpoints,\n });\n Object.assign(properties, externals);\n // Recipe interpretation resolves refs against the subsystem's properties. On override the parent's\n // (reconstructed) properties are the base, the partial's fresh ones win on collision.\n const interpretProperties = ctx.inheritedProperties\n ? { ...ctx.inheritedProperties, ...properties }\n : properties;\n\n const recipeGroups = buildSubsystemRuleSets(\n subsystem,\n rawSlice?.recipes as Record<string, unknown> | undefined,\n {\n breakpoints: ctx.breakpoints,\n media: ctx.media,\n properties: interpretProperties,\n allowedBreakpoints: ctx.allowedBreakpoints,\n allowedStates: ctx.allowedStates,\n allowedContainers: ctx.allowedContainers,\n },\n );\n\n // Generator-driven rule-sets (layout's columns/grids/stacks/container). Structural groups insert\n // **ahead of** recipe groups; the config knobs merge into the subsystem's tokens as extraProperties.\n let ruleSetGroups = recipeGroups;\n let extraProperties: Record<string, PropertyModel> | undefined;\n let keyframes: Record<string, Keyframe> | undefined;\n if (subsystem.buildStructural && rawSlice) {\n const structural = subsystem.buildStructural(rawSlice, {\n breakpoints: ctx.breakpoints,\n media: ctx.media,\n mediaConfig: ctx.mediaConfig,\n // §9: a structural subsystem whose rule-sets carry recipe-style conditions (globals element\n // `states` / container `responsive`) validates them against the same sets the recipe path uses.\n allowedStates: ctx.allowedStates,\n allowedContainers: ctx.allowedContainers,\n });\n ruleSetGroups = { ...structural.ruleSetGroups, ...recipeGroups };\n if (Object.keys(structural.configProperties).length) {\n extraProperties = structural.configProperties;\n }\n // Keyframes (§10.2, animation) ride their own Model slot — neither rule-set nor token.\n if (structural.keyframes && Object.keys(structural.keyframes).length) {\n keyframes = structural.keyframes;\n }\n }\n\n const input: SubsystemModelInput = {};\n if (Object.keys(properties).length) input.properties = properties;\n if (Object.keys(ruleSetGroups).length) input.ruleSetGroups = ruleSetGroups;\n if (extraProperties) input.extraProperties = extraProperties;\n if (keyframes) input.keyframes = keyframes;\n return input;\n}\n\n/**\n * Reconstruct a subsystem's normalized-property view from its Model {@link PropertyModel}s — base\n * value + variant keys + scalar extras. This is the \"everything override needs is in the Model\"\n * principle: no raw retention. It only needs to be faithful enough for recipe **reference\n * resolution** (a name existing, its variant keys), which this shape provides. Subsystem-generic.\n */\nfunction reconstructNormalizedProperties(\n subModel: SubsystemModel | undefined,\n): NormalizedProperties {\n const out: NormalizedProperties = {};\n if (!subModel?.properties) return out;\n for (const [name, pm] of Object.entries(subModel.properties)) {\n const normalized: Record<string, unknown> = { base: pm.base.value };\n if (pm.variants && Object.keys(pm.variants).length) {\n const variants: Record<string, unknown> = {};\n for (const [vname, v] of Object.entries(pm.variants)) {\n // dec.3 — reconstruct the variant's base + its own extras for recipe reference resolution.\n const reconstructed: Record<string, unknown> = { base: v.base.value };\n if (v.extras) for (const [ename, ref] of Object.entries(v.extras)) reconstructed[ename] = ref.value;\n variants[vname] = reconstructed;\n }\n normalized.variants = variants;\n }\n if (pm.extras) {\n for (const [ename, ref] of Object.entries(pm.extras)) normalized[ename] = ref.value;\n }\n out[name] = normalized as NormalizedPropertyValue<unknown, Record<string, unknown>>;\n }\n return out;\n}\n\n/**\n * Immutable per-subsystem merge — **property-level replace** (a property in the partial replaces\n * the whole {@link PropertyModel}; untouched properties keep their reference) + **rule-set\n * variant-level replace within a group** (a variant in the partial replaces that variant; untouched\n * variants and untouched groups keep their references). New objects only at the touched levels;\n * everything else is shared. No per-subsystem branch — the shape is the same for all five.\n */\nfunction mergeSubsystemModel(\n current: SubsystemModel | undefined,\n partial: SubsystemModel,\n): SubsystemModel {\n if (!current) return partial;\n const merged: SubsystemModel = { ...current };\n if (partial.properties) {\n merged.properties = { ...(current.properties ?? {}), ...partial.properties };\n }\n if (partial.ruleSets) {\n const ruleSets: Record<string, RuleSetGroup> = { ...(current.ruleSets ?? {}) };\n for (const [group, groupRuleSets] of Object.entries(partial.ruleSets)) {\n ruleSets[group] = { ...(current.ruleSets?.[group] ?? {}), ...groupRuleSets };\n }\n merged.ruleSets = ruleSets;\n }\n // Keyframes (§10.2): name-level replace — a keyframe in the partial replaces that keyframe;\n // untouched ones keep their reference. Same rule as rule-set variants; additive when absent.\n if (partial.keyframes) {\n merged.keyframes = { ...(current.keyframes ?? {}), ...partial.keyframes };\n }\n return merged;\n}\n\n/**\n * DTCG round-trip: splice a prebuilt IR overlay (rule-sets / keyframes / containers) into a resolved\n * Model, reusing {@link mergeSubsystemModel} for the per-subsystem merge (no new merge logic). Returns\n * the model unchanged when no overlay option is set, so the standard build path stays byte-identical.\n */\nfunction applyModelOverlay(model: ThemeModel, options: CreateThemeOptions): ThemeModel {\n const { propertiesOverlay, ruleSetsOverlay, keyframesOverlay, containersOverlay } = options;\n if (!propertiesOverlay && !ruleSetsOverlay && !keyframesOverlay && !containersOverlay) return model;\n const subsystems = { ...model.subsystems };\n const keys = new Set([\n ...Object.keys(propertiesOverlay ?? {}),\n ...Object.keys(ruleSetsOverlay ?? {}),\n ...Object.keys(keyframesOverlay ?? {}),\n ]);\n for (const key of keys) {\n subsystems[key] = mergeSubsystemModel(subsystems[key], {\n properties: propertiesOverlay?.[key],\n ruleSets: ruleSetsOverlay?.[key],\n keyframes: keyframesOverlay?.[key],\n });\n }\n const next: ThemeModel = { ...model, subsystems };\n if (containersOverlay) next.containers = { ...(model.containers ?? {}), ...containersOverlay };\n return next;\n}\n\n/** The stable engine an initial theme and every child derived from it share. */\ninterface ThemeEngine {\n readonly adapter: ThemeAdapter;\n readonly derivationRegistry: ReturnType<typeof buildDerivationRegistry>;\n readonly allowedStates?: ReadonlyArray<string>;\n /** Media unit config (§10.5 D6) — shared by the viewport `@media` + container `@container` descriptors. */\n readonly mediaConfig?: MediaConfig;\n /** Length-unit resolution config (§21) — `units` role map + `baseFontSize`. Stable across children. */\n readonly unitConfig?: UnitResolutionConfig;\n}\n\nexport interface CreateThemeOptions<TAdapter extends ThemeAdapter = ThemeAdapter> {\n /** Required — the format target. Core ships no default adapter. */\n readonly adapter: TAdapter;\n /**\n * Media-query output config (§10.5) — `{ unit: \"px\" | \"em\" | \"rem\"; baseFontSize }`. Breakpoint and\n * container thresholds are authored as px numbers; `unit` controls the emitted unit (em/rem = value ÷\n * baseFontSize). Defaults to px. Stable across `override()` children.\n */\n readonly media?: MediaConfig;\n /**\n * Declaration-value length units (§21) — a token-path-prefix role map. `units.default` (global),\n * `units[\"<subsystem>\"]`, `units[\"<subsystem>.<property>\"]`; most-specific wins, over a built-in seed\n * (length subsystems → px, `lineHeight` → none, `letterSpacing` → em). A bare authored number is\n * deferred (resolved here); an explicit unit (`\"1.5rem\"`) is pinned. Unit intent is a theme fact, so it\n * lives here (not on the adapter): every adapter receives a Model with fully-resolved `{ value, unit }`.\n */\n readonly units?: UnitsConfig;\n /** Divisor for a deferred length resolving to `rem` (§21). Defaults to 16. */\n readonly baseFontSize?: number;\n /**\n * DTCG round-trip (§12 Phase 2) — prebuilt property Model to splice in **after** property build,\n * keyed `subsystem → property`. Carries the lossless bits the resolved DTCG token surface can't\n * (appearance `modes` / `responsive` / derivation refs / `external`); a property present here\n * REPLACES the one the standard tokens rebuilt (property-level merge). `fromDTCGTheme` sets it from\n * the `com.theme-registry.refract` extension. Absent → the standard build is untouched.\n */\n readonly propertiesOverlay?: Record<string, Record<string, PropertyModel>>;\n /**\n * DTCG round-trip — prebuilt, already-interpreted rule-set IR to splice into the Model **after**\n * property build, keyed `subsystem → group → variant`. Bypasses authoring/normalization (the IR is\n * a built Model slice, lengths already resolved), then flows through the normal `{ ref }` validation.\n * `fromDTCGTheme` sets this to restore recipes a DTCG document carried in its\n * `com.theme-registry.refract` extension. Rarely set by hand. Absent → the standard build is untouched.\n */\n readonly ruleSetsOverlay?: Record<string, Record<string, RuleSetGroup>>;\n /** DTCG round-trip — prebuilt keyframes to splice in, keyed `subsystem → name`. See {@link ruleSetsOverlay}. */\n readonly keyframesOverlay?: Record<string, Record<string, Keyframe>>;\n /** DTCG round-trip — prebuilt query containers to splice into the Model root. See {@link ruleSetsOverlay}. */\n readonly containersOverlay?: Record<string, ContainerModel>;\n}\n\n/** The public theme surface. Grows: `css`/recipe helpers (step 1). */\nexport interface Theme {\n /** The format-neutral held state — the single source of truth. */\n readonly model: ThemeModel;\n /**\n * Flat, lazy, cached `path -> Ref` view of the Model's property tokens\n * (`\"<subsystem>.<property>[.<variant|extra>]\"`). Aliases / derived steps stay as refs\n * (`{ ref }` / `{ ref, fn, arg }`), so the map is override-safe. Rule-sets are excluded.\n */\n readonly tokens: Record<string, Ref>;\n /**\n * Resolve one token path to its concrete literal — following aliases and running derivations\n * (`lighten` / `darken` / …) through the subsystem derivation registry. Throws on unknown paths.\n */\n readonly resolveToken: (path: string) => Literal;\n /**\n * Derive a **child** theme by immutably merging `partial` (a partial raw theme) into this theme's\n * Model. Only the partial's subsystem slices are re-normalized; the merge is a property /\n * rule-set-variant replace. The parent theme (Model, tokens, css) is untouched — call it again to\n * derive siblings. Overriding a colour base re-derives its synthesized steps automatically.\n *\n * Accepts a (partial) {@link RawTheme} — every key is already optional, so a delta touching one\n * subsystem slice is a valid `RawTheme`.\n */\n readonly override: (partial: RawTheme) => Theme;\n}\n\nexport function createTheme(\n rawTheme: RawTheme,\n options: CreateThemeOptions,\n): Theme {\n const { adapter } = options;\n\n // Bridge the strict authoring type to the loose spine once, at the boundary: subsystem hooks\n // still consume each `raw[key]` slice as `Record<string, unknown>` (types-only, no runtime change).\n const raw = rawTheme as Record<string, unknown>;\n const breakpoints = (raw.breakpoints as Record<string, number> | undefined) ?? DEFAULT_BREAKPOINTS;\n const allowedBreakpoints = Object.keys(breakpoints);\n // §W6b — the parent theme's var prefix for external-token passthroughs (default `\"dt\"`).\n const extendsPrefix = (raw.extends as { prefix?: string } | undefined)?.prefix ?? \"dt\";\n // The adapter owns the known-state set; core validates recipe `state:` refs against it (no CSS import).\n const allowedStates = adapter.allowedStates;\n // dec.1 — the appearance-mode registry. Property `modes` keys are validated against it (typo-detection).\n // Default `[\"dark\", \"light\"]`; declaring `modes` is how a custom mode (e.g. `hc`) becomes valid.\n const allowedModes = new Set((raw.modes as string[] | undefined) ?? [\"dark\", \"light\"]);\n const mediaConfig = options.media;\n const media = buildMedia(breakpoints, mediaConfig);\n\n // Named query containers (§10.5): normalize the config, derive the allowed-size sets container\n // recipe overrides validate against. Absent → additive (no `containers` on the Model).\n const containers = normalizeContainers(raw.containers);\n const allowedContainers = containerSizeSets(containers);\n\n // Loop the subsystem list into per-subsystem Model inputs. Generic by construction:\n // a new subsystem is a push onto SUBSYSTEMS, never a change here.\n const subsystemInputs: Record<string, SubsystemModelInput> = {};\n for (const subsystem of SUBSYSTEMS) {\n const input = buildSubsystemInput(subsystem, raw[subsystem.key] as Record<string, unknown> | undefined, {\n breakpoints,\n extendsPrefix,\n media,\n mediaConfig,\n allowedBreakpoints,\n allowedStates,\n allowedContainers,\n });\n if (Object.keys(input).length) subsystemInputs[subsystem.key] = input;\n }\n\n const built = buildThemeModel({ breakpoints, containers, ...subsystemInputs } as BuildThemeModelInput);\n\n // §21: resolve every length leaf to a concrete `{ value, unit }` — the single format-neutral pass\n // that consults the `units` role map. Adapters downstream never see a deferred length. Default (no\n // `units`) tags px only → CSS/SCSS byte-identical. `unitConfig` is stable across `override()` children.\n const unitConfig: UnitResolutionConfig = { units: options.units, baseFontSize: options.baseFontSize };\n const resolved = resolveModelUnits(built, unitConfig);\n\n // DTCG round-trip: splice any prebuilt IR overlay (recipes/keyframes/containers a DTCG document\n // carried in its `com.theme-registry.refract` extension) into the Model AFTER unit resolution (the\n // overlay came from a built Model, so its lengths are already resolved) and BEFORE the ref-validation\n // below — so a restored rule-set's `{ ref }`s are validated exactly like an authored one.\n const overlaid = applyModelOverlay(resolved, options);\n\n // One derivation registry, collected generically from each subsystem's `derivations` map —\n // no subsystem-specific import here (spine stays control-flow-generic). Stable across children.\n const derivationRegistry = buildDerivationRegistry(\n SUBSYSTEMS.flatMap(subsystem => (subsystem.derivations ? [subsystem.derivations] : [])),\n );\n\n // dec.4 — fill every CROSS-property derived variant / mode value (a `{ ref, modifiers }` sourcing\n // another property) against the full token map, now that it exists. Byte-identical for a Model with\n // no cross-property derivation (returned by reference). Runs before validation so an unknown-source\n // ref fails loud here.\n const model = bakeCrossPropertyDerivations(overlaid, derivationRegistry);\n\n // §19 / §9 — post-build ref validation, collect-all (P2-3). A component `css` delta and a globals\n // element declaration are literal-first: a bare string is raw CSS; a `ref(\"…\")` / `{ ref }` marks a\n // token path. Every marked `{ ref }` must resolve to a real token BEFORE any adapter runs, so a\n // mistyped path fails loud here instead of lowering to a dangling `var(--…)`. Both passes ACCUMULATE\n // their failures so an invalid theme reports every bad ref at once, as one `REFRACT_E_VALIDATION`.\n const validationErrors = [\n ...collectComponentReferenceErrors(model),\n ...collectComponentCssRefErrors(model),\n ...collectGlobalsRefErrors(model),\n ...collectModeErrors(model, allowedModes),\n ];\n if (validationErrors.length > 0) {\n const list = validationErrors.map(e => ` - ${e}`).join(\"\\n\");\n throw new RefractError(\n \"REFRACT_E_VALIDATION\",\n `refract: ${validationErrors.length} validation error(s):\\n${list}`,\n validationErrors,\n );\n }\n\n return assembleTheme(model, { adapter, derivationRegistry, allowedStates, mediaConfig, unitConfig });\n}\n\n/**\n * dec.1 — validate every property `modes` key against the declared `modes` registry (default\n * `[\"dark\", \"light\"]`). A mode name not in the registry is a typo or an undeclared custom mode; throw\n * so it fails loud (like an unknown breakpoint) instead of silently emitting a dead `[data-theme]` block.\n * Walks the built Model's per-subsystem property `modes` — the same post-build shape the other\n * collectors use. Initial-build only (mirrors the existing collect-* passes).\n */\nfunction collectModeErrors(model: ThemeModel, allowedModes: ReadonlySet<string>): string[] {\n const errors: string[] = [];\n const report = (subKey: string, propName: string, mode: string, where: string): void => {\n if (!allowedModes.has(mode)) {\n errors.push(\n `${subKey}.${propName}${where}: unknown appearance mode '${mode}' — declare it in the top-level ` +\n `'modes' registry (known: ${[...allowedModes].join(\", \")})`,\n );\n }\n };\n for (const [subKey, sub] of Object.entries(model.subsystems)) {\n for (const [propName, pm] of Object.entries(sub.properties ?? {})) {\n for (const entry of pm.modes ?? []) {\n if (entry.mode) report(subKey, propName, entry.mode, \"\");\n }\n // dec.9 — a responsive entry's `mode` condition is validated against the same registry.\n for (const entry of pm.responsive ?? []) {\n if (entry.mode) report(subKey, propName, entry.mode, \" (responsive)\");\n }\n }\n }\n return errors;\n}\n\n/**\n * A component variant references sibling recipes cross-subsystem (`colors: \"solid.primary\"` → stored as\n * `\"colors:solid.primary\"`). Those pointers are what compose the class-list at emit time — a reference\n * to a recipe that doesn't exist would silently drop from the composition and ship a button missing its\n * colours. Assert each `subsystem:group.variant` reference resolves to a real recipe in the built Model,\n * collect-all so every dangling reference is reported at once.\n */\nfunction collectComponentReferenceErrors(model: ThemeModel): string[] {\n const ruleSets = model.subsystems.components?.ruleSets;\n if (!ruleSets) return [];\n const errors: string[] = [];\n for (const [group, ruleSetGroup] of Object.entries(ruleSets)) {\n for (const [variant, ruleSet] of Object.entries(ruleSetGroup)) {\n for (const reference of ruleSet.references ?? []) {\n const [subsystem, rest = \"\"] = reference.split(\":\");\n const dot = rest.indexOf(\".\");\n const refGroup = dot >= 0 ? rest.slice(0, dot) : rest;\n const refVariant = dot >= 0 ? rest.slice(dot + 1) : \"\";\n if (!model.subsystems[subsystem]?.ruleSets?.[refGroup]?.[refVariant]) {\n errors.push(\n `components.${group}.${variant}: Recipe variant \"${refVariant}\" is not defined in ` +\n `\"${subsystem}:${refGroup}\". Check the subsystem:group.variant reference against what the ` +\n `subsystem declares.`,\n );\n }\n }\n }\n }\n return errors;\n}\n\n/**\n * §19: validate every component `css`-delta reference. A component's own rule-set declarations are\n * literal-first — a bare authored string stays a literal; only a `ref(\"…\")` / `{ ref }` marker becomes\n * a `{ ref }`. Assert each such `{ ref }` points at a real token in the flat global namespace\n * (`buildTokenMap`); an unknown path is a typo in the marked token path (a raw CSS value needs no\n * marker — it's just a bare string). Rule-set-only (components own no property tokens),\n * so this walks just the component `ruleSets` base declarations + their condition overrides.\n */\nfunction collectComponentCssRefErrors(model: ThemeModel): string[] {\n const ruleSets = model.subsystems.components?.ruleSets;\n if (!ruleSets) return [];\n const tokens = buildTokenMap(model);\n const errors: string[] = [];\n const checkDecls = (\n declarations: Record<string, Ref> | undefined,\n group: string,\n variant: string,\n where: string,\n ): void => {\n for (const [property, ref] of Object.entries(declarations ?? {})) {\n if (ref.ref !== undefined && !(ref.ref in tokens)) {\n errors.push(\n `components.${group}.${variant}: css '${property}'${where} references unknown token ` +\n `'${ref.ref}' — check the token path, or use a bare string / number for a raw CSS value`,\n );\n }\n }\n };\n for (const [group, ruleSetGroup] of Object.entries(ruleSets)) {\n for (const [variant, ruleSet] of Object.entries(ruleSetGroup)) {\n checkDecls(ruleSet.declarations, group, variant, \"\");\n for (const override of ruleSet.overrides ?? []) {\n checkDecls(override.declarations, group, variant, \" (override)\");\n }\n }\n }\n return errors;\n}\n\n/**\n * §9: validate every `globals` themed-element reference. An element declaration is literal-first — a\n * `ref(\"…\")` / `{ ref: \"…\" }` marker became `{ ref }`. Assert each `{ ref }` in the `kind:\"globals\"`\n * element rule-sets (base declarations, condition overrides, and each variant's delta) points at a real\n * token, throwing on an unknown path (a typo in the marked token path).\n * Only `kind:\"globals\"` is checked — the preset `static`/`defaults` layers (`kind:\"reset\"`) keep\n * their opportunistic drop policy (a ratio-less theme drops missing heading scale steps).\n */\nfunction collectGlobalsRefErrors(model: ThemeModel): string[] {\n const ruleSets = model.subsystems.globals?.ruleSets;\n if (!ruleSets) return [];\n const tokens = buildTokenMap(model);\n const errors: string[] = [];\n const checkDecls = (\n declarations: Record<string, Ref> | undefined,\n selector: string,\n where: string,\n ): void => {\n for (const [property, ref] of Object.entries(declarations ?? {})) {\n if (ref.ref !== undefined && !(ref.ref in tokens)) {\n errors.push(\n `globals element '${selector}'${where}: '${property}' references unknown token ` +\n `'${ref.ref}' — check the token path, or use a bare string / number for a raw CSS value`,\n );\n }\n }\n };\n for (const ruleSetGroup of Object.values(ruleSets)) {\n for (const ruleSet of Object.values(ruleSetGroup)) {\n if (ruleSet.kind !== \"globals\") continue;\n const selector = ruleSet.selector ?? \"\";\n checkDecls(ruleSet.declarations, selector, \"\");\n for (const override of ruleSet.overrides ?? []) {\n checkDecls(override.declarations, selector, \" (override)\");\n }\n for (const [variantName, variant] of Object.entries(ruleSet.variants ?? {})) {\n const where = ` (variant '${variantName}')`;\n checkDecls(variant.declarations, selector, where);\n for (const override of variant.overrides ?? []) {\n checkDecls(override.declarations, selector, `${where} (override)`);\n }\n }\n }\n }\n return errors;\n}\n\n/**\n * Assemble the public theme surface over a Model — the token map, `resolveToken`, `adapter.bind`,\n * and the `override` seam. Called once for the initial Model and once per child (a fresh surface\n * over the merged Model), so parent and child never share mutable derived state — only the\n * immutable Model branches the merge left untouched.\n */\nfunction assembleTheme(model: ThemeModel, engine: ThemeEngine): Theme {\n const media = buildMedia(model.breakpoints, engine.mediaConfig);\n // Per-named-container `@container` descriptors (§10.5), sharing the media unit config.\n const containers = buildContainerDescriptors(model.containers, engine.mediaConfig);\n\n // Flat `path -> Ref` token map, derived lazily from the Model and cached on the Model reference\n // (the locked caching principle). A child's new Model is a new WeakMap key → a fresh, un-stale map.\n const tokenMapCache = new WeakMap<ThemeModel, Record<string, Ref>>();\n const getTokens = (): Record<string, Ref> => {\n let map = tokenMapCache.get(model);\n if (!map) {\n map = buildTokenMap(model);\n tokenMapCache.set(model, map);\n }\n return map;\n };\n\n // Resolve one token path to a literal via the 0e resolver (also fills RenderContext.resolve).\n const resolve = (path: string): Literal =>\n resolveToken(getTokens(), engine.derivationRegistry, path);\n const ctx: RenderContext = { media, containers, resolve };\n\n // Bind the adapter once (curries Model + ctx onto the render surface). Its `extend` attaches the\n // adapter's own output surface (the CSS adapter → `css` / `variablesCss` / `recipesCss` / `nodes`\n // / `classes`, computed on demand). Core stays format-agnostic.\n const bound = engine.adapter.bind(model, ctx);\n\n const theme: Theme = {\n model,\n get tokens() {\n return getTokens();\n },\n resolveToken: resolve,\n override: partial => overrideTheme(model, partial as Record<string, unknown>, engine),\n };\n\n const extensions = bound.extend?.(theme as unknown as Record<string, unknown>);\n if (extensions) {\n Object.defineProperties(theme, Object.getOwnPropertyDescriptors(extensions));\n }\n\n return theme;\n}\n\n/**\n * `theme.override(partial)` — the delta merge. Normalize ONLY the partial's changed subsystem\n * slices through {@link buildSubsystemInput}, immutably merge those fragments into the current\n * Model ({@link mergeSubsystemModel}), and re-assemble onto the new Model. The parent Model is left\n * byte-identical (structural sharing for untouched branches). Recipe interpretation in the delta\n * resolves refs against the parent's reconstructed properties overlaid with the partial's own.\n */\nfunction overrideTheme(\n currentModel: ThemeModel,\n partial: Record<string, unknown>,\n engine: ThemeEngine,\n): Theme {\n const partialBreakpoints = partial.breakpoints as Record<string, number> | undefined;\n const nextBreakpoints = partialBreakpoints\n ? { ...currentModel.breakpoints, ...partialBreakpoints }\n : currentModel.breakpoints;\n const allowedBreakpoints = Object.keys(nextBreakpoints);\n const media = buildMedia(nextBreakpoints, engine.mediaConfig);\n\n // Containers (§10.5): a partial `containers` config merges by name into the parent's (like breakpoints).\n const partialContainers = normalizeContainers(partial.containers);\n const nextContainers = partialContainers\n ? { ...(currentModel.containers ?? {}), ...partialContainers }\n : currentModel.containers;\n const allowedContainers = containerSizeSets(nextContainers);\n\n // Shallow copy of the subsystem map; only the touched keys get a new SubsystemModel (the rest keep\n // their reference → real structural sharing, parent stays byte-identical).\n const nextSubsystems: Record<string, SubsystemModel> = { ...currentModel.subsystems };\n for (const subsystem of SUBSYSTEMS) {\n const rawSlice = partial[subsystem.key] as Record<string, unknown> | undefined;\n if (rawSlice === undefined) continue; // untouched subsystem → shared reference\n\n const inheritedProperties = reconstructNormalizedProperties(currentModel.subsystems[subsystem.key]);\n const partialInput = buildSubsystemInput(subsystem, rawSlice, {\n breakpoints: nextBreakpoints,\n // Parent externals survive via mergeSubsystemModel; this prefix only resolves a NEW external the\n // override partial itself introduces (partial `extends` wins, else the default `\"dt\"`).\n extendsPrefix: (partial.extends as { prefix?: string } | undefined)?.prefix ?? \"dt\",\n media,\n mediaConfig: engine.mediaConfig,\n allowedBreakpoints,\n allowedStates: engine.allowedStates,\n allowedContainers,\n inheritedProperties,\n });\n const partialSubModel = buildSubsystemModel(partialInput);\n if (!partialSubModel) continue; // the delta contributed nothing to this subsystem\n\n nextSubsystems[subsystem.key] = mergeSubsystemModel(currentModel.subsystems[subsystem.key], partialSubModel);\n }\n\n const nextModel: ThemeModel = { breakpoints: nextBreakpoints, subsystems: nextSubsystems };\n if (nextContainers && Object.keys(nextContainers).length) nextModel.containers = nextContainers;\n // §21: re-resolve length units on the merged Model. Idempotent — already-resolved parent branches\n // (units baked) are skipped; only the partial's freshly-built fragments get resolved.\n const resolved = resolveModelUnits(nextModel, engine.unitConfig);\n // dec.4 — re-bake cross-property derived values against the MERGED token map, so a child re-derives\n // them when the source property changed (even if the deriving property wasn't in the partial). The\n // pass is immutable, so the parent's shared Refs are never mutated.\n const baked = bakeCrossPropertyDerivations(resolved, engine.derivationRegistry);\n return assembleTheme(baked, engine);\n}\n","/**\n * `resolveEmitPlan` — normalize the authored `Emit` directive into a discriminated `NormalizedEmit`\n * with every default filled (§9, 9a). This is the build layer's light normalization; the *vocabulary*\n * (`Emit`/`NormalizedEmit`) lives in core (`src/core/ThemeAdapter.ts`), and each adapter decides which\n * modes it actually honors — `resolveEmitPlan` never renders anything.\n *\n * Discriminator inference (only `single`/`split` may omit `type`):\n * - `undefined` / `{}` / `{ file }` → `single` (`file` renames the one file; default theme.css)\n * - the `variables` key present → `split` (that key is what tips `{ file, variables }` in)\n * - `subsystem` / `components` → require an explicit `type` (or the string shorthand)\n *\n * Per-type filename/name defaults:\n * - single → `theme.css`\n * - split → `styles.css` + `variables.css`\n * - subsystem → `<sub>.css` / `<sub>.variables.css`\n * - components→ `${group}-${variant}.css`, `inline: true`, `variables` on (a filename)\n */\nimport type { Emit, NormalizedEmit } from \"../core/ThemeAdapter\";\n\nconst DEFAULT_SINGLE_FILE = \"theme.css\";\nconst DEFAULT_SPLIT_STYLES = \"styles.css\";\nconst DEFAULT_SPLIT_VARIABLES = \"variables.css\";\nconst DEFAULT_SUBSYSTEM_FILENAME = (subsystem: string, kind: \"styles\" | \"variables\"): string =>\n kind === \"variables\" ? `${subsystem}.variables.css` : `${subsystem}.css`;\nconst DEFAULT_COMPONENTS_FILENAME = (c: { group: string; variant: string }): string =>\n `${c.group}-${c.variant}.css`;\nconst DEFAULT_COMPONENTS_VARIABLES = \"variables.css\";\n\n/** Normalize an authored {@link Emit} directive into a fully-defaulted {@link NormalizedEmit}. */\nexport function resolveEmitPlan(emit: Emit): NormalizedEmit {\n // String shorthands.\n if (emit === undefined) return { type: \"single\", file: DEFAULT_SINGLE_FILE };\n if (typeof emit === \"string\") {\n switch (emit) {\n case \"single\":\n return { type: \"single\", file: DEFAULT_SINGLE_FILE };\n case \"split\":\n return {\n type: \"split\",\n file: DEFAULT_SPLIT_STYLES,\n variables: DEFAULT_SPLIT_VARIABLES,\n };\n case \"subsystem\":\n return { type: \"subsystem\", filename: DEFAULT_SUBSYSTEM_FILENAME };\n case \"components\":\n return {\n type: \"components\",\n inline: true,\n filename: DEFAULT_COMPONENTS_FILENAME,\n variables: DEFAULT_COMPONENTS_VARIABLES,\n };\n }\n }\n\n // Object forms. Infer the discriminator when omitted: `variables` key ⇒ split, else single.\n const type = emit.type ?? (\"variables\" in emit ? \"split\" : \"single\");\n\n switch (type) {\n case \"single\": {\n const o = emit as { type?: \"single\"; file?: string };\n return { type: \"single\", file: o.file ?? DEFAULT_SINGLE_FILE };\n }\n case \"split\": {\n const o = emit as { type?: \"split\"; file?: string; variables?: string };\n return {\n type: \"split\",\n file: o.file ?? DEFAULT_SPLIT_STYLES,\n variables: o.variables ?? DEFAULT_SPLIT_VARIABLES,\n };\n }\n case \"subsystem\": {\n const o = emit as {\n type: \"subsystem\";\n filename?: (subsystem: string, kind: \"styles\" | \"variables\") => string;\n };\n return { type: \"subsystem\", filename: o.filename ?? DEFAULT_SUBSYSTEM_FILENAME };\n }\n case \"components\": {\n const o = emit as {\n type: \"components\";\n inline?: boolean;\n filename?: (c: { group: string; variant: string }) => string;\n variables?: string | false;\n };\n return {\n type: \"components\",\n inline: o.inline ?? true,\n filename: o.filename ?? DEFAULT_COMPONENTS_FILENAME,\n variables: o.variables ?? DEFAULT_COMPONENTS_VARIABLES,\n };\n }\n }\n\n // Unreachable — the union is exhausted above; keeps the compiler's return-path check happy.\n throw new Error(`resolveEmitPlan: unrecognized emit directive.`);\n}\n","/**\n * W3C Design Tokens Community Group (DTCG) format types.\n * Based on Second Editors' Draft (2024).\n */\n\n// --- Primitive token value types ---\n\nexport type DTCGColorValue = string;\n\nexport type DTCGDimensionValue = string; // e.g. \"16px\", \"1rem\"\n\nexport type DTCGFontFamilyValue = string | string[];\n\nexport type DTCGFontWeightValue = number | string; // 400 or \"bold\"\n\nexport type DTCGDurationValue = string; // \"200ms\", \"0.3s\"\n\nexport type DTCGCubicBezierValue = [number, number, number, number];\n\nexport type DTCGNumberValue = number;\n\n// --- Composite token value types ---\n\nexport type DTCGTypographyValue = {\n fontFamily: string | string[];\n fontSize: string;\n fontWeight: number | string;\n lineHeight: number | string;\n letterSpacing?: string;\n};\n\nexport type DTCGShadowLayerValue = {\n offsetX: string;\n offsetY: string;\n blur: string;\n spread: string;\n color: string;\n inset?: boolean;\n};\n\nexport type DTCGShadowValue = DTCGShadowLayerValue | DTCGShadowLayerValue[];\n\nexport type DTCGBorderValue = {\n color: string;\n width: string;\n style: string;\n};\n\nexport type DTCGTransitionValue = {\n duration: string;\n delay?: string;\n timingFunction: DTCGCubicBezierValue;\n};\n\n// --- Token types enum ---\n\nexport type DTCGTokenType =\n | \"color\"\n | \"dimension\"\n | \"fontFamily\"\n | \"fontWeight\"\n | \"duration\"\n | \"cubicBezier\"\n | \"number\"\n | \"typography\"\n | \"shadow\"\n | \"border\"\n | \"transition\"\n | \"strokeStyle\"\n | \"gradient\";\n\n// --- Token node ---\n\nexport type DTCGToken = {\n $value: unknown;\n $type?: DTCGTokenType;\n $description?: string;\n $extensions?: Record<string, unknown>;\n};\n\nexport type DTCGGroup = {\n $type?: DTCGTokenType;\n $description?: string;\n $extensions?: Record<string, unknown>;\n [key: string]: DTCGToken | DTCGGroup | DTCGTokenType | string | Record<string, unknown> | undefined;\n};\n\nexport type DTCGDocument = DTCGGroup & {\n $name?: string;\n};\n\n// --- Resolved token (after reference resolution) ---\n\nexport type ResolvedDTCGToken = {\n path: string[];\n type: DTCGTokenType;\n value: unknown;\n description?: string;\n extensions?: Record<string, unknown>;\n};\n\n// --- refract round-trip extension ---\n\n/**\n * The reverse-DNS `$extensions` key under which `toDTCG(theme, { includeRecipes: true })` stashes the\n * built rule-set / keyframe / container IR so a document round-trips `refract → DTCG → refract` without\n * loss. Standard DTCG tools ignore unknown extensions, so the payload is **refract-specific and not\n * portable** — property tokens are the interoperable surface; recipes ride here.\n */\nexport const REFRACT_DTCG_EXTENSION = \"com.theme-registry.refract\";\n\n/** The payload schema version under {@link REFRACT_DTCG_EXTENSION}; bumped on a breaking shape change. */\nexport const REFRACT_DTCG_EXTENSION_VERSION = 1;\n","import type { DTCGDocument, DTCGTokenType, ResolvedDTCGToken } from \"./types\";\nimport { RefractError } from \"../core/errors\";\n\nconst SPEC_KEYS = new Set([\"$value\", \"$type\", \"$description\", \"$extensions\", \"$name\"]);\n\nconst isToken = (node: unknown): boolean =>\n typeof node === \"object\" && node !== null && \"$value\" in (node as Record<string, unknown>);\n\n/**\n * Walk a DTCG document and extract all tokens with resolved types and paths.\n * References (`{path.to.token}`) are resolved recursively.\n */\nexport const parseDTCGDocument = (doc: DTCGDocument): ResolvedDTCGToken[] => {\n const tokens: ResolvedDTCGToken[] = [];\n const tokensByPath = new Map<string, ResolvedDTCGToken>();\n\n // First pass: collect all tokens with their raw values\n const walk = (node: Record<string, unknown>, path: string[], inheritedType?: DTCGTokenType) => {\n const groupType = (node.$type as DTCGTokenType | undefined) ?? inheritedType;\n\n for (const [key, child] of Object.entries(node)) {\n if (key.startsWith(\"$\")) continue;\n if (typeof child !== \"object\" || child === null) continue;\n\n const childPath = [...path, key];\n\n if (isToken(child)) {\n const token = child as Record<string, unknown>;\n const resolved: ResolvedDTCGToken = {\n path: childPath,\n type: (token.$type as DTCGTokenType) ?? groupType ?? \"color\",\n value: token.$value,\n description: token.$description as string | undefined,\n extensions: token.$extensions as Record<string, unknown> | undefined,\n };\n tokens.push(resolved);\n tokensByPath.set(childPath.join(\".\"), resolved);\n } else {\n walk(child as Record<string, unknown>, childPath, groupType);\n }\n }\n };\n\n walk(doc, []);\n\n // Second pass: resolve references\n for (const token of tokens) {\n token.value = resolveReferences(token.value, tokensByPath);\n }\n\n return tokens;\n};\n\nconst REFERENCE_PATTERN = /^\\{([^}]+)\\}$/;\n\nconst resolveReferences = (\n value: unknown,\n tokensByPath: Map<string, ResolvedDTCGToken>,\n visited = new Set<string>(),\n): unknown => {\n if (typeof value === \"string\") {\n const match = value.match(REFERENCE_PATTERN);\n if (match) {\n const refPath = match[1];\n if (visited.has(refPath)) {\n throw new RefractError(\"REFRACT_E_CYCLE\", `Circular token reference: ${refPath}`);\n }\n const referenced = tokensByPath.get(refPath);\n if (!referenced) {\n return value; // unresolved reference — leave as-is\n }\n visited.add(refPath);\n return resolveReferences(referenced.value, tokensByPath, visited);\n }\n return value;\n }\n\n if (Array.isArray(value)) {\n return value.map(item => resolveReferences(item, tokensByPath, new Set(visited)));\n }\n\n if (typeof value === \"object\" && value !== null) {\n const result: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(value)) {\n result[k] = resolveReferences(v, tokensByPath, new Set(visited));\n }\n return result;\n }\n\n return value;\n};\n","/**\n * `defineAdapter` — turns an `AdapterSpec` (identity + a `bind` returning the four\n * required primitives) into a full `ThemeAdapter` whose `bind` yields a complete\n * `BoundAdapter` with the DEFAULTED aggregators supplied.\n *\n * The defaults are pure Model walks: the Model enumerates every subsystem and every\n * (group, variant), so core loops it, calls the author's per-unit renderers, and\n * `join`s the results. Model/ctx are already bound, so the aggregators take no args.\n * An author can still override any aggregator (a format whose full document isn't a\n * flat concatenation).\n */\n\nimport type { ThemeModel } from \"./model\";\nimport type {\n AdapterSpec,\n ThemeAdapter,\n BoundAdapter,\n RenderContext,\n UsageDescriptor,\n} from \"./ThemeAdapter\";\n\n/** Every rule-set address in the Model — `(subsystem, group, variant)` triples. */\nfunction eachRuleSet(model: ThemeModel): Array<{ subsystem: string; group: string; variant: string }> {\n const out: Array<{ subsystem: string; group: string; variant: string }> = [];\n for (const [subsystem, sub] of Object.entries(model.subsystems)) {\n for (const [group, ruleSet] of Object.entries(sub.ruleSets ?? {})) {\n for (const variant of Object.keys(ruleSet)) {\n out.push({ subsystem, group, variant });\n }\n }\n }\n return out;\n}\n\n/**\n * Complete an `AdapterSpec` into a `ThemeAdapter`.\n *\n * Wraps the author's `bind` so the returned `BoundAdapter` gains the defaulted\n * aggregators (`renderAllRecipes` / `renderAllVariables` / `renderAll`) built from\n * the required primitives — unless the spec already provides its own override.\n * `name` / `version` pass through unchanged.\n *\n * @param spec identity (`name`/`version`) + a `bind(model, ctx)` returning the\n * required render primitives (and any optional overrides).\n * @returns a full adapter whose `bind(model, ctx)` yields a complete `BoundAdapter`.\n */\nexport function defineAdapter<TUnit>(spec: AdapterSpec<TUnit>): ThemeAdapter<TUnit> {\n return {\n name: spec.name,\n version: spec.version,\n allowedStates: spec.allowedStates,\n bind(model: ThemeModel, ctx: RenderContext): BoundAdapter<TUnit> {\n const b = spec.bind(model, ctx);\n\n const renderAllRecipes =\n b.renderAllRecipes ??\n ((): TUnit =>\n b.join(\n eachRuleSet(model).map(({ subsystem, group, variant }) =>\n b.renderRecipe(subsystem, group, variant),\n ),\n ));\n\n const renderAllVariables =\n b.renderAllVariables ??\n ((): TUnit => b.join(Object.keys(model.subsystems).map(subsystem => b.renderVariables(subsystem))));\n\n const renderAll =\n b.renderAll ?? ((): TUnit => b.join([renderAllVariables(), renderAllRecipes()]));\n\n // Generic self-documentation: the recipe identities are format-correct via `recipeName`; an\n // adapter overrides `describeUsage` to add format-specific import prose to `summary`.\n const describeUsage =\n b.describeUsage ??\n ((): UsageDescriptor => ({\n format: spec.name,\n summary: [`This theme was built with the \"${spec.name}\" refract adapter.`],\n recipes: eachRuleSet(model).map(({ subsystem, group, variant }) => ({\n subsystem,\n group,\n variant,\n name: b.recipeName(subsystem, group, variant),\n })),\n }));\n\n return { ...b, renderAllRecipes, renderAllVariables, renderAll, describeUsage };\n },\n };\n}\n","/**\n * `createNoopAdapter` — the trivial, built-in null adapter (monorepo split, friction 2).\n *\n * `createTheme` requires an `adapter`, but some consumers of the built `Theme` never touch\n * adapter-produced strings — they read only the format-neutral `theme.tokens` / `theme.resolveToken`\n * / `theme.model` (the DTCG export is the canonical example: `toDTCG` walks the flat token map and the\n * breakpoints, never a rendered rule). Those callers need *a* valid adapter purely to satisfy the\n * contract; the output is discarded.\n *\n * Before the split the CLI's `tokens` command reached for `createCssAdapter` as that throwaway builder\n * — which forced a core→adapter dependency (`src/build` importing `src/adapters/css`). The monorepo\n * guiding rule is that the dependency arrow points ONLY into core, so core now ships its own null\n * object: `createNoopAdapter()` emits nothing (empty strings, an empty `emit()`), lets `createTheme`\n * build the Model + token map exactly as any adapter would, and keeps `src/build` free of every\n * adapter package.\n *\n * It's a `ThemeAdapter` like any other (built through {@link defineAdapter}, so it gets the defaulted\n * aggregators for free), just with render primitives that produce empty output.\n */\n\nimport { defineAdapter } from \"./defineAdapter\";\nimport type { ThemeAdapter } from \"./ThemeAdapter\";\n\n/**\n * A no-op adapter: every render primitive returns an empty string and `emit()` writes no files. Use it\n * whenever a `Theme` is needed only for its format-neutral data (`tokens` / `resolveToken` / `model`)\n * and the rendered output is irrelevant — e.g. the `refract tokens` DTCG export.\n */\nexport function createNoopAdapter(): ThemeAdapter<string> {\n return defineAdapter<string>({\n name: \"noop\",\n version: 1,\n bind: () => ({\n recipeName: () => \"\",\n renderRecipe: () => \"\",\n renderVariables: () => \"\",\n join: parts => parts.join(\"\"),\n emit: () => ({ files: {} }),\n }),\n });\n}\n","import type { DTCGDocument, DTCGShadowLayerValue, DTCGTypographyValue, DTCGBorderValue, DTCGTransitionValue, ResolvedDTCGToken } from \"./types\";\nimport { REFRACT_DTCG_EXTENSION, REFRACT_DTCG_EXTENSION_VERSION } from \"./types\";\nimport type { RefractDTCGExtension } from \"./export\";\nimport { parseDTCGDocument } from \"./parse\";\nimport { createTheme, RefractError } from \"../core\";\nimport type { Theme, ThemeAdapter } from \"../core\";\n\ntype RawThemeInput = Record<string, unknown>;\n\nexport type FromDTCGOptions = {\n /**\n * How to map DTCG groups to refract subsystems.\n * Default: auto-detect from $type and group name.\n */\n groupMapping?: Record<string, \"colors\" | \"typography\" | \"effects\" | \"borders\" | \"layout\" | \"ignore\">;\n\n /**\n * Breakpoints as { name: pixelValue } — DTCG has no breakpoint type,\n * so these must be provided separately or mapped from dimension tokens.\n */\n breakpoints?: Record<string, number>;\n\n /**\n * DTCG group path to use as breakpoints source (e.g. \"breakpoint\").\n * Dimension values are parsed to pixels.\n */\n breakpointGroup?: string;\n};\n\n/**\n * Convert a DTCG token document into a `createTheme` raw input.\n *\n * Returns a plain object — modify it freely before passing to `createTheme`.\n */\nexport const fromDTCG = (doc: DTCGDocument, options?: FromDTCGOptions): RawThemeInput => {\n const tokens = parseDTCGDocument(doc);\n const groupMapping = options?.groupMapping ?? {};\n\n const colors: Record<string, unknown> = {};\n const typography: Record<string, unknown> = {};\n const effects: Record<string, unknown> = {};\n const borders: Record<string, unknown> = {};\n const layout: Record<string, unknown> = {};\n let breakpoints: Record<string, number> = options?.breakpoints ?? {};\n\n // Group tokens by their top-level path segment\n const grouped = new Map<string, ResolvedDTCGToken[]>();\n for (const token of tokens) {\n const topGroup = token.path[0];\n if (!grouped.has(topGroup)) grouped.set(topGroup, []);\n grouped.get(topGroup)!.push(token);\n }\n\n // Extract breakpoints if a breakpoint group is specified\n const bpGroup = options?.breakpointGroup;\n if (bpGroup && grouped.has(bpGroup)) {\n breakpoints = {};\n for (const token of grouped.get(bpGroup)!) {\n const name = token.path[token.path.length - 1];\n breakpoints[name] = parseDimension(token.value as string);\n }\n grouped.delete(bpGroup);\n }\n\n for (const [groupName, groupTokens] of grouped) {\n const mapping = groupMapping[groupName] ?? detectSubsystem(groupName, groupTokens);\n if (mapping === \"ignore\") continue;\n\n switch (mapping) {\n case \"colors\":\n mapColorTokens(groupTokens, groupName, colors);\n break;\n case \"typography\":\n mapTypographyTokens(groupTokens, groupName, typography);\n break;\n case \"effects\":\n mapEffectsTokens(groupTokens, groupName, effects);\n break;\n case \"borders\":\n mapBordersTokens(groupTokens, groupName, borders);\n break;\n case \"layout\":\n mapLayoutTokens(groupTokens, groupName, layout);\n break;\n }\n }\n\n const result: RawThemeInput = {};\n if (Object.keys(breakpoints).length) result.breakpoints = breakpoints;\n if (Object.keys(colors).length) result.colors = colors;\n if (Object.keys(typography).length) result.typography = typography;\n if (Object.keys(effects).length) result.effects = effects;\n if (Object.keys(borders).length) result.borders = borders;\n if (Object.keys(layout).length) result.layout = layout;\n\n return result;\n};\n\n// --- Auto-detection ---\n\nconst detectSubsystem = (\n groupName: string,\n tokens: ResolvedDTCGToken[],\n): \"colors\" | \"typography\" | \"effects\" | \"borders\" | \"layout\" | \"ignore\" => {\n const firstType = tokens[0]?.type;\n\n // By type\n if (firstType === \"color\") return \"colors\";\n if (firstType === \"typography\") return \"typography\";\n if (firstType === \"shadow\") return \"effects\";\n if (firstType === \"border\") return \"borders\"; // §14 — border geometry lives in `borders` now\n if (firstType === \"strokeStyle\") return \"borders\";\n if (firstType === \"transition\") return \"effects\";\n\n // By name convention\n const lower = groupName.toLowerCase();\n if (lower.includes(\"color\") || lower.includes(\"palette\")) return \"colors\";\n if (lower.includes(\"font\") || lower.includes(\"typo\") || lower.includes(\"text\")) return \"typography\";\n if (lower.includes(\"spacing\") || lower.includes(\"space\") || lower.includes(\"gutter\")) return \"layout\";\n // Borders keywords take precedence over effects (radius/border/outline moved out of effects).\n if (lower.includes(\"radius\") || lower.includes(\"border\") || lower.includes(\"outline\")) return \"borders\";\n if (lower.includes(\"shadow\") || lower.includes(\"blur\") || lower.includes(\"opacity\") ||\n lower.includes(\"z-index\") || lower.includes(\"zindex\") || lower.includes(\"transition\") ||\n lower.includes(\"effect\")) return \"effects\";\n\n // Dimension tokens: check naming\n if (firstType === \"dimension\") {\n if (lower.includes(\"spacing\") || lower.includes(\"gap\")) return \"layout\";\n if (lower.includes(\"radius\") || lower.includes(\"border\")) return \"borders\";\n if (lower.includes(\"font\") || lower.includes(\"size\")) return \"typography\";\n }\n\n return \"ignore\";\n};\n\n// --- External aliases (dec.6 / §12 Phase 2) ---\n\n/** A DTCG value left as `\"{group.token}\"` after parse — an alias whose target is ABSENT from the\n * document (`parseDTCGDocument` leaves an unresolvable reference verbatim). */\nconst UNRESOLVED_ALIAS = /^\\{([^}]+)\\}$/;\n\n/**\n * Map a genuinely-external DTCG alias (target absent from the doc) to a refract `external` token path\n * — the refract analog of \"this references a token another (parent) theme owns.\" The DTCG `color`\n * group renames to the `colors` subsystem; other groups pass through best-effort. Returns `undefined`\n * for a non-alias / resolved value (which stays a normal literal). A resolvable same-doc alias never\n * reaches here — `parseDTCGDocument` already flattened it to its literal.\n */\nconst aliasToExternalPath = (value: unknown): string | undefined => {\n if (typeof value !== \"string\") return undefined;\n const match = value.match(UNRESOLVED_ALIAS);\n if (!match) return undefined;\n const inner = match[1];\n const dot = inner.indexOf(\".\");\n const group = dot < 0 ? inner : inner.slice(0, dot);\n const rest = dot < 0 ? \"\" : inner.slice(dot + 1);\n const subsystem = group === \"color\" ? \"colors\" : group;\n return rest ? `${subsystem}.${rest}` : subsystem;\n};\n\n// --- Color mapping ---\n\nconst mapColorTokens = (tokens: ResolvedDTCGToken[], groupName: string, colors: Record<string, unknown>) => {\n // Group by second path segment (e.g. color.brand.primary → \"brand\")\n const subgroups = new Map<string, ResolvedDTCGToken[]>();\n const topLevel: ResolvedDTCGToken[] = [];\n\n for (const token of tokens) {\n if (token.path.length <= 2) {\n topLevel.push(token);\n } else {\n const sub = token.path[1];\n if (!subgroups.has(sub)) subgroups.set(sub, []);\n subgroups.get(sub)!.push(token);\n }\n }\n\n // Top-level color tokens → flat colors with base. A genuinely-external alias (absent target) →\n // a refract `external` passthrough (dec.6) rather than a literal `{ base }` (which would reject `{…}`).\n for (const token of topLevel) {\n const name = token.path[token.path.length - 1];\n if (!colors[name]) {\n const external = aliasToExternalPath(token.value);\n colors[name] = external ? { external } : { base: String(token.value) };\n }\n }\n\n // Subgroups → colors with variants\n for (const [subName, subTokens] of subgroups) {\n if (subTokens.length === 1) {\n const token = subTokens[0];\n const name = token.path[token.path.length - 1];\n if (name === subName) {\n colors[subName] = { base: String(token.value) };\n } else {\n if (!colors[subName]) colors[subName] = { base: String(subTokens[0].value) };\n (colors[subName] as Record<string, unknown>).variants = {\n [name]: String(token.value),\n };\n }\n } else {\n // Multiple tokens in subgroup → first or \"base\"/\"default\"/\"500\" is base, rest are variants\n const baseToken = subTokens.find(t => {\n const last = t.path[t.path.length - 1];\n return last === \"base\" || last === \"default\" || last === \"500\";\n }) ?? subTokens[0];\n\n const variants: Record<string, string> = {};\n for (const t of subTokens) {\n if (t === baseToken) continue;\n const variantName = t.path.slice(2).join(\"-\");\n variants[variantName] = String(t.value);\n }\n\n colors[subName] = {\n base: String(baseToken.value),\n ...(Object.keys(variants).length ? { variants } : {}),\n };\n }\n }\n};\n\n// --- Typography mapping ---\n\nconst TYPO_PROPERTY_MAP: Record<string, string> = {\n fontfamily: \"fontFamily\",\n fontsize: \"fontSize\",\n fontweight: \"fontWeight\",\n lineheight: \"lineHeight\",\n letterspacing: \"letterSpacing\",\n fontstyle: \"fontStyle\",\n texttransform: \"textTransform\",\n textdecoration: \"textDecoration\",\n textalign: \"textAlign\",\n};\n\nconst mapTypographyTokens = (tokens: ResolvedDTCGToken[], groupName: string, typography: Record<string, unknown>) => {\n for (const token of tokens) {\n if (token.type === \"typography\") {\n // Composite typography token → decompose into individual properties\n const value = token.value as DTCGTypographyValue;\n const variantName = token.path.slice(1).join(\"-\") || token.path[token.path.length - 1];\n\n if (value.fontFamily) {\n addTypographyVariant(typography, \"fontFamily\",\n Array.isArray(value.fontFamily) ? value.fontFamily.join(\", \") : value.fontFamily, variantName);\n }\n if (value.fontSize) {\n addTypographyVariant(typography, \"fontSize\", parseDimensionOrKeep(value.fontSize), variantName);\n }\n if (value.fontWeight !== undefined) {\n addTypographyVariant(typography, \"fontWeight\", value.fontWeight, variantName);\n }\n if (value.lineHeight !== undefined) {\n addTypographyVariant(typography, \"lineHeight\", value.lineHeight, variantName);\n }\n if (value.letterSpacing) {\n addTypographyVariant(typography, \"letterSpacing\", value.letterSpacing, variantName);\n }\n } else {\n // Individual token (fontFamily, fontSize, fontWeight, dimension)\n const propertyKey = detectTypoProperty(token, groupName);\n if (!propertyKey) continue;\n const variantName = token.path[token.path.length - 1];\n const value = token.type === \"fontFamily\" && Array.isArray(token.value)\n ? (token.value as string[]).join(\", \")\n : token.type === \"dimension\"\n ? parseDimensionOrKeep(token.value as string)\n : token.value;\n addTypographyVariant(typography, propertyKey, value as string | number, variantName);\n }\n }\n};\n\nconst addTypographyVariant = (\n typography: Record<string, unknown>,\n property: string,\n value: string | number,\n variantName: string,\n) => {\n if (!typography[property]) {\n typography[property] = { base: value, variants: {} };\n return;\n }\n const prop = typography[property] as { base: unknown; variants: Record<string, unknown> };\n if (variantName === \"base\" || variantName === \"default\" || variantName === \"md\") {\n prop.base = value;\n } else {\n prop.variants[variantName] = value;\n }\n};\n\nconst detectTypoProperty = (token: ResolvedDTCGToken, groupName: string): string | null => {\n // Check token type\n if (token.type === \"fontFamily\") return \"fontFamily\";\n if (token.type === \"fontWeight\") return \"fontWeight\";\n\n // Check group or parent path naming\n const fullPath = token.path.join(\".\").toLowerCase();\n for (const [key, prop] of Object.entries(TYPO_PROPERTY_MAP)) {\n if (fullPath.includes(key)) return prop;\n }\n\n // Check group name\n const lower = groupName.toLowerCase();\n for (const [key, prop] of Object.entries(TYPO_PROPERTY_MAP)) {\n if (lower.includes(key)) return prop;\n }\n\n return null;\n};\n\n// --- Effects mapping ---\n\nconst mapEffectsTokens = (tokens: ResolvedDTCGToken[], groupName: string, effects: Record<string, unknown>) => {\n for (const token of tokens) {\n const variantName = token.path[token.path.length - 1];\n\n switch (token.type) {\n case \"shadow\": {\n const shadowStr = formatShadowValue(token.value);\n addEffectsVariant(effects, \"shadow\", shadowStr, variantName);\n break;\n }\n case \"transition\": {\n const transition = token.value as DTCGTransitionValue;\n const bezier = transition.timingFunction\n ? `cubic-bezier(${transition.timingFunction.join(\", \")})`\n : \"ease\";\n const transStr = `all ${transition.duration} ${bezier}`;\n addEffectsVariant(effects, \"transitions\", transStr, variantName);\n break;\n }\n case \"dimension\": {\n const lower = token.path.join(\".\").toLowerCase();\n if (lower.includes(\"blur\")) {\n addEffectsVariant(effects, \"blur\", parseDimensionOrKeep(token.value as string), variantName);\n }\n break;\n }\n case \"number\": {\n const lower = token.path.join(\".\").toLowerCase();\n if (lower.includes(\"opacity\")) {\n addEffectsVariant(effects, \"opacity\", token.value as number, variantName);\n } else if (lower.includes(\"z-index\") || lower.includes(\"zindex\")) {\n addEffectsVariant(effects, \"zIndex\", token.value as number, variantName);\n }\n break;\n }\n }\n }\n};\n\nconst addEffectsVariant = (\n effects: Record<string, unknown>,\n property: string,\n value: string | number,\n variantName: string,\n) => {\n if (!effects[property]) {\n effects[property] = { base: value, variants: {} };\n return;\n }\n const prop = effects[property] as { base: unknown; variants: Record<string, unknown> };\n if (variantName === \"base\" || variantName === \"default\" || variantName === \"md\") {\n prop.base = value;\n } else {\n prop.variants[variantName] = value;\n }\n};\n\n// --- Borders mapping (§14) ---\n\nconst mapBordersTokens = (tokens: ResolvedDTCGToken[], groupName: string, borders: Record<string, unknown>) => {\n for (const token of tokens) {\n const variantName = token.path[token.path.length - 1];\n\n switch (token.type) {\n case \"border\": {\n // The DTCG `border` composite carries width + style + color; only the geometry maps to\n // borders tokens (§14.4 — color is never a borders token, so it is dropped on import).\n const border = token.value as DTCGBorderValue;\n addBordersVariant(borders, \"width\", parseDimensionOrKeep(border.width), variantName);\n if (border.style) addBordersVariant(borders, \"style\", border.style, variantName);\n break;\n }\n case \"strokeStyle\": {\n addBordersVariant(borders, \"style\", String(token.value), variantName);\n break;\n }\n case \"dimension\": {\n const lower = token.path.join(\".\").toLowerCase();\n if (lower.includes(\"radius\")) {\n addBordersVariant(borders, \"radius\", parseDimensionOrKeep(token.value as string), variantName);\n } else if (lower.includes(\"offset\")) {\n addBordersVariant(borders, \"offset\", parseDimensionOrKeep(token.value as string), variantName);\n } else if (lower.includes(\"width\")) {\n addBordersVariant(borders, \"width\", parseDimensionOrKeep(token.value as string), variantName);\n }\n break;\n }\n }\n }\n};\n\nconst addBordersVariant = (\n borders: Record<string, unknown>,\n property: string,\n value: string | number,\n variantName: string,\n) => {\n if (!borders[property]) {\n borders[property] = { base: value, variants: {} };\n return;\n }\n const prop = borders[property] as { base: unknown; variants: Record<string, unknown> };\n if (variantName === \"base\" || variantName === \"default\" || variantName === \"md\") {\n prop.base = value;\n } else {\n prop.variants[variantName] = value;\n }\n};\n\n// --- Layout mapping ---\n\nconst mapLayoutTokens = (tokens: ResolvedDTCGToken[], groupName: string, layout: Record<string, unknown>) => {\n for (const token of tokens) {\n if (token.type !== \"dimension\") continue;\n const variantName = token.path[token.path.length - 1];\n const value = parseDimension(token.value as string);\n\n if (!layout.spacing) {\n layout.spacing = { base: value, variants: {} };\n }\n\n const spacing = layout.spacing as { base: number; variants: Record<string, number> };\n if (variantName === \"base\" || variantName === \"default\" || variantName === \"4\") {\n spacing.base = value;\n } else {\n spacing.variants[variantName] = value;\n }\n }\n};\n\n// --- Helpers ---\n\nconst formatShadowValue = (value: unknown): string => {\n if (Array.isArray(value)) {\n return value.map(layer => formatSingleShadow(layer as DTCGShadowLayerValue)).join(\", \");\n }\n return formatSingleShadow(value as DTCGShadowLayerValue);\n};\n\nconst formatSingleShadow = (layer: DTCGShadowLayerValue): string => {\n const parts: string[] = [];\n if (layer.inset) parts.push(\"inset\");\n parts.push(layer.offsetX, layer.offsetY, layer.blur, layer.spread, layer.color);\n return parts.join(\" \");\n};\n\nconst parseDimension = (value: string | number): number => {\n if (typeof value === \"number\") return value;\n const num = parseFloat(value);\n if (isNaN(num)) return 0;\n // Convert rem to px (assume 16px base)\n if (value.endsWith(\"rem\")) return Math.round(num * 16);\n return num;\n};\n\nconst parseDimensionOrKeep = (value: string | number): string | number => {\n if (typeof value === \"number\") return value;\n const num = parseFloat(value);\n if (isNaN(num)) return value;\n if (value.endsWith(\"px\")) return num;\n return value;\n};\n\n// --- refract round-trip (recipes via the com.theme-registry.refract extension) ---\n\n/**\n * Read the refract round-trip payload from a DTCG document's top-level `$extensions`, or `undefined`\n * when it carries none. `parseDTCGDocument` intentionally drops top-level `$extensions`, so this reads\n * `doc.$extensions` directly. Throws on a payload from a newer, unreadable schema version.\n */\nexport const readRefractExtension = (doc: DTCGDocument): RefractDTCGExtension | undefined => {\n const ext = doc.$extensions?.[REFRACT_DTCG_EXTENSION] as RefractDTCGExtension | undefined;\n if (!ext) return undefined;\n if (ext.version !== REFRACT_DTCG_EXTENSION_VERSION) {\n throw new RefractError(\n \"REFRACT_E_DTCG_VERSION\",\n `Unsupported refract DTCG extension version ${ext.version} (this build reads version ` +\n `${REFRACT_DTCG_EXTENSION_VERSION}). Upgrade @theme-registry/refract to import this document's recipes.`,\n );\n }\n return ext;\n};\n\n/**\n * Lossless `DTCG → refract` round-trip entry: {@link fromDTCG} for the property tokens, plus the\n * recipes / keyframes / containers the document stashed under `com.theme-registry.refract` reinjected\n * through createTheme's overlay. A plain DTCG document (no refract extension) round-trips to a\n * recipe-less theme — identical to `createTheme(fromDTCG(doc), { adapter })`.\n */\nexport const fromDTCGTheme = (\n doc: DTCGDocument,\n options: FromDTCGOptions & { adapter: ThemeAdapter },\n): Theme => {\n const raw = fromDTCG(doc, options);\n const ext = readRefractExtension(doc);\n return createTheme(raw, {\n adapter: options.adapter,\n propertiesOverlay: ext?.properties,\n ruleSetsOverlay: ext?.ruleSets,\n keyframesOverlay: ext?.keyframes,\n containersOverlay: ext?.containers,\n });\n};\n","import type { Theme } from \"../core\";\nimport type { Literal, ShadowDimension, ShadowLayer, TransitionPart } from \"../core\";\nimport type { ThemeModel, RuleSetGroup, Keyframe, ContainerModel, PropertyModel } from \"../core\";\nimport type { DTCGDocument, DTCGTokenType } from \"./types\";\nimport { REFRACT_DTCG_EXTENSION, REFRACT_DTCG_EXTENSION_VERSION } from \"./types\";\nimport { toHexColor } from \"../subsystems/colors/utils\";\n\n/** The refract round-trip payload stashed under {@link REFRACT_DTCG_EXTENSION}. Built IR, verbatim. */\nexport type RefractDTCGExtension = {\n version: number;\n /**\n * Per-subsystem property Model verbatim (§12 Phase 2) — the lossless channel for what the portable\n * DTCG token surface can't carry: appearance `modes` (a `PropertyOverride[]` list), `responsive`\n * overrides, derivation metadata (`{ ref, modifiers }`), and `external` passthroughs. Reinjected on\n * import via createTheme's `propertiesOverlay`. The standard resolved-literal tokens still emit\n * alongside for portability; this is refract-only (other tools ignore the extension).\n */\n properties?: Record<string, Record<string, PropertyModel>>;\n ruleSets?: Record<string, Record<string, RuleSetGroup>>;\n keyframes?: Record<string, Record<string, Keyframe>>;\n containers?: Record<string, ContainerModel>;\n};\n\n/**\n * Collect a theme's built property / rule-set / keyframe / container IR into the round-trip payload, or\n * `undefined` when the theme has none (so `includeRecipes` on an empty theme still emits no\n * `$extensions`, keeping standard output byte-identical). The Model is \"serializable as-is\", a plain walk.\n */\nconst buildRefractExtension = (model: ThemeModel): RefractDTCGExtension | undefined => {\n const properties: Record<string, Record<string, PropertyModel>> = {};\n const ruleSets: Record<string, Record<string, RuleSetGroup>> = {};\n const keyframes: Record<string, Record<string, Keyframe>> = {};\n for (const [sub, subModel] of Object.entries(model.subsystems)) {\n if (subModel.properties && Object.keys(subModel.properties).length) properties[sub] = subModel.properties;\n if (subModel.ruleSets && Object.keys(subModel.ruleSets).length) ruleSets[sub] = subModel.ruleSets;\n if (subModel.keyframes && Object.keys(subModel.keyframes).length) keyframes[sub] = subModel.keyframes;\n }\n const hasProperties = Object.keys(properties).length > 0;\n const hasRuleSets = Object.keys(ruleSets).length > 0;\n const hasKeyframes = Object.keys(keyframes).length > 0;\n const hasContainers = !!model.containers && Object.keys(model.containers).length > 0;\n if (!hasProperties && !hasRuleSets && !hasKeyframes && !hasContainers) return undefined;\n return {\n version: REFRACT_DTCG_EXTENSION_VERSION,\n ...(hasProperties ? { properties } : {}),\n ...(hasRuleSets ? { ruleSets } : {}),\n ...(hasKeyframes ? { keyframes } : {}),\n ...(hasContainers ? { containers: model.containers } : {}),\n };\n};\n\nexport type ToDTCGOptions = {\n /** Name for the DTCG document. */\n name?: string;\n\n /** Whether to include breakpoints as dimension tokens. Default: true. */\n includeBreakpoints?: boolean;\n\n /**\n * Stash the theme's built Model IR — **property tokens (incl. modes / responsive / derivation refs /\n * external), rule-sets, keyframes, containers** — under the reverse-DNS `com.theme-registry.refract`\n * `$extensions` key, so the document round-trips `refract → DTCG → refract` **losslessly** via\n * {@link fromDTCGTheme} (§12 Phase 2 widened this from recipes-only to the whole Model). **Not\n * portable** — other DTCG tools ignore the extension and see the resolved property tokens only.\n * Default `false` (standard output stays byte-identical).\n */\n includeRecipes?: boolean;\n};\n\n/**\n * Convert a built theme's tokens into a DTCG-compliant JSON document.\n *\n * **Model-first re-port:** this walks the flat, format-neutral `theme.tokens` map\n * (`\"<subsystem>.<property>[.<variant>]\" -> Ref`) — the single source of truth that\n * replaced the retired per-subsystem `theme.<sub>.tokens` shape. Each token path is\n * resolved to a concrete literal via `theme.resolveToken` (following aliases and\n * running `lighten` / `darken` derivations), then re-grouped into DTCG groups.\n *\n * DTCG carries **property tokens only** — recipes / composition are out of scope, and\n * layout structural-config knobs (property names containing `--`) are skipped.\n *\n * Returns a plain object — modify it freely before writing to a file.\n */\nexport const toDTCG = (theme: Theme, options?: ToDTCGOptions): DTCGDocument => {\n const doc: DTCGDocument = {};\n\n if (options?.name) {\n doc.$name = options.name;\n }\n\n // Breakpoints — read from the Model, emitted as dimension tokens.\n const breakpoints = theme.model.breakpoints;\n if (options?.includeBreakpoints !== false && breakpoints && Object.keys(breakpoints).length) {\n const bp: Record<string, unknown> = { $type: \"dimension\" as DTCGTokenType };\n for (const [name, value] of Object.entries(breakpoints)) {\n bp[name] = { $value: `${value}px` };\n }\n doc.breakpoint = bp;\n }\n\n // Group the flat token map by subsystem → property, resolving each path to a literal.\n const grouped = groupTokens(theme);\n\n // Resolve a `colors.*` (or any) token path to its literal for embedding in a composed shadow\n // string; falls back to the raw path if unresolvable (defensive).\n const resolveColor = (path: string): string => {\n try {\n return String(theme.resolveToken(path));\n } catch {\n return path;\n }\n };\n\n // Colors — { $type: color, <name>: { base, text?, <variant> } }\n const colors = grouped.get(\"colors\");\n if (colors) {\n const group: Record<string, unknown> = { $type: \"color\" as DTCGTokenType };\n for (const [name, prop] of colors) {\n const node: Record<string, unknown> = {};\n if (prop.base !== undefined) {\n node.base = { $value: toHexColor(String(prop.base)) };\n }\n for (const [member, value] of Object.entries(prop.members)) {\n node[member] = { $value: toHexColor(String(value)) };\n }\n group[name] = node;\n }\n doc.color = group;\n }\n\n // Typography — nested under `doc.typography`, one group per property.\n const typography = grouped.get(\"typography\");\n if (typography) {\n const typo: Record<string, unknown> = {};\n for (const [propName, prop] of typography) {\n const type = getTypographyTokenType(propName);\n const group: Record<string, unknown> = { $type: type };\n if (prop.base !== undefined) {\n group.base = { $value: formatTypoValue(prop.base, prop.baseUnit) };\n }\n for (const [variant, value] of Object.entries(prop.members)) {\n group[variant] = { $value: formatTypoValue(value, prop.memberUnits[variant]) };\n }\n typo[propName] = group;\n }\n doc.typography = typo;\n }\n\n // Effects — one top-level group per property, named/typed by getEffectsGroupInfo.\n const effects = grouped.get(\"effects\");\n if (effects) {\n for (const [propName, prop] of effects) {\n const { groupName, type } = getEffectsGroupInfo(propName);\n if (!doc[groupName]) {\n doc[groupName] = { $type: type };\n }\n const group = doc[groupName] as Record<string, unknown>;\n // §15: a structured shadow/transition token composes to a CSS string at the DTCG boundary\n // (its `colors.*` color ref resolved to a literal) — consistent with how a string-authored\n // shadow already exports. A fully-structured DTCG composite round-trip is a future enhancement.\n if (prop.base !== undefined) {\n group.base = { $value: formatEffectsValue(propName, prop.base, resolveColor, prop.baseUnit) };\n }\n for (const [variant, value] of Object.entries(prop.members)) {\n group[variant] = { $value: formatEffectsValue(propName, value, resolveColor, prop.memberUnits[variant]) };\n }\n }\n }\n\n // Borders (§14) — one top-level group per property (radius/width/offset → dimension px,\n // style → strokeStyle). Border geometry moved out of effects; color is never a borders token.\n const borders = grouped.get(\"borders\");\n if (borders) {\n for (const [propName, prop] of borders) {\n const { groupName, type } = getBordersGroupInfo(propName);\n if (!doc[groupName]) {\n doc[groupName] = { $type: type };\n }\n const group = doc[groupName] as Record<string, unknown>;\n if (prop.base !== undefined) {\n group.base = { $value: formatBordersValue(prop.base, prop.baseUnit) };\n }\n for (const [variant, value] of Object.entries(prop.members)) {\n group[variant] = { $value: formatBordersValue(value, prop.memberUnits[variant]) };\n }\n }\n }\n\n // Layout (spacing / gutters / aspectRatio) — dimension tokens. Structural-config\n // knobs (`columns--*` / `container--*`) are internal, not interchange tokens.\n const layout = grouped.get(\"layout\");\n if (layout) {\n for (const [propName, prop] of layout) {\n if (propName.includes(\"--\")) continue;\n const groupName = propName;\n if (!doc[groupName]) {\n doc[groupName] = { $type: \"dimension\" as DTCGTokenType };\n }\n const group = doc[groupName] as Record<string, unknown>;\n if (prop.base !== undefined) {\n group.base = { $value: formatDimensionValue(prop.base, prop.baseUnit) };\n }\n for (const [variant, value] of Object.entries(prop.members)) {\n group[variant] = { $value: formatDimensionValue(value, prop.memberUnits[variant]) };\n }\n }\n }\n\n // §DTCG round-trip — opt-in: stash the built rule-set/keyframe/container IR under the refract\n // extension key. Only touched when `includeRecipes` is set AND the theme actually has recipes, so\n // the standard property-token document stays byte-identical by default.\n if (options?.includeRecipes) {\n const ext = buildRefractExtension(theme.model);\n if (ext) doc.$extensions = { ...(doc.$extensions ?? {}), [REFRACT_DTCG_EXTENSION]: ext };\n }\n\n return doc;\n};\n\n// --- Flat-token grouping ---\n\ntype PropTokens = {\n /** the `<sub>.<prop>` base token, if present. */\n base?: Literal;\n /** the `<sub>.<prop>.<member>` variants / extras (e.g. colors' `text`). */\n members: Record<string, Literal>;\n /** §21 resolved length unit for `base` (absent = unit-less / non-length / raw string). */\n baseUnit?: string;\n /** §21 resolved length unit per member. */\n memberUnits: Record<string, string>;\n};\n\n/** A resolved dimension → DTCG text: append the §21 unit baked on the Model leaf; a unit-less value\n * (lineHeight, opacity, aspectRatio) or a raw string passes through untouched. */\nconst dimText = (value: Literal, unit?: string): string | number =>\n unit !== undefined ? `${value}${unit}` : value;\n\n/**\n * Group the flat `theme.tokens` map into `subsystem -> property -> { base, members }`,\n * resolving each path to a concrete literal via `theme.resolveToken`. Unresolvable\n * paths are skipped (defensive — a well-formed Model resolves everything).\n */\nconst groupTokens = (theme: Theme): Map<string, Map<string, PropTokens>> => {\n const out = new Map<string, Map<string, PropTokens>>();\n for (const path of Object.keys(theme.tokens)) {\n const dot = path.indexOf(\".\");\n if (dot < 0) continue;\n const subsystem = path.slice(0, dot);\n const rest = path.slice(dot + 1);\n const dot2 = rest.indexOf(\".\");\n const property = dot2 < 0 ? rest : rest.slice(0, dot2);\n const member = dot2 < 0 ? undefined : rest.slice(dot2 + 1);\n\n // §W6b / §12 Phase 2: an EXTERNAL token is a passthrough to a parent-owned var (`var(--…)`); it\n // has no value this document owns. Skip it from the portable token surface — emitting it as a\n // `var(--…)` colour would break re-import (colours reject `var()`). The lossless refract extension\n // carries it verbatim (its `PropertyModel.base` keeps `external`), so the round-trip restores it.\n const ref = theme.tokens[path];\n if (ref?.external !== undefined) continue;\n let value: Literal;\n if (ref?.struct !== undefined) {\n value = ref.struct as unknown as Literal;\n } else {\n try {\n value = theme.resolveToken(path);\n } catch {\n continue;\n }\n }\n const unit = ref?.unit; // §21 resolved length unit (absent for unit-less / raw / struct tokens)\n\n let subMap = out.get(subsystem);\n if (!subMap) {\n subMap = new Map<string, PropTokens>();\n out.set(subsystem, subMap);\n }\n let prop = subMap.get(property);\n if (!prop) {\n prop = { members: {}, memberUnits: {} };\n subMap.set(property, prop);\n }\n if (member === undefined) {\n prop.base = value;\n if (unit !== undefined) prop.baseUnit = unit;\n } else {\n prop.members[member] = value;\n if (unit !== undefined) prop.memberUnits[member] = unit;\n }\n }\n return out;\n};\n\n// --- Value formatting (per subsystem/property) ---\n\nconst getTypographyTokenType = (propName: string): DTCGTokenType => {\n switch (propName) {\n case \"fontFamily\": return \"fontFamily\";\n case \"fontWeight\": return \"fontWeight\";\n case \"fontSize\":\n case \"letterSpacing\": return \"dimension\";\n default: return \"number\";\n }\n};\n\n/** Typography value → DTCG. Length props (fontSize, letterSpacing) carry a resolved unit; the rest\n * (fontFamily string, fontWeight/lineHeight numbers) are unit-less → pass through. */\nconst formatTypoValue = (value: Literal, unit?: string): string | number => dimText(value, unit);\n\nconst getEffectsGroupInfo = (propName: string): { groupName: string; type: DTCGTokenType } => {\n switch (propName) {\n case \"shadow\": return { groupName: \"shadow\", type: \"shadow\" };\n case \"transitions\": return { groupName: \"transition\", type: \"transition\" };\n case \"blur\": return { groupName: propName, type: \"dimension\" };\n case \"opacity\":\n case \"zIndex\": return { groupName: propName, type: \"number\" };\n default: return { groupName: propName, type: \"dimension\" };\n }\n};\n\n/** A resolved shadow geometry field (§21 `{value,unit}`, or a bare number) → CSS text. */\nconst dtcgShadowDim = (dim: ShadowDimension): string =>\n typeof dim === \"number\" ? `${dim}px` : `${dim.value}${dim.unit}`;\n\n/** The layer's shared length unit — from the first resolved geometry field; `px` if none resolved. */\nconst dtcgLayerUnit = (layer: ShadowLayer): string => {\n for (const field of [layer.offsetX, layer.offsetY, layer.blur, layer.spread]) {\n if (field !== undefined && typeof field !== \"number\") return field.unit;\n }\n return \"px\";\n};\n\n/** Compose a structured shadow value (§15) → a CSS `box-shadow` string with color refs resolved\n * (translucency is carried by the referenced colour — an `alpha` colour variant, §13.3). Geometry\n * fields carry a resolved unit (§21); an absent (required) offset defaults to `0` in the layer's unit. */\nconst composeDtcgShadow = (layers: ShadowLayer[], resolveColor: (path: string) => string): string =>\n layers\n .map(layer => {\n const zero = `0${dtcgLayerUnit(layer)}`;\n const len = (dim: ShadowDimension | undefined): string => (dim === undefined ? zero : dtcgShadowDim(dim));\n const parts: string[] = [];\n if (layer.inset) parts.push(\"inset\");\n parts.push(len(layer.offsetX), len(layer.offsetY));\n if (layer.spread != null) parts.push(len(layer.blur), len(layer.spread));\n else if (layer.blur != null) parts.push(len(layer.blur));\n if (layer.color) parts.push(resolveColor(layer.color));\n return parts.join(\" \");\n })\n .join(\", \");\n\n/** Compose a structured transition value (§15) → a CSS `transition` string. */\nconst composeDtcgTransition = (parts: TransitionPart[]): string =>\n parts\n .map(part => {\n const segs: string[] = [part.property];\n if (part.duration != null || part.delay != null) segs.push(`${part.duration ?? 0}ms`);\n if (part.timingFunction) segs.push(part.timingFunction);\n if (part.delay != null) segs.push(`${part.delay}ms`);\n return segs.join(\" \");\n })\n .join(\", \");\n\nconst formatEffectsValue = (\n propName: string,\n value: Literal,\n resolveColor: (path: string) => string,\n unit?: string,\n): string | number => {\n // §15: shadow/transitions arrive as a structured array (cast to `Literal` in groupTokens).\n if (Array.isArray(value)) {\n return propName === \"transitions\"\n ? composeDtcgTransition(value as TransitionPart[])\n : composeDtcgShadow(value as ShadowLayer[], resolveColor);\n }\n // `blur` carries a resolved length unit (§21); `opacity`/`zIndex` are unit-less → pass through.\n return dimText(value, unit);\n};\n\nconst getBordersGroupInfo = (propName: string): { groupName: string; type: DTCGTokenType } => {\n switch (propName) {\n case \"radius\": return { groupName: \"radius\", type: \"dimension\" };\n case \"width\": return { groupName: \"borderWidth\", type: \"dimension\" };\n case \"offset\": return { groupName: \"outlineOffset\", type: \"dimension\" };\n case \"style\": return { groupName: \"borderStyle\", type: \"strokeStyle\" };\n default: return { groupName: propName, type: \"dimension\" };\n }\n};\n\n/** Borders geometry: radius/width/offset carry a resolved length unit (§21); `style` is a raw\n * strokeStyle string (no unit → passes through). */\nconst formatBordersValue = (value: Literal, unit?: string): string | number => dimText(value, unit);\n\n/** Layout dimension: spacing/gutters/sizes carry a resolved unit (§21); aspectRatio is unit-less. */\nconst formatDimensionValue = (value: Literal, unit?: string): string | number => dimText(value, unit);\n","/**\n * `emitTheme` — the programmatic build API (Node-only, §7 Step 10b).\n *\n * The build-time delivery method (alongside runtime `createTheme`): build a theme, ask the adapter\n * to `emit()` its self-contained static output, and write it to disk. After this a consuming app\n * imports the emitted files and drops refract at runtime.\n *\n * Adapter-agnostic by construction — it takes the fully-constructed adapter *object* (the config's\n * `import` is the extensibility seam; `emitTheme` imports zero adapters itself). It orchestrates ONLY\n * over the public surface (`createTheme`) + the `emit()` / `VENDOR_HELPERS` seams; no reach-in.\n *\n * Two vendoring lanes (Option A, locked 2026-07-11):\n * - `emit().vendorHelpers` — *theme-specific* live helpers the adapter generates (e.g. the SC media\n * module with baked `@media` strings). Always written when present.\n * - `helpers` opt-in — *shared static* helpers (color-math) materialized here from their single\n * source via `VENDOR_HELPERS`. Explicit opt-in — a target names which it wants; never auto-emitted.\n */\nimport { mkdirSync, writeFileSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport type { ThemeAdapter, Emit } from \"../core/ThemeAdapter\";\nimport type { RawTheme } from \"../core/rawTheme\";\nimport type { MediaConfig } from \"../core/media\";\nimport type { UnitsConfig } from \"../core/units\";\nimport { createTheme } from \"../core/createTheme\";\nimport { buildMediaDescriptor, buildContainerDescriptors, mediaQueryString, resolveMediaConfig } from \"../core/media\";\nimport { VENDOR_HELPERS, findVendorHelper } from \"./vendor\";\nimport { readVendorSource, transpileToEsm } from \"./paths\";\nimport { resolveEmitPlan } from \"./emit\";\nimport { buildGuide } from \"./guide\";\nimport { toDTCG } from \"../dtcg\";\n\n/** Opt-in self-documenting output config (§C). `true` uses defaults; the object tunes names/overlay. */\nexport type GuideConfig = {\n /** Published package specifier — adds a by-specifier import overlay to the guide (else relative-only). */\n readonly packageName?: string;\n /** Narrative guide filename (default `\"llms.txt\"`). */\n readonly llmsFile?: string;\n /** Machine index filename (default `\"manifest.json\"`); `false` suppresses it. */\n readonly manifestFile?: string | false;\n};\n\nexport interface EmitThemeOptions {\n /** The raw theme config (same shape `createTheme` consumes). */\n readonly raw: RawTheme;\n /** The fully-constructed adapter object (`createCssAdapter(...)`, an SC adapter, …). */\n readonly adapter: ThemeAdapter;\n /** Directory to write the emitted files into (created recursively). */\n readonly outDir: string;\n /** Shared vendorable helper ids to materialize from `VENDOR_HELPERS` (e.g. `[\"color-math\"]`). */\n readonly helpers?: readonly string[];\n /** Output-shape directive (§9); normalized to a plan and passed to the adapter's `emit(plan)`. */\n readonly emit?: Emit;\n /** Media unit config (§10.5) — threaded into `createTheme` + the emit rebind so em/rem reaches disk. */\n readonly media?: MediaConfig;\n /** Declaration-value length units (§21) — threaded into `createTheme` so built output honors the role map. */\n readonly units?: UnitsConfig;\n /** Divisor when a deferred length resolves to `rem` (§21). Defaults to 16. */\n readonly baseFontSize?: number;\n /** §C — emit a self-documenting `llms.txt` + `manifest.json` into `outDir`. Off by default. */\n readonly guide?: boolean | GuideConfig;\n}\n\nexport interface EmitThemeResult {\n readonly outDir: string;\n /** Absolute paths of every file written, in write order. */\n readonly files: string[];\n}\n\nexport async function emitTheme(options: EmitThemeOptions): Promise<EmitThemeResult> {\n const { raw, adapter, outDir, helpers = [], emit, media: mediaConfig, units, baseFontSize, guide } = options;\n\n const theme = createTheme(raw, { adapter, media: mediaConfig, units, baseFontSize });\n\n // Re-bind with the PLAIN core media descriptor: `emit()` isn't on the theme surface, and an\n // adapter may decorate `theme.media` (SC → tagged templates), whereas emitted vendored helpers\n // (SC's media.ts) need the plain `@media` query strings. This mirrors the 10a gate.\n const media = buildMediaDescriptor(theme.model.breakpoints, o =>\n mediaQueryString(o, resolveMediaConfig(mediaConfig)),\n );\n const containers = buildContainerDescriptors(theme.model.containers, mediaConfig);\n const bound = adapter.bind(theme.model, { media, containers, resolve: theme.resolveToken });\n\n if (!bound.emit) {\n throw new Error(`Adapter \"${adapter.name}\" does not implement emit(); it cannot build to disk.`);\n }\n const emitted = bound.emit(resolveEmitPlan(emit));\n\n const written: string[] = [];\n mkdirSync(outDir, { recursive: true });\n const write = (name: string, contents: string): void => {\n const dest = join(outDir, name);\n mkdirSync(dirname(dest), { recursive: true });\n writeFileSync(dest, contents, \"utf8\");\n written.push(dest);\n };\n\n // Static consume-as-is artifacts (theme.css, …).\n for (const [name, contents] of Object.entries(emitted.files)) write(name, contents);\n // Theme-specific vendored helpers (SC media.ts) — always ride along with the adapter's output.\n for (const [name, contents] of Object.entries(emitted.vendorHelpers ?? {})) write(name, contents);\n\n // Shared static vendored helpers — materialized from their single source (no adapter re-embed).\n for (const id of helpers) {\n const helper = findVendorHelper(id);\n if (!helper) {\n throw new Error(\n `Unknown vendor helper \"${id}\". Known: ${VENDOR_HELPERS.map(h => h.id).join(\", \")}.`,\n );\n }\n // `transpileToEsm` lazy-loads the optional `typescript` peer (Step 10e) — reached only here, on\n // an explicit `helpers` opt-in, so a helper-free CSS build never needs `typescript` installed.\n write(helper.outfile, await transpileToEsm(readVendorSource(helper.source)));\n }\n\n // §C — self-documenting output: an llms.txt guide + manifest.json describing THIS theme's real\n // names, written beside the artifacts so they travel with any distribution form. Opt-in.\n if (guide) {\n const cfg: GuideConfig = guide === true ? {} : guide;\n const built = buildGuide(bound.describeUsage(), toDTCG(theme), {\n files: Object.keys(emitted.files),\n packageName: cfg.packageName,\n llmsFile: cfg.llmsFile,\n manifestFile: cfg.manifestFile,\n });\n for (const [name, contents] of Object.entries(built.files)) write(name, contents);\n }\n\n return { outDir, files: written };\n}\n","/**\n * `theme.config.(ts|js|mjs)` — the primary build interface + the adapter seam (Node-only, §7 10b).\n *\n * The config is USER CODE in the user's project: it `import`s the adapter from wherever it lives\n * (refract for CSS, an external package for SC/third-party) and hands the CLI a fully-constructed\n * adapter object per target. That `import` IS the extensibility seam — same model as\n * Rollup/Vite/PostCSS/Jest — so adapter *options* (`prefix`/…) are passed at construction in the\n * config, not as CLI flags. Multiple targets let one theme emit CSS + SC at once.\n *\n * Loader (chosen 2026-07-11 — NO new dep): reuse `typescript` (an OPTIONAL peer, lazy-loaded as of\n * Step 10e — only a `.ts` config pays for it). A `.ts` config is compiled via a `ts.createProgram`\n * **graph compile** (§8b): the config **and its local relative `.ts` graph** are type-stripped to\n * adjacent hidden `.mjs` files, so a `.ts` config can `import` a sibling `theme.raw.ts` (the 8a\n * `RawTheme` payoff). Bare specifiers and relative `.mjs`/`.js`/`.json` stay external (resolved at\n * their original adjacent location). `.mjs`/`.js` configs import directly. See {@link compileTsConfigGraph}\n * for the emit-location + specifier-rewrite details. Rejected jiti/esbuild (both absent → a new dep).\n */\nimport { existsSync } from \"node:fs\";\nimport { extname, join, resolve } from \"node:path\";\nimport { pathToFileURL } from \"node:url\";\nimport type { ThemeAdapter, Emit } from \"../core/ThemeAdapter\";\nimport type { RawTheme } from \"../core/rawTheme\";\nimport type { MediaConfig } from \"../core/media\";\nimport type { UnitsConfig } from \"../core/units\";\nimport type { GuideConfig } from \"./emitTheme\";\nimport { compileTsConfigGraph } from \"./paths\";\n\n/** One emit target: an adapter + where to write it, plus which shared vendored helpers it wants. */\nexport interface EmitTarget {\n readonly adapter: ThemeAdapter;\n readonly outDir: string;\n readonly helpers?: readonly string[];\n /** Optional label — lets `refract build --target <name>` select this target (else index/outDir). */\n readonly name?: string;\n /** Optional output-shape directive (§9): single / split / subsystem / components. Default = single. */\n readonly emit?: Emit;\n /**\n * §C — emit a self-documenting `llms.txt` + `manifest.json` into this target's `outDir`, so a\n * published/zipped theme carries its own AI consumption guide (real class names / token paths) for\n * a downstream dev who has neither refract nor its skills. `true` uses defaults; an object tunes the\n * file names or adds a `packageName` for a by-specifier import overlay. Off by default.\n */\n readonly guide?: boolean | GuideConfig;\n}\n\n/** The `theme.config` shape: the raw theme + one or more emit targets. */\nexport interface ThemeConfig {\n readonly raw: RawTheme;\n readonly targets: readonly EmitTarget[];\n /**\n * Media-query output config (§10.5) — `{ unit: \"px\" | \"em\" | \"rem\"; baseFontSize }`. Applies to\n * both the viewport `@media` and container `@container` widths (breakpoints/container thresholds are\n * authored as px numbers; `unit` controls the emitted unit). Defaults to px.\n */\n readonly media?: MediaConfig;\n /**\n * Declaration-value length units (§21) — a token-path role map (`units.default`, `units[\"<subsystem>\"]`,\n * `units[\"<subsystem>.<property>\"]`), most-specific wins over the built-in seed. Resolved once, format-\n * neutrally, so every target emits the same unit. The build-time twin of `createTheme`'s `units` option.\n */\n readonly units?: UnitsConfig;\n /** Divisor when a deferred length resolves to `rem` (§21). Defaults to 16. */\n readonly baseFontSize?: number;\n}\n\n/** Identity fn — types the config authored in `theme.config.(ts|js|mjs)`. */\nexport const defineConfig = (config: ThemeConfig): ThemeConfig => config;\n\nconst CONFIG_BASENAME = \"theme.config\";\nconst EXT_ORDER = [\".ts\", \".mjs\", \".js\"] as const;\n\n/** Find `theme.config.{ts,mjs,js}` in `fromDir`, honoring the ts→mjs→js resolution order. */\nexport const findConfigFile = (fromDir: string = process.cwd()): string | undefined => {\n for (const ext of EXT_ORDER) {\n const candidate = join(fromDir, `${CONFIG_BASENAME}${ext}`);\n if (existsSync(candidate)) return candidate;\n }\n return undefined;\n};\n\n/**\n * Import a config module. A `.ts` file is graph-compiled (config + its relative `.ts` graph → adjacent\n * hidden `.mjs` files; see {@link compileTsConfigGraph}) then the emitted entry is dynamically imported\n * and every temp file removed; `.mjs`/`.js` are imported directly.\n */\nlet importCounter = 0;\nasync function importConfigModule(path: string): Promise<Record<string, unknown>> {\n if (extname(path) !== \".ts\") {\n // Cache-bust the ESM import: Node caches modules by URL, so a repeated `loadConfig` on an *edited*\n // config (e.g. a long-lived MCP server watching `theme.config.mjs`) would otherwise re-get the stale\n // module. A fresh query key forces a re-read. Harmless for one-shot CLI use. (A `.ts` config already\n // re-reads: `compileTsConfigGraph` emits a fresh temp file each call.)\n const url = `${pathToFileURL(path).href}?v=${++importCounter}`;\n return (await import(url)) as Record<string, unknown>;\n }\n const { entry, cleanup } = await compileTsConfigGraph(path);\n try {\n return (await import(pathToFileURL(entry).href)) as Record<string, unknown>;\n } finally {\n cleanup();\n }\n}\n\nexport interface LoadedConfig {\n readonly config: ThemeConfig;\n /** Absolute path the config was loaded from. */\n readonly path: string;\n}\n\n/**\n * Resolve + load a `theme.config`. `configPath` (a CLI `--config` override) wins; otherwise the\n * ts→mjs→js search in `cwd`. Returns the `defineConfig(...)` object (default or named `config` export).\n */\nexport async function loadConfig(\n options: { cwd?: string; configPath?: string } = {},\n): Promise<LoadedConfig> {\n const cwd = options.cwd ?? process.cwd();\n const path = options.configPath ? resolve(cwd, options.configPath) : findConfigFile(cwd);\n if (!path || !existsSync(path)) {\n const where = options.configPath ? `\"${options.configPath}\"` : `${CONFIG_BASENAME}.(ts|mjs|js) in \"${cwd}\"`;\n throw new Error(`No theme config found at ${where}.`);\n }\n\n const mod = await importConfigModule(path);\n const config = (mod.default ?? mod.config ?? mod) as ThemeConfig;\n if (!config || typeof config !== \"object\" || !Array.isArray(config.targets)) {\n throw new Error(`\"${path}\" must export (default) a defineConfig({ raw, targets }) object.`);\n }\n return { config, path };\n}\n","/**\n * `refract init` — scaffold a runnable `theme.config.(ts|js|mjs)` (Node-only, §7 Step 10c).\n *\n * The config is the primary build interface + the adapter seam (10b): it is USER CODE that `import`s\n * the adapter it wants. `init` writes a starter that is runnable out of the box — it uses the CSS\n * adapter package (`@theme-registry/refract-css`) + `defineConfig` (refract's `./build` subpath), a\n * minimal inline `raw`, and one CSS target — plus commented lines showing how to add another adapter\n * target (e.g. an SC package) once installed. Post monorepo split every adapter lives in its own\n * sibling package, so the scaffold imports the CSS adapter from `refract-css`, not from core. Adapter\n * *options* are passed at construction in the config (`createCssAdapter({ … })`), never as CLI flags\n * (a flag can't carry an imported object).\n *\n * Default variant is `.ts`; `--js` / `--mjs` pick the ESM variants. All three share one ESM body\n * (the `.ts` file only differs by extension — it lets the author add types later); the difference is\n * purely Node's module-resolution semantics (`.mjs` is always ESM; `.js` follows the project type).\n * `init` refuses to clobber an existing config unless `--force`.\n */\nimport { existsSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { findPackageRoot } from \"./paths\";\n\nexport type ConfigVariant = \"ts\" | \"js\" | \"mjs\";\n\n/**\n * The sibling package the CSS adapter ships from post monorepo split. `defineConfig`/`RawTheme` still\n * come from core (`${packageName}/build`); only the adapter itself moved to its own package.\n */\nexport const CSS_ADAPTER_PACKAGE = \"@theme-registry/refract-css\";\n\nexport interface InitOptions {\n /** Project dir to scaffold into (default `process.cwd()`). */\n readonly cwd?: string;\n /** Which config flavor to write (default `\"ts\"`). */\n readonly variant?: ConfigVariant;\n /** Overwrite an existing config instead of refusing (default `false`). */\n readonly force?: boolean;\n /** Package name to import from in the scaffold (default: this package's own `name`). */\n readonly packageName?: string;\n /**\n * Override the raw-theme detection: a {@link DetectedRawTheme} to wire up regardless of what's on\n * disk, or `null` to force the self-contained starter config. Omit to detect (the normal path).\n */\n readonly rawTheme?: DetectedRawTheme | null;\n}\n\nexport interface InitResult {\n /** Absolute path of the written config. */\n readonly path: string;\n readonly variant: ConfigVariant;\n /** The package name the scaffold imports from. */\n readonly packageName: string;\n /** The raw theme the config was wired to, or `undefined` when it carries its own starter palette. */\n readonly rawTheme?: DetectedRawTheme;\n}\n\n/** Read this package's own `name` (so the scaffold imports the currently-installed package name). */\nexport function readOwnPackageName(): string {\n const pkgPath = join(findPackageRoot(), \"package.json\");\n const pkg = JSON.parse(readFileSync(pkgPath, \"utf8\")) as { name?: string };\n return pkg.name ?? \"@theme-registry/refract\";\n}\n\n/**\n * Raw-theme filenames `init` will wire up, in resolution order. `.ts` first (the richest), then the\n * plain-ESM flavours, then `.json`. Matches what `refract create` and `refract import` write.\n */\nconst RAW_BASENAME = \"theme.raw\";\nconst RAW_EXT_ORDER = [\".ts\", \".mts\", \".mjs\", \".js\", \".json\"] as const;\n\n/** A raw theme found next to the config, and how a config should reach it. */\nexport interface DetectedRawTheme {\n /** Absolute path of the file found. */\n readonly path: string;\n /** Its basename, e.g. `theme.raw.json`. */\n readonly filename: string;\n /** The extension, including the dot. */\n readonly ext: string;\n}\n\n/**\n * Look for an authored raw theme in `fromDir`.\n *\n * This is the seam between `create` and `init`: `create` designs the theme, `init` wires the build.\n * When a theme is already there, `init` must not invent a second one — a project with two sources of\n * truth for its tokens is worse than a project with none.\n */\nexport const findRawTheme = (fromDir: string = process.cwd()): DetectedRawTheme | undefined => {\n for (const ext of RAW_EXT_ORDER) {\n const candidate = join(fromDir, `${RAW_BASENAME}${ext}`);\n if (existsSync(candidate)) {\n return { path: candidate, filename: `${RAW_BASENAME}${ext}`, ext };\n }\n }\n return undefined;\n};\n\n/**\n * The import line (or lines) a config uses to reach a detected raw theme.\n *\n * `.ts` is graph-compiled alongside the config, so an extensionless specifier resolves and the\n * transformer rewrites it. `.mjs`/`.js` are imported by Node directly, so they keep their extension.\n * `.json` is read rather than imported: an import attribute (`with { type: \"json\" }`) would work on\n * current Node but pins the scaffolded config to a version floor for no benefit, and `readFileSync`\n * behaves identically in every flavour.\n */\nexport function rawThemeImport(detected: DetectedRawTheme): { head: string; expression: string } {\n if (detected.ext === \".json\") {\n return {\n head:\n `import { readFileSync } from \"node:fs\";\\n` +\n `\\n// The theme is JSON, so it's read rather than imported — no module-attribute support needed.\\n` +\n `const raw = JSON.parse(readFileSync(new URL(\"./${detected.filename}\", import.meta.url), \"utf8\"));\\n`,\n expression: \"raw\",\n };\n }\n const specifier =\n detected.ext === \".ts\" || detected.ext === \".mts\"\n ? `./${RAW_BASENAME}`\n : `./${detected.filename}`;\n return { head: `import { raw } from \"${specifier}\";\\n`, expression: \"raw\" };\n}\n\n/**\n * The config body when a raw theme already exists — it imports that theme instead of carrying one.\n * Deliberately short: everything about the design lives in the theme file, and this is only wiring.\n */\nexport function scaffoldConfigForRaw(packageName: string, detected: DetectedRawTheme): string {\n const { head, expression } = rawThemeImport(detected);\n return `import { defineConfig } from \"${packageName}/build\";\nimport { createCssAdapter } from \"${CSS_ADAPTER_PACKAGE}\";\n${head}\n// refract build config. \\`refract build\\` reads this file, builds the theme once, and writes each\n// target's emitted files into that target's \\`outDir\\`. The config is your code: it \\`import\\`s the\n// adapters it wants and passes their options at construction (not via CLI flags).\n//\n// Your tokens live in \\`${detected.filename}\\` — edit them there, not here.\nexport default defineConfig({\n raw: ${expression},\n targets: [\n // The CSS adapter (from @theme-registry/refract-css). Pass its options here, at construction.\n { adapter: createCssAdapter(/* { colors: { prefix: \"app\" } } */), outDir: \"dist/theme\" },\n\n // Add another adapter target once its package is installed, e.g.:\n // import { createStyledComponentsAdapter } from \"@theme-registry/refract-styled-components\";\n // { adapter: createStyledComponentsAdapter(), outDir: \"dist/theme-sc\" },\n ],\n});\n`;\n}\n\n/** The scaffolded config body — one shared ESM template across ts/js/mjs. */\nexport function scaffoldConfig(packageName: string): string {\n return `import { defineConfig } from \"${packageName}/build\";\nimport { createCssAdapter } from \"${CSS_ADAPTER_PACKAGE}\";\n\n// refract build config. \\`refract build\\` reads this file, builds the theme once, and writes\n// each target's emitted files into that target's \\`outDir\\`. The config is your code: it \\`import\\`s\n// the adapters it wants and passes their options at construction (not via CLI flags).\nexport default defineConfig({\n // The raw theme — authored in refract's nested slices. Extend with typography/effects/layout.\n raw: {\n breakpoints: { sm: 576, md: 768, lg: 1024, xl: 1280 },\n colors: {\n // Starter palette passes its own contrast audit (WCAG AA): white text clears 4.5:1 on both\n // bases. Keep that when you retune — the auditor is a shipped feature; the default should model it.\n primary: { base: \"#1864ab\", text: \"#fff\", variants: { dark: \"#0b4a86\", light: \"#a5d8ff\" } },\n neutral: { base: \"#495057\", text: \"#fff\", variants: { light: \"#f1f3f5\", dark: \"#212529\" } },\n recipes: {\n solid: {\n primary: { background: \"primary\", color: \"primary.text\" },\n neutral: { background: \"neutral.light\", color: \"neutral.dark\" },\n },\n },\n },\n },\n targets: [\n // The CSS adapter (from @theme-registry/refract-css). Pass its options here, at construction.\n { adapter: createCssAdapter(/* { colors: { prefix: \"app\" } } */), outDir: \"dist/theme\" },\n\n // Add another adapter target once its package is installed, e.g.:\n // import { createStyledComponentsAdapter } from \"@theme-registry/refract-styled-components\";\n // { adapter: createStyledComponentsAdapter(), outDir: \"dist/theme-sc\" },\n ],\n});\n`;\n}\n\n/**\n * Scaffold `theme.config.<variant>` into `cwd`. Throws if the file exists and `force` is not set\n * (never silently clobbers a user's config).\n */\nexport function runInit(options: InitOptions = {}): InitResult {\n const cwd = options.cwd ?? process.cwd();\n const variant = options.variant ?? \"ts\";\n const packageName = options.packageName ?? readOwnPackageName();\n\n const path = join(cwd, `theme.config.${variant}`);\n if (existsSync(path) && !options.force) {\n throw new Error(\n `theme.config.${variant} already exists at \"${path}\". Pass --force to overwrite it.`,\n );\n }\n\n // If the project already has a theme, wire it up rather than inventing a second one. Only when\n // there's nothing to find does the config carry a starter palette of its own — so `refract init`\n // on its own still produces something runnable, exactly as it always has.\n const detected = options.rawTheme === null ? undefined : options.rawTheme ?? findRawTheme(cwd);\n const body = detected ? scaffoldConfigForRaw(packageName, detected) : scaffoldConfig(packageName);\n\n writeFileSync(path, body, \"utf8\");\n return { path, variant, packageName, rawTheme: detected };\n}\n","/**\n * Guided raw-theme generator (Node-only, pure) — the engine behind `refract create`.\n *\n * Turns a seed colour plus a handful of answers into a complete `RawTheme`. Deliberately split from\n * the prompting (`cli.ts`) and from the file writing (`createCommand.ts`) so the whole generator is\n * testable without a TTY and reusable programmatically.\n *\n * The governing rule for what lands in the output:\n *\n * **Bake a literal** where the value came from an opinion the engine does not hold — the harmony\n * rotation, the contrast nudge, the leading/tracking curves. Those are this module's taste, and a\n * scaffolded theme is a style guide the user then owns, so it must hold still.\n *\n * **Write the declaration** where the engine already synthesizes — `fontSize.ratio`,\n * `layout.spacing.step`. Baking those would throw the intent away: re-tuning a scale should stay a\n * one-word edit, not a regeneration of eight numbers.\n *\n * Nothing here changes the palette model. It calls the colour helpers the package already ships\n * (`rotateHue`/`darken`, and `audit` for the contrast gate) and writes down what they return, once.\n * Callers who want a companion that *re-derives* on `override()` should use `colors.harmony` instead —\n * that is the other tool, for the other job.\n */\n\nimport type { RawTheme } from \"../core\";\nimport { createTheme } from \"../core/createTheme\";\nimport { createNoopAdapter } from \"../core/noopAdapter\";\nimport { audit } from \"../subsystems/colors/audit\";\nimport type { WcagLevel } from \"../subsystems/colors/audit\";\nimport { darken, rotateHue, parseColor, convertRgbToHex, rgbToOklch } from \"../subsystems/colors/utils\";\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Tunable constants — the generator's opinions, deliberately in the open.\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Leading falls as size grows: `LEADING_AT_BASE × (BASE_PX / size) ^ LEADING_EXPONENT`, clamped.\n * Fitted to land on conventional values at 16px (1.50) and to tighten a display line enough that a\n * dramatic ratio doesn't ship a 67px headline set at 1.5. Another designer would pick differently.\n */\nconst LEADING_AT_BASE = 1.5;\nconst LEADING_EXPONENT = 0.22;\nconst LEADING_MIN = 1.1;\nconst LEADING_MAX = 1.7;\n\n/**\n * Tracking crosses from positive (small text wants air) to negative (display text wants tightening):\n * `TRACKING_NUMERATOR / size − TRACKING_OFFSET`, in em. Zero at 16px by construction.\n */\nconst TRACKING_NUMERATOR = 0.36;\nconst TRACKING_OFFSET = 0.0225;\n\n/** The reference size both curves are anchored at. */\nconst CURVE_ANCHOR_PX = 16;\n\n/** The engine's default `fontSize` step names and their exponent off `base`. Mirrors typography. */\nconst TYPE_STEPS: ReadonlyArray<readonly [string, number]> = [\n [\"xs\", -2], [\"sm\", -1], [\"md\", 0], [\"lg\", 1],\n [\"xl\", 2], [\"2xl\", 3], [\"3xl\", 4], [\"4xl\", 5],\n];\n\n/** Numeric value of each named type ratio. Mirrors `TYPOGRAPHY_RATIOS` in the typography subsystem. */\nconst RATIO_VALUES: Readonly<Record<string, number>> = {\n \"minor-second\": 1.067, \"major-second\": 1.125, \"minor-third\": 1.2, \"major-third\": 1.25,\n \"perfect-fourth\": 1.333, \"augmented-fourth\": 1.414, \"perfect-fifth\": 1.5, golden: 1.618,\n};\n\n/**\n * Hue rotations per scheme. Aligned with the colours subsystem's own `HARMONY_SCHEMES` where they\n * overlap, so a scaffolded literal and an authored `harmony:` key agree. `pentadic` is local — the\n * subsystem has no five-way scheme, and the scaffolder needs one to reach five brand colours.\n */\nconst SCHEME_ROTATIONS: Readonly<Record<string, readonly number[]>> = {\n complement: [180],\n analogous: [-30, 30],\n \"split-complement\": [150, 210],\n triadic: [120, 240],\n tetradic: [90, 180, 270],\n pentadic: [72, 144, 216, 288],\n};\n\n/** Ordinal names for the generated brand palettes. Rename freely — it's your file. */\nconst BRAND_NAMES = [\"primary\", \"secondary\", \"tertiary\", \"quaternary\", \"quinary\"] as const;\n\n/**\n * Semantic colours start from fixed hue anchors, NOT from a rotation off the seed. Rotating would\n * make \"danger\" whatever hue lands at +150° — from a red seed you'd get a green danger, which is\n * worse than useless. These are conventional anchors; the contrast pass then adapts their lightness.\n */\nconst SEMANTIC_ANCHORS: ReadonlyArray<readonly [string, string, string]> = [\n [\"success\", \"#2f9e44\", \"#ffffff\"],\n [\"info\", \"#1c7ed6\", \"#ffffff\"],\n [\"warning\", \"#e89012\", \"#1f2733\"],\n [\"danger\", \"#e03131\", \"#ffffff\"],\n];\n\n/** The neutral seed and the shadow ink. Both are deliberately cool — they sit under everything. */\nconst NEUTRAL_SEED = \"#6b7280\";\nconst SHADOW_INK = \"#18274b\";\n\n/** The absolute lightness ladder every palette carries. `L = (1000 − label) / 10`. */\nconst LADDER: readonly number[] = [50, 100, 200, 300, 400, 500, 600, 700, 800, 900];\n\n/** Alpha levels for the shadow tints, matched to the three elevation levels. */\nconst SHADOW_ALPHAS: readonly number[] = [8, 14, 22];\n\n/** How many times the contrast pass may darken a failing palette before giving up. */\nconst MAX_CONTRAST_ITERATIONS = 40;\n\n// ─────────────────────────────────────────────────────────────────────────────\n// \"Overall feel\" presets — type family, density and corners move together.\n// Choosing them separately is how you end up with an incoherent system.\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport type Feel = \"neutral\" | \"compact\" | \"editorial\" | \"technical\";\n\ninterface FeelPreset {\n readonly label: string;\n readonly blurb: string;\n /** `fontFamily` base + the `mono` variant (system stacks only — a CLI can't install fonts). */\n readonly fontFamily: { readonly base: string; readonly mono: string };\n /** Multiplier map for the linear spacing curve (`step: 4`). */\n readonly spacing: Readonly<Record<string, number>>;\n /** Radius base + variants. */\n readonly radius: { readonly base: number; readonly variants: Readonly<Record<string, number | string>> };\n /** Suggested type ratio when the user takes the default. */\n readonly ratio: string;\n}\n\nconst SYSTEM_SANS = \"system-ui, -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif\";\nconst SYSTEM_MONO = \"ui-monospace, 'SF Mono', Menlo, Consolas, monospace\";\nconst SYSTEM_SERIF = \"'Iowan Old Style', 'Palatino Linotype', Palatino, Georgia, serif\";\n\nexport const FEEL_PRESETS: Readonly<Record<Feel, FeelPreset>> = {\n neutral: {\n label: \"Neutral\",\n blurb: \"system type, comfortable spacing, soft corners\",\n fontFamily: { base: SYSTEM_SANS, mono: SYSTEM_MONO },\n spacing: { xs: 1, sm: 2, md: 4, lg: 6, xl: 8, \"2xl\": 12 },\n radius: { base: 8, variants: { none: 0, sm: 4, lg: 14, pill: \"9999px\" } },\n ratio: \"major-third\",\n },\n compact: {\n label: \"Compact\",\n blurb: \"dense UI, tight scale, small radius\",\n fontFamily: { base: SYSTEM_SANS, mono: SYSTEM_MONO },\n spacing: { xs: 1, sm: 2, md: 3, lg: 4, xl: 6, \"2xl\": 8 },\n radius: { base: 4, variants: { none: 0, sm: 2, lg: 8, pill: \"9999px\" } },\n ratio: \"major-second\",\n },\n editorial: {\n label: \"Editorial\",\n blurb: \"serif display, spacious, generous leading\",\n fontFamily: { base: SYSTEM_SERIF, mono: SYSTEM_MONO },\n spacing: { xs: 2, sm: 4, md: 6, lg: 8, xl: 12, \"2xl\": 16 },\n radius: { base: 2, variants: { none: 0, sm: 1, lg: 4, pill: \"9999px\" } },\n ratio: \"perfect-fourth\",\n },\n technical: {\n label: \"Technical\",\n blurb: \"mono accents, compact, sharp corners\",\n fontFamily: { base: SYSTEM_MONO, mono: SYSTEM_MONO },\n spacing: { xs: 1, sm: 2, md: 3, lg: 4, xl: 6, \"2xl\": 8 },\n radius: { base: 0, variants: { none: 0, sm: 0, lg: 2, pill: \"9999px\" } },\n ratio: \"minor-third\",\n },\n};\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Answers\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport type BrandScheme = keyof typeof SCHEME_ROTATIONS;\nexport type ResetPreset = \"preflight\" | \"normalize\" | \"none\";\nexport type ContrastTarget = \"AA\" | \"AAA\" | \"none\";\n\nexport interface ScaffoldAnswers {\n /** The seed colour — any form `parseColor` accepts (hex, `rgb()`, `oklch()`). */\n readonly seed: string;\n /** `auto` derives colours 2…N by hue rotation; `manual` takes them verbatim from `extraColors`. */\n readonly mode?: \"auto\" | \"manual\";\n /** Total brand colours including the primary, 1–5. Default 2. */\n readonly brandCount?: number;\n /** Which rotation set to use. Ignored unless `mode: \"auto\"`; defaulted from `brandCount`. */\n readonly scheme?: BrandScheme;\n /** `mode: \"manual\"` — the colours after the primary, in order. */\n readonly extraColors?: readonly string[];\n /** Add success / info / warning / danger. Default true. */\n readonly semantics?: boolean;\n /** Add the neutral ramp. Default true. */\n readonly neutral?: boolean;\n /** Add shadow ink + alpha tints, and the effects ramp that references them. Default true. */\n readonly shadows?: boolean;\n /** Contrast bar for the text-on-base pass. Default `\"AA\"`; `\"none\"` skips the pass entirely. */\n readonly contrast?: ContrastTarget;\n /** Base font size in px. Default 16. */\n readonly baseFontSize?: number;\n /** Named type ratio. Defaults to the feel preset's suggestion. */\n readonly ratio?: string;\n /** Type family + density + corners, moved together. Default `\"neutral\"`. */\n readonly feel?: Feel;\n /** Which normalization layer `globals.preset` gets. Default `\"preflight\"`. */\n readonly reset?: ResetPreset;\n}\n\n/** What the contrast pass did to one palette — surfaced so the CLI can report it honestly. */\nexport interface ContrastAdjustment {\n readonly name: string;\n /** The colour before the pass. */\n readonly seed: string;\n /** The colour written to the file. */\n readonly final: string;\n /** OKLCH lightness points removed (0 when untouched). */\n readonly nudge: number;\n /** Ratio before, and after. */\n readonly ratioBefore: number;\n readonly ratioAfter: number;\n readonly levelAfter: WcagLevel;\n /** True when the pass ran out of room without reaching the bar. */\n readonly unresolved: boolean;\n}\n\nexport interface ScaffoldReport {\n /** The seed's OKLCH lightness, 0–100. */\n readonly seedLightness: number;\n /** The ladder label the seed sits nearest — `base` stays canonical, this is orientation only. */\n readonly nearestStep: number;\n /** Brand palettes in order, with the hue rotation that produced each (0 for the primary/manual). */\n readonly brand: ReadonlyArray<{ readonly name: string; readonly hex: string; readonly rotation: number }>;\n /** Every palette the contrast pass looked at. Empty when `contrast: \"none\"`. */\n readonly contrast: readonly ContrastAdjustment[];\n /** Derived per-step leading and tracking, for the CLI's summary line. */\n readonly type: ReadonlyArray<{ readonly step: string; readonly px: number; readonly leading: number; readonly tracking: string }>;\n /** The resolved spacing ramp in px, for the CLI's summary line. */\n readonly spacing: ReadonlyArray<{ readonly step: string; readonly px: number }>;\n}\n\nexport interface ScaffoldResult {\n readonly raw: RawTheme;\n readonly report: ScaffoldReport;\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Helpers\n// ─────────────────────────────────────────────────────────────────────────────\n\nconst round = (n: number, places: number): number => Number(n.toFixed(places));\n\n/** Normalize any accepted colour input to a `#rrggbb` literal, so the written file is uniform. */\nconst toHex = (value: string): string => convertRgbToHex(parseColor(value).rgb);\n\n/** Leading for a size, from the curve above. */\nexport const deriveLeading = (sizePx: number): number =>\n round(\n Math.min(LEADING_MAX, Math.max(LEADING_MIN, LEADING_AT_BASE * Math.pow(CURVE_ANCHOR_PX / sizePx, LEADING_EXPONENT))),\n 2,\n );\n\n/** Tracking (em) for a size, from the curve above. */\nexport const deriveTracking = (sizePx: number): string =>\n `${round(TRACKING_NUMERATOR / sizePx - TRACKING_OFFSET, 3)}em`;\n\n/**\n * The ladder label a colour's lightness sits nearest. `base` stays the brand colour — this exists so\n * the CLI can tell you which stops are your hover and active shades without moving the hex you typed.\n */\nexport const nearestLadderStep = (lightness: number): number => {\n const label = 1000 - lightness * 10;\n let best = LADDER[0];\n for (const stop of LADDER) if (Math.abs(stop - label) < Math.abs(best - label)) best = stop;\n return best;\n};\n\n/** Which scheme a brand count implies when the caller doesn't name one. */\nexport const defaultSchemeFor = (brandCount: number): BrandScheme | undefined => {\n if (brandCount <= 1) return undefined;\n if (brandCount === 2) return \"complement\";\n if (brandCount === 3) return \"triadic\";\n if (brandCount === 4) return \"tetradic\";\n return \"pentadic\";\n};\n\n/** Schemes that produce exactly `brandCount − 1` members — the valid choices at that count. */\nexport const schemesFor = (brandCount: number): readonly BrandScheme[] =>\n (Object.keys(SCHEME_ROTATIONS) as BrandScheme[]).filter(\n (s) => SCHEME_ROTATIONS[s].length === brandCount - 1,\n );\n\n/**\n * The contrast gate. Builds the palette set, audits every text-on-base pairing, and walks the\n * lightness of each failing colour down one OKLCH point at a time until it clears the bar.\n *\n * Iterative rather than closed-form because the ratio is not monotonic in a way worth inverting, and\n * because `audit` owns the thresholds — re-running it is how the generator stays honest about what\n * the library considers a pass.\n */\nfunction applyContrastPass(\n palettes: ReadonlyArray<{ name: string; base: string; text: string }>,\n bar: Exclude<ContrastTarget, \"none\">,\n): { palettes: Array<{ name: string; base: string; text: string }>; adjustments: ContrastAdjustment[] } {\n const current = palettes.map((p) => ({ ...p }));\n const nudges = new Map<string, number>(current.map((p) => [p.name, 0]));\n const firstRatio = new Map<string, number>();\n\n const scoreAll = (): Map<string, { ratio: number; level: WcagLevel; pass: boolean }> => {\n const colors: Record<string, unknown> = {};\n for (const p of current) colors[p.name] = { base: p.base, text: p.text };\n const theme = createTheme({ colors } as RawTheme, { adapter: createNoopAdapter() });\n const result = audit(theme, { minWcag: bar, includeRecipes: false });\n const out = new Map<string, { ratio: number; level: WcagLevel; pass: boolean }>();\n for (const pairing of result.pairings) {\n // A pairing whose fg/bg isn't a derivable colour is reported as `skipped` with no score. It\n // can't be nudged toward a bar it was never measured against, so leave it out entirely.\n if (pairing.skipped || pairing.wcagRatio === undefined) continue;\n const name = pairing.label.replace(/^colors\\./, \"\");\n out.set(name, {\n ratio: pairing.wcagRatio,\n level: pairing.wcagLevel ?? \"fail\",\n pass: pairing.pass ?? false,\n });\n }\n return out;\n };\n\n let scores = scoreAll();\n for (const [name, s] of scores) if (!firstRatio.has(name)) firstRatio.set(name, s.ratio);\n\n for (let i = 0; i < MAX_CONTRAST_ITERATIONS; i++) {\n const failing = current.filter((p) => scores.get(p.name) && !scores.get(p.name)!.pass);\n if (!failing.length) break;\n for (const p of failing) {\n p.base = toHex(darken(p.base, 1));\n nudges.set(p.name, (nudges.get(p.name) ?? 0) + 1);\n }\n scores = scoreAll();\n }\n\n const adjustments: ContrastAdjustment[] = current.map((p, idx) => {\n const s = scores.get(p.name);\n return {\n name: p.name,\n seed: palettes[idx].base,\n final: p.base,\n nudge: nudges.get(p.name) ?? 0,\n ratioBefore: round(firstRatio.get(p.name) ?? 0, 2),\n ratioAfter: round(s?.ratio ?? 0, 2),\n levelAfter: s?.level ?? \"fail\",\n unresolved: !!s && !s.pass,\n };\n });\n\n return { palettes: current, adjustments };\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// The generator\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Build a complete `RawTheme` from the interview answers. Pure — no filesystem, no prompting, no\n * randomness — so the same answers always produce the same theme.\n */\nexport function scaffoldTheme(answers: ScaffoldAnswers): ScaffoldResult {\n const mode = answers.mode ?? \"auto\";\n const feel = FEEL_PRESETS[answers.feel ?? \"neutral\"];\n const brandCount = Math.min(5, Math.max(1, answers.brandCount ?? 2));\n const baseFontSize = answers.baseFontSize ?? CURVE_ANCHOR_PX;\n const ratioName = answers.ratio ?? feel.ratio;\n const ratioValue = RATIO_VALUES[ratioName];\n if (!ratioValue) {\n throw new Error(`Unknown type ratio \"${ratioName}\". Use one of: ${Object.keys(RATIO_VALUES).join(\", \")}.`);\n }\n\n // ── brand colours ──────────────────────────────────────────────────────────\n const seedHex = toHex(answers.seed);\n const brand: Array<{ name: string; hex: string; rotation: number }> = [\n { name: BRAND_NAMES[0], hex: seedHex, rotation: 0 },\n ];\n\n if (mode === \"manual\") {\n (answers.extraColors ?? []).slice(0, BRAND_NAMES.length - 1).forEach((c, i) => {\n brand.push({ name: BRAND_NAMES[i + 1], hex: toHex(c), rotation: 0 });\n });\n } else if (brandCount > 1) {\n const scheme = answers.scheme ?? defaultSchemeFor(brandCount)!;\n const rotations = SCHEME_ROTATIONS[scheme];\n if (!rotations) throw new Error(`Unknown harmony scheme \"${scheme}\".`);\n rotations.slice(0, brandCount - 1).forEach((deg, i) => {\n brand.push({ name: BRAND_NAMES[i + 1], hex: toHex(rotateHue(seedHex, deg)), rotation: deg });\n });\n }\n\n // ── the contrast gate ──────────────────────────────────────────────────────\n const contrastTarget = answers.contrast ?? \"AA\";\n const candidates: Array<{ name: string; base: string; text: string }> = [\n ...brand.map((b) => ({ name: b.name, base: b.hex, text: \"#ffffff\" })),\n ...(answers.semantics === false ? [] : SEMANTIC_ANCHORS.map(([n, base, text]) => ({ name: n, base, text }))),\n ...(answers.neutral === false ? [] : [{ name: \"neutral\", base: NEUTRAL_SEED, text: \"#ffffff\" }]),\n ];\n\n const { palettes, adjustments } =\n contrastTarget === \"none\"\n ? { palettes: candidates, adjustments: [] as ContrastAdjustment[] }\n : applyContrastPass(candidates, contrastTarget);\n\n // ── colors ─────────────────────────────────────────────────────────────────\n const colors: Record<string, unknown> = {};\n for (const p of palettes) colors[p.name] = { base: p.base, text: p.text, steps: [...LADDER] };\n if (answers.shadows !== false) {\n const variants: Record<string, unknown> = {};\n for (const a of SHADOW_ALPHAS) variants[`a${String(a).padStart(2, \"0\")}`] = { modifiers: [{ alpha: a }] };\n colors.shadow = { base: SHADOW_INK, variants };\n }\n\n // ── typography ─────────────────────────────────────────────────────────────\n // `fontSize` is a DECLARATION — the engine synthesizes xs…4xl from base + ratio. Leading and\n // tracking are baked, because the curves are this module's opinion, and they're named after the\n // size step they were tuned for so the pairing documents itself without a recipe.\n const sizes = TYPE_STEPS.map(([step, exp]) => ({ step, px: round(baseFontSize * Math.pow(ratioValue, exp), 2) }));\n const leading: Record<string, number> = {};\n const tracking: Record<string, string> = {};\n for (const { step, px } of sizes) {\n if (step === \"md\") continue; // md === base; the base value covers it\n leading[step] = deriveLeading(px);\n tracking[step] = deriveTracking(px);\n }\n tracking.caps = \"0.06em\"; // caps always want more air than the curve gives\n\n const typography = {\n fontFamily: { base: feel.fontFamily.base, variants: { mono: feel.fontFamily.mono } },\n fontWeight: { base: 400, variants: { medium: 500, semibold: 600, bold: 700 } },\n fontSize: { base: baseFontSize, ratio: ratioName },\n lineHeight: { base: deriveLeading(baseFontSize), variants: leading },\n letterSpacing: { base: \"0em\", variants: tracking },\n };\n\n // ── layout ─────────────────────────────────────────────────────────────────\n // The LINEAR curve, not the geometric one: `step: 4` keeps every stop on a 4px grid, where\n // `ratio: 1.5` would give 8·12·18·27·40.5·60.75. Geometric is right for type and wrong for space.\n const layout = { spacing: { base: 4, step: 4, steps: { ...feel.spacing } } };\n\n // ── borders · effects · animation · globals ────────────────────────────────\n const borders = {\n width: { base: 1, variants: { thick: 2 } },\n style: { base: \"solid\" },\n radius: { base: feel.radius.base, variants: { ...feel.radius.variants } },\n };\n\n const effects = answers.shadows === false\n ? undefined\n : {\n shadow: {\n offsetY: 1, blur: 3, color: \"colors.shadow.a08\",\n variants: {\n md: { offsetY: 6, blur: 16, color: \"colors.shadow.a14\" },\n lg: { offsetY: 14, blur: 34, color: \"colors.shadow.a22\" },\n none: \"none\",\n },\n },\n };\n\n // No `keyframes`: one would only pay off with a recipe to reference it, and the scaffold writes\n // no recipes — so generating one would ship dead CSS.\n const animation = {\n duration: { base: 200, variants: { fast: 120, slow: 400 } },\n easing: { base: \"cubic-bezier(.2,.7,.3,1)\", variants: { out: \"cubic-bezier(.16,.84,.44,1)\" } },\n };\n\n const raw = {\n colors,\n typography,\n layout,\n borders,\n ...(effects ? { effects } : {}),\n animation,\n ...(answers.reset === \"none\" ? {} : { globals: { preset: answers.reset ?? \"preflight\" } }),\n } as RawTheme;\n\n const seedLightness = round(rgbToOklch(parseColor(seedHex).rgb).L, 1);\n\n return {\n raw,\n report: {\n seedLightness,\n nearestStep: nearestLadderStep(seedLightness),\n brand: brand.map((b) => {\n const adjusted = adjustments.find((a) => a.name === b.name);\n return { name: b.name, hex: adjusted?.final ?? b.hex, rotation: b.rotation };\n }),\n contrast: adjustments,\n type: sizes.map(({ step, px }) => ({\n step, px, leading: deriveLeading(px), tracking: deriveTracking(px),\n })),\n spacing: Object.entries(feel.spacing).map(([step, mult]) => ({ step, px: mult * 4 })),\n },\n };\n}\n","/**\n * `refract create` — write a scaffolded `theme.raw.(ts|js|json)` (Node-only).\n *\n * The interview lives in `cli.ts`; the generator lives in `scaffold.ts`. This module is only the\n * seam between them: resolve answers → generate → serialize → write, refusing to clobber.\n *\n * One artefact per command. `create` writes the raw theme and nothing else — no build config (that's\n * `init`, which detects this file), and no rendered specimen (that's a build-time concern, since a\n * `RawTheme` has no rendered form and this command has no idea which adapter you'll build with).\n *\n * Mirrors `import`'s conventions on purpose — same default filename, same refuse-to-clobber, same\n * \"a theme you then own and edit\" framing — because they're the same job from a different input.\n */\nimport { existsSync, writeFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { readOwnPackageName } from \"./init\";\nimport { scaffoldTheme, type ScaffoldAnswers, type ScaffoldReport } from \"./scaffold\";\nimport type { RawTheme } from \"../core\";\n\n/** The file flavours `create` can emit. */\nexport type RawFormat = \"ts\" | \"js\" | \"json\";\n\nexport const DEFAULT_RAW_BASENAME = \"theme.raw\";\n\nexport interface CreateOptions extends ScaffoldAnswers {\n /** Project dir to write into (default `process.cwd()`). */\n readonly cwd?: string;\n /** Which flavour to write (default `\"ts\"`). */\n readonly format?: RawFormat;\n /** Output filename, relative to `cwd` (default `theme.raw.<format>`). */\n readonly out?: string;\n /** Overwrite an existing file instead of refusing (default `false`). */\n readonly force?: boolean;\n /** Package name the `.ts`/`.js` type import points at (default: this package's own `name`). */\n readonly packageName?: string;\n}\n\nexport interface CreateResult {\n /** Absolute path of the written file. */\n readonly path: string;\n readonly format: RawFormat;\n /** The generated theme, so callers can compile it without re-reading the file. */\n readonly raw: RawTheme;\n /** What the generator derived — the CLI prints this as its summary. */\n readonly report: ScaffoldReport;\n /** Count of emitted top-level subsystem slices. */\n readonly sections: readonly string[];\n}\n\n/** A key that can be written bare in JS/TS source rather than quoted. */\nconst BARE_KEY = /^[A-Za-z_$][A-Za-z0-9_$]*$/;\n\n/** Characters that must be escaped inside a double-quoted source string. */\nconst escapeString = (s: string): string => JSON.stringify(s);\n\n/** Width at which a primitive-only array stops being inlined and goes one-per-line. */\nconst INLINE_ARRAY_WIDTH = 76;\n\n/**\n * Pretty-print a value as JS/TS source.\n *\n * `JSON.stringify` would be shorter, but it quotes every key and explodes a ten-number ladder over\n * ten lines — and this file's entire premise is that you open it and edit it. So: bare keys where\n * they're legal, and primitive arrays kept on one line while they fit.\n */\nfunction formatLiteral(value: unknown, indent = 0): string {\n const pad = \" \".repeat(indent);\n const padInner = \" \".repeat(indent + 1);\n\n if (value === null) return \"null\";\n if (typeof value === \"string\") return escapeString(value);\n if (typeof value === \"number\" || typeof value === \"boolean\") return String(value);\n\n if (Array.isArray(value)) {\n if (!value.length) return \"[]\";\n const primitives = value.every(v => v === null || typeof v !== \"object\");\n if (primitives) {\n const inline = `[${value.map(v => formatLiteral(v)).join(\", \")}]`;\n if (pad.length + inline.length <= INLINE_ARRAY_WIDTH) return inline;\n }\n const items = value.map(v => `${padInner}${formatLiteral(v, indent + 1)}`);\n return `[\\n${items.join(\",\\n\")}\\n${pad}]`;\n }\n\n const entries = Object.entries(value as Record<string, unknown>);\n if (!entries.length) return \"{}\";\n const lines = entries.map(([key, v]) => {\n const name = BARE_KEY.test(key) ? key : escapeString(key);\n return `${padInner}${name}: ${formatLiteral(v, indent + 1)}`;\n });\n return `{\\n${lines.join(\",\\n\")}\\n${pad}}`;\n}\n\n/** Shared preamble for the code flavours. Kept short — the file is the user's from here on. */\nconst banner = (seed: string, detail: string): string =>\n `// Generated by \\`refract create\\` — seed ${seed} · ${detail}.\\n` +\n `// This is YOUR theme now: every value is a literal you can read, edit and delete. The generator\\n` +\n `// does not run again. Tonal ladders, the type scale and the spacing ramp are synthesized by the\\n` +\n `// engine from the declarations below — re-tune a scale by editing one word, not eight numbers.\\n`;\n\n/**\n * Serialize a generated theme to source text.\n *\n * `ts` and `js` share one body and differ only in how the type is attached (a real `satisfies` vs a\n * JSDoc cast), so a JS user gets the same editor completion without adding a compile step. `json`\n * carries no types and no shared `ladder` const — it is the portable flavour, and for a scaffolded\n * theme it is exactly as faithful, because nothing here is a function or a recipe.\n */\nexport function renderRawTheme(\n raw: RawTheme,\n options: { format: RawFormat; packageName: string; seed: string; detail: string },\n): string {\n // JSON stays strict JSON — quoted keys, no trailing anything — so it parses anywhere.\n if (options.format === \"json\") return `${JSON.stringify(raw, null, 2)}\\n`;\n\n const body = formatLiteral(raw);\n\n if (options.format === \"js\") {\n return (\n `${banner(options.seed, options.detail)}\\n` +\n `/** @type {import(\"${options.packageName}/build\").RawTheme} */\\n` +\n `export const raw = ${body};\\n`\n );\n }\n\n return (\n `${banner(options.seed, options.detail)}` +\n `import type { RawTheme } from \"${options.packageName}/build\";\\n\\n` +\n `export const raw = ${body} satisfies RawTheme;\\n`\n );\n}\n\n/** A one-line description of the choices that produced a theme, for the file banner. */\nfunction describeChoices(options: CreateOptions): string {\n const parts: string[] = [];\n const count = options.mode === \"manual\" ? (options.extraColors?.length ?? 0) + 1 : options.brandCount ?? 2;\n parts.push(`${count} brand colour${count === 1 ? \"\" : \"s\"}`);\n if (options.mode !== \"manual\" && count > 1) parts.push(options.scheme ?? \"auto\");\n parts.push(options.feel ?? \"neutral\");\n if (options.contrast !== \"none\") parts.push(`WCAG ${options.contrast ?? \"AA\"}`);\n return parts.join(\" · \");\n}\n\n/**\n * Generate and write the raw theme. Throws when the target exists and `force` is not set — the same\n * guard `init` and `import` use, so no command in this CLI can silently destroy authored work.\n */\nexport function runCreate(options: CreateOptions): CreateResult {\n const cwd = options.cwd ?? process.cwd();\n const format: RawFormat = options.format ?? \"ts\";\n const filename = options.out ?? `${DEFAULT_RAW_BASENAME}.${format}`;\n const path = join(cwd, filename);\n\n if (existsSync(path) && !options.force) {\n throw new Error(`\"${filename}\" already exists. Re-run with --force to overwrite it.`);\n }\n\n const { raw, report } = scaffoldTheme(options);\n const packageName = options.packageName ?? readOwnPackageName();\n const source = renderRawTheme(raw, {\n format,\n packageName,\n seed: options.seed,\n detail: describeChoices(options),\n });\n\n writeFileSync(path, source, \"utf8\");\n\n return { path, format, raw, report, sections: Object.keys(raw as Record<string, unknown>) };\n}\n","/**\n * Interactive prompts over `node:readline` and raw stdin (Node-only).\n *\n * The package ships zero runtime dependencies and this is the build layer, so rather than pull in a\n * prompt library these are the shapes the CLIs actually need, implemented directly.\n *\n * Three tiers, chosen per call:\n *\n * 1. **Raw mode** (a TTY that grants `setRawMode`) — arrow keys move, space toggles, Enter confirms.\n * What people expect from `npm create`.\n * 2. **Line mode** (a TTY that refuses raw mode — some CI shells, some remote terminals) — the same\n * questions answered by typing a number. Plainer, but never wedged.\n * 3. **Non-interactive** (no TTY at all: a pipe, CI, `--yes`) — every prompt takes its default\n * without blocking, so a scripted run can't deadlock on stdin that will never arrive.\n *\n * Key handling is a **pure reducer** (`applyKey`), so navigation is unit-testable without a terminal;\n * the raw loop is only plumbing around it.\n */\nimport { createInterface, type Interface } from \"node:readline\";\n\n/** ANSI helpers — no-ops when the stream isn't a TTY, so piped output stays clean. */\nconst useColor = (): boolean => Boolean(process.stdout.isTTY) && !process.env.NO_COLOR;\nconst paint = (code: string, s: string): string => (useColor() ? `\\u001b[${code}m${s}\\u001b[0m` : s);\nexport const bold = (s: string): string => paint(\"1\", s);\nexport const dim = (s: string): string => paint(\"2\", s);\nexport const cyan = (s: string): string => paint(\"36\", s);\nexport const green = (s: string): string => paint(\"32\", s);\nexport const yellow = (s: string): string => paint(\"33\", s);\n\n/** Terminal control, named so the rendering below reads as intent rather than escape soup. */\nconst cursorUp = (n: number): string => (n > 0 ? `\\u001b[${n}A` : \"\");\nconst CLEAR_DOWN = \"\\u001b[0J\";\nconst HIDE_CURSOR = \"\\u001b[?25l\";\nconst SHOW_CURSOR = \"\\u001b[?25h\";\n\n/** One choice in a `select` / `multiselect`. */\nexport interface Choice<T> {\n readonly value: T;\n readonly label: string;\n /** Trailing grey note — what this option means. */\n readonly hint?: string;\n}\n\n/** The keys a list prompt understands, after decoding an stdin chunk. */\nexport type ListKey = \"up\" | \"down\" | \"space\" | \"submit\" | \"all\" | \"cancel\" | \"none\";\n\n/** Decode a raw stdin chunk into a {@link ListKey}. Arrows arrive as escape sequences; j/k mirror vim. */\nexport function decodeKey(chunk: string): ListKey {\n switch (chunk) {\n case \"\\u001b[A\":\n case \"k\":\n return \"up\";\n case \"\\u001b[B\":\n case \"j\":\n return \"down\";\n case \" \":\n return \"space\";\n case \"\\r\":\n case \"\\n\":\n return \"submit\";\n case \"a\":\n return \"all\";\n case \"\\u0003\": // Ctrl-C\n case \"\\u001b\": // bare Escape\n return \"cancel\";\n default:\n return \"none\";\n }\n}\n\n/**\n * Split one stdin chunk into the keys it contains.\n *\n * A held-down arrow key, or fast typing, delivers several sequences in a single `data` event — so\n * decoding the chunk as one key would swallow all but the first and make the list feel like it drops\n * input. Escape sequences (`ESC [ <letter>`) are taken as a unit; everything else is one key each.\n */\nexport function decodeKeys(chunk: string): ListKey[] {\n const keys: ListKey[] = [];\n for (let i = 0; i < chunk.length; ) {\n if (chunk[i] === \"\\u001b\" && chunk[i + 1] === \"[\" && i + 2 < chunk.length) {\n keys.push(decodeKey(chunk.slice(i, i + 3)));\n i += 3;\n } else {\n keys.push(decodeKey(chunk[i]));\n i += 1;\n }\n }\n return keys;\n}\n\n/** Where a list prompt currently stands. */\nexport interface ListState {\n readonly cursor: number;\n readonly selected: ReadonlySet<number>;\n readonly done: boolean;\n readonly cancelled: boolean;\n}\n\n/**\n * Advance a list prompt by one key. Pure — no I/O — so navigation is testable without a terminal.\n *\n * The cursor **wraps** at both ends: with six options, up from the first should land on the last\n * rather than stick. `space` and `a` toggle only in multi mode; in single mode Enter is the commit,\n * so space would be ambiguous.\n */\nexport function applyKey(state: ListState, key: ListKey, count: number, multi: boolean): ListState {\n if (state.done || state.cancelled || count === 0) return state;\n switch (key) {\n case \"up\":\n return { ...state, cursor: (state.cursor - 1 + count) % count };\n case \"down\":\n return { ...state, cursor: (state.cursor + 1) % count };\n case \"space\": {\n if (!multi) return state;\n const next = new Set(state.selected);\n if (next.has(state.cursor)) next.delete(state.cursor);\n else next.add(state.cursor);\n return { ...state, selected: next };\n }\n case \"all\": {\n if (!multi) return state;\n const everything = state.selected.size === count;\n return {\n ...state,\n selected: everything ? new Set() : new Set(Array.from({ length: count }, (_, i) => i)),\n };\n }\n case \"submit\":\n return { ...state, done: true };\n case \"cancel\":\n return { ...state, cancelled: true };\n default:\n return state;\n }\n}\n\n/** Can we drive the terminal directly? Some TTYs (and most CI) don't grant raw mode. */\nconst rawCapable = (): boolean =>\n Boolean(process.stdin.isTTY) && typeof process.stdin.setRawMode === \"function\";\n\n/**\n * A prompt session. Holds at most one readline interface, so stdin is opened and closed once;\n * `interactive` is false when there's no TTY, and every ask short-circuits to its default.\n */\nexport class Prompter {\n private rl: Interface | undefined;\n readonly interactive: boolean;\n\n constructor(interactive = Boolean(process.stdin.isTTY) && Boolean(process.stdout.isTTY)) {\n this.interactive = interactive;\n }\n\n private get io(): Interface {\n if (!this.rl) this.rl = createInterface({ input: process.stdin, output: process.stdout });\n return this.rl;\n }\n\n close(): void {\n this.rl?.close();\n this.rl = undefined;\n }\n\n private question(text: string): Promise<string> {\n return new Promise(resolve => this.io.question(text, answer => resolve(answer)));\n }\n\n /** Raw write, no newline — for cursor control during a live render. */\n private out(s: string): void {\n process.stdout.write(s);\n }\n\n /** Print a line. Kept on the prompter so command code never touches `process.stdout`. */\n write(line = \"\"): void {\n process.stdout.write(`${line}\\n`);\n }\n\n /** Free-text, with a default shown in the prompt. Blank input takes the default. */\n async text(label: string, fallback: string, validate?: (v: string) => string | undefined): Promise<string> {\n if (!this.interactive) return fallback;\n for (;;) {\n const answer = (await this.question(`${cyan(\"?\")} ${bold(label)} ${dim(`(${fallback})`)} `)).trim();\n const value = answer || fallback;\n const error = validate?.(value);\n if (!error) return value;\n this.write(` ${yellow(\"!\")} ${error}`);\n }\n }\n\n /** A number, validated as finite. */\n async number(label: string, fallback: number, validate?: (v: number) => string | undefined): Promise<number> {\n const answer = await this.text(label, String(fallback), v => {\n const n = Number(v);\n if (!Number.isFinite(n)) return `\"${v}\" is not a number.`;\n return validate?.(n);\n });\n return Number(answer);\n }\n\n /** Pick one — arrows to move, Enter to choose. */\n async select<T>(label: string, choices: readonly Choice<T>[], defaultIndex = 0): Promise<T> {\n if (!this.interactive || choices.length === 1) return choices[defaultIndex]?.value ?? choices[0].value;\n if (rawCapable()) {\n const picked = await this.runList(label, choices, {\n multi: false,\n cursor: defaultIndex,\n selected: new Set<number>(),\n });\n return choices[picked[0] ?? defaultIndex].value;\n }\n return this.selectByNumber(label, choices, defaultIndex);\n }\n\n /** Pick any — arrows to move, space to toggle, `a` for all/none, Enter to confirm. */\n async multiselect<T>(\n label: string,\n choices: readonly Choice<T>[],\n preselected: readonly number[],\n ): Promise<T[]> {\n if (!this.interactive) return preselected.map(i => choices[i].value);\n if (rawCapable()) {\n const picked = await this.runList(label, choices, {\n multi: true,\n cursor: preselected[0] ?? 0,\n selected: new Set(preselected),\n });\n return picked.map(i => choices[i].value);\n }\n return this.multiselectByNumber(label, choices, preselected);\n }\n\n /**\n * The raw-mode list loop. Renders in place: each keypress rewinds over the block just drawn and\n * repaints it, so the list stays put instead of scrolling the terminal away.\n *\n * Any readline interface is closed first — it would otherwise swallow the keystrokes we need.\n * `cleanup` always restores the terminal (raw mode off, cursor shown), including on cancel, so a\n * Ctrl-C can't leave the shell in a state where typing is invisible.\n */\n private runList<T>(\n label: string,\n choices: readonly Choice<T>[],\n init: { multi: boolean; cursor: number; selected: Set<number> },\n ): Promise<number[]> {\n this.close(); // readline and raw mode can't both own stdin\n const stdin = process.stdin;\n const { multi } = init;\n let state: ListState = {\n cursor: Math.max(0, Math.min(init.cursor, choices.length - 1)),\n selected: init.selected,\n done: false,\n cancelled: false,\n };\n let painted = 0;\n\n const help = multi ? \"↑↓ move · space toggle · a all · enter confirm\" : \"↑↓ move · enter select\";\n\n const frame = (): string => {\n const rows = choices.map((c, i) => {\n const here = i === state.cursor;\n const mark = multi ? (state.selected.has(i) ? green(\"◉\") : dim(\"◯\")) : here ? green(\"❯\") : \" \";\n const name = here ? bold(c.label) : c.label;\n const hint = c.hint ? ` ${dim(`— ${c.hint}`)}` : \"\";\n return ` ${mark} ${name}${hint}`;\n });\n return [`${cyan(\"?\")} ${bold(label)} ${dim(help)}`, ...rows].join(\"\\n\");\n };\n\n const paintFrame = (): void => {\n if (painted) this.out(cursorUp(painted) + CLEAR_DOWN);\n const text = frame();\n this.out(`${text}\\n`);\n painted = text.split(\"\\n\").length;\n };\n\n return new Promise<number[]>((resolve, reject) => {\n const cleanup = (): void => {\n stdin.removeListener(\"data\", onData);\n stdin.removeListener(\"end\", onEnd);\n if (stdin.isTTY) stdin.setRawMode(false);\n stdin.pause();\n this.out(SHOW_CURSOR);\n };\n\n /**\n * stdin closed while we were waiting — a piped run, a closed terminal, a killed parent. There\n * is no further input coming, so commit what's on screen instead of blocking forever.\n */\n const onEnd = (): void => {\n const chosen = multi ? [...state.selected].sort((a, b) => a - b) : [state.cursor];\n this.out(cursorUp(painted) + CLEAR_DOWN);\n cleanup();\n resolve(chosen);\n };\n\n const onData = (chunk: string): void => {\n // One event can carry several keys (a held-down arrow); apply them all, then paint once.\n for (const key of decodeKeys(chunk)) {\n state = applyKey(state, key, choices.length, multi);\n if (state.done || state.cancelled) break;\n }\n\n if (state.cancelled) {\n this.out(cursorUp(painted) + CLEAR_DOWN);\n cleanup();\n reject(new Error(\"Cancelled.\"));\n return;\n }\n\n if (state.done) {\n const chosen = multi ? [...state.selected].sort((a, b) => a - b) : [state.cursor];\n // Replace the live block with a one-line record of the answer, so a finished interview\n // reads back as a transcript rather than a wall of spent menus.\n this.out(cursorUp(painted) + CLEAR_DOWN);\n const summary = chosen.length ? chosen.map(i => choices[i].label).join(\", \") : \"none\";\n this.write(`${cyan(\"?\")} ${bold(label)} ${dim(\"›\")} ${green(summary)}`);\n cleanup();\n resolve(chosen);\n return;\n }\n\n paintFrame();\n };\n\n stdin.setRawMode(true);\n stdin.resume();\n stdin.setEncoding(\"utf8\");\n this.out(HIDE_CURSOR);\n stdin.on(\"data\", onData);\n stdin.on(\"end\", onEnd);\n paintFrame();\n });\n }\n\n /** Line-mode fallback: pick one by number. */\n private async selectByNumber<T>(\n label: string,\n choices: readonly Choice<T>[],\n defaultIndex: number,\n ): Promise<T> {\n this.write(`${cyan(\"?\")} ${bold(label)}`);\n choices.forEach((c, i) => {\n const marker = i === defaultIndex ? green(\"❯\") : \" \";\n const hint = c.hint ? ` ${dim(`— ${c.hint}`)}` : \"\";\n this.write(` ${marker} ${dim(`${i + 1}.`)} ${i === defaultIndex ? bold(c.label) : c.label}${hint}`);\n });\n for (;;) {\n const answer = (await this.question(` ${dim(`1–${choices.length}`)} `)).trim();\n if (!answer) return choices[defaultIndex].value;\n const index = Number(answer) - 1;\n if (Number.isInteger(index) && index >= 0 && index < choices.length) return choices[index].value;\n this.write(` ${yellow(\"!\")} Enter a number between 1 and ${choices.length}.`);\n }\n }\n\n /** Line-mode fallback: pick any by comma-separated numbers. */\n private async multiselectByNumber<T>(\n label: string,\n choices: readonly Choice<T>[],\n preselected: readonly number[],\n ): Promise<T[]> {\n this.write(`${cyan(\"?\")} ${bold(label)} ${dim('(comma-separated, blank = keep, \"none\" = clear)')}`);\n choices.forEach((c, i) => {\n const on = preselected.includes(i);\n const hint = c.hint ? ` ${dim(`— ${c.hint}`)}` : \"\";\n this.write(` ${on ? green(\"◉\") : dim(\"◯\")} ${dim(`${i + 1}.`)} ${c.label}${hint}`);\n });\n for (;;) {\n const answer = (await this.question(` ${dim(`1–${choices.length}`)} `)).trim().toLowerCase();\n if (!answer) return preselected.map(i => choices[i].value);\n if (answer === \"none\") return [];\n const parts = answer.split(\",\").map(s => Number(s.trim()) - 1);\n if (parts.every(i => Number.isInteger(i) && i >= 0 && i < choices.length)) {\n return parts.map(i => choices[i].value);\n }\n this.write(` ${yellow(\"!\")} Enter numbers between 1 and ${choices.length}, separated by commas.`);\n }\n }\n}\n","/**\n * The `refract create` interview (Node-only) — the question flow, separated from both CLIs that run it.\n *\n * `refract create` asks it to write a theme into an existing project; `create-refract-theme` asks it\n * while scaffolding a whole new package. Two entry points, one script of questions — because an\n * interview duplicated across two packages is an interview that drifts.\n *\n * Every answer can be supplied up front (a flag, or a caller's default), and every prompt is\n * non-interactive-safe, so the same function serves a human at a terminal and a scripted run.\n */\nimport type { Prompter } from \"./prompt\";\nimport { dim, green, yellow } from \"./prompt\";\nimport {\n FEEL_PRESETS,\n defaultSchemeFor,\n nearestLadderStep,\n schemesFor,\n type BrandScheme,\n type ContrastTarget,\n type Feel,\n type ResetPreset,\n type ScaffoldAnswers,\n} from \"./scaffold\";\nimport type { CreateResult, RawFormat } from \"./createCommand\";\nimport { parseColor, rgbToOklch } from \"../subsystems/colors/utils\";\n\n/** What each harmony scheme is for, in one line — the names mean nothing to most people. */\nexport const SCHEME_HINTS: Readonly<Record<string, string>> = {\n complement: \"one companion, 180° opposite — maximum separation\",\n analogous: \"two neighbours, ±30° — quiet and cohesive\",\n \"split-complement\": \"the complement's neighbours — contrast with less tension\",\n triadic: \"even thirds, ±120° — three colours of equal weight\",\n tetradic: \"two complementary pairs — the most range\",\n pentadic: \"five evenly spaced hues — needs a dominant colour picked by hand\",\n};\n\n/**\n * Ratio choices, tightest to most dramatic, each showing the ladder it produces from 16px. The ratio\n * is the most consequential typographic choice in the theme and its name carries no information, so\n * the numbers do the explaining.\n */\nexport const TYPE_SCALE_CHOICES: ReadonlyArray<readonly [string, string]> = [\n [\"major-second\", \"1.125 · 16 · 18 · 20 · 23 · 26 · 29\"],\n [\"minor-third\", \"1.2 · 16 · 19 · 23 · 28 · 33 · 40\"],\n [\"major-third\", \"1.25 · 16 · 20 · 25 · 31 · 39 · 49\"],\n [\"perfect-fourth\", \"1.333 · 16 · 21 · 28 · 38 · 51 · 67\"],\n [\"perfect-fifth\", \"1.5 · 16 · 24 · 36 · 54 · 81 · 122\"],\n [\"golden\", \"1.618 · 16 · 26 · 42 · 68 · 110 · 178\"],\n];\n\n/** Answers a caller already has — from CLI flags, or a host tool's own defaults. */\nexport interface InterviewGiven {\n readonly seed?: string;\n /** Brand count in auto mode, or a comma-separated colour list in manual mode. */\n readonly colors?: string;\n readonly scheme?: string;\n readonly manual?: boolean;\n readonly feel?: string;\n readonly ratio?: string;\n readonly baseSize?: string | number;\n readonly contrast?: string;\n readonly reset?: string;\n readonly format?: string;\n readonly noSemantics?: boolean;\n readonly noNeutral?: boolean;\n readonly noShadows?: boolean;\n}\n\n/** The fully-resolved answer set, ready for `runCreate`. */\nexport type InterviewAnswers = ScaffoldAnswers & { readonly format: RawFormat };\n\nconst isColor = (v: string): string | undefined => {\n try {\n parseColor(v);\n return undefined;\n } catch {\n return `\"${v}\" isn't a colour refract can parse. Try a hex like #4c6ef5.`;\n }\n};\n\n/**\n * Run the interview. Anything present in `given` is taken as answered and never asked.\n *\n * The scheme question only appears when the brand count admits more than one rotation set — which is\n * only at three colours. Two is a complement, four a tetradic, five a pentadic: asking would be a\n * prompt with a single option.\n */\nexport async function promptCreateAnswers(p: Prompter, given: InterviewGiven = {}): Promise<InterviewAnswers> {\n const seed = given.seed ?? (await p.text(\"Primary colour\", \"#4c6ef5\", isColor));\n const lightness = Math.round(rgbToOklch(parseColor(seed).rgb).L * 10) / 10;\n p.write(` ${dim(`parsed · lightness ${lightness}% — lands at ≈${nearestLadderStep(lightness)} on the ladder`)}`);\n p.write();\n\n const manual = Boolean(given.manual);\n let brandCount = 2;\n let scheme: BrandScheme | undefined;\n let extraColors: string[] = [];\n\n if (manual) {\n extraColors = (given.colors ?? \"\").split(\",\").map(s => s.trim()).filter(Boolean);\n if (!extraColors.length && p.interactive) {\n const total = await p.number(\"How many brand colours in total?\", 2, n =>\n Number.isInteger(n) && n >= 1 && n <= 5 ? undefined : \"Pick a whole number from 1 to 5.\");\n for (let i = 1; i < total; i++) {\n extraColors.push(await p.text(`Brand colour ${i + 1}`, \"#e64980\", isColor));\n }\n }\n brandCount = extraColors.length + 1;\n } else {\n brandCount = given.colors\n ? Number(given.colors)\n : await p.number(\"How many brand colours? (including the primary)\", 2, n =>\n Number.isInteger(n) && n >= 1 && n <= 5 ? undefined : \"Pick a whole number from 1 to 5.\");\n const options = schemesFor(brandCount);\n scheme = (given.scheme as BrandScheme | undefined) ?? defaultSchemeFor(brandCount);\n if (!given.scheme && options.length > 1) {\n scheme = await p.select<BrandScheme>(\n \"Harmony scheme\",\n options.map(s => ({ value: s, label: s, hint: SCHEME_HINTS[s] })),\n Math.max(0, options.indexOf(scheme as BrandScheme)),\n );\n }\n if (scheme && brandCount > 1) {\n p.write(` ${dim(`→ ${scheme} · each member becomes its own palette with a full ladder`)}`);\n p.write();\n }\n }\n\n const anyExtraFlag = given.noSemantics || given.noNeutral || given.noShadows;\n const extras = anyExtraFlag || !p.interactive\n ? { semantics: !given.noSemantics, neutral: !given.noNeutral, shadows: !given.noShadows }\n : await (async () => {\n const picked = await p.multiselect<\"semantics\" | \"neutral\" | \"shadows\">(\n \"Also add\",\n [\n { value: \"semantics\", label: \"Semantic colours\", hint: \"success · info · warning · danger\" },\n { value: \"neutral\", label: \"Neutral ramp\", hint: \"50 … 900\" },\n { value: \"shadows\", label: \"Shadow tints\", hint: \"3 alpha levels + the effects ramp\" },\n ],\n [0, 1, 2],\n );\n return {\n semantics: picked.includes(\"semantics\"),\n neutral: picked.includes(\"neutral\"),\n shadows: picked.includes(\"shadows\"),\n };\n })();\n\n const contrast = (given.contrast as ContrastTarget | undefined) ?? await p.select<ContrastTarget>(\n \"Contrast target\",\n [\n { value: \"AA\", label: \"WCAG AA\", hint: \"4.5:1 body text\" },\n { value: \"AAA\", label: \"WCAG AAA\", hint: \"7:1 — expect heavier nudges\" },\n { value: \"none\", label: \"Skip\", hint: \"write the colours exactly as given\" },\n ],\n );\n\n const baseFontSize = given.baseSize !== undefined\n ? Number(given.baseSize)\n : await p.number(\"Base font size (px)\", 16, n => (n > 0 ? undefined : \"Must be greater than zero.\"));\n\n const feel = (given.feel as Feel | undefined) ?? await p.select<Feel>(\n \"Overall feel\",\n (Object.keys(FEEL_PRESETS) as Feel[]).map(k => ({\n value: k, label: FEEL_PRESETS[k].label, hint: FEEL_PRESETS[k].blurb,\n })),\n );\n\n const ratio = given.ratio ?? await p.select<string>(\n \"Type scale\",\n TYPE_SCALE_CHOICES.map(([value, hint]) => ({ value, label: value, hint })),\n Math.max(0, TYPE_SCALE_CHOICES.findIndex(([v]) => v === FEEL_PRESETS[feel].ratio)),\n );\n\n const reset = (given.reset as ResetPreset | undefined) ?? await p.select<ResetPreset>(\n \"CSS reset\",\n [\n { value: \"preflight\", label: \"preflight\", hint: \"full normalization + an h1–h6 size map\" },\n { value: \"normalize\", label: \"normalize\", hint: \"the classic, no heading map\" },\n { value: \"none\", label: \"none\", hint: \"you already ship one\" },\n ],\n );\n\n const format = (given.format as RawFormat | undefined) ?? await p.select<RawFormat>(\n \"Format\",\n [\n { value: \"ts\", label: \"theme.raw.ts\", hint: \"typed, `satisfies RawTheme`\" },\n { value: \"js\", label: \"theme.raw.js\", hint: \"plain ESM, no build step\" },\n { value: \"json\", label: \"theme.raw.json\", hint: \"portable, no code at all\" },\n ],\n );\n\n return {\n seed, mode: manual ? \"manual\" : \"auto\", brandCount, scheme, extraColors,\n ...extras, contrast, baseFontSize, ratio, feel, reset, format,\n };\n}\n\n/**\n * The post-generation summary: what the contrast pass did, and what landed. Returned as lines rather\n * than printed so each host can frame them — the standalone command and the project scaffolder put\n * different things around the same facts.\n */\nexport function createReportLines(result: CreateResult, variableCount: number): string[] {\n const lines: string[] = [];\n const { contrast } = result.report;\n if (contrast.length) {\n lines.push(` ${dim(`Contrast · ${contrast.length} pairings checked`)}`);\n for (const c of contrast) {\n const shift = c.nudge > 0\n ? `${yellow(`−${c.nudge}`)} ${green(`${c.ratioAfter} ${c.levelAfter}`)}`\n : dim(\"unchanged\");\n const flag = c.unresolved ? ` ${yellow(\"! still short of the bar\")}` : \"\";\n lines.push(` ${c.name.padEnd(10)} ${String(c.ratioBefore).padStart(5)} ${shift}${flag}`);\n }\n lines.push(\"\");\n }\n const nudged = contrast.filter(c => c.nudge > 0).length;\n lines.push(` ${dim(`${result.sections.length} subsystems · ${variableCount} variables · 0 recipes`)}`);\n if (nudged) lines.push(` ${dim(`${nudged} colour${nudged === 1 ? \"\" : \"s\"} darkened to clear the contrast bar`)}`);\n return lines;\n}\n","/**\n * `refract import` — seed a theme from a DTCG `tokens.json` (Node-only, §7 Step 10f).\n *\n * DTCG is edge interchange, NOT a build input: rather than load `tokens.json` on every build, this\n * runs `fromDTCG` ONCE and writes a `theme.raw.ts` the user then owns and edits — the same ownership\n * model as `init` (blank template), just seeded from a DTCG document instead. Two reasons it must be a\n * one-shot scaffold, not a live loader:\n * - `fromDTCG` is heuristic + lossy (guesses subsystem mapping, drops the DTCG `border` composite's\n * color, rounds rem→px). Baking those guesses in on every build would hide them; as generated\n * source they land as an editor-reviewable diff.\n * - DTCG carries **property tokens only** — recipes / composition / states / components have no DTCG\n * representation, so the seed is always incomplete and needs hand-authoring on top.\n *\n * Emits a typed `theme.raw.ts` (`export const raw: RawTheme = …`) and, unless `--raw-only`, a runnable\n * `theme.config.ts` that imports it (the §8b sibling-`.ts` graph-compile makes the extensionless\n * `./theme.raw` import resolve). Refuses to clobber either file unless `--force`.\n *\n * `fromDTCG` is imported as a relative `../dtcg` static import (NOT the `./dtcg` package subpath) so the\n * in-repo gate resolves with no dist build — the same pattern as the rest of `src/build/`.\n */\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { basename, dirname, isAbsolute, join, resolve } from \"node:path\";\nimport { fromDTCG, type DTCGDocument, type FromDTCGOptions } from \"../dtcg\";\nimport { readOwnPackageName, CSS_ADAPTER_PACKAGE } from \"./init\";\n\nconst DEFAULT_RAW_OUT = \"theme.raw.ts\";\nconst DEFAULT_CONFIG_OUT = \"theme.config.ts\";\n\nexport interface ImportOptions {\n /** Project dir to scaffold into (default `process.cwd()`). */\n readonly cwd?: string;\n /** Path to the DTCG `tokens.json` to import (relative to cwd or absolute). Required. */\n readonly input: string;\n /** `--out` — the raw-theme file to write (default `theme.raw.ts`, resolved against cwd). */\n readonly out?: string;\n /** `--raw-only` — write only `theme.raw.ts`, skip the companion `theme.config.ts` (default false). */\n readonly rawOnly?: boolean;\n /** `--force` — overwrite existing files instead of refusing (default false). */\n readonly force?: boolean;\n /** `--breakpoint-group` — DTCG group whose dimension tokens seed the breakpoints. */\n readonly breakpointGroup?: string;\n /** `--breakpoints` — explicit `{ name: px }` fallback when the doc carries no breakpoint group. */\n readonly breakpoints?: Record<string, number>;\n /** Package name the generated files import from (default: this package's own `name`). */\n readonly packageName?: string;\n}\n\nexport interface ImportResult {\n /** Absolute path of the DTCG document read. */\n readonly inputFile: string;\n /** Absolute path of the written `theme.raw.ts`. */\n readonly rawFile: string;\n /** Absolute path of the written `theme.config.ts`, or `undefined` when `--raw-only`. */\n readonly configFile?: string;\n /** Top-level raw keys produced (e.g. `[\"breakpoints\", \"colors\", \"typography\"]`). */\n readonly sections: readonly string[];\n /** Per-subsystem property count seeded from the document (excludes `breakpoints`). */\n readonly counts: Readonly<Record<string, number>>;\n}\n\n/** Parse a `--breakpoints \"sm:576,md:768\"` flag into `{ sm: 576, md: 768 }`. Ignores malformed pairs. */\nexport function parseBreakpointsFlag(spec: string): Record<string, number> {\n const out: Record<string, number> = {};\n for (const pair of spec.split(\",\")) {\n const [name, raw] = pair.split(\":\");\n const key = name?.trim();\n const value = Number.parseFloat((raw ?? \"\").trim());\n if (key && Number.isFinite(value)) out[key] = value;\n }\n return out;\n}\n\n/** The generated `theme.raw.ts` body — a typed `RawTheme` the user then owns and extends. */\nexport function scaffoldRaw(packageName: string, raw: unknown, sourceLabel: string): string {\n const body = JSON.stringify(raw, null, 2);\n return `// Generated by \\`refract import\\` from ${sourceLabel}.\n// DTCG carries property tokens ONLY — recipes, components, composition, and states are not imported.\n// The mapping is heuristic (subsystem inferred from \\`$type\\`/name; \\`border\\` composite colors dropped;\n// rem rounded to px). Review the seeded tokens, then hand-author the rest of your theme below.\nimport type { RawTheme } from \"${packageName}/build\";\n\nexport const raw: RawTheme = ${body};\n`;\n}\n\n/** The generated companion `theme.config.ts` — a runnable build config importing the seeded raw. */\nexport function scaffoldImportConfig(packageName: string, rawImportSpec: string): string {\n return `import { defineConfig } from \"${packageName}/build\";\nimport { createCssAdapter } from \"${CSS_ADAPTER_PACKAGE}\";\nimport { raw } from \"${rawImportSpec}\";\n\n// Generated by \\`refract import\\`. This is your build config — edit it freely. Add adapter options at\n// construction (\\`createCssAdapter({ … })\\`) and extra targets (SC/JSON/…) as their packages install.\nexport default defineConfig({\n raw,\n targets: [\n { adapter: createCssAdapter(), outDir: \"dist/theme\" },\n ],\n});\n`;\n}\n\n/** Count seeded properties per subsystem for the summary (each subsystem value is a `{ prop: … }` map). */\nfunction summarizeCounts(raw: Record<string, unknown>): Record<string, number> {\n const counts: Record<string, number> = {};\n for (const [key, value] of Object.entries(raw)) {\n if (key === \"breakpoints\") continue;\n counts[key] = value && typeof value === \"object\" ? Object.keys(value).length : 0;\n }\n return counts;\n}\n\n/**\n * Read the DTCG document at `input`, convert it via `fromDTCG`, and write a `theme.raw.ts` (plus, unless\n * `rawOnly`, a companion `theme.config.ts`) into `cwd`. Returns a summary of what was seeded. Throws on a\n * missing/unparseable input or when an output file exists and `force` is not set (never clobbers).\n */\nexport function runImport(options: ImportOptions): ImportResult {\n const cwd = options.cwd ?? process.cwd();\n const packageName = options.packageName ?? readOwnPackageName();\n\n // --- Read + parse the DTCG document ---\n const inputFile = isAbsolute(options.input) ? options.input : resolve(cwd, options.input);\n if (!existsSync(inputFile)) {\n throw new Error(`No DTCG document found at \"${options.input}\" (resolved to \"${inputFile}\").`);\n }\n let doc: unknown;\n try {\n doc = JSON.parse(readFileSync(inputFile, \"utf8\"));\n } catch (err) {\n throw new Error(`\"${inputFile}\" is not valid JSON: ${(err as Error).message}`);\n }\n\n // --- Convert (heuristic, lossy — one-shot at import time only) ---\n const fromOpts: FromDTCGOptions = {};\n if (options.breakpointGroup) fromOpts.breakpointGroup = options.breakpointGroup;\n if (options.breakpoints && Object.keys(options.breakpoints).length) {\n fromOpts.breakpoints = options.breakpoints;\n }\n const raw = fromDTCG(doc as DTCGDocument, fromOpts) as Record<string, unknown>;\n\n // --- Write theme.raw.ts (refuse to clobber unless --force) ---\n const rawFile = options.out\n ? isAbsolute(options.out)\n ? options.out\n : resolve(cwd, options.out)\n : resolve(cwd, DEFAULT_RAW_OUT);\n if (existsSync(rawFile) && !options.force) {\n throw new Error(`${basename(rawFile)} already exists at \"${rawFile}\". Pass --force to overwrite it.`);\n }\n mkdirSync(dirname(rawFile), { recursive: true });\n writeFileSync(rawFile, scaffoldRaw(packageName, raw, JSON.stringify(basename(inputFile))), \"utf8\");\n\n // --- Write the companion theme.config.ts (unless --raw-only; refuse to clobber unless --force) ---\n let configFile: string | undefined;\n if (!options.rawOnly) {\n configFile = resolve(dirname(rawFile), DEFAULT_CONFIG_OUT);\n if (existsSync(configFile) && !options.force) {\n throw new Error(\n `${DEFAULT_CONFIG_OUT} already exists at \"${configFile}\". Pass --force to overwrite it, or ` +\n `--raw-only to skip writing a config.`,\n );\n }\n // Extensionless sibling spec — the §8b graph-compile rewrites it to the emitted `.mjs`.\n const rawImportSpec = `./${basename(rawFile).replace(/\\.(ts|mts|cts|tsx)$/, \"\")}`;\n writeFileSync(configFile, scaffoldImportConfig(packageName, rawImportSpec), \"utf8\");\n }\n\n return {\n inputFile,\n rawFile,\n configFile,\n sections: Object.keys(raw),\n counts: summarizeCounts(raw),\n };\n}\n","/**\n * `refract build` — load the config, emit every target to disk (Node-only, §7 Step 10c).\n *\n * The config is the adapter seam (10b): `loadConfig` returns fully-constructed adapter objects, and\n * this command drives each through the adapter-agnostic `emitTheme` (10b). The CLI imports zero\n * adapters itself. A target's `outDir` is resolved relative to the config file's directory (so a\n * config is portable regardless of the invoking cwd); an absolute `outDir` is used as-is.\n *\n * Overrides (flags): `--config <path>` picks the config; `--target <name|index|outDir>` limits the\n * build to one target; `--out <dir>` overrides the selected target's `outDir`. `--out` without\n * `--target` is only allowed when the config has exactly one target (otherwise it is ambiguous).\n * Per-target `helpers` are always honored.\n */\nimport { dirname, isAbsolute, resolve } from \"node:path\";\nimport { loadConfig, type EmitTarget } from \"./config\";\nimport { emitTheme } from \"./emitTheme\";\n\nexport interface BuildOptions {\n readonly cwd?: string;\n /** `--config` override — a path to the config file. */\n readonly configPath?: string;\n /** `--target` override — a target name, numeric index, or outDir to build in isolation. */\n readonly target?: string;\n /** `--out` override — replaces the selected target's outDir. */\n readonly out?: string;\n}\n\nexport interface BuildTargetSummary {\n readonly name?: string;\n readonly adapter: string;\n /** Absolute outDir the target was written to. */\n readonly outDir: string;\n /** Absolute paths of every file written for this target. */\n readonly files: string[];\n}\n\nexport interface BuildResult {\n readonly configPath: string;\n readonly targets: BuildTargetSummary[];\n}\n\n/** Select the target(s) to build. `--target` matches by name, then numeric index, then outDir. */\nfunction selectTargets(targets: readonly EmitTarget[], selector?: string): EmitTarget[] {\n if (selector === undefined) return [...targets];\n\n const byName = targets.filter(t => t.name === selector);\n if (byName.length) return byName;\n\n if (/^\\d+$/.test(selector)) {\n const idx = Number(selector);\n if (idx >= 0 && idx < targets.length) return [targets[idx]];\n }\n\n const byOutDir = targets.filter(t => t.outDir === selector);\n if (byOutDir.length) return byOutDir;\n\n throw new Error(\n `No target matched \"${selector}\". Config has ${targets.length} target(s): ` +\n targets.map((t, i) => t.name ?? `#${i} (${t.outDir})`).join(\", \") + \".\",\n );\n}\n\n/** Load the config and emit every (selected) target to disk. */\nexport async function runBuild(options: BuildOptions = {}): Promise<BuildResult> {\n const cwd = options.cwd ?? process.cwd();\n const { config, path } = await loadConfig({ cwd, configPath: options.configPath });\n\n if (!config.targets.length) {\n throw new Error(`\"${path}\" has no targets to build.`);\n }\n\n const selected = selectTargets(config.targets, options.target);\n\n if (options.out !== undefined && selected.length > 1) {\n throw new Error(\n `--out is ambiguous across ${selected.length} targets; pass --target to pick one first.`,\n );\n }\n\n const configDir = dirname(path);\n const summaries: BuildTargetSummary[] = [];\n for (const target of selected) {\n // A config-relative `outDir` resolves against the config file (portable); a `--out` override is\n // relative to the invoking cwd (it's a command-line path). Absolute paths pass through.\n const outDir =\n options.out !== undefined\n ? isAbsolute(options.out)\n ? options.out\n : resolve(cwd, options.out)\n : isAbsolute(target.outDir)\n ? target.outDir\n : resolve(configDir, target.outDir);\n const result = await emitTheme({\n raw: config.raw,\n adapter: target.adapter,\n outDir,\n helpers: target.helpers,\n emit: target.emit,\n media: config.media,\n units: config.units,\n baseFontSize: config.baseFontSize,\n guide: target.guide,\n });\n summaries.push({\n name: target.name,\n adapter: target.adapter.name,\n outDir: result.outDir,\n files: result.files,\n });\n }\n\n return { configPath: path, targets: summaries };\n}\n","/**\n * `refract tokens` — export the theme as a DTCG `tokens.json` (Node-only, §7 Step 10d).\n *\n * A SEPARATE command from `build`, not part of it: DTCG is adapter-free data-interchange, not an\n * output adapter. So this reads ONLY the config's `raw` (never its `targets`/`emitTheme`) and writes a\n * single JSON document — no `theme.css`, no vendored helpers.\n *\n * `toDTCG` needs a *built* `Theme` (it walks the flat `theme.tokens` + `theme.resolveToken` +\n * `theme.model.breakpoints`), so we `createTheme(raw, { adapter })` first. The adapter choice is\n * IMMATERIAL to the output — `toDTCG` never touches adapter-produced strings — so we use core's own\n * built-in `createNoopAdapter` as the trivial builder. (Before the monorepo split this reached for\n * `createCssAdapter`, which forced a core→adapter dependency; the null adapter keeps `src/build` free\n * of every adapter package — the guiding rule is the dependency arrow points ONLY into core.)\n *\n * `toDTCG` is imported as a relative `../dtcg` static import (NOT the `./dtcg` package subpath) so the\n * in-repo gate resolves with no dist build — the same pattern as everything else in `src/build/`.\n */\nimport { mkdirSync, writeFileSync } from \"node:fs\";\nimport { dirname, isAbsolute, resolve } from \"node:path\";\nimport { createTheme } from \"../core/createTheme\";\nimport { createNoopAdapter } from \"../core/noopAdapter\";\nimport { toDTCG } from \"../dtcg\";\nimport { loadConfig } from \"./config\";\n\nconst DEFAULT_OUT = \"tokens.json\";\n\nexport interface TokensOptions {\n readonly cwd?: string;\n /** `--config` override — a path to the config file. */\n readonly configPath?: string;\n /** `--out` override — the JSON file to write (default `tokens.json`, resolved against cwd). */\n readonly out?: string;\n}\n\nexport interface TokensResult {\n /** Absolute path the config was loaded from. */\n readonly configPath: string;\n /** Absolute path of the written `tokens.json`. */\n readonly outFile: string;\n /** Number of top-level DTCG groups written (excludes `$`-prefixed document keys). */\n readonly groupCount: number;\n}\n\n/** Load the config, build the theme, and write its DTCG document to disk. Returns a summary. */\nexport async function runTokens(options: TokensOptions = {}): Promise<TokensResult> {\n const cwd = options.cwd ?? process.cwd();\n const { config, path } = await loadConfig({ cwd, configPath: options.configPath });\n\n // Adapter choice is immaterial — `toDTCG` reads only `theme.tokens`/`resolveToken`/`model`.\n const theme = createTheme(config.raw, { adapter: createNoopAdapter() });\n const doc = toDTCG(theme);\n\n // `--out` is a command-line path (relative to cwd); absolute passes through.\n const outFile = options.out\n ? isAbsolute(options.out)\n ? options.out\n : resolve(cwd, options.out)\n : resolve(cwd, DEFAULT_OUT);\n\n mkdirSync(dirname(outFile), { recursive: true });\n writeFileSync(outFile, `${JSON.stringify(doc, null, 2)}\\n`, \"utf8\");\n\n const groupCount = Object.keys(doc).filter(k => !k.startsWith(\"$\")).length;\n return { configPath: path, outFile, groupCount };\n}\n","/**\n * `refract audit` — score the theme's colour pairings for WCAG 2 contrast (+ advisory APCA).\n *\n * Adapter-free like `refract tokens`: the audit reads only `theme.tokens` / `theme.resolveToken` /\n * `theme.model`, so we build with core's `createNoopAdapter`. Reports by default; `--strict` makes the\n * command exit non-zero (via an aggregated throw from `audit`). Returns a serializable summary so the\n * gate test can drive it directly.\n *\n * `audit` is imported as a relative `../subsystems/colors/audit` (not a package subpath) so the in-repo\n * gate resolves with no dist build — the same pattern as the rest of `src/build/`.\n */\nimport { createTheme } from \"../core/createTheme\";\nimport { createNoopAdapter } from \"../core/noopAdapter\";\nimport { audit, type AuditResult, type WcagLevel } from \"../subsystems/colors/audit\";\nimport { loadConfig } from \"./config\";\n\nexport interface AuditCommandOptions {\n readonly cwd?: string;\n /** `--config` override — a path to the config file. */\n readonly configPath?: string;\n /** `--strict` — throw (non-zero exit) when any pairing fails. */\n readonly strict?: boolean;\n /** `--min-wcag` — pass bar (`\"AA\"` default). */\n readonly minWcag?: WcagLevel;\n /** `--large` — score against large-text thresholds. */\n readonly largeText?: boolean;\n}\n\nexport interface AuditCommandResult {\n /** Absolute path the config was loaded from. */\n readonly configPath: string;\n readonly result: AuditResult;\n}\n\n/** Load the config, build the theme (adapter-free), and audit its colour pairings. */\nexport async function runAudit(options: AuditCommandOptions = {}): Promise<AuditCommandResult> {\n const cwd = options.cwd ?? process.cwd();\n const { config, path } = await loadConfig({ cwd, configPath: options.configPath });\n\n const theme = createTheme(config.raw, { adapter: createNoopAdapter() });\n const result = audit(theme, {\n strict: options.strict,\n minWcag: options.minWcag,\n largeText: options.largeText,\n });\n return { configPath: path, result };\n}\n","/**\n * `diffThemes` — the blast radius of a candidate theme edit, computed against a base (§5 agent-native).\n *\n * refract stores every synthesized rung/variant as a `{ ref, fn, arg }` graph, not a frozen literal, so\n * a candidate theme can be *built and compared* before it's applied — the claim no token file can make:\n * see what a change does before you make it. This is the shared engine behind `refract diff <candidate>`\n * (a human CLI + a CI gate) and the MCP `diffTheme` tool (an agent's plan-then-apply guardrail).\n *\n * Three axes, each adapter-independent except `classes`:\n * - `tokens` — which resolved token values moved (added / removed / changed).\n * - `classes` — which emitted recipe classes changed CSS (only when the themes emit classes, e.g. the\n * CSS adapter — read via the duck-typed `renderRecipe` / `getClass`).\n * - `contrast` — which WCAG pairings crossed a pass/level threshold (via {@link audit}).\n */\nimport type { Theme } from \"../core\";\nimport { audit, type PairingScore } from \"../subsystems/colors/audit\";\n\nexport type ChangeKind = \"added\" | \"removed\" | \"changed\";\n\nexport interface TokenChange {\n path: string;\n before: string | null;\n after: string | null;\n kind: ChangeKind;\n}\n\nexport interface ClassChange {\n /** The emitted class name (or the `subsystem.group.variant` id when no adapter names it). */\n name: string;\n kind: ChangeKind;\n}\n\nexport interface ContrastScore {\n ratio?: number;\n level?: string;\n pass?: boolean;\n}\n\nexport interface ContrastChange {\n label: string;\n before: ContrastScore | null;\n after: ContrastScore | null;\n /** True when the pass verdict or the WCAG level changed — the threshold-crossing an agent cares about. */\n crossed: boolean;\n}\n\nexport interface ThemeDiff {\n tokens: TokenChange[];\n classes: ClassChange[];\n contrast: ContrastChange[];\n summary: {\n tokensChanged: number;\n classesChanged: number;\n /** Pairings whose pass verdict or level crossed a threshold. */\n pairingsCrossed: number;\n };\n}\n\n/** The CSS-style surface a class-emitting adapter attaches to the theme (duck-typed — absent on noop). */\ntype ClassEmittingTheme = Theme & {\n renderRecipe?: (subsystem: string, group: string, variant: string) => string;\n getClass?: (subsystem: string, group: string, variant: string) => string | undefined;\n};\n\nconst resolvedValue = (theme: Theme, path: string): string | null => {\n try {\n return String(theme.resolveToken(path));\n } catch {\n return null;\n }\n};\n\nconst diffTokens = (base: Theme, candidate: Theme): TokenChange[] => {\n const paths = new Set([...Object.keys(base.tokens), ...Object.keys(candidate.tokens)]);\n const out: TokenChange[] = [];\n for (const path of paths) {\n const inBase = path in base.tokens;\n const inCandidate = path in candidate.tokens;\n const before = inBase ? resolvedValue(base, path) : null;\n const after = inCandidate ? resolvedValue(candidate, path) : null;\n if (inBase && !inCandidate) out.push({ path, before, after: null, kind: \"removed\" });\n else if (!inBase && inCandidate) out.push({ path, before: null, after, kind: \"added\" });\n else if (before !== after) out.push({ path, before, after, kind: \"changed\" });\n }\n return out.sort((a, b) => a.path.localeCompare(b.path));\n};\n\n/** Enumerate every recipe identity a theme's Model declares (`subsystem.group.variant`). */\nconst recipeIds = (theme: Theme): Array<{ subsystem: string; group: string; variant: string }> => {\n const out: Array<{ subsystem: string; group: string; variant: string }> = [];\n for (const [subsystem, sub] of Object.entries(theme.model.subsystems)) {\n for (const [group, ruleSetGroup] of Object.entries(sub.ruleSets ?? {})) {\n for (const variant of Object.keys(ruleSetGroup)) out.push({ subsystem, group, variant });\n }\n }\n return out;\n};\nconst hasRecipe = (theme: Theme, s: string, g: string, v: string): boolean =>\n Boolean(theme.model.subsystems[s]?.ruleSets?.[g]?.[v]);\n\nconst diffClasses = (base: Theme, candidate: Theme): ClassChange[] => {\n const b = base as ClassEmittingTheme;\n const c = candidate as ClassEmittingTheme;\n // Class-level diff needs an adapter that emits classes on at least one side; otherwise there's nothing\n // to compare (noop themes have no CSS). Report empty rather than inventing names.\n if (!b.renderRecipe && !c.renderRecipe) return [];\n const seen = new Set<string>();\n const ids = [...recipeIds(base), ...recipeIds(candidate)].filter((id) => {\n const key = `${id.subsystem}.${id.group}.${id.variant}`;\n if (seen.has(key)) return false;\n seen.add(key);\n return true;\n });\n const out: ClassChange[] = [];\n for (const { subsystem, group, variant } of ids) {\n const inBase = hasRecipe(base, subsystem, group, variant);\n const inCandidate = hasRecipe(candidate, subsystem, group, variant);\n const name =\n c.getClass?.(subsystem, group, variant) ??\n b.getClass?.(subsystem, group, variant) ??\n `${subsystem}.${group}.${variant}`;\n if (inBase && !inCandidate) out.push({ name, kind: \"removed\" });\n else if (!inBase && inCandidate) out.push({ name, kind: \"added\" });\n else {\n const before = b.renderRecipe?.(subsystem, group, variant) ?? \"\";\n const after = c.renderRecipe?.(subsystem, group, variant) ?? \"\";\n if (before !== after) out.push({ name, kind: \"changed\" });\n }\n }\n return out.sort((a, b2) => a.name.localeCompare(b2.name));\n};\n\nconst diffContrast = (base: Theme, candidate: Theme): ContrastChange[] => {\n const score = (p?: PairingScore): ContrastScore | null =>\n p ? { ratio: p.wcagRatio, level: p.wcagLevel, pass: p.pass } : null;\n const byLabel = (pairings: readonly PairingScore[]): Map<string, PairingScore> =>\n new Map(pairings.map((p) => [p.label, p]));\n const before = byLabel(audit(base).pairings);\n const after = byLabel(audit(candidate).pairings);\n const labels = new Set([...before.keys(), ...after.keys()]);\n const out: ContrastChange[] = [];\n for (const label of labels) {\n const b = before.get(label);\n const a = after.get(label);\n const bs = score(b);\n const as = score(a);\n const changed = bs?.ratio !== as?.ratio || bs?.level !== as?.level || Boolean(b) !== Boolean(a);\n if (!changed) continue;\n const crossed = (b?.pass ?? null) !== (a?.pass ?? null) || (b?.wcagLevel ?? null) !== (a?.wcagLevel ?? null);\n out.push({ label, before: bs, after: as, crossed });\n }\n return out.sort((a, b) => a.label.localeCompare(b.label));\n};\n\n/**\n * Diff a candidate theme against a base. Both should be built with the same adapter; pass a\n * class-emitting adapter (e.g. CSS) on both sides to populate `classes`, or any adapter for the\n * adapter-independent `tokens` / `contrast` axes.\n */\nexport function diffThemes(base: Theme, candidate: Theme): ThemeDiff {\n const tokens = diffTokens(base, candidate);\n const classes = diffClasses(base, candidate);\n const contrast = diffContrast(base, candidate);\n return {\n tokens,\n classes,\n contrast,\n summary: {\n tokensChanged: tokens.length,\n classesChanged: classes.length,\n pairingsCrossed: contrast.filter((c) => c.crossed).length,\n },\n };\n}\n","/**\n * `refract diff <candidate>` — build the project's theme and a candidate, and report the blast radius\n * (tokens moved, classes changed, contrast crossings). Optional thresholds make it a CI gate: fail the\n * PR if a token change alters more than N classes or drops a pairing below a WCAG bar.\n *\n * Adapter-free like `tokens`/`audit`: it builds against the config's own target adapters (whatever the\n * config imported), picking a class-emitting one so the class axis is populated. The candidate is a\n * module (default-exported raw theme) or a `.json` raw theme.\n */\nimport { existsSync, readFileSync } from \"node:fs\";\nimport { extname, resolve } from \"node:path\";\nimport { pathToFileURL } from \"node:url\";\nimport type { RawTheme } from \"../core/rawTheme\";\nimport type { Theme, ThemeAdapter } from \"../core\";\nimport { createTheme } from \"../core/createTheme\";\nimport { assertRawTheme } from \"../core/assertRawTheme\";\nimport { createNoopAdapter } from \"../core/noopAdapter\";\nimport { loadConfig } from \"./config\";\nimport { compileTsConfigGraph } from \"./paths\";\nimport { diffThemes, type ThemeDiff } from \"./diff\";\n\nconst WCAG_RANK: Record<string, number> = { fail: 0, \"AA-large\": 1, AA: 2, AAA: 3 };\n\nexport interface DiffCommandOptions {\n cwd?: string;\n configPath?: string;\n /** Path to the candidate theme (`.ts` / `.mjs` / `.js` default-export, or `.json`). */\n candidatePath: string;\n /** CI gate: fail if more than this many classes changed. */\n maxClassChanges?: number;\n /** CI gate: fail if more than this many tokens changed. */\n maxTokenChanges?: number;\n /** CI gate: fail if any pairing's `after` level drops below this WCAG bar. */\n failBelow?: string;\n}\n\nexport interface TargetStatus {\n name: string;\n ok: boolean;\n errors: string[];\n}\n\nexport interface DiffCommandResult {\n configPath: string;\n candidatePath: string;\n diff: ThemeDiff;\n /** Per configured target: does the candidate still build? */\n targets: TargetStatus[];\n /** CI-gate verdict: false when any threshold was breached (or a target stopped building). */\n ok: boolean;\n violations: string[];\n}\n\nlet counter = 0;\n\n/**\n * Load a candidate raw theme from a module (default export) or a `.json` file, and assert it's actually\n * theme-shaped before returning — a mis-shaped candidate (e.g. a `defineConfig`) must fail loud here,\n * not silently diff as \"everything removed\" (see {@link assertRawTheme}).\n */\nasync function loadCandidate(path: string): Promise<RawTheme> {\n if (!existsSync(path)) throw new Error(`candidate theme not found at \"${path}\".`);\n let candidate: unknown;\n if (extname(path) === \".json\") {\n candidate = JSON.parse(readFileSync(path, \"utf8\"));\n } else if (extname(path) === \".ts\") {\n const { entry, cleanup } = await compileTsConfigGraph(path);\n try {\n const mod = (await import(pathToFileURL(entry).href)) as Record<string, unknown>;\n candidate = mod.default ?? mod.raw ?? mod;\n } finally {\n cleanup();\n }\n } else {\n const mod = (await import(`${pathToFileURL(path).href}?v=${++counter}`)) as Record<string, unknown>;\n candidate = mod.default ?? mod.raw ?? mod;\n }\n assertRawTheme(candidate, path);\n return candidate;\n}\n\n/** Does this built theme expose the class-emitting surface (CSS-style adapter)? */\nconst emitsClasses = (theme: Theme): boolean => typeof (theme as { renderRecipe?: unknown }).renderRecipe === \"function\";\n\nexport async function runDiff(options: DiffCommandOptions): Promise<DiffCommandResult> {\n const cwd = options.cwd ?? process.cwd();\n const { config, path: configPath } = await loadConfig({ cwd, configPath: options.configPath });\n const candidatePath = resolve(cwd, options.candidatePath);\n const candidateRaw = await loadCandidate(candidatePath);\n const buildOpts = { units: config.units, baseFontSize: config.baseFontSize, media: config.media };\n\n const adapters: Array<{ name: string; adapter: ThemeAdapter }> = config.targets.map((t, i) => ({\n name: t.name ?? t.outDir ?? `target-${i}`,\n adapter: t.adapter,\n }));\n\n // Per-target: does the candidate still build? (a \"targets now fail\" signal for CI).\n const targets: TargetStatus[] = adapters.map(({ name, adapter }) => {\n try {\n createTheme(candidateRaw, { adapter, ...buildOpts });\n return { name, ok: true, errors: [] };\n } catch (e) {\n const err = e as { failures?: readonly string[]; message?: string };\n return { name, ok: false, errors: err.failures ? [...err.failures] : [err.message ?? String(e)] };\n }\n });\n\n // Choose the adapter to diff through: a class-emitting target if any, else the first target, else noop.\n const pick =\n adapters.find(({ adapter }) => emitsClasses(createTheme(config.raw, { adapter, ...buildOpts }))) ??\n adapters[0] ?? { name: \"noop\", adapter: createNoopAdapter() };\n const base = createTheme(config.raw, { adapter: pick.adapter, ...buildOpts });\n // The candidate may not build (that's a real, reportable outcome — see `targets`). When it doesn't,\n // there's nothing to diff; return the empty diff and let the target-failure violation carry the news.\n const EMPTY_DIFF: ThemeDiff = { tokens: [], classes: [], contrast: [], summary: { tokensChanged: 0, classesChanged: 0, pairingsCrossed: 0 } };\n let diff = EMPTY_DIFF;\n try {\n diff = diffThemes(base, createTheme(candidateRaw, { adapter: pick.adapter, ...buildOpts }));\n } catch {\n /* candidate doesn't build — captured in `targets` below */\n }\n\n // CI-gate evaluation.\n const violations: string[] = [];\n if (options.maxClassChanges !== undefined && diff.summary.classesChanged > options.maxClassChanges) {\n violations.push(`${diff.summary.classesChanged} classes changed (max ${options.maxClassChanges})`);\n }\n if (options.maxTokenChanges !== undefined && diff.summary.tokensChanged > options.maxTokenChanges) {\n violations.push(`${diff.summary.tokensChanged} tokens changed (max ${options.maxTokenChanges})`);\n }\n if (options.failBelow) {\n const bar = WCAG_RANK[options.failBelow] ?? 0;\n for (const c of diff.contrast) {\n const afterRank = c.after?.level ? (WCAG_RANK[c.after.level] ?? 0) : 0;\n const beforeRank = c.before?.level ? (WCAG_RANK[c.before.level] ?? 0) : 0;\n if (c.after && afterRank < bar && afterRank < beforeRank) {\n violations.push(`${c.label} drops to ${c.after.level} (below ${options.failBelow})`);\n }\n }\n }\n const failedTargets = targets.filter((t) => !t.ok).map((t) => t.name);\n if (failedTargets.length) violations.push(`candidate no longer builds for: ${failedTargets.join(\", \")}`);\n\n return { configPath, candidatePath, diff, targets, ok: violations.length === 0, violations };\n}\n","/**\n * Fail-loud shape guard for a value that is *supposed* to be a {@link RawTheme}.\n *\n * `createTheme` accepts a bare object, and an empty `{}` is a valid (empty) theme — so a value of the\n * *wrong* shape doesn't necessarily throw during a build. That's the trap `refract diff` fell into: hand\n * it a `defineConfig({ raw, targets })` where it wanted the raw theme and it built the config as an\n * (effectively empty) theme, then reported a nonsense \"every token removed\" diff and exited 0. A\n * governance tool must not quietly mis-report. This guard is the loud, coded gate for that class of\n * mistake — used by `diff` (and available to `validate` / the MCP server) before anything is compared.\n *\n * It is deliberately narrow: it rejects only values that cannot be a RawTheme (non-objects, arrays,\n * `null`) or that are affirmatively something else (a `defineConfig`, spotted by its `targets` array).\n * A bare `{}` still passes — an empty theme is legitimately empty.\n */\nimport { RefractError } from \"./errors\";\nimport type { RawTheme } from \"./rawTheme\";\n\nexport function assertRawTheme(value: unknown, source?: string): asserts value is RawTheme {\n const at = source ? ` (${source})` : \"\";\n\n if (value === null || typeof value !== \"object\" || Array.isArray(value)) {\n const got = Array.isArray(value) ? \"an array\" : value === null ? \"null\" : typeof value;\n throw new RefractError(\n \"REFRACT_E_RAW_SHAPE\",\n `Expected a RawTheme object${at}, got ${got}. Pass the raw theme (a module's default export, or a .json raw theme).`,\n );\n }\n\n // The documented mistake: a defineConfig({ raw, targets }) passed where the bare RawTheme was wanted.\n // A RawTheme never has a top-level `targets`; a config always does.\n if (Array.isArray((value as { targets?: unknown }).targets)) {\n throw new RefractError(\n \"REFRACT_E_RAW_SHAPE\",\n `Expected a RawTheme object${at}, but got what looks like a defineConfig({ raw, targets }). Pass its \\`raw\\` (or a module that default-exports the raw theme), not the whole config.`,\n );\n }\n}\n","/**\n * `refract skills` — install the bundled AI skills into a project's agent CLI(s) (Node-only).\n *\n * The canonical skill sources ship *inside this package* (`skills/<name>/SKILL.md`, added to\n * `package.json#files`), so `node_modules/@theme-registry/refract/skills/` is the version-locked\n * source of truth — upgrade refract, re-run `skills update`, and the skills match the installed API.\n *\n * One source, many agent formats (the same one-model-many-adapters idea refract is built on):\n * - **claude** natively loads `.claude/skills/<name>/SKILL.md`, so we copy each file verbatim.\n * - Every other agent (codex, opencode, github-copilot, cursor, generic) loads a flat instructions\n * file on *every* request, so inlining a dozen skill bodies would bloat each turn. Instead we\n * write a small **router** into that agent's instructions file (a table pointing at\n * `.refract/skills/<name>.md`) and drop the full bodies as on-demand files — reconstructing\n * Claude's progressive disclosure manually.\n *\n * The command implementations return data (`runSkillsInstall`/`List`/`Update`), so tests drive them\n * directly; the CLI wrapper (`cli.ts`) maps argv + interactive prompts onto them.\n */\nimport { existsSync, mkdirSync, readFileSync, readdirSync, writeFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\nimport { findPackageRoot } from \"./paths\";\n\nexport type SkillTier = \"core\" | \"optional\";\n\n/** One skill's parsed metadata + content. */\nexport interface SkillMeta {\n readonly name: string;\n readonly description: string;\n readonly tier: SkillTier;\n /** The full file (frontmatter + body) — what the claude target copies verbatim. */\n readonly raw: string;\n /** The markdown body after the frontmatter — what the agents-md targets drop as an on-demand file. */\n readonly body: string;\n readonly sourcePath: string;\n}\n\nexport type AgentTarget = \"claude\" | \"codex\" | \"opencode\" | \"github-copilot\" | \"cursor\" | \"generic\";\nexport type InstallScope = \"local\" | \"global\";\n\nexport const AGENT_TARGETS: readonly AgentTarget[] = [\n \"claude\",\n \"codex\",\n \"opencode\",\n \"github-copilot\",\n \"cursor\",\n \"generic\",\n];\n\n/**\n * How each agent consumes skills. `claude` gets native per-skill directories; every other agent\n * shares the \"agents-md\" shape (a router in its instructions file + on-demand body files), differing\n * only in *which* file it reads. Adding a bespoke per-agent adapter later means one more entry here.\n */\nconst AGENT_ROUTER: Record<AgentTarget, { kind: \"claude\" | \"agents-md\"; routerFile: string }> = {\n claude: { kind: \"claude\", routerFile: \".claude/skills\" },\n codex: { kind: \"agents-md\", routerFile: \"AGENTS.md\" },\n opencode: { kind: \"agents-md\", routerFile: \"AGENTS.md\" },\n \"github-copilot\": { kind: \"agents-md\", routerFile: \".github/copilot-instructions.md\" },\n cursor: { kind: \"agents-md\", routerFile: \".cursor/rules/refract-skills.mdc\" },\n generic: { kind: \"agents-md\", routerFile: \"AGENTS.md\" },\n};\n\nconst ROUTER_START = \"<!-- refract-skills:start -->\";\nconst ROUTER_END = \"<!-- refract-skills:end -->\";\nconst MANIFEST_REL = join(\".refract\", \"skills.lock\");\nconst BODY_DIR_REL = join(\".refract\", \"skills\");\n\n/** Locate the bundled catalog. Defaults to `<packageRoot>/skills` (ships via package.json#files). */\nexport function skillsCatalogDir(override?: string): string {\n return override ?? join(findPackageRoot(), \"skills\");\n}\n\n/** Read this package's `name` + `version` (recorded in the manifest so `update` matches the API). */\nfunction readOwnPackageMeta(): { name: string; version: string } {\n const pkg = JSON.parse(readFileSync(join(findPackageRoot(), \"package.json\"), \"utf8\")) as {\n name?: string;\n version?: string;\n };\n return { name: pkg.name ?? \"@theme-registry/refract\", version: pkg.version ?? \"0.0.0\" };\n}\n\n/** Parse the leading `--- … ---` frontmatter for the fields we need; body is everything after. */\nfunction parseSkillFile(raw: string, sourcePath: string): SkillMeta {\n const match = /^---\\r?\\n([\\s\\S]*?)\\r?\\n---\\r?\\n?/.exec(raw);\n const front = match ? match[1] : \"\";\n const body = match ? raw.slice(match[0].length).replace(/^\\s+/, \"\") : raw;\n const field = (key: string): string | undefined => {\n const line = new RegExp(`^${key}:\\\\s*(.*)$`, \"m\").exec(front);\n return line ? line[1].trim() : undefined;\n };\n const name = field(\"name\") ?? dirname(sourcePath).split(/[\\\\/]/).pop() ?? \"unnamed\";\n const tier = field(\"tier\") === \"optional\" ? \"optional\" : \"core\";\n return { name, description: field(\"description\") ?? \"\", tier, raw, body, sourcePath };\n}\n\n/** Read every `<catalog>/<name>/SKILL.md`, sorted by name. */\nexport function listSkills(catalogDir?: string): SkillMeta[] {\n const dir = skillsCatalogDir(catalogDir);\n if (!existsSync(dir)) {\n throw new Error(`Skills catalog not found at \"${dir}\". Reinstall @theme-registry/refract.`);\n }\n return readdirSync(dir, { withFileTypes: true })\n .filter(entry => entry.isDirectory())\n .map(entry => join(dir, entry.name, \"SKILL.md\"))\n .filter(existsSync)\n .map(path => parseSkillFile(readFileSync(path, \"utf8\"), path))\n .sort((a, b) => a.name.localeCompare(b.name));\n}\n\n/** The one-line \"use it for\" cell — the description up to (but not including) its `Triggers:` list. */\nfunction shortDescription(skill: SkillMeta): string {\n const beforeTriggers = skill.description.split(/\\s*Triggers:/)[0].trim();\n const firstSentence = beforeTriggers.split(/\\.\\s/)[0].trim();\n return (firstSentence || beforeTriggers).replace(/\\|/g, \"\\\\|\");\n}\n\n/** Render the shared router block (identical content for every agents-md target). */\nfunction renderRouter(skills: SkillMeta[]): string {\n const rows = skills\n .map(s => `| [${s.name}](${BODY_DIR_REL}/${s.name}.md) | ${shortDescription(s)} |`)\n .join(\"\\n\");\n return [\n ROUTER_START,\n \"\",\n \"## refract theme skills\",\n \"\",\n \"These skills document the [refract](https://github.com/theme-registry/refract) theme toolkit.\",\n \"When a task matches a row below, read the linked file before working.\",\n \"\",\n \"| Skill | Use it for |\",\n \"| --- | --- |\",\n rows,\n \"\",\n ROUTER_END,\n ].join(\"\\n\");\n}\n\n/** Insert or replace the marked router block in an existing instructions file (idempotent). */\nfunction upsertRouterBlock(existing: string, block: string): string {\n const start = existing.indexOf(ROUTER_START);\n const end = existing.indexOf(ROUTER_END);\n if (start !== -1 && end !== -1 && end > start) {\n return existing.slice(0, start) + block + existing.slice(end + ROUTER_END.length);\n }\n const trimmed = existing.replace(/\\s+$/, \"\");\n return trimmed ? `${trimmed}\\n\\n${block}\\n` : `${block}\\n`;\n}\n\nfunction writeFileEnsuring(path: string, content: string): void {\n mkdirSync(dirname(path), { recursive: true });\n writeFileSync(path, content, \"utf8\");\n}\n\nexport interface SkillsInstallOptions {\n readonly agents: readonly AgentTarget[];\n /** `local` (default) writes into the project; `global` into the user's home dir. */\n readonly scope?: InstallScope;\n /** Explicit skill names to install. Omit to install all `core` skills (+ optional if `includeOptional`). */\n readonly skills?: readonly string[];\n /** When `skills` is omitted, also install `optional`-tier skills. Default `false`. */\n readonly includeOptional?: boolean;\n /** Project dir for `local` scope (default `process.cwd()`). */\n readonly cwd?: string;\n /** Home dir for `global` scope (default `os.homedir()`); injectable for tests. */\n readonly home?: string;\n /** Override the bundled catalog dir (tests). */\n readonly catalogDir?: string;\n}\n\nexport interface SkillsInstallResult {\n readonly scope: InstallScope;\n readonly agents: readonly AgentTarget[];\n readonly skills: readonly string[];\n readonly files: readonly string[];\n readonly manifestPath: string;\n}\n\ninterface SkillsManifest {\n readonly schema: 1;\n readonly packageName: string;\n readonly refractVersion: string;\n readonly scope: InstallScope;\n readonly agents: readonly AgentTarget[];\n readonly skills: readonly string[];\n}\n\n/** Resolve the selection from options: explicit names, or all core (+ optional). */\nfunction selectSkills(catalog: SkillMeta[], options: SkillsInstallOptions): SkillMeta[] {\n if (options.skills && options.skills.length > 0) {\n const byName = new Map(catalog.map(s => [s.name, s]));\n const chosen: SkillMeta[] = [];\n for (const name of options.skills) {\n const skill = byName.get(name);\n if (!skill) {\n throw new Error(\n `Unknown skill \"${name}\". Available: ${catalog.map(s => s.name).join(\", \")}.`,\n );\n }\n chosen.push(skill);\n }\n return chosen;\n }\n return catalog.filter(s => s.tier === \"core\" || options.includeOptional);\n}\n\n/**\n * Install (or re-sync) the selected skills for the selected agents. Pure w.r.t. its options — the CLI\n * layer handles prompting; this does the filesystem work and returns what it wrote.\n */\nexport function runSkillsInstall(options: SkillsInstallOptions): SkillsInstallResult {\n const scope: InstallScope = options.scope ?? \"local\";\n const base = scope === \"global\" ? (options.home ?? homedir()) : (options.cwd ?? process.cwd());\n const catalog = listSkills(options.catalogDir);\n const selected = selectSkills(catalog, options);\n if (options.agents.length === 0) throw new Error(\"Pick at least one agent target.\");\n\n const files = new Set<string>();\n const needsAgentsMd = options.agents.some(a => AGENT_ROUTER[a].kind === \"agents-md\");\n\n // Shared on-demand body files (written once, referenced by every agents-md router).\n if (needsAgentsMd) {\n for (const skill of selected) {\n const path = join(base, BODY_DIR_REL, `${skill.name}.md`);\n writeFileEnsuring(path, skill.body);\n files.add(path);\n }\n }\n\n for (const agent of options.agents) {\n const target = AGENT_ROUTER[agent];\n if (target.kind === \"claude\") {\n // Native: one directory per skill, the file copied verbatim.\n for (const skill of selected) {\n const path = join(base, target.routerFile, skill.name, \"SKILL.md\");\n writeFileEnsuring(path, skill.raw);\n files.add(path);\n }\n } else {\n // Router into this agent's instructions file (idempotent via the marker block).\n const routerPath = join(base, target.routerFile);\n const existing = existsSync(routerPath) ? readFileSync(routerPath, \"utf8\") : \"\";\n writeFileEnsuring(routerPath, upsertRouterBlock(existing, renderRouter(selected)));\n files.add(routerPath);\n }\n }\n\n const { name: packageName, version: refractVersion } = readOwnPackageMeta();\n const manifest: SkillsManifest = {\n schema: 1,\n packageName,\n refractVersion,\n scope,\n agents: [...options.agents],\n skills: selected.map(s => s.name),\n };\n const manifestPath = join(base, MANIFEST_REL);\n writeFileEnsuring(manifestPath, `${JSON.stringify(manifest, null, 2)}\\n`);\n\n return {\n scope,\n agents: [...options.agents],\n skills: selected.map(s => s.name),\n files: [...files].sort(),\n manifestPath,\n };\n}\n\n/** Re-sync a prior install from its `.refract/skills.lock` (upgrades the skill bodies to this version). */\nexport function runSkillsUpdate(\n options: { scope?: InstallScope; cwd?: string; home?: string; catalogDir?: string } = {},\n): SkillsInstallResult {\n const scope: InstallScope = options.scope ?? \"local\";\n const base = scope === \"global\" ? (options.home ?? homedir()) : (options.cwd ?? process.cwd());\n const manifestPath = join(base, MANIFEST_REL);\n if (!existsSync(manifestPath)) {\n throw new Error(\n `No skills manifest at \"${manifestPath}\". Run \\`refract skills install\\` first.`,\n );\n }\n const manifest = JSON.parse(readFileSync(manifestPath, \"utf8\")) as SkillsManifest;\n return runSkillsInstall({\n agents: manifest.agents,\n scope,\n skills: manifest.skills,\n cwd: options.cwd,\n home: options.home,\n catalogDir: options.catalogDir,\n });\n}\n","/**\n * `refract` CLI (Node-only, §7 Step 10c) — a thin subcommand dispatcher over the build layer.\n *\n * Arg parsing is hand-wired on `node:util`'s `parseArgs` (no new dep). Commands:\n * - `init` — scaffold a runnable `theme.config.(ts|js|mjs)` (`--js`/`--mjs`/`--force`).\n * - `import` — seed a `theme.raw.ts` (+ config) from a DTCG `tokens.json` (`--out`/`--raw-only`/…).\n * - `build` — load the config → `emitTheme` per target (`--config`/`--out`/`--target`).\n * - `tokens` — DTCG export (`toDTCG` → `tokens.json`); adapter-free, reads only the config's `raw`.\n *\n * The command implementations (`runInit`/`runImport`/`runBuild`/`runTokens`) live in their own modules and\n * return data, so the gate test drives them directly; this file only maps argv → those calls + prints\n * summaries. It imports zero adapters — the config's own `import` is the adapter seam (10b).\n */\nimport { createInterface } from \"node:readline/promises\";\nimport { parseArgs } from \"node:util\";\nimport { runBuild } from \"./buildCommand\";\nimport { runImport, parseBreakpointsFlag } from \"./importCommand\";\nimport { runInit, type ConfigVariant } from \"./init\";\nimport {\n AGENT_TARGETS,\n listSkills,\n runSkillsInstall,\n runSkillsUpdate,\n type AgentTarget,\n type InstallScope,\n} from \"./skillsCommand\";\nimport { runTokens } from \"./tokensCommand\";\nimport { runAudit } from \"./auditCommand\";\nimport { runDiff } from \"./diffCommand\";\nimport { runCreate } from \"./createCommand\";\nimport { createReportLines, promptCreateAnswers } from \"./createInterview\";\nimport { Prompter, bold, dim } from \"./prompt\";\nimport { createTheme } from \"../core/createTheme\";\nimport { createNoopAdapter } from \"../core/noopAdapter\";\nimport type { RawTheme } from \"../core\";\nimport type { WcagLevel } from \"../subsystems/colors/audit\";\n\nconst HELP = `refract — build a refract theme to disk.\n\nUsage:\n refract create [--seed <color>] [--colors <n|list>] [--scheme <name>] [--manual]\n [--feel <neutral|compact|editorial|technical>] [--ratio <name>]\n [--base-size <px>] [--contrast <AA|AAA|none>] [--reset <name>]\n [--format <ts|js|json>] [--out <file>] [--no-semantics]\n [--no-neutral] [--no-shadows] [--yes] [--force]\n refract init [--js | --mjs] [--force]\n refract import <tokens.json> [--out <file>] [--raw-only] [--force]\n [--breakpoint-group <name>] [--breakpoints <n:px,…>]\n refract build [--config <path>] [--target <name|index>] [--out <dir>]\n refract tokens [--config <path>] [--out <file>]\n refract diff <candidate> [--config <path>] [--max-class-changes <n>]\n [--max-token-changes <n>] [--fail-below <AA|AAA|AA-large>]\n refract audit [--config <path>] [--strict] [--min-wcag <AA|AAA|AA-large>] [--large]\n refract skills <install|list|update> [--agent <a,b|all>] [--global|--local]\n [--only <names>] [--optional]\n refract help\n\nCommands:\n create Design a theme.raw.(ts|js|json) from one seed colour and a short interview.\n init Scaffold a runnable theme.config.(ts|js|mjs) in the current directory.\n import Seed a theme.raw.ts (+ theme.config.ts) from a DTCG tokens.json (one-shot).\n build Load the config and emit every target's files to its outDir.\n tokens Export the theme's tokens as a DTCG tokens.json (adapter-free).\n diff Show a candidate theme's blast radius vs the config (tokens/classes/contrast); thresholds gate CI.\n audit Score colour pairings for WCAG-2 contrast (+ advisory APCA). Reports; --strict fails.\n skills Install the bundled AI skills into your agent CLI(s) (claude/codex/…).\n`;\n\n/**\n * Uniform error reporter for a command's catch block. Surfaces a `RefractError`'s stable `code`\n * (`[REFRACT_E_…] message`) so an agent or CI log sees the machine-readable code, and lists each\n * collect-all `failure` — a plain `Error` just prints its message. Returns the exit code (1).\n */\nfunction reportError(cmd: string, err: unknown): number {\n const e = err as { code?: string; message?: string; failures?: readonly string[] };\n const code = typeof e.code === \"string\" && e.code.startsWith(\"REFRACT_E_\") ? `[${e.code}] ` : \"\";\n process.stderr.write(`refract ${cmd}: ${code}${e.message ?? String(err)}\\n`);\n if (e.failures) for (const f of e.failures) process.stderr.write(` - ${f}\\n`);\n return 1;\n}\n\nasync function cmdInit(argv: string[]): Promise<number> {\n const { values } = parseArgs({\n args: argv,\n options: {\n js: { type: \"boolean\", default: false },\n mjs: { type: \"boolean\", default: false },\n force: { type: \"boolean\", default: false },\n },\n allowPositionals: false,\n });\n\n if (values.js && values.mjs) {\n process.stderr.write(\"refract init: pass at most one of --js / --mjs.\\n\");\n return 1;\n }\n const variant: ConfigVariant = values.mjs ? \"mjs\" : values.js ? \"js\" : \"ts\";\n\n try {\n const result = runInit({ variant, force: Boolean(values.force) });\n if (result.rawTheme) {\n process.stdout.write(`Found ${result.rawTheme.filename} — wired it up.\\n`);\n }\n process.stdout.write(`Created ${result.path}\\n`);\n process.stdout.write(\n result.rawTheme\n ? `Next: run \\`refract build\\`.\\n`\n : `Next: edit the starter theme in the config (or run \\`refract create\\` to design one), then \\`refract build\\`.\\n`,\n );\n return 0;\n } catch (err) {\n return reportError(\"init\", err);\n }\n}\n\n/**\n * `refract create` — the guided raw-theme scaffolder.\n *\n * Flags only here: the question flow lives in `createInterview.ts` so `create-refract-theme` runs\n * the identical script, and the generation lives in `scaffold.ts`. Every prompt has a flag and every\n * flag has a default, so this command is fully scriptable (`--yes`) and never blocks in CI.\n */\nasync function cmdCreate(argv: string[]): Promise<number> {\n const { values } = parseArgs({\n args: argv,\n options: {\n seed: { type: \"string\" },\n colors: { type: \"string\" },\n scheme: { type: \"string\" },\n manual: { type: \"boolean\", default: false },\n feel: { type: \"string\" },\n ratio: { type: \"string\" },\n \"base-size\": { type: \"string\" },\n contrast: { type: \"string\" },\n reset: { type: \"string\" },\n format: { type: \"string\" },\n out: { type: \"string\" },\n \"no-semantics\": { type: \"boolean\", default: false },\n \"no-neutral\": { type: \"boolean\", default: false },\n \"no-shadows\": { type: \"boolean\", default: false },\n yes: { type: \"boolean\", default: false },\n force: { type: \"boolean\", default: false },\n },\n allowPositionals: false,\n });\n\n const p = new Prompter(values.yes ? false : undefined);\n try {\n p.write();\n p.write(` ${bold(\"refract\")} ${dim(\"· raw-theme scaffold\")}`);\n p.write();\n\n const answers = await promptCreateAnswers(p, {\n seed: values.seed,\n colors: values.colors,\n scheme: values.scheme,\n manual: values.manual,\n feel: values.feel,\n ratio: values.ratio,\n baseSize: values[\"base-size\"],\n contrast: values.contrast,\n reset: values.reset,\n format: values.format,\n noSemantics: values[\"no-semantics\"],\n noNeutral: values[\"no-neutral\"],\n noShadows: values[\"no-shadows\"],\n });\n\n const result = runCreate({ ...answers, out: values.out, force: Boolean(values.force) });\n\n p.write();\n for (const line of createReportLines(result, countVariables(result.raw))) p.write(line);\n p.write();\n p.write(` ${bold(result.path.split(/[\\\\/]/).pop() ?? \"\")} written`);\n p.write();\n p.write(` ${dim(\"Next — wire up a build:\")} ${bold(\"refract init\")}`);\n p.write();\n return 0;\n } catch (err) {\n return reportError(\"create\", err);\n } finally {\n p.close();\n }\n}\n\n/** Compile the generated theme with the null adapter purely to count what it emits, for the report. */\nfunction countVariables(raw: RawTheme): number {\n try {\n const theme = createTheme(raw, { adapter: createNoopAdapter() });\n return Object.keys(theme.tokens as Record<string, unknown>).length;\n } catch {\n return 0;\n }\n}\n\n\nasync function cmdImport(argv: string[]): Promise<number> {\n const { values, positionals } = parseArgs({\n args: argv,\n options: {\n out: { type: \"string\" },\n \"raw-only\": { type: \"boolean\", default: false },\n force: { type: \"boolean\", default: false },\n \"breakpoint-group\": { type: \"string\" },\n breakpoints: { type: \"string\" },\n },\n allowPositionals: true,\n });\n\n const input = positionals[0];\n if (!input) {\n process.stderr.write(\"refract import: pass the DTCG document to import, e.g. `refract import tokens.json`.\\n\");\n return 1;\n }\n if (positionals.length > 1) {\n process.stderr.write(`refract import: unexpected extra argument \"${positionals[1]}\".\\n`);\n return 1;\n }\n\n try {\n const result = runImport({\n input,\n out: values.out,\n rawOnly: Boolean(values[\"raw-only\"]),\n force: Boolean(values.force),\n breakpointGroup: values[\"breakpoint-group\"],\n breakpoints: values.breakpoints ? parseBreakpointsFlag(values.breakpoints) : undefined,\n });\n process.stdout.write(`Imported ${result.inputFile}\\n`);\n process.stdout.write(` raw → ${result.rawFile}\\n`);\n if (result.configFile) process.stdout.write(` config → ${result.configFile}\\n`);\n const seeded = Object.entries(result.counts).map(([k, n]) => `${k} (${n})`).join(\", \");\n if (seeded) process.stdout.write(` seeded: ${seeded}\\n`);\n process.stdout.write(`Next: review the inferred tokens, then add recipes/components and run \\`refract build\\`.\\n`);\n return 0;\n } catch (err) {\n return reportError(\"import\", err);\n }\n}\n\nasync function cmdBuild(argv: string[]): Promise<number> {\n const { values } = parseArgs({\n args: argv,\n options: {\n config: { type: \"string\" },\n target: { type: \"string\" },\n out: { type: \"string\" },\n },\n allowPositionals: false,\n });\n\n try {\n const result = await runBuild({\n configPath: values.config,\n target: values.target,\n out: values.out,\n });\n process.stdout.write(`Built from ${result.configPath}\\n`);\n for (const t of result.targets) {\n const label = t.name ? `${t.name} [${t.adapter}]` : t.adapter;\n process.stdout.write(` ${label} → ${t.outDir} (${t.files.length} file(s))\\n`);\n for (const f of t.files) process.stdout.write(` ${f}\\n`);\n }\n return 0;\n } catch (err) {\n return reportError(\"build\", err);\n }\n}\n\nasync function cmdTokens(argv: string[]): Promise<number> {\n const { values } = parseArgs({\n args: argv,\n options: {\n config: { type: \"string\" },\n out: { type: \"string\" },\n },\n allowPositionals: false,\n });\n\n try {\n const result = await runTokens({\n configPath: values.config,\n out: values.out,\n });\n process.stdout.write(`Exported tokens from ${result.configPath}\\n`);\n process.stdout.write(` ${result.groupCount} group(s) → ${result.outFile}\\n`);\n return 0;\n } catch (err) {\n return reportError(\"tokens\", err);\n }\n}\n\nconst WCAG_LEVELS: ReadonlySet<string> = new Set([\"AAA\", \"AA\", \"AA-large\"]);\n\nasync function cmdDiff(argv: string[]): Promise<number> {\n const { values, positionals } = parseArgs({\n args: argv,\n options: {\n config: { type: \"string\" },\n \"max-class-changes\": { type: \"string\" },\n \"max-token-changes\": { type: \"string\" },\n \"fail-below\": { type: \"string\" },\n },\n allowPositionals: true,\n });\n\n const candidate = positionals[0];\n if (!candidate) {\n process.stderr.write(\"refract diff: pass the candidate theme, e.g. `refract diff candidate.ts`.\\n\");\n return 1;\n }\n const failBelow = values[\"fail-below\"];\n if (failBelow !== undefined && !WCAG_LEVELS.has(failBelow)) {\n process.stderr.write(`refract diff: --fail-below must be one of AAA | AA | AA-large (got \"${failBelow}\").\\n`);\n return 1;\n }\n\n try {\n const result = await runDiff({\n configPath: values.config,\n candidatePath: candidate,\n maxClassChanges: values[\"max-class-changes\"] !== undefined ? Number(values[\"max-class-changes\"]) : undefined,\n maxTokenChanges: values[\"max-token-changes\"] !== undefined ? Number(values[\"max-token-changes\"]) : undefined,\n failBelow,\n });\n const { diff } = result;\n process.stdout.write(`Diffed ${result.candidatePath}\\n vs ${result.configPath}\\n`);\n process.stdout.write(\n ` ${diff.summary.tokensChanged} token(s), ${diff.summary.classesChanged} class(es), ${diff.summary.pairingsCrossed} pairing(s) crossed a threshold\\n`,\n );\n for (const t of diff.tokens.slice(0, 20)) {\n const arrow = t.kind === \"changed\" ? `${t.before} → ${t.after}` : t.kind === \"added\" ? `+ ${t.after}` : `- ${t.before}`;\n process.stdout.write(` token ${t.path}: ${arrow}\\n`);\n }\n if (diff.tokens.length > 20) process.stdout.write(` … +${diff.tokens.length - 20} more token(s)\\n`);\n for (const c of diff.classes) process.stdout.write(` class ${c.kind.padEnd(7)} ${c.name}\\n`);\n for (const c of diff.contrast.filter((x) => x.crossed)) {\n process.stdout.write(` contrast ${c.label}: ${c.before?.level ?? \"—\"} → ${c.after?.level ?? \"—\"}\\n`);\n }\n if (result.violations.length) {\n process.stderr.write(`✗ diff gate failed:\\n`);\n for (const v of result.violations) process.stderr.write(` ${v}\\n`);\n return 1;\n }\n return 0;\n } catch (err) {\n return reportError(\"diff\", err);\n }\n}\n\nasync function cmdAudit(argv: string[]): Promise<number> {\n const { values } = parseArgs({\n args: argv,\n options: {\n config: { type: \"string\" },\n strict: { type: \"boolean\", default: false },\n \"min-wcag\": { type: \"string\" },\n large: { type: \"boolean\", default: false },\n },\n allowPositionals: false,\n });\n\n const minWcag = values[\"min-wcag\"];\n if (minWcag !== undefined && !WCAG_LEVELS.has(minWcag)) {\n process.stderr.write(`refract audit: --min-wcag must be one of AAA | AA | AA-large (got \"${minWcag}\").\\n`);\n return 1;\n }\n\n try {\n const { configPath, result } = await runAudit({\n configPath: values.config,\n strict: values.strict,\n minWcag: minWcag as WcagLevel | undefined,\n largeText: values.large,\n });\n process.stdout.write(`Audited ${configPath}\\n`);\n for (const p of result.pairings) {\n if (p.skipped) {\n process.stdout.write(` ~ ${p.label} — skipped (${p.skipped})\\n`);\n } else {\n const flag = p.pass ? \"✓\" : \"✗\";\n process.stdout.write(` ${flag} ${p.label} — ${p.wcagRatio}:1 ${p.wcagLevel} · APCA Lc ${p.apcaLc}\\n`);\n }\n }\n const s = result.summary;\n process.stdout.write(`${s.passed}/${s.total} pass, ${s.failed} fail, ${s.skipped} skipped\\n`);\n // Report mode: a failing audit is not a CLI error (exit 0). --strict makes `runAudit` throw first.\n return 0;\n } catch (err) {\n return reportError(\"audit\", err);\n }\n}\n\n/** Parse an `--agent` value (`\"all\"` or a comma list) into validated targets. */\nfunction parseAgents(raw: string): AgentTarget[] {\n if (raw.trim() === \"all\") return [...AGENT_TARGETS];\n const names = raw.split(\",\").map(s => s.trim()).filter(Boolean);\n const bad = names.filter(n => !AGENT_TARGETS.includes(n as AgentTarget));\n if (bad.length > 0) {\n throw new Error(\n `unknown agent(s) ${bad.map(b => `\"${b}\"`).join(\", \")}. Known: ${AGENT_TARGETS.join(\", \")}.`,\n );\n }\n return names as AgentTarget[];\n}\n\n/** Interactively gather install options when none were passed and a TTY is attached. */\nasync function promptSkillsInstall(): Promise<{\n agents: AgentTarget[];\n scope: InstallScope;\n includeOptional: boolean;\n}> {\n const rl = createInterface({ input: process.stdin, output: process.stdout });\n try {\n process.stdout.write(\"Install refract skills for which agent(s)?\\n\");\n AGENT_TARGETS.forEach((a, i) => process.stdout.write(` ${i + 1}) ${a}\\n`));\n const pick = await rl.question(\"Enter numbers (comma-separated), or 'all': \");\n const agents =\n pick.trim() === \"all\" || pick.trim() === \"\"\n ? [...AGENT_TARGETS]\n : pick\n .split(\",\")\n .map(s => AGENT_TARGETS[Number(s.trim()) - 1])\n .filter((a): a is AgentTarget => Boolean(a));\n if (agents.length === 0) throw new Error(\"no agents selected.\");\n\n const scopeAns = (await rl.question(\"Scope — [l]ocal (project) or [g]lobal (home)? [l]: \"))\n .trim()\n .toLowerCase();\n const scope: InstallScope = scopeAns.startsWith(\"g\") ? \"global\" : \"local\";\n\n const optAns = (await rl.question(\"Include optional skills (adapter-scaffold, troubleshooting)? [y/N]: \"))\n .trim()\n .toLowerCase();\n return { agents, scope, includeOptional: optAns.startsWith(\"y\") };\n } finally {\n rl.close();\n }\n}\n\nasync function cmdSkills(argv: string[]): Promise<number> {\n const [sub, ...rest] = argv;\n\n if (sub === \"list\") {\n try {\n for (const s of listSkills()) {\n process.stdout.write(` ${s.name.padEnd(26)} [${s.tier}] ${s.description.split(/\\s*Triggers:/)[0].trim().slice(0, 80)}\\n`);\n }\n return 0;\n } catch (err) {\n return reportError(\"skills list\", err);\n }\n }\n\n const { values } = parseArgs({\n args: rest,\n options: {\n agent: { type: \"string\" },\n global: { type: \"boolean\", default: false },\n local: { type: \"boolean\", default: false },\n only: { type: \"string\" },\n optional: { type: \"boolean\", default: false },\n },\n allowPositionals: false,\n });\n\n if (values.global && values.local) {\n process.stderr.write(\"refract skills: pass at most one of --global / --local.\\n\");\n return 1;\n }\n const scope: InstallScope = values.global ? \"global\" : \"local\";\n\n try {\n if (sub === \"update\") {\n const result = runSkillsUpdate({ scope });\n process.stdout.write(`Updated ${result.skills.length} skill(s) for ${result.agents.join(\", \")} (${result.scope}).\\n`);\n return 0;\n }\n\n if (sub === \"install\" || sub === undefined) {\n let agents: AgentTarget[];\n let includeOptional = Boolean(values.optional);\n let installScope = scope;\n\n if (values.agent) {\n agents = parseAgents(values.agent);\n } else if (process.stdin.isTTY) {\n const answers = await promptSkillsInstall();\n agents = answers.agents;\n includeOptional = answers.includeOptional;\n if (!values.global && !values.local) installScope = answers.scope;\n } else {\n process.stderr.write(\"refract skills install: pass --agent <a,b|all> (no TTY for prompts).\\n\");\n return 1;\n }\n\n const result = runSkillsInstall({\n agents,\n scope: installScope,\n skills: values.only ? values.only.split(\",\").map(s => s.trim()).filter(Boolean) : undefined,\n includeOptional,\n });\n process.stdout.write(\n `Installed ${result.skills.length} skill(s) for ${result.agents.join(\", \")} (${result.scope}):\\n`,\n );\n for (const f of result.files) process.stdout.write(` ${f}\\n`);\n process.stdout.write(` manifest → ${result.manifestPath}\\n`);\n return 0;\n }\n\n process.stderr.write(`refract skills: unknown subcommand \"${sub}\". Use install | list | update.\\n`);\n return 1;\n } catch (err) {\n return reportError(\"skills\", err);\n }\n}\n\n/** Dispatch a parsed argv (without the node/script prefix). Returns a process exit code. */\nexport async function main(argv: string[]): Promise<number> {\n const [command, ...rest] = argv;\n switch (command) {\n case \"create\":\n return cmdCreate(rest);\n case \"init\":\n return cmdInit(rest);\n case \"import\":\n return cmdImport(rest);\n case \"build\":\n return cmdBuild(rest);\n case \"tokens\":\n return cmdTokens(rest);\n case \"diff\":\n return cmdDiff(rest);\n case \"audit\":\n return cmdAudit(rest);\n case \"skills\":\n return cmdSkills(rest);\n case undefined:\n case \"help\":\n case \"--help\":\n case \"-h\":\n process.stdout.write(HELP);\n return 0;\n default:\n process.stderr.write(`refract: unknown command \"${command}\".\\n\\n${HELP}`);\n return 1;\n }\n}\n\n// Executed as the `bin` entry: run and map the exit code. Guarded so importing this module (tests)\n// doesn't trigger a run. `require.main === module` is the CJS \"am I the entry\" check; the CLI bundle\n// ships as CJS (see rollup.config.mjs), where `require`/`module` are the real CommonJS globals.\nif (typeof require !== \"undefined\" && typeof module !== \"undefined\" && require.main === module) {\n main(process.argv.slice(2)).then(\n code => process.exit(code),\n err => {\n process.stderr.write(`refract: ${(err as Error).stack ?? err}\\n`);\n process.exit(1);\n },\n );\n}\n"],"names":["VENDOR_HELPERS","id","outfile","source","exports","description","findVendorHelper","find","h","findPackageRoot","startDir","__dirname","dir","existsSync","join","parent","dirname","Error","readVendorSource","path","readFileSync","async","loadTypescript","mod","import","default","_a","transpileToEsm","sourceText","tsc","transpileModule","compilerOptions","module","ModuleKind","ESNext","target","ScriptTarget","ES2020","outputText","graphCounter","graphKey","p","resolve","replace","compileTsConfigGraph","configPath","options","moduleResolution","ModuleResolutionKind","Bundler","resolveJsonModule","allowJs","noLib","skipLibCheck","noEmitOnError","declaration","sourceMap","types","host","createCompilerHost","program","createProgram","tempFor","Map","isCompiledTs","sf","isDeclarationFile","fileName","includes","test","getSourceFiles","abs","base","basename","set","process","pid","rewrite","context","sourceFile","containing","factory","specFor","text","temp","spec","containingFile","startsWith","resolved","resolveModuleName","resolvedModule","resolvedFileName","get","undefined","rewriteTarget","createStringLiteral","visit","node","isImportDeclaration","isStringLiteral","moduleSpecifier","next","updateImportDeclaration","modifiers","importClause","attributes","isExportDeclaration","updateExportDeclaration","isTypeOnly","exportClause","isCallExpression","expression","kind","SyntaxKind","ImportKeyword","arguments","length","updateCallExpression","typeArguments","slice","visitEachChild","visitNode","written","writeFile","writeFileSync","push","cleanup","file","rmSync","force","emit","before","err","entry","escapeCell","s","renderLlms","descriptor","manifestName","lines","format","files","f","summary","packageName","recipes","shown","r","subsystem","group","variant","name","rest","buildGuide","tokens","llmsName","llmsFile","manifestFile","manifest","schema","JSON","stringify","RefractError","constructor","code","message","failures","super","this","Object","setPrototypeOf","prototype","isLiteral","value","isStructuredValue","Array","isArray","toRef","variantToRef","derive","ref","fn","arg","MODE_STRUCTURAL_KEYS","Set","buildModeFields","mode","propertyName","modeName","fields","struct","key","entries","has","collectScalarRefs","obj","exclude","out","VARIANT_STRUCTURAL_KEYS","PROPERTY_STRUCTURAL_KEYS","RESPONSIVE_CONDITION_KEYS","buildPropertyModel","normalized","model","external","extras","keys","variants","variantDerive","variantExtras","normalizedModes","modes","override","overrides","responsive","map","e","breakpoint","query","orientation","collectFieldRefs","buildRuleSetFromInterpreted","declarations","state","container","size","buildComponentRuleSetFromInterpreted","references","ruleSet","COMPONENT_SUBSYSTEM_KEYS","hasEntries","buildSubsystemModel","properties","collection","buildPropertiesModel","extraProperties","ruleSetGroups","ruleSets","keyframes","buildTokenMap","subModel","subsystems","property","propertyModel","v","_b","field","_c","_d","UNIT_SET","NUMERIC_RE","LENGTH_RE","parseLength","input","trimmed","trim","Number","m","exec","unit","toLowerCase","raw","SEED","resolveRoleUnit","pathKey","units","indexOf","roundRem","baseFontSize","toFixed","resolveDeferred","role","resolveShadowDimension","dim","LENGTH_REGISTRY","typography","fontSize","letterSpacing","lineHeight","layout","spacing","gutters","sizes","borders","width","offset","radius","effects","blur","shadow","mapRefs","record","changed","mapPropertyLeaves","includeExtras","mapVariants","mapModes","mapResponsive","resolvePropertyModel","layers","layer","resolveShadowLayer","parsed","resolveLengthRef","resolveModelUnits","config","anySubChanged","subKey","anyPropChanged","prop","pm","formatContextLabel","propertyPath","isAllowedValue","allowed","validateNormalizedResponsiveRefs","variantNames","label","isModeDerivation","parseModifiers","i","isExtendedProperty","resolveBaseValue","providedBase","fallback","candidate","fallbackBase","coerceValue","partitionLeafBase","leafFields","leafSet","extra","hasLeaf","resolveBaseAndExtra","partitioned","assembled","normalizeVariant","variantPath","extended","resolvedBase","normalizePropertyValue","normalizedVariants","fromEntries","definition","modePath","normalizeMode","responsiveContext","allowedBreakpoints","normalizedResponsive","allowedVariants","allowedTargets","finalResponsive","condition","others","explicitBase","some","assembleResponsiveLeaf","CONTAINER_INVALID_FIELDS","RESPONSIVE_KEY","STATES_KEY","CSS_KEY","VARIANTS_KEY","toStateArray","states","delta","stateEntryKey","mergeRecipeStates","index","d","at","mergeRecipe","merged","normalizeRecipeGroup","expandedGroup","values","recipe","expanded","recipeName","recipeDef","baseForSibling","filter","variantName","expandRecipeVariants","allowedVariantSet","forEach","normalizeRecipeVariant","allowedStates","allowedContainers","normalizeRecipeStates","normalizeRecipeResponsive","stateName","sibling","normalizeContainerEntry","createRecipeVariantResolver","interpret","cache","inProgress","groupPath","cycle","result","pop","resolveAll","resolveToken","registry","resolving","cached","add","reduce","delete","isCrossPropertyDerived","owner","seg0","seg1","split","propertyPrefix","rebake","where","apply","rebakeFields","rebakeProperty","rebakeVariants","nextFields","bakeCrossPropertyDerivations","modelChanged","nextSubsystems","sub","nextProps","subChanged","propName","nextPm","RESERVED_BREAKPOINT_KEYS","maxValueForNext","buildMediaDescriptor","breakpoints","resolveQuery","sort","a","b","sortBreakpointKeys","conflicts","k","assertNoReservedBreakpointNames","nextOf","groups","acc","own","nextKey","buildGroupDescriptor","resolveKey","min","max","exact","between","from","to","toValue","maxValue","DEFAULT_MEDIA_CONFIG","resolveMediaConfig","formatWidth","converted","mediaQueryString","clauses","containerQueryString","DEFAULT_BREAKPOINTS","xs","sm","md","lg","xl","buildContainerDescriptors","containers","opts","HEX_LENGTHS","clamp","Math","clampChannel","roundAlpha","round","convertHexToRGB","hex","sanitized","parseInt","substring","convertRgbToHex","rgb","toString","RGB_FN","parseColor","serializeColor","alpha","g","R","G","B","DEG","PI","srgbToLinear","c","pow","linearToSrgb","rgbToOklch","lab","lr","lb","l","l_","cbrt","m_","s_","L","linearRgbToOklab","C","sqrt","atan2","oklchToRgb","color","hr","cosh","cos","sinh","sin","linearAt","oklabToLinearRgb","inGamut","lin","every","lo","hi","mid","withOklch","transform","lighten","lch","darken","setL","rotateHue","deg","adjust","dials","toHexColor","padStart","percent","clampPercent","CSS_COLOR_KEYWORDS","aliceblue","antiquewhite","aqua","aquamarine","azure","beige","bisque","black","blanchedalmond","blue","blueviolet","brown","burlywood","cadetblue","chartreuse","chocolate","coral","cornflowerblue","cornsilk","crimson","cyan","darkblue","darkcyan","darkgoldenrod","darkgray","darkgreen","darkgrey","darkkhaki","darkmagenta","darkolivegreen","darkorange","darkorchid","darkred","darksalmon","darkseagreen","darkslateblue","darkslategray","darkslategrey","darkturquoise","darkviolet","deeppink","deepskyblue","dimgray","dimgrey","dodgerblue","firebrick","floralwhite","forestgreen","fuchsia","gainsboro","ghostwhite","gold","goldenrod","gray","green","greenyellow","grey","honeydew","hotpink","indianred","indigo","ivory","khaki","lavender","lavenderblush","lawngreen","lemonchiffon","lightblue","lightcoral","lightcyan","lightgoldenrodyellow","lightgray","lightgreen","lightgrey","lightpink","lightsalmon","lightseagreen","lightskyblue","lightslategray","lightslategrey","lightsteelblue","lightyellow","lime","limegreen","linen","magenta","maroon","mediumaquamarine","mediumblue","mediumorchid","mediumpurple","mediumseagreen","mediumslateblue","mediumspringgreen","mediumturquoise","mediumvioletred","midnightblue","mintcream","mistyrose","moccasin","navajowhite","navy","oldlace","olive","olivedrab","orange","orangered","orchid","palegoldenrod","palegreen","paleturquoise","palevioletred","papayawhip","peachpuff","peru","pink","plum","powderblue","purple","rebeccapurple","red","rosybrown","royalblue","saddlebrown","salmon","sandybrown","seagreen","seashell","sienna","silver","skyblue","slateblue","slategray","slategrey","snow","springgreen","steelblue","tan","teal","thistle","tomato","turquoise","violet","wheat","white","whitesmoke","yellow","yellowgreen","hslToRgb","hue","x","OKLCH_STR","HSL_STR","coerceColorInput","ok","hs","keyword","parseColorInput","n","DERIVE_FNS","NAMED_LIGHTER_ORDER","NAMED_DARKER_ORDER","isCrossPropertyRef","coerceText","error","finalizePaletteNormalization","normalized0","derivationSpecs","coerceTextFields","baseParseable","isParseableColor","hasSteps","steps","hasDerivations","hasHarmony","harmony","autoVariants","generateAutoVariants","harmonyVariants","generateHarmonyVariants","plainVariants","known","derivedVariants","bakeDerivationVariants","bakedModes","bakeDerivedModes","bakedResponsive","bakeResponsiveDerivations","rawModifiers","coerced","parseSpecModifiers","_ref","_mods","_base","_derive","resolveSource","palette","generateNumericSteps","generateDefaultVariants","HARMONY_SCHEMES","complement","analogous","triadic","tetradic","scheme","renames","members","member","buildChain","existingVariants","chainSteps","fnName","amount","tokenPath","prevName","prev","step","lightenAmount","lightenBy","darkenAmount","darkenBy","labelToL","bad","isNaN","parseAdjust","specs","baking","baseOf","bakeOne","sourceOf","KNOWN_CSS_PROPERTIES","VENDOR_PREFIX","isKnownCssProperty","kebab","RESERVED_RECIPE_KEYS","interpretProps","props","ctx","resolvePaletteReference","formatPropertyName","segments","relLuminance","LEVEL_RANK","fail","AA","AAA","APCA","apcaY","apcaLc","bg","y","yTxt","yBg","sapc","dp","refToColor","theme","String","FG_KEY","BG_KEYS","pickBg","decls","scorePair","fg","fgRgb","bgRgb","skipped","ratio","la","wcagRatio","level","large","wcagLevel","largeText","pass","minWcag","audit","includeRecipes","pairings","includePalettes","ruleSetGroup","baseFg","baseBg","_e","oFg","_g","_f","oBg","_h","cond","_l","_j","_k","scored","failed","worst","w","Infinity","total","passed","strict","list","RESERVED_KEYS","isDerivationSpec","splitDerivationVariants","plain","nextVariants","colorsSubsystem","derivations","normalizeProperties","rawSlice","plainValue","finalized","interpretRecipe","swap","rawDecls","resolveRecipeVariant","interpretPaletteRecipeVariant","TYPOGRAPHY_RATIOS","golden","DEFAULT_SCALE_STEPS","finalizeTypographyNormalization","propertyKey","generateFontSizeScaleVariants","ratioValue","precision","algorithm","generated","previousValue","rounded","PROPERTY_CSS_MAP","fontFamily","fontWeight","fontStyle","textTransform","textDecoration","textAlign","cssProperty","typographySubsystem","interpretTypographyRecipeVariant","LAYOUT_PROPERTY_KEYS","SCALE_PROPERTIES","FORCE_NONE_PROPERTIES","DEFAULT_LADDER","finalizeLayoutNormalization","hasRatio","hasStep","names","exp","curve","mult","readScaleConfig","forceNoneVariant","synthesized","synthesizeVariants","none","propBase","expandedAny","geometric","hasBase","expandResponsive","stripScaleKeys","paddingY","paddingX","marginY","marginX","gap","background","minWidth","maxWidth","height","minHeight","maxHeight","PROPERTY_DOMAIN","domain","cssProperties","spacingRef","guttersRef","configRef","literal","sortByWidth","GRID_LITERAL_PROPS","gridDeclarations","grid","includeDisplay","resolveContainerConfig","inset","gutter","direction","align","justify","buildContainer","containerInput","sizeNames","mediaConfig","resolvedMedia","mediaLen","configProperties","sortedKeys","baseConfig","responsiveEntries","variantKeyFor","buildSingleContainer","suffix","insetKey","gutterKey","insetRef","gutterRef","maxWidthValue","maxBp","maxBpIndex","resolveFluidMaxWidth","variantKey","buildLayoutStructural","merge","assign","spans","_","span","colVariant","offsetVariant","colDecl","offsetDecl","columns","buildColumns","grids","respDecls","buildGrids","stacks","stack","display","inline","wrap","buildStacks","collectSizeNames","PROPERTY_KEYS","layoutSubsystem","scaleStep","interpretLayoutRecipeVariant","buildStructural","boxShadow","opacity","transition","zIndex","RESOLVE_KEY_MAP","isPlainObject","numberField","dimensionField","SHADOW_FIELDS","coerceShadowLayer","offsetX","offsetY","spread","TRANSITION_FIELDS","coerceTransitionPart","part","duration","delay","timingFunction","LEAF_FIELDS","transitions","coerceFor","coerceShadowValue","coerceTransitionValue","effectsSubsystem","interpretEffectsRecipeVariant","MODIFIER_KEYS","ASPECT_KEYS","cssPropertyFor","as","side","aspect","refFor","bordersSubsystem","baseAs","baseSide","entryAs","entrySide","interpretBordersRecipeVariant","easing","iterationCount","fillMode","playState","declarationRef","parseStepDeclarations","parseKeyframe","stop","buildKeyframes","animationSubsystem","interpretAnimationRecipeVariant","interpretCssDelta","css","cssValueToRef","componentsSubsystem","_variantName","interpretComponentsRecipeVariant","extractReferences","normalizedVariantBase","rawVariantBase","extractComponentReferences","tokenRef","resetRuleSet","selector","staticGroup","DEFAULT_HEADINGS","PRESETS","preflight","static","margin","padding","font","headings","normalize","reset","border","GLOBALS_PRESET_NAMES","expandPreset","preset","defaults","tag","buildDefaultHeadingGroup","CONDITION_KEYS","leafToRef","formatProperty","interpretDeclarations","interpretOverride","normalizeElementItem","def","interpretItem","buildGlobalsRuleSets","elements","element","baseDef","variantMap","buildElementsGroup","SUBSYSTEMS","buildMedia","normalizeContainers","type","containerSizeSets","resolveExternalVar","prefix","dashed","buildSubsystemInput","clean","externals","varName","extractExternals","extendsPrefix","interpretProperties","inheritedProperties","recipeGroups","rawRecipes","groupName","groupDef","resolver","media","interpreted","interpretedVariant","buildSubsystemRuleSets","structural","reconstructNormalizedProperties","vname","reconstructed","ename","mergeSubsystemModel","current","partial","groupRuleSets","createTheme","rawTheme","adapter","extends","allowedModes","subsystemInputs","built","colors","animation","components","globals","buildThemeModel","unitConfig","overlaid","propertiesOverlay","ruleSetsOverlay","keyframesOverlay","containersOverlay","applyModelOverlay","derivationRegistry","contributions","contribution","buildDerivationRegistry","flatMap","validationErrors","collectComponentReferenceErrors","collectComponentCssRefErrors","collectGlobalsRefErrors","collectModeErrors","assembleTheme","errors","report","reference","dot","refGroup","refVariant","checkDecls","engine","tokenMapCache","WeakMap","getTokens","bound","bind","currentModel","partialBreakpoints","nextBreakpoints","partialContainers","nextContainers","partialInput","partialSubModel","nextModel","baked","overrideTheme","extensions","extend","call","defineProperties","getOwnPropertyDescriptors","DEFAULT_SINGLE_FILE","DEFAULT_SPLIT_STYLES","DEFAULT_SPLIT_VARIABLES","DEFAULT_SUBSYSTEM_FILENAME","DEFAULT_COMPONENTS_FILENAME","DEFAULT_COMPONENTS_VARIABLES","resolveEmitPlan","variables","filename","o","REFRACT_DTCG_EXTENSION","isToken","REFERENCE_PATTERN","resolveReferences","tokensByPath","visited","match","refPath","referenced","item","eachRuleSet","createNoopAdapter","version","renderRecipe","renderVariables","parts","renderAllRecipes","renderAllVariables","renderAll","describeUsage","fromDTCG","doc","walk","inheritedType","groupType","$type","child","childPath","token","$value","$description","$extensions","parseDTCGDocument","groupMapping","grouped","topGroup","bpGroup","breakpointGroup","parseDimension","groupTokens","mapping","detectSubsystem","mapColorTokens","mapTypographyTokens","mapEffectsTokens","mapBordersTokens","mapLayoutTokens","firstType","lower","UNRESOLVED_ALIAS","aliasToExternalPath","inner","subgroups","topLevel","subName","subTokens","baseToken","t","last","TYPO_PROPERTY_MAP","fontfamily","fontsize","fontweight","lineheight","letterspacing","fontstyle","texttransform","textdecoration","textalign","addTypographyVariant","parseDimensionOrKeep","detectTypoProperty","fullPath","shadowStr","formatShadowValue","addEffectsVariant","bezier","transStr","addBordersVariant","style","formatSingleShadow","num","parseFloat","endsWith","toDTCG","$name","includeBreakpoints","bp","resolveColor","typo","getTypographyTokenType","formatTypoValue","baseUnit","memberUnits","getEffectsGroupInfo","formatEffectsValue","getBordersGroupInfo","formatBordersValue","formatDimensionValue","ext","hasProperties","hasRuleSets","hasKeyframes","hasContainers","buildRefractExtension","dimText","dot2","subMap","segs","zero","dtcgLayerUnit","len","dtcgShadowDim","composeDtcgShadow","emitTheme","outDir","helpers","guide","emitted","mkdirSync","recursive","write","contents","dest","vendorHelpers","helper","cfg","defineConfig","CONFIG_BASENAME","EXT_ORDER","findConfigFile","fromDir","cwd","importCounter","loadConfig","extname","url","pathToFileURL","href","importConfigModule","targets","CSS_ADAPTER_PACKAGE","readOwnPackageName","pkgPath","parse","RAW_BASENAME","RAW_EXT_ORDER","findRawTheme","rawThemeImport","detected","head","scaffoldConfigForRaw","scaffoldConfig","runInit","body","TYPE_STEPS","RATIO_VALUES","SCHEME_ROTATIONS","pentadic","BRAND_NAMES","SEMANTIC_ANCHORS","LADDER","SHADOW_ALPHAS","SYSTEM_SANS","SYSTEM_MONO","FEEL_PRESETS","neutral","blurb","mono","pill","compact","editorial","technical","places","toHex","deriveLeading","sizePx","deriveTracking","nearestLadderStep","lightness","best","defaultSchemeFor","brandCount","schemesFor","scaffoldTheme","answers","feel","ratioName","seedHex","seed","brand","rotation","extraColors","rotations","contrastTarget","contrast","candidates","semantics","palettes","adjustments","bar","nudges","firstRatio","scoreAll","pairing","scores","failing","idx","final","nudge","ratioBefore","ratioAfter","levelAfter","unresolved","applyContrastPass","shadows","px","leading","tracking","caps","medium","semibold","bold","thick","fast","slow","seedLightness","nearestStep","adjusted","DEFAULT_RAW_BASENAME","BARE_KEY","escapeString","formatLiteral","indent","pad","repeat","padInner","banner","detail","renderRawTheme","describeChoices","count","runCreate","sections","paint","Boolean","stdout","isTTY","env","NO_COLOR","cursorUp","CLEAR_DOWN","decodeKey","chunk","decodeKeys","applyKey","multi","done","cancelled","cursor","selected","everything","rawCapable","stdin","setRawMode","Prompter","interactive","io","rl","createInterface","output","close","question","Promise","answer","line","validate","number","isFinite","select","choices","defaultIndex","runList","selectByNumber","multiselect","preselected","multiselectByNumber","init","painted","help","paintFrame","rows","here","hint","frame","reject","removeListener","onData","onEnd","pause","chosen","resume","setEncoding","on","marker","isInteger","SCHEME_HINTS","TYPE_SCALE_CHOICES","isColor","promptCreateAnswers","given","manual","noSemantics","noNeutral","noShadows","picked","baseSize","findIndex","createReportLines","variableCount","shift","flag","padEnd","nudged","DEFAULT_CONFIG_OUT","parseBreakpointsFlag","pair","scaffoldRaw","sourceLabel","scaffoldImportConfig","rawImportSpec","summarizeCounts","counts","runImport","inputFile","isAbsolute","fromOpts","rawFile","configFile","rawOnly","runBuild","byName","byOutDir","selectTargets","configDir","summaries","runTokens","outFile","groupCount","runAudit","resolvedValue","recipeIds","hasRecipe","diffThemes","paths","inBase","inCandidate","after","localeCompare","diffTokens","classes","seen","ids","getClass","b2","diffClasses","score","byLabel","labels","bs","crossed","diffContrast","tokensChanged","classesChanged","pairingsCrossed","WCAG_RANK","counter","loadCandidate","got","assertRawTheme","runDiff","candidatePath","candidateRaw","buildOpts","adapters","pick","diff","violations","maxClassChanges","maxTokenChanges","failBelow","afterRank","beforeRank","failedTargets","AGENT_TARGETS","AGENT_ROUTER","claude","routerFile","codex","opencode","generic","ROUTER_START","ROUTER_END","MANIFEST_REL","BODY_DIR_REL","skillsCatalogDir","listSkills","catalogDir","readdirSync","withFileTypes","isDirectory","sourcePath","front","RegExp","tier","parseSkillFile","renderRouter","skills","skill","beforeTriggers","shortDescription","upsertRouterBlock","existing","block","start","end","writeFileEnsuring","content","runSkillsInstall","scope","home","homedir","catalog","includeOptional","selectSkills","agents","agent","routerPath","refractVersion","pkg","readOwnPackageMeta","manifestPath","runSkillsUpdate","HELP","reportError","cmd","stderr","cmdCreate","argv","parseArgs","args","yes","allowPositionals","countVariables","WCAG_LEVELS","cmdSkills","global","local","only","optional","installScope","parseAgents","promptSkillsInstall","main","command","js","mjs","cmdInit","positionals","seeded","cmdImport","cmdBuild","cmdTokens","arrow","cmdDiff","cmdAudit","require","then","exit"],"mappings":"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"}
|