Get started

Recommended stack

A design kit controls the look. The stack underneath controls whether that look actually holds across the entire product. These recommendations come from shipping agent-built projects where the kit stayed consistent across hundreds of components.

Component primitives

Every interactive element (button, input, select, dialog, tooltip, popover, tabs, accordion) should use a component primitive library, not raw HTML. The kit handles the visual layer; the primitive handles behavior, accessibility, keyboard navigation, and screen reader announcements.

LibraryWhen to use it
shadcn/uiDefault choice. Components copy into your project as source code using CSS variables. Identity Forge ships a shadcn registry that installs a kit's tokens in one command.
Radix UIWhen you want full control over markup and styling. The unstyled primitives underneath shadcn.
Base UIAlternative unstyled primitives with a minimal API. shadcn/ui also ships a Base UI registry.

Pick one and stay with it. Mixing primitive libraries in the same project creates inconsistency in focus behavior, portal placement, and animation timing.

Hard requirements

Add these to your project instructions (CLAUDE.md, .cursorrules, or equivalent). They are the minimum set that keeps a design kit effective.

Every UI element uses a primitive

## Component rules

Every interactive UI element uses shadcn/ui (or Radix UI / Base UI).
No raw HTML `<button>`, `<input>`, `<select>`, `<dialog>`, or `<table>`.
Custom components wrap the primitive, never replace it.

Components live in src/components/ui/ as source code.

Tokens, not values

## Design tokens

No hex colors, no rgb(), no hsl() literals in components.
All colors via Tailwind classes mapped to CSS custom properties:
bg-primary, text-foreground, border-border, bg-muted, etc.
All radii via the --radius token: rounded-sm, rounded-md, rounded-lg.

Verification: `grep -rn '#[0-9a-fA-F]' src/components/` must return zero hits.

Conditional styling through cn()

## Styling

All conditional class composition through cn() (clsx + tailwind-merge).
No string concatenation for classes. No ternary-in-className without cn().
Pattern: className={cn("base-classes", condition && "conditional-classes", className)}

Review flow

After completing a feature or section, run a review as a separate agent prompt:

Review every component in src/components/ and flag:
1. Any interactive element not using shadcn/ui, Radix, or Base UI
2. Any hardcoded color (grep -rn '#[0-9a-fA-F]' src/components/ must return zero)
3. Any className composition that doesn't use cn()
4. Any raw HTML form element (<input>, <select>, <textarea>) not wrapped in a primitive

For each finding: fix it, don't just flag it.

Run this as a separate prompt after the implementation work, not during it. Mixing implementation and review in one prompt produces weaker results in both.

Full stack recommendation

For a new project using Identity Forge design kits:

LayerRecommendation
FrameworkNext.js (App Router) with TypeScript strict
StylingTailwind CSS with design kit tokens as CSS custom properties
Componentsshadcn/ui (copies into project, uses CSS variables natively)
FormsReact Hook Form + Zod validation
Motionmotion/react with semantic duration constants, not magic numbers
Internationalizationnext-intl (all user-facing text via message catalogs)
Design systemIdentity Forge kit installed via CLI, MCP, or shadcn registry

This is not the only stack that works, but it is the one where the most friction has been removed. The shadcn registry install maps kit tokens directly to the CSS variables shadcn components already use, so the kit applies with zero manual wiring.

Enforcement in agent instructions

Copy this block into your project's agent instructions file. It combines the hard requirements above with the review trigger.

## Design system enforcement

This project uses an Identity Forge design kit as the single source of truth
for all visual decisions. The kit tokens are installed as CSS custom properties.

### Rules (no exceptions)
- Every interactive element uses shadcn/ui, Radix UI, or Base UI primitives
- Every color, radius, shadow, and font reference uses a design token
- All conditional class composition uses cn() (clsx + tailwind-merge)
- No raw HTML form elements: <input>, <select>, <textarea>, <button>

### Verification
After completing any UI work, run:
  grep -rn '#[0-9a-fA-F]' src/components/
Zero results means the token rule holds. Any hit must be fixed before the work
is considered done.

### Periodic review
After completing a feature, review src/components/ for:
primitives not used, tokens not used, cn() not used, raw HTML form elements.
Fix each finding in place.