docs/react/ui/colors.mdx
Spacedrive uses a semantic color system built on CSS variables and HSL values. The system provides context-aware colors that automatically support theming and opacity modifiers.
Colors are defined as HSL triplets (hue, saturation, lightness) in CSS variables, then referenced via Tailwind's alpha() function for opacity support.
/* Definition */
--color-accent: 208, 100%, 57%;
/* Usage in Tailwind */
bg-accent /* hsla(var(--color-accent), 1) */
bg-accent/50 /* hsla(var(--color-accent), 0.5) */
This approach enables:
/10, /20, /50, etc.)Primary brand colors for interactive elements.
<div className="bg-accent text-white">
Primary action button
</div>
<div className="border border-accent/20 bg-accent/5">
Subtle accent background
</div>
Variants:
accent - Default accent (220, 90%, 56%)Hierarchical text colors for content.
<h1 className="text-ink">Primary heading</h1>
<p className="text-ink-dull">Secondary text</p>
<span className="text-ink-faint">Tertiary/disabled text</span>
Hierarchy:
ink - Primary text (92% lightness)ink-dull - Secondary text (70% lightness)ink-faint - Tertiary text (55% lightness)Main application area colors for backgrounds, borders, and surfaces.
<div className="bg-app border border-app-line">
<div className="bg-app-box">
Card or panel
</div>
<input className="bg-app-input border-app-line" />
<button className="hover:bg-app-hover active:bg-app-selected">
Interactive element
</button>
</div>
Color Scale:
app - Base background (235, 15%, 13%)app-box - Card/panel background (235, 15%, 18%)app-overlay - Overlay background (235, 15%, 16%)app-line - Border color (235, 15%, 23%)app-frame - Frame border (235, 15%, 25%)Use Case Examples:
// Layered cards
<div className="bg-app">
<div className="bg-app-box border border-app-line">
<div className="bg-app-dark-box">
Nested content
</div>
</div>
</div>
// Interactive elements
<button className="bg-app-button border-app-line hover:bg-app-hover">
Button
</button>
// Form inputs
<input className="bg-app-input border-app-line focus:bg-app-focus" />
Sidebar-specific colors that can differ from main app area.
<aside className="bg-sidebar">
<nav className="bg-sidebar-box border-sidebar-line">
<a className="text-sidebar-ink hover:bg-sidebar-selected">
Nav item
</a>
</nav>
</aside>
Scale:
sidebar - Base (235, 15%, 7%)sidebar-box - Panels (235, 15%, 16%)sidebar-line - Borders (235, 15%, 23%)sidebar-selected - Selected state (235, 15%, 24%)sidebar-button - Button background (235, 15%, 18%)sidebar-divider - Dividers (235, 15%, 17%)sidebar-ink / sidebar-ink-dull / sidebar-ink-faint - Text hierarchyContext menu and dropdown colors.
<div className="bg-menu border-menu-line">
<button className="text-menu-ink hover:bg-menu-hover">
Menu item
</button>
</div>
Scale:
menu - Base (235, 15%, 13%)menu-line - Borders (235, 15%, 23%)menu-hover - Hover state (235, 15%, 20%)menu-selected - Selected state (235, 15%, 24%)menu-shade - Shadow (235, 15%, 8%)menu-ink - Primary text (235, 15%, 92%)menu-faint - Secondary text (235, 10%, 55%)Uses --dark-hue: 235 with low lightness values.
Add .vanilla-theme class to root for light mode. Uses --light-hue: 235 with high lightness values.
<html className="vanilla-theme">
</html>
The same color classes (text-ink, bg-app-box, etc.) automatically adapt to the theme.
Create custom themes by defining a new class with color overrides:
.custom-theme {
--dark-hue: 280; /* Purple-tinted theme */
--color-accent: 280, 100%, 60%;
/* Other color overrides */
}
Don't use raw colors:
<div className="bg-gray-800 text-gray-200">
Use semantic colors:
<div className="bg-app-box text-ink">
Don't mix contexts unnecessarily:
<div className="bg-sidebar">
<p className="text-app-ink">
</div>
Use matching context:
<div className="bg-sidebar">
<p className="text-sidebar-ink">
</div>
Don't hardcode alpha values:
<div style={{ backgroundColor: 'rgba(...)' }}>
Use Tailwind opacity:
<div className="bg-accent/10">
<button className="
bg-app-button
border-app-line
hover:bg-app-hover
active:bg-app-selected
focus:ring-accent
">
Button with full interaction states
</button>
Accent:
accent, accent-faint, accent-deepText:
ink, ink-dull, ink-faintApp:
app, app-box, app-dark-box, app-darker-box, app-light-boxapp-input, app-focus, app-buttonapp-line, app-dividerapp-hover, app-selected, app-activeapp-overlay, app-shade, app-frame, app-sliderSidebar:
sidebar, sidebar-box, sidebar-linesidebar-ink, sidebar-ink-dull, sidebar-ink-faintsidebar-divider, sidebar-button, sidebar-selected, sidebar-shadeMenu:
menu, menu-line, menu-hover, menu-selectedmenu-ink, menu-faint, menu-shadeIf you have code using generic Tailwind colors, migrate to semantic names:
| Old | New |
|---|---|
text-white | text-ink |
text-gray-400 | text-ink-dull |
text-gray-500 | text-ink-faint |
bg-gray-800 | bg-app-box |
bg-gray-900 | bg-app |
border-gray-700 | border-app-line |
hover:bg-gray-700 | hover:bg-app-hover |
This ensures your UI automatically adapts to theme changes.