{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "theme-tokens",
  "type": "registry:lib",
  "title": "Theme token manifest",
  "description": "@interlace/ui — the registry of themes and the list of every `--interlace-*` token a theme must define. A missing token does not throw; it silently inherits the previous theme's value.",
  "author": "ofri-peretz <https://github.com/ofri-peretz>",
  "categories": [
    "foundation",
    "util"
  ],
  "dependencies": [],
  "registryDependencies": [],
  "files": [
    {
      "path": "registry/interlace-ui/lib/theme-tokens.ts",
      "target": "lib/theme-tokens.ts",
      "type": "registry:lib",
      "content": "export const THEME_TOKENS = [\n  'primary',\n  'primary-hover',\n  'primary-active',\n  'primary-foreground',\n  'primary-subtle',\n  'primary-subtle-foreground',\n  'background',\n  'foreground',\n  'card',\n  'card-foreground',\n  'popover',\n  'popover-foreground',\n  'muted',\n  'muted-foreground',\n  'border',\n  'input',\n  'ring',\n  'accent',\n  'accent-foreground',\n  'secondary',\n  'secondary-foreground',\n  'destructive',\n  'destructive-foreground',\n  'success',\n  'success-foreground',\n  'warning',\n  'warning-foreground',\n  'info',\n  'info-foreground',\n  'caution',\n  'caution-foreground',\n  'scrim',\n  'scrim-foreground',\n  'hero-star',\n  'hero-trail',\n  'hero-meteor',\n  'hero-surface',\n  'hero-surface-deep',\n  'hero-foreground',\n  'window-control-close',\n  'window-control-minimize',\n  'window-control-zoom',\n  'chart-1',\n  'chart-2',\n  'chart-3',\n  'chart-4',\n  'chart-5',\n  'viz-grid',\n  'viz-axis',\n  'viz-edge',\n  'radius-sm',\n  'radius-md',\n  'radius-lg',\n  'brand-mark-bar-o',\n  'brand-mark-bar-g',\n] as const;\n\n/** A token name from the manifest, without the `--interlace-` prefix. */\nexport type ThemeToken = (typeof THEME_TOKENS)[number];\n\n/** The colour-scheme axis. Orthogonal to the theme axis. */\nexport const SCHEMES = ['light', 'dark'] as const;\nexport type Scheme = (typeof SCHEMES)[number];\n\n/**\n * The theme registry.\n *\n * `name` is the literal written to `<html data-theme=\"…\">` — except for the\n * default, which writes NO attribute at all (`:root` is Interlace, so an\n * attribute would be redundant and would make \"no preference\" and \"chose the\n * default\" indistinguishable in the DOM).\n */\nexport const THEMES = [\n  {\n    name: 'interlace',\n    label: 'Interlace',\n    /** Burnt orange + brand green, warm neutrals. `styles/interlace-theme.css`. */\n    description: 'Warm burnt orange — the Interlace brand.',\n    default: true,\n  },\n  {\n    name: 'harbor',\n    label: 'Harbor',\n    /** Deep harbour blue on cool slate. `styles/themes/harbor.css`. */\n    description: 'Deep harbour blue on cool slate.',\n    default: false,\n  },\n] as const;\n\n/** A registered theme name. */\nexport type ThemeName = (typeof THEMES)[number]['name'];\n\n/** The theme that `:root` already is — written as no attribute at all. */\nexport const DEFAULT_THEME: ThemeName = 'interlace';\n\n/** Narrow an arbitrary string to a registered theme name. */\nexport function isThemeName(value: unknown): value is ThemeName {\n  return (\n    typeof value === 'string' &&\n    THEMES.some((theme) => theme.name === value)\n  );\n}\n\n/** Narrow an arbitrary string to a colour scheme. */\nexport function isScheme(value: unknown): value is Scheme {\n  return value === 'light' || value === 'dark';\n}\n\n/**\n * @interlace/ui — the theme contract.\n *\n * `THEME_TOKENS` enumerates every `--interlace-*` custom property a theme\n * MUST define, for BOTH colour schemes. `THEMES` is the registry of themes\n * that claim to satisfy it.\n *\n * ─── Why this exists as data rather than as CSS ───────────────────\n *\n * A missing token does not throw. CSS has no such thing as \"undeclared\" at\n * this level — the value simply resolves from whatever rule of lower\n * specificity matched, which for a theme file is the PREVIOUS theme in the\n * cascade. So a theme that forgets `--interlace-card` renders one surface\n * in the other brand's colour, on a page that is otherwise perfect, and\n * nobody files a bug because nobody can name what is wrong. That is the\n * failure this manifest exists to make impossible: it is the input to\n * `__tests__/theme-contract-lock.test.ts`, which fails on a theme missing\n * a token, on a theme inventing one outside the list (a typo is silent for\n * exactly the same reason), and on any theme × scheme whose measured\n * contrast drops below the WCAG 2.2 floors.\n *\n * ─── Provenance ──────────────────────────────────────────────────\n *\n * The list is DERIVED, not hand-typed: it is the `--interlace-*`\n * declarations of the `:root` block in `styles/interlace-theme.css`, in\n * source order. The lock re-derives it from that file on every run and\n * fails if the two disagree — so adding a token to the default theme\n * without adding it here (or vice versa) is a red test, not a discovery\n * six months later.\n *\n * ─── The two axes ────────────────────────────────────────────────\n *\n *   scheme  →  light | dark              (`.dark` / `[data-scheme='dark']`)\n *   theme   →  interlace | harbor | …    (`[data-theme='<name>']`)\n *\n * See the header of `styles/interlace-theme.css` for the selector matrix.\n */\n\n/**\n * Every `--interlace-*` token a theme must declare, in both schemes.\n * The `--interlace-` prefix is omitted; `'primary'` means\n * `--interlace-primary`.\n */\n\n// @interlace/theme-tokens v1.0.0 — Interlace design system.\n// Docs, props and live preview: https://ds.interlace.tools/c/theme-tokens\n// What changed since: https://ds.interlace.tools/c/theme-tokens#history\n// Generated banner — keep it, the upgrade diff reads this version.\n"
    }
  ],
  "meta": {
    "tier": "util",
    "client": false,
    "minViewport": null,
    "loading": false,
    "version": "1.0.0",
    "since": "1.0.0"
  },
  "docs": "## @interlace/theme-tokens\n\nInstalled to `lib/theme-tokens.ts`.\n\n```tsx\nimport { /* … */ } from '@/lib/theme-tokens';\n```\n\nProps, a11y contract, live preview and source: https://ds.interlace.tools/c/theme-tokens"
}
