shadcn-remix
GitHub

Theming

Using CSS variables and the css() mixin to theme components.

How it works

Components read colors and radii from CSS variables defined in app/ui/globals.css — exactly the shadcn/ui tokens. Change a variable and every component follows.

app/ui/globals.css
:root {
  --background: oklch(1 0 0);
  --foreground: oklch(0.145 0 0);
  --primary: oklch(0.205 0 0);
  --primary-foreground: oklch(0.985 0 0);
  --radius: 0.625rem;
}

.dark {
  --background: oklch(0.145 0 0);
  --foreground: oklch(0.985 0 0);
  --primary: oklch(0.922 0 0);
  --primary-foreground: oklch(0.205 0 0);
}

Dark mode

Add the dark class to <html> to switch themes. Component styles target .dark &, the same as Tailwind’s dark: variant.

Convention

Every color comes as a pair: --x for the background and --x-foreground for the text on it.

VariableUsed for
--background / --foregroundPage background and default text
--card / --card-foregroundCards
--popover / --popover-foregroundPopovers, menus, selects
--primary / --primary-foregroundPrimary buttons, active states
--secondary / --secondary-foregroundSecondary buttons
--muted / --muted-foregroundMuted backgrounds and descriptions
--accent / --accent-foregroundHover and highlighted items
--destructiveDestructive actions and errors
--border, --input, --ringBorders, inputs, focus rings
--sidebar-*The sidebar component
--chart-1 … --chart-5Charts

Radius

--radius drives every corner: calc(var(--radius) - 4px) for small elements, calc(var(--radius) - 2px) for controls, var(--radius) for surfaces and calc(var(--radius) + 4px) for cards.

Customizing components

Every component accepts mix, applied after its own styles. Each css() call is its own cascade layer, ordered by first use, so your mix always wins over the component — no !important, no class merging.

<Button variant="outline" mix={css({ borderRadius: '9999px' })}>
  Rounded
</Button>