Guidelines
Rules for developers and AI Builders.
AI Builder rules
Do
- Use semantic tokens (bg-background, bg-card, text-muted-foreground)
- Use status tokens for state: bg-success-background / bg-warning-background / bg-destructive-background
- Import primitives from @morada-ai/niemeyer/components
- Use @tabler/icons-react
- Follow the page templates under /templates
- Use font-heading for titles, font-body for prose
- Add aria-label on icon-only buttons
Don’t
- Hardcode colors (bg-white, text-gray-500, #ffffff)
- Use raw <button>/<input>/<select> when a primitive exists
- Use lucide-react, react-icons, or any other icon set
- Create one-off Card or Button wrappers — extend with className instead
- Remove the focus ring (outline-none) without restoring focus-visible
- Skip <Label> on form inputs
- Use Tailwind's `!` (important) modifier inside design-system primitives
// Context for AI prompts:
// Framework: Next.js 16+, React 19+, TypeScript (the package itself supports React 18+)
// Styling: Tailwind CSS 4 + Niemeyer semantic tokens
// Components: @morada-ai/niemeyer/components — Niemeyer-customized shadcn primitives
// Icons: @tabler/icons-react only
// Fonts: Outfit (font-heading), Lato (font-body) — both required as CSS variablesAccessibility
WCAG 2.1 level AA.
| Rule | Detail |
|---|---|
| Text contrast | Minimum 4.5:1 (normal) or 3:1 (large text) |
| Keyboard | All interactive content reachable via Tab; focus ring visible |
| Semantics | Semantic HTML; headings in order; one h1 per page |
| Labels | Every input has an associated <Label htmlFor=...> |
| ARIA | aria-label on icon buttons, aria-invalid on input errors |
| Color | Never use color as the only state indicator (pair with icon or text) |
Dark mode
Enabled via the .dark class on the html element. Always reach for semantic tokens — they flip automatically.
// Correct — theme-aware
<div className="bg-background text-foreground border-border" />
// Wrong — not theme-aware
<div className="bg-white text-gray-900 border-gray-200" />Icons
Use @tabler/icons-react only. Sizes follow the Niemeyer pixel ladder (size-N maps to the package's --space-* tokens, not stock Tailwind rem values).
| Context | Size | Class |
|---|---|---|
| Inside a Button or Input | 16px | size-4 |
| Menu / sidebar item | 24px | size-5 |
| Feature icon (in a circle) | 32px | size-6 |
| Illustration / hero | 40–48px | size-7 → size-8 |