A spec snippet for new Next.js + Tailwind + shadcn/ui projects. Paste into your spec before the first build so the design system is set up correctly from the start — no retrofit later.
Prerequisite: a style reference doc at the project root (e.g. design.md) with tokens, typography, surfaces, components, and do/don'ts. The reference is the source of truth for visual direction; this foundation is its shadcn/Tailwind implementation. If no reference exists yet, generate one first.
Before writing any page or component code, run the foundation. One session, one commit.
Paste the reference's Quick Start CSS (Tailwind v4 block if present) into globals.css. Then map brand-specific names onto shadcn's semantic names so the primitives work without per-call overrides:
:root {
/* Brand tokens (from design.md) */
--color-warm-canvas: #fbfaf9;
--color-graphite: #474645;
--color-midnight: #121212;
--color-ember-orange: #ff3e00;
/* …etc */
/* Shadcn semantic mapping */
--background: var(--color-warm-canvas);
--foreground: var(--color-graphite);
--primary: var(--color-midnight);
--primary-foreground: #ffffff;
--accent: var(--color-ember-orange);
/* …etc */
}This mapping is the highest-leverage decision in the session. Document each mapping inline.
For every component the reference defines (Primary CTA, Feature Card, Testimonial Card, etc.), modify the shadcn source under components/ui/ so its defaults match — not Tailwind overrides at the call site.
Example: if the reference says cards use an inset stone border (no CSS border, no drop shadow, box-shadow: ... inset), make that the Card default.
Audit at minimum before first use: Card, Button, Badge, Input, Select.
PageLayout, Section, Stack only if they encode non-obvious values from the reference (max-width, section gap, sanctioned gap scale). Don't wrap for the sake of wrapping — three repeated lines beat a premature abstraction.
The project's implementation doc — derived from the reference, tells engineers/agents what to do with it:
- Token mapping table: brand name → shadcn name → when to use
- Component inventory: what's been built, with the brand vocabulary each implements
- Sanctioned scales: spacing, radius, typography (mirror the reference, name what's allowed)
- Anti-patterns: pull the reference's "Don't" list verbatim, add project rules (no raw Tailwind colors, no
style={{ }})
design.md = visual direction. DESIGN_SYSTEM.md = implementation.
~10 lines, reference both docs:
- Visual direction →
design.md. Implementation rules →src/DESIGN_SYSTEM.md. - Use semantic tokens (
bg-card,text-foreground) — never raw Tailwind colors (bg-white,text-gray-500). - Fix wrong primitive defaults at the source (
components/ui/), not at the call site. - New visual decision? Update
design.mdfirst, propagate toDESIGN_SYSTEM.md, then build. Never invent values inline.
Catch in CI what review can't:
- Disallow raw color utilities (
bg-white,text-gray-*,text-slate-*,bg-zinc-*) and hex literals in JSXclassName - Disallow
style={{ }}props (escape:// eslint-disable-next-linewith justification) - Optional: disallow off-scale spacing if the reference defines a sanctioned scale
After this session: every feature is built against this foundation. New visual decision needed → update design.md, propagate to DESIGN_SYSTEM.md, then build. Never invent visual values inline.