Designing with Claude Without the AI Slop: Constraints, Skills and Verification Loops
Ask any model for a landing page and you get the statistical centre of every landing page it has learned from. Better adjectives will not fix that. Encoding taste as constraints, packaging it as Claude Code Skills, and verifying every render with real measurements will.
AI design looks generic because the model gives you the average of everything it has seen, so the fix is to write your taste down as firm rules, have the AI load them every time, and check every page with real measurements.
Thesis
AI-generated design converges on the statistical median of the web; distinctiveness comes from encoding taste as constraints, skills and verification loops — not from better prompts alone.
Key takeaways
- “Slop” has a mechanism: models sample from the high-probability centre of their training data, and preference tuning narrows output diversity further. Anthropic’s own engineers call it distributional convergence.
- Constraints beat adjectives. A brief with a palette, a type system, a ban list, a structural reference and the real content moves the model off the median; “bold and modern” does not.
- Package taste once as a Claude Code Skill. Only its description sits in context until it is needed, so a detailed house style costs almost nothing per session.
- Ban lists create new defaults. Anthropic found Claude converging on Space Grotesk after Inter was banned — so pair bans with positive choices and a reason for each.
- Never accept UI you have not rendered, critiqued and measured. On this site, one contrast audit moved code comments from 3.12:1 to 4.90:1 with a single hex change.
- Accessibility is the constraint that keeps distinctiveness honest: 83.9% of the top million home pages still fail text contrast in 2026.
I rebuilt this portfolio with Claude Code. Partway through, I looked at a draft and said the quiet part out loud: the fonts are giving AI slop. The hero used Fraunces, a display serif, with one word set in an italic accent — a look I had seen on a great many AI-generated sites. Nothing about it was wrong. That was the problem. We replaced it with Archivo, a variable sans-serif whose width axis lets headlines run condensed, and IBM Plex Mono for labels and data. The site you are reading is the result.
That moment is the subject of this article, because it exposes something more general than one font choice. My thesis: AI-generated design converges on the statistical median of the web, and distinctiveness comes from encoding taste as constraints, skills and verification loops — not from better prompts alone. A prompt is a one-off request. Taste that survives across sessions, collaborators and deadlines has to be written down as rules the model must follow, loaded automatically, and checked against a rendered page with real numbers.
Here is the route. I start with why this matters now and what the data say about the web that models learn from. I explain the mechanism behind “slop”, then offer a framework. The deep dives cover the anatomy of slop tells, constraint-first briefs with templates, packaging taste as Claude Code Skills, plugins and MCP servers, the render–critique–measure loop, and accessibility as a design constraint. I then walk through three cases — including this site’s redesign — before steelmanning the objections, drawing out implications by role, setting out an action plan and stating the limits of the evidence.
Context: why this matters now
A growing share of interface code is now drafted by models. That changes the economics of design: a passable page costs minutes rather than days. It also changes the failure mode. When a page is cheap to produce, the scarce thing is no longer a page — it is a page that looks like it belongs to you, and that works for everyone who has to use it.
The second point is not hypothetical. WebAIM’s annual scan of the top one million home pages found detectable WCAG failures on 95.9% of them in February 2026, with an average of 56.1 errors per page. Low-contrast text — the most common failure — appeared on 83.9% of home pages, up from 79.1% a year earlier, ending a slow improvement (WebAIM). WebAIM suggests the trend likely reflects broader shifts in web development, including more third-party frameworks and AI-assisted coding, though its scan does not measure AI-generated sites directly. The same report links error counts to technology choices — pages using Astro, the framework this site is built on, averaged 9.0 errors — while stressing that these correlations do not show the technology caused the difference. Defaults in the stack matter, for better and worse.
Exhibit 1
Four in five top home pages still ship low-contrast text — and 2026 went backwards
Share of the top 1,000,000 home pages with detected low-contrast text (%)
Automated detection only: automated tools cannot detect every accessibility issue, so true failure rates are likely higher.
Source: WebAIM, The WebAIM Million (2026 report)
View data table
| Year | Low-contrast text (%) |
|---|---|
| 2019 | 85.3 |
| 2020 | 86.3 |
| 2021 | 86.4 |
| 2022 | 83.9 |
| 2023 | 83.6 |
| 2024 | 81 |
| 2025 | 79.1 |
| 2026 | 83.9 |
Exhibit 2
Contrast is the most common accessibility failure on the web, ahead of missing alt text
Share of top 1,000,000 home pages with each detected failure, February 2026 (%)
Source: WebAIM, The WebAIM Million (2026 report)
View data table
| Failure type | % of home pages |
|---|---|
| Low-contrast text | 83.9 |
| Missing image alt text | 53.1 |
| Missing form input labels | 51 |
| Empty links | 46.3 |
| Empty buttons | 30.6 |
| Missing document language | 13.5 |
Put the two forces together and the stakes are clear. Models make it easy to ship pages that look like everyone else’s and, unless someone checks, fail the same basic accessibility tests everyone else fails. Distinctiveness and accessibility are not competing goals here; both are casualties of accepting the default.
The evidence: why models produce slop
The mechanism: distributional convergence
Anthropic’s Applied AI team described the problem plainly in November 2025. “During sampling, models predict tokens based on statistical patterns in training data,” they wrote, and “safe design choices — those that work universally and offend no one — dominate web training data.” Without direction, the model gravitates to that centre; unguided prompts often yield “Inter fonts, purple gradients on white backgrounds, and minimal animations.” They call this distributional convergence (Anthropic).
Post-training compounds it. Research on reinforcement learning from human feedback (RLHF) found that it “significantly reduces output diversity compared to SFT across a variety of measures” (Kirk et al.). Preference tuning rewards answers that most raters find acceptable, and in design, “acceptable to most people” is close to a definition of generic. The model is not failing; it is doing exactly what it was optimised to do.
The median of what, exactly?
One detail in the data surprised me and sharpened the argument. If AI slop were simply the median of the web, its typeface would be Roboto or Open Sans, not Inter. HTTP Archive’s Web Almanac found Roboto on 15.2% of desktop sites in 2024 and Inter on about 1% (Web Almanac 2024); the 2025 edition puts Inter at roughly 1.4–1.5% of pages, rising quickly (Web Almanac 2025).
Exhibit 3
The web’s median typeface is Roboto, not Inter — slop mirrors a narrower slice of the web
Share of desktop websites using each font family, 2024 (%)
Font Awesome (10.4%) is an icon font and is omitted. Mobile shares differ; Roboto’s low mobile figure (2.7%) likely reflects locally installed copies on Android.
Source: HTTP Archive, Web Almanac 2024 — Fonts chapter (Figure 4.18)
View data table
| Family | Desktop (%) | Mobile (%) |
|---|---|---|
| Roboto | 15.2 | 2.7 |
| Noto Sans JP | 6.1 | 5.7 |
| Open Sans | 5.6 | 6.8 |
| Poppins | 4.7 | 5.8 |
| Montserrat | 3.3 | 3.9 |
| Lato | 3.2 | 3.8 |
| Inter | 1 | 1.1 |
My interpretation — and it is an interpretation, not a measured finding — is that model output reflects the slice of the web that models learn UI code from and are rewarded for: recent framework starters, component libraries, tutorials and showcase sites, where a handful of choices recur. That matters for the remedy. You are not fighting “the web”; you are fighting a specific, recognisable, recent house style. Which means you can name it, and what you can name, you can ban.
Why distinctiveness is worth the effort
People judge visual appeal fast. Gitte Lindgaard’s team at Carleton University found that impressions of web pages formed in the first 50 milliseconds “tallied well with judgements made after a longer period of scrutiny” (Nature News). And attractiveness carries over: the aesthetic-usability effect, first studied at Hitachi with 252 participants rating 26 ATM interface variations, describes “users’ tendency to perceive attractive products as more usable” (NN/g). A page that reads as a template in the first glance spends the rest of the visit earning back credibility.
The same NN/g article contains the caveat that keeps this honest: “A pretty design can make users forgiving of minor usability problems, but not of large ones.” Distinctiveness buys attention and goodwill; it does not buy a pass on legibility.
A framework: aim for the top-right, enforce with three layers
Two axes matter: how recognisably yours a design is, and whether people can actually read and use it.
Exhibit 4
Slop is usable but generic; the goal is distinctive and usable
Author’s framework
Getting to the top-right takes three layers, each fixing a different weakness of prompting alone:
- Constraints move the model off the median for a given task. They are specific, testable rules — tokens, type, bans, references, real content — rather than adjectives.
- Skills make those constraints persistent. A constraint you have to remember to paste is a constraint you will eventually forget.
- Verification loops catch what constraints miss. A model cannot see its output unless you give it a browser, and neither can you if you only read the diff.
The deep dives take each layer in turn.
Deep dive 1: the anatomy of slop
You cannot ban what you cannot name. These are the patterns I look for, grouped by dimension. None is wrong in isolation; together they read as “nobody decided”.
Exhibit 5
The tells of AI-generated design — and what to ask for instead
Author’s field list of default patterns
| The default | Why it reads as slop | What to ask for instead | |
|---|---|---|---|
| Type | Inter or a display serif with an italic accent word; a popular mono for code | The most frequent pairings in recent starters and showcases | A named family chosen for a reason (e.g. a width axis), one weight scale, no italic emphasis by default |
| Colour | Indigo-to-purple gradients, glass cards, glow everywhere | Signals a template before anyone reads a word | One accent with a defined role, neutral surfaces, emphasis reserved for one thing per view |
| Layout | Centred hero, three identical feature cards with icons | Symmetry with nothing to say | A grid driven by your content: your numbers, your diagrams, your proof |
| Imagery | Isometric people, abstract blobs, stock dashboards | Could belong to any company | Diagrams of your actual system and data |
| Copy | Generic promises about AI-powered workflows | Says nothing a competitor could not | A specific claim with a number and a source |
| Motion | Everything fades up on scroll | Content invisible until animated; tiring | Motion that explains; content visible without JavaScript |
Failure mode. Bans alone create new defaults. Anthropic’s own article noted that after steering Claude away from overused fonts, it still tended to converge on Space Grotesk — a font that had appeared in their own list of suggestions (Anthropic). Remove the centre of a distribution and the model finds the next most probable point. The fix is to pair every ban with a positive, reasoned choice that belongs to you.
How to measure. Keep the ban list in the repository and grep for it: font-family declarations, gradient syntax, backdrop blur, banned phrases in copy. A ban that is not checked is a suggestion.
Deep dive 2: constraint-first briefs
“Make it bold and modern” is an adjective. Adjectives get you the median, because the median is what most people mean by them. Constraints get you a point of view. Every UI brief I write contains five things:
- A palette with roles — surfaces, primary and muted text, one accent, one warning — as hex values, with the rule for when the accent may appear.
- A type system — named families, allowed weights and widths, and what each is for.
- A ban list — the defaults from Exhibit 5 that are not allowed, each paired with what to do instead.
- A structural reference — a real publication, product or print artefact whose structure you admire, not its surface.
- The real content — the actual headline, numbers, names and diagrams the design must carry. Designing around placeholder text produces placeholder design.
Design the hero for an AI engineer's portfolio.
Palette: ink #0a0d0c, raised #111715, text #ecefea, muted #8b958f,
accent #3df5a7 (one accent moment per viewport).
Type: Archivo variable. Headlines: font-stretch 72%, weight 800.
Body: 100% width, weight 400. IBM Plex Mono for labels and data only.
Banned: serif display + italic accent word -> use width and weight for emphasis
gradients and glass cards -> flat surfaces, hairline borders
centred hero + icon-card triplet -> asymmetric grid led by real numbers
stock or isometric illustration -> diagrams of real systems
Reference: the structure of a consulting exhibit: numbered, insight-led title,
source line, data table.
Content: [paste the real headline, metrics and sources]
Before writing code, list each design decision with a one-line reason.
Flag any decision whose only reason is "modern" or "clean".
The last two lines do more work than they appear to. Asking for a reason per decision forces the model to articulate a rationale before committing to tokens, and “because it is modern” becomes visibly inadequate. I have found this the single cheapest intervention against the median.
The second template is for critique. I run it against screenshots, not code, because the code can be perfect while the page is not:
You are reviewing screenshots of this page at 1440, 768 and 375 px.
1. List every element that matches the ban list in SKILL.md, with location.
2. Name the one thing a visitor sees first at each width. Is it the most
important thing? If not, what is competing with it?
3. List any text you would expect to fail WCAG AA contrast (4.5:1 body,
3:1 large) and the token responsible.
4. Identify anything that overflows, truncates or collides at 375 px.
Return findings only; do not fix anything yet.
Separating critique from fixing is deliberate. When the same turn finds and fixes, the model tends to find only what it already knows how to fix.
Failure mode. Over-specified briefs produce rigid, lifeless pages: every value fixed, no room for the model to make a good local decision. Constrain the system (tokens, type, bans), not every instance.
Deep dive 3: packaging taste as a Claude Code Skill
If you paste the same brief every session, it should be a Skill. The Claude Code documentation defines the format precisely: a skill is a folder containing a SKILL.md file with YAML frontmatter between --- markers, followed by Markdown instructions (Claude Code docs). Several details matter for design work:
- All frontmatter fields are optional;
descriptionis the one that is recommended, because “Claude uses it to decide when to apply the skill.”namedefaults to the directory name. The combineddescriptionandwhen_to_usetext is truncated at 1,536 characters in the skill listing, so put the key use case first. - Loading is progressive. In a session, only skill descriptions sit in context; “full skill content only loads when invoked.” As the docs put it, “a skill’s body loads only when it’s used, so long reference material costs almost nothing until you need it.” This is why a skill beats stuffing your house style into
CLAUDE.md, which is loaded every time. - Supporting files stay out of context until needed. The docs recommend keeping
SKILL.mdunder 500 lines and moving detailed reference into separate files that the skill points to; scripts in the folder are executed rather than loaded. - Location sets scope. Project skills live in
.claude/skills/<name>/SKILL.mdand travel with the repository; personal skills live in~/.claude/skills/; plugin skills are invoked as/plugin-name:skill-name. - Invocation is automatic or explicit. Claude loads a skill when a request matches its description, or you type
/skill-name. Settingdisable-model-invocation: truemakes a skill manual-only — useful for heavyweight audits you want to run deliberately.
Here is a house-style skill in that format:
---
name: house-style
description: Use for any UI, page, component, chart or styling work in this repo.
Applies the house design tokens, type system and anti-slop ban list, and
requires browser verification with contrast checks before work is called done.
---
# House style
## Tokens (source of truth: src/styles/tokens.css)
- Surfaces #0a0d0c / #111715 / #172019. Hairlines #1e2824.
- Text #ecefea (primary), #c4cbc6 (secondary), #8b958f (muted, never below 14px).
- Accent #3df5a7: one accent moment per viewport.
## Type
- Archivo variable. Headlines font-stretch 72%, weight 750-800. Body 100%, 400.
- IBM Plex Mono for labels, data and code only.
## Never -> instead
- Serif display + italic accent word -> emphasis through width and weight
- Gradients, glass cards, glow -> flat surfaces, hairline borders
- Icon-card triplets, centred hero -> grid led by real content
- Content hidden until animation runs -> visible by default, motion optional
## Before calling UI work done
1. Render and screenshot at 1440, 768 and 375 px.
2. Run the critique prompt in critique.md against the screenshots.
3. Check contrast for every text token used (AA: 4.5:1 body, 3:1 large).
4. Run a Lighthouse accessibility audit and fix every failed audit.
See exhibits.md for chart conventions.
Note what the skill does and does not contain. It holds decisions and checks, not essays about good design. It points to the token file as the source of truth, so the skill and the CSS cannot drift apart silently. And it keeps the long material — critique prompt, chart conventions — in supporting files that load only when needed.
Exhibit 6
Put taste where it will load at the right time: rules in a Skill, tools in MCP, distribution in a plugin
Where design knowledge can live in Claude Code — Author’s framework, based on the Claude Code documentation
| Loads when | Good for | Weakness | |
|---|---|---|---|
| One-off prompt | Only in that turn | Exploration, a single page | Forgotten next session |
| CLAUDE.md | Every session, in full | Short, always-true project rules | Long style guides cost context every turn |
| Skill | Description always; body when invoked | House style, critique checklists, chart rules | Only as good as its description’s trigger |
| MCP server | Tools available while connected | Seeing and measuring: browsers, audits | Third-party servers can expose prompt-injection risk |
| Plugin | Bundled components, every enabled session | Sharing a whole setup with a team | Each enabled plugin adds descriptions to every turn |
Failure mode. The most common skill failure is a vague description, so the skill never triggers. “Design guidelines” will not match “fix the spacing on the pricing card”; “Use for any UI, page, component, chart or styling work” will. Test the trigger by asking for a small UI change in a fresh session and checking whether the skill loads.
Deep dive 4: plugins and MCP servers — giving Claude eyes
Skills encode what you know. Plugins and MCP servers add what Claude cannot do on its own.
A plugin is “a directory of skills, agents, hooks, MCP servers, or other components that Claude Code installs and loads as one unit,” usually with a manifest at .claude-plugin/plugin.json; you browse and install them with /plugin (Claude Code docs). Anthropic packaged the approach from its own frontend-design article as exactly this kind of installable skill. Two cautions from the documentation are worth repeating. An enabled plugin is part of every session, so the names and descriptions of its skills and agents sit in context on every turn. And “what the plugin runs, it runs as you” — review third-party plugins before installing them.
An MCP server connects Claude Code to external tools through the Model Context Protocol, “an open source standard for AI-tool integrations” (Claude Code docs). For design work, the essential servers are browsers. Microsoft’s Playwright MCP server provides browser automation and, notably, works primarily from Playwright’s accessibility tree rather than pixels; its README describes browser_snapshot as “better than screenshot” for acting on a page, while browser_take_screenshot captures what the page looks like and browser_resize sets the viewport (Playwright MCP). The Chrome DevTools MCP server adds a lighthouse_audit tool covering accessibility, SEO and best practices (performance is traced separately) (tool reference).
# A browser Claude can drive, resize and screenshot
claude mcp add playwright npx @playwright/mcp@latest
# Chrome DevTools: Lighthouse audits, traces, emulation
claude mcp add chrome-devtools -- npx -y chrome-devtools-mcp@latest
# Share a server with your team: project scope writes .mcp.json at the repo root
claude mcp add --scope project playwright npx @playwright/mcp@latest
The accessibility-tree design has a side benefit I did not expect. If the snapshot Claude reads is a meaningless list of unlabelled divs, that is roughly what a screen-reader user experiences too. The tool that lets the model see the page doubles as a structural accessibility check.
Failure mode. Browser servers fetch and read external content, and the Claude Code docs warn that “servers that fetch external content can expose you to prompt injection risk.” Point design-verification browsers at your local dev server, and be deliberate before letting them roam the open web in the same session that has write access to your code.
Deep dive 5: render, critique, measure
Most slop survives because nobody — human or model — looked at the rendered page at three widths and measured it. The loop below is how this site was built.
Exhibit 7
Never accept UI you have not rendered, critiqued and measured
The anti-slop loop with Claude Code — Author’s framework
- 01BriefPalette, type, bans with replacements, a structural reference, real content.
- 02GenerateClaude states a reason for each decision, then writes the code.
- 03RenderScreenshots at 1440, 768 and 375 px through a browser MCP server.
- 04CritiqueBan list and critique prompt against the screenshots — findings only.
- 05MeasureContrast ratios, Lighthouse, overflow checks: numbers, not impressions.
- 06RefineFix the findings, then loop until the measurements pass.
Measurement catches what eyes miss. On this site, a Lighthouse accessibility audit flagged code comments inside highlighted code lines. Against the lighter highlighted-line background, the comment colour #5d6a64 reached only 3.12:1 — below the 4.5:1 minimum for body text. Changing it to #7d8a84 raised the ratio to 4.90:1. One hex value; without the audit it would have shipped.
Exhibit 8
One audit, one hex change: code comments went from failing to passing WCAG AA
Contrast ratio of code-comment text on a highlighted code line (AA minimum for body text is 4.5:1)
View data table
| Version | Colour | Contrast |
|---|---|---|
| Before | #5d6a64 | 3.12:1 |
| After | #7d8a84 | 4.90:1 |
The arithmetic is simple enough to put in the loop itself. WCAG defines relative luminance for sRGB as L = 0.2126 R + 0.7152 G + 0.0722 B on linearised channels, and contrast as (L1 + 0.05) / (L2 + 0.05), lighter over darker (W3C). A script Claude can run against your tokens:
// WCAG 2.x contrast ratio between two hex colours
const lin = (c) => (c <= 0.04045 ? c / 12.92 : ((c + 0.055) / 1.055) ** 2.4);
const lum = (hex) => {
const [r, g, b] = [1, 3, 5].map((i) => lin(parseInt(hex.slice(i, i + 2), 16) / 255));
return 0.2126 * r + 0.7152 * g + 0.0722 * b;
};
const contrast = (a, b) => {
const [hi, lo] = [lum(a), lum(b)].sort((x, y) => y - x);
return (hi + 0.05) / (lo + 0.05);
};
console.log(contrast('#8b958f', '#0a0d0c').toFixed(2)); // 6.31
Run across the site’s text tokens against the page background, it shows every text colour clearing AA, with the muted grey — the token most likely to fail in a dark theme — at 6.31:1.
Exhibit 9
Every text colour on this site clears WCAG AA, including the muted grey
Contrast ratio against the page background #0a0d0c (AA: 4.5:1 for body text)
Source: Computed with the WCAG relative-luminance formula from this site’s design tokens
View data table
| Token | Hex | Contrast |
|---|---|---|
| Primary text | #ecefea | 16.83:1 |
| Accent | #3df5a7 | 13.77:1 |
| Secondary text | #c4cbc6 | 11.81:1 |
| Muted text | #8b958f | 6.31:1 |
Know what Lighthouse measures. The Lighthouse accessibility score is a weighted average of pass/fail audits based on axe-core; “a page doesn’t get points for partially passing an accessibility audit,” and the colour-contrast audit carries a weight of 7 on a scale whose weights are 3, 7 and 10. Manual checks — focus order, landmarks — “don’t affect your score” (Chrome for Developers). A score of 100 means the automated audits passed, not that the page is accessible. Keep a short manual checklist alongside it: keyboard through every interactive element, check focus visibility, zoom to 200%.
Failure mode. The loop can become theatre: screenshots taken, nobody reads them. Make the critique output a list of findings with locations, and do not move on until each is fixed or explicitly waived.
Deep dive 6: accessibility as a design constraint
I treat accessibility as a design input, not a compliance step at the end, for a practical reason: it is the constraint that keeps distinctiveness honest. Most attempts to look different push towards the bottom-right of Exhibit 4 — thin weights, low-contrast “sophisticated” greys, text over imagery. A hard contrast floor rules those moves out early and forces the distinctiveness to come from structure, type and content instead.
The 4.5:1 threshold is not arbitrary. W3C explains that visual acuity of 20/40 is associated with a contrast-sensitivity loss of roughly 1.5, and the baseline 3:1 multiplied by 1.5 gives 4.5:1; large text — at least 18 point, or 14 point bold — gets the lower 3:1 threshold (W3C). That is a design rule with a reason, which is exactly what a good constraint looks like.
The variable-font trend makes this easier than it was. About a third of websites used variable fonts in 2024; the 2025 Web Almanac puts it at 39.4% of desktop and 41.3% of mobile sites (Web Almanac 2025). A width or weight axis gives you a large range of expressive emphasis — condensed headlines, heavy numerals — without resorting to the low-contrast or decorative tricks that fail audits.
Exhibit 10
Variable fonts are now mainstream: two in five sites use one
Share of websites using at least one variable font (%)
Source: HTTP Archive, Web Almanac 2024 and 2025 — Fonts chapters
View data table
| Year · client | Share (%) |
|---|---|
| 2024 desktop | 33 |
| 2024 mobile | 34 |
| 2025 desktop | 39.4 |
| 2025 mobile | 41.3 |
Case examples
Anthropic’s frontend-design skill (November 2025). Anthropic’s Applied AI team diagnosed distributional convergence and responded not with a better one-off prompt but with a compact, roughly 400-token prompt covering typography, colour, motion and backgrounds, packaged as a skill that loads on demand (Anthropic). Their typography guidance named families to avoid (Inter, Roboto, Open Sans, Lato, default system fonts) and families to consider, including the IBM Plex family. They also reported the failure mode — convergence on Space Grotesk — candidly. Lesson: the vendor’s own answer to slop is the thesis of this article: constraints, packaged as a skill. And bans alone create new defaults.
The GOV.UK Design System. The UK government’s design system exists to “make government services consistent with GOV.UK,” providing reusable, accessible components so teams can “learn from the research and experience of other service teams” (GOV.UK). It is deliberately plain. Lesson: this is taste encoded as constraints at national scale, and its goal is recognisability and usability, not novelty. Distinctiveness in this article’s sense means “recognisably yours” — and for GOV.UK, being recognisably GOV.UK is the point.
This portfolio’s redesign. The facts are simple. An early draft used Fraunces as a display serif with an italic accent for emphasis. I judged the fonts to be “giving AI slop”, and the type system was replaced with Archivo — loaded as a variable font with its width axis, set condensed for display (font-stretch between 72% and 84%) and at normal width for body text — and IBM Plex Mono for labels, data and code. The tokens in Exhibit 9 were checked against WCAG, and a Lighthouse audit caught the code-comment contrast failure in Exhibit 8.
Exhibit 11
The redesign replaced a fashionable pairing with one variable family and one mono, each with a reason
This site’s type decisions — Author’s summary from the site’s source
| Decision | Reason | |
|---|---|---|
| Removed | Fraunces display serif with an italic accent word, Geist for body, JetBrains Mono for labels | Read as a common AI-template look and the default developer-portfolio pairing |
| Display | Archivo variable, condensed via the width axis (font-stretch 72–84%) | Emphasis from width and weight, not a serif-italic contrast |
| Body | Archivo at normal width, weight 400 | One family, one scale; display and body stay related |
| Data and labels | IBM Plex Mono (400, 500, 600) | Separates numbers, sources and code from prose |
| Loading | Self-hosted via Fontsource packages | No third-party font requests |
| Verification | Contrast maths on every text token; Lighthouse audit | Caught the code-comment failure in Exhibit 8 |
Source: This site’s stylesheets (tokens.css, blog.css) and font packages
Counterpoints
Implications by stakeholder
Founders and product leads. Your site is often the first evidence a prospect sees. A model can produce a credible page in minutes, which means a credible page is no longer a signal. Invest a few hours, once, in deciding what your visual identity is and writing it down as constraints; that document is now an asset your team and your tools can both use.
Designers. The role shifts from producing every screen to authoring the system that produces screens — tokens, rules, bans with reasons, critique checklists — and to judging output at speed. Designers who can write a good skill will multiply their influence across every engineer and every model session in the organisation.
Engineers. Treat design rules like lint rules. Keep tokens in one file, point the skill at it, add browser MCP servers to the project scope, and make “rendered at three widths and measured” part of the definition of done. A grep for banned patterns in CI is cheap and catches regressions a reviewer will miss.
What to do next
Week 1 — name your median. Generate three pages with an unguided prompt. List every recurring pattern across them. That list, with a reasoned replacement for each item, is your ban list.
Week 2 — write the constraints. Define tokens with roles, a type system with a reason for each family, a structural reference and real content. Check every text token for contrast before writing any components.
Week 3 — package it. Write .claude/skills/house-style/SKILL.md with a trigger-rich description, the decisions and the done-checklist; move the critique prompt and chart rules into supporting files. Test that it loads in a fresh session.
Week 4 — close the loop. Add Playwright and Chrome DevTools MCP servers at project scope. Make screenshots at 1440, 768 and 375 px, the critique pass, contrast checks and a Lighthouse accessibility audit mandatory before UI work is called finished.
Ongoing — maintain it. Every time a review finds a new tell or a model starts converging on a new default, add it to the skill. Re-run the unguided prompt every few months: when a new model version ships, its median moves, and so should your ban list.
Limitations and methodology
Several limits apply. The mechanism of distributional convergence is described by Anthropic’s engineers and supported by research on RLHF and output diversity, but there is no published, systematic measurement of how often AI-generated sites use specific fonts or colours; my slop tells are a practitioner’s field list, not a census. My explanation of why model output differs from the web’s typographic median is an interpretation.
WebAIM’s figures come from automated testing, which catches only a subset of accessibility problems; WebAIM associates technologies with error counts but notes that correlation is not causation, and it does not measure AI-generated pages directly. Web Almanac font shares depend on detection method and differ between desktop and mobile. The first-impressions research dates from 2006 and measured visual appeal, not conversion. The contrast values for this site are exact calculations from its tokens; the redesign narrative beyond the facts stated is flagged for confirmation. Lighthouse scores, finally, measure automated audits, not the experience of a disabled user — nothing here substitutes for testing with people.
Closing
Models are excellent averagers. Asked for a page with no direction, they will reliably produce the centre of what they have learned — competent, inoffensive and indistinguishable. That is not a bug to be prompted away one request at a time. It is a property of how the systems work, and the answer is structural: decide what your taste is, encode it as constraints with reasons, package those constraints so they load every time, and verify each render with screenshots and numbers. Do that and the model stops being the source of the median and becomes the fastest way to apply a point of view.
In short
- AI tools default to the “average” look of the web. Asking for something “bold and modern” just gets you the average again; specific rules (these colours, this font, never that) get you something that looks like yours.
- Write those rules down once, as a Claude Code Skill, so the AI loads them automatically instead of you pasting them in every time and eventually forgetting.
- Never accept a page you have not looked at and measured. On this site one automated check found hard-to-read text, and a single colour change fixed it.
Ask a hundred people to describe “a nice website” and blend their answers together. You will get something perfectly pleasant that nobody would remember: clean font, purple gradient, three neat boxes with icons. That blend is roughly what an AI model gives you when you ask it to design a page with no direction. Partway through rebuilding this site with Claude Code, I looked at a draft and said it out loud: the fonts are giving AI slop.
This piece explains why that happens and what to do about it. The short version of the argument: AI-generated design drifts towards the average of the web, and the way to get something distinctive is to write your taste down as rules, have the AI load those rules automatically, and check every result with real measurements — not just to write a cleverer request.
Why AI design all looks the same
An AI model writes a web page the way it writes a sentence: by predicting the most likely next piece, based on patterns in what it learned from. Anthropic’s own engineers described this in November 2025. Safe design choices, the ones that “offend no one”, dominate the pages the models learned from, so without direction the model drifts to that safe middle. Their words for the typical result were “Inter fonts, purple gradients on white backgrounds, and minimal animations.” They call the effect distributional convergence: the output converges on the centre of what the model has seen.
A second step in training makes it stronger. After the basic learning, models are tuned on human feedback, rewarded for answers most people rate as acceptable. Research has found that this tuning noticeably reduces the variety of what the model produces. In design, “acceptable to most people” is close to the definition of generic. The model is not broken. It is doing exactly what it was trained to do.
One detail sharpens the picture. If AI design were simply the average of the whole web, its favourite font would be Roboto, which appears on about 15% of desktop sites. Instead it is Inter, which appears on only about 1%. My reading (an interpretation, not a measurement) is that models copy a narrower slice: recent starter templates, tutorials and showcase sites, where a handful of choices keep repeating. That is good news. A specific, recognisable house style can be named, and anything you can name, you can ban.
Why bother? People judge how a web page looks in about the first 50 milliseconds, and those snap judgements tend to match what they think after a longer look. People also tend to see attractive products as easier to use. A page that reads as a template at first glance spends the rest of the visit earning back trust.
There is a second cost to accepting the default. Every year, a group called WebAIM scans the home pages of the top one million websites for accessibility problems: things that make a page hard or impossible to use for people with poor eyesight or who use assistive tools. Hard-to-read, low-contrast text is the most common problem by a wide margin.
Exhibit 1
Hard-to-read text is the web’s most common accessibility failure
Share of the top 1,000,000 home pages with each detected problem, February 2026 (%)
Automated checks only, so the true rates are likely higher. Low-contrast text rose from 79.1% of pages in 2025 to 83.9% in 2026.
Source: WebAIM, The WebAIM Million (2026 report)
View data table
| Problem | % of home pages |
|---|---|
| Low-contrast text | 83.9 |
| Missing image descriptions | 53.1 |
| Empty buttons | 30.6 |
So the default fails twice: it looks like everyone else, and, unless somebody checks, it fails the same basic readability tests everyone else fails.
Jargon decoder
| In plain words | |
|---|---|
| AI slop | Design (or writing) that looks generic and machine-made because nobody made any real decisions |
| Distributional convergence | The model drifting towards the most common, middle-of-the-road answer |
| Constraint | A specific, checkable rule: “use this exact colour”, rather than “make it bold” |
| Claude Code | Anthropic’s AI assistant that writes and edits code inside a software project |
| Skill | A saved instruction file the assistant loads automatically when a task needs it |
| MCP server | A plug-in connection that gives the assistant a new tool, such as a web browser it can drive |
| Contrast ratio | How much text stands out from its background; 4.5:1 is the usual minimum for normal text (the WCAG AA standard) |
| Lighthouse | An automated checker that scores a page on things like accessibility |
Fix 1: rules beat adjectives
“Make it bold and modern” is an adjective, and adjectives get you the average, because the average is what most people mean by them. A useful design brief instead contains five concrete things:
- A palette with jobs. Exact colours, and a rule for when the one accent colour is allowed to appear.
- A type system. Named fonts, and what each is for.
- A ban list. The tell-tale defaults you will not accept, each paired with what to do instead.
- A structural reference. A real publication or product whose structure you admire, not just its look.
- The real content. Your actual headline, numbers and diagrams. Designing around placeholder text produces placeholder design.
One cheap trick does a lot of work: ask the AI to give a one-line reason for every design decision before it writes any code, and to flag any decision whose only reason is “modern” or “clean”. Forced to explain itself, the model can no longer hide behind the average.
There is a catch. A ban list on its own creates a new default. When Anthropic steered Claude away from the overused fonts, it simply settled on the next most likely one, Space Grotesk. Take away the middle of the crowd and the model finds the next most popular spot. So every ban needs a positive choice, with a reason, that belongs to you.
The goal looks like this:
Exhibit 2
Slop works but looks like everything else; the goal is distinctive and usable
Author’s framework
Fix 2: write your taste down once, as a Skill
A rule you have to remember to paste in is a rule you will eventually forget. Claude Code solves this with Skills: a folder holding a short instruction file. The clever part is how it loads. In each session, the assistant only keeps a one-line description of each skill in mind; the full instructions load only when a task matches. So a detailed house style costs almost nothing until you need it.
A good design skill holds decisions and checks, not essays: the colour values, the fonts, the “never this, do that instead” list, and a checklist that must pass before any design work counts as finished. The most common mistake is a vague description. “Design guidelines” will not match a request like “fix the spacing on the pricing card”; “use for any page, component, chart or styling work” will.
Skills hold what you know. MCP servers add what the assistant cannot do on its own, most importantly see. A browser connection lets it open the page, resize it to phone and desktop widths, take screenshots and run accessibility audits. One caution from the documentation: tools that read content from the open web can be tricked by hidden instructions on those pages, so point them at your own work.
Fix 3: look, then measure
Most slop survives because nobody, human or AI, looked at the finished page at different screen sizes and measured it. The loop that built this site goes: write the brief, generate, take screenshots at desktop, tablet and phone widths, critique them against the ban list, measure, fix, and repeat until the numbers pass. Finding problems and fixing them happen in separate steps on purpose. When the same pass does both, the AI tends to find only what it already knows how to fix.
Measurement catches what eyes miss. On this site, a Lighthouse audit flagged the grey comments inside highlighted code examples. Their contrast was 3.12:1, below the 4.5:1 minimum. Changing one colour value raised it to 4.90:1. Without the audit it would have shipped.
Exhibit 3
One check, one colour change: the code comments went from failing to passing
Contrast of code-comment text on a highlighted line (the minimum for normal text is 4.5:1)
Source: Computed with the WCAG contrast formula; problem flagged by a Lighthouse audit of this site
View data table
| Version | Colour | Contrast |
|---|---|---|
| Before | #5d6a64 | 3.12:1 |
| After | #7d8a84 | 4.90:1 |
Two honest caveats. A perfect Lighthouse score means the automated checks passed, not that the page works for every disabled visitor; you still test with a keyboard and zoom in. And readability rules help distinctiveness rather than fight it: they rule out the cheap “sophisticated” tricks such as thin pale-grey text, and force the personality to come from structure, type and content.
What this looked like on this site
Could design systems or good taste alone do this without the machinery? A design system is the best rulebook you can have, and a skill should point to it. But a component library will not stop an AI from arranging approved parts into a generic layout or skipping the screenshot. And no, rules do not create taste. A person with taste has to write them, and has to keep updating them as new tells appear.
If you remember one thing
AI models are excellent averagers. Ask for a page with no direction and you will reliably get the middle of everything they have seen: competent, inoffensive and forgettable. You will not fix that one request at a time. Decide what your taste is, write it down as rules with reasons, have the AI load those rules every time, and check every page with screenshots and numbers. Then the AI stops being the source of the average and becomes the fastest way to apply your point of view.
Sources
- Anthropic — Improving frontend design through Skills (12 Nov 2025)
- Claude Code docs — Extend Claude with skills
- Claude Code docs — Plugins overview
- Claude Code docs — Connect Claude Code to tools via MCP
- Microsoft — Playwright MCP server
- Chrome DevTools MCP — repository and tool reference
- Chrome for Developers — Lighthouse accessibility scoring
- W3C — Understanding WCAG 2.2 Success Criterion 1.4.3: Contrast (Minimum)
- WebAIM — The WebAIM Million (2026 report)
- HTTP Archive — Web Almanac 2024, Fonts chapter
- HTTP Archive — Web Almanac 2025, Fonts chapter
- Kirk et al. — Understanding the Effects of RLHF on LLM Generalisation and Diversity (arXiv:2310.06452)
- Nielsen Norman Group — The Aesthetic-Usability Effect
- Nature News — First impressions count for web (Lindgaard et al., 2006)
- GOV.UK Design System