AI slop UI

AI slop UI is the look a model falls back on when nothing in the project tells it otherwise: tracked capitals, eyebrow labels, gradients and glass, colored bars on one edge of a card, status dots, pills, pulsing loaders and words like "seamless". Each design.how system lists these reflexes on its anti-slop page and fails the ones a pattern can catch in its lint.

The systems define 61 anti-slop rules between them (Glaze 17, Quartz 26, Lime 18), each with the reason it exists. The terms below are the common ones. Where a lint rule catches the pattern, the line under it is the exact error the agent reads, which names the fix.

The tells

Tracked capitals
Capitals read slower and make every label shout, so a real warning no longer stands out. Quartz rule anti-slop-no-caps.quartz/no-caps "uppercase" sets capitals or spreads letters; keep sentence case.
Eyebrow
The heading already names the section, and the label only adds a second voice saying less. Lime rule anti-slop-no-eyebrow. No lint rule catches it; the agent checks the screen against the anti-slop list.
Gradient and blob decoration
Decoration competes with the one glowing action, which is the only light Lime allows. Lime rule anti-slop-no-decoration.lime/no-gradient "bg-linear-to-br" draws a gradient; use a flat role such as bg-surface, and the Button primary variant for the one glow.
Glass
The page shows through and pulls the overlay text under its contrast floor. Quartz rule anti-slop-no-glass.quartz/no-glass "bg-raised/70" lets the page show through, which pulls text under its contrast floor; use the solid bg-raised.
Side rail
An edge bar reads as a status stripe, so a selected row looks flagged. Quartz rule anti-slop-no-side-rail.quartz/no-side-rail "border-s-4" with a border color draws a bar on one edge; mark a chosen row with bg-accent-wash, and keep borders 1px all round.
Status dot
A dot carries status by hue alone, which color-blind people, forced colors and screen readers all lose. Quartz rule anti-slop-no-status-dots.quartz/no-status-dot A colored dot carries status by hue alone, which grayscale, forced colors and screen readers lose; use <Status status="ok"/>, which writes the word.
Pill
A pill reads as a toggle, so people click a static tag. Quartz rule anti-slop-no-pill.quartz/no-pill "rounded-full" makes a pill, which reads as a toggle; use <Badge> for a tag, or rounded-inner, rounded-soft or rounded-frame for a box you build. Full radius is for a person (an avatar or the presence mark), and for the radio and the switch, which have their own components.
Stat card row
Equal boxes make every number equally loud, so the one that matters is lost. Lime rule anti-slop-no-stat-cards. No lint rule catches it; the agent checks the screen against the anti-slop list.
Icon tile
The tile spends the hue on decoration, and the glyph names nothing a screen reader can read. Quartz rule anti-slop-no-icon-tiles. No lint rule catches it; the agent checks the screen against the anti-slop list.
Middle-dot separator
A screen reader reads each dot aloud, and the string wraps mid-fact on a phone. Quartz rule anti-slop-no-dot-separator.quartz/no-dot-separator A middle dot between facts is read aloud and wraps mid-fact on a phone; give each fact its own element in a flex row with a gap.
A screen reader listing links hears ten Learn mores and no destination. Quartz rule anti-slop-no-arrow-links.quartz/no-arrow-link "Rotating API keys →" ends in an arrow; a screen reader reads it aloud, so drop it and let the text name where the link goes.
Decorative motion
Constant motion takes the eye from the row that changed and keeps moving under reduced motion. Quartz rule anti-slop-no-decorative-motion.quartz/skeleton-still "animate-pulse" loops for decoration; a Skeleton stays still, and the spinner is Quartz's one looping motion.
Scroll reveal
Content that hides until scrolled is missed. Glaze rule anti-slop-no-scroll-reveal.glaze/no-scroll-reveal whileInView fades or slides content in as it scrolls into view; render it in place, and keep motion for answers to what the person did.
Shimmer text
The sweep drops the text under its contrast floor mid-pass and never says when the work stops. Quartz rule anti-slop-no-shimmer-text. No lint rule catches it; the agent checks the screen against the anti-slop list.
Terminal cosplay
A screen reader reads the signs and brackets aloud, and people try to type at the fake cursor. Quartz rule anti-slop-no-terminal-cosplay. No lint rule catches it; the agent checks the screen against the anti-slop list.
Filler words
The words promise without telling the person what happens or how fast. Quartz rule anti-slop-no-filler. No lint rule catches it; the agent checks the screen against the anti-slop list.
Placeholder data
Placeholder data hides the truncation and alignment problems real data shows. Glaze rule anti-slop-no-fake-data. No lint rule catches it; the agent checks the screen against the anti-slop list.

