Every round of visual iteration adjusts something — a margin, a border color, a heading size. If each adjustment is a bare number, the next iteration has no anchor to compare against. Three sessions later the spacing feels arbitrary because it is arbitrary: each value was set against the previous value, not against a scale.

Treating CSS variables as a design-system contract turns consistency from a memory problem into a constraint the code can enforce.

#The Drift Problem

Style drift is not a judgment call gone wrong. It is what happens when the reviewer and the author have no shared reference. In agent-assisted work it accelerates: the agent is asked to "make it a bit tighter," tightens by some amount, and the next reviewer — human or agent — has no way to check whether the new value is part of the system or a local exception.

The symptoms are recognizable:

Each value is defensible in isolation. The problem is the set.

#The Constraint Pattern

Declare the vocabulary once, reference it everywhere. CSS custom properties are designed for this — they turn named tokens into the only legal values for margin, padding, color, and border width.

A minimal spacing scale:

:root {
  --space-xs: 0.25rem;
  --space-sm: 0.5rem;
  --space-md: 1rem;
  --space-lg: 1.5rem;
  --space-xl: 2.5rem;
}

.section { padding: var(--space-lg); }
.card + .card { margin-top: var(--space-md); }

The rule is not "use variables sometimes." The rule is "a bare rem or px for margin, padding, border-width, or gap is a bug." Variables should cover every decision the design makes repeatedly.

#What to Put Under Variables

Anything that appears more than once and is expected to stay consistent:

#Why This Mirrors Brand-Constant Single-Source-of-Truth

The same principle operates at the project-metadata layer: keep brand name, tagline, and URLs in one place (e.g., package.json) and read them from build scripts, OG tags, and canonical URLs. Duplicating "Agent Master Handbook" across templates produces the same class of bug as duplicating 1.5rem across CSS — eventually one copy drifts.

CSS variables are the styling-layer instance of the same rule: constants live in one place, consumers reference them. The payoff is identical: future changes touch one line, not fifteen.

#Typography Baseline as an Anchor

Once variables define the vocabulary, the scale itself needs an anchor. Inventing a new typographic scale for technical documentation rarely produces something better than what already works. Start from a known-good baseline and adjust only where editorial voice requires it.

For article-like content, GitHub Markdown CSS is a widely adopted reference:

Deviating by more than roughly ±15% from these values usually signals drift, not intent. Pick the baseline that matches the content genre (editorial, documentation, marketing), then encode the derived values as variables so future edits stay inside the chosen scale.

#How to Adopt Incrementally

A repo that already has drift does not need a full rewrite.

  1. Audit what is already there. List every distinct value used for margin, padding, and border in the current stylesheet.
  2. Cluster and name. Most of the numbers will cluster around five to seven canonical sizes. Name those; discard the rest.
  3. Extract the scale. Declare the cluster representatives as CSS variables.
  4. Replace bare values, one property at a time. Spacing first (highest drift rate), then borders, then colors.
  5. Forbid bare values going forward. Add a lint rule, a review check, or — if neither is available — a line in the project's agent instructions that says bare rem/px for margin/padding/border is a review finding.

The final step is what makes the system stick. Without it, the next iteration drops a bare 1.125rem back in and the audit was temporary.

#Review Surface

Once the scale exists, the review criteria collapse to a small set of questions:

These questions are mechanical enough to be part of an automated lint rule or a post-change review skill. Drift becomes a findable, fixable class of issue rather than an aesthetic argument.

#References