← Back
[W] Writing

Your design system didn't drift, your product did

When a mature product looks inconsistent, people tend to look for someone to blame. Someone wasn't careful, or someone ignored the system.

Working on the dashboard at TextCortex, I came to think that's almost never what happened. Different areas had been built at different times, by different people, under different deadlines. Each one was reasonable by itself. They had just drifted apart.

Here's what that tends to look like.

ContinueSettings, year one
ContinueBilling, a redesign
ContinueEditor, needs density
ContinueOnboarding, a campaign
ContinueTeam, built quickly
ContinueTemplates, a contractor
An illustration, not TextCortex's real buttons. They're rendered live with slightly different radius, padding, weight and colour. Any one of them is fine. It's only the whole set that's wrong.

Each difference is easy to defend. The editor really does need to be denser. The campaign really was in a hurry. This is why you can't review your way out of it. Nothing ever looked wrong in the pull request.

The real cost is what comes later

The inconsistency itself isn't the worst of it. A person using one page might never notice that another page has a slightly different radius.

The cost shows up the next time you want to improve something.

Twenty copies. One improvement is twenty edits, so it becomes a project, and projects get postponed.
One source. One improvement is one edit, and every screen gets it.
The same twenty screens. This is why I care about centralising. Tidiness is the smaller benefit.

When a decision lives in twenty places, nobody makes it better, because no one has budgeted for twenty edits. So the product gets worse in a way nobody can see: not through bad decisions, but through good ones that never got made.

You can't fix this with a redesign

The tempting answer is a big redesign. Stop everything, make it all match, then launch.

On a mature product with people using it every day, I don't think that works, and it wasn't what I did at TextCortex. I worked on two threads at once.

Thread one: improve an area
  • Pick one area
  • Tighten hierarchy, spacing, states
  • Remove one-offs
Thread two: pull decisions into the system
  • Find the copies
  • Move the decision to one place
  • Point the screen at it
Without the second thread, the first one doesn't last. Your improvement is just one more copy, and it starts drifting the day you ship it.

No single change here is dramatic. There's rarely a good before-and-after screenshot, which makes this work hard to show off and hard to get approved. But people experience an interface as a whole, and a dashboard where every area behaves the same way feels calmer than one where each page has its own rules.

Consistency as the default

Here's the code version of the whole idea.

/* Before: each screen decides */
.billing-cta { border-radius: 8px; padding: 6px 13px; }
.editor-cta  { border-radius: 4px; padding: 4px 10px; }

/* After: the system decides */
.button { border-radius: var(--radius-control); }
[data-density="compact"] { padding: var(--space-1); }

The editor still gets to be denser, since that was a real need. But now density is a decision the system knows about, and it stops being a private arrangement inside one file.

That's the distinction I'd keep. Some of the differences in your product are real, and those deserve a name. The rest are just history.

Once decisions live in one place, consistency stops being a cleanup task. New screens start out consistent, and building more of the product stops meaning more drift.

Next