Theming

Everything is driven by CSS variables in OKLCH. Surfaces, actions, status colors, a brand accent and motion curves — all in one file.

Playground

Pick a hue and a radius, then copy the variables into your theme file.

330°
Newv0.1
:root {
  --radius: 0.625rem;
  --brand: oklch(0.56 0.2 330);
  --ring: oklch(0.56 0.2 330 / 45%);
}

.dark {
  --brand: oklch(0.7 0.17 330);
  --ring: oklch(0.7 0.17 330 / 50%);
}

Tokens

Each token comes in pairs where it makes sense: --primary is the fill, --primary-foreground is the text that sits on it. Tailwind utilities like bg-primary and text-muted-foreground map to them automatically.

Surfaces

--background

Page background

--card

Raised surfaces

--popover

Menus, popovers, dialogs

--muted

Subtle fills

--accent

Hover and highlight

Actions

--primary

Main buttons, selected states

--secondary

Secondary buttons

--brand

Your accent color, used sparingly

--destructive

Dangerous actions

Status

--success

Positive outcomes

--warning

Needs attention

--info

Neutral information

Lines

--border

Dividers and outlines

--input

Form control borders

--ring

Focus rings

Dark mode

Dark tokens live under a .dark class. Use next-themes (or anything that toggles the class on html):

pnpm add next-themes
components/theme-provider.tsx
"use client"

import { ThemeProvider as NextThemesProvider } from "next-themes"

export function ThemeProvider({ children }: { children: React.ReactNode }) {
  return (
    <NextThemesProvider attribute="class" defaultTheme="system" enableSystem disableTransitionOnChange>
      {children}
    </NextThemesProvider>
  )
}
Tip
Dark surfaces use lightness steps instead of shadows: background → card → popover each get a touch brighter, and borders are translucent white so they adapt to any surface.

Adding tokens

Declare the variable for both themes, then expose it to Tailwind with @theme inline.

:root { --highlight: oklch(0.9 0.12 95); }
.dark { --highlight: oklch(0.4 0.1 95); }

@theme inline {
  --color-highlight: var(--highlight);
}

/* bg-highlight, text-highlight, border-highlight… are now available */