Design Tokens
Last updated on 2026-05-31
The SaaS Metrics Kit uses oklch color tokens defined as CSS custom properties in app/globals.css. All components reference these tokens through Tailwind CSS v4 -- never hardcoded colors. The kit ships with a deep blue-violet theme (oklch hue 260) and a golden secondary accent (hue 71).
oklch Color System
The kit uses oklch (Oklab Lightness Chroma Hue) instead of hex or hsl:
- Perceptually uniform -- equal steps in lightness look equal to the human eye, so your palette looks balanced without manual tweaking
- Wider gamut -- access to more vibrant colors on modern displays (P3, Rec. 2020)
- Easy palette generation -- change one hue angle to produce a cohesive brand palette across all semantic tokens
The format is oklch(lightness chroma hue) where lightness is 0-1, chroma is 0-0.4 (saturation intensity), and hue is 0-360 (color angle on the color wheel).
Color Tokens
Semantic color tokens that automatically adapt between light and dark mode:
:root {
--background: oklch(0.99 0.002 260);
--foreground: oklch(0.17 0.02 260);
--card: oklch(1 0 0);
--card-foreground: oklch(0.17 0.02 260);
--popover: oklch(1 0 0);
--popover-foreground: oklch(0.17 0.02 260);
--primary: oklch(0.45 0.2 260);
--primary-foreground: oklch(0.98 0.005 260);
--secondary: oklch(0.78 0.14 71);
--secondary-foreground: oklch(0.25 0.05 71);
--muted: oklch(0.96 0.005 260);
--muted-foreground: oklch(0.4 0.03 260);
--accent: oklch(0.94 0.02 260);
--accent-foreground: oklch(0.35 0.15 260);
--destructive: oklch(0.58 0.22 27);
--border: oklch(0.91 0.01 260);
--input: oklch(0.91 0.01 260);
--ring: oklch(0.55 0.18 260);
}
Dark Mode Tokens
.dark {
--background: oklch(0.16 0.02 260);
--foreground: oklch(0.96 0.005 260);
--card: oklch(0.21 0.025 260);
--card-foreground: oklch(0.96 0.005 260);
--popover: oklch(0.21 0.025 260);
--popover-foreground: oklch(0.96 0.005 260);
--primary: oklch(0.7 0.18 260);
--primary-foreground: oklch(0.15 0.02 260);
--secondary: oklch(0.72 0.14 71);
--secondary-foreground: oklch(0.18 0.04 71);
--muted: oklch(0.27 0.025 260);
--muted-foreground: oklch(0.7 0.03 260);
--accent: oklch(0.32 0.05 260);
--accent-foreground: oklch(0.92 0.01 260);
--destructive: oklch(0.704 0.191 22.216);
--border: oklch(1 0 0 / 12%);
--input: oklch(1 0 0 / 15%);
--ring: oklch(0.6 0.16 260);
}
Sidebar Tokens
Dedicated tokens for the dashboard sidebar navigation:
:root {
--sidebar: oklch(0.97 0.008 260);
--sidebar-foreground: oklch(0.17 0.02 260);
--sidebar-primary: oklch(0.45 0.2 260);
--sidebar-primary-foreground: oklch(0.98 0.005 260);
--sidebar-accent: oklch(0.93 0.025 260);
--sidebar-accent-foreground: oklch(0.35 0.15 260);
--sidebar-border: oklch(0.91 0.01 260);
--sidebar-ring: oklch(0.55 0.18 260);
}
.dark {
--sidebar: oklch(0.19 0.025 260);
--sidebar-foreground: oklch(0.96 0.005 260);
--sidebar-primary: oklch(0.7 0.18 260);
--sidebar-primary-foreground: oklch(0.15 0.02 260);
--sidebar-accent: oklch(0.28 0.04 260);
--sidebar-accent-foreground: oklch(0.92 0.01 260);
--sidebar-border: oklch(1 0 0 / 12%);
--sidebar-ring: oklch(0.6 0.16 260);
}
Chart Colors
Five chart-specific color tokens used by all Recharts components across analytics and management screens:
:root {
--chart-1: oklch(0.55 0.2 260); /* Blue-violet (primary) */
--chart-2: oklch(0.75 0.14 71); /* Gold */
--chart-3: oklch(0.65 0.2 146); /* Green */
--chart-4: oklch(0.6 0.18 326); /* Magenta */
--chart-5: oklch(0.7 0.15 196); /* Teal */
}
.dark {
--chart-1: oklch(0.7 0.18 260);
--chart-2: oklch(0.72 0.14 71);
--chart-3: oklch(0.65 0.2 146);
--chart-4: oklch(0.65 0.18 326);
--chart-5: oklch(0.7 0.15 196);
}
Usage in Tailwind
Tokens map directly to Tailwind utility classes. Use them like standard Tailwind colors:
<div className="bg-background text-foreground border-border">
<button className="bg-primary text-primary-foreground">
View Revenue
</button>
<span className="text-muted-foreground">Last updated 2 hours ago</span>
<div className="bg-sidebar text-sidebar-foreground">
Sidebar content
</div>
</div>
Charts reference tokens via CSS variables:
<Area
type="monotone"
dataKey="mrr"
stroke="var(--chart-1)"
fill="var(--chart-1)"
fillOpacity={0.15}
/>
Dark Mode
The kit uses next-themes with class-based dark mode. The ThemeToggle component handles the switch:
import { ThemeToggle } from "@/components/layout/theme-toggle"
<ThemeToggle />
Dark mode values are defined in the .dark selector within globals.css. All semantic tokens automatically switch when the theme changes. The ThemeToggle component includes proper aria-label text that updates to reflect the current action ("Switch to light mode" / "Switch to dark mode").
Typography
The kit uses three font families configured in app/layout.tsx:
| Token | Font | Usage |
|---|---|---|
--font-sans |
Inter | Body text |
--font-heading |
DM Sans | Headings (h1-h6) |
--font-mono |
JetBrains Mono | Code blocks, invoice numbers |
Headings use tighter letter-spacing (-0.025em) and shorter line-height (1.2) for visual weight. Body text uses -0.011em letter-spacing with 1.6 line-height for readability.
Border Radius
The kit uses a base --radius value of 0.625rem with computed variants:
| Token | Computed Value |
|---|---|
--radius-sm |
0.375rem (radius * 0.6) |
--radius-md |
0.5rem (radius * 0.8) |
--radius-lg |
0.625rem (base radius) |
--radius-xl |
0.875rem (radius * 1.4) |
--radius-2xl |
1.125rem (radius * 1.8) |
--radius-3xl |
1.375rem (radius * 2.2) |
--radius-4xl |
1.625rem (radius * 2.6) |
Animation Tokens
The kit includes custom keyframe animations defined in globals.css:
| Class | Keyframe | Duration | Use Case |
|---|---|---|---|
animate-fade-in-up |
fade-in-up |
0.5s | Page section entrances |
animate-fade-in |
fade-in |
0.4s | Element appearances |
animate-scale-in |
scale-in |
0.3s | Card/modal entrances |
animate-float |
float |
6s (loop) | Landing page decorative elements |
animate-shimmer |
shimmer |
1.5s (loop) | Loading state placeholders |
Stagger delay utilities (.stagger-1 through .stagger-6) add 100ms increments for sequenced entrance animations.
Customizing for Your Brand
To rebrand the kit, change the hue value in app/globals.css. The default theme uses hue 260. Update it to your brand color and all 25 screens adapt automatically:
:root {
/* Change hue from 260 (blue-violet) to 150 (green) */
--primary: oklch(0.45 0.2 150);
--primary-foreground: oklch(0.98 0 0);
--ring: oklch(0.55 0.18 150);
/* Update remaining tokens to match... */
}
.dark {
--primary: oklch(0.7 0.18 150);
--primary-foreground: oklch(0.15 0.02 150);
/* ... */
}
All components automatically inherit the new palette -- buttons, badges, links, charts, sidebar accents, status indicators, and focus rings all update at once.
For full customization details, see the Customization guide.