Every component in our product referenced a different source of truth (Design system)

Project overview

NewU's UI had a colour problem. Not an ugly-colours problem. A who-decides-what-purple-means problem.

Buttons used one blue. Links used another. Both were supposed to be the same. Neither referenced a shared system. Dark mode was a manual repaint. Brand theming for client white-labelling was a guessing game. Every new feature meant re-answering the same question: what colour should this be?

Company: NewU · Dutch health tech · B2B employee wellness platform

Timeline: 4 weeks, October 2025

My role: Lead Product Designer & Art Director - Audit, architecture, token design, documentation

Scope: Complete colour token rebuild — primitives, semantic roles, component aliases, light/dark modes

Team: Emmanuel Job, Nkiru (Design), Development team


What "inconsistent" actually looked like in practice

The word "inconsistent" undersells it. Here's what was actually happening:

  • Components referenced primitive values directly. A button's background was blue-500. Not "action-primary" — the literal hex ramp value.


  • Colour ramps weren't normalised. Our grey scale had uneven perceptual steps. The brand blue ramp had gaps. Designers eyeballed values. Developers hardcoded them.


  • Dark mode was a repaint, not a theme. Every time we needed dark mode, someone manually swapped colours. No mirroring. No token aliasing. Just a person going screen by screen, picking darker versions of each colour.


  • Brand theming for client companies was impossible. NewU wanted to offer custom branding for clients; their logo, their colours in the app. Without semantic tokens, changing a brand colour meant touching dozens of components by hand.


Old colour ramps 1.1


I started by auditing everything we had, then built a three-layer architecture

The audit. I catalogued every colour value used across the product — in Figma and in code mainly. I evaluated two approaches:

Option A: A flat token system — one layer of named colours mapping to values. Simpler. Faster to build. But it wouldn't support theming or dark mode without duplication.

Option B: A three-layer system — Primitives → Semantic Roles → Component Aliases. More complex upfront. But it would make dark mode automatic, brand theming trivial, and future design decisions consistent by default.

I chose Option B. The upfront cost was worth the long-term payoff. Here's how each layer works:

  • Primitives are the raw colour ramps. Blue-50 through Blue-900. Grey-50 through Grey-900. No meaning attached — just the palette. I normalised every ramp to have perceptually even steps.


  • Semantic Roles assign meaning. action-primary points to blue-600 in light mode and blue-400 in dark mode. foreground-default points to grey-900 in light mode and grey-100 in dark mode. The names describe what the colour does, not what it looks like.


  • Component Aliases connect components to roles. A button's background references action-primary. A card's border references border-subtle. Components never touch primitives.


Simple token architecture diagram 2.0


Dark mode went from days of manual work to a toggle

The payoff of three layers: dark mode required zero new names. Light mode maps action-primary to purple-600. Dark mode maps it to purple-400. Same semantic name. Different primitive value. Every component that references action-primary adapts automatically.





Four weeks from audit to shipped documentation

A focused, repeatable cadence over 4 weeks.

  • Week 1: Audit colour usage, list primitives in use, define naming rules

  • Week 2: Build variables (primitives), create roles, map all core components

  • Week 3: Dark aliases, action families, migrate remaining components

  • Week 4 +: QA pass (contrast, leaks), docs, library clean-up and attaching aliases to recent project files.


The hardest week was Week 2. Naming is deceptively difficult. foreground-default vs. text-primary. surface-subtle vs. background-secondary. Every name needed to be intuitive to designers, unambiguous to developers, and scalable for future additions.

  • Before: hard-coded hex, uneven ramps, manual dark/custom theme edits

  • After: token-first system, normalised ramps, light/dark parity, faster theming


The design system now supports theming, dark mode, and client branding from one source of truth

One thing I underestimated: the documentation was as important as the system itself. A perfectly designed token architecture is useless if the team doesn't understand it. I spent more time on the reference tables and migration guide than I initially planned


What I'd do differently next time

I'd also plan for the token system to extend beyond colour. Spacing, typography, and elevation tokens would make the design system fully semantic. Colour was the most urgent problem, but the architecture pattern applies to everything.

Create a free website with Framer, the website builder loved by startups, designers and agencies.