# avoid-ai-design **A Claude Code skill that audits AI-generated frontend code and rewrites it so it stops looking AI-generated, including the "tasteful" defaults that replaced the purple gradient.** [](LICENSE) [](https://agentskills.io) [](https://claude.com/claude-code) [](#compatibility)
One real page, run through the skill. Same product, same sections, same copy; only the design changed. The scanner finds 23 tells before and no design tells after. Pages and the full audit: examples/demo/.
Ask Claude, Codex, or any model to "build a landing page" and you get the same page every time: a purple-to-blue gradient, Inter for every word, a centered hero over three rounded feature cards, a glassy navbar. Ask it to make that look less AI and you get the *next* same page: warm cream with a terracotta accent, or near-black with one acid-green signal, all-caps monospace labels, one colored word in the headline, features numbered 01 / 02 / 03. `avoid-ai-design` catches both. It scans the frontend an AI just produced, flags the patterns that give it away, and rewrites the interface around a direction drawn from your product rather than from a list of looks. On multi-page work it writes that direction down once, in a `DESIGN.md`, so page two cannot drift from page one. It is the design counterpart to [`avoid-ai-writing`](https://github.com/conorbronsdon/avoid-ai-writing): same idea, applied to UI instead of prose. --- ## The problem: AI design converges, twice Models are trained toward the average, so their UI clusters around safe defaults you can recognize on sight: - **Type** that is always Inter, Roboto, or the system stack, with no pairing and no display face. - **Color** that is a purple or indigo gradient fading into blue. - **Layout** that centers everything: hero, subhead, two buttons, then a three-card feature grid. - **Components** wrapped in `rounded-2xl`, `shadow-lg`, and `backdrop-blur`, straight from the shadcn defaults. - **Copy** that opens with "Elevate your workflow" and ends with a "Get Started" button. Then the fix converged too. Anthropic's own `frontend-design` skill now lists the clusters AI design gathers around once it avoids the purple: cream with a terracotta accent (Claude's own interface color), near-black with one acid-green or vermilion signal, broadsheet hairlines, the SaaS card kit, and template chrome like tracked all-caps eyebrows and `A · B · C` meta strings. These *second-order defaults* read as AI to anyone who has seen a few hundred generated pages. This skill's own first demo landed in them, which is how v0.4 came to check for them by name. ## What it catches The full catalog lives in [`references/ai-tells-catalog.md`](references/ai-tells-catalog.md): 67 tells, each with a detection signal, why it reads as AI, a fix for plain HTML/CSS and for React + Tailwind + shadcn, and its sources. | Category | Example tells | |---|---| | **Second-order defaults** | cream + terracotta (the Claude look), near-black + one acid-green accent, broadsheet cosplay, all-caps and mono template chrome, one accented headline word, decorative 01 / 02 / 03, fake window dots, the emerald fallback | | **Typography** | Inter everywhere, the "tasteful free font" set (Space Grotesk, Geist, Instrument Serif, Fraunces), a face declared in CSS but never loaded | | **Color** | the purple/indigo gradient, gradient headline text, untouched shadcn palettes, one hue pretending to be two, muted text below WCAG AA | | **Layout** | the centered hero, three icon cards, the stock section order (hero, logos, features, stats, pricing, CTA), three-tier pricing rings, the four-column footer | | **Components** | `rounded-2xl shadow-lg` on everything, reflexive glass, icon-in-a-rounded-square, stock Aceternity / Magic UI effects, missing focus states | | **Motion** | the same fade-up on every section, bounce easing, count-up stats, animation that ignores reduced-motion | | **Icons, copy, imagery** | the worn Lucide set and the sparkle-for-AI, "Elevate / Seamless / Powerful", arrows welded to CTAs, generic CTA labels, placeholder avatars | | **Consistency** | design-system drift: font, color, radius, nav, or footer that changes from page to page, or ignores the design you chose | Every tell is ranked by **who notices it**: P0 a layperson, P1 a designer or developer, P2 craft and polish. And the catalog is explicit about what *not* to flag: a tell is evidence of a default nobody chose, never proof that a model made the page. ## Scan in one command `scripts/detect.mjs` finds the code-certain tells with no model call and no dependencies (Node 18+): ```bash node ~/.claude/skills/avoid-ai-design/scripts/detect.mjs src/ ``` ``` src/app/page.tsx P0 5 · P1 12 · P2 4 P0 C1 Purple / indigo gradient L13 The canonical unchosen gradient (the Tailwind indigo-500 lineage). P0 C6 Gradient-filled headline text L13 bg-clip-text gradients are a 2024-era default flourish that also hurts legibility. P0 L1 Pill badge + centered hero L13 ... ``` - `--json` for machine-readable output, `--min=P1` to hide polish-level findings. - Exit code `2` when any P0 or P1 is found, `0` when clean, so it works as a CI gate. - It skips `examples/`, `fixtures/`, `stories/`, and files marked `slop-example`, and it honors ignore comments for choices your brief asked for: `avoid-ai-design-ignore: SD1` on a line, or `avoid-ai-design-ignore-file: SD1, SD4` in a file. The scanner covers the half of the audit that lives in source. Palette weight, spacing rhythm, hierarchy, and structure-level sameness need a render, and the skill does that part. **Optional: check every UI edit in Claude Code.** Add a `PostToolUse` hook to `.claude/settings.json`. When an edit introduces P0 or P1 tells, Claude sees the list right away and can fix it in the same turn: ```json { "hooks": { "PostToolUse": [ { "matcher": "Edit|Write|MultiEdit", "hooks": [ { "type": "command", "command": "node ~/.claude/skills/avoid-ai-design/scripts/detect.mjs --hook" } ] } ] } } ``` ## Two modes | Mode | What it does | When to use | |---|---|---| | `rewrite` *(default)* | Scan, audit, plan a direction, review the plan against the defaults, rewrite, re-scan | You want the UI fixed | | `detect` | Scan and audit only, no edits | You want to see the tells and decide yourself, or you are reviewing code you should not change | Trigger `detect` with phrases like "just audit", "flag only", "don't change the code", or "scan this for AI tells". ## How it works 1. **Scope.** What is under review, the stack, the mode, and any design system you already have: a `DESIGN.md`, tokens, sibling pages, or a font and color you chose. 2. **Scan.** Run the scanner for the code-certain tells. 3. **Render.** Screenshot the UI when a tool is available, judge the visual tells from pixels, and run the silhouette test: shrink the page to a black-and-white block outline and ask whether it could be anyone's. 4. **Audit.** Merge everything into one report: each tell with its ID, location, severity, and why it reads as AI. 5. **Ground the plan in the subject.** If a system exists, it is the direction. Otherwise, derive one from what the product is made of (its materials, its artifacts, its vernacular) and write it down as 4-6 colors with roles, the faces, a layout idea, and one signature detail. 6. **Review the plan against the defaults.** For every move: would you have made it for any similar page? If so, it is a default. Revise it before any code is written. You confirm the plan. 7. **Rewrite.** Edit the real files at the right depth: surgical inside a design system, a rebuild for a standalone page. Functionality, props, data flow, accessibility, and the meaning of your copy stay intact. Multi-page work gets a `DESIGN.md` ([template](references/design-md-template.md), Google's open format) that every page is built from. 8. **Re-scan and judge.** No P0, no second-order default the brief did not ask for, and four tests: justified, coherent, not a second-order default, consistent across pages. ## See it work on a real page [`examples/demo/`](examples/demo/) is a real end-to-end run on one generic AI-built SaaS page. Every file holds the same product, sections, and copy; only the design varies. **1. The run.** [`slop.html`](examples/demo/slop.html) is the page an AI tool produces unprompted. [`refined.html`](examples/demo/refined.html) is the same page after the skill, grounded in the product's most characteristic artifact: the retention cohort table is the hero, the page is built like a table, and the table's heat ramp is the only color. [`AUDIT.md`](examples/demo/AUDIT.md) is the full run, including an honest section on what the previous version of this demo got wrong. Full-page screenshots: [before](docs/demo-before.png) and [after](docs/demo-after.png). **2. More than one right answer.** The same page, rebuilt four ways, each drawn from a different part of the product's world, each scanning clean of first- and second-order defaults: