UI agent playbook: design contracts, tokens, and verification
Date: 2026-04-16
Audience: Anyone using AI agents (Cursor, Claude Code, Codex, etc.) to build or refactor web UI at Brainforge.
Cursor rule: .cursor/rules/ui-agent-design-contracts.mdc (requestable; complements .cursor/rules/web-design-skill-routing.mdc).
Why this exists
AI tools are strong at layout and speed and weak at consistency unless the workspace is constrained. The failure mode is parallel systems: the model ignores your Tailwind theme, design tokens, or component library and invents a second styling language next to yours. This playbook defines contracts (allowed surface) and a verification loop so generation stays on-brand and maintainable.
Canonical references
| Resource | Use |
|---|---|
| brainforge-ai/brainforge-brand-kit | Brand tokens, Astro primitives, reference site patterns (clone and read README + theme entrypoints). |
| Chrome DevTools MCP / chrome-devtools-mcp | Runtime truth: DOM, computed CSS, console, performance. Use after or during UI work, not as a substitute for tokens. |
.cursor/rules/web-design-skill-routing.mdc | When work is visual or UX-heavy, still route through frontend-design / improve-designs / Impeccable as appropriate. |
Deep dives (this vault)
| Doc | Purpose |
|---|---|
knowledge/engineering/brainforge-brand-kit-map-2026-04-16.md | Repo tree, token pipeline, how to run the gallery. |
knowledge/engineering/brainforge-brand-kit-allowed-surface-2026-04-16.md | Allowed surface for Astro kit work (tokens, components, out-of-bounds). |
knowledge/engineering/forge-vs-brand-kit-strategy-2026-04-16.md | Forge vs kit placement (Next+MUI vs Astro; token parity). |
Principles
- Contracts over prompts — Narrow the model to semantic tokens, component variants, and layout primitives. Aesthetic instructions alone do not prevent drift.
- Tailwind as compression — Utilities are token-efficient for agents; guard with semantic names and no arbitrary values unless explicitly approved (e.g. ban
p-[17px], magic hex in class strings). - One source of truth — CSS variables /
@theme(Tailwind v4 style) or the repo’s existing theme: extend, do not fork. - DevTools MCP = inspector — Use it to catch overflow, contrast, wrong computed styles, and regressions. It does not replace a written allowed surface.
- Presentation-only passes — When “fixing” UI, scope agents to visual layer unless the ticket requires logic changes (see prompt pack below).
Repo placement: Forge vs brand kit
See forge-vs-brand-kit-strategy-2026-04-16.md (decisions, consumption models, agent scope per stack).
Agent instructions (paste or encode in rules)
Use variants of the following in PRs, tickets, or Cursor rules:
- Reuse only: “Reuse existing design tokens and components from this repo. Do not invent new color, spacing, or radius scales. Do not add one-off Tailwind arbitrary values unless the user explicitly approves.”
- No parallel system: “Do not introduce a parallel styling approach (inline styles for layout, new global CSS files, or duplicate button/card patterns) when an existing primitive exists.”
- Scope: “Presentation only: typography, spacing, color tokens, component consistency, states, and a11y. Do not refactor business logic or data fetching unless asked.”
Layered “design system fix” pass (order)
Work top-down in one pass or separate commits:
- Typography scale and hierarchy
- Spacing rhythm (sections, stacks, forms)
- Semantic color (background, foreground, border, accent)
- Component variants (size, emphasis, density)
- Interactive states (hover, focus, disabled, invalid)
- Quick a11y check (focus visible, labels, contrast)
Paste-ready: “UI system fix” prompt (presentation only)
Use when you want a single agent pass to polish without behavior changes:
You are a senior UI engineer. Audit and fix the visual system of this project so it looks intentional and consistent with existing tokens and components—not vibe-coded.
Do not change business logic, data fetching, or API contracts. Only adjust presentation: typography, spacing, semantic colors, component consistency, interactive states, and basic a11y (focus rings, label association, contrast).
Work in this order: (1) typography hierarchy (2) spacing rhythm (3) semantic colors from the theme (4) reuse or align component variants (5) hover/focus/disabled/error states (6) quick a11y pass.
Reuse existing design tokens and components. Do not invent new palettes, spacing scales, or parallel button/input patterns. Avoid arbitrary Tailwind bracket values unless the user explicitly approves.
Good vs bad (patterns)
These examples are illustrative; exact class names depend on target repo (kit vs Forge).
| Bad (parallel / arbitrary) | Good (contract-aligned) |
|---|---|
className="text-gray-500 bg-[#f5f5f0] p-[13px]" ad hoc | Semantic text + surface: e.g. text-fg-secondary bg-bg-root p-4 (kit) or MUI Typography + theme palette (Forge) |
New <button class="rounded-xl bg-blue-600 px-8 …"> in every feature | Reuse Button / Button from MUI or kit Button.astro with existing variant props |
style={{ marginTop: 24 }} for layout that Tailwind/grid already solves | mt-6 / stack gap-* / MUI Stack spacing props |
Second set of CSS variables --my-accent outside theme files | Extend themes/brainforge.css or Forge @theme / MUI theme—one accent story |
| Hero built only from random Unsplash + gray defaults | bg-token-surface-hero, --fg-on-dark, components from HeroSection patterns |
Parallel systems smell: same screen mixes kit semantic classes, raw Tailwind gray scale, and inline hex—with no mapping to theme.
Verification checklist (human or agent)
- No new colors/spacing outside the documented scale
- Reused existing components where a pattern already exists
- Focus states visible; form labels associated
- Checked layout overflow and breakpoints (DevTools MCP or manual)
- No unrelated file churn (keep diffs reviewable)
ESLint (The Forge)
apps/platform/eslint.config.mjs enables eslint-plugin-better-tailwindcss only for better-tailwindcss/no-restricted-classes (warnings) against:
- Arbitrary pixel classes matching
[NNpx]in a utility - Arbitrary hex in brackets (e.g.
bg-[#244926])
We intentionally do not enable no-unknown-classes for the whole preset: the Forge mixes Tailwind with BEM-style marketing class names that are not Tailwind utilities.
Optional hardening
- Stricter Tailwind — Later, enable additional
better-tailwindcssrules selectively per folder (e.g. onlysrc/app/(main)/dashboard/**) if noise stays low. - Design extract tools — For reference sites, community tools exist to snapshot tokens into markdown/Tailwind config; treat output as input to contracts, not as unreviewed truth.
Related internal notes
- Skill vs playbook gate:
knowledge/engineering/skill-vs-playbook-decision-guide.md - Slack-facing UX norms (different domain):
knowledge/engineering/slack-ux-guidelines.md
Changelog
| Date | Change |
|---|---|
| 2026-04-16 | Initial playbook from brand kit + Tailwind contracts + DevTools MCP thread. |
| 2026-04-16 | Brand kit map, allowed surface, Forge vs kit strategy; Forge ESLint arbitrary-class warnings; good/bad table and paste-ready UI fix prompt. |