{"version":3,"file":"index.mjs","names":["defineTerrazzoConfig","resolvePath","resolvePath"],"sources":["../src/chrome.ts","../src/config.ts","../src/diagnostics.ts","../src/disabled-axes.ts","../src/presets.ts","../src/terrazzo-options.ts","../src/permutations/default.ts","../src/permutations/util.ts","../src/types.ts","../src/permutations/layered.ts","../src/permutations/resolver.ts","../src/permutations/normalize.ts","../src/token-listing.ts","../src/token-graph/diagnostics.ts","../src/token-graph/build.ts","../src/load.ts","../src/css-escape.ts","../src/css-axis-projected.ts"],"sourcesContent":["import { makeCSSVar } from '@terrazzo/token-tools/css';\nimport type { Diagnostic } from '#/types.ts';\n\n/**\n * Closed set of roles that swatchbook's block chrome reads. Each role emits\n * to a fixed `--swatchbook-<dashform>` custom property that blocks reference\n * directly — independent of the project's `cssVarPrefix`, so there is zero\n * chance of the project's token namespace colliding with chrome reads.\n *\n * Consumers whose tokens don't happen to match these roles supply a\n * `chrome` config entry mapping each role to a token path in their own\n * tree; the CSS emitter appends `:root` aliases of the form\n * `--swatchbook-<role>: var(--<prefix>-<target>);`, so chrome reads resolve\n * through the alias to the consumer's tokens while per-theme value flips\n * ride through the target's existing per-theme emission.\n */\nexport const CHROME_ROLES = [\n  'borderDefault',\n  'surfaceDefault',\n  'surfaceMuted',\n  'surfaceRaised',\n  'textDefault',\n  'textMuted',\n  'accentBg',\n  'accentFg',\n  'bodyFontFamily',\n] as const satisfies readonly string[];\n\nexport type ChromeRole = (typeof CHROME_ROLES)[number];\n\n/** Fixed prefix for chrome CSS custom properties. Independent of project config. */\nexport const CHROME_VAR_PREFIX = 'swatchbook';\n\n/**\n * Hard-coded literal CSS values for each chrome role. Used as the baseline\n * for every project — the CSS emitter always declares all nine chrome vars,\n * starting from these defaults and overlaying any user-supplied `chrome`\n * entry as a `var(...)` reference on top.\n *\n * Single owned literal values. Swatchbook has no intrinsic dark axis, so the\n * zero-config default is one committed appearance; per-axis variation comes\n * from `config.chrome` mapping roles to the consumer's tokens. No\n * `light-dark()` or system colors — those couple to the OS color-scheme,\n * which is foreign to swatchbook's axis model.\n *\n * Values meet WCAG AA on their respective surfaces. Consumers theme chrome\n * against their own tokens by filling `config.chrome`.\n */\nexport const DEFAULT_CHROME_MAP: Record<ChromeRole, string> = {\n  surfaceDefault: '#ffffff',\n  surfaceMuted: '#f8fafc',\n  surfaceRaised: '#ffffff',\n  textDefault: '#0f172a',\n  textMuted: '#475569',\n  borderDefault: '#e2e8f0',\n  accentBg: '#1d4ed8',\n  accentFg: '#ffffff',\n  bodyFontFamily: \"system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif\",\n};\n\n/**\n * The chrome defaults as a standalone `:root` stylesheet block. Shipped by the\n * blocks as a bundled base layer so `--swatchbook-*` is defined without the\n * addon. The emitter produces a superset of this (defaults + consumer\n * overrides) that wins via source order when the addon is present.\n */\nexport function buildChromeDefaultsCss(): string {\n  const lines = CHROME_ROLES.map(\n    (role) => `  ${makeCSSVar(role, { prefix: CHROME_VAR_PREFIX })}: ${DEFAULT_CHROME_MAP[role]};`,\n  );\n  return `:root {\\n${lines.join('\\n')}\\n}`;\n}\n\nexport interface ChromeValidationResult {\n  entries: Record<string, string>;\n  diagnostics: Diagnostic[];\n}\n\n/**\n * Validate `config.chrome` against the project's known token paths.\n * Unknown roles (outside `CHROME_ROLES`) and target paths that don't\n * appear in any theme produce `warn` diagnostics and are dropped.\n * Surviving entries land on `Project.chrome` and override the\n * hard-coded `DEFAULT_CHROME_MAP` literals during CSS emission.\n *\n * Caller pre-computes `tokenIDs` (typically from `listPaths(project.tokenGraph)`)\n * so this function doesn't reach into the resolver directly.\n */\nexport function validateChrome(\n  raw: Record<string, string> | undefined,\n  tokenIDs: ReadonlySet<string>,\n): ChromeValidationResult {\n  const diagnostics: Diagnostic[] = [];\n  if (!raw) return { entries: {}, diagnostics };\n\n  const known = new Set<string>(CHROME_ROLES);\n\n  const entries: Record<string, string> = {};\n  for (const [role, target] of Object.entries(raw)) {\n    if (!known.has(role)) {\n      diagnostics.push({\n        severity: 'warn',\n        group: 'swatchbook/chrome',\n        message: `\\`chrome\\` references unknown role \"${role}\" — dropped. Known roles: ${CHROME_ROLES.join(', ')}.`,\n      });\n      continue;\n    }\n    if (!targetResolves(target, tokenIDs)) {\n      diagnostics.push({\n        severity: 'warn',\n        group: 'swatchbook/chrome',\n        message: `\\`chrome\\` maps \"${role}\" → \"${target}\" but \"${target}\" is not a token or composite sub-field in any theme — dropped.`,\n      });\n      continue;\n    }\n    entries[role] = target;\n  }\n\n  return { entries, diagnostics };\n}\n\n// A target resolves if it's either a direct token ID, or a composite\n// sub-field under one (`typography.body.font-family` under the composite\n// `typography.body`). Composite tokens emit one CSS var per sub-field,\n// so either form is a valid alias target.\nfunction targetResolves(target: string, tokenIDs: ReadonlySet<string>): boolean {\n  if (tokenIDs.has(target)) return true;\n  const lastDot = target.lastIndexOf('.');\n  if (lastDot < 0) return false;\n  return tokenIDs.has(target.slice(0, lastDot));\n}\n","import type { Config } from '#/types.ts';\n\n/**\n * Identity helper for typed `swatchbook.config.ts`. Consumers write:\n *\n * ```ts\n * import { defineSwatchbookConfig } from '@unpunnyfuns/swatchbook-core';\n * export default defineSwatchbookConfig({\n *   tokens: ['tokens/**\\/*.json'],\n *   resolver: 'tokens/resolver.json',\n * });\n * ```\n *\n * Or with authored layered axes (no resolver file):\n *\n * ```ts\n * export default defineSwatchbookConfig({\n *   tokens: ['tokens/base/**\\/*.json'],\n *   axes: [\n *     {\n *       name: 'mode',\n *       contexts: { Light: [], Dark: ['tokens/modes/dark.json'] },\n *       default: 'Light',\n *     },\n *   ],\n * });\n * ```\n *\n * `resolver` and `axes` are mutually exclusive. Setting neither falls\n * back to a single synthetic theme.\n *\n * Named distinctly from Terrazzo's `defineConfig` to keep imports unambiguous.\n */\nexport function defineSwatchbookConfig(config: Config): Config {\n  return config;\n}\n","import { Logger } from '@terrazzo/parser';\nimport type { LogEntry, LogSeverity } from '@terrazzo/parser';\nimport type { Diagnostic, DiagnosticSeverity } from '#/types.ts';\n\ninterface BufferedEntry {\n  severity: LogSeverity;\n  entry: LogEntry;\n}\n\n/**\n * Terrazzo `Logger` subclass that captures log entries into an in-memory\n * buffer instead of writing to stdout. We attach one per `loadProject` call\n * and drain it into `Project.diagnostics` once loading settles.\n *\n * Subclassing is a pragmatic exception to the \"functional style\" rule —\n * Terrazzo's parser/resolver APIs take a `Logger` instance, so this is the\n * cleanest way to intercept their output.\n */\nexport class BufferedLogger extends Logger {\n  readonly entries: BufferedEntry[] = [];\n\n  override error(...entries: LogEntry[]): void {\n    for (const entry of entries) this.entries.push({ severity: 'error', entry });\n  }\n\n  override warn(...entries: LogEntry[]): void {\n    for (const entry of entries) this.entries.push({ severity: 'warn', entry });\n  }\n\n  override info(...entries: LogEntry[]): void {\n    for (const entry of entries) this.entries.push({ severity: 'info', entry });\n  }\n}\n\n/** Map a buffered log entry into swatchbook's public `Diagnostic` shape. */\nexport function toDiagnostics(logger: BufferedLogger): Diagnostic[] {\n  return logger.entries.map(({ severity, entry }) => {\n    const diagnostic: Diagnostic = {\n      severity: normalizeSeverity(severity),\n      group: entry.group,\n      message: entry.message,\n    };\n    if (entry.label) diagnostic.label = entry.label;\n    if (entry.filename) diagnostic.filename = entry.filename.pathname;\n    const loc = entry.node?.loc?.start;\n    if (loc) {\n      diagnostic.line = loc.line;\n    }\n    return diagnostic;\n  });\n}\n\n/**\n * Collapse diagnostics identical in every field, preserving first-seen order.\n *\n * Multi-tuple loads parse once per singleton tuple against one shared logger,\n * so a single malformed token is reported once per tuple and the count scales\n * with axis cardinality. Diagnostics that differ in source location stay\n * distinct: `filename` and `line` are part of the key.\n */\nexport function dedupeDiagnostics(diagnostics: readonly Diagnostic[]): Diagnostic[] {\n  const seen = new Set<string>();\n  const unique: Diagnostic[] = [];\n  for (const diagnostic of diagnostics) {\n    const key = JSON.stringify([\n      diagnostic.severity,\n      diagnostic.group,\n      diagnostic.label,\n      diagnostic.message,\n      diagnostic.filename,\n      diagnostic.line,\n    ]);\n    if (seen.has(key)) continue;\n    seen.add(key);\n    unique.push(diagnostic);\n  }\n  return unique;\n}\n\nfunction normalizeSeverity(severity: LogSeverity): DiagnosticSeverity {\n  return severity === 'debug' ? 'info' : severity;\n}\n","import type { Axis, Diagnostic } from '#/types.ts';\n\nexport interface DisabledAxesValidationResult {\n  names: string[];\n  diagnostics: Diagnostic[];\n}\n\n/**\n * Validate + sanitize the user-supplied `config.disabledAxes` list against\n * the project's axes. Unknown axis names produce `warn` diagnostics and are\n * dropped; the surviving names are what gets filtered out of\n * `Project.axes`, `Project.permutations`, and CSS emission.\n *\n * Mirrors the shape of `validatePresets` so the two validation surfaces\n * feel identical to authors reading diagnostics.\n */\nexport function validateDisabledAxes(\n  raw: string[] | undefined,\n  axes: Axis[],\n): DisabledAxesValidationResult {\n  const diagnostics: Diagnostic[] = [];\n  if (!raw || raw.length === 0) return { names: [], diagnostics };\n\n  const known = new Set(axes.map((a) => a.name));\n  const seen = new Set<string>();\n  const names: string[] = [];\n  for (const name of raw) {\n    if (seen.has(name)) continue;\n    seen.add(name);\n    if (!known.has(name)) {\n      diagnostics.push({\n        severity: 'warn',\n        group: 'swatchbook/disabled-axes',\n        message: `Config \\`disabledAxes\\` references unknown axis \"${name}\" — dropped.`,\n      });\n      continue;\n    }\n    names.push(name);\n  }\n\n  return { names, diagnostics };\n}\n","import type { Axis, Diagnostic, Preset } from '#/types.ts';\n\nexport interface PresetValidationResult {\n  presets: Preset[];\n  diagnostics: Diagnostic[];\n}\n\n/**\n * Validate + sanitize user-authored presets against the project's axes.\n * Unknown axis keys and invalid context values produce `warn` diagnostics;\n * the offending entries are stripped but the preset itself is kept (possibly\n * empty, which is still a valid tuple — it just resolves to all defaults).\n */\nexport function validatePresets(raw: Preset[] | undefined, axes: Axis[]): PresetValidationResult {\n  const diagnostics: Diagnostic[] = [];\n  if (!raw || raw.length === 0) return { presets: [], diagnostics };\n\n  const axisByName = new Map<string, Axis>();\n  for (const axis of axes) axisByName.set(axis.name, axis);\n\n  const presets: Preset[] = raw.map((preset) => {\n    const sanitized: Partial<Record<string, string>> = {};\n    for (const [axisName, ctx] of Object.entries(preset.axes)) {\n      if (ctx === undefined) continue;\n      const axis = axisByName.get(axisName);\n      if (!axis) {\n        diagnostics.push({\n          severity: 'warn',\n          group: 'swatchbook/presets',\n          message: `Preset \"${preset.name}\" references unknown axis \"${axisName}\" — dropped.`,\n        });\n        continue;\n      }\n      if (!axis.contexts.includes(ctx)) {\n        diagnostics.push({\n          severity: 'warn',\n          group: 'swatchbook/presets',\n          message: `Preset \"${preset.name}\" sets axis \"${axisName}\" to \"${ctx}\" which isn't a known context (${axis.contexts.join(', ')}) — dropped.`,\n        });\n        continue;\n      }\n      sanitized[axisName] = ctx;\n    }\n    const out: Preset = { name: preset.name, axes: sanitized };\n    if (preset.description !== undefined) out.description = preset.description;\n    return out;\n  });\n\n  return { presets, diagnostics };\n}\n","import { defineConfig as defineTerrazzoConfig } from '@terrazzo/parser';\nimport type { Config as TerrazzoConfig, ConfigInit, Logger, Plugin } from '@terrazzo/parser';\nimport type { CSSPluginOptions } from '@terrazzo/plugin-css';\nimport type { Diagnostic } from '#/types.ts';\n\n/**\n * CSS plugin options that swatchbook manages internally and strips from\n * the allowed surface. `variableName` and `permutations` are load-bearing\n * for axis-aware emission and prefix handling; `filename` and `skipBuild`\n * would break the in-memory capture the listing pipeline relies on.\n */\nexport type StrippedCssOption = 'variableName' | 'permutations' | 'filename' | 'skipBuild';\n\nexport type ForwardedCssOptions = Omit<CSSPluginOptions, StrippedCssOption>;\n\n// Deprecated plugin-css knobs that are silently inert under swatchbook's\n// permutation-based emission. Calling them out as `warn` diagnostics beats\n// the alternative — authors wonder why their `modeSelectors` don't take\n// effect and blame swatchbook.\nconst INERT_DEPRECATED_KEYS = ['baseSelector', 'baseScheme', 'modeSelectors'] as const;\n\n/**\n * Validate user-supplied `cssOptions`. The type system already prevents\n * setting the stripped fields; this catches no-ops the type doesn't know\n * about — plugin-css's deprecated mode selectors, superseded by the\n * permutations swatchbook builds per theme.\n */\nexport function validateCssOptions(raw: ForwardedCssOptions | undefined): {\n  diagnostics: Diagnostic[];\n} {\n  if (!raw) return { diagnostics: [] };\n\n  const diagnostics: Diagnostic[] = [];\n  const present = INERT_DEPRECATED_KEYS.filter(\n    (key) => (raw as Record<string, unknown>)[key] !== undefined,\n  );\n  if (present.length > 0) {\n    diagnostics.push({\n      severity: 'warn',\n      group: 'swatchbook/css-options',\n      message: `\\`cssOptions.${present.join('`, `cssOptions.')}\\` ${\n        present.length === 1 ? 'is' : 'are'\n      } deprecated in @terrazzo/plugin-css and do not apply — swatchbook builds one permutation per resolver theme for axis-aware emission. Remove the setting${\n        present.length === 1 ? '' : 's'\n      } to silence this diagnostic.`,\n    });\n  }\n  return { diagnostics };\n}\n\n/**\n * Terrazzo lint configuration accepted on swatchbook's `Config`. Sourced from\n * Terrazzo's own `Config['lint']` rather than restated, so an upstream shape\n * change surfaces at typecheck rather than at runtime.\n */\nexport type TerrazzoLintOptions = NonNullable<TerrazzoConfig['lint']>;\n\n/** Inputs to a single `buildParseConfig` call; one per permutation-loader call site. */\nexport interface BuildParseConfigOptions {\n  lintOptions?: TerrazzoLintOptions;\n  plugins?: readonly Plugin[];\n  logger: Logger;\n  cwd: URL;\n}\n\n/**\n * Build the Terrazzo config for swatchbook's internal `parse()` passes.\n *\n * Both permutation loaders route through here so the lint configuration —\n * and any future forwarded field — is applied once rather than duplicated\n * per call site. Omitting `lintOptions` yields Terrazzo's recommended rules,\n * which is the long-standing default.\n *\n * `plugins` is forwarded so `lintOptions.rules` can reference a rule\n * registered by a `terrazzoPlugins` entry rather than Terrazzo core — Terrazzo\n * validates rule ids against the loaded plugin set. Only each plugin's `lint`\n * hook is forwarded, via `lintContributionOf`.\n */\nexport function buildParseConfig({\n  lintOptions,\n  plugins,\n  logger,\n  cwd,\n}: BuildParseConfigOptions): ConfigInit {\n  const lintContributors = plugins?.filter((plugin) => typeof plugin.lint === 'function');\n  return defineTerrazzoConfig(\n    {\n      ...(lintOptions && { lint: lintOptions }),\n      ...(lintContributors?.length && { plugins: lintContributors.map(lintContributionOf) }),\n    },\n    { logger, cwd },\n  );\n}\n\n// Reduce a consumer plugin to its lint-rule registration. The parse config\n// carries no plugin-css, and peer-checking plugins throw from `config()` when\n// it is absent (`@terrazzo/plugin-sass` asserts it is present), so no hook\n// beyond `lint` may reach this config.\nfunction lintContributionOf(plugin: Plugin): Plugin {\n  return { name: plugin.name, lint: () => plugin.lint?.() ?? {} };\n}\n","import type { Axis, Diagnostic } from '#/types.ts';\n\nexport interface DefaultTupleResult {\n  tuple: Record<string, string>;\n  diagnostics: Diagnostic[];\n}\n\n/**\n * Resolve the project's starting tuple by merging the author-supplied\n * `config.default` onto the axis-default baseline. Unknown axis keys and\n * invalid context values surface as `warn` diagnostics (group\n * `swatchbook/default`) and the offending entry is dropped; the axis's own\n * `default` fills in. When `explicit` is absent the result is exactly the\n * axis-default baseline.\n */\nexport function resolveDefaultTuple(\n  explicit: Partial<Record<string, string>> | undefined,\n  axes: Axis[],\n): DefaultTupleResult {\n  const tuple: Record<string, string> = {};\n  for (const axis of axes) tuple[axis.name] = axis.default;\n\n  const diagnostics: Diagnostic[] = [];\n  if (!explicit) return { tuple, diagnostics };\n\n  const axisByName = new Map<string, Axis>();\n  for (const axis of axes) axisByName.set(axis.name, axis);\n\n  for (const [axisName, ctx] of Object.entries(explicit)) {\n    if (ctx === undefined) continue;\n    const axis = axisByName.get(axisName);\n    if (!axis) {\n      diagnostics.push({\n        severity: 'warn',\n        group: 'swatchbook/default',\n        message: `Config \"default\" references unknown axis \"${axisName}\" — using axis defaults.`,\n      });\n      continue;\n    }\n    if (!axis.contexts.includes(ctx)) {\n      diagnostics.push({\n        severity: 'warn',\n        group: 'swatchbook/default',\n        message: `Config \"default\" sets axis \"${axisName}\" to \"${ctx}\" which isn't a known context (${axis.contexts.join(', ')}) — using axis default.`,\n      });\n      continue;\n    }\n    tuple[axisName] = ctx;\n  }\n  return { tuple, diagnostics };\n}\n","import { globSync } from 'node:fs';\nimport { isAbsolute, resolve as resolvePath } from 'node:path';\n\n/** Expand globs relative to cwd, returning deduplicated absolute paths in sorted order. */\nexport function collectGlobbedFiles(patterns: string[], cwd: string): string[] {\n  const seen = new Set<string>();\n  for (const pattern of patterns) {\n    for (const match of globSync(pattern, { cwd })) {\n      const absolute = isAbsolute(match) ? match : resolvePath(cwd, match);\n      seen.add(absolute);\n    }\n  }\n  return [...seen].toSorted();\n}\n","import type { InputSourceWithDocument } from '@terrazzo/json-schema-tools';\nimport type { Plugin, Resolver, TokenNormalized } from '@terrazzo/parser';\nimport type { CSSPluginOptions } from '@terrazzo/plugin-css';\nimport type { TokenListingPluginOptions } from '@terrazzo/plugin-token-listing';\nimport type { ChromeRole } from '#/chrome.ts';\nimport type { ColorFormat } from '#/color-formats.ts';\nimport type { TerrazzoLintOptions } from '#/terrazzo-options.ts';\nimport type { TokenListingByPath } from '#/token-listing.ts';\nimport type { TokenGraph } from '#/token-graph/types.ts';\n\n/**\n * Swatchbook's public token shape — the contract surfaced on\n * `Project.defaultTokens` and `Project.resolveAt()` output. A strict\n * subset of `@terrazzo/parser`'s `TokenNormalized`: the fields\n * downstream blocks actually read, no internals (`id`, `source`,\n * `originalValue`, `group`, `dependencies`, `$extensions`, `$extends`)\n * leaked through.\n *\n * Insulates swatchbook consumers from Terrazzo type churn: a future\n * `TokenNormalized` field rename or restructure won't ripple into the\n * `@unpunnyfuns/swatchbook-core` API surface. Assignable from\n * `TokenNormalized` by structural subtyping — internal core code can\n * pass resolver output straight into a `TokenMap` without casts.\n */\nexport interface SwatchbookToken {\n  $type?: string | undefined;\n  $value?: unknown;\n  $description?: string | undefined;\n  /**\n   * DTCG `$deprecated`, already group-inheritance-normalized per token by\n   * the parser. `true` (deprecated, no message) or a string (deprecated,\n   * with a message that typically points at the replacement). Surfaced as\n   * a row indicator + strikethrough in TokenNavigator and a notice in\n   * TokenDetail.\n   */\n  $deprecated?: string | boolean | undefined;\n  aliasOf?: string | undefined;\n  aliasChain?: readonly string[] | undefined;\n  aliasedBy?: readonly string[] | undefined;\n  /**\n   * Per-sub-field alias map for composite tokens whose value blends\n   * primitives with aliased fragments. Shape varies per composite type;\n   * typed as `unknown` so consumers narrow at the use-site.\n   */\n  partialAliasOf?: unknown;\n}\n\nexport type TokenMap = Record<string, SwatchbookToken>;\n\n/**\n * Per-axis breakdown carried on every variance result — whether each\n * axis affects this token, and the stringified value seen in each of\n * its contexts (holding other axes at their defaults).\n */\nexport type AxisVariancePerAxis = Record<\n  string,\n  {\n    varying: boolean;\n    contexts: Record<string, string>;\n  }\n>;\n\n/**\n * Discriminated on `kind` so a `switch (result.kind)` narrows\n * `varyingAxes`'s cardinality and exposes the `axis: string` shortcut\n * on the single-axis variant.\n */\nexport type AxisVarianceResult =\n  | {\n      path: string;\n      kind: 'constant';\n      varyingAxes: readonly [];\n      constantAcrossAxes: readonly string[];\n      perAxis: AxisVariancePerAxis;\n    }\n  | {\n      path: string;\n      kind: 'single';\n      /** Convenience accessor — the sole varying axis, also at `varyingAxes[0]`. */\n      axis: string;\n      varyingAxes: readonly [string];\n      constantAcrossAxes: readonly string[];\n      perAxis: AxisVariancePerAxis;\n    }\n  | {\n      path: string;\n      kind: 'multi';\n      varyingAxes: readonly [string, string, ...string[]];\n      constantAcrossAxes: readonly string[];\n      perAxis: AxisVariancePerAxis;\n    };\n\n/**\n * Compose the resolved `TokenMap` for any tuple of axis selections.\n * Graph-backed: walks `Project.tokenGraph` rather than re-running the\n * resolver. Accepts partial tuples (missing axes fall back to their\n * defaults) and memoizes on the canonical tuple key.\n */\nexport type ResolveAt = (tuple: Record<string, string>) => TokenMap;\n\n/**\n * @internal Loader-internal materialization of a singleton tuple\n * (default tuple + per-axis non-default cells + presets). No longer\n * surfaced on `Project`; kept here as the shape `normalize` /\n * `loadResolverPermutations` / `loadLayeredPermutations` produce\n * internally, consumed by the cells builder via a resolver callback.\n */\nexport interface Permutation {\n  name: string;\n  /** The resolver input tuple (e.g. `{ theme: 'Light' }` or `{ mode: 'Dark', brand: 'Brand A' }`). */\n  input: Readonly<Record<string, string>>;\n}\n\n/**\n * One modifier axis of the theming model. Resolver-backed projects surface\n * one `Axis` per DTCG modifier; layered-config projects surface one `Axis`\n * per `axes[]` entry; projects without a resolver or layered config get a\n * single synthetic axis named `theme`.\n */\nexport interface Axis {\n  name: string;\n  contexts: readonly string[];\n  default: string;\n  description?: string;\n  source: 'resolver' | 'layered' | 'synthetic';\n}\n\n/**\n * A named quick-select combination of axis contexts. Rendered as a pill in\n * the toolbar. Any axis the preset omits falls back to that axis's\n * `default` when applied.\n */\nexport interface Preset {\n  name: string;\n  /** axisName → contextName. Unknown keys or invalid values produce diagnostics and are sanitized. */\n  axes: Partial<Record<string, string>>;\n  description?: string;\n}\n\n/**\n * One authored axis for layered configurations. Each context names an\n * ordered list of glob patterns / file paths (relative to cwd) that layer\n * on top of `Config.tokens` for that context. An empty array means \"no\n * override\" — valid, and common for a `Default` context.\n */\nexport interface AxisConfig {\n  name: string;\n  description?: string;\n  contexts: Record<string, string[]>;\n  default: string;\n}\n\n// Fields shared across every swatchbook config variant. The three\n// discriminated subtypes (`ResolverConfig`, `LayeredConfig`,\n// `PlainConfig`) extend this with their own load-strategy fields plus\n// `?: never` rejections of the other variants' fields, so an invalid\n// combination (`resolver` + `axes`, `axes` without `tokens`) is a\n// compile error before it ever reaches the loader's runtime checks.\ninterface CommonConfig {\n  /**\n   * Initial active tuple (`{ axisName: contextName }`). Any axis the tuple\n   * omits falls back to that axis's own `default`. Unknown axis keys or\n   * invalid context values produce `warn` diagnostics and are sanitized.\n   * When absent, the starting tuple is built from each axis's `default`.\n   */\n  default?: Partial<Record<string, string>>;\n  /** Prefix for emitted CSS custom properties. */\n  cssVarPrefix?: string;\n  /** Project-local output directory for codegen artifacts. */\n  outDir?: string;\n  /** Named tuple presets — rendered as quick-select pills in the toolbar. */\n  presets?: Preset[];\n  /**\n   * Axis names to suppress from the toolbar and CSS emission. Each listed\n   * axis is pinned to its `default` context: it disappears from\n   * `Project.axes`, its tuples collapse into the default-context slice, and\n   * emitted CSS drops it from the compound selector. Unknown names produce\n   * `warn` diagnostics (group `swatchbook/disabled-axes`) and are ignored.\n   * Config-level only — no runtime toggle.\n   */\n  disabledAxes?: string[];\n  /**\n   * Map from swatchbook block chrome roles (the closed set in `CHROME_PATHS`\n   * — e.g. `color.surface.default`, `color.text.default`) to token paths in\n   * the consumer's project. Each entry emits a `:root` alias\n   * `--swatchbook-<role>: var(--<prefix>-<target>)`; blocks read the fixed\n   * `--swatchbook-*` namespace directly, so the project's `cssVarPrefix`\n   * never collides with chrome reads.\n   *\n   * Target var indirection means per-theme values flip automatically — no\n   * per-theme override needed. Unknown role keys and target paths that\n   * don't resolve in any theme produce `warn` diagnostics (group\n   * `swatchbook/chrome`) and are dropped. Without a chrome map, blocks\n   * fall back to the `Canvas` / `CanvasText` system colors.\n   */\n  chrome?: Partial<Record<ChromeRole, string>>;\n  /**\n   * Project-wide baseline for the block row-indicator strip (the\n   * `<TokenNavigator>` / `<TokenTable>` per-row alias / variance / gamut /\n   * deprecation / description glyphs). Known keys are `alias`, `variance`,\n   * `gamut`, `deprecation`, `description`, `composes`; each maps to a\n   * boolean. Sits between the hard-coded indicator defaults and a block's\n   * own `indicators` prop — a per-block prop overrides this baseline.\n   *\n   * Typed loosely as `Record<string, boolean>` so core stays free of a\n   * blocks dependency; blocks narrows the keys at the use-site.\n   */\n  indicators?: Readonly<Record<string, boolean>>;\n  /**\n   * Options forwarded to the `@terrazzo/plugin-css` instance swatchbook\n   * runs internally (for the stylesheet it emits and for the Token\n   * Listing's `names.css` derivation). Line this up with the consumer's\n   * own `plugin-css` options — `legacyHex`, `transform`, `include`,\n   * and similar — so docs-side names and values match what the\n   * consumer's production build emits.\n   *\n   * `variableName` / `permutations` / `filename` / `skipBuild` are\n   * managed internally and cannot be overridden — swatchbook's\n   * axis-aware emission and in-memory listing capture depend on them.\n   * Passing deprecated knobs (`baseSelector`, `baseScheme`,\n   * `modeSelectors`) produces a `swatchbook/css-options` warn diagnostic\n   * because they're superseded by permutations in newer plugin-css.\n   */\n  cssOptions?: Omit<CSSPluginOptions, 'variableName' | 'permutations' | 'filename' | 'skipBuild'>;\n  /**\n   * Terrazzo lint configuration for swatchbook's internal parse pass, in the\n   * same shape as `terrazzo.config.ts`'s `lint` field. Line this up with the\n   * consumer's own lint config so `<Diagnostics />` reports the same pass/fail\n   * state as their `terrazzo build`.\n   *\n   * Omitted, Terrazzo's recommended rules apply — which flag legacy\n   * hex-string colors, among others. A project that allows those in its own\n   * build needs\n   * `lintOptions: { rules: { 'core/valid-color': ['error', { legacyFormat: true }] } }`\n   * here to match.\n   *\n   * `rules` replaces Terrazzo's recommended set rather than merging into it —\n   * any rule left out of a supplied `rules` object does not run.\n   *\n   * To keep one source of truth, import the Terrazzo config and forward its\n   * `lint` field rather than restating rules.\n   */\n  lintOptions?: TerrazzoLintOptions;\n  /**\n   * Options forwarded to `@terrazzo/plugin-token-listing`. Use\n   * `platforms` to register additional platforms beyond `css` (e.g.\n   * `swift`, `android`, `figma`) — each entry's `name` is a reference\n   * to a loaded plugin. For the reference to resolve, that plugin has\n   * to be loaded into the build, which is what `terrazzoPlugins` below\n   * is for.\n   *\n   * `filename` is managed internally (the listing is captured in\n   * memory, not written to disk).\n   */\n  listingOptions?: Omit<TokenListingPluginOptions, 'filename'>;\n  /**\n   * Additional Terrazzo plugins to load alongside swatchbook's own\n   * `plugin-css` + `plugin-token-listing`. The listing can reference\n   * any of these by name in its `platforms` map to derive per-platform\n   * identifiers. Plugins whose outputs swatchbook doesn't consume are\n   * simply ignored — they run, their files land in the in-memory\n   * output set, nothing else happens.\n   */\n  terrazzoPlugins?: readonly Plugin[];\n  /**\n   * Maximum arity of joint-divergence detection per token. Joint\n   * divergences are cases where the cartesian-correct value at a\n   * multi-axis tuple differs from cascade composition of all lower-arity\n   * blocks. Each such case emits a compound CSS selector\n   * (`[data-axis-a=\"…\"][data-axis-b=\"…\"]…`) at emission time.\n   *\n   * Default `4`. Covers the largest joint shapes real-world design\n   * systems tend to express (mode × brand × density × contrast).\n   *\n   * Bump if the design system has tokens with genuine 5+-axis joint\n   * divergences — those tuples will otherwise resolve to the\n   * cascade-composed value, which may be the wrong CSS variable\n   * binding for the specific multi-axis combination.\n   *\n   * Lower if load-time work is a concern in projects with many\n   * axes. Per-token probe work scales as\n   * `Σ_{k=2..arity} C(|affectedBy|, k) × Π non-default contexts in combo`;\n   * tokens affected by many axes including dense (large-context-count)\n   * ones dominate. `1` disables joint-block emission entirely.\n   *\n   * @default 4\n   */\n  maxJointArity?: number;\n  /**\n   * Starting color format for blocks that display color values. This is\n   * the lowest-precedence source in the chain: a block's own `colorFormat`\n   * prop wins over wrapping the subtree in `ColorFormatContext`, which\n   * wins over this project default. Defaults to `'hex'`.\n   */\n  defaultColorFormat?: ColorFormat;\n}\n\n/**\n * Resolver-driven config — axes derived from a DTCG 2025.10 resolver\n * file's modifiers. `tokens` is optional: the resolver's own `$ref`\n * targets determine which files get loaded, and the addon's Vite\n * plugin derives HMR watch paths from the resolved source list.\n * Supplying `tokens` alongside `resolver` overrides the watch-path\n * derivation — useful when you want HMR to watch directories broader\n * than the resolver references directly.\n */\nexport interface ResolverConfig extends CommonConfig {\n  resolver: string;\n  tokens?: string[];\n  /** Mutually exclusive with `resolver`. */\n  axes?: never;\n}\n\n/**\n * Layered-axes config — authored axes with per-context overlay globs\n * that layer onto the base `tokens`. The base `tokens` is required:\n * the layered loader needs a base layer to overlay against.\n */\nexport interface LayeredConfig extends CommonConfig {\n  axes: AxisConfig[];\n  tokens: string[];\n  /** Mutually exclusive with `axes`. */\n  resolver?: never;\n}\n\n/**\n * Plain-parse config — single synthetic axis (`theme`), no resolver,\n * no overlays. Just parses the `tokens` globs and exposes a one-cell\n * project. The fallback for the simplest \"I just have token files\"\n * case.\n */\nexport interface PlainConfig extends CommonConfig {\n  tokens: string[];\n  resolver?: never;\n  axes?: never;\n}\n\n/**\n * Swatchbook configuration. Discriminated by which load-strategy\n * field is present: `resolver` (resolver-driven), `axes` (layered),\n * or neither (plain-parse). Invalid combinations (`resolver` + `axes`,\n * `axes` without `tokens`) are compile-time errors; the loader still\n * checks at runtime as defense-in-depth for JS callers that bypass\n * the type system.\n */\nexport type Config = ResolverConfig | LayeredConfig | PlainConfig;\n\nexport type DiagnosticSeverity = 'error' | 'warn' | 'info';\n\n/**\n * A single problem or notice surfaced while loading or building a project.\n * Collected on `Project.diagnostics`; consumers render these as toolbar\n * badges, console output, or CLI exit-code triggers.\n *\n * `group` is a `swatchbook/<area>` slug for swatchbook-originated\n * diagnostics (e.g. `swatchbook/chrome`, `swatchbook/disabled-axes`,\n * `swatchbook/css-options`, `swatchbook/listing`) or a bare Terrazzo group\n * name (`parser`, `resolver`, `plugin`, …) when the diagnostic is passed\n * through unchanged from the underlying `@terrazzo/parser` build. `filename`\n * and `line` are populated only when the diagnostic traces back to a\n * specific source location Terrazzo reported (a parse or resolver error);\n * swatchbook-originated diagnostics about config shape or runtime behavior\n * omit both.\n */\nexport interface Diagnostic {\n  severity: DiagnosticSeverity;\n  /** Source group from Terrazzo (parser, resolver, plugin, …). */\n  group: string;\n  /**\n   * Originating rule or subsystem within `group`. Lint diagnostics carry the\n   * rule id, which is the key `lintOptions.rules` takes, so this is what tells\n   * a reader which rule to configure. Absent when Terrazzo emits no label.\n   */\n  label?: string;\n  message: string;\n  filename?: string;\n  line?: number;\n}\n\n/**\n * Loaded swatchbook project. Read any tuple via `project.resolveAt(tuple)`;\n * read the default-tuple snapshot directly via `project.defaultTokens`.\n * Walk the project's token resolution graph via `project.tokenGraph`.\n */\nexport interface Project {\n  config: Config;\n  axes: readonly Axis[];\n  /**\n   * Axis names suppressed via `config.disabledAxes`. Validated against the\n   * resolver's axis list at load time — unknown names are dropped here and\n   * surface as `warn` diagnostics. Downstream tooling (panels, blocks) can\n   * read this to indicate that a modifier exists in the resolver but is\n   * pinned to its default for this session.\n   */\n  disabledAxes: readonly string[];\n  /** Validated + sanitized presets from `config.presets`. Empty if unset. */\n  presets: readonly Preset[];\n  /**\n   * Validated chrome-alias map from `config.chrome`. Keys are members\n   * of the closed `ChromeRole` set; values are token paths that resolve\n   * in at least one permutation. Invalid entries from the raw config\n   * are dropped and reported as diagnostics. Empty when the config\n   * doesn't supply any.\n   */\n  chrome: Partial<Record<ChromeRole, string>>;\n  /** Resolved tokens at the project's default tuple. Convenience for global views. */\n  defaultTokens: TokenMap;\n  /**\n   * The default tuple — `{ axisName: axis.default }` for every axis,\n   * after `disabledAxes` filtering.\n   */\n  defaultTuple: Record<string, string>;\n  /**\n   * Compose the resolved `TokenMap` for any tuple of axis selections.\n   * Graph-backed; memoized on the canonical tuple key. Partial tuples\n   * are allowed — missing axes fall back to their defaults.\n   */\n  resolveAt: ResolveAt;\n  /**\n   * Walkable token graph — the primary resolution data structure.\n   * Consumers can query through it via the\n   * `@unpunnyfuns/swatchbook-core/graph` subpath helpers (`resolveAllAt`,\n   * `getVariance`, `listPaths`, etc.).\n   */\n  tokenGraph: TokenGraph;\n  /**\n   * Absolute paths of every file loaded while building the project —\n   * the resolver file (if any), every `$ref` target it pulled in, every\n   * overlay file the layered loader concatenated, or every globbed file\n   * the plain-parse fallback consumed. Consumers use this for file-watching\n   * (the addon's Vite plugin does exactly that).\n   */\n  sourceFiles: readonly string[];\n  /**\n   * Absolute path of the directory all config-relative paths (resolver,\n   * token globs, layered overlays) resolved against. Passed into\n   * `loadProject(config, cwd)`; retained here because downstream emitters\n   * need it for `defineConfig({ cwd })` in Terrazzo's JS API.\n   */\n  cwd: string;\n  /**\n   * Path-indexed Token Listing data from `@terrazzo/plugin-token-listing`.\n   * Each entry carries the plugin-css-authoritative var name under\n   * `$extensions[\"app.terrazzo.listing\"].names.css`, a `previewValue`\n   * string, the original aliased value, and the source file + line range.\n   * Empty when the project isn't resolver-backed (layered / plain-parse\n   * paths don't run the build), or when the listing plugin errored.\n   *\n   * Treat as enrichment: consumers should fall back gracefully when a\n   * given path is absent.\n   */\n  listing: TokenListingByPath;\n  diagnostics: Diagnostic[];\n}\n\n/**\n * Pass-through bag of the three values `@terrazzo/parser`'s `build()`\n * requires alongside a config. Threaded through `loadResolver()` →\n * `loadProject()` → `computeTokenListing()` during the load and then\n * dropped — never lands on the public `Project` shape, never crosses\n * a package boundary.\n *\n * @internal Internal to the loader pipeline. The `ParserInput` shape\n * leaks Terrazzo types (`Resolver`, `InputSourceWithDocument`) that\n * would otherwise pin our public API to a peer dep's evolving surface;\n * keeping it private lets the swatchbook surface stay stable.\n */\nexport interface ParserInput {\n  tokens: Record<string, TokenNormalized>;\n  sources: InputSourceWithDocument[];\n  resolver: Resolver;\n}\n\n/**\n * @internal Serialize an axis tuple to the stable string ID used as\n * an internal cache key and the wire-format theme name. Single-axis\n * tuples stringify to the context value alone (`{ theme: 'Light' }` →\n * `\"Light\"`); multi-axis tuples join context values with ` · ` in\n * insertion order (`{ mode: 'Dark', brand: 'Brand A' }` → `\"Dark · Brand A\"`).\n *\n * Not interchangeable with `tupleToName` (themes.ts): this is the\n * insertion-order internal wire key with no default fallback, whereas\n * `tupleToName` builds the axis-order display name and fills omitted axes\n * from their defaults.\n */\nexport function permutationID(input: Record<string, string>): string {\n  const values = Object.values(input);\n  const [first, ...rest] = values;\n  if (first === undefined) return '';\n  if (rest.length === 0) return first;\n  return values.join(' · ');\n}\n\n/**\n * Display-side integration the Storybook addon exposes for a third-party\n * tool (Tailwind v4, emotion, vanilla-extract, bootstrap, whatever).\n * Each integration contributes at most one virtual module whose body is\n * derived from the loaded `Project`. The addon's Vite plugin serves the\n * virtual module under `integration.virtualModule.virtualId` and\n * re-renders it on HMR so the output stays in lockstep with whatever\n * the toolbar / config / tokens currently say.\n *\n * Integrations are published as their own packages\n * (`@unpunnyfuns/swatchbook-integrations/tailwind`, …) and composed into\n * the addon via its options; the addon itself stays tool-agnostic.\n */\nexport interface SwatchbookIntegration {\n  /** Stable identifier for logs + diagnostics. */\n  name: string;\n  /**\n   * Optional virtual module this integration serves. Users import\n   * `virtualId` from their preview (or main) and receive whatever\n   * `render(project)` produces for the current project state.\n   */\n  virtualModule?: {\n    /** e.g. `'virtual:swatchbook/tailwind.css'`. Must be unique. */\n    virtualId: string;\n    /** Produce the module body for the currently-loaded project. */\n    render(project: Project): string;\n    /**\n     * When `true`, the addon's preset auto-injects a side-effect import\n     * (`import '<virtualId>';`) into the Storybook preview. Appropriate\n     * for integrations that contribute global CSS (Tailwind's `@theme`\n     * block, a stylesheet full of rules). Integrations exposing named\n     * exports that consumers import per-site (e.g. `import { theme }\n     * from '...'`) should leave this `false`. Defaults to `false`.\n     */\n    autoInject?: boolean;\n  };\n}\n","import { readFile } from 'node:fs/promises';\nimport { pathToFileURL } from 'node:url';\nimport { parse } from '@terrazzo/parser';\nimport type { Plugin } from '@terrazzo/parser';\nimport type { BufferedLogger } from '#/diagnostics.ts';\nimport { collectGlobbedFiles } from '#/permutations/util.ts';\nimport { buildParseConfig } from '#/terrazzo-options.ts';\nimport type { TerrazzoLintOptions } from '#/terrazzo-options.ts';\nimport { permutationID } from '#/types.ts';\nimport type { Axis, AxisConfig, Diagnostic, Permutation, TokenMap } from '#/types.ts';\n\nexport interface LayeredLoadResult {\n  axes: Axis[];\n  permutations: Permutation[];\n  resolved: Record<string, TokenMap>;\n  sourceFiles: string[];\n  diagnostics: Diagnostic[];\n}\n\n/**\n * Realize permutations from a layered (resolver-less) configuration.\n *\n * Enumerates `1 + Σ(axes × (contexts - 1))` singleton tuples — the\n * default tuple plus one per `(axis, non-default-context)` — and\n * parses `[base, ...overlays-for-tuple]` per singleton. Bounded by\n * axis cardinality, independent of the cartesian product.\n *\n * Joint divergences (two overlays both touching the same token at a\n * multi-non-default tuple) are not probed: there's no resolver to\n * consult for the cartesian truth. The truth model for layered is\n * projection composition over delta cells, so `composeAt` at any\n * multi-non-default tuple applies each axis's delta on top of the\n * baseline in axis order. The result matches what consumers already\n * see at runtime under multi-attribute CSS selectors.\n */\nexport async function loadLayeredPermutations(\n  axesConfig: AxisConfig[],\n  tokenGlobs: string[],\n  cwd: string,\n  logger: BufferedLogger,\n  lintOptions?: TerrazzoLintOptions,\n  plugins?: readonly Plugin[],\n): Promise<LayeredLoadResult> {\n  const cwdUrl = pathToFileURL(`${cwd}/`);\n  const terrazzoConfig = buildParseConfig({\n    ...(lintOptions && { lintOptions }),\n    ...(plugins && { plugins }),\n    logger,\n    cwd: cwdUrl,\n  });\n  const skipLint = terrazzoConfig.lint.build.enabled === false;\n\n  const baseFiles = await collectGlobbedFiles(tokenGlobs, cwd);\n\n  const axes: Axis[] = axesConfig.map((ax) => ({\n    name: ax.name,\n    contexts: Object.keys(ax.contexts),\n    default: ax.default,\n    ...(ax.description !== undefined ? { description: ax.description } : {}),\n    source: 'layered' as const,\n  }));\n\n  const fileCache = new Map<string, string>();\n  const readInput = async (filename: string) => {\n    let src = fileCache.get(filename);\n    if (src === undefined) {\n      src = await readFile(filename, 'utf8');\n      fileCache.set(filename, src);\n    }\n    return { filename: pathToFileURL(filename), src };\n  };\n\n  const contextFilesCache = new Map<string, string[]>();\n  const filesForAxisContext = (axisName: string, ctx: string, patterns: string[]): string[] => {\n    const key = `${axisName}::${ctx}`;\n    let files = contextFilesCache.get(key);\n    if (!files) {\n      files = patterns.length === 0 ? [] : collectGlobbedFiles(patterns, cwd);\n      contextFilesCache.set(key, files);\n    }\n    return files;\n  };\n\n  const overlayFilesFor = (input: Record<string, string>): string[] => {\n    const overlays: string[] = [];\n    for (const ax of axesConfig) {\n      const ctx = input[ax.name];\n      if (ctx === undefined) continue;\n      const patterns = ax.contexts[ctx] ?? [];\n      overlays.push(...filesForAxisContext(ax.name, ctx, patterns));\n    }\n    return overlays;\n  };\n\n  const parseTuple = async (\n    input: Record<string, string>,\n  ): Promise<{ input: Record<string, string>; allFiles: string[]; tokens: TokenMap }> => {\n    const overlayFiles = overlayFilesFor(input);\n    const allFiles = [...baseFiles, ...overlayFiles];\n    const inputs = await Promise.all(allFiles.map(readInput));\n    const parsed = await parse(inputs, {\n      logger,\n      config: terrazzoConfig,\n      resolveAliases: true,\n      continueOnError: true,\n      skipLint,\n    });\n    return { input, allFiles, tokens: parsed.tokens };\n  };\n\n  const tuples: Record<string, string>[] = [];\n  if (axesConfig.length === 0) {\n    tuples.push({});\n  } else {\n    const defaultTuple = Object.fromEntries(axesConfig.map((ax) => [ax.name, ax.default]));\n    tuples.push(defaultTuple);\n    for (const ax of axesConfig) {\n      for (const ctx of Object.keys(ax.contexts)) {\n        if (ctx === ax.default) continue;\n        tuples.push({ ...defaultTuple, [ax.name]: ctx });\n      }\n    }\n  }\n\n  const perTuple = await Promise.all(tuples.map(parseTuple));\n\n  const permutations: Permutation[] = [];\n  const resolved: Record<string, TokenMap> = {};\n  const sourceSet = new Set<string>();\n  for (const { input, allFiles, tokens } of perTuple) {\n    const id = permutationID(input);\n    permutations.push({ name: id, input: { ...input } });\n    resolved[id] = tokens;\n    for (const f of allFiles) sourceSet.add(f);\n  }\n\n  return { axes, permutations, resolved, sourceFiles: [...sourceSet].toSorted(), diagnostics: [] };\n}\n","import { existsSync } from 'node:fs';\nimport { readFile } from 'node:fs/promises';\nimport { createRequire } from 'node:module';\nimport { isAbsolute, resolve as resolvePath } from 'node:path';\nimport { fileURLToPath, pathToFileURL } from 'node:url';\nimport { lintRunner, loadResolver, parse } from '@terrazzo/parser';\nimport type { Plugin } from '@terrazzo/parser';\nimport { permutationID } from '#/types.ts';\nimport type { Axis, Diagnostic, ParserInput, Permutation, TokenMap } from '#/types.ts';\nimport type { BufferedLogger } from '#/diagnostics.ts';\nimport { collectGlobbedFiles } from '#/permutations/util.ts';\nimport { buildParseConfig } from '#/terrazzo-options.ts';\nimport type { TerrazzoLintOptions } from '#/terrazzo-options.ts';\n\nexport interface ResolverLoadResult {\n  axes: Axis[];\n  permutations: Permutation[];\n  resolved: Record<string, TokenMap>;\n  sourceFiles: string[];\n  /** Retained Terrazzo parse output for downstream plugin emission. */\n  parserInput?: ParserInput;\n  diagnostics: Diagnostic[];\n}\n\n// Resolve a `config.resolver` value to an absolute file path.\n//\n// Resolution order:\n//\n// 1. Absolute paths pass through unchanged.\n// 2. Explicit relative paths (`./resolver.json`, `../config/resolver.json`)\n//    resolve against `cwd`.\n// 3. Anything else first tries `cwd`-relative on disk — so a bare\n//    `resolver.json` in the project root resolves — and falls back\n//    to `node_modules` resolution when that file isn't present. Token\n//    packages can ship a resolver that consumers reference directly\n//    (`@scope/pkg/resolver.json`) without copying it into their tree.\n//\n// The `createRequire` anchor doesn't need to exist on disk — it only\n// fixes the starting point for the `node_modules` walk.\nfunction resolveResolverInput(resolverPath: string, cwd: string): string {\n  if (isAbsolute(resolverPath)) return resolverPath;\n  if (resolverPath.startsWith('.')) return resolvePath(cwd, resolverPath);\n\n  const cwdRelative = resolvePath(cwd, resolverPath);\n  if (existsSync(cwdRelative)) return cwdRelative;\n\n  const require = createRequire(resolvePath(cwd, '__swatchbook_resolver__'));\n  try {\n    return require.resolve(resolverPath);\n  } catch {\n    throw new Error(\n      `swatchbook: could not resolve config.resolver \"${resolverPath}\". Tried \"${cwdRelative}\" on disk and node_modules under \"${cwd}\".`,\n    );\n  }\n}\n\n/**\n * Realize permutations from a DTCG 2025.10 native resolver file.\n *\n * Terrazzo's `loadResolver` scans the provided input list for a resolver\n * document, normalizes it, then lets us enumerate permutations via\n * `resolver.listPermutations()` and realize each with `resolver.apply()`.\n *\n * We intercept Terrazzo's `$ref` fetch callback so every file it pulls in\n * gets recorded on `sourceFiles`. The addon's Vite plugin uses that list\n * for HMR watch paths when the consumer's config doesn't supply an\n * explicit `tokens` glob.\n */\nexport async function loadResolverPermutations(\n  resolverPath: string | undefined,\n  tokenGlobs: string[] | undefined,\n  cwd: string,\n  logger: BufferedLogger,\n  lintOptions?: TerrazzoLintOptions,\n  plugins?: readonly Plugin[],\n): Promise<ResolverLoadResult> {\n  const cwdUrl = pathToFileURL(`${cwd}/`);\n  const terrazzoConfig = buildParseConfig({\n    ...(lintOptions && { lintOptions }),\n    ...(plugins && { plugins }),\n    logger,\n    cwd: cwdUrl,\n  });\n  const skipLint = terrazzoConfig.lint.build.enabled === false;\n\n  const tokenFiles = tokenGlobs ? await collectGlobbedFiles(tokenGlobs, cwd) : [];\n  const refFiles = new Set<string>();\n\n  const req = async (url: URL): Promise<string> => {\n    const filename = url.protocol === 'file:' ? fileURLToPath(url) : url.toString();\n    if (url.protocol === 'file:') refFiles.add(filename);\n    return readFile(filename, 'utf8');\n  };\n\n  let loaded: Awaited<ReturnType<typeof loadResolver>> | undefined;\n  let resolverAbsolute: string | undefined;\n  if (resolverPath) {\n    resolverAbsolute = resolveResolverInput(resolverPath, cwd);\n    // `loadResolver` expects the resolver file alone as input and fetches\n    // referenced token files via `req`. Passing tokens up front triggers\n    // \"Resolver must be the only input\" errors.\n    const resolverInput = {\n      filename: pathToFileURL(resolverAbsolute),\n      src: await readFile(resolverAbsolute, 'utf8'),\n    };\n    loaded = await loadResolver([resolverInput], {\n      config: terrazzoConfig,\n      logger,\n      req,\n    });\n  }\n\n  if (!loaded?.resolver) {\n    // Fall back to plain parse; no resolver found.\n    if (tokenFiles.length === 0) {\n      throw new Error(\n        'swatchbook config must specify `resolver`, `axes`, or non-empty `tokens`. None were set.',\n      );\n    }\n    const tokenInputs = await Promise.all(\n      tokenFiles.map(async (filename) => ({\n        filename: pathToFileURL(filename),\n        src: await readFile(filename, 'utf8'),\n      })),\n    );\n    const parsed = await parse(tokenInputs, {\n      logger,\n      config: terrazzoConfig,\n      resolveAliases: true,\n      continueOnError: true,\n      skipLint,\n    });\n    const name = 'default';\n    return {\n      axes: [{ name: 'theme', contexts: [name], default: name, source: 'synthetic' }],\n      permutations: [{ name, input: { theme: name } }],\n      resolved: { [name]: parsed.tokens },\n      sourceFiles: tokenFiles,\n      parserInput: {\n        tokens: parsed.tokens,\n        sources: parsed.sources,\n        resolver: parsed.resolver,\n      },\n      diagnostics: [],\n    };\n  }\n\n  const { resolver, tokens: baseTokens, sources: parsedSources } = loaded;\n\n  // `loadResolver` resolves without linting; only `parse()` runs the lint pass,\n  // and the resolver path never reaches it. Run it here so a resolver-backed\n  // project reports the same lint state as its `terrazzo build`. Once, against\n  // the baseline token set, rather than per tuple.\n  if (!skipLint) {\n    await lintRunner({\n      tokens: baseTokens,\n      sources: parsedSources,\n      config: terrazzoConfig,\n      logger,\n    });\n  }\n\n  const diagnostics: Diagnostic[] = [];\n  const axes: Axis[] = Object.entries(resolver.source.modifiers ?? {}).map(([name, modifier]) => {\n    const contexts = Object.keys(modifier.contexts ?? {});\n    let defaultContext = modifier.default ?? contexts[0];\n    // The DTCG 2025.10 resolver spec allows a modifier with no `default` to\n    // fall through to the first context key; a modifier with neither a\n    // `default` nor any contexts is a malformed resolver that produces an\n    // axis with empty-string `default` downstream. Flag it so users see\n    // where the nonsense is coming from instead of debugging from a\n    // mysterious `\"\"` permutation name.\n    if (defaultContext === undefined) {\n      diagnostics.push({\n        severity: 'warn',\n        group: 'swatchbook/resolver',\n        message: `Resolver modifier \"${name}\" has no default and no contexts — axis is unusable.`,\n      });\n      defaultContext = '';\n    }\n    return {\n      name,\n      contexts,\n      default: defaultContext,\n      ...(modifier.description !== undefined ? { description: modifier.description } : {}),\n      source: 'resolver' as const,\n    };\n  });\n\n  const permutations: Permutation[] = [];\n  const resolved: Record<string, TokenMap> = {};\n\n  // Materialize `Σ(axes × contexts)` singleton permutations: the\n  // default tuple + one per `(axis, non-default-context)` cell.\n  // Bounded by axis cardinality — independent of the cartesian\n  // product, so even pathological resolvers (terrazzo#752's ~15M\n  // tuples) load in milliseconds. Joint divergences are picked up\n  // downstream via targeted `resolver.apply` probes in\n  // `probeJointOverrides`. The resolver itself stays on\n  // `parserInput.resolver` for any consumer that needs an\n  // on-demand `apply` at a non-singleton tuple.\n  const defaultInput: Record<string, string> = {};\n  for (const axis of axes) defaultInput[axis.name] = axis.default;\n  const defaultId = permutationID(defaultInput);\n  permutations.push({ name: defaultId, input: defaultInput });\n  resolved[defaultId] = resolver.apply(defaultInput);\n\n  for (const axis of axes) {\n    for (const ctx of axis.contexts) {\n      if (ctx === axis.default) continue;\n      const cellInput = { ...defaultInput, [axis.name]: ctx };\n      const id = permutationID(cellInput);\n      if (resolved[id] !== undefined) continue;\n      permutations.push({ name: id, input: cellInput });\n      resolved[id] = resolver.apply(cellInput);\n    }\n  }\n\n  const sourceFiles = [...refFiles];\n  if (resolverAbsolute) sourceFiles.push(resolverAbsolute);\n  // If the consumer supplied explicit globs, take their union — they may\n  // want HMR to watch directories broader than the resolver references.\n  for (const f of tokenFiles) if (!sourceFiles.includes(f)) sourceFiles.push(f);\n\n  return {\n    axes,\n    permutations,\n    resolved,\n    sourceFiles: sourceFiles.toSorted(),\n    parserInput: { tokens: baseTokens, sources: parsedSources, resolver },\n    diagnostics,\n  };\n}\n","import type { BufferedLogger } from '#/diagnostics.ts';\nimport { loadLayeredPermutations } from '#/permutations/layered.ts';\nimport { loadResolverPermutations } from '#/permutations/resolver.ts';\nimport type { Axis, Config, Diagnostic, ParserInput, Permutation, TokenMap } from '#/types.ts';\n\nexport interface NormalizedPermutations {\n  axes: Axis[];\n  permutations: Permutation[];\n  resolved: Record<string, TokenMap>;\n  sourceFiles: string[];\n  /** Present for resolver + plain-parse paths; undefined for layered. */\n  parserInput?: ParserInput;\n  diagnostics: Diagnostic[];\n}\n\n/**\n * Realize permutations from the config. Exactly one of `resolver` or\n * `axes` may be set; when neither is set, we fall back to a single\n * synthetic axis containing the plain-parsed token files (which then\n * must be supplied via `config.tokens`).\n */\nexport async function normalizePermutations(\n  config: Config,\n  cwd: string,\n  logger: BufferedLogger,\n): Promise<NormalizedPermutations> {\n  if (config.resolver && config.axes) {\n    throw new Error('swatchbook: config must specify either `resolver` or `axes`, not both.');\n  }\n\n  if (config.axes) {\n    if (!config.tokens || config.tokens.length === 0) {\n      throw new Error(\n        'swatchbook: config with `axes` must also supply `tokens` (the base token files the overlays layer onto).',\n      );\n    }\n    return loadLayeredPermutations(\n      config.axes,\n      config.tokens,\n      cwd,\n      logger,\n      config.lintOptions,\n      config.terrazzoPlugins,\n    );\n  }\n\n  return loadResolverPermutations(\n    config.resolver,\n    config.tokens,\n    cwd,\n    logger,\n    config.lintOptions,\n    config.terrazzoPlugins,\n  );\n}\n","import { pathToFileURL } from 'node:url';\nimport { build, defineConfig, Logger } from '@terrazzo/parser';\nimport type { Plugin } from '@terrazzo/parser';\nimport cssPlugin from '@terrazzo/plugin-css';\nimport type { CSSPluginOptions } from '@terrazzo/plugin-css';\nimport tokenListingPlugin from '@terrazzo/plugin-token-listing';\nimport type { ListedToken, TokenListingPluginOptions } from '@terrazzo/plugin-token-listing';\nimport { makeCSSVar } from '@terrazzo/token-tools/css';\nimport type { Diagnostic, ParserInput } from '#/types.ts';\n\n/**\n * Token Listing data indexed by path for fast per-token lookup. Each entry\n * is the raw `ListedToken` emitted by `@terrazzo/plugin-token-listing` —\n * `$name`, `$type`, `$value`, `$extensions[\"app.terrazzo.listing\"]` with\n * names / previewValue / originalValue / source.loc.\n *\n * Produced by `computeTokenListing`; attached to `Project.listing` when the\n * project is resolver-backed so downstream consumers can read authoritative\n * CSS var names and preview strings instead of re-deriving them.\n *\n * Accepted coupling: `ListedToken`'s shape comes straight from\n * `@terrazzo/plugin-token-listing`, which core depends on at an exact pin\n * (`\"@terrazzo/plugin-token-listing\": \"0.1.1\"`, not a range) precisely\n * because this type isn't insulated from it. Any upstream listing-format\n * change is a deliberate, coordinated bump here, not a silent break —\n * consumers who need insulation from that churn should read\n * `SlimListedToken` (`/snapshot-for-wire`) instead of this type directly.\n */\nexport type TokenListingByPath = Record<string, ListedToken>;\n\n/**\n * Run Terrazzo's build pipeline with `plugin-css` + `plugin-token-listing`\n * and parse the resulting listing JSON into a path-indexed map.\n *\n * Uses the same `plugin-css` variable-naming rule the smart-axis-\n * projected emitter uses, so the `names.css` field in every entry\n * matches exactly what emission would produce — by construction, no\n * parallel logic to drift.\n *\n * Returns `{ listing, diagnostics }`. On any failure (missing listing\n * output, parse error, plugin crash inside a user-supplied\n * `terrazzoPlugins` entry) returns an empty map plus a `swatchbook/listing`\n * warn diagnostic so the caller surfaces the failure instead of silently\n * degrading `<TokenTable>` / `<ColorTable>` previews.\n */\nexport interface ComputeTokenListingOptions {\n  /** Extra options forwarded to the internal `plugin-css` instance. */\n  cssOptions?: Omit<CSSPluginOptions, 'variableName' | 'permutations' | 'filename' | 'skipBuild'>;\n  /** Extra options forwarded to the internal `plugin-token-listing` instance. */\n  listingOptions?: Omit<TokenListingPluginOptions, 'filename'>;\n  /** Extra plugins loaded into the build — referenced by `listingOptions.platforms`. */\n  extraPlugins?: readonly Plugin[];\n}\n\nexport interface ComputeTokenListingResult {\n  listing: TokenListingByPath;\n  diagnostics: Diagnostic[];\n}\n\nexport async function computeTokenListing(\n  parserInput: ParserInput,\n  cwd: string,\n  prefix: string,\n  options: ComputeTokenListingOptions = {},\n): Promise<ComputeTokenListingResult> {\n  try {\n    const { tokens, sources, resolver } = parserInput;\n    const logger = new Logger({ level: 'warn' });\n    const cwdURL = pathToFileURL(`${cwd}/`);\n\n    // User-supplied `platforms` overrides the default CSS entry when\n    // present — otherwise the built-in `css` platform is the only one\n    // registered.\n    const platforms = options.listingOptions?.platforms ?? {\n      css: { name: '@terrazzo/plugin-css', description: 'CSS custom properties' },\n    };\n\n    const config = defineConfig(\n      {\n        plugins: [\n          cssPlugin({\n            ...options.cssOptions,\n            filename: 'tokens.css',\n            variableName: (token) =>\n              prefix ? makeCSSVar(String(token.id), { prefix }) : makeCSSVar(String(token.id)),\n          }),\n          ...(options.extraPlugins ?? []),\n          tokenListingPlugin({\n            ...options.listingOptions,\n            filename: 'tokens.listing.json',\n            platforms,\n          }),\n        ],\n      },\n      { logger, cwd: cwdURL },\n    );\n\n    const result = await build(tokens, { config, resolver, sources, logger });\n    const listingFile = result.outputFiles.find((f) => f.filename === 'tokens.listing.json');\n    if (!listingFile) {\n      return { listing: {}, diagnostics: [missingListingDiagnostic()] };\n    }\n\n    const raw =\n      typeof listingFile.contents === 'string'\n        ? listingFile.contents\n        : new TextDecoder().decode(listingFile.contents);\n    const parsed = JSON.parse(raw) as { data?: ListedToken[] };\n    if (!Array.isArray(parsed.data)) {\n      return { listing: {}, diagnostics: [malformedListingDiagnostic()] };\n    }\n\n    const byPath: TokenListingByPath = {};\n    for (const entry of parsed.data) {\n      byPath[entry.$name] = entry;\n    }\n    return { listing: byPath, diagnostics: corruptPreviewDiagnostics(parsed.data) };\n  } catch (error) {\n    return { listing: {}, diagnostics: [crashedListingDiagnostic(error)] };\n  }\n}\n\n// `previewValue` is upstream-controlled and blocks forward it verbatim, so a\n// stringifier that interpolated a missing field reaches the user as a table\n// cell reading `undefinedundefined`. Name the token here instead, at build\n// time, where the path is still in hand.\nfunction corruptPreviewDiagnostics(entries: readonly ListedToken[]): Diagnostic[] {\n  const diagnostics: Diagnostic[] = [];\n  for (const entry of entries) {\n    const preview = entry.$extensions['app.terrazzo.listing'].previewValue;\n    if (typeof preview !== 'string' || !preview.includes('undefined')) {\n      continue;\n    }\n    diagnostics.push({\n      severity: 'warn',\n      group: 'swatchbook/listing',\n      label: 'preview-value',\n      message: `Token \\`${entry.$name}\\` has a corrupted preview value (\\`${preview}\\`). Its \\`$value\\` is likely written in a form the CSS stringifier can't read — a dimension as a bare string or number rather than \\`{ value, unit }\\`. Blocks display this string as-is.`,\n    });\n  }\n  return diagnostics;\n}\n\nfunction crashedListingDiagnostic(err: unknown): Diagnostic {\n  const detail = err instanceof Error ? err.message : String(err);\n  return {\n    severity: 'warn',\n    group: 'swatchbook/listing',\n    message: `Token listing build failed: ${detail}. <TokenTable> / <ColorTable> previews will fall back to raw values.`,\n  };\n}\n\nfunction missingListingDiagnostic(): Diagnostic {\n  return {\n    severity: 'warn',\n    group: 'swatchbook/listing',\n    message: `Token listing build emitted no \\`tokens.listing.json\\` output. <TokenTable> / <ColorTable> previews will fall back to raw values.`,\n  };\n}\n\nfunction malformedListingDiagnostic(): Diagnostic {\n  return {\n    severity: 'warn',\n    group: 'swatchbook/listing',\n    message: `Token listing JSON had no \\`data\\` array. <TokenTable> / <ColorTable> previews will fall back to raw values.`,\n  };\n}\n","import type { Diagnostic } from '#/types.ts';\n\nexport function unresolvableAliasDiagnostic(\n  axis: string,\n  context: string,\n  path: string,\n  target: string,\n): Diagnostic {\n  return {\n    severity: 'error',\n    group: 'swatchbook/token-graph',\n    message: `Modifier \\`${axis}/${context}\\` writes \\`${path}\\` as alias to \\`${target}\\`, which is not defined in any modifier or baseline.`,\n  };\n}\n\nexport function buildFailedDiagnostic(detail: string): Diagnostic {\n  return {\n    severity: 'error',\n    group: 'swatchbook/token-graph',\n    message: `Graph build failed: ${detail}. \\`tokenGraph\\` will be empty; \\`resolveAt()\\` returns baseline-only values.`,\n  };\n}\n\nexport function aliasCycleDiagnostic(path: string, chain: readonly string[]): Diagnostic {\n  return {\n    severity: 'warn',\n    group: 'swatchbook/token-graph',\n    message: `Alias cycle starting at \\`${path}\\` (chain: ${chain.join(' → ')} → ${path}). Walker returns baseline literal at cycle entry.`,\n  };\n}\n\nexport function malformedColorShapeDiagnostic(\n  path: string,\n  fieldPath: string,\n  reason: string,\n): Diagnostic {\n  const where = fieldPath ? `${path} (at \\`${fieldPath}\\`)` : path;\n  return {\n    severity: 'warn',\n    group: 'swatchbook/token-graph',\n    message: `Color value at \\`${where}\\` is structurally invalid: ${reason}. CSS emission will fail for any context that resolves to this token.`,\n  };\n}\n\nexport function unresolvedRefDiagnostic(path: string, fieldPath: string, ref: string): Diagnostic {\n  const where = fieldPath ? `${path} (at \\`${fieldPath}\\`)` : path;\n  return {\n    severity: 'warn',\n    group: 'swatchbook/token-graph',\n    message: `Unresolved \\`$ref\\` at \\`${where}\\`: \\`${ref}\\`. The upstream DTCG parser did not substitute the target value, so this field will reach CSS emission as a \\`{ $ref }\\` object literal. Check that the JSON Pointer resolves and that the parser version handles \\`$ref\\` into non-Object targets (arrays, scalars).`,\n  };\n}\n","import type { Axis, Diagnostic, ParserInput, SwatchbookToken, TokenMap } from '#/types.ts';\nimport { permutationID } from '#/types.ts';\nimport type { TokenGraph, TokenGraphNode, WriteValue } from '#/token-graph/types.ts';\nimport { valueKey } from '#/value-key.ts';\nimport { isPlainObject } from '#/token-graph/internal-utils.ts';\nimport {\n  aliasCycleDiagnostic,\n  malformedColorShapeDiagnostic,\n  unresolvableAliasDiagnostic,\n  unresolvedRefDiagnostic,\n} from '#/token-graph/diagnostics.ts';\n\nconst COMPOSITE_TYPES = new Set(['border', 'typography', 'transition', 'gradient', 'shadow']);\n\nconst SLIM_KEYS = [\n  '$value',\n  '$type',\n  '$description',\n  '$deprecated',\n  'aliasOf',\n  'aliasChain',\n  'partialAliasOf',\n  'aliasedBy',\n] as const;\n\n// Strip a Terrazzo-shaped token to only the fields swatchbook consumers\n// read. Terrazzo's `TokenNormalized` carries `source.node`, `mode`,\n// `group`, `originalValue`, `jsonID`, `id`, `dependencies` — none of\n// which any swatchbook consumer reads, but which together account for\n// ~530 KB of the wire payload on the reference fixture (`source.node`\n// alone is 245 KB).\n//\n// Apply at graph-build time so the in-memory graph carries only the\n// slim shape; the wire payload then naturally serializes the slim shape.\nfunction slimToken(token: SwatchbookToken): SwatchbookToken {\n  const result: Record<string, unknown> = {};\n  for (const key of SLIM_KEYS) {\n    const value = (token as Record<string, unknown>)[key];\n    if (value !== undefined) result[key] = value;\n  }\n  return result as SwatchbookToken;\n}\nconst ALIAS_RE = /^\\{(.+)\\}$/;\n\nexport function extractWritesFromModifiers(\n  modifiers: Record<\n    string,\n    { contexts?: Record<string, unknown[]> | undefined; default?: string | undefined }\n  >,\n  axes: readonly Axis[],\n  refLookup: TokenMap = {},\n): Record<string, Record<string, Record<string, WriteValue>>> {\n  const out: Record<string, Record<string, Record<string, WriteValue>>> = {};\n  for (const axis of axes) {\n    const modifier = modifiers[axis.name];\n    if (!modifier?.contexts) continue;\n    for (const [contextName, groupNodes] of Object.entries(modifier.contexts)) {\n      if (contextName === axis.default) continue;\n      for (const node of groupNodes) {\n        collectLeafWrites(node, '', axis.name, contextName, out, refLookup);\n      }\n    }\n  }\n  return out;\n}\n\nfunction collectLeafWrites(\n  node: unknown,\n  prefix: string,\n  axisName: string,\n  contextName: string,\n  out: Record<string, Record<string, Record<string, WriteValue>>>,\n  refLookup: TokenMap,\n  inheritedType?: string,\n): void {\n  if (!isPlainObject(node)) return;\n  if ('$value' in node) {\n    if (!prefix) return;\n    const effectiveType = typeof node['$type'] === 'string' ? node['$type'] : inheritedType;\n    const write = toWriteValue(node, effectiveType, refLookup);\n    if (write) {\n      (out[prefix] ??= {})[axisName] ??= {};\n      out[prefix]![axisName]![contextName] = write;\n    }\n    return;\n  }\n  const nextInheritedType = typeof node['$type'] === 'string' ? node['$type'] : inheritedType;\n  for (const [key, child] of Object.entries(node)) {\n    if (key.startsWith('$')) continue;\n    const childPath = prefix ? `${prefix}.${key}` : key;\n    collectLeafWrites(child, childPath, axisName, contextName, out, refLookup, nextInheritedType);\n  }\n}\n\nfunction toWriteValue(\n  token: Record<string, unknown>,\n  effectiveType?: string,\n  refLookup: TokenMap = {},\n): WriteValue | undefined {\n  const rawValue = token['$value'];\n  if (rawValue === undefined) return undefined;\n  const value = resolveRefsInValue(rawValue, refLookup);\n  const $type = typeof token['$type'] === 'string' ? token['$type'] : effectiveType;\n  const tokenWithSubstitutedValue = value === rawValue ? token : { ...token, $value: value };\n  const withType: SwatchbookToken =\n    $type !== undefined && token['$type'] === undefined\n      ? ({ ...tokenWithSubstitutedValue, $type } as SwatchbookToken)\n      : (tokenWithSubstitutedValue as SwatchbookToken);\n  if (typeof value === 'string') {\n    const match = ALIAS_RE.exec(value);\n    if (match) return { kind: 'alias', target: match[1]! };\n    return { kind: 'literal', value: slimToken(withType) };\n  }\n  if ($type && COMPOSITE_TYPES.has($type) && (isPlainObject(value) || Array.isArray(value))) {\n    const aliasFields: Record<string, string> = {};\n    walkPartialAliasFields(value, '', aliasFields);\n    if (Object.keys(aliasFields).length > 0) {\n      return {\n        kind: 'partial-alias',\n        baseValue: slimToken(withType),\n        aliasFields,\n      };\n    }\n  }\n  return { kind: 'literal', value: slimToken(withType) };\n}\n\n// Walk `value` and replace any `{ $ref: '<JSON Pointer>' }` object with the\n// resolved target from `refLookup`. Terrazzo's resolver normalize pass\n// doesn't substitute cross-document `$ref` references in modifier source\n// values — they're only substituted at `resolver.apply()` time via\n// `processTokens`, which our `extractWritesFromModifiers` bypasses by\n// reading `resolver.source.modifiers` directly. This function fills that\n// gap by performing the same JSON Pointer substitution against an already-\n// resolved token snapshot (typically the resolver's baseline output).\n//\n// Unresolved pointers are left as-is — they then surface via\n// `unresolvedRefDiagnostic` (load-time) or the emit-wrap (runtime).\nfunction resolveRefsInValue(value: unknown, refLookup: TokenMap): unknown {\n  if (Array.isArray(value)) {\n    let changed = false;\n    const next: unknown[] = [];\n    for (const entry of value) {\n      const replaced = resolveRefsInValue(entry, refLookup);\n      if (replaced !== entry) changed = true;\n      next.push(replaced);\n    }\n    return changed ? next : value;\n  }\n  if (!isPlainObject(value)) return value;\n  const ref = value['$ref'];\n  if (typeof ref === 'string') {\n    const resolved = lookupJsonPointer(ref, refLookup);\n    if (resolved !== undefined) return resolved;\n    return value;\n  }\n  let changed = false;\n  const next: Record<string, unknown> = {};\n  for (const [k, v] of Object.entries(value)) {\n    const replaced = resolveRefsInValue(v, refLookup);\n    if (replaced !== v) changed = true;\n    next[k] = replaced;\n  }\n  return changed ? next : value;\n}\n\nfunction lookupJsonPointer(pointer: string, refLookup: TokenMap): unknown {\n  if (!pointer.startsWith('#/')) return undefined;\n  const parts = pointer\n    .slice(2)\n    .split('/')\n    .map((p) => p.replace(/~1/g, '/').replace(/~0/g, '~'));\n  for (let i = parts.length; i > 0; i--) {\n    const tokenID = parts.slice(0, i).join('.');\n    const token = refLookup[tokenID];\n    if (!token) continue;\n    let node: unknown = token;\n    for (const part of parts.slice(i)) {\n      if (node == null || typeof node !== 'object') return undefined;\n      node = (node as Record<string, unknown>)[part];\n    }\n    return node;\n  }\n  return undefined;\n}\n\n// Walks raw DTCG `$value` looking for `{path}`-shaped alias syntax. Used during modifier-source extraction.\nfunction walkPartialAliasFields(value: unknown, prefix: string, out: Record<string, string>): void {\n  if (typeof value === 'string') {\n    const match = ALIAS_RE.exec(value);\n    if (match && prefix) out[prefix] = match[1]!;\n    return;\n  }\n  if (Array.isArray(value)) {\n    value.forEach((entry, i) =>\n      walkPartialAliasFields(entry, prefix ? `${prefix}.${i}` : String(i), out),\n    );\n    return;\n  }\n  if (isPlainObject(value)) {\n    for (const [k, v] of Object.entries(value)) {\n      walkPartialAliasFields(v, prefix ? `${prefix}.${k}` : k, out);\n    }\n    return;\n  }\n  // Numbers, booleans, and other primitives carry no alias syntax — skip silently.\n}\n\nexport interface BuildTokenGraphResult {\n  graph: TokenGraph;\n  diagnostics: readonly Diagnostic[];\n}\n\nexport function buildTokenGraph(\n  parserInput: ParserInput,\n  axes: readonly Axis[],\n  defaultTuple: Record<string, string>,\n): BuildTokenGraphResult {\n  const baseline = parserInput.resolver.apply(defaultTuple);\n  const writesByPath = extractWritesFromModifiers(\n    parserInput.resolver.source?.modifiers ?? {},\n    axes,\n    baseline,\n  );\n  // Singleton-apply sweep: each non-default (axis, ctx) tuple.\n  // Records resolved values per singleton so writes-only paths\n  // (absent from the default-tuple resolve) get a meaningful\n  // baselineValue from the first axis/context they appear in.\n  const singletonList: { tuple: Record<string, string>; resolved: TokenMap }[] = [];\n  for (const axis of axes) {\n    for (const ctx of axis.contexts) {\n      if (ctx === axis.default) continue;\n      const tuple = { ...defaultTuple, [axis.name]: ctx };\n      const resolved = parserInput.resolver.apply(tuple);\n      singletonList.push({ tuple, resolved });\n    }\n  }\n  return assembleGraph(axes, baseline, writesByPath, singletonList);\n}\n\nfunction findFirstSingletonValue(\n  path: string,\n  singletons: readonly { tuple: Record<string, string>; resolved: TokenMap }[],\n): SwatchbookToken | undefined {\n  for (const { resolved } of singletons) {\n    if (resolved[path]) return resolved[path];\n  }\n  return undefined;\n}\n\nfunction validateAliasTargets(nodes: Record<string, TokenGraphNode>): Diagnostic[] {\n  const diagnostics: Diagnostic[] = [];\n  const pathExists = (path: string): boolean => path in nodes;\n\n  for (const [path, node] of Object.entries(nodes)) {\n    if (\n      node.baselineKind === 'alias' &&\n      node.baselineAliasTarget &&\n      !pathExists(node.baselineAliasTarget)\n    ) {\n      diagnostics.push(\n        unresolvableAliasDiagnostic('(baseline)', '(default)', path, node.baselineAliasTarget),\n      );\n    }\n    if (node.baselineKind === 'partial-alias' && node.baselinePartialFields) {\n      for (const target of Object.values(node.baselinePartialFields)) {\n        if (!pathExists(target)) {\n          diagnostics.push(unresolvableAliasDiagnostic('(baseline)', '(default)', path, target));\n        }\n      }\n    }\n    for (const [axis, axisWrites] of Object.entries(node.writes)) {\n      for (const [ctx, write] of Object.entries(axisWrites)) {\n        if (write.kind === 'alias' && !pathExists(write.target)) {\n          diagnostics.push(unresolvableAliasDiagnostic(axis, ctx, path, write.target));\n        } else if (write.kind === 'partial-alias') {\n          for (const target of Object.values(write.aliasFields)) {\n            if (!pathExists(target)) {\n              diagnostics.push(unresolvableAliasDiagnostic(axis, ctx, path, target));\n            }\n          }\n        }\n      }\n    }\n  }\n  return diagnostics;\n}\n\n// Walks every literal `$value` in the graph and reports DTCG color\n// objects whose `components` field is missing or non-array — the\n// shape that crashes `colorjs.io` inside `inGamut(...)` with the\n// unactionable `coords.map is not a function` traceback. Covers\n// top-level color tokens AND color sub-fields inside composites\n// (border, gradient, shadow) uniformly: any object whose\n// `colorSpace` is a string is treated as a color and validated.\nfunction validateColorShapes(nodes: Record<string, TokenGraphNode>): Diagnostic[] {\n  const diagnostics: Diagnostic[] = [];\n  for (const [path, node] of Object.entries(nodes)) {\n    if (node.baselineKind === 'literal') {\n      scanValueForColorShape(path, node.baselineValue.$value, '', diagnostics);\n    } else if (node.baselineKind === 'partial-alias') {\n      scanValueForColorShape(path, node.baselineValue.$value, '', diagnostics);\n    }\n    for (const axisWrites of Object.values(node.writes)) {\n      for (const write of Object.values(axisWrites)) {\n        if (write.kind === 'literal') {\n          scanValueForColorShape(path, write.value.$value, '', diagnostics);\n        } else if (write.kind === 'partial-alias') {\n          scanValueForColorShape(path, write.baseValue.$value, '', diagnostics);\n        }\n      }\n    }\n  }\n  return diagnostics;\n}\n\nfunction scanValueForColorShape(\n  tokenPath: string,\n  value: unknown,\n  fieldPath: string,\n  out: Diagnostic[],\n): void {\n  if (Array.isArray(value)) {\n    value.forEach((entry, i) => {\n      const nextPath = fieldPath ? `${fieldPath}.${i}` : String(i);\n      scanValueForColorShape(tokenPath, entry, nextPath, out);\n    });\n    return;\n  }\n  if (!isPlainObject(value)) return;\n  if (typeof value['colorSpace'] === 'string') {\n    const components = value['components'];\n    if (components === undefined) {\n      out.push(\n        malformedColorShapeDiagnostic(tokenPath, fieldPath, '`components` field is missing'),\n      );\n    } else if (!Array.isArray(components)) {\n      const refTarget = unresolvedRefTarget(components);\n      const componentsField = fieldPath ? `${fieldPath}.components` : 'components';\n      if (refTarget !== undefined) {\n        out.push(unresolvedRefDiagnostic(tokenPath, componentsField, refTarget));\n      } else {\n        out.push(\n          malformedColorShapeDiagnostic(\n            tokenPath,\n            fieldPath,\n            `\\`components\\` must be an array of numbers (got ${typeof components})`,\n          ),\n        );\n      }\n    }\n    return;\n  }\n  for (const [key, child] of Object.entries(value)) {\n    if (key.startsWith('$')) continue;\n    const nextPath = fieldPath ? `${fieldPath}.${key}` : key;\n    scanValueForColorShape(tokenPath, child, nextPath, out);\n  }\n}\n\n// Returns the JSON Pointer if `value` is an unresolved DTCG `$ref` object\n// (a plain object whose only non-`$`-prefixed shape is a string `$ref`\n// member). Returns `undefined` for anything else. Used to distinguish a\n// source-side malformation from an upstream parser failing to substitute\n// a `$ref` target.\nfunction unresolvedRefTarget(value: unknown): string | undefined {\n  if (!isPlainObject(value)) return undefined;\n  const ref = value['$ref'];\n  if (typeof ref !== 'string') return undefined;\n  return ref;\n}\n\nfunction detectAliasCycles(nodes: Record<string, TokenGraphNode>): Diagnostic[] {\n  const diagnostics: Diagnostic[] = [];\n  const reportedCycles = new Set<string>();\n\n  const aliasTargets = new Map<string, Set<string>>();\n  for (const [path, node] of Object.entries(nodes)) {\n    const targets = new Set<string>();\n    if (node.baselineKind === 'alias' && node.baselineAliasTarget) {\n      targets.add(node.baselineAliasTarget);\n    }\n    if (node.baselineKind === 'partial-alias' && node.baselinePartialFields) {\n      for (const target of Object.values(node.baselinePartialFields)) targets.add(target);\n    }\n    for (const axisWrites of Object.values(node.writes)) {\n      for (const write of Object.values(axisWrites)) {\n        if (write.kind === 'alias') targets.add(write.target);\n        else if (write.kind === 'partial-alias') {\n          for (const target of Object.values(write.aliasFields)) targets.add(target);\n        }\n      }\n    }\n    aliasTargets.set(path, targets);\n  }\n\n  for (const startPath of Object.keys(nodes)) {\n    const stack: string[] = [];\n    const onStack = new Set<string>();\n    const dfs = (current: string): void => {\n      if (onStack.has(current)) {\n        const idx = stack.indexOf(current);\n        const cycle = stack.slice(idx).concat(current);\n        const canonical = [...cycle].toSorted().join(' → ');\n        if (!reportedCycles.has(canonical)) {\n          reportedCycles.add(canonical);\n          diagnostics.push(aliasCycleDiagnostic(cycle[0]!, cycle.slice(1, -1)));\n        }\n        return;\n      }\n      stack.push(current);\n      onStack.add(current);\n      const targets = aliasTargets.get(current);\n      if (targets) {\n        for (const target of targets) {\n          if (target in nodes) dfs(target);\n        }\n      }\n      stack.pop();\n      onStack.delete(current);\n    };\n    dfs(startPath);\n  }\n\n  return diagnostics;\n}\n\nfunction assembleGraph(\n  axes: readonly Axis[],\n  baseline: TokenMap,\n  writesByPath: Record<string, Record<string, Record<string, WriteValue>>>,\n  singletonList: readonly { tuple: Record<string, string>; resolved: TokenMap }[],\n): BuildTokenGraphResult {\n  const pathUniverse = new Set<string>([...Object.keys(baseline), ...Object.keys(writesByPath)]);\n  for (const { resolved } of singletonList) {\n    for (const path of Object.keys(resolved)) pathUniverse.add(path);\n  }\n\n  const nodes: Record<string, TokenGraphNode> = {};\n  for (const path of pathUniverse) {\n    const baselineForNode = baseline[path] ?? findFirstSingletonValue(path, singletonList);\n    nodes[path] = buildNode(baselineForNode, writesByPath[path] ?? {});\n  }\n\n  const axisDefaults: Record<string, string> = {};\n  const axisContexts: Record<string, readonly string[]> = {};\n  for (const axis of axes) {\n    axisDefaults[axis.name] = axis.default;\n    axisContexts[axis.name] = axis.contexts;\n  }\n\n  const aliasDiagnostics = validateAliasTargets(nodes);\n  const cycleDiagnostics = detectAliasCycles(nodes);\n  const colorShapeDiagnostics = validateColorShapes(nodes);\n\n  computeAffectedBy(\n    nodes,\n    axes.map((a) => a.name),\n  );\n\n  return {\n    graph: { nodes, axes: axes.map((a) => a.name), axisDefaults, axisContexts },\n    diagnostics: [...aliasDiagnostics, ...cycleDiagnostics, ...colorShapeDiagnostics],\n  };\n}\n\nfunction buildNode(\n  baselineToken: SwatchbookToken | undefined,\n  writes: Record<string, Record<string, WriteValue>>,\n): TokenGraphNode {\n  if (!baselineToken) {\n    throw new Error(\n      'buildTokenGraph: path has writes but no resolvable value at default or any singleton tuple — graph cannot represent it',\n    );\n  }\n  const baselineKind = detectBaselineKind(baselineToken);\n  const aliases: string[] = [];\n  let baselineAliasTarget: string | undefined;\n  let baselinePartialFields: Record<string, string> | undefined;\n\n  if (baselineKind === 'alias') {\n    // detectBaselineKind only returns 'alias' when aliasOf is a string\n    baselineAliasTarget = baselineToken.aliasOf as string;\n    aliases.push(baselineAliasTarget);\n  } else if (baselineKind === 'partial-alias') {\n    baselinePartialFields = extractPartialAliasFields(baselineToken.partialAliasOf);\n    for (const target of Object.values(baselinePartialFields)) aliases.push(target);\n  }\n\n  return {\n    baselineValue: slimToken(baselineToken),\n    baselineKind,\n    ...(baselineAliasTarget !== undefined ? { baselineAliasTarget } : {}),\n    ...(baselinePartialFields !== undefined ? { baselinePartialFields } : {}),\n    writes,\n    affectedBy: [],\n    aliases,\n    aliasedBy: [],\n  };\n}\n\nfunction detectBaselineKind(token: SwatchbookToken): 'literal' | 'alias' | 'partial-alias' {\n  if (typeof token.aliasOf === 'string') return 'alias';\n  if (token.partialAliasOf !== undefined) return 'partial-alias';\n  return 'literal';\n}\n\nfunction extractPartialAliasFields(partialAliasOf: unknown): Record<string, string> {\n  const fields: Record<string, string> = {};\n  walkPartialAliasTargets(partialAliasOf, '', fields);\n  return fields;\n}\n\n// Generous cycle guard. Acyclic propagation terminates in at most\n// (max alias-chain depth) iterations — 1000 covers any realistic project.\nconst AFFECTED_BY_FIXPOINT_BOUND = 1000;\n\nfunction computeAliasTargets(nodes: Record<string, TokenGraphNode>): Record<string, Set<string>> {\n  const out: Record<string, Set<string>> = {};\n  for (const [path, node] of Object.entries(nodes)) {\n    const targets = new Set<string>(node.aliases);\n    for (const axisWrites of Object.values(node.writes)) {\n      for (const write of Object.values(axisWrites)) {\n        if (write.kind === 'alias') targets.add(write.target);\n        else if (write.kind === 'partial-alias') {\n          for (const t of Object.values(write.aliasFields)) targets.add(t);\n        }\n      }\n    }\n    out[path] = targets;\n  }\n  return out;\n}\n\nexport function computeAffectedBy(\n  nodes: Record<string, TokenGraphNode>,\n  axisOrder: readonly string[],\n): void {\n  const affected: Record<string, Set<string>> = {};\n  for (const [path, node] of Object.entries(nodes)) {\n    affected[path] = new Set(Object.keys(node.writes));\n  }\n\n  const aliasTargets = computeAliasTargets(nodes);\n\n  let iterations = 0;\n  let changed = true;\n  while (changed) {\n    iterations += 1;\n    if (iterations > AFFECTED_BY_FIXPOINT_BOUND) {\n      throw new Error(\n        `affectedBy fixpoint did not stabilize after ${AFFECTED_BY_FIXPOINT_BOUND} iterations`,\n      );\n    }\n    changed = false;\n    for (const [path, targets] of Object.entries(aliasTargets)) {\n      for (const target of targets) {\n        const targetAffected = affected[target];\n        if (!targetAffected) continue;\n        for (const axis of targetAffected) {\n          if (!affected[path]!.has(axis)) {\n            affected[path]!.add(axis);\n            changed = true;\n          }\n        }\n      }\n    }\n  }\n\n  for (const [path, node] of Object.entries(nodes)) {\n    (node as { affectedBy: readonly string[] }).affectedBy = axisOrder.filter((a) =>\n      affected[path]!.has(a),\n    );\n  }\n\n  const aliasedBy: Record<string, Set<string>> = {};\n  for (const [path, targets] of Object.entries(aliasTargets)) {\n    for (const target of targets) {\n      (aliasedBy[target] ??= new Set()).add(path);\n    }\n  }\n  for (const [target, set] of Object.entries(aliasedBy)) {\n    const node = nodes[target];\n    if (node) (node as { aliasedBy: readonly string[] }).aliasedBy = [...set].toSorted();\n  }\n}\n\n// Walks Terrazzo's already-extracted `partialAliasOf` map where values are bare path strings (no braces). Used during baseline node construction.\nfunction walkPartialAliasTargets(\n  value: unknown,\n  prefix: string,\n  out: Record<string, string>,\n): void {\n  if (typeof value === 'string') {\n    if (prefix) out[prefix] = value;\n    return;\n  }\n  if (Array.isArray(value)) {\n    value.forEach((entry, i) =>\n      walkPartialAliasTargets(entry, prefix ? `${prefix}.${i}` : String(i), out),\n    );\n    return;\n  }\n  if (isPlainObject(value)) {\n    for (const [k, v] of Object.entries(value)) {\n      walkPartialAliasTargets(v, prefix ? `${prefix}.${k}` : k, out);\n    }\n    return;\n  }\n  // partialAliasOf values are strings or nested structures; primitives carry no path data.\n}\n\n/**\n * Build a token-graph from layered/per-tuple resolved output (no resolver\n * source available). Used for layered configs.\n *\n * Plain-parse projects do NOT route here — they go through `buildTokenGraph`\n * via a synthetic resolver constructed by `loadResolverPermutations`.\n *\n * Writes are inferred by diffing each singleton's resolved TokenMap\n * against the baseline: any path whose value differs from the baseline\n * yields a WriteValue derived from the singleton token's alias metadata.\n *\n * @param axes - Project axes (post-disabledAxes filter).\n * @param baseline - Resolved TokenMap for the default tuple.\n * @param perSingletonResolved - All per-tuple resolved maps, keyed by\n *   `permutationID(tuple)`. The function only reads singleton tuples\n *   (one non-default axis at a time); joint tuples in the map are ignored.\n * @param defaultTuple - The project's default tuple (axisName → defaultContext).\n */\nexport function buildTokenGraphFromLayered(\n  axes: readonly Axis[],\n  baseline: TokenMap,\n  perSingletonResolved: Readonly<Record<string, TokenMap>>,\n  defaultTuple: Readonly<Record<string, string>>,\n): BuildTokenGraphResult {\n  const writesByPath = extractWritesFromLayeredSingletons(\n    axes,\n    baseline,\n    perSingletonResolved,\n    defaultTuple,\n  );\n  const singletonList: { tuple: Record<string, string>; resolved: TokenMap }[] = [];\n  for (const axis of axes) {\n    for (const ctx of axis.contexts) {\n      if (ctx === axis.default) continue;\n      const singletonTuple = { ...defaultTuple, [axis.name]: ctx };\n      const resolved = perSingletonResolved[permutationID(singletonTuple)];\n      if (resolved) singletonList.push({ tuple: singletonTuple, resolved });\n    }\n  }\n  return assembleGraph(axes, baseline, writesByPath, singletonList);\n}\n\nfunction extractWritesFromLayeredSingletons(\n  axes: readonly Axis[],\n  baseline: TokenMap,\n  perSingletonResolved: Readonly<Record<string, TokenMap>>,\n  defaultTuple: Readonly<Record<string, string>>,\n): Record<string, Record<string, Record<string, WriteValue>>> {\n  const out: Record<string, Record<string, Record<string, WriteValue>>> = {};\n  for (const axis of axes) {\n    for (const ctx of axis.contexts) {\n      if (ctx === axis.default) continue;\n      const singletonTuple = { ...defaultTuple, [axis.name]: ctx };\n      const id = permutationID(singletonTuple);\n      const resolved = perSingletonResolved[id];\n      if (!resolved) continue;\n      for (const [path, token] of Object.entries(resolved)) {\n        const baselineToken = baseline[path];\n        const sameAsBaseline =\n          baselineToken !== undefined && valueKey(token) === valueKey(baselineToken);\n        const writeValue = toWriteValueFromResolvedToken(token);\n        // Always record alias-shape writes — even when they happen to resolve to\n        // the same value at this singleton, the alias target may differ from\n        // baseline's, and that difference matters at joint tuples where the\n        // target's value diverges. Only literal writes can be safely skipped on\n        // value coincidence (a literal == literal at all tuples it applies to).\n        if (writeValue.kind === 'literal' && sameAsBaseline) continue;\n        if (\n          writeValue.kind === 'alias' &&\n          typeof baselineToken?.aliasOf === 'string' &&\n          baselineToken.aliasOf === writeValue.target &&\n          sameAsBaseline\n        )\n          continue;\n        // partial-alias: rare for both sides to have identical aliasFields; just always record\n        (out[path] ??= {})[axis.name] ??= {};\n        out[path]![axis.name]![ctx] = writeValue;\n      }\n    }\n  }\n  return out;\n}\n\nfunction toWriteValueFromResolvedToken(token: SwatchbookToken): WriteValue {\n  if (typeof token.aliasOf === 'string') {\n    return { kind: 'alias', target: token.aliasOf };\n  }\n  if (token.partialAliasOf !== undefined) {\n    return {\n      kind: 'partial-alias',\n      baseValue: slimToken(token),\n      aliasFields: extractPartialAliasFields(token.partialAliasOf),\n    };\n  }\n  return { kind: 'literal', value: slimToken(token) };\n}\n","import { validateChrome } from '#/chrome.ts';\nimport { BufferedLogger, dedupeDiagnostics, toDiagnostics } from '#/diagnostics.ts';\nimport { validateDisabledAxes } from '#/disabled-axes.ts';\nimport { validatePresets } from '#/presets.ts';\nimport { validateCssOptions } from '#/terrazzo-options.ts';\nimport { canonicalKey } from '#/tuple-key.ts';\nimport { resolveDefaultTuple } from '#/permutations/default.ts';\nimport { normalizePermutations } from '#/permutations/normalize.ts';\nimport { computeTokenListing } from '#/token-listing.ts';\nimport { buildTokenGraph, buildTokenGraphFromLayered } from '#/token-graph/build.ts';\nimport type { BuildTokenGraphResult } from '#/token-graph/build.ts';\nimport { buildFailedDiagnostic } from '#/token-graph/diagnostics.ts';\nimport { listPaths } from '#/token-graph/queries.ts';\nimport { resolveAllWithProvenanceAt } from '#/token-graph/walk.ts';\nimport { permutationID } from '#/types.ts';\nimport type { Axis, Config, Diagnostic, Permutation, Project, TokenMap } from '#/types.ts';\n\n/** Default `cssVarPrefix` applied when the config omits one. Namespaces\n * emitted vars (`--swatch-…`) and data attributes (`data-swatch-…`) so\n * swatchbook output doesn't collide with whatever else the consumer has\n * claimed in `:root`. Override in config to use a project-specific prefix\n * or set to `''` to opt out of namespacing. */\nconst DEFAULT_CSS_VAR_PREFIX = 'swatch';\n\n// Opt-in phase timing for `loadProject`. Activate with the env var\n// `SWATCHBOOK_LOG_VERBOSE=1`. Each major phase logs its duration to\n// stdout as `[swatchbook:load] <phase>: <ms>ms`. When the env var is\n// unset, the overhead is a few `performance.now()` calls per phase\n// (negligible) and no console output.\n//\n// Primary use case: a consumer reports a hung or slow `loadProject` and\n// we need to know which phase is the offender before reaching for a\n// full CPU profile.\nfunction isVerbose(): boolean {\n  return process.env['SWATCHBOOK_LOG_VERBOSE'] === '1';\n}\n\nfunction logPhase(label: string, startedAt: number): void {\n  if (!isVerbose()) return;\n  const ms = performance.now() - startedAt;\n  // Opt-in debug output, gated behind the verbose env var.\n  console.log(`[swatchbook:load] ${label}: ${ms.toFixed(0)}ms`);\n}\n\n/**\n * Load a swatchbook project from a config. Read tokens at any axis\n * tuple via `project.resolveAt(tuple)`; read the default-tuple\n * snapshot directly via `project.defaultTokens`.\n *\n * The `cwd` defaults to `process.cwd()`. All relative paths in\n * `config` (token globs, `resolver`, layered axis overlay globs)\n * resolve against this directory.\n */\nexport async function loadProject(config: Config, cwd: string = process.cwd()): Promise<Project> {\n  const loadStart = performance.now();\n  const logger = new BufferedLogger({ level: 'warn' });\n  const cssVarPrefix = config.cssVarPrefix ?? DEFAULT_CSS_VAR_PREFIX;\n  const configWithDefaults: Config = {\n    ...config,\n    cssVarPrefix,\n    defaultColorFormat: config.defaultColorFormat ?? 'hex',\n  };\n  const tParse = performance.now();\n  const normalized = await normalizePermutations(configWithDefaults, cwd, logger);\n  logPhase('parse + normalize', tParse);\n\n  const { names: disabledAxes, diagnostics: disabledDiagnostics } = validateDisabledAxes(\n    config.disabledAxes,\n    normalized.axes,\n  );\n\n  const {\n    axes: filteredAxes,\n    permutations: filteredPermutations,\n    resolved: filteredResolved,\n  } = applyDisabledAxes(\n    normalized.axes,\n    normalized.permutations,\n    normalized.resolved,\n    disabledAxes,\n  );\n\n  const { tuple: defaultTuple, diagnostics: defaultDiagnostics } = resolveDefaultTuple(\n    config.default,\n    filteredAxes,\n  );\n\n  const { presets, diagnostics: presetDiagnostics } = validatePresets(config.presets, filteredAxes);\n\n  const { diagnostics: cssOptionsDiagnostics } = validateCssOptions(config.cssOptions);\n\n  const tListing = performance.now();\n  const { listing, diagnostics: listingDiagnostics } =\n    normalized.parserInput !== undefined\n      ? await computeTokenListing(normalized.parserInput, cwd, cssVarPrefix, {\n          ...(config.cssOptions !== undefined && { cssOptions: config.cssOptions }),\n          ...(config.listingOptions !== undefined && { listingOptions: config.listingOptions }),\n          ...(config.terrazzoPlugins !== undefined && { extraPlugins: config.terrazzoPlugins }),\n        })\n      : { listing: {}, diagnostics: [] };\n  logPhase('token-listing build', tListing);\n\n  // `defaultTuple` here is the post-disabledAxes-filter version.\n  const projectDefaultTuple: Record<string, string> = {};\n  for (const axis of filteredAxes) projectDefaultTuple[axis.name] = axis.default;\n\n  // Build the token graph. Resolver-backed projects build from the live\n  // Resolver; layered / plain-parse projects infer writes by diffing\n  // per-singleton resolved maps.\n  const tGraph = performance.now();\n  let tokenGraphResult: BuildTokenGraphResult;\n  try {\n    if (normalized.parserInput?.resolver) {\n      tokenGraphResult = buildTokenGraph(normalized.parserInput, filteredAxes, projectDefaultTuple);\n    } else {\n      const baselineFromLayered =\n        filteredResolved[permutationID(projectDefaultTuple)] ??\n        filteredResolved[Object.values(filteredPermutations)[0]?.name ?? ''] ??\n        {};\n      tokenGraphResult = buildTokenGraphFromLayered(\n        filteredAxes,\n        baselineFromLayered,\n        filteredResolved,\n        projectDefaultTuple,\n      );\n    }\n    logPhase('graph build', tGraph);\n  } catch (error) {\n    const detail = error instanceof Error ? error.message : String(error);\n    tokenGraphResult = {\n      graph: {\n        nodes: {},\n        axes: filteredAxes.map((a) => a.name),\n        axisDefaults: projectDefaultTuple,\n        axisContexts: Object.fromEntries(filteredAxes.map((a) => [a.name, a.contexts])),\n      },\n      diagnostics: [buildFailedDiagnostic(detail)] as readonly Diagnostic[],\n    };\n  }\n\n  // resolveAt: graph-backed for all projects. Fills in axis defaults (so\n  // partial tuples canonicalize to the same key as a fully-specified\n  // equivalent) and memoizes by canonical key so repeated calls with the\n  // same effective tuple return the same instance.\n  const resolveAt = (() => {\n    const memo = new Map<string, TokenMap>();\n    return (tuple: Record<string, string>): TokenMap => {\n      const full: Record<string, string> = { ...projectDefaultTuple };\n      for (const axis of filteredAxes) {\n        const val = tuple[axis.name];\n        if (val !== undefined) full[axis.name] = val;\n      }\n      const key = canonicalKey(full);\n      const cached = memo.get(key);\n      if (cached) return cached;\n      const result = resolveAllWithProvenanceAt(tokenGraphResult.graph, full);\n      memo.set(key, result);\n      return result;\n    };\n  })();\n\n  // `project.defaultTokens` is the resolved snapshot at the user's default\n  // tuple, served through the same graph-backed `resolveAt` as every other\n  // tuple — so it carries the slim `SwatchbookToken` shape the type promises\n  // rather than the raw `TokenNormalized` the resolver emits.\n  const defaultTokens = resolveAt(defaultTuple);\n\n  // `validateChrome` checks targets against the project's path universe.\n  // `listPaths` returns every path present in the graph.\n  const tokenIDs = new Set<string>(listPaths(tokenGraphResult.graph));\n  const { entries: chrome, diagnostics: chromeDiagnostics } = validateChrome(\n    config.chrome,\n    tokenIDs,\n  );\n\n  logPhase('total', loadStart);\n\n  return {\n    config: configWithDefaults,\n    axes: filteredAxes,\n    disabledAxes,\n    presets,\n    chrome,\n    defaultTokens,\n    defaultTuple: projectDefaultTuple,\n    resolveAt,\n    tokenGraph: tokenGraphResult.graph,\n    sourceFiles: normalized.sourceFiles,\n    cwd,\n    listing,\n    diagnostics: dedupeDiagnostics([\n      ...toDiagnostics(logger),\n      ...normalized.diagnostics,\n      ...disabledDiagnostics,\n      ...defaultDiagnostics,\n      ...presetDiagnostics,\n      ...chromeDiagnostics,\n      ...cssOptionsDiagnostics,\n      ...listingDiagnostics,\n      ...tokenGraphResult.diagnostics,\n    ]),\n  };\n}\n\n// Project `disabledAxes` onto the loader output: drop disabled axes from\n// the axis list, keep only the permutations whose disabled-axis values\n// equal their axis defaults, and prune `resolved` to the surviving\n// permutation names. Returns the original triple unchanged when\n// `disabled` is empty.\nfunction applyDisabledAxes(\n  axes: Axis[],\n  permutations: Permutation[],\n  resolved: Record<string, TokenMap>,\n  disabled: string[],\n): { axes: Axis[]; permutations: Permutation[]; resolved: Record<string, TokenMap> } {\n  if (disabled.length === 0) return { axes, permutations, resolved };\n\n  const disabledSet = new Set(disabled);\n  const axisDefaults = new Map<string, string>();\n  for (const axis of axes) axisDefaults.set(axis.name, axis.default);\n\n  const filteredAxes = axes.filter((a) => !disabledSet.has(a.name));\n  const filteredPermutations = permutations.filter((perm) => {\n    for (const name of disabled) {\n      if (perm.input[name] !== axisDefaults.get(name)) return false;\n    }\n    return true;\n  });\n  const canonicalised: Record<string, TokenMap> = {};\n  for (const perm of filteredPermutations) {\n    const tokens = resolved[perm.name];\n    if (!tokens) continue;\n    const filteredTuple: Record<string, string> = {};\n    for (const axis of filteredAxes)\n      filteredTuple[axis.name] = perm.input[axis.name] ?? axis.default;\n    canonicalised[permutationID(filteredTuple)] = tokens;\n  }\n  // Re-key permutation names to match the canonicalised (filtered-axes-only) key shape.\n  const rekeyed = filteredPermutations.map((perm) => {\n    const filteredTuple: Record<string, string> = {};\n    for (const axis of filteredAxes)\n      filteredTuple[axis.name] = perm.input[axis.name] ?? axis.default;\n    return { ...perm, name: permutationID(filteredTuple) };\n  });\n  return { axes: filteredAxes, permutations: rekeyed, resolved: canonicalised };\n}\n","/**\n * Escape backslash + double-quote in a CSS string literal — used for\n * `data-*` attribute selector values and other places where token /\n * context names may contain characters that need quoting.\n */\nexport function cssEscape(value: string): string {\n  return value.replaceAll('\\\\', '\\\\\\\\').replaceAll('\"', '\\\\\"');\n}\n","import type { TokenNormalized } from '@terrazzo/parser';\nimport { generateShorthand, makeCSSVar, transformCSSValue } from '@terrazzo/token-tools/css';\nimport { CHROME_ROLES, CHROME_VAR_PREFIX, DEFAULT_CHROME_MAP } from '#/chrome.ts';\nimport { cssEscape } from '#/css-escape.ts';\nimport { dataAttr } from '#/data-attr.ts';\nimport { listPaths } from '#/token-graph/queries.ts';\nimport { resolveAliasAllAt, resolveAllAt } from '#/token-graph/walk.ts';\nimport { canonicalKey } from '#/tuple-key.ts';\nimport type { Project, TokenMap } from '#/types.ts';\nimport { valueKey } from '#/value-key.ts';\n\n// Internal alias: the raw Terrazzo-shape map this emitter passes into\n// `transformCSSValue` / `generateShorthand`. The graph stores slim\n// `SwatchbookToken` shapes (no `id`, `source`, `mode`, etc.). The CSS\n// emitter needs `token.id` (= the token path) for `transformAlias` and\n// `defaultAliasTransform`. `withSyntheticIds` injects `id: path` so\n// `transformCSSValue` can resolve alias var references correctly without\n// requiring the full Terrazzo shape in the graph.\ntype RawTokenMap = Record<string, TokenNormalized>;\n\nfunction withSyntheticIds(map: TokenMap): RawTokenMap {\n  const out: RawTokenMap = {};\n  for (const [path, token] of Object.entries(map)) {\n    out[path] = { ...token, id: path } as unknown as TokenNormalized;\n  }\n  return out;\n}\n\n// Produces a token's emitted CSS value, applying the same cssOptions the\n// listing build (plugin-css) applies — `legacyHex` color output and a user\n// `transform` hook — so preview CSS and the listing previewValue come from\n// one option set and never diverge.\ntype TransformValue = (\n  token: TokenNormalized,\n  tokensSet: RawTokenMap,\n  permutation: Record<string, string>,\n) => ReturnType<typeof transformCSSValue>;\n\n// Distinguishes a token's variance shape so the emitter can route it.\ntype VarianceInfo =\n  | {\n      kind: 'baseline-only';\n    }\n  | {\n      kind: 'single-axis';\n      axis: string;\n    }\n  | {\n      kind: 'orthogonal-after-probe';\n      touching: ReadonlySet<string>;\n    }\n  | {\n      kind: 'joint-variant';\n      touching: ReadonlySet<string>;\n      jointCases: readonly JointCase[];\n    };\n\n// One concrete partial tuple (2+ axes at non-default contexts) where\n// cascade composition would NOT produce the cartesian-correct value\n// for this token. Emitted as a compound `[data-axis=\"…\"][…]` block.\n//\n// `tuple` carries only the non-default axes — its `Object.keys` length\n// is the joint case's arity (2 for pairs, 3 for triples, etc.).\ninterface JointCase {\n  tuple: Record<string, string>;\n  cartesianValueKey: string;\n}\n\n// Default cap on joint-case arity probed per token. See `Config.maxJointArity`\n// in the public types for the per-project override and the failure-mode\n// tradeoffs. Per-token work scales as\n// `Σ C(|affectedBy|, k) × Π non_default_contexts` for k = 2..arity.\n// 4 covers virtually all design-system shapes (mode × brand × density ×\n// contrast is the largest real-world joint anyone tends to express);\n// beyond that, joint blocks aren't emitted and the cascade resolves to\n// whatever lower-arity composition produces.\nconst DEFAULT_MAX_JOINT_ARITY = 4;\n\n// Classify every token in a project. Returns a Map keyed by token path.\n// Reads from `project.tokenGraph` — the sole resolution surface.\n//\n// For tokens affected by 2+ axes, probes joint divergences from arity 2\n// up to `min(|affectedBy|, MAX_JOINT_ARITY)`. Each probe checks whether\n// cascade composition (baseline + per-axis cell overlays in project axis\n// order + lower-arity joint corrections recorded for this token) produces\n// the cartesian-correct value at the candidate tuple. When it doesn't,\n// an arity-k joint case is recorded — which will become an arity-k\n// compound block at emission.\n//\n// The per-token bound on probing scope is what keeps this tractable for\n// many-axis projects: a token affected by 3 axes only ever probes within\n// those 3 axes, regardless of how many axes the project has overall.\nfunction analyzeProjectVariance(project: Project): Map<string, VarianceInfo> {\n  const result = new Map<string, VarianceInfo>();\n  const { axes, tokenGraph, defaultTuple } = project;\n\n  if (axes.length === 0) {\n    for (const path of listPaths(tokenGraph)) {\n      result.set(path, { kind: 'baseline-only' });\n    }\n    return result;\n  }\n\n  const axisByName = new Map<string, Axis>(axes.map((a) => [a.name, a]));\n  const projectAxisOrder = new Map<string, number>(axes.map((a, i) => [a.name, i]));\n  const configuredMaxArity =\n    typeof project.config.maxJointArity === 'number' && project.config.maxJointArity > 0\n      ? project.config.maxJointArity\n      : DEFAULT_MAX_JOINT_ARITY;\n\n  // The emitter uses `resolveAllAt(tokenGraph, defaultTuple)` for its\n  // baseline; our cascade simulation matches that exactly.\n  const baselineValues = resolveAllAt(tokenGraph, defaultTuple);\n\n  // Per-axis-context resolved snapshots, memoized — the simulation\n  // calls `resolveAllAt(graph, { default with axis=ctx })` many times\n  // across tokens, and the walker memoizes per-tuple but a Map lookup\n  // here cuts the per-cell call back to a single `resolveAllAt` per\n  // axis-context across all tokens.\n  const cellSnapshots = new Map<string, TokenMap>();\n  function cellAt(axisName: string, ctx: string): TokenMap {\n    const key = `${axisName}=${ctx}`;\n    let snap = cellSnapshots.get(key);\n    if (snap === undefined) {\n      snap = resolveAllAt(tokenGraph, { ...defaultTuple, [axisName]: ctx });\n      cellSnapshots.set(key, snap);\n    }\n    return snap;\n  }\n\n  for (const path of listPaths(tokenGraph)) {\n    const node = tokenGraph.nodes[path];\n    if (!node) continue;\n    const touching: Set<string> = new Set(node.affectedBy);\n\n    if (touching.size === 0) {\n      result.set(path, { kind: 'baseline-only' });\n      continue;\n    }\n\n    if (touching.size === 1) {\n      const [axis] = touching;\n      if (axis === undefined) continue;\n      result.set(path, { kind: 'single-axis', axis });\n      continue;\n    }\n\n    // Order the touching axes by project axis position so cascade-composition\n    // matches CSS source order at emission time.\n    const touchingAxes: Axis[] = [...touching]\n      .map((name) => axisByName.get(name))\n      .filter((a): a is Axis => a !== undefined)\n      .toSorted(\n        (a, b) => (projectAxisOrder.get(a.name) ?? 0) - (projectAxisOrder.get(b.name) ?? 0),\n      );\n\n    const jointCases: JointCase[] = [];\n    const maxArity = Math.min(touchingAxes.length, configuredMaxArity);\n    const baselineKey = valueKey(baselineValues[path]);\n\n    for (let arity = 2; arity <= maxArity; arity++) {\n      for (const combo of axisCombinations(touchingAxes, arity)) {\n        for (const partialTuple of contextProducts(combo)) {\n          const fullTuple = { ...defaultTuple, ...partialTuple };\n          const cartesianKey = valueKey(resolveAllAt(tokenGraph, fullTuple)[path]);\n\n          // Compose cascade value: baseline → per-axis cells (project axis\n          // order, last wins, only when cell value differs from baseline —\n          // the emitter's delta-paths rule, mirrored here) → lower-arity\n          // joint corrections already recorded for this token (arity\n          // ascending, matching emission order).\n          let composedKey = baselineKey;\n          for (const axis of touchingAxes) {\n            const ctx = fullTuple[axis.name];\n            if (ctx === undefined || ctx === defaultTuple[axis.name]) continue;\n            const cellKey = valueKey(cellAt(axis.name, ctx)[path]);\n            if (cellKey !== baselineKey) {\n              composedKey = cellKey;\n            }\n          }\n          for (const jc of jointCases) {\n            if (isPartialTupleSubset(jc.tuple, fullTuple)) {\n              composedKey = jc.cartesianValueKey;\n            }\n          }\n\n          if (cartesianKey !== composedKey) {\n            jointCases.push({\n              tuple: { ...partialTuple },\n              cartesianValueKey: cartesianKey,\n            });\n          }\n        }\n      }\n    }\n\n    if (jointCases.length === 0) {\n      result.set(path, { kind: 'orthogonal-after-probe', touching });\n    } else {\n      result.set(path, { kind: 'joint-variant', touching, jointCases });\n    }\n  }\n\n  return result;\n}\n\n// True if every axis=ctx in `partial` appears the same way in `full`.\nfunction isPartialTupleSubset(\n  partial: Record<string, string>,\n  full: Record<string, string>,\n): boolean {\n  for (const [axis, ctx] of Object.entries(partial)) {\n    if (full[axis] !== ctx) return false;\n  }\n  return true;\n}\n\n/** @internal Addon-internal smart-emitter options. Not part of the public API. */\nexport interface EmitAxisProjectedCssOptions {\n  /** Override the prefix from project config (default: `project.config.cssVarPrefix ?? ''`). */\n  prefix?: string;\n  /**\n   * Validated chrome-alias entries from `Project.chrome`. Each `source →\n   * target` pair appends `--<prefix>-<source>: var(--<prefix>-<target>);`\n   * to a trailing `:root` block. Defaults to `project.chrome`. See\n   * `validateChrome`.\n   */\n  chrome?: Record<string, string>;\n  /**\n   * Pre-computed variance analysis. When omitted, the emitter calls\n   * `analyzeProjectVariance(project)` itself. Callers that need the\n   * analysis for other purposes (diagnostics, alternative emit paths)\n   * can compute it once and pass it here to avoid duplicate work.\n   */\n  variance?: Map<string, VarianceInfo>;\n}\n\n/**\n * Emit a single concatenated stylesheet by routing each token to the\n * cheapest emit strategy that still produces the spec-correct value\n * at every tuple. Spec-faithful for any DTCG-compliant resolver\n * (orthogonal or not):\n *\n * - **Baseline-only tokens** — emitted once in `:root`, never in any cell\n * - **Single-axis tokens** — emitted in `:root` plus the touching axis's\n *   cell blocks (standard projection: `[data-<prefix>-<axis>=\"<ctx>\"]`)\n * - **Orthogonal-after-probe tokens** (touched by 2+ axes but\n *   cell-composition matches cartesian) — emitted in `:root` plus\n *   every touching axis's cell blocks; CSS cascade resolves the\n *   correct value at any tuple\n * - **Joint-variant tokens** (cell composition diverges from cartesian\n *   at some joint tuple) — emitted in `:root` plus per-axis cell blocks\n *   AS WELL AS compound `[data-A=\"ctx_a\"][data-B=\"ctx_b\"]` blocks\n *   carrying the cartesian-correct value at exactly the divergent\n *   joint tuples. Compound selector specificity `(0,2,0)` beats the\n *   singletons' `(0,1,0)`, so the joint cell wins under cascade.\n *\n * Smart dedup: every cell re-emits a token's value when ANY axis touches\n * the token (not just when this cell differs from baseline). For\n * orthogonal-after-probe tokens this means the last touching axis's\n * cell wins under cascade — which matches what `analyzeProjectVariance`\n * already verified for the `orthogonal-after-probe` classification.\n *\n * The classification work is the value-comparison + targeted-joint-probe\n * pass in `analyzeProjectVariance`. The emitter consumes that analysis\n * and does no spec reasoning of its own — every routing decision is\n * already in the `VarianceInfo` for the token.\n *\n * Output size scales with `baseline + per-axis cells + joint compound\n * blocks`. For mostly-orthogonal fixtures, dramatically smaller than\n * cartesian. In the worst case (every token touched by every axis with\n * joint variance on every pair), output approaches cartesian but never\n * exceeds it.\n *\n * For single-axis projects (a synthetic `theme` axis, or a resolver\n * with one modifier), the cell selector uses the axis's actual name\n * — e.g. `[data-mode=\"Dark\"]`.\n *\n * Public, but scoped to swatchbook's own preview build: this is how the\n * addon produces the stylesheet it injects into Storybook and how the MCP\n * server answers CSS-preview queries — both call it directly through this\n * entry rather than duplicating the emission logic. It is not a\n * general-purpose production CSS emitter; consumers building their own\n * transform pipeline for a shipped platform should drive\n * `@terrazzo/plugin-css` / the Terrazzo CLI against their DTCG sources\n * instead, the same way swatchbook's own preview build does internally.\n */\nexport function emitAxisProjectedCss(\n  project: Project,\n  options: EmitAxisProjectedCssOptions = {},\n): string {\n  const prefix = options.prefix ?? project.config.cssVarPrefix ?? '';\n  const varOpts: VarOpts = prefix ? { prefix } : {};\n  const transformAlias = (token: TokenNormalized): string =>\n    makeCSSVar(token.id, { ...varOpts, wrapVar: true });\n\n  // Mirror plugin-css's value pipeline (see token-listing's build) so the\n  // emitted CSS matches the listing previewValue: same legacyHex color\n  // output, same user `transform` fallback before transformCSSValue.\n  const cssOptions = project.config.cssOptions;\n  const customTransform = cssOptions?.transform;\n  const color =\n    cssOptions?.legacyHex !== undefined ? { legacyHex: cssOptions.legacyHex } : undefined;\n  const transformValue: TransformValue = (token, tokensSet, permutation) => {\n    const opts = { tokensSet, permutation, transformAlias, ...(color && { color }) };\n    return customTransform?.(token, opts) ?? transformCSSValue(token, opts);\n  };\n\n  const { axes, tokenGraph } = project;\n  const variance = options.variance ?? analyzeProjectVariance(project);\n\n  const defaultTuple = project.defaultTuple;\n  // Baseline map from tokenGraph for value-comparison (delta detection).\n  // resolveAliasAllAt preserves alias tokens in the Terrazzo-native shape\n  // transformCSSValue requires.\n  const baselineValues = resolveAllAt(tokenGraph, defaultTuple);\n  const baselineTokens = resolveAliasAllAt(tokenGraph, defaultTuple);\n\n  const blocks: string[] = [];\n\n  // 1. Baseline `:root` — every token's baseline value lives here.\n  //    Baseline-only tokens never appear elsewhere; all other variance\n  //    kinds also need a baseline value to start the cascade from.\n  {\n    const baselineRaw = withSyntheticIds(baselineTokens);\n    const lines = collectLines(\n      baselineRaw,\n      baselineRaw,\n      () => true,\n      defaultTuple,\n      varOpts,\n      transformValue,\n    );\n    if (lines.length > 0) blocks.push(`:root {\\n${lines.join('\\n')}\\n}`);\n  }\n\n  // Pre-compute per-axis delta sets using tokenGraph walks. A path is\n  // in a delta cell when its resolved value at that singleton tuple\n  // differs from the baseline.\n  const deltaPathsByAxis: Record<string, Record<string, Set<string>>> = {};\n  for (const axis of axes) {\n    const axisDeltaPaths: Record<string, Set<string>> = {};\n    for (const ctx of axis.contexts) {\n      if (ctx === axis.default) continue;\n      const cellTuple = { ...defaultTuple, [axis.name]: ctx };\n      const cellValues = resolveAllAt(tokenGraph, cellTuple);\n      const delta = new Set<string>();\n      for (const [path, token] of Object.entries(cellValues)) {\n        if (valueKey(token) !== valueKey(baselineValues[path])) delta.add(path);\n      }\n      axisDeltaPaths[ctx] = delta;\n    }\n    deltaPathsByAxis[axis.name] = axisDeltaPaths;\n  }\n\n  // 2. Per-axis singleton cells — emit every token this axis touches.\n  //    Under smart dedup we don't drop \"matches baseline\" values; the\n  //    cascade needs them to win against other axes that might have\n  //    overridden the var. Variance routing makes \"touches\" precise:\n  //    only tokens where `axesTouching(token)` includes this axis emit\n  //    here. Baseline-only tokens are filtered out entirely.\n  for (const axis of axes) {\n    for (const ctx of axis.contexts) {\n      if (ctx === axis.default) continue;\n      const cellTuple = { ...defaultTuple, [axis.name]: ctx };\n      const cellTokens = resolveAliasAllAt(tokenGraph, cellTuple);\n      const cellTokensForAliases = cellTokens;\n      const deltaPaths = deltaPathsByAxis[axis.name]?.[ctx] ?? new Set<string>();\n\n      const lines = collectLines(\n        withSyntheticIds(cellTokens),\n        withSyntheticIds(cellTokensForAliases),\n        (path) => deltaPaths.has(path) && axisTouchesToken(axis.name, variance.get(path)),\n        cellTuple,\n        varOpts,\n        transformValue,\n      );\n      if (lines.length === 0) continue;\n      const selector = `[${dataAttr(prefix, axis.name)}=\"${cssEscape(ctx)}\"]`;\n      blocks.push(`${selector} {\\n${lines.join('\\n')}\\n}`);\n    }\n  }\n\n  // 3. Compound joint cells — drive emission from the per-token joint\n  //    cases recorded in `analyzeProjectVariance`. Each joint case is a\n  //    partial tuple where cascade composition diverges from cartesian\n  //    truth for that specific token; group those cases by tuple to emit\n  //    one compound block per unique joint tuple containing every token\n  //    that diverges there.\n  for (const block of collectJointBlocks(project, variance, prefix, varOpts, transformValue)) {\n    blocks.push(block);\n  }\n\n  // 4. Chrome aliases — trailing `:root` block.\n  const chrome = options.chrome ?? project.chrome;\n  const chromeLines: string[] = [];\n  for (const role of CHROME_ROLES) {\n    const sourceVar = makeCSSVar(role, { prefix: CHROME_VAR_PREFIX });\n    const target = chrome[role];\n    if (target !== undefined) {\n      const targetVar = makeCSSVar(target, { ...varOpts, wrapVar: true });\n      chromeLines.push(`  ${sourceVar}: ${targetVar};`);\n    } else {\n      chromeLines.push(`  ${sourceVar}: ${DEFAULT_CHROME_MAP[role]};`);\n    }\n  }\n  blocks.push(`:root {\\n${chromeLines.join('\\n')}\\n}`);\n\n  return `${blocks.join('\\n\\n')}\\n`;\n}\n\ntype VarOpts = Record<string, never> | { prefix: string };\n\n// Tells whether the given axis is in a token's touching set. Drives the\n// per-axis cell-block filter: only tokens this axis actually affects\n// appear in that axis's cell blocks.\nfunction axisTouchesToken(axisName: string, info: VarianceInfo | undefined): boolean {\n  if (!info) return false;\n  switch (info.kind) {\n    case 'baseline-only':\n      return false;\n    case 'single-axis':\n      return info.axis === axisName;\n    case 'orthogonal-after-probe':\n    case 'joint-variant':\n      return info.touching.has(axisName);\n    default: {\n      const exhaustive: never = info;\n      throw new Error(`unhandled VarianceInfo kind: ${JSON.stringify(exhaustive)}`);\n    }\n  }\n}\n\ninterface Axis {\n  name: string;\n  contexts: readonly string[];\n  default: string;\n}\n\n// Emit one compound `[data-axis=\"…\"][…]` block per unique joint tuple\n// that any token in the project diverges at. The set of joint tuples\n// comes from `analyzeProjectVariance`'s per-token `jointCases` — no\n// cartesian enumeration over project axes is performed. For a token\n// with `affectedBy = [A, B]` the only joint tuples probed involve A\n// and B; the rest of the project's axes are irrelevant for that token.\n//\n// Blocks are emitted in arity-ascending order so cascade composition\n// resolves correctly: higher-arity blocks override lower-arity blocks\n// at the same specificity gradient (n-attribute selectors have\n// specificity (0, n, 0); a 3-axis block beats both its constituent\n// 2-axis blocks).\nfunction collectJointBlocks(\n  project: Project,\n  variance: Map<string, VarianceInfo>,\n  prefix: string,\n  varOpts: VarOpts,\n  transformValue: TransformValue,\n): string[] {\n  const { axes, tokenGraph, defaultTuple } = project;\n  if (axes.length < 2) return [];\n\n  const projectAxisOrder = new Map<string, number>(axes.map((a, i) => [a.name, i]));\n\n  // Group joint cases across tokens by canonical tuple key so each\n  // unique joint tuple becomes one compound block holding every token\n  // that diverges at that tuple.\n  interface Grouped {\n    tuple: Record<string, string>;\n    paths: string[];\n  }\n  const grouped = new Map<string, Grouped>();\n  for (const [path, info] of variance) {\n    if (info.kind !== 'joint-variant') continue;\n    for (const jc of info.jointCases) {\n      const key = canonicalKey(jc.tuple);\n      let entry = grouped.get(key);\n      if (!entry) {\n        entry = { tuple: jc.tuple, paths: [] };\n        grouped.set(key, entry);\n      }\n      entry.paths.push(path);\n    }\n  }\n\n  // Sort: arity ascending first (cascade requires lower-arity blocks before\n  // higher-arity). Within an arity, by project-axis order of the involved\n  // axes; within same axes, by context iteration order — a stable emission\n  // order keyed off project-axis and context declaration order.\n  function emissionSortKey(tuple: Record<string, string>): string {\n    const sortedAxes = Object.keys(tuple).toSorted(\n      (a, b) => (projectAxisOrder.get(a) ?? 0) - (projectAxisOrder.get(b) ?? 0),\n    );\n    return sortedAxes\n      .map((axisName) => {\n        const axisPos = String(projectAxisOrder.get(axisName) ?? 0).padStart(4, '0');\n        const ctx = tuple[axisName] ?? '';\n        const axis = axes.find((a) => a.name === axisName);\n        const ctxPos = String(axis ? axis.contexts.indexOf(ctx) : 0).padStart(4, '0');\n        return `${axisPos}.${ctxPos}`;\n      })\n      .join('|');\n  }\n  const orderedKeys = [...grouped.keys()].toSorted((a, b) => {\n    const entryA = grouped.get(a);\n    const entryB = grouped.get(b);\n    if (!entryA || !entryB) return 0;\n    const aArity = Object.keys(entryA.tuple).length;\n    const bArity = Object.keys(entryB.tuple).length;\n    if (aArity !== bArity) return aArity - bArity;\n    return emissionSortKey(entryA.tuple).localeCompare(emissionSortKey(entryB.tuple));\n  });\n\n  const blocks: string[] = [];\n  for (const key of orderedKeys) {\n    const entry = grouped.get(key);\n    if (!entry) continue;\n    const fullTuple = { ...defaultTuple, ...entry.tuple };\n    const fullTokens = withSyntheticIds(resolveAliasAllAt(tokenGraph, fullTuple));\n\n    // Selector order: project axis order, not the order the entry's\n    // tuple happens to be keyed in.\n    const sortedEntries = Object.entries(entry.tuple).toSorted(\n      ([a], [b]) => (projectAxisOrder.get(a) ?? 0) - (projectAxisOrder.get(b) ?? 0),\n    );\n    const selector = sortedEntries\n      .map(([axisName, ctx]) => `[${dataAttr(prefix, axisName)}=\"${cssEscape(ctx)}\"]`)\n      .join('');\n\n    const lines: string[] = [];\n    for (const path of entry.paths) {\n      const token = fullTokens[path];\n      if (!token) continue;\n      for (const decl of collectTokenDeclarations(\n        path,\n        token,\n        fullTokens,\n        fullTuple,\n        varOpts,\n        transformValue,\n      )) {\n        lines.push(`  ${decl.varName}: ${decl.value};`);\n      }\n    }\n    if (lines.length > 0) blocks.push(`${selector} {\\n${lines.join('\\n')}\\n}`);\n  }\n\n  return blocks;\n}\n\n// Collect emitted declaration lines for a token map, filtering tokens\n// by `accept(path)`. Each line is `  --var: value;` (with leading\n// indent for embedding in a block). Composite tokens contribute one\n// line per sub-field plus an optional shorthand line; primitives\n// contribute one line.\n//\n// `tokensForAliasResolution` is the broader resolution context —\n// with delta cells, `tokens` itself only carries the delta paths,\n// so composite token sub-aliases need the full composed TokenMap\n// to resolve references to non-delta tokens.\nfunction collectLines(\n  tokens: RawTokenMap,\n  tokensForAliasResolution: RawTokenMap,\n  accept: (path: string) => boolean,\n  permutation: Record<string, string>,\n  varOpts: VarOpts,\n  transformValue: TransformValue,\n): string[] {\n  const lines: string[] = [];\n  for (const [path, token] of Object.entries(tokens)) {\n    if (!accept(path)) continue;\n    for (const decl of collectTokenDeclarations(\n      path,\n      token,\n      tokensForAliasResolution,\n      permutation,\n      varOpts,\n      transformValue,\n    )) {\n      lines.push(`  ${decl.varName}: ${decl.value};`);\n    }\n  }\n  return lines;\n}\n\n/**\n * Expand a single token into its emitted `{ varName, value }` records.\n * Primitive tokens yield one record; composite tokens yield one per\n * sub-field plus an optional shorthand.\n */\nexport function* collectTokenDeclarations(\n  path: string,\n  token: TokenNormalized,\n  tokensSet: RawTokenMap,\n  permutation: Record<string, string>,\n  varOpts: VarOpts,\n  transformValue: TransformValue,\n): Generator<{ varName: string; value: string }> {\n  const varName = makeCSSVar(path, varOpts);\n  let value: ReturnType<typeof transformCSSValue>;\n  try {\n    value = transformValue(token, tokensSet, permutation);\n  } catch (error) {\n    const permutationStr = JSON.stringify(permutation);\n    const valueStr = safeStringify(token.$value);\n    const original = error instanceof Error ? error.message : String(error);\n    throw new Error(\n      `swatchbook: failed to transform token \"${path}\" at permutation ${permutationStr}.\\n` +\n        `  $type: ${token.$type}\\n` +\n        `  $value: ${valueStr}\\n` +\n        `  cause: ${original}`,\n      { cause: error },\n    );\n  }\n  if (typeof value === 'string') {\n    yield { varName, value };\n    return;\n  }\n  for (const [subKey, subVal] of Object.entries(value)) {\n    yield { varName: makeCSSVar(`${path}.${subKey}`, varOpts), value: subVal };\n  }\n  const shorthand = generateShorthand({ token, localID: path });\n  if (shorthand) yield { varName, value: shorthand };\n}\n\nfunction safeStringify(value: unknown): string {\n  try {\n    return JSON.stringify(value);\n  } catch {\n    return String(value);\n  }\n}\n\nfunction* axisCombinations(axes: readonly Axis[], k: number): Generator<readonly Axis[]> {\n  if (k === 0) {\n    yield [];\n    return;\n  }\n  if (k > axes.length) return;\n  for (let i = 0; i <= axes.length - k; i++) {\n    const head = axes[i] as Axis;\n    for (const tail of axisCombinations(axes.slice(i + 1), k - 1)) {\n      yield [head, ...tail];\n    }\n  }\n}\n\nfunction* contextProducts(axisCombo: readonly Axis[]): Generator<Record<string, string>> {\n  if (axisCombo.length === 0) {\n    yield {};\n    return;\n  }\n  const [first, ...rest] = axisCombo;\n  if (!first) return;\n  for (const ctx of first.contexts) {\n    if (ctx === first.default) continue;\n    for (const subTuple of contextProducts(rest)) {\n      yield { [first.name]: ctx, ...subTuple };\n    }\n  }\n}\n"],"mappings":"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"}