All work

Case studyDesign systemHealthcare

Building an enterprise design system from legacy chaos.

How six live product surfaces — including a decade-old legacy application — went from independently reinventing the same button, table, and tab pattern, to one token-driven design system: audited by screenshot, planned atom by atom in Figma, and built in React with accessibility as a default, not a pass.

RolePrimary Designer
Team2–3 designers, 5+ engineers
Timeline2023 — Present
PlatformWeb · Responsive
This case study is published under an active NDA. Specific component details, client names, and internal metrics have been generalized or omitted. Screens shown are abstract representations, not production UI. Happy to walk through the detailed work in an interview.

Challenge

Six product surfaces — one of them a decade-old legacy application — each independently reinventing the same buttons, tables, tabs, and modals. Some had no design tokens at all; one ran three coexisting styling systems at once.

My role

I led the cross-product audit and planned every primitive and pattern atomically in Figma. I'm a product designer, not an engineer — so building the actual React system was a partnership with a senior frontend developer, with 1–2 designers collaborating on patterns.

Outcome

One token-driven component library adopted across every surface, accessibility built in by default, and a documented, evidence-based system built to outlive any single person on the team.

Context

What Viveka looked like before the system.

Viveka Health builds enterprise healthcare platforms — eligibility verification, claims workflows, provider search, care coordination — used by US healthcare organizations to manage benefits and member services.

Those products didn't grow from one codebase. They grew from six — built by different teams, at different times, on different stacks, including a decade-old AngularJS application that was still running in production while its React replacements were being built alongside it. Every team had shipped real business value. Every team had also, independently, built its own version of a button, a table, a tab bar, and a modal.

Research

The audit started with screenshots, not opinions.

Before proposing a system, I needed to know exactly what existed — not what anyone remembered existing. I went surface by surface across all six live products, screenshotting every button, table, tab, and modal I could find in production, including the legacy application still running in parallel with its modern replacements.

Laid out side by side, the fragmentation stopped being a hunch and became a spreadsheet. One product had over 200 raw button elements spread across 60 files, with zero shared button component. Another had installed a full off-the-shelf UI kit and then quietly built a second, hand-rolled set of components anyway — so its button existed six different ways. The largest product ran three separate styling systems at the same time, and its brand red existed as two different hex values for years because of a single mistyped character nobody had caught. Tables had been hand-built independently more than forty times, across four different frameworks. And one small bug said everything about the platform at once: three separate teams had each hardcoded a different guess for the exact same shared header height.

6live product surfaces audited by screenshot
200+raw buttons in one product, zero shared component
40+hand-rolled table implementations, no reuse
3styling systems running at once, same product

That inventory — screenshots, file counts, hex values, the small absurd stuff like a z-index literal twenty digits long — became the brief. It made the case for a system to engineering leadership without me needing to argue for it. The wall of inconsistency argued for itself.

The problem

Four compounding issues, not one.

Calling it “no design system” would've been wrong. Components existed. They just existed everywhere, in slightly different shapes. Once the audit was laid out, four problems were doing the real damage:

  • Fragmentation. The same handful of patterns — buttons, tables, tabs, modals — had been hand-built independently across six surfaces, sometimes more than once within the same product. One team's tabs shared no code and often no accessibility semantics with another team's tabs.
  • Accessibility debt. The legacy application had barely a hundred ARIA attributes across its entire surface. Newer products weren't much better — contrast ratios that failed AA, dialogs where a single Escape key press closed an entire stack of overlays, clickable cards with no keyboard support at all.
  • Velocity tax. The same handful of table cell types and tab visual languages were being reinvented from scratch in every framework represented on the platform. Every new feature meant re-deciding basics that had already been decided five times over, badly.
  • Handoff friction. With three coexisting styling systems in the platform's largest product alone, the same component name could mean three different things depending on which file an engineer happened to open first.
“Design wasn't the bottleneck. Re-deciding was.”

Approach

Five decisions that shaped the system.

01

Start with tokens, not components.

The fastest way to fake a design system is to build a dozen components and call it done. The system looks finished; nothing underneath actually changed.

