Getting started
Theming
--brand aliases --primary in light and --sidebar-primary in dark so accents stay readable. Merriweather for headings, DM Sans for UI and body, opt-in Caveat sketch. After npx shadcn add, tokens live in your host CSS — not behind a required npm import.CSS variables
Light and dark themes live under :root and .dark. Default brand tracks Mira --primary (oklch(0.457 0.24 277.023) in light). Override Mira variables to restyle without rewriting components. Site chrome CTAs (.atro-btn; .ms-cta aliases it) and shadcn Button all read --primary.
:root {
--background: oklch(1 0 0);
--foreground: oklch(0.141 0.005 285.823);
--primary: oklch(0.457 0.24 277.023);
--radius: 0.45rem;
}
.dark {
--background: oklch(0.185 0.006 285.9);
--foreground: oklch(0.985 0 0);
--primary: oklch(0.398 0.195 277.366);
--card: oklch(0.235 0.007 285.9);
}The docs host and Host API consumers can still import atroui/globals.css from the npm package when they already depend on atroui. Pure registry apps should keep tokens in the host stylesheet the CLI/theme setup already owns. See npm → shadcn registry.
Accents
Live accents (Mira / Tide / Ember / Bloom / Graphite) set data-color-theme on the docs host. When you pick Tide on a component page, the install chip appends @atroui/theme-tide so the CLI ships those tokens with the block. Mira is the default — no companion package. Try it in Theme Studio.
Fonts
Same pairing as the shadcn Mira + Indigo preset:
- Merriweather — headings, page titles, section H2s, display accents
- DM Sans — body, ledes, labels, buttons, chrome
- Caveat — opt-in sketch only; never the default display face
- Geist Mono — code, stamps, and section rails
Utility classes: .ds-display, .ds-headline, .ds-sketch, .ms-stamp. On the docs host, load the four families in the root layout and expose --font-merriweather, --font-dm-sans, --font-caveat, and --font-geist-mono.
/* Face stacks → role tokens → utilities (font-sans → --font-body) */
--font-heading: var(--font-merriweather); /* titles / H2 */
--font-display: var(--font-heading);
--font-body: var(--font-dm-sans); /* body / UI */
--font-sans: var(--font-body); /* utility → role */
--font-sketch: var(--font-caveat); /* opt-in sketch only */Radius
One knob. CTAs, stamps, and panels use --radius (and --radius-lg, --radius-md). Default is soft rectangle — not capsules. Circles stay for avatars, status dots, and true toggles. Try Soft / Mira / Sharp live in Theme Studio.
:root {
/* Soft rect (AtroUI default) — controls follow via --atro-control-radius */
--radius: 0.45rem;
/* Sharp — set once, CTAs follow */
/* --radius: 0; */
/* Extra soft — still not a pill */
/* --radius: 1.25rem; */
}Want full pills? Edit the installed block — change rounded-lg to rounded-full on that button. We don’t ship a second variant of every block.
Site brand
Chrome strings (name, domain, email, site URL) come from getBrand() after you add @atroui/brand (typically lib/brand.ts). Defaults are AtroUI; override with env:
NEXT_PUBLIC_SITE_NAME=AtroUI
NEXT_PUBLIC_SITE_DOMAIN=atroui.com
NEXT_PUBLIC_SITE_EMAIL=hello@iamk.xyz
NEXT_PUBLIC_SITE_URL=https://www.atroui.comDemo modules may still show studio sample copy - swap CONTENT at the top of each installed block when shipping your own site.
Dark mode
Use next-themes with attribute="class". Add the toggle from the registry: npx shadcn add @atroui/theme-toggle. If flipping to dark hides muted copy or flattens a designed light palette, use Adaptive Theme Switch (@atroui/theme-adapt) instead. It still uses .dark, then lifts type tokens to WCAG AA.
import { ThemeProvider } from "next-themes"
import { ThemeToggle } from "@/components/ui/theme-toggle"
<ThemeProvider attribute="class" defaultTheme="system" enableSystem>
<ThemeToggle />
{children}
</ThemeProvider>