Skip to content
Drivn

Theming

Add dark/light theme support to your project. Theming is optional — Drivn works with light theme by default.

Installation

Run the add command to enable dark/light theme switching.

npx drivn add theme
  • Appends dark/light theme tokens to your globals file
  • Creates theme-provider.tsx component
  • Installs next-themes

Setup

After installing, wrap your app with the ThemeProvider.

1// app/layout.tsx
2import { ThemeProvider } from "@/components/ui/theme-provider"
3
4export default function Layout({ children }) {
5 return (
6 <html suppressHydrationWarning>
7 <body>
8 <ThemeProvider>
9 {children}
10 </ThemeProvider>
11 </body>
12 </html>
13 )
14}

Built for Tailwind v4

Drivn uses Tailwind v4's @theme inline to map CSS custom properties to utility classes. No tailwind.config.ts needed.

1@theme inline {
2 /* Surfaces */
3 --color-background: var(--background);
4 --color-foreground: var(--foreground);
5 --color-card: var(--card);
6 --color-card-foreground: var(--card-foreground);
7 --color-muted: var(--muted);
8 --color-muted-foreground: var(--muted-foreground);
9 --color-accent: var(--accent);
10 --color-accent-foreground: var(--accent-foreground);
11
12 /* Brand */
13 --color-primary: var(--primary);
14 --color-primary-light: var(--primary-light);
15 --color-primary-foreground: var(--primary-foreground);
16 --color-secondary: var(--secondary);
17 --color-secondary-foreground: var(--secondary-foreground);
18
19 /* Semantic */
20 --color-destructive: var(--destructive);
21 --color-destructive-foreground: var(--destructive-foreground);
22 --color-success: var(--success);
23 --color-success-foreground: var(--success-foreground);
24 --color-info: var(--info);
25 --color-info-foreground: var(--info-foreground);
26 --color-brand: var(--brand);
27 --color-brand-light: var(--brand-light);
28 --color-brand-foreground: var(--brand-foreground);
29
30 /* Borders & Inputs */
31 --color-border: var(--border);
32 --color-input: var(--input);
33 --color-ring: var(--ring);
34
35 /* Special Surfaces */
36 --color-nav: var(--nav);
37 --color-code: var(--code);
38 --color-code-highlight: var(--code-highlight);
39 --color-overlay: var(--overlay);
40
41 /* Terminal (always dark-on-dark) */
42 --color-terminal: var(--terminal);
43 --color-terminal-foreground: var(--terminal-foreground);
44 --color-terminal-muted: var(--terminal-muted);
45 --color-terminal-border: var(--terminal-border);
46
47 /* Syntax Highlighting */
48 --color-syntax-keyword: var(--syntax-keyword);
49 --color-syntax-string: var(--syntax-string);
50 --color-syntax-function: var(--syntax-function);
51 --color-syntax-component: var(--syntax-component);
52 --color-syntax-prop: var(--syntax-prop);
53 --color-syntax-operator: var(--syntax-operator);
54 --color-syntax-punctuation: var(--syntax-punctuation);
55}

Color Palette

All available design tokens. Swatches reflect the current theme — toggle dark/light to see both sets.

Surfaces

background

bg-background

card

bg-card

muted

bg-muted

accent

bg-accent

Semantic

success

bg-success

info

bg-info

destructive

bg-destructive

Borders & Inputs

border

bg-border

input

bg-input

ring

bg-ring

Special Surfaces

nav

bg-nav

code

bg-code

code-highlight

bg-code-highlight

overlay

bg-overlay

Dark Theme

The dark theme is applied via :root and data-theme attribute.

