Colors
Basalt UI uses warm basalt colored neutrals meeting expressive accents. Our color system uses foundation colors defined once and referenced everywhere—change one value, update your entire interface.
Foundation Palette
Base neutral tones (light/dark) defined once. All semantic tokens reference these values—simple, consistent, maintainable.
Blue + Expressive Colors
Professional blue for actions and links. Expressive colors for errors, success, and warnings. Same values work in light and dark modes.
Always Pair Foreground
Every background has a foreground token for accessible contrast. Use bg-blue text-blue-foreground together.
Foundation Palette
Core neutral tones defined once and reused everywhere. Change --light-2
→ updates background across the entire system.
Light Tones
Light mode backgrounds, dark mode text, elevated surfaces
Light 1
--light-1Cards, popovers, overlays
Light 2
--light-2Main background (light mode)
Light 3
--light-3Muted, disabled states
Light 4
--light-4Borders, inputs
Dark Tones
Dark mode backgrounds, light mode text
Dark 1
--dark-1Near-black, reserved
Dark 2
--dark-2Main background (dark mode)
Dark 3
--dark-3Cards (dark mode)
Dark 4
--dark-4Borders, muted (dark mode)
Blue Primary
Professional blue accent for actions, links, and interactive elements
Blue
--bluePrimary actions, links, focus
Blue Light
--blue-lightHover states, highlights
Blue Deep
--blue-deepStrong emphasis
Expressive Colors
Semantic colors for errors, warnings, success, and special states
Red
--redErrors, destructive actions
Orange
--orangeWarnings, moderate alerts
Yellow
--yellowCaution, highlights
Green
--greenSuccess, confirmations
Purple
--purpleSpecial features
Why Foundation Colors?
- DRY: Each OKLCH value defined once, referenced everywhere
- Consistency: All semantic tokens use same base
- Maintainability: Change once, update entire system
- Clarity: Foundation → Semantic → UI hierarchy
Sequential Chart Palette
Constant hue (249°) with progressive lightness and gradually increasing chroma. All adjacent colors exceed WCAG 3:1 contrast.
Sequential Chart Palette
Eight perceptually uniform blue tones for sequential data
Blue 1
--chart-blue-1Blue 2
--chart-blue-2Blue 3
--chart-blue-3Blue 4
--chart-blue-4Blue 5
--chart-blue-5Blue 6
--chart-blue-6Blue 7
--chart-blue-7Blue 8
--chart-blue-8Use Cases
- Sequential data: temperature scales, density maps, intensity visualization
- Gradient backgrounds: from subtle (blue-1) to prominent (blue-8)
- Perceptually uniform: equal perceived steps between colors
Semantic Color Tokens
Meaningful names for UI elements that reference the foundation palette. These automatically switch between light and dark modes.
--background Main page background
--foreground Primary text color
--primary Actions, links, focus
--secondary Alternative actions
--accent Hover states
--destructive Errors, delete actions
--muted Disabled states
--card Card surfaces
--border Borders, dividers
Text Color Pairing
Every background color has a corresponding foreground token ensuring accessible contrast.
Light Text (White)
bg-primary text-primary-foregroundbg-blue text-blue-foregroundbg-red text-red-foregroundbg-purple text-purple-foreground
Dark Text
bg-background text-foregroundbg-orange text-orange-foregroundbg-yellow text-yellow-foregroundbg-green text-green-foreground
Best Practices
- Always use foreground tokens for automatic dark mode support
- All pairs meet WCAG AA standards (4.5:1 for text)
Usage Guidelines
- • Use semantic color tokens (bg-primary, text-muted-foreground)
- • Rely on automatic dark mode switching via .dark class
- • Use blue (primary) for interactive elements and links
- • Use expressive colors for semantic states (red = error, green = success)
- • Always pair background colors with their foreground tokens
- • Don't use arbitrary color values (bg-[#f3f3f3])
- • Don't use HSL or RGB colors (breaks OKLCH benefits)
- • Don't use red for non-error states
- • Don't manually handle dark mode (system does it automatically)
- • Don't use text-white or hardcoded colors - use foreground tokens
Implementation
.component {
background: var(--background);
color: var(--foreground);
border: 1px solid var(--border);
}
.button {
background: var(--primary);
color: var(--primary-foreground);
}
.button:hover {
background: var(--accent);
color: var(--accent-foreground);
} <!-- Main layout --> <div class="bg-background text-foreground"> <!-- Primary button --> <button class="bg-primary text-primary-foreground"> Click me </button> <!-- Card surface --> <div class="bg-card text-card-foreground border-border"> Card content </div> <!-- Error state --> <div class="bg-destructive text-destructive-foreground"> Error message </div>
OKLCH Color Space
L (Lightness)
0-1 scale. Changes correspond to perceived brightness—no unexpected gray zones.
C (Chroma)
Saturation matching human perception. Consistent across different hues.
H (Hue)
Color angle (0-360). 249° = blue, 15° = red, 84° = yellow, 131° = green.
Why OKLCH?
- Perceptually uniform—gradients stay clean and predictable
- Better accessibility—easier to maintain proper contrast ratios
- Consistent saturation across hues