# 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.

Updated 19 October 2026. By Arlan Marat (https://design.how/about).

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`.

Lint `quartz/no-caps` prints: `"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`.

Lint `lime/no-gradient` prints: `"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`.

Lint `quartz/no-glass` prints: `"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`.

Lint `quartz/no-side-rail` prints: `"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`.

Lint `quartz/no-status-dot` prints: `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`.

Lint `quartz/no-pill` prints: `"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`.

Lint `quartz/no-dot-separator` prints: `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.`

### Arrow link

A screen reader listing links hears ten Learn mores and no destination. Quartz rule `anti-slop-no-arrow-links`.

Lint `quartz/no-arrow-link` prints: `"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`.

Lint `quartz/skeleton-still` prints: `"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`.

Lint `glaze/no-scroll-reveal` prints: `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:
```tsx
<p className="text-xs font-medium text-fg-3">Overview</p><h2>Spending</h2>
```

After:
```tsx
<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:
```tsx
<Card>Income</Card><Card>Spent</Card><Card>Saved</Card>
```

After:
```tsx
<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:
```tsx
`${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:
```tsx
<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:
```tsx
<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:
```tsx
<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:
```tsx
<span className="animate-ping rounded-full bg-green-500"/>
```

After:
```tsx
<Status status="running"/>
```

Quartz, `anti-slop-no-filler`. The words promise without telling the person what happens or how fast.

Before:
```tsx
Seamlessly deploy robust agents.
```

After:
```tsx
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](https://design.how/claude-code-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](https://design.how/skills/ui-review) skill does this and ranks what it finds.

The anti-slop pages themselves: [Glaze](https://design.how/systems/glaze/foundations/anti-slop), [Quartz](https://design.how/systems/quartz/foundations/anti-slop), [Lime](https://design.how/systems/lime/foundations/anti-slop).

## 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

- [Claude blog: Improving frontend design through Skills (12 November 2025)](https://claude.com/blog/improving-frontend-design-through-skills)
- [shadcn-ui/lint on GitHub](https://github.com/shadcn-ui/lint)

## Related

- [What is a design system for agents?](https://design.how/design-systems-for-agents.md)
- [design.how vs the frontend-design skill](https://design.how/compare/frontend-design-skill.md)
- [How to give Claude Code a design system](https://design.how/claude-code-design-system.md)
