Skip to main content
Orbit is no longer dark-theme-only. Both interface theme and accent color are configurable from Settings → Account → Preferences (see Settings), persist across sessions, and apply instantly, app-wide.

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 in localStorage 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 in resources/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.
Last modified on August 17, 2026