Tailwind theme tokens a coding agent can follow
With --color-*: initial in @theme, Tailwind stops generating classes such as bg-indigo-600. It still generates bracket values such as bg-[#6d28d9], so the agent's instructions need to rule those out.
6 min read
Give the agent a fixed set of class names
In Tailwind CSS v4, each variable in an @theme block creates utility classes: --color-brand creates bg-brand, text-brand and border-brand. If the theme names every colour, font and radius the site uses, an agent writing a component can choose from those names instead of inventing a value.
Tailwind's documentation draws the line this way: use @theme for a token that should map to a utility class, and :root for a variable that should not.
Copy the theme file
This is src/app.css for the fictional Wrenboard site. The line --color-*: initial removes Tailwind's default palette, so only the seven named colours produce colour classes. The two font variables create font-display and font-body, and the two radius variables create rounded-control and rounded-card.
@import "tailwindcss";
@theme {
/* Remove Tailwind's default palette so only Wrenboard colours exist. */
--color-*: initial;
--color-page: #f7f4ee;
--color-surface: #ffffff;
--color-ink: #1d2a26;
--color-muted: #55635e;
--color-brand: #0f5b4f;
--color-brand-ink: #ffffff;
--color-line: #d9d3c7;
--font-display: "Source Serif 4", Georgia, serif;
--font-body: system-ui, -apple-system, "Segoe UI", sans-serif;
--radius-control: 8px;
--radius-card: 12px;
}What does the theme stop, and what does it allow?
On 5 November 2026, we compiled this file with Tailwind 4.2.4's own compiler, once for each class below, and recorded the CSS it generated.
Removing the default palette closes one route to an off-brand colour: bg-indigo-600 produces no CSS. Square-bracket values still compile. An agent that writes bg-[#6d28d9] gets a purple background, so the instructions must cover bracket values, and a search of the diff must check for them.
| Class | CSS generated |
|---|---|
| bg-brand | background-color: var(--color-brand) |
| rounded-card | border-radius: var(--radius-card) |
| font-display | font-family: var(--font-display) |
| bg-indigo-600 | None |
| text-slate-700 | None |
| bg-[#6d28d9] | background-color: #6d28d9 |
| rounded-[14px] | border-radius: 14px |
Write the rules the theme cannot enforce
Save this as AGENTS.md at the repository root; Codex reads AGENTS.md files before it starts work. The file says which utilities exist, rules out bracket values for colour, font, radius and shadow, and says what to do when the theme lacks a value: name the variable to add to app.css instead of writing a one-off value in the component. Its last section gives the search a reviewer can run on a diff.
# Wrenboard site: styling rules
## Where design values live
- `src/app.css` is the only place colours, fonts and radii are defined, in the `@theme` block.
- Tailwind generates a utility from each theme variable: `--color-brand` gives `bg-brand`, `text-brand` and `border-brand`; `--font-display` gives `font-display`; `--radius-card` gives `rounded-card`.
- The default Tailwind palette is removed (`--color-*: initial`), so classes such as `bg-indigo-600` produce no CSS.
## Rules for components
- Use only colour utilities built from the theme: page, surface, ink, muted, brand, brand-ink, line.
- Do not use arbitrary values in square brackets for colour, font, radius or shadow, for example `bg-[#6d28d9]` or `rounded-[14px]`. Tailwind will still generate those classes, so nothing else stops them.
- Headings use `font-display`; body text uses `font-body`.
- Buttons use `rounded-control`; cards use `rounded-card`.
- If a design needs a value the theme does not have, stop and say which variable you would add to `src/app.css`. Do not add it inside a component.
## Checking a change
Search the changed files for `[#`, `-[` and default palette names such as `indigo`, `purple`, `slate` and `gray`. Each match is either a rule break or needs a reason in the pull request.What Codex wrote with these files
On 5 November 2026, Codex CLI 0.162.1 ran codex exec in read-only mode in the example folder with the request below. It exited 0 and returned a PricingCard component. Every colour class came from the theme: bg-surface, border-line, text-ink, text-muted, bg-brand, text-brand-ink and marker:text-brand. The heading used font-display, the card rounded-card and the link rounded-control. A search of the output for “[#”, “-[” and the default palette names in AGENTS.md found no matches.
This was one run, and the component was not rendered. Codex also loaded the user's global configuration, so the run does not isolate the effect of the project AGENTS.md.
Write a PricingCard React component for src/components/PricingCard.tsx that shows one plan: Clinic, NZ$89 a month, three included features and a Book a demo link. Follow the project instructions. Do not edit files; reply with the complete file contents only.Where do DESIGN.md decisions fit?
Keep the values in app.css and use DESIGN.md, if you have one, to say what each value is for: which colour the primary action uses, when a card is appropriate, which font sets headings. If both files hold the same hex values, one of them will eventually be wrong. The token-conflict guide shows how to trace a value to the file that owns it, and the dark-mode guide covers paired colours for two themes.
Put the brief into practice
A launch page should make the buyer, promise, proof, and next action obvious. iter0 uses this same standard when it turns a brief or reference site into a builder-ready page.
Start your launch build