Skip to content

Now in the official shadcn registry directory.

Start free
Getting started

Theming

One token file drives everything. Standard shadcn variables stay untouched - ai2 adds tone channels, surfaces and motion on top.

How it works

In this repository, tokens/tokens.json is the single source of truth. A build script generates the CSS, and the registry publishes the same values as the @ai2/tokens theme item, which the CLI merges into your globals.css automatically when you install any component. In your project the tokens are plain CSS variables: override them and every component follows, in both modes.

ai2 deliberately reuses the standard shadcn variables (--primary, --muted, --border…) for everything they already cover. Your existing shadcn theme keeps working. Only the extensions below are ai2-specific.

Tone tokens

TokenPurpose
--brand / --brand-foregroundPrimary product tone: ai2's own magenta (hue 331). Override one variable to swap it for your brand.
--brand-soft / --brand-soft-foregroundLow-emphasis brand surfaces: soft buttons, badges, hovers.
--success, --warning, --danger, --info (+ -foreground)Solid semantic tones for buttons, badges, alerts, progress.
--*-soft / --*-soft-foregroundSoft pair for every semantic tone: tinted backgrounds with readable text.
brand
success
warning
danger
info
muted

Surface tokens

TokenPurpose
--surface-2First elevation above the page background: section bands, code blocks, tiles.
--surface-3Second elevation: nested surfaces inside surface-2.
--field-borderBorder of every form control (input, textarea, select, checkbox, radio, OTP, file input). Kept at 3:1 against the page in both themes, because the border is the only cue that says where a field is (WCAG 1.4.11). Deliberately separate from --border, which stays faint for decorative rules, and from --input, which shadcn also uses as a fill.

Motion tokens

TokenPurpose
--motion-fast150ms: hovers, color transitions.
--motion-base200ms: reveals, toggles.
--motion-slow300ms: overlays, larger movement.
--motion-easecubic-bezier(0.2, 0, 0, 1), the single easing curve.

In Tailwind, use them as duration-(--motion-fast) and ease-(--motion-ease).

Using tokens

TS
<Button tone="brand">Uses --brand</Button>
<Alert tone="success">Uses --success + --success-soft</Alert>
<div className="bg-surface-2 rounded-xl p-6">Uses --surface-2</div>
<div className="transition-colors duration-(--motion-fast)">…</div>

Building your own theme

ai2 ships its own magenta brand, but it is just a default. To recolor, override the variables after the ai2 token block - no component changes needed:

CSS
/* globals.css - after the ai2 token block */
:root {
  --brand: oklch(0.55 0.2 265);            /* indigo brand */
  --brand-foreground: oklch(0.985 0 0);
  --brand-soft: oklch(0.93 0.05 265);
  --brand-soft-foreground: oklch(0.4 0.18 265);
}

.dark {
  --brand: oklch(0.7 0.16 265);
  --brand-foreground: oklch(0.15 0.02 265);
}

Ready-made overlays

A theme is a registry:theme item: CSS variables only, no component changes. Install one and every component reading the brand tone follows, in both modes. Semantic tones (success, warning, danger, info) stay untouched.

ai2 Magenta is the built-in default (hue 331, light and dark). It ships automatically with @ai2/tokens when you install any component, so there is nothing extra to add.

Indigo is a free overlay that recolors the brand channel in both modes:

npx shadcn@latest add @ai2/theme-indigo

To dial your own values against real components and copy the result, use the theme generator.

Dark mode

Every token defines a light and a dark value; dark mode is the .dark class on <html>. This site defaults to the system preference and persists your toggle in localStorage. Any mechanism that sets the class works (next-themes included).

Get new components in your inbox

Component drops, new themes and release notes. No spam, and you can unsubscribe from any email.

© 2026 ai2 design system · MIT licensed · Built with its own components