Skip to content
Drivn logoDrivn

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.

1npx 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-dark: var(--primary-dark);
16 --color-primary-foreground: var(--primary-foreground);
17 --color-secondary: var(--secondary);
18 --color-secondary-foreground: var(--secondary-foreground);
19
20 /* Semantic */
21 --color-destructive: var(--destructive);
22 --color-destructive-foreground: var(--destructive-foreground);
23 --color-success: var(--success);
24 --color-success-foreground: var(--success-foreground);
25
26 /* Borders & Inputs */
27 --color-border: var(--border);
28 --color-input: var(--input);
29
30 /* Special Surfaces */
31 --color-nav: var(--nav);
32 --color-code: var(--code);
33 --color-overlay: var(--overlay);
34
35 /* Terminal (always dark-on-dark) */
36 --color-terminal: var(--terminal);
37 --color-terminal-foreground: var(--terminal-foreground);
38 --color-terminal-muted: var(--terminal-muted);
39 --color-terminal-border: var(--terminal-border);
40 --color-terminal-header: var(--terminal-header);
41 --color-terminal-accent: var(--terminal-accent);
42 --color-terminal-accent-border: var(--terminal-accent-border);
43
44 /* Syntax Highlighting */
45 --color-syntax-keyword: var(--syntax-keyword);
46 --color-syntax-string: var(--syntax-string);
47 --color-syntax-function: var(--syntax-function);
48 --color-syntax-component: var(--syntax-component);
49 --color-syntax-prop: var(--syntax-prop);
50 --color-syntax-operator: var(--syntax-operator);
51 --color-syntax-punctuation: var(--syntax-punctuation);
52}

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

Brand

primary

bg-primary

primary-light

bg-primary-light

primary-dark

bg-primary-dark

secondary

bg-secondary

Semantic

success

bg-success

destructive

bg-destructive

Borders & Inputs

border

bg-border

input

bg-input

Special Surfaces

nav

bg-nav

code

bg-code

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 */
14 --primary: hsl(239 84% 67%);
15 --primary-light: hsl(239 84% 74%);
16 --primary-dark: hsl(243 75% 59%);
17 --primary-foreground: hsl(0 0% 100%);
18 --secondary: hsl(189 94% 53%);
19 --secondary-foreground: hsl(0 0% 100%);
20
21 /* Semantic */
22 --success: hsl(142 71% 59%);
23 --success-foreground: hsl(0 0% 100%);
24 --destructive: hsl(0 84% 60%);
25 --destructive-foreground: hsl(0 0% 100%);
26
27 /* Borders & Inputs */
28 --border: hsl(240 4% 16%);
29 --input: hsl(240 4% 16%);
30
31 /* Special Surfaces */
32 --nav: hsl(240 6% 4% / 0.8);
33 --code: hsl(240 6% 10%);
34 --overlay: hsl(0 0% 0% / 0.5);
35
36 /* Terminal (always dark) */
37 --terminal: hsl(240 23% 15%);
38 --terminal-foreground: hsl(0 0% 98%);
39 --terminal-muted: hsl(240 5% 46%);
40 --terminal-border: hsl(0 0% 100% / 0.08);
41 --terminal-header: hsl(0 0% 100% / 0.02);
42 --terminal-accent: hsl(239 84% 67% / 0.08);
43 --terminal-accent-border: hsl(239 84% 67% / 0.2);
44 --terminal-shadow: 0 0 0 1px hsl(0 0% 100% / 0.05), 0 20px 50px -10px hsl(0 0% 0% / 0.5), 0 0 80px -20px hsl(239 84% 67% / 0.3);
45
46 /* Syntax Highlighting (dark) */
47 --syntax-keyword: hsl(286 60% 67%);
48 --syntax-string: hsl(95 38% 62%);
49 --syntax-function: hsl(207 82% 66%);
50 --syntax-component: hsl(207 82% 66%);
51 --syntax-prop: hsl(39 67% 69%);
52 --syntax-operator: hsl(187 47% 55%);
53 --syntax-punctuation: hsl(220 9% 73%);
54}

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(222 47% 11%);
5 --card: hsl(0 0% 100%);
6 --card-foreground: hsl(222 47% 11%);
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 47% 11%);
11
12 /* Brand */
13 --primary: hsl(239 84% 50%);
14 --primary-light: hsl(239 84% 57%);
15 --primary-dark: hsl(243 75% 43%);
16 --primary-foreground: hsl(0 0% 100%);
17 --secondary: hsl(189 90% 36%);
18 --secondary-foreground: hsl(0 0% 100%);
19
20 /* Semantic */
21 --success: hsl(142 76% 36%);
22 --success-foreground: hsl(0 0% 100%);
23 --destructive: hsl(0 72% 51%);
24 --destructive-foreground: hsl(0 0% 100%);
25
26 /* Borders & Inputs */
27 --border: hsl(214 32% 91%);
28 --input: hsl(214 32% 91%);
29
30 /* Special Surfaces */
31 --nav: hsl(0 0% 100% / 0.8);
32 --code: hsl(0 0% 100%);
33 --overlay: hsl(0 0% 0% / 0.18);
34
35 /* Terminal (stays dark in light theme) */
36 --terminal: hsl(240 23% 15%);
37 --terminal-foreground: hsl(0 0% 98%);
38 --terminal-muted: hsl(240 5% 46%);
39 --terminal-border: hsl(0 0% 100% / 0.1);
40 --terminal-header: hsl(0 0% 100% / 0.04);
41 --terminal-accent: hsl(239 84% 67% / 0.12);
42 --terminal-accent-border: hsl(239 84% 67% / 0.25);
43 --terminal-shadow: 0 0 0 1px hsl(0 0% 0% / 0.08), 0 20px 50px -10px hsl(0 0% 0% / 0.15), 0 0 80px -20px hsl(239 84% 67% / 0.15);
44
45 /* Syntax Highlighting (light darker, more saturated for contrast) */
46 --syntax-keyword: hsl(286 72% 40%);
47 --syntax-string: hsl(120 50% 30%);
48 --syntax-function: hsl(210 90% 40%);
49 --syntax-component: hsl(210 90% 40%);
50 --syntax-prop: hsl(30 80% 38%);
51 --syntax-operator: hsl(187 70% 32%);
52 --syntax-punctuation: hsl(220 15% 40%);
53}

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>