You need three colors in your Tailwind config. Here's how to set them up for both v4 and v3 so the 60-30-10 split is baked into your utility classes.
This is the only page that shows both formats in full. Other Tailwind docs focus on one version — if you're migrating or supporting both, bookmark this.
The palette
A SaaS dashboard palette built around the 60-30-10 rule:
| Role | Hex | Usage |
|------|-----|-------|
| Dominant (60%) | #f8fafc | Page backgrounds, card surfaces, content area |
| Secondary (30%) | #1e293b | Sidebar, navigation, headers, footers |
| Accent (10%) | #3b82f6 | Buttons, links, active states, badges |
The logic: the accent only appears on interactive elements. Because it's rare, users immediately recognize it as "act here." When accent fills more than 10% of the surface area, it stops signaling anything.
Tailwind v4: @theme block
Tailwind v4 moves color tokens into CSS — no JS config needed (official @theme docs). Add this block to your globals.css:
@theme {
--color-dominant: #f8fafc;
--color-secondary: #1e293b;
--color-accent: #3b82f6;
}
That's it. Tailwind v4 registers every utility class automatically: bg-dominant, text-secondary, bg-accent, border-accent, and all opacity variants (bg-accent/50, etc.).
No tailwind.config.ts changes required. The CSS file is the config.
Tailwind v3: tailwind.config.js
For Tailwind v3 projects, extend the colors key (v3 customizing colors docs):
module.exports = {
theme: {
extend: {
colors: {
dominant: '#f8fafc',
secondary: '#1e293b',
accent: '#3b82f6',
},
},
},
}
Or in TypeScript:
import type { Config } from "tailwindcss";
const config: Config = {
theme: {
extend: {
colors: {
dominant: "#f8fafc",
secondary: "#1e293b",
accent: "#3b82f6",
},
},
},
};
export default config;
Same utility classes result: bg-dominant, text-secondary, bg-accent.
When to use which
Use v4 @theme for new projects. It's CSS-native, eliminates a JS config file, and plays well with modern tooling. If you're starting from scratch today, use v4.
Use v3 module.exports for existing codebases. Migrating from v3 to v4 is a breaking change — no need to do it just to add colors. Keep v3 until you're ready to migrate the whole project.
The utility class names are identical in both. You can share JSX components across both setups without changes.
Using the utility classes in JSX
Once configured, the color tokens become Tailwind utilities everywhere in your project:
export default function DashboardLayout({ children }: { children: React.ReactNode }) {
return (
<div className="flex h-screen bg-dominant">
{/* Sidebar — secondary color (30%) */}
<aside className="w-64 bg-secondary flex flex-col gap-1 px-3 py-4">
<span className="text-dominant font-semibold px-3 mb-2">Acme</span>
<a
href="/dashboard"
className="flex items-center gap-2 px-3 py-2 rounded-md
text-dominant bg-accent/20 text-accent font-medium"
>
Dashboard
</a>
<a
href="/projects"
className="flex items-center gap-2 px-3 py-2 rounded-md
text-dominant/60 hover:text-dominant"
>
Projects
</a>
</aside>
{/* Main — dominant color (60%) */}
<main className="flex-1 flex flex-col">
<header className="h-14 bg-secondary/10 border-b border-secondary/20
flex items-center justify-between px-6">
<h1 className="text-secondary font-semibold">Dashboard</h1>
{/* Primary CTA — accent color (10%) */}
<button className="bg-accent text-white px-4 py-2 rounded-md text-sm font-medium">
New project
</button>
</header>
<div className="flex-1 p-6">{children}</div>
</main>
</div>
);
}
The accent color (bg-accent) only appears twice: the active nav indicator and the primary CTA button. That scarcity is intentional — it's what makes the button stand out without extra styling work.
Extending beyond 3 colors
The 60-30-10 structure doesn't mean you're locked to exactly three utility names. You can add tonal variants while keeping the proportional logic:
/* Tailwind v4 */
@theme {
--color-dominant: #f8fafc;
--color-secondary: #1e293b;
--color-accent: #3b82f6;
/* Tonal variants — still part of the accent "role" */
--color-accent-light: #93c5fd;
--color-accent-dark: #1d4ed8;
/* Surface variants for layered UIs */
--color-dominant-subtle: #f1f5f9;
}
The rule to preserve: accent tokens should still cover only ~10% of rendered surface area. Adding accent-light and accent-dark is fine as long as you use them sparingly — hover states, focus rings, secondary badges — not as decorative fills.
Generator tie-in
The generator at sixtythirtyten.co outputs both formats when you download a palette. The ZIP includes a @theme CSS file for v4 and a tailwind.config.js for v3 — both pre-filled with your generated colors. Drop either file into your project and the utility classes are ready.
For the framework-agnostic CSS approach (no Tailwind dependency), see the CSS variables cheat sheet.
For dark mode palette variants (including how to wire @theme with a .dark class swap), see 60-30-10 Dark Mode Color Palette.
For dashboard-specific extensions (status colors, chart palette), see SaaS Dashboard Color Palette.
For the foundational logic behind the 60-30-10 split, see The 60-30-10 Rule: A Developer's Guide to UI Color Balance.
Your palette, your utility classes — ready to drop in.
Generate your palette at sixtythirtyten.co →
Enter one color and get a matching 60-30-10 palette with the Tailwind v4 and v3 configs already written.