Three products, three brands, one design system: the math works with design tokens organized in layers. A token separates decision from value; which color represents the primary action is a decision, the exact hex is a value. Without that separation, every new brand copies components and the system drifts apart within weeks. With it, a brand overrides values and the whole system changes skin without component forks.

What are the token layers?

  1. Primitive tokens: raw values like color-blue-500, shared across all brands
  2. Semantic tokens: action-primary, surface-raised, text-danger, referencing primitives
  3. Component tokens: button-bg, consuming semantics and isolating variations

Naming discipline holds the system together: names describe role, so brand B renders danger in orange while text-danger survives. Primitives change rarely; semantics follow the product; component tokens absorb edge cases without leaking them into the rest. Renaming a token after adoption costs more than any naming debate at creation time.

How do you compile tokens for multiple platforms?

A single JSON source compiles through Style Dictionary into CSS custom properties, Swift, Kotlin, and Tailwind config. A broken reference between layers fails the CI build before it reaches design review. Hand-synced theme files drift within weeks; the pipeline publishes versioned packages per platform.

How do you switch brands at runtime?

Custom properties cascade per scope. A data-theme="brand-b" attribute on the wrapper redefines the semantic tokens, and the page changes without a rebuild. The same mechanism serves white-label embedding: the host overrides two tokens and the embedded widget wears the partner identity. Inlined tokens cost a few KB and skip an extra request; under SSR, they land before paint to avoid a flash of the wrong theme on first render.

How do you keep different brands coherent?

A modular type scale at a 1.25 ratio with a 4/8px spacing grid supports three distinct personalities. Brands vary color, border radius, and display weight; vertical rhythm and hierarchy stay identical everywhere.

How do you govern token changes?

A token PR goes through review with visual regression snapshots in Chromatic and Playwright screenshots comparing components across the three brands. The pipeline publishes a changelog per release, and consuming teams see the diff in the PR before upgrading. Breaking renames follow a deprecation cycle like any public API: the new version coexists with aliases of the old one for a release.

Does dark mode come free?

It does. The dark theme becomes another brand file overriding surface and text tokens alone. No new selectors, no component forks; the semantic layer absorbs the whole variation.