Vibe Coding Methodology · Quality Baseline

Style Convergence: Don't Ship Eight CSS Kits for One Button

Ask AI to ship ten features in a row, and you'll pile up eight button classes that look almost the same. It's not that it won't reuse — each new conversation has no idea what you already have. This lesson covers why styles proliferate, how to clean them up, and which differences should stay.

Reuse firstdesign tokenTech debt
Interactive Demo 1 · Pile Up a Heap of Buttons Yourself

This simulates a real project's iteration. Each click of "Add another feature" is you opening a new conversation and asking AI to build a page. Watch how it handles the button each time, and how the four numbers below climb.

The project is still empty. Click the button below to start iterating.

Round 0: Not started yet.
0Button impls
0Primary colors
0Corner radii
0Lines of CSS

After eight rounds, look at this pile of buttons — you can't tell which one to edit. That's the feel of "loose parts."

Don't rush to blame AI — the environment forced its hand

Reinventing styles isn't the model being lazy. It's three structural reasons stacked together. See the reasons, and you'll know where to put the gate.

Can't see

Your CSS isn't in front of it

A new conversation only has the few files you just handed it. It has no way to know the project already has .btn-primary, so it writes a fresh one for the request.

Cheaper

Writing new is cheaper than reading the old

Understanding an existing style means reading every related file, plus worrying that a change will break something else. A new class name is zero risk and zero reading cost — that's its optimal solution, not yours.

Won't touch

Afraid of breaking things, so it adds a parallel copy

When it needs a button with a shadow, it would rather write .btn-primary-new than change the original — editing a style others already use is high-risk, so it picks the safe path that proliferates.

All three reasons point to the same thing: it's missing a list of "what we already have." Write that list into the project rules file so it can see it every round, and the proliferation stops. Same idea as Lesson 8 encoding environment facts in a Rule — this time the asset is styles.

Four steps to converge: inventory first, then merge, then gate

Don't expect one big refactor to clean up a messy project. Follow these four steps — you can stop and verify after each one.

1

Inventory — look, don't touch

Have AI scan the project's styles and produce a duplication list: which classes implement the same control, how many color and radius values are scattered around. No code changes in this step — first see how much debt you owe.

2

Set tokens — fold magic numbers into a few tiers

From the inventory, pick the values actually in use and lock them into a small set of variables: primary color, semantic colors, two or three radius tiers, four spacing tiers, control height. Few tiers — few is what you can defend.

3

Merge in batches, one control at a time

Buttons first, then verify; cards next, then verify; then inputs. Commit each batch separately so you can roll back one batch if something breaks. Convergence is an equivalent replacement — visually nothing should change. If you actually need a new look, that's a different task.

4

Set a gate so it doesn't grow back tomorrow

Write this into the rules file: "Before writing a new style, search tokens and shared components first. Reuse if you find one; only create a new one if you don't, and say what you searched." Without this gate, you'll be cleaning up again in three months.

Interactive Demo 2 · Merge it, or keep a justified difference

The easiest place for convergence to go too far is flattening differences that should exist. Five real style pairs — you decide which were piled up by accident, and which have a reason.

One test: does the difference have a name

To decide whether to merge, ask one question: what is this difference called? If you can name it, keep it — "secondary button," "destructive action," "touch-target minimum," "overlay one tier above the card." Those are design decisions; write the reason in a comment. If you can't name it, merge it — two radii 2px apart, two blues the eye can't tell apart. They aren't called anything. They were written on the fly.

The consistency lesson in the Taste series says the same thing: difference isn't a crime — having no reason is. That lesson covers how to set the variable table from the design side; this one covers how to pull things back once the code has scattered. Read them as a pair: one gives you the standard, the other gives you the surgical plan.

Further reading: Taste Engineering · Consistency: Where System Feel Comes From (how to set tokens) · Previous lesson: PlayGround (where to tune components after you converge)

Three traps you'll hit while converging

Big-bang full rewrite

Tell AI to "unify the site's styles" and you'll get a 60-file diff you can't review and don't dare ship. Always batch by control.

"While we're here" visual tweaks

During convergence it often "optimizes" the radius and palette while it's at it. Then you can't tell whether the page looks different because of a merge bug or its aesthetic improvisation. Convergence is equivalent replacement only.

Tokens too fine-grained

Twelve radius tiers and nine grays is the same as having none — next time it still has to pick, and it will pick wrong. Tiers only constrain when there's almost nothing to choose from.

Key Takeaway

AI will not reuse what you never told it exists. Styles proliferate because it forgets every round, so the fix has two halves: fold the mess into tokens by control, and block the future with one rule — search before you write. The Skill at the top of this page is the executable version of both halves. Copy it to your Agent; it will hand you a debt inventory first, instead of starting to edit.

The companion rule is "check for duplicates before adding a feature" in the itshen/xs_vibe_rules repo. This lesson extends that from features to styles.