We started with a comprehensive audit of every screen, component, and color scheme across our Figma files. Not just to count problems — but to understand why they had accumulated and what they were costing us. The audit gave us a holistic picture of the design landscape and a clear brief for what EntriVerse needed to solve.
What looked like a visual inconsistency problem turned out to be three separate problems stacked on top of each other.
Our primary color, #59A1C9, failed WCAG contrast standards — and it wasn't the only one. Color contrast ratios were broken across the product, including onboarding and core learning flows.
Each designer had developed their own style — their own color usage, spacing conventions, component shapes. Good intentions, but no shared foundation. The output diverged with every sprint.
Color values were hardcoded everywhere. A brand color update meant manually hunting through dozens of Figma files. There was no token layer — so a single change cascaded into hours of design cleanup.
There was no architecture to support a dark theme. Without tokens mapping colors to intent, building dark mode would have meant duplicating every screen and maintaining two parallel design systems indefinitely.
Every team was designing in good faith. The problem was structural: there was no shared layer between design decisions and implementation. Each designer maintained their own component set. Each developer interpreted specs locally. There was no contract between them.
The inconsistency wasn't a discipline problem. It was a missing infrastructure problem. Without tokens, without a component library with documented states, without accessibility baked in at the source — the output was always going to drift.
Before committing to building a full design system, we considered lighter-weight approaches. Each had a reason it wasn't enough.
color.text.on-primary always passes AA against its background), it can't be accidentally violated in a component. The foundation fixes the root cause, not just the symptoms.
What if accessibility, consistency, and speed weren't separate problems — but all symptoms of the same missing layer?
The system was built in layers. Global tokens first — raw color, spacing, radius, and type values with no semantic meaning attached. Then reference (alias) tokens that mapped globals to usage intent, with light and dark modes both defined. Then component tokens that only referenced aliases, never raw values.
The timing was fortuitous. Our mobile engineering team was simultaneously migrating to Jetpack Compose and KMM for unified Android and iOS support — a ground-up rewrite. That meant they could implement the design tokens natively in Compose from day one, rather than retrofitting them onto legacy code. The design system didn't have to fight existing patterns. It became the pattern.
A design system is only as good as its adoption. The token architecture and component library were the foundation — but these specific decisions were what made designers and developers actually use it.
The building blocks of the system — color, spacing, radius, type. Named by scale (blue-300, space-4) — consistent everywhere, but with no usage meaning attached.
Global tokens mapped to intuitive, usage-intent names — with light and dark mode colors both mapped here. WCAG contrast verified at this layer. Change a global token and the alias updates everywhere.
Component-level tokens for specific elements — buttons, cards, form fields, radio buttons. Reusable, documented styles that ensure consistency without locking teams into rigid patterns.
Every interactive component required a visible focus state, a 44×44px minimum touch target, and a colour contrast ratio of ≥4.5:1 before it could be added to the library. Not guidelines — hard gates.
Default, hover, focus, active, disabled, loading, error — all explicitly designed and annotated. Developers stopped asking "what does the disabled state look like?" because the answer was always one click away.
Instead of a single Button component with 30 props, components were kept small and composable. A Card was a surface + padding token — not a locked pattern. Teams could build layouts without needing new components.
Component documentation focused on when to use a component, not just what it does. "Use the destructive variant only for irreversible actions" prevented misuse better than listing every prop value.
The implementation of EntriVerse yielded tangible outcomes: increased design delivery speed and reduced development time. These were the metrics we committed to at the start — and they held up.
Accessibility, consistency, and slow handoffs aren't three problems. They're three symptoms of one missing thing — a shared layer between decisions and implementation.
The biggest shift in thinking was understanding that EntriVerse wasn't a project to complete — it's infrastructure to maintain. A design system needs to evolve as the product evolves. Locking it down creates a different kind of bottleneck.
Because the system was touched by multiple designers simultaneously, we built a change log page to track every update — what changed, why, and when. That single artifact became one of the most-used references on the team. It made the system feel trustworthy, not mysterious.
The system is live and in active use, but a design system is never done. Version 1 solved the foundational problems — here's what V2 looks like.
Extend EntriVerse beyond the core app to web, admin, and partner surfaces — using the same token layer so brand stays consistent across every product touchpoint.
Introduce a formal deprecation process so legacy components can be retired without breaking existing screens in production.
Track which components are most used, most deviated from, and most often questioned — to prioritise what gets documented and improved next.
Open the system for developer contributions with a lightweight RFC process — so the system grows with the team instead of creating a bottleneck.