var{defineProperty:I,getOwnPropertyNames:W,getOwnPropertyDescriptor:X}=Object,Y=Object.prototype.hasOwnProperty;function Z(b){return this[b]}var G=(b)=>{var j=(P??=new WeakMap).get(b),z;if(j)return j;if(j=I({},"__esModule",{value:!0}),b&&typeof b==="object"||typeof b==="function"){for(var A of W(b))if(!Y.call(j,A))I(j,A,{get:Z.bind(b,A),enumerable:!(z=X(b,A))||z.enumerable})}return P.set(b,j),j},P;var _=(b)=>b;function $(b,j){this[b]=_.bind(null,j)}var O=(b,j)=>{for(var z in j)I(b,z,{get:j[z],enumerable:!0,configurable:!0,set:$.bind(j,z)})};var T=(b,j)=>()=>(b&&(j=b(b=0)),j);var U={};O(U,{groupByToArray:()=>V,groupByMultiple:()=>h,groupBy:()=>H,getUniqueTags:()=>L,getUniqueOwners:()=>C,getUniqueDomains:()=>R,filterBy:()=>K,GroupingStrategies:()=>J});function K(b,j){return b.filter((z)=>{if(j.tags?.length){if(!j.tags.some((D)=>z.meta.tags?.includes(D)))return!1}if(j.owners?.length){if(!j.owners.some((D)=>z.meta.owners?.includes(D)))return!1}if(j.stability?.length){if(!j.stability.includes(z.meta.stability??"stable"))return!1}if(j.domain){if(J.byDomain(z)!==j.domain)return!1}if(j.keyPattern){let A=z.meta.key??z.meta.key??"",D=j.keyPattern.replace(/\*/g,".*").replace(/\?/g,".");if(!new RegExp(`^${D}$`,"i").test(A))return!1}return!0})}function H(b,j){let z=new Map;for(let A of b){let D=j(A),E=z.get(D);if(E)E.push(A);else z.set(D,[A])}return z}function V(b,j){let z=H(b,j);return Array.from(z.entries()).map(([A,D])=>({key:A,items:D}))}function h(b,j){let z=new Map;for(let A of b){let D=j(A);for(let E of D){let N=z.get(E);if(N)N.push(A);else z.set(E,[A])}}return z}function L(b){let j=new Set;for(let z of b)for(let A of z.meta.tags??[])j.add(A);return Array.from(j).sort()}function C(b){let j=new Set;for(let z of b)for(let A of z.meta.owners??[])j.add(A);return Array.from(j).sort()}function R(b){let j=new Set;for(let z of b)j.add(J.byDomain(z));return Array.from(j).sort()}var J;var Q=T(()=>{J={byTag:(b)=>b.meta.tags?.[0]??"untagged",byAllTags:(b)=>b.meta.tags?.length?b.meta.tags:["untagged"],byOwner:(b)=>b.meta.owners?.[0]??"unowned",byDomain:(b)=>{return(b.meta.key??b.meta.key??"").split(".")[0]??"default"},byStability:(b)=>b.meta.stability??"stable",byUrlPath:(b)=>(j)=>{if(!j.path)return"root";return j.path.split("/").filter(Boolean).slice(0,b).join("/")||"root"}}});Q();import{compareVersions as q}from"compare-versions";var B=(b)=>`${b.meta.key}.v${b.meta.version}`;class M{contractType;items=new Map;constructor(b,j){this.contractType=b;if(j)j.forEach((z)=>this.register(z))}register(b){let j=B(b);if(this.items.has(j))throw Error(`Duplicate contract \`${this.contractType}\` ${j}`);return this.items.set(j,b),this}count(){return this.items.size}list(){return[...this.items.values()]}get(b,j){if(j!=null)return this.items.get(`${b}.v${j}`);let z;for(let[A,D]of this.items.entries()){if(!A.startsWith(`${b}.v`))continue;if(!z||q(D.meta.version,z.meta.version)>0)z=D}return z}has(b,j){return!!this.get(b,j)}filter(b){return K(this.list(),b)}listByTag(b){return this.list().filter((j)=>j.meta.tags?.includes(b))}listByOwner(b){return this.list().filter((j)=>j.meta.owners?.includes(b))}groupBy(b){return H(this.list(),b)}getUniqueTags(){return L(this.list())}}class x extends M{constructor(b){super("theme",b)}}function u(b){return{key:b.meta.key,version:b.meta.version}}var c=[{id:"docs.tech.contracts.themes",title:"ThemeSpec Overview",summary:"`ThemeSpec` defines a structured, versioned source of truth for design tokens, component variants, and scoped overrides. Use it to describe how tenants or individual users should experience the design system without hand-maintaining ad-hoc theme files. Specs live in `@contractspec/lib.contracts-spec`, making them accessible to generators, docs, and runtime tooling.",kind:"reference",visibility:"public",route:"/docs/tech/contracts/themes",tags:["tech","contracts","themes"],body:`# ThemeSpec Overview

## Purpose

\`ThemeSpec\` defines a structured, versioned source of truth for design tokens, component variants, and scoped overrides. Use it to describe how tenants or individual users should experience the design system without hand-maintaining ad-hoc theme files. Specs live in \`@contractspec/lib.contracts-spec\`, making them accessible to generators, docs, and runtime tooling.

## Location

- Types & registry: \`packages/libs/contracts/src/themes.ts\`
- Design tokens bridge: \`packages/libs/design-system/src/theme/*\`

## Schema

\`\`\`ts
export interface ThemeSpec {
  meta: ThemeMeta;            // ownership metadata + { name, version, extends?, scopes? }
  tokens: ThemeTokens;        // design tokens grouped by colors, radii, space, etc.
  components?: ComponentVariantSpec[]; // per-component variant configuration
  overrides?: ThemeOverride[];         // scoped tenant/user overrides
}
\`\`\`

- **ThemeMeta**
  - \`name\`: fully-qualified identifier (e.g., \`design.pastel\`)
  - \`version\`: increment when tokens/variants change in a breaking way
  - \`extends?\`: optional \`{ name, version }\` pointer to a base theme
  - \`scopes?\`: default scopes where the theme applies (\`global\`, \`tenant\`, \`user\`)
- **ThemeTokens**
  - \`colors\`, \`radii\`, \`space\`, \`typography\`, \`shadows\`, \`motion\`
  - Each entry is a map of \`{ value: T; description?: string }\`
- **ComponentVariantSpec**
  - \`component\`: design-system component key (e.g., \`Button\`, \`NavMain\`)
  - \`variants\`: map of variant names → \`{ props?, tokens? }\`
- **ThemeOverride**
  - \`scope\`: \`'global' | 'tenant' | 'user'\`
  - \`target\`: identifier (e.g., \`tenant:artisanos\`, \`user:123\`)
  - \`tokens?\` / \`components?\`: partial token/variant overrides for the target

## Registry Usage

\`\`\`ts
import { ThemeRegistry } from '@contractspec/lib.contracts-spec/themes';
import { PastelTheme } from './themes/design.pastel';

const themes = new ThemeRegistry();
themes.register(PastelTheme);

const theme = themes.get('design.pastel');
const tenantVariant = themes
  .get('design.pastel')
  ?.overrides?.find((o) => o.target === 'tenant:artisanos');
\`\`\`

The registry guarantees \`name + version\` uniqueness and exposes \`list()\` for discovery tooling.

## Rendering

The design system consumes specs (via adapters you provide) to build runtime tokens. A simple adapter might:

1. Resolve the base theme + applicable overrides.
2. Merge token maps using \`ThemeTokens\`.
3. Feed the result into \`mapTokensForPlatform\` in \`@contractspec/lib.design-system\`.

\`\`\`ts
import { ThemeRegistry } from '@contractspec/lib.contracts-spec/themes';
import { mapTokensForPlatform } from '@contractspec/lib.design-system';

function resolveTokens(registry: ThemeRegistry, ref: ThemeRef, ctx: { tenant?: string; user?: string }) {
  const spec = registry.get(ref.name, ref.version);
  if (!spec) throw new Error('Theme not found');

  const tokens = deepMerge(spec.tokens, collectOverrides(spec.overrides, ctx));
  return mapTokensForPlatform(tokens);
}
\`\`\`

## Authoring Guidelines

1. Keep token names aligned with the design-system defaults (\`background\`, \`mutedForeground\`, etc.).
2. Use \`extends\` to create layered themes (base brand → tenant tweaks → user-level overrides).
3. Document variants with \`description\` to help designers and automation understand intent.
4. Prefer scoped overrides (\`tenant:foo\`) instead of duplicating the entire theme per tenant.
5. When tokens influence multiple components, capture them in \`tokens\` and keep \`components\` for API-level variant wiring.

## CLI (Future Work)

The \`contractspec\` CLI does not yet scaffold theme specs. Planned additions:

- \`contractspec create --type theme\`
- \`contractspec build <theme.theme.ts>\` → generate design-system adapters

For now, author specs manually and register them alongside contract bundles.

`}];export{c as tech_contracts_themes_DocBlocks,u as makeThemeRef,x as ThemeRegistry};
