The fastest way to stop AI-generated UI from looking generic is to put your design system where the agent always reads it: design tokens defined once in code, a Tailwind v4 @theme block that deletes the default palette, and a short "Design rules" section in CLAUDE.md or AGENTS.md that names your colour roles, type scale, spacing, radius, banned defaults and existing components. Then make a linter fail the build when the agent ignores them. Prompts fix one screen; repo-level rules fix every screen after it. This guide gives you a copy-ready @theme block, a full CLAUDE.md design section, the equivalent files for Cursor and GitHub Copilot, and an ESLint config that turns off-brand Tailwind classes into errors.
Why does Claude keep producing the same purple, Inter-font UI?
Anthropic has named the problem itself. In its November 2025 post on improving frontend design through Skills, it explains that models sample from statistical patterns in their training data, so without direction they converge on generic, on-distribution output, which users call the AI slop aesthetic. The post lists the usual suspects: overused fonts such as Inter, Roboto, Arial and system fonts, and cliched colour schemes, particularly purple gradients on white. The model is not choosing purple because it likes purple; nothing in the conversation or the repository made a different choice more likely. A one-off prompt such as "make it look premium" shifts the odds for one response. A design system committed to the repo, loaded into every session and enforced by tooling, shifts them permanently. Our pillar post, Why AI websites look the same and how to make Claude design better, covers the diagnosis; this one is the fix at the source.
- •Defaults win when the context is empty: no palette, no type scale, no component inventory means the agent invents them.
- •Instructions given only in chat do not carry over; Anthropic's memory docs say to put them in CLAUDE.md so they persist and survive compaction.
- •Tailwind ships a large default palette, so bg-indigo-500 or bg-violet-600 always compiles unless you remove it.
- •Anthropic's own advice is blunt: telling Claude to avoid Inter and Roboto improves results immediately, which is exactly what a rules file does on every request.
What are design tokens, and is the W3C format stable yet?
Design tokens are named design decisions, such as colour.brand.primary or radius.card, stored as data instead of being scattered through stylesheets as raw hex codes and pixel values. The Design Tokens Community Group, a W3C community group, published the first stable version of its specification, version 2025.10, on 28 October 2025. It is a Final Community Group Report rather than an official W3C Recommendation, but it is the vendor-neutral format the major tools are converging on. Files are JSON with the recommended extension .tokens or .tokens.json and the media type application/design-tokens+json. Every token has a $value, an optional $type that can be inherited from its group, and references to other tokens use curly-brace syntax such as {color.saffron.500}. Supported types include color, dimension, fontFamily, fontWeight, duration, cubicBezier and number, plus composites such as shadow, border, typography, transition and gradient. The W3C announcement adds full support for Display P3, OKLCH and the other CSS Color Module 4 spaces, and names Style Dictionary, Tokens Studio and Terrazzo as reference implementations, so one token file can generate the CSS variables your Tailwind theme consumes.
How do Tailwind v4 @theme tokens make off-brand classes impossible?
Tailwind CSS v4 moved configuration from tailwind.config.js into CSS. Variables declared inside an @theme block are not plain CSS variables: the Tailwind docs explain that they instruct Tailwind to create utility classes, so --color-saffron-500 produces bg-saffron-500, text-saffron-500 and the rest. The namespaces map directly to a design system: --color-*, --font-*, --text-*, --font-weight-*, --tracking-*, --leading-*, --spacing, --radius-*, --shadow-* and --breakpoint-*. The decisive line for AI work is the namespace reset. Writing --color-*: initial removes every default colour utility, so after it bg-indigo-500 simply does not exist in your project and only your brand colours remain. Do the same for fonts, radii and shadows and the agent's favourite defaults have nothing to compile against. Use @theme for tokens that should become utilities, :root for variables that should not, and @theme inline when a theme variable points at another variable. Paste the block below into app/globals.css and rename.
Where does shadcn/ui theming fit with your tokens?
If your stack uses shadcn/ui, as many AI-built sites do, you already have a semantic token layer. shadcn/ui themes through CSS variables with a surface and foreground convention: the base token controls the surface colour and the -foreground token controls the text and icons on it, so bg-primary pairs with text-primary-foreground. The default theme ships tokens for background, foreground, card, popover, primary, secondary, muted, accent, destructive, border, input and ring, plus sidebar variants and chart-1 to chart-5, written in OKLCH and overridden inside a .dark selector. That is why so many shadcn sites look alike: nobody changes the neutral defaults. The fix is to point those semantic variables at your brand ramps, as the :root and .dark blocks above do, and tell the agent in CLAUDE.md to style components with the role names, never the ramps.
- •Keep two layers: brand ramps (saffron-500, ink-950) in @theme, semantic roles (primary, muted, border) in :root and .dark.
- •Components use roles only: bg-primary text-primary-foreground, never bg-saffron-500 inside a Button.
- •Leave cssVariables set to true in components.json, which shadcn/ui documents as the default, so new components inherit your roles.
- •Change the chart-1 to chart-5 tokens too, or every dashboard the agent builds will use the stock chart palette.
- •When you add a role, add it to :root, .dark and @theme inline in the same commit, then list it in CLAUDE.md.
What should a CLAUDE.md design rules section contain?
Claude Code loads CLAUDE.md at the start of every session, and the project file at ./CLAUDE.md or ./.claude/CLAUDE.md is shared with your team through version control. Anthropic's guidance is to write instructions that are concrete enough to verify, keep each file under about 200 lines because longer files reduce adherence, and group rules under headers and bullets. For design, that means naming roles and exact class names rather than adjectives. "Use a modern, clean look" gives the model nothing; "one accent, primary, used for the main CTA only" gives it a rule it can check against. Add to it whenever the agent makes the same visual mistake twice, the trigger Anthropic suggests for any CLAUDE.md entry.
The eight blocks of a design rules section
A complete CLAUDE.md design section you can copy
Here is the section we would start a new marketing site with, sized to stay well inside the 200-line guidance alongside build commands and other conventions. It refers to the tokens by the class names Tailwind generates from the @theme block above, so the agent and the linter speak the same language. Keep the banned list specific: "no bg-gradient-* on heroes" is checkable, "avoid cliches" is not. If the file grows past what is useful in every session, Claude Code lets you move part of it into .claude/rules/ with a paths frontmatter field, for example a rule that only loads when the agent reads files under components/, so frontend rules cost nothing during backend work.
CLAUDE.md, AGENTS.md, Cursor rules or copilot-instructions.md: which file does each tool read?
Most teams use more than one agent, so the design rules have to reach all of them. AGENTS.md is the cross-tool convention: the agents.md site describes it as a README for agents, says it is now stewarded by the Agentic AI Foundation under the Linux Foundation, reports use in over 60,000 open-source projects, and lists tools including OpenAI Codex, Google Jules, GitHub Copilot, VS Code, Cursor, Zed, Devin, Gemini CLI, Warp and Windsurf. Claude Code can now read AGENTS.md directly from v2.1.277, but by default only when the repository has no CLAUDE.md; if you have both, add an @AGENTS.md import to the top of CLAUDE.md so Claude reads the shared rules and then its own extras. Cursor and GitHub Copilot read AGENTS.md alongside their own formats, summarised below.
| Tool | Primary file | Scoping to UI files | Reads AGENTS.md? |
|---|---|---|---|
| Claude Code | CLAUDE.md or .claude/CLAUDE.md | .claude/rules/*.md with paths frontmatter | Yes from v2.1.277, by default only when no CLAUDE.md exists; otherwise import it with @AGENTS.md |
| Cursor | .cursor/rules/*.mdc | globs frontmatter, or alwaysApply: true for global rules | Yes, including nested AGENTS.md files |
| GitHub Copilot | .github/copilot-instructions.md | .github/instructions/*.instructions.md with applyTo | Yes, nearest AGENTS.md in the tree wins |
| Codex, Jules, Gemini CLI and others | AGENTS.md | Nested AGENTS.md per directory | It is their native file |
How do you keep one design source of truth across every agent?
Murphy Trueman's May 2026 essay on design systems fragmenting into agent files makes the governance point well: AGENTS.md, SKILL.md and DESIGN.md do different jobs, and the risk is not the files themselves but nobody owning the seams between them. Brent Haskins argues in a May 2026 post that AI coding agents need structured, unambiguous data rather than a Storybook to browse, and that the high-impact 20 percent, colours, spacing, typography and core component variants, covers most of what agents generate. Our working order is below.
Tokens first
Keep raw values in one place: a DTCG .tokens.json file, or the @theme block itself if you do not need other platforms. No hex code lives anywhere else.
Rules file second
Write the design section once in AGENTS.md if you use several tools, or in CLAUDE.md if you only use Claude Code. Reference token names and class names, never raw values, so the rules cannot drift from the tokens.
Thin adapters
CLAUDE.md starts with @AGENTS.md. A single .cursor/rules/design.mdc with alwaysApply: true points to the same section. .github/copilot-instructions.md repeats only the banned list and the source-of-truth path.
Scope the heavy parts
Move long component documentation into a path-scoped rule or a skill so it loads only when the agent works on UI files. Anthropic notes that @imports organise a file but still load at launch, so they do not save context.
Audit regularly
Conflicting instructions make Claude pick one arbitrarily, per Anthropic's docs. Recent Claude Code versions include /doctor prompt-audit to flag outdated or contradictory instruction files; run it after design changes.
How do you enforce design tokens with ESLint, Stylelint and hooks?
CLAUDE.md is context, not enforcement: Anthropic's docs say plainly that Claude treats it as guidance and that hooks and settings are the deterministic layer. So back the rules with tools that fail. For Tailwind, eslint-plugin-better-tailwindcss supports v3 and v4 and includes no-unknown-classes, which reports classes not registered with your Tailwind config, and no-restricted-classes, which bans classes by regular expression with a custom message. Point its entryPoint setting at the CSS file holding your @theme block, and because you reset --color-*, any bg-indigo-500 the agent writes becomes an unknown class. Add patterns that ban arbitrary values like bg-[#7c3aed] and p-[13px]. For plain CSS and CSS modules, Stylelint's built-in color-no-hex rule disallows hex colours, with an ignoreFunctions option. Finally, close the loop inside Claude Code with a PostToolUse hook on Edit|Write that runs the linter on the changed file: per the hooks reference, a PostToolUse hook that exits with code 2 shows its stderr to Claude, so the agent sees the lint error and fixes it in the same turn.
What mistakes make design rules files fail?
Rules files tend to fail in a few predictable ways, each cheap to fix.
⚠️Writing adjectives instead of rules
Consequence: "Modern, clean, premium" carries no information, so the model falls back to its defaults, which is the purple gradient you were trying to avoid.
Solution: Name tokens, classes and counts: one accent, two radii, one shadow, text-4xl and text-6xl for headings.
⚠️Putting raw hex values in the rules file
Consequence: The rules and the stylesheet drift apart within weeks, and the agent copies whichever value it saw last.
Solution: Reference token names only and keep values in the @theme block or the .tokens.json file.
⚠️Leaving Tailwind's default palette in place
Consequence: bg-violet-600 still compiles, so a single lapse ships an off-brand component that looks fine to a reviewer skimming the diff.
Solution: Reset --color-*, --font-*, --radius-* and --shadow-* to initial in @theme and redefine only what you use.
⚠️A 600-line CLAUDE.md
Consequence: Anthropic's docs say longer files consume more context and reduce adherence, so the design section gets diluted by everything else.
Solution: Stay under about 200 lines and move component docs into path-scoped .claude/rules/ files or a skill.
⚠️Having both CLAUDE.md and AGENTS.md with different content
Consequence: By default Claude Code reads only CLAUDE.md when both exist, so the shared rules your Cursor and Copilot users rely on never reach Claude.
Solution: Make AGENTS.md the shared file and start CLAUDE.md with an @AGENTS.md import.
⚠️No enforcement
Consequence: Rules hold for the first few components and erode under deadline pressure, from people and agents alike.
Solution: Lint as errors in CI, plus a PostToolUse hook so Claude sees violations the moment it writes them.
Frequently asked questions
Quick answers to the questions developers and founders ask most when they set up design tokens and rules files for AI coding agents.
Frequently Asked Questions
Want AI-built pages that look like your brand, not like every other AI site?
Tech Arion builds websites with AI coding agents every day, and every repo we start gets a token file, a design rules section and lint that enforces it before the first page is generated. If your team is shipping with Claude Code, Cursor or Copilot and the output keeps drifting off-brand, we can set up the tokens, rules files and checks with you and hand them over.
Sources & References
Sources fetched on 1 October 2026:
- 1.
Design Tokens Community Group. (28 Oct 2025). Design Tokens Format Module 2025.10 - Final Community Group Report. $value, $type, .tokens.json, application/design-tokens+json, curly-brace aliases, token types.
View Source - 2.
W3C Design Tokens Community Group. (28 Oct 2025). Design Tokens specification reaches first stable version. Display P3 and OKLCH colour support, reference implementations, contributing organisations.
View Source - 3.
Tailwind Labs. Theme variables - Tailwind CSS documentation. @theme, namespaces, namespace reset with initial, @theme inline.
View Source - 4.
shadcn. Theming - shadcn/ui documentation. Surface and foreground convention, token list, OKLCH defaults, cssVariables option.
View Source - 5.
Anthropic. How Claude remembers your project - Claude Code documentation. CLAUDE.md locations, 200-line guidance, .claude/rules paths, AGENTS.md support from v2.1.277, /doctor prompt-audit.
View Source - 6.
Anthropic. Hooks reference - Claude Code documentation. PostToolUse hooks with an Edit|Write matcher; exit code 2 from PostToolUse shows stderr to Claude.
View Source - 7.
Anthropic. (12 Nov 2025). Improving frontend design through Skills. Distributional convergence, the AI slop aesthetic, Inter and purple gradients.
View Source - 8.
AGENTS.md. A simple, open format for guiding coding agents. Stewarded by the Agentic AI Foundation; 60k+ projects; supported tools; nearest file wins.
View Source - 9.
Cursor. Rules - Cursor documentation. .cursor/rules .mdc files with description, globs and alwaysApply; AGENTS.md support.
View Source - 10.
GitHub. Adding repository custom instructions for GitHub Copilot. copilot-instructions.md, .instructions.md with applyTo, AGENTS.md.
View Source - 11.
Schoero. eslint-plugin-better-tailwindcss. no-unknown-classes, no-restricted-classes, entryPoint setting, Tailwind v3 and v4 support.
View Source - 12.
Stylelint. color-no-hex rule. Disallows hex colours, with ignoreFunctions option.
View Source - 13.
Trueman, M. (15 May 2026). Your design system is fragmenting into agent files.
View Source - 14.
Haskins, B. (25 May 2026). Your design system needs to be machine-readable first.
View Source