1:root,
2[data-theme="dark"] {
3 /* Surfaces */
4 --background: hsl(240 6% 4%);
5 --foreground: hsl(0 0% 98%);
6 --card: hsl(240 5% 7%);
7 --card-foreground: hsl(0 0% 98%);
8 --muted: hsl(240 4% 16%);
9 --muted-foreground: hsl(220 17% 83%);
10 --accent: hsl(240 4% 10%);
11 --accent-foreground: hsl(0 0% 98%);
12
13 /* Brand (monochrome near-white on dark surfaces) */
14 --primary: hsl(0 0% 98%);
15 --primary-light: hsl(0 0% 85%);
16 --primary-foreground: hsl(240 6% 10%);
17 --secondary: hsl(189 94% 53%);
18 --secondary-foreground: hsl(240 6% 4%);
19
20 /* Semantic */
21 --success: hsl(142 71% 59%);
22 --success-foreground: hsl(240 6% 4%);
23 --info: hsl(217 91% 60%);
24 --info-foreground: hsl(0 0% 100%);
25 --destructive: hsl(0 84% 60%);
26 --destructive-foreground: hsl(0 0% 100%);
27
28 /* Brand accent DESIGN/marketing surfaces only, never shipped in components */
29 --brand: hsl(239 84% 67%);
30 --brand-light: hsl(239 84% 74%);
31 --brand-foreground: hsl(0 0% 100%);
32
33 /* Borders & Inputs */
34 --border: hsl(240 4% 16%);
35 --input: hsl(240 4% 16%);
36 --ring: hsl(0 0% 56%);
37
38 /* Special Surfaces */
39 --nav: hsl(240 6% 4% / 0.8);
40 --code: hsl(240 6% 10%);
41 --code-highlight: hsl(0 0% 100% / 0.06);
42 --overlay: hsl(0 0% 0% / 0.5);
43
44 /* Terminal (always dark) */
45 --terminal: hsl(240 23% 15%);
46 --terminal-foreground: hsl(0 0% 98%);
47 --terminal-muted: hsl(240 5% 46%);
48 --terminal-border: hsl(0 0% 100% / 0.08);
49
50 /* Syntax Highlighting (dark) */
51 --syntax-keyword: hsl(286 60% 67%);
52 --syntax-string: hsl(95 38% 62%);
53 --syntax-function: hsl(207 82% 66%);
54 --syntax-component: hsl(207 82% 66%);
55 --syntax-prop: hsl(39 67% 69%);
56 --syntax-operator: hsl(187 47% 55%);
57 --syntax-punctuation: hsl(220 9% 73%);
58}

Light Theme

Light theme overrides the same custom properties via data-theme selector.

1[data-theme="light"] {
2 /* Surfaces */
3 --background: hsl(0 0% 100%);
4 --foreground: hsl(224 16% 14%);
5 --card: hsl(0 0% 100%);
6 --card-foreground: hsl(222 16% 14%);
7 --muted: hsl(0 0% 95.3%);
8 --muted-foreground: hsl(220 17% 17%);
9 --accent: hsl(240 5% 96.5%);
10 --accent-foreground: hsl(222 16% 14%);
11
12 /* Brand (monochrome near-black on light surfaces) */
13 --primary: hsl(240 6% 10%);
14 --primary-light: hsl(240 5% 26%);
15 --primary-foreground: hsl(0 0% 98%);
16 --secondary: hsl(189 85% 48%);
17 --secondary-foreground: hsl(224 16% 14%);
18
19 /* Semantic */
20 --success: hsl(142 76% 36%);
21 --success-foreground: hsl(0 0% 100%);
22 --info: hsl(217 91% 45%);
23 --info-foreground: hsl(0 0% 100%);
24 --destructive: hsl(0 72% 51%);
25 --destructive-foreground: hsl(0 0% 100%);
26
27 /* Brand accent DESIGN/marketing surfaces only, never shipped in components */
28 --brand: hsl(239 80% 66%);
29 --brand-light: hsl(239 70% 58%);
30 --brand-foreground: hsl(0 0% 100%);
31
32 /* Borders & Inputs */
33 --border: hsl(214 32% 91%);
34 --input: hsl(214 32% 91%);
35 --ring: hsl(0 0% 64%);
36
37 /* Special Surfaces */
38 --nav: hsl(0 0% 100% / 0.8);
39 --code: hsl(0 0% 100%);
40 --code-highlight: hsl(0 0% 0% / 0.05);
41 --overlay: hsl(0 0% 0% / 0.18);
42
43 /* Terminal (stays dark in light theme) */
44 --terminal: hsl(240 23% 15%);
45 --terminal-foreground: hsl(0 0% 98%);
46 --terminal-muted: hsl(240 5% 46%);
47 --terminal-border: hsl(0 0% 100% / 0.1);
48
49 /* Syntax Highlighting (light darker, more saturated for contrast) */
50 --syntax-keyword: hsl(286 72% 40%);
51 --syntax-string: hsl(120 50% 30%);
52 --syntax-function: hsl(210 90% 40%);
53 --syntax-component: hsl(210 90% 40%);
54 --syntax-prop: hsl(30 80% 38%);
55 --syntax-operator: hsl(187 70% 32%);
56 --syntax-punctuation: hsl(220 15% 40%);
57}

Usage in Components

Reference tokens through Tailwind utility classes.

1<div className="bg-background text-foreground">
2 <p className="text-muted-foreground">Muted text</p>
3 <div className="bg-primary/10 text-primary">
4 Primary with opacity
5 </div>
6 <div className="border border-border rounded-lg">
7 Bordered container
8 </div>
9</div>

Adding New Colors

Add a custom token in four steps: :root, light theme, @theme inline, then use it.

1/* 1. Add to :root */
2:root,
3[data-theme="dark"] {
4 --warning: hsl(38 92% 50%);
5}
6
7/* 2. Add to light theme */
8[data-theme="light"] {
9 --warning: hsl(38 92% 50%);
10}
11
12/* 3. Add to @theme inline */
13@theme inline {
14 --color-warning: var(--warning);
15}
16
17/* 4. Use in components */
18<div className="bg-warning text-white">Warning</div>