S Sulci Early Access

App Developer Docs

Theme System

Themes are CSS custom property sets scoped to [data-theme="name"] on the <html> element. Adding a new theme means one new CSS file and two lines of code.

How it works

  1. src/styles/themes/*.css — one file per theme, each defining CSS custom properties under :root[data-theme="<name>"].
  2. All theme files are imported in src/main.js.
  3. stores/theme.js reads from localStorage on init and calls document.documentElement.setAttribute('data-theme', name) to activate a theme.
  4. The top bar’s theme toggle button cycles through the THEMES array in stores/theme.js.

Available themes

NameBackgroundAccent
dark#070a14#60a5fa (blue)
light#f8fafc#2563eb (blue)

CSS variable reference

Every component in the app uses these variables. Define all of them in each theme file.

VariableRole
--bg-primaryPage background
--bg-secondaryCards, nav bars
--bg-cardElevated surfaces
--bg-inputForm inputs
--text-primaryBody text
--text-secondarySubdued labels
--text-mutedPlaceholders, hints
--accentPrimary interactive color (buttons, links, active states)
--accent-hoverHover state for accent
--accent-softLow-opacity accent for backgrounds
--borderAll borders and dividers
--successPositive states
--warningCaution states
--errorError messages
--shadowBox shadows
--radiusLarge border-radius (cards)
--radius-smSmall border-radius (buttons, inputs)

Adding a new theme

1. Create the CSS file:

/* frontend/src/styles/themes/forest.css */
:root[data-theme="forest"] {
  --bg-primary: #0d1a0d;
  --bg-secondary: #122012;
  --bg-card: #1a2e1a;
  --bg-input: #0d1a0d;
  --text-primary: #e6f0e6;
  --text-secondary: #9ab89a;
  --text-muted: #5a7a5a;
  --accent: #4ade80;
  --accent-hover: #86efac;
  --accent-soft: rgba(74, 222, 128, 0.12);
  --border: #1f3020;
  --success: #4ade80;
  --warning: #fbbf24;
  --error: #fb7185;
  --shadow: 0 2px 12px rgba(0, 0, 0, 0.5);
  --radius: 12px;
  --radius-sm: 8px;
}

2. Import it in main.js:

import './styles/themes/forest.css'

3. Add it to the THEMES array in stores/theme.js:

export const THEMES = ['dark', 'light', 'forest']

The theme toggle in the top bar will now cycle to it.

Theme persistence

The active theme name is stored in localStorage under the key sulci-theme. On next visit, stores/theme.js reads it and re-applies the theme before the first render. The default (if nothing is stored) is dark.

Themes are currently per-device. There is no server-side preference — the theme column in the users table exists for future use.