Tailwind

DESIGN.md for Tailwind CSS

Use DESIGN.md to stop Tailwind-generated UI from collapsing into generic utility soup.

Dima BravenDima Braven8 min read

See it in practice

Related DESIGN.md references

Browse all →

Why Tailwind alone produces inconsistent AI output

The tailwindcss.com homepage with an annotated hero showing utility class names next to the rendered text
tailwindcss.com — every valid utility is one keystroke away, which is exactly the problem.

Tailwind's utility-first approach makes it fast to implement any visual style — which means an AI agent can generate visually inconsistent code just as quickly as consistent code. Without DESIGN.md, the agent picks from the full Tailwind utility set based on training distribution, not product decisions. You get p-4 in one card and p-5 in another, text-gray-700 on one label and text-slate-600 on another, rounded-md in one button and rounded-lg in the next. The inconsistency is not random — it reflects the most common Tailwind patterns seen in training data, which average out to no specific product's design choices. The problem compounds across sessions: each new component is internally consistent but inconsistent with components built in previous sessions, because the agent has no stable reference for which Tailwind classes your product prefers. By the time ten screens have been implemented, the codebase contains three or four competing interpretations of the same visual intent. Refactoring them into a consistent system requires more effort than writing a DESIGN.md would have taken at the start of the project.

Translating your Tailwind config into DESIGN.md

The tailwind.config.ts extend section is the closest thing Tailwind has to a token system. Custom colors, custom spacing steps, custom font families, and custom border radius values defined there represent the brand vocabulary. DESIGN.md takes that vocabulary and adds semantic meaning. If the Tailwind config has not been extended yet, DESIGN.md can specify stock Tailwind preferences directly. These rules are trivial to state but eliminate a major source of visual drift in AI-generated code.

DESIGN.md
## Color usage
 
- bg-brand-500 for primary action backgrounds.
- text-brand-600 for interactive links.
- border-brand-400 for focus rings.
- Never use bg-brand-300 or lighter for interactive elements —
the contrast is insufficient.
 
## Spacing scale
 
- Steps in use: 3 (12px), 4 (16px), 6 (24px), 8 (32px), 12 (48px).
- Do not introduce intermediate values like p-5 or gap-7 —
they break the visual rhythm.
 
## Neutrals (no extended config yet)
 
- All borders: border-slate-200.
- Hover backgrounds: hover:bg-slate-50.
- Pick one neutral family (slate) — never mix gray-* and slate-*.

The class preference problem

Tailwind offers too many valid ways to express the same visual intent, and AI agents pick among them inconsistently. Text at 14px can be text-sm. Hover states can be hover:bg-gray-100, hover:bg-gray-50, or hover:opacity-90. Dividers can be border-gray-200, border-neutral-200, or border-slate-200 — visually similar in most color profiles but semantically inconsistent and harder to update globally. Without DESIGN.md specifying the canonical choice, an agent makes independent decisions each time, accumulating drift that becomes expensive to normalize later. DESIGN.md's role in a Tailwind project is to canonicalize these choices with explicit class names, not just semantic intent. Specifying the exact class names is what makes the rule actionable. An agent implementing "use a subtle hover state" is making a judgment call that will differ across sessions; an agent implementing "hover:bg-muted" is matching an exact string.

  • Interactive hover backgrounds use hover:bg-muted. Never use hover:opacity for background changes.
  • Borders use border-border throughout. Dividers use divide-y divide-border.
  • Focus rings use focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2.

Page-level layout rules for Tailwind projects

Layout is where Tailwind inconsistency is most visible and hardest to repair after the fact. When different pages use different max-width containers, different section spacing, different sidebar widths, and different responsive breakpoint logic, the product feels structurally incoherent even when individual components look correct in isolation. For a B2B tool never used on mobile, documenting that sub-md breakpoints are not used saves agents from adding mobile styles that will never apply. For a mobile-first consumer product, documenting the baseline mobile layout before tablet and desktop variants ensures agents start from the right default. Layout rules are the most commonly skipped section in a first DESIGN.md draft and the most valuable once they exist.

DESIGN.md
## Layout
 
- Main content container: max-w-6xl mx-auto px-4 sm:px-6 lg:px-8
- Vertical rhythm: space-y-8 between top-level sections,
space-y-4 between grouped cards.
- Sidebar: w-64 fixed at desktop, hidden on mobile with a slide-in drawer.
- This product is desktop-only below md — do not add sm: variants.

Anti-patterns and the maintenance loop

The anti-patterns section for a Tailwind project captures the utility combinations that agents reach for automatically but that are wrong for this specific product. Each anti-pattern was born from a real mistake, either observed in AI output or learned from a past inconsistency. Maintaining DESIGN.md as a living document means updating the anti-patterns section after every session where the agent produced something that needed correction. Over time the file becomes a Tailwind style guide tested against actual AI output in this specific codebase — not a generic best-practices document, but a record of exactly what this agent needs to be told to produce consistent work.

  • Do not use arbitrary values like w-[723px] or pt-[18px] — if a spacing step is missing from the scale, add it to the config.
  • Do not use bg-gradient-to-r or any gradient background on operational UI surfaces.
  • Do not mix Tailwind with CSS modules in the same component.
  • Do not stack more than two modifier utilities for hover and focus-visible states together.
  • Do not use text-pretty or leading-relaxed outside of documentation or prose content pages.

Use DESIGN.md with a real product reference

Browse curated DESIGN.md examples from product teams, design systems, developer tools, SaaS dashboards, and AI-native apps. Use them as references before your agent builds the next screen.

Related guides

Frequently asked questions

Does DESIGN.md replace tailwind.config.ts?

No. tailwind.config.ts defines the token values (colors, spacing steps, fonts). DESIGN.md maps those values to usage rules — which class to reach for in which context, and which combinations are forbidden.

Should DESIGN.md list every Tailwind class we use?

No — only the ones with more than one valid-looking option (hover backgrounds, border colors, spacing steps). Canonicalize those, and let the agent use standard Tailwind everywhere else.

How do we stop AI agents from using arbitrary values like w-[723px]?

Add an explicit anti-pattern rule and make sure the spacing scale in DESIGN.md actually covers the values the product needs. If a step is genuinely missing, add it to tailwind.config.ts instead of allowing arbitrary values.