Early docs These pages are very early. Structure and tone are still being worked out, so anything here may change drastically.
Skip to content
Rendered from ui/THEME.md in the repository — edit it there.

Theming ​

How light/dark mode and the accent colour work. The SCSS design language — tokens, base elements, utilities — lives in the shared @coldcrabby/ui repo, vendored at vendor/coldcrabby-ui/ (see README → Shared UI); for the visual rules that govern what you build with these tokens, see the design language.

Modes ​

Dark mode is a class on <html>. Light is the default; html.dark swaps the token values.

Tokens are defined per mode in the vendored vendor/coldcrabby-ui/src/styles/theme/: _tokens.scss holds what doesn't change (spacing, radii, durations), _light.scss and _dark.scss hold the colours.

AppTheme owns the switch:

isDarkMode()The resolved mode, as a signal
hasExplicitPreference()False when following the system
toggleTheme()Flip and persist

With no stored preference it follows prefers-color-scheme and keeps following it live. That's why there are three options in the UI — Light, Dark and System — but only two token sets.

Accent ​

Every colour in the UI derives from one --accent variable. Override it and the whole interface recolours; nothing else needs to know.

AccentService resolves where that value comes from:

SourceValue
brandThe molten-amber default baked into the theme tokens
systemThe OS accent colour (desktop only)
customA preset or a colour the user picked

It defaults to the OS accent on desktop and to brand on the web — the app should look like it belongs to the machine it's running on.

Using tokens ​

In component styles, use the CSS variables. Don't reach for SCSS colour functions, and never hardcode a brand colour:

scss
.my-element {
  background: var(--color-bg-secondary);
  color: var(--color-text-primary);
  padding: var(--spacing-md);
  border-radius: var(--radius-md);
  transition: all var(--transition-normal);
}

Hardcoding a colour breaks three things at once: dark mode, the user's accent, and the OS accent on desktop.

Persistence ​

Theme and accent preferences are stored in localStorage through BrowserStorage, which keeps them in sync across tabs.