← Back to home

Case Study

Figma Design Token Rewrite

A ground-up rebuild of a global financial services Figma design token architecture — migrating two enterprise-scale libraries from a bloated, inconsistent legacy system to a clean, variable-driven semantic token model aligned with production CSS and W3C standards. The project covered two enterprise design system libraries simultaneously, reducing token count by 56% while increasing coverage and consistency.

Role: Lead Engineer / Design SystemsYear: 2026

Overview

Two enterprise libraries powering the same global financial services platform were rebuilt in parallel, replacing flat primitive dumps and broken bindings with a semantic alias layer and a generated CSS export aligned to W3C DTCG.

The problem

The existing legacy token libraries were the product of years of uncoordinated growth. Tokens used Title Case naming with emoji prefixes, had no codeSyntax.WEB values (meaning Figma's developer tools returned nothing useful), and were structured as flat primitive dumps with no semantic layer. Components were bound directly to color primitives, bypassing any semantic aliasing — so a brand color change required hundreds of manual rebinds across thousands of nodes.

By the time the audit ran, the two libraries had accumulated 262 and 268 tokens respectively — nearly 3x the industry standard for an enterprise system of this scale. 6,209 variable bindings in one library were outright broken, pointing to deleted primitives with no path to resolution. The system had 12 external library dependencies in one file and 6 in the other, creating circular reference risks. Production CSS had two broken custom properties shipping to users — broken since a previous refactor that was never completed.

What was done

The migration was executed in phases using a combination of custom MCP-driven Figma scripts and structured analysis.

  1. Phase 1

    Audit and mapping

    Queried both libraries end-to-end via Figma MCP to produce a complete inventory of every variable, its collection, naming format, alias chain, codeSyntax.WEB status, and binding count. Cross-referenced against production CSS to identify what was actually in use versus what was dead weight.

  2. Phase 2

    Naming and codeSyntax

    Renamed 168 variables from Title Case to lowercase kebab-case using slash-separated hierarchy (color/action/button-default, spacing/md, radius/pill). Set codeSyntax.WEB on all 179 variables, bringing coverage from 0% to 100%. All variables now return usable CSS custom property names from Figma's developer tools and MCP.

  3. Phase 3

    Semantic layer

    Established a clean two-tier architecture — semantic Tokens collection aliasing into typed Primitives. Designers work only with semantic tokens (what a color is for, not what it is). Primitives are an implementation detail. Created 11 missing variables (5 colors, 6 radius tokens) to close gaps between the Figma system and production CSS needs.

  4. Phase 4

    Token consolidation

    Reduced both libraries from ~265 tokens to 116 — the number that maps precisely to production CSS usage. Eliminated 3x spacing token bloat (30 → 10 t-shirt sizes), 6x typography token bloat (77 → 15 semantic typography tokens), and consolidated redundant color scales. Removed all 18 external library dependencies.

  5. Phase 5

    Binding repair

    Resolved 6,209 broken variable bindings by building an automated rebinding script that mapped deleted primitive IDs to their correct Tokens collection replacements. What would have taken 40–80 hours of manual Figma work took under 4 hours to script and 30 minutes to run.

  6. Phase 6

    CSS export pipeline

    Built a Node.js script (generate-tokens-css.mjs) that pulls the Tokens collection via the Figma Variables API, resolves all alias chains to raw values, and writes three output formats: CSS custom properties (:root { ... }), a JSON token map for tooling, and a W3C DTCG-compliant JSON file for cross-platform use. Achieved 96.3% parity between the Figma export and the live production CSS theme.

Numbers

Before

  • 262 tokens (Library A), 268 tokens (Library B)
  • 0% codeSyntax.WEB coverage
  • 168 variables in Title Case with no CSS output
  • 6,209 broken variable bindings
  • 18 external library dependencies across both files
  • 0 semantic alias layer
  • 2 broken CSS custom properties in production

After

  • 116 tokens in each library (56% reduction)
  • 100% codeSyntax.WEB coverage — every variable returns a usable CSS name
  • Clean two-tier architecture: Tokens (semantic) → Primitives → RGB
  • 0 broken bindings
  • 0 external dependencies
  • 96.3% Figma-to-production CSS parity
  • Token export pipeline producing CSS, JSON, and W3C DTCG outputs from a single Figma source

Project artifacts

Token outputs generated from the same source include CSS custom properties and a W3C token JSON map. The previews below show representative values from that artifact set.

Color tokens

Action

  • #1d2550

    --color-action-button-default

  • #302b25

    --color-action-button-hover

  • #302b25

    --color-action-button-pressed

  • #878787

    --color-action-button-inactive

  • #ffffff

    --color-action-button-label

  • #302b25

    --color-action-link-default

  • #641ee0

    --color-action-link-hover

  • #813684

    --color-action-link-visited

Alert

  • #cf0000

    --color-alert-error-text

  • #ffeaeb

    --color-alert-error-bg

  • #fff7e6

    --color-alert-warning-bg

  • #e3f5e1

    --color-alert-success-bg

  • #c7deff

    --color-alert-info-bg

  • #fdc828

    --color-alert-highlight

Surface

  • #ffffff

    --color-surface-default

  • #f2f2f2

    --color-surface-subtle

  • #1d2550

    --color-surface-hero

  • #fdc828

    --color-surface-focus

Text

  • #000000

    --color-text-black

  • #302b25

    --color-text-on-light

  • #6b6b6b

    --color-text-muted

  • #ffffff

    --color-text-on-dark

Border

  • #cfcfcf

    --color-border-divider-light

  • #ababab

    --color-border-divider-medium

  • #fdc828

    --color-border-focus

Control

  • #0061f4

    --color-control-active

  • #cf0000

    --color-control-error

  • #6b6b6b

    --color-control-inactive

  • #ffffff

    --color-control-surface-primary

  • #fafafa

    --color-control-surface-secondary

Input

  • #0061f4

    --color-input-focus

  • #302b25

    --color-input-hover

  • #0d7406

    --color-input-success

  • #c51321

    --color-input-error

Accent

  • #1d2550

    --color-accent-night-blue

  • #187ac9

    --color-accent-sky-blue

  • #278904

    --color-accent-grass-green

  • #cc1ad4

    --color-accent-hot-pink

  • #e7ff00

    --color-accent-yellow

Spacing tokens

  • --spacing-tn4px
  • --spacing-xs8px
  • --spacing-sm12px
  • --spacing-md16px
  • --spacing-lg24px
  • --spacing-xl32px

Radius tokens

  • --radius-card6px
  • --radius-component8px
  • --radius-pill80px

Typography tokens

--typography-display-lg · 72px

Display

--typography-display-sm · 48px

Display

--typography-heading-xl · 40px

Heading

--typography-heading-lg · 36px

Heading

--typography-heading-md · 32px

Heading

--typography-heading-sm · 26px

Heading

--typography-body-xl · 22px

The quick brown fox jumps over the lazy dog

--typography-body-lg · 20px

The quick brown fox jumps over the lazy dog

--typography-body-md · 18px

The quick brown fox jumps over the lazy dog

--typography-body-sm · 14px

The quick brown fox jumps over the lazy dog

--typography-weight-light

Weight 300

--typography-weight-regular

Weight 400

--typography-weight-medium

Weight 500

--typography-weight-semi-bold

Weight 600

--typography-weight-bold

Weight 700

Business value

Figma as the single source of truth

Previously, a designer changing a brand color in Figma had no reliable path to production — the CSS ignored it, the token names meant nothing to engineers, and the developer inspect panel returned empty. Now a token change in Figma flows to generated CSS in minutes.

Intent is encoded, not just values

The semantic layer means a developer consuming --color-action-button-default knows exactly what they're styling — and knows it will never be an arbitrary hex. Brand changes propagate through the alias chain automatically rather than requiring a file-wide search and replace.

A learnable system

The reduction from ~265 to 116 tokens makes the system learnable. New designers and engineers can understand the full token vocabulary in an afternoon rather than inheriting a system that nobody fully understood.