I argued for starting with the layer underneath: a single source of truth for color, typography, spacing, radii, and elevation, generated into code rather than hand-maintained in three places at once. The audit had already shown what happens without that discipline — a brand color existing as two different hex values because of one mistyped character, copy-pasted across products for years. One generated token file makes that kind of drift structurally impossible, not just discouraged.

Tokens are unglamorous — you ship them and no screen visibly changes. But once they're in place, every component built after is consistent by construction, and the whole system themes from a single file.

02

Plan in Figma, build with engineering.

I designed every primitive and pattern atomically in Figma first — the same layered hierarchy the system now enforces in code, just designed before a line of React existed. Working that way meant every component arrived at engineering already validated as a composition of smaller, reusable parts, instead of a one-off screen that needed reverse-engineering into the system later.

I'm a product designer, not a frontend engineer, so standing up the actual codebase — the build pipeline, the token compiler, the linting rules that enforce the architecture — was a partnership. I worked closely with a senior frontend developer to translate the Figma-side atomic structure into a matching layered system in code, where each layer is only allowed to depend on the one below it.

03

Let evidence pick the variants, not opinion.

Tabs had been reinvented independently across the platform — different products, different frameworks, most with their accessibility semantics stripped out. Rather than inventing a “correct” set of variants, I read every real implementation on the platform and asked what people had actually converged on without ever coordinating. The answer was exactly two visual languages: an underline style and a segmented-pill style. That became the entire Tabs API — not because I decided two was the right number, but because two is what six independent teams had already decided, without knowing it.

Tables got the same treatment at a much larger scale — the single most duplicated pattern on the platform. A dozen-plus hand-rolled implementations became one system built on a proven table engine, and a five-hundred-line hand-rolled table could collapse into a column model and a handful of props.

04

Accessibility as a default, not a pass.

The easy path is to ship components first and audit them for accessibility later. That path produces patches. The hard path is to make accessibility a condition of shipping.

Every component in the system has keyboard support, focus management, ARIA labels, and contrast-checked tokens baked in at the component level. The system supports both a compact and a comfortable density mode for data-heavy screens, but accessibility isn't a mode — when a density choice and a contrast requirement conflict, accessibility wins, every time.

When an outside architecture review came back with real findings — a legacy stylesheet documentation claimed was removed but was still shipping in every build, a single Escape key closing an entire stack of modals — we treated it exactly like our own internal audits: fix it, log the decision, move on. Getting reviewed by someone else was part of the plan, not a failure of it.

05

Documentation and adoption over completeness.

Most design system docs tell you what a component looks like and what props it takes. The documentation I pushed for answers a different question: when should you use this component, and when should you not? Every component carries a maturity signal — stable, beta, experimental, deprecated — so nobody has to guess whether it's safe to build on, and every systemic decision gets logged with its context and consequence, so the same argument doesn't happen again next quarter.

A design system that isn't used isn't a design system — it's a Figma file. I prioritized what teams reached for every day — buttons, inputs, modals, tables, form patterns — over exotic components nobody had asked for yet, and stayed close to the teams adopting the system: pairing during implementation, fixing friction fast.

Outcome

What changed, qualitatively.

Shorter path from spec to ship.

Patterns that used to mean a five-hundred-line hand-rolled table, or yet another one-off tab bar, now mean composing existing primitives — and engineering handoff is noticeably faster with no more re-litigating which button to use.

Accessibility by default.

Components ship with WCAG 2.2 AA compliance built in, including a density system where accessibility always wins the conflict. Teams don't need to become accessibility experts — they just need to use the system correctly.

A shared vocabulary.

A product that once ran three coexisting styling systems at the same time now runs one. Design, engineering, and product use the same names for the same things, and reviews stopped being consistency debates.

A system that can outlive me.

With tokens, a logged decision history, and a recurring audit practice in place, the system keeps working whether I'm in the room or not. That's the real deliverable.

Reflection

What I'd do differently.

If I started again, I'd invest more in adoption infrastructure earlier — office hours, a channel for system questions, regular component critiques. The system gains trust by being a good teammate, not just a good library.

I'd also push harder on engineering partnership from week one. The best parts of the system came from tight collaboration with the frontend engineer building it alongside me — and the slowest parts came from moments when design ran ahead and engineering had to catch up.

Design systems aren't a design project. They're a team practice. The sooner you treat them that way, the better they get.