Token-first, from the ground up.

Token files drive everything — the CSS, the Figma variables, two independent brands. Three weeks lost to a naming mistake. One pipeline that made it worth it.

Design system token architecture

I started with the token file, not the components.

The JSON file is the source of truth — not Figma. Style Dictionary compiles it to CSS; the same names flow into Figma variables. A token name in two places with different spellings is a hidden handoff step in disguise. Building the visual layer from scratch meant no inherited conventions — and no inherited mistakes. The cost came later: three weeks spent not on components, but on names.

Tier 01 · Global

Primitive values

tokens/global.json

Never referenced directly in components
color.neutral-900#1a1a1b
space.524px
font-weight.bold700
Tier 02 · Semantic

Component decisions

tokens/brands/portfolio/tokens.json

The only tier components are allowed to reference
color-text-primary{color.neutral-900}
color-accent-default{color.teal-500}
space-component-gap{space.5}
Tier 03 · Brand

Brand overrides

tokens/brands/[brand]/tokens.json

Only the tokens that diverge from the default theme
color-accent-default{brand-a.indigo-400}
font-family-heading'DM Serif Display'
color-surface-primary{brand-a.background-0}

Primitive values never appear in component CSS — only semantic tokens do.

Figma as the verifier, not the author.

Most token-first systems start in Figma: set the variable, export it, hope the handoff holds. I inverted that. The JSON file is authoritative. Style Dictionary compiles it to CSS. A separate step pushes the same names into Figma. Figma shows you whether the pipeline worked. If Figma and CSS disagree, CSS is right.

Structure from BEM. Behaviour from Radix. Everything visible: mine.

BEM with CSS custom properties: class names describe structure, tokens carry all visual values. Swap the brand class and every component re-resolves through a different token set — no logic, no JavaScript, no build change. Radix handles the one category I chose not to build: interactive components that need accessible behaviour by specification. Everything visible is mine.

Design SystemsToken ArchitectureMulti-brandReactStyle DictionaryStorybook
Layer 01 · Delivery

Next.js App Router

Framework — pages, routing, server and client components

Layer 02 · Styling

BEM + CSS Custom Properties

Component structure and visual values — driven entirely by tokens

Layer 03 · Tokens

Style Dictionary

Compiles token JSON to CSS — single build output: styles/brands/portfolio.css

Layer 04 · Components

React + Radix UI

Stateless presentational components — Radix only for accessible primitives

Layer 05 · Review

Storybook + Chromatic

Component review across both brand contexts — visual regression per commit

One stack. One source of truth. One codebase.

Where design met code

One name, three places.

Design

The Figma variable panel holds the same names as the Style Dictionary source. Not because they were synced — because they were compiled from the same file. The pipeline never interprets. It copies.

Code

The compiled CSS custom property carries the same name. Three sources, one namespace. When all three agree — as the block below shows — there is nothing left to translate. That is what the absence of a handoff step looks like.

Figma variablebutton-primary-background = #15616D
Style Dictionarybutton-primary-background: #15616D
Compiled CSS--button-primary-background: #15616D
Design

Figma

Component designed with variants, tokens, and correct naming convention

Bridge

Console MCP

Exposes Figma structure and token data directly to Claude Code — no screenshots

Generate

Claude Code

Reads CLAUDE.md and token files, generates BEM component and Storybook story

Review

Storybook

Review props, variants, and states across both brand contexts via brand switcher

Approve

Chromatic

Visual regression sign-off per commit — snapshots compared per brand automatically

Ship

GitHub

Commit reviewed component — production-ready, token-compliant, system-aligned

Design to code. No manual translation.

One source. Two brands. Zero drift.

Token coverage

271 semantic tokens across three tiers — global primitives, semantic decisions, brand overrides. No hardcoded values anywhere in component code. Every visual property resolves through the pipeline.

Brand switching

Two independent brand themes share one component codebase. Switching brands is a single CSS class swap — no component logic, no JavaScript, no duplicated components. Add a third brand: write a token file.

Design-to-code pipeline

Figma variables map 1:1 to Style Dictionary token names. The pipeline compiles — it doesn't interpret, negotiate, or drift. When Figma and CSS agree, that agreement is structural, not maintained.

A stable language first. Then let agents build on top of it.

This is the version I'd design next.

Final angle: orchestration on top of a stable language

Three weeks spent not on components. On names.

I added tokens as I needed them. That worked for the first few weeks. Then the system had to support three tiers simultaneously — global primitives, semantic decisions, brand overrides — and the names I'd used for the first tier made no sense for the second. color-gray-100 makes an appearance claim. neutral-100 describes a position. Nothing visual changed. The language did, completely. In a token-first system, naming is architecture — get it wrong and you don't fix the name, you refactor the system.

An agent generating a new component needs to know which token to reach for. One enforcing brand consistency needs to verify the right names are in use. One proposing a palette change needs to understand which tier it's operating in. All of that requires stable, unambiguous language. The naming work wasn't just architecture. It was the condition for safe AI participation.

Before agents can coordinate a design system, the design system has to know what its own words mean.

Most portfolios build something, then document the system behind it. This one is the system. Every visual decision runs through the same token pipeline — the dark and light mode toggle in the navigation is that same system running live, documented step by step in the DS Playbook. It also turned out to be the prerequisite for the next problem: a language stable enough for agents to act on safely.

Open the inspector. It's all tokens.

The foundations, running

Explore the full design system →

Typography

H1Display
H3Sub-heading
LeadLead paragraph
BodyBody text
Labellabel

Color

Surface
primary
secondary
tertiary
inverse
Text
primary
secondary
inverse
Accent
default
hover
Border
default
strong

Spacing

tight-gap
inline-gap
label-gap
element-gap
component-gap