DEV Community

Cody Wang
Cody Wang

Posted on

An AI cleanup deleted 8 lines of CSS. The build passed. The signboard vanished.

A few weeks ago I asked an agent to tidy the token layer of a restaurant template. It did exactly what I asked. One theme block had eight custom properties that looked unused: three wood tones, one border shade, one inset shade, and three paper tones for a signboard face. Nothing in the React code referenced them by name. The agent deleted all eight and reported "removed unused variables."

The build passed. Typecheck passed. No console error. The page still rendered.

The hand-painted A-frame sign at the top of the page — the one element a customer would actually photograph — was now a blank, transparent rectangle. Every gradient on it resolved to nothing.

Why nothing caught it

  • CSS custom properties are strings. var(--wood-2) with no definition is not a syntax error; it's invalid at computed-value time, so the property falls back to unset — usually transparent.
  • TypeScript doesn't read CSS. ESLint doesn't know your design tokens. Neither does the bundler.
  • Lighthouse is happy. Zero errors, zero warnings. The page is still "accessible" and still "fast."
  • "Unused" had been judged by grepping the TSX. The tokens were consumed in a different language — inside linear-gradient() and layered box-shadow.

Here's the shape of what disappeared, from the theme block:

[data-theme="estuario"] {
  --wood-1: #8b5a2b;  --wood-2: #6e4320;  --wood-3: #a67c52;
  --wood-border: #5c3a1e;  --wood-inset: #3d2412;
  --board-face-a: #f3ebe0;  --board-face-b: #e8dcc8;  --board-face-c: #d9c9b0;
}
Enter fullscreen mode Exit fullscreen mode

Eight lines. The sign was built from all eight.

What I changed in my process

  1. The token layer is additive-only. Deleting from it requires a human diff review, even at eight lines.
  2. Every change ships with before/after screenshots of the section it touched, at 390px and 1440px — not a screenshot of the homepage.
  3. I review by blast radius, not diff size. Those eight deleted lines touched every surface on that page. A 300-line new component touches one section.
  4. Before any deletion, the agent has to say what consumes it, with a grep across CSS, TSX, and JSON. If it can't produce that, it doesn't delete.

The part that generalizes

Agents are strong at additive work and unreliable at cleanup, because cleanup requires knowing the blast radius — and the blast radius is precisely what isn't in the file being edited. A deletion is a claim about the whole repo. Most of the time nobody checks that claim.

So my rule is boring: additions get reviewed by tests, deletions get reviewed by eyes. Build passing means nothing here — it passed the whole time the sign was gone.

If you're shipping sites with agents, the review is the product. The 17 templates I've shipped all clear the same gates — zero console errors, no horizontal overflow at 390px, 7:1 contrast, no external image domains — and not one of those gates would have caught this. Only the screenshot did.

Live pages: https://slice-templates-pool.vercel.app/

The broader build, and why the constraint is verification rather than generation speed: https://dev.to/amazong110/i-built-17-nextjs-homepage-templates-heres-the-part-ai-cant-do-389h

Top comments (0)