Brand System

Token Contract

The canonical CSS-variable contract every brand instance must satisfy — 67 tokens, a date-based contract version, the exact-match rule, and pnpm brand:lint.

Token Contract

The contract is the canonical set of CSS-variable names and structure that every brand profile must define. An instance is one brand's values for exactly those names. This is the concrete form of "full controllable palette" — the brand owns every default-driving variable, so per-tenant recoloring is a values-only swap (ADR 0002 §3).

Source of truth

lib/brand-contract-tokens.json is the single canonical manifest (ADR 0002 §3, O-5 decision 2026-06-04). It declares:

  • contractVersion — a date-based version (currently 2026.06.04).
  • tokens — the exhaustive list of required CSS custom-property names (currently 67 tokens).

lib/brand-contract.ts is the typed Zod surface over that manifest. It exports CONTRACT_VERSION, REQUIRED_TOKENS, and BrandTokenProfileSchema. The schema validates a brand profile shaped as:

{
  namespace: string,        // ^[a-z0-9][a-z0-9-]*$
  contractVersion: "2026.06.04",
  tokens: Record<string, string>
}

The match is exact. BrandTokenProfileSchema fails if a profile is missing any contract token or introduces an off-contract token. A brand instance defines every contract variable and no extras.

The 67 tokens

The contract spans these groups (see lib/brand-contract-tokens.json for the authoritative list):

GroupTokens
Brand accents--brand-cyan, --brand-cyan-light, --brand-blue, --brand-ice, --sand, --sand-light, --sand-whisper
Surface ladder--background, --card, --popover, --muted, --obsidian, --surface-1, --surface-2, --surface-3
Semantic--foreground, --primary, --secondary, --accent, --destructive, --border, --input, --ring, plus their -foreground pairs
Muted text--muted-foreground, --muted-fg-low, --muted-fg-vlow, --title-foreground
Charts--chart-1--chart-5
Gauges--gauge-healthy, --gauge-attn, --gauge-warn, --gauge-critical
Heatmap--heatmap-1--heatmap-4
Rank ramp--rank-1--rank-6
Sidebar--sidebar, --sidebar-foreground, --sidebar-primary, --sidebar-accent, --sidebar-border, --sidebar-ring, plus -foreground pairs
Shadows--shadow-card, --shadow-signal, --shadow-cta-glow, --shadow-sheet
Typography & radius--font-sans, --font-mono, --font-display, --radius

Every value is oklch (or a color-mix() / shadow composite built on oklch tokens). Canvas / WebGL effects are the only exception — they may use literal color constants where CSS variables are unavailable, and those literals must mirror the brand-palette values.

Validation — pnpm brand:lint

pnpm brand:lint

brand:lint (scripts/brand-contract-check.mjs) enforces the contract against each registries/{ns}/brand-system.css: every :root block is parsed, declarations are unioned, and the resulting set must match the manifest exactly — a build fails if a tenant omits a contract token or introduces an off-contract one (registries/README.md).

The script reads lib/brand-contract-tokens.json directly in plain Node and encodes the same exact-match rule as BrandTokenProfileSchema. The two must stay in sync — if the contract semantics ever change, change both (lib/brand-contract.ts header note).

Versioning

The contract version is date-based (2026.06.04), matching the brand-package versioning scheme (see Versions & Snapshots). A brand profile pins the contractVersion it was authored against, so a contract change is an explicit, reviewable event rather than silent drift. A generated requirements.schema.json is derived from this manifest and shipped in each version snapshot.

Token meanings

For the full annotated token reference — every value, its purpose, and the brand rationale — see the Vandoko Dark Theme doc. Vandoko's instance of this contract ships as the vandoko-brand-system registry:base (with vandoko-theme as its alias); both carry the same CSS. See Consuming the Brand System for installing it.

On this page