Getting started

Theming

Novix UI uses OKLCH design tokens exposed as CSS custom properties. Override a variable at any scope — :root, .dark, a section, a component — and the entire surface follows.

Semantic-only tokens

Novix UI never hardcodes color inside components. Every surface reads from a named token, so a single override cascades everywhere. Use tokens likebg-surfaceandtext-foreground— never bg-white.

Palette

Click any plate below to copy its CSS variable (var(--name)) or Tailwind class (bg-name).

Neutrals

background

--background

surface

--surface

subtle

--subtle

muted

--muted

border

--border

border-strong

--border-strong

foreground

--foreground

Semantic

primary

--primary

accent

--accent

success

--success

warning

--warning

danger

--danger

CSS tokens code

Add these token definitions to your global.css or app.css to match Novix UI's full palette:

css
:root {
/* Neutrals — Light */
--background: oklch(0.995 0 0);
--foreground: oklch(0.145 0.01 260);
--surface: oklch(0.985 0.002 260);
--subtle: oklch(0.965 0.004 260);
--muted: oklch(0.955 0.005 260);
--border: oklch(0.918 0.006 260);
--border-strong: oklch(0.86 0.008 260);
 
/* Semantic */
--primary: oklch(0.19 0.02 260);
--accent: oklch(0.62 0.19 265);
--success: oklch(0.68 0.15 155);
--warning: oklch(0.78 0.15 75);
--danger: oklch(0.6 0.22 27);
}
 
.dark {
/* Neutrals — Dark */
--background: oklch(0.145 0.008 260);
--foreground: oklch(0.975 0.003 260);
--surface: oklch(0.185 0.01 260);
--subtle: oklch(0.22 0.012 260);
--muted: oklch(0.24 0.013 260);
--border: oklch(1 0 0 / 9%);
--border-strong: oklch(1 0 0 / 16%);
 
/* Semantic */
--primary: oklch(0.975 0.003 260);
--accent: oklch(0.7 0.18 265);
--success: oklch(0.75 0.16 155);
--warning: oklch(0.82 0.15 75);
--danger: oklch(0.6 0.22 27);
}

Light, dark, and system

ThemeProvider persists the user's preference to localStorage and syncs with the OS. The useTheme() hook exposes the current mode plus a toggle() action.

tsx
import { useTheme, IconButton } from "@novix-ui/react";
import { Moon, Sun } from "lucide-react";
 
export function ThemeToggle() {
const { resolvedTheme, toggle } = useTheme();
return (
<IconButton
aria-label="Toggle theme"
onClick={toggle}
icon={resolvedTheme === "dark" ? <Sun /> : <Moon />}
/>
);
}

Custom themes

Override any token at any scope. Novix UI reads variables at paint time, so themes can be swapped per-route, per-section, or per-component with zero re-mounting.

css
/* Warm brand override, scoped to a marketing route */
[data-theme="brand"] {
--accent: oklch(0.7 0.19 30);
--accent-muted: oklch(0.94 0.05 30);
--ring: oklch(0.68 0.2 30);
}