Before and after

Each pair is the wrong and the right snippet from a system's anti-slop page.

Lime, anti-slop-no-eyebrow. The heading already names the section, and the label only adds a second voice saying less.

Before

<p className="text-xs font-medium text-fg-3">Overview</p><h2>Spending</h2>

After

<h2 className="text-lg font-semibold">Spending</h2>
Lime, anti-slop-no-stat-cards. Equal boxes make every number equally loud, so the one that matters is lost.

Before

<Card>Income</Card><Card>Spent</Card><Card>Saved</Card>

After

<Balance value={1240}/><p>You spent $820 of $2,100 this month.</p>
Quartz, anti-slop-no-dot-separator. A screen reader reads each dot aloud, and the string wraps mid-fact on a phone.

Before

`${model} · ${variant} · ${time}`

The lint says: A middle dot between facts is read aloud and wraps mid-fact on a phone; give each fact its own element in a flex row with a gap.

After

<span>{model}</span><span>{variant}</span><time>{time}</time>
Quartz, anti-slop-no-pill. A pill reads as a toggle, so people click a static tag.

Before

<span className="rounded-full px-2">beta</span>

The lint says: "rounded-full" makes a pill, which reads as a toggle; use <Badge> for a tag, or rounded-inner, rounded-soft or rounded-frame for a box you build. Full radius is for a person (an avatar or the presence mark), and for the radio and the switch, which have their own components.

After

<Badge>Beta</Badge>
Quartz, anti-slop-no-decorative-motion. Constant motion takes the eye from the row that changed and keeps moving under reduced motion.

Before

<span className="animate-ping rounded-full bg-green-500"/>

After

<Status status="running"/>
Quartz, anti-slop-no-filler. The words promise without telling the person what happens or how fast.

Before

Seamlessly deploy robust agents.

After

Deploys an agent in 42 seconds to 3 regions.

How to keep it out

  1. Give the agent a design system it loads on its own, so its defaults never come into play. How to give Claude Code a design system has the commands.
  2. Add the system's lint and have the agent run it before it calls a screen done: npx eslint -c quartz.eslint.config.mjs ..
  3. Review the rendered screen, not the code, at a phone width and a desktop width. The ui-review skill does this and ranks what it finds.

The anti-slop pages themselves: Glaze, Quartz, Lime.

Questions

Why does AI-generated UI look the same?

With no direction in the project, a model reaches for its most likely patterns. The Claude blog post on the frontend-design skill describes Claude sampling from "this high-probability center". So screens from different prompts and different people share the same defaults, and a design system in the project replaces those defaults with decisions.

Is there a lint for AI slop?

Yes. Each design.how system ships an ESLint config with its anti-slop rules, installed with the shadcn CLI, such as npx shadcn@latest add https://design.how/r/quartz/lint.json. @shadcn/lint covers the value side, such as raw colors and restyled components, for shadcn/ui projects.

Are all gradients and shadows slop?

No. Lime keeps one glow on its primary action, Glaze puts glass on what a person presses, and Quartz casts a shadow under overlays. The slop is the reflex: the same effect on everything, chosen by default rather than for a reason.

Sources