Theme
Three modes are available:
Your choice is stored in
localStorage under the theme key. “System” is resolved via window.matchMedia('(prefers-color-scheme: light)'); the resolved value (light or dark, never system itself) is written to a data-theme attribute on <html>, which is what Orbit’s CSS actually keys off.
Accent color
Eleven accent options are available: Default (Orbit’s original purple) plus ten colors — red, orange, yellow, green, lime, blue, sky, violet, purple, and pink. Your choice is stored inlocalStorage under the accentColor key.
Choosing a non-default accent overrides three CSS custom properties on <html> (--accent-color, --accent-light-color, --accent-color-opacity), computed from the color’s base and light hex values with a lower opacity in Light mode (0.12) than Dark mode (0.2) so accent-tinted surfaces don’t overwhelm the lighter background. Choosing Default removes the override entirely, so the theme’s own built-in accent value applies instead.
Avoiding a flash of the wrong theme
Because Inertia pages render after the initial HTML loads, applying theme and accent purely from React would show a flash of the wrong colors on every full page load. Orbit avoids this with a small blocking<script> in resources/views/app.blade.php, inlined in <head> before any stylesheet or React code runs: it reads theme and accentColor from localStorage, resolves system the same way the React ThemeContext does, and sets data-theme and the accent CSS variables directly — so the very first paint already has the right colors.
The CSS token system
Both themes are defined as a complete set of CSS custom properties inresources/css/global.css, scoped under [data-theme='dark'] and [data-theme='light']: background and hover surfaces, text (primary, muted, and gray), borders (regular and “strong”), a semi-transparent --surface-color, an --overlay-color for modal backdrops, and the accent trio above. Components consume these as Tailwind arbitrary values (bg-[var(--bg-color)]) rather than Tailwind’s built-in palette, which is what makes a single component correct in both themes without a dark: variant.
A few colors are deliberately left as fixed hex values rather than theme tokens: text on solid accent-colored buttons, and the label, priority, and status badge colors (
Badge’s bug, feature, high, open, and so on variants). These are meant to look the same regardless of theme or accent choice, so they weren’t swept into the token system along with everything else.