Theming
Customize Nimbus's look and feel with CSS variables. Create your own brand theme in minutes.
Introduction
Nimbus uses a CSS custom properties (variables) based theming system that makes it easy to customize every aspect of the design. Override a few variables for quick branding, or create entirely new themes by defining your own variable sets.
:root selector and can be overridden at any scope level for granular control.
The theming system is organized into several variable categories:
- Colors — Primary, secondary, semantic, and neutral color palettes
- Typography — Font families, sizes, weights, and line heights
- Spacing — Consistent spacing scale for padding and margins
- Shadows — Elevation and depth system
- Border Radius — Corner rounding scales
Color Variables
Nimbus provides a comprehensive color system organized into primary, secondary, semantic, and neutral color families.
Primary Colors
primary-50
var(--hu-primary-50)
primary-100
var(--hu-primary-100)
primary-200
var(--hu-primary-200)
primary-300
var(--hu-primary-300)
primary-400
var(--hu-primary-400)
primary-500
var(--hu-primary-500)
primary-600
var(--hu-primary-600)
primary-700
var(--hu-primary-700)
primary-800
var(--hu-primary-800)
primary-900
var(--hu-primary-900)
Semantic Colors
success
var(--hu-success-500)
warning
var(--hu-warning-500)
danger
var(--hu-danger-500)
info
var(--hu-info-500)
Color Variable Reference
| Variable | Default Value | Description |
|---|---|---|
--hu-primary-500 |
#2563eb |
Primary brand color |
--hu-secondary-500 |
#64748b |
Secondary/neutral accent |
--hu-success-500 |
#22c55e |
Success states |
--hu-warning-500 |
#f59e0b |
Warning states |
--hu-danger-500 |
#ef4444 |
Error/danger states |
--hu-info-500 |
#06b6d4 |
Informational elements |
--hu-neutral-50 |
#f8fafc |
Lightest background |
--hu-neutral-900 |
#0f172a |
Darkest text color |
Customizing Colors
Override any color variable by redefining it in your CSS. Variables cascade naturally, so you can override at :root for global changes or on specific elements for scoped changes.
Global Override
:root {
--hu-primary-500: #7c3aed;
--hu-primary-600: #6d28d9;
--hu-primary-700: #5b21b6;
}
Scoped Override
Green Scoped Card
This card has its own color scope.
.my-component {
--hu-primary-500: #059669;
--hu-primary-600: #047857;
}
/* All child elements using primary colors
will automatically use the new values */
Typography
Nimbus uses Inter for body text and JetBrains Mono for code blocks. Customize the type system with these variables.
Font Variables
| Variable | Default Value | Description |
|---|---|---|
--hu-font-sans |
"Inter", sans-serif |
Primary font family |
--hu-font-mono |
"JetBrains Mono", monospace |
Monospace font for code |
--hu-text-xs |
0.75rem |
Extra small text (12px) |
--hu-text-sm |
0.875rem |
Small text (14px) |
--hu-text-base |
1rem |
Base text (16px) |
--hu-text-lg |
1.125rem |
Large text (18px) |
--hu-text-xl |
1.25rem |
Extra large text (20px) |
--hu-text-2xl |
1.5rem |
2x large text (24px) |
--hu-text-3xl |
1.875rem |
3x large text (30px) |
--hu-text-4xl |
2.25rem |
4x large text (36px) |
Font Weight Variables
Regular (400) — Quick brown fox jumps over the lazy dog
Medium (500) — Quick brown fox jumps over the lazy dog
Semibold (600) — Quick brown fox jumps over the lazy dog
Bold (700) — Quick brown fox jumps over the lazy dog
:root {
--hu-font-normal: 400;
--hu-font-medium: 500;
--hu-font-semibold: 600;
--hu-font-bold: 700;
--hu-leading-tight: 1.25;
--hu-leading-normal: 1.5;
--hu-leading-relaxed: 1.75;
}
Spacing
A consistent spacing scale ensures visual harmony across your UI. All spacing values follow a base-4 scale.
Spacing Scale
0.125rem
0.25rem
0.5rem
0.75rem
1rem
1.5rem
2rem
3rem
4rem
6rem
:root {
--hu-space-0: 0;
--hu-space-0-5: 0.125rem; /* 2px */
--hu-space-1: 0.25rem; /* 4px */
--hu-space-1-5: 0.375rem; /* 6px */
--hu-space-2: 0.5rem; /* 8px */
--hu-space-3: 0.75rem; /* 12px */
--hu-space-4: 1rem; /* 16px */
--hu-space-5: 1.25rem; /* 20px */
--hu-space-6: 1.5rem; /* 24px */
--hu-space-8: 2rem; /* 32px */
--hu-space-10: 2.5rem; /* 40px */
--hu-space-12: 3rem; /* 48px */
--hu-space-16: 4rem; /* 64px */
--hu-space-20: 5rem; /* 80px */
--hu-space-24: 6rem; /* 96px */
}
Shadows
The shadow system provides elevation levels for cards, modals, dropdowns, and other layered elements.
Shadow Levels
:root {
--hu-shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.05);
--hu-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1);
--hu-shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
--hu-shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
--hu-shadow-xl: 0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1);
--hu-shadow-2xl: 0 25px 50px -12px rgb(0 0 0 / 0.25);
}
Border Radius
Control the roundness of corners across your UI with consistent radius values.
Radius Scale
:root {
--hu-radius-none: 0;
--hu-radius-sm: 0.125rem; /* 2px */
--hu-radius: 0.25rem; /* 4px */
--hu-radius-md: 0.375rem; /* 6px */
--hu-radius-lg: 0.5rem; /* 8px */
--hu-radius-xl: 0.75rem; /* 12px */
--hu-radius-2xl: 1rem; /* 16px */
--hu-radius-full: 9999px;
}
Dark Mode
Nimbus's dark mode works by swapping CSS variable values when the data-theme attribute is set to "dark". This approach means your custom themes automatically support dark mode.
How It Works
Default appearance
Inverted palette
[data-theme="dark"] {
--hu-bg-primary: #0f172a;
--hu-bg-secondary: #1e293b;
--hu-bg-tertiary: #334155;
--hu-text-primary: #f1f5f9;
--hu-text-secondary: #cbd5e1;
--hu-text-muted: #94a3b8;
--hu-border-primary: #334155;
--hu-border-secondary: #475569;
}
Customizing Dark Mode
/* Override dark mode colors for your brand */
[data-theme="dark"] {
--hu-primary-500: #818cf8;
--hu-primary-600: #6366f1;
--hu-bg-primary: #1a1a2e;
--hu-bg-secondary: #16213e;
}
/* Or use OS preference with a media query fallback */
@media (prefers-color-scheme: dark) {
:root:not([data-theme="light"]) {
--hu-bg-primary: #0f172a;
}
}
Creating Themes
Create reusable themes by namespacing your CSS variables under a class or attribute selector. This allows users to switch between themes dynamically.
Theme Structure
/* Define a theme using a data attribute */
[data-theme="blue"] {
--hu-primary-50: #eff6ff;
--hu-primary-100: #dbeafe;
--hu-primary-200: #bfdbfe;
--hu-primary-300: #93c5fd;
--hu-primary-400: #60a5fa;
--hu-primary-500: #3b82f6;
--hu-primary-600: #2563eb;
--hu-primary-700: #1d4ed8;
--hu-primary-800: #1e40af;
--hu-primary-900: #1e3a8a;
}
[data-theme="green"] {
--hu-primary-50: #f0fdf4;
--hu-primary-100: #dcfce7;
--hu-primary-500: #22c55e;
--hu-primary-600: #16a34a;
--hu-primary-700: #15803d;
}
/* Apply theme to a container */
.theme-blue { /* or [data-theme="blue"] */ }
.theme-green { /* or [data-theme="green"] */ }
Switching Themes
// Theme switcher JavaScript
function setTheme(themeName) {
document.documentElement.setAttribute('data-theme', themeName);
localStorage.setItem('hu-theme', themeName);
}
// Load saved theme
const savedTheme = localStorage.getItem('hu-theme') || 'blue';
setTheme(savedTheme);
// Theme selector UI
document.querySelectorAll('[data-theme-btn]').forEach(btn => {
btn.addEventListener('click', () => {
setTheme(btn.dataset.themeBtn);
});
});
Brand Theme Examples
Here are three complete brand themes showing how a full set of variables transforms the entire UI.
Blue / Corporate Theme
[data-theme="blue"] {
--hu-primary-50: #eff6ff;
--hu-primary-100: #dbeafe;
--hu-primary-200: #bfdbfe;
--hu-primary-300: #93c5fd;
--hu-primary-400: #60a5fa;
--hu-primary-500: #3b82f6;
--hu-primary-600: #2563eb;
--hu-primary-700: #1d4ed8;
--hu-primary-800: #1e40af;
--hu-primary-900: #1e3a8a;
--hu-bg-primary: #ffffff;
--hu-bg-secondary: #f8fafc;
--hu-text-primary: #0f172a;
--hu-text-secondary: #475569;
--hu-border-primary: #e2e8f0;
}
Green / Eco-Friendly Theme
[data-theme="green"] {
--hu-primary-50: #f0fdf4;
--hu-primary-100: #dcfce7;
--hu-primary-200: #bbf7d0;
--hu-primary-300: #86efac;
--hu-primary-400: #4ade80;
--hu-primary-500: #22c55e;
--hu-primary-600: #16a34a;
--hu-primary-700: #15803d;
--hu-primary-800: #166534;
--hu-primary-900: #14532d;
--hu-bg-primary: #ffffff;
--hu-bg-secondary: #f0fdf4;
--hu-text-primary: #14532d;
--hu-text-secondary: #166534;
--hu-border-primary: #dcfce7;
}
Dark / Premium Theme
[data-theme="dark"] {
--hu-primary-50: #faf5ff;
--hu-primary-100: #f3e8ff;
--hu-primary-200: #e9d5ff;
--hu-primary-300: #d8b4fe;
--hu-primary-400: #c084fc;
--hu-primary-500: #a855f7;
--hu-primary-600: #9333ea;
--hu-primary-700: #7e22ce;
--hu-primary-800: #6b21a8;
--hu-primary-900: #581c87;
--hu-bg-primary: #0f0f1a;
--hu-bg-secondary: #1a1a2e;
--hu-bg-tertiary: #252540;
--hu-text-primary: #f1f5f9;
--hu-text-secondary: #cbd5e1;
--hu-text-muted: #94a3b8;
--hu-border-primary: #2e2e4a;
--hu-border-secondary: #3d3d5c;
}