Design system
Tokens

The problem
NewU had a colour problem, but not the kind a new palette could fix. Nobody had decided what each colour meant.
Buttons used one blue and links used another, even though they were meant to match. Neither pointed to a shared system. Dark mode meant repainting every screen by hand. Theming the product for client brands was a guessing game.
Every new feature meant answering the same question again: what colour should this be?
What I found
I started with an audit, listing every colour value used across the product in both Figma and code. Four issues kept coming up.
Components used raw values. A button background pointed straight at a palette colour instead of a role like "primary action".
Colour scales were uneven. Greys and brand accents jumped in inconsistent steps across the product.
Dark mode was a repaint, not a theme. Screens couldn't inherit the right values, so each one was adjusted by hand.
Client theming was close to impossible. Changing a brand colour meant editing dozens of components one by one.
The root cause was the same every time. Components were tied to what a colour looked like, not what it was for.

My approach
I weighed two options.
Option A was a flat token system: one layer of named colours mapped straight to values. It was faster to build, but it couldn't support dark mode or theming cleanly.
Option B was a three layer system. It took more work upfront, but it could handle dark mode, white labelling and future growth without making the same decisions twice. I chose Option B.
Primitives are the raw colour scales, like Blue 50 to Blue 900. They carry no meaning.
Semantic roles give colours meaning. Names like action-primary or foreground-default describe what a colour does, not how it looks.
Component tokens connect components to roles, so buttons, cards and inputs never touch raw values.

What I built
We went from audit to shipped documentation in four weeks.
Week 1. Audited colour usage, listed the primitives already in use and set the naming rules.
Week 2. Built the primitives, created semantic roles and connected the first core components.
Week 3. Added dark mode values, extended the action colours and moved the remaining components over.
Week 4 onward. Checked contrast, fixed leftover raw values, documented the system and connected recent project files.
Week 2 was the hardest. Naming is harder than it looks. Every name had to make sense to designers, be precise enough for developers and still work as the system grew.

The results
The three layers paid off straight away. In light mode, action-primary points to one colour. In dark mode, the same role points to another. The name never changes, so every component that uses it adapts on its own.
Dark mode went from days of manual work to a toggle. Client theming became realistic too. Once the roles existed, a brand update stopped being a recolouring exercise.
Before Hard-coded hex values, uneven scales and manual edits for dark mode and client themes
After A token-first system, even scales, full light and dark parity and much faster theming
This system became the foundation for what came next. The gamification work could feel like one product on every screen because the tokens enforced it. The Personal Space redesign could rely on accessible, consistent patterns because contrast was guaranteed at the token level, not checked component by component.

What I learned
Tokens are invisible when they work, but they are the reason everything visible holds together.
Next time, I would extend the same structure beyond colour much earlier. Spacing, typography and elevation tokens would make the whole system meaningful, not just visually consistent. Colour was the most urgent problem, but the pattern is bigger than colour.
