Guidelines for AI agents working on this documentation codebase.
Primitives (Layer 1) Semantic Tokens (Layer 2)
─────────────────────────────────────────────────────────
--blue-500 → --primary, --brand
--grey-light-700 → --sidebar-item-foreground
--white-0 → --background, --card
--grey-light-200 → --border
Rule: Always use Layer 2 (semantic tokens) in components. Never use primitives directly.
Global: bg-{property} → bg-background, bg-primary
Component: bg-{component}-{property} → bg-sidebar-background
State: bg-{component}-{property}-{state} → bg-sidebar-item-background-hover
src/
├── app/
│ ├── global.css # Token definitions - EDIT HERE for new tokens
│ └── docs/ # Documentation pages
├── components/
│ ├── ui/ # shadcn components - generally don't modify
│ ├── layout/ # Sidebar, navbar, etc.
│ ├── mdx/ # MDX components for content
│ └── helpers/ # Utility components
├── styles/
│ └── DESIGN_SYSTEM.md # Token reference documentation
└── lib/
└── source.ts # Fumadocs configuration
/* 1. In :root (light mode) */
--new-token: var(--blue-300);
--new-token-foreground: var(--white-0);
/* 2. In .dark (dark mode) */
--new-token: var(--blue-400);
--new-token-foreground: var(--white-0);
/* 3. In @theme inline (Tailwind mapping) */
--color-new-token: var(--new-token);
--color-new-token-foreground: var(--new-token-foreground);// ✅ Correct
className="bg-sidebar-background text-sidebar-item-foreground"
className="bg-card border border-card-border"
className="text-page-nav-foreground-active"
// ❌ Wrong - using var() wrapper
className="bg-[var(--sidebar-background)]"
// ❌ Wrong - using old docs- prefix
className="bg-docs-sidebar-bg"
// ❌ Wrong - using primitives
className="bg-[var(--blue-500)]"Use these tokens:
sidebar-*for sidebarnavbar-*for top navigationborderfor dividers
Use these tokens:
card-*for cardsforegroundfor textbrandfor headings/accentsborderfor dividers
These are shadcn components. They use:
primary,secondary,destructivefor buttonscard,popoverfor containersmuted,accentfor states
background, foreground, border, primary, secondary, muted, accent, destructive, brand
sidebar-background, sidebar-item-background, sidebar-item-background-hover, sidebar-item-background-active, sidebar-item-foreground, sidebar-item-foreground-hover, sidebar-item-foreground-active, sidebar-border
navbar-background, navbar-border
search-background, search-background-hover, search-foreground, search-foreground-active, search-border, search-results-background-hover, search-results-foreground, search-results-foreground-primary
key-background, key-foreground, key-underline
menu-item-background, menu-item-background-hover, menu-item-foreground, menu-item-border
page-nav-foreground, page-nav-foreground-hover, page-nav-foreground-active
card, card-foreground, card-border, card-header-background
breadcrumb-current, breadcrumb-previous
link-foreground, link-underline
feedback-success-background, feedback-success-foreground, feedback-warning-background, feedback-warning-foreground, feedback-error-background, feedback-error-foreground, feedback-info-background, feedback-info-foreground
- Don't use
docs-prefix - We removed this for simplicity - Don't wrap in
var()- Tailwind v4 handles this automatically - Don't use primitives directly - Always use semantic tokens
- Don't hardcode colors - Use tokens for theming support
- Don't forget dark mode - Add both
:rootand.darkvariants
# Pre-commit guardrail (runs lint-staged + typecheck)
pnpm validate:precommit
# Type check
pnpm types:check
# Build (catches CSS errors)
pnpm build
# If CSS parsing errors occur, clear cache
rm -rf .next && pnpm build- Content lives in
docs/directory as MDX files source.tsconfigures the content source- Page tree is auto-generated from file structure
- Use
meta.jsonfiles to customize navigation order