Using auri with shadcn

auri is not a shadcn alternative — it is the other lane. shadcn/ui is the chrome humans write: navigation, settings, dialogs. auri is the surfaces agents emit over the wire at runtime. A real product has both, and they should read as one system. This page is the bridge that makes that mechanical.

Why this is easy

auri's Foundation adopts shadcn/ui v4's values on purpose: the same chroma-zero oklch neutrals, the same hairline-in-light / white-alpha-in-dark border treatment, a radius scale built around shadcn's own 0.625rem base. On a stock shadcn theme the bridge below is a near no-op — it starts mattering the moment you customize your theme, because from then on auri follows your values instead of merely resembling them.

It also works without ceremony because auri's tokens ship at :where() zero specificity by design — any declaration in your own stylesheet outranks them. Overriding is the supported customization path, not a fight with the cascade.

The one-variable path

If all you want is auri in your brand color, skip the bridge: set --auri-seed (light) and --auri-seed-dark (dark) and every primary tone — buttons, focus rings, tinted containers — reseeds from those two values. The full bridge is for apps that want auri to inherit the whole shadcn theme: ground, cards, borders, radius, charts.

The bridge, two steps

1 — mirror the dark class. shadcn toggles .dark; auri's renderer keys off .a2ui-dark. Set both in your theme toggle:

const toggle = () => {
	document.documentElement.classList.toggle('dark', isDark);
	document.documentElement.classList.toggle('a2ui-dark', isDark); // one added line
};

This flips everything the token bridge doesn't carry — the five intents, skeleton shimmer, hover/press state layers. Without it, a dark shadcn app would get light-mode intent colors on a dark ground. (If you use the media-query strategy instead of a class, skip this step — auri's own prefers-color-scheme block already tracks it.)

2 — paste the token bridge after your shadcn theme. Colors flip with your theme automatically, because every bridged value points at a shadcn variable that itself changes under .dark:

/* auri ← shadcn bridge — paste after your shadcn theme (e.g. globals.css). */
:root {
	--auri-surface: var(--background);
	--auri-surface-container: var(--card);
	--auri-surface-container-high: var(--muted);
	--auri-on-surface: var(--foreground);
	--auri-on-surface-variant: var(--muted-foreground);
	--auri-outline-variant: var(--border);

	--auri-primary: var(--primary);
	--auri-on-primary: var(--primary-foreground);
	--auri-primary-container: color-mix(in oklab, var(--primary) 10%, var(--background));
	--auri-on-primary-container: var(--primary);

	--auri-shape-sm: calc(var(--radius) - 4px);
	--auri-shape-md: var(--radius);
	--auri-shape-lg: calc(var(--radius) + 4px);

	/* optional — adopt your chart palette (auri keeps its sixth) */
	--auri-chart-1: var(--chart-1);
	--auri-chart-2: var(--chart-2);
	--auri-chart-3: var(--chart-3);
	--auri-chart-4: var(--chart-4);
	--auri-chart-5: var(--chart-5);
}

/* Dark tunes the two derived primary tones; scope to your dark selector. */
.dark {
	--auri-primary-container: color-mix(in oklab, var(--primary) 16%, var(--background));
	--auri-on-primary-container: color-mix(in oklab, var(--primary) 55%, white);
}

The mapping

auri roleshadcn variablenote
--auri-surface--backgroundthe page ground
--auri-surface-container--cardcards: Stat, Chart, ApprovalCard…
--auri-surface-container-high--mutedmuted fills, code insets
--auri-on-surface--foregroundprimary text
--auri-on-surface-variant--muted-foregroundlabels, captions
--auri-outline-variant--borderhairlines
--auri-primary family--primary familycontainers derived via color-mix
--auri-shape-sm/md/lg--radius ±4pxshadcn's own calc pattern
--auri-chart-1…5--chart-1…5optional; auri keeps its sixth

What deliberately stays auri

  • The five intents. good / bad / warning / info / neutral is the design signature agents rely on, and shadcn has no counterpart scale — --destructive maps to roughly one fifth of it. The intent trios stay auri's and flip with .a2ui-dark (step 1).
  • Input fill. Not bridged because the defaults already agree: transparent hairline inputs in light, translucent white-alpha fills in dark — auri adopted shadcn's treatment outright.
  • Motion, skeletons, type roles. No shadcn counterpart exists; they are part of what a catalog promises an agent (in-between states are contract concerns), so they ship with auri.
  • Fonts need no bridge. auri components inherit the host font stack — a shadcn app that sets Geist (or anything else) on body is already done.