Skip to main content
View as Markdown

Baseline & Dark Mode

Three theme properties decide what your app looks like before you style anything, and what it looks like at night: baseline, darkColors, and colorScheme.

baseline

baseline controls whether Sovrium's prebuilt components come with a look attached.

Value Behavior
extend (default) Components inherit Sovrium's default design-system tokens — cards have a border and shadow, buttons have a fill, form controls have focus rings. Your tokens layer on top.
replace Components drop the default look and start from a neutral, unstyled floor. Nothing is prestyled; every surface is yours to define.

Start with extend. It gets a usable app on screen with a handful of color tokens, and any individual prestyle can still be overridden — an author-supplied props.className is appended last, so it wins the Tailwind cascade. Reach for replace only when you are building a design system of your own and the defaults are actively in the way.

app.yaml
theme:
  baseline: extend

darkColors

darkColors mirrors the colors structure and supplies the values used in dark mode. One theme therefore ships both palettes, and no component needs a dark: variant written by hand.

app.yaml
theme:
  colors:
    background: '#ffffff'
    background-raised: '#f8fafc'
    foreground: '#0f172a'
    foreground-muted: '#64748b'
    primary: '#4f46e5'
  darkColors:
    background: '#0f172a'
    background-raised: '#1e293b'
    foreground: '#f8fafc'
    foreground-muted: '#94a3b8'
    primary: '#818cf8'

Only the tokens that need to change have to appear in darkColors. A token you leave out keeps its light value in both schemes — correct for a brand accent, and usually wrong for anything with background or foreground in the name.

darkColors overrides the palette; it does not extend it. A name that appears only in darkColors and never in colors produces no utility, because bg-{name} and text-{name} are minted from the colors block. Declare the token in colors first, then give it its second value here.

colorScheme

colorScheme sets which palette a first-time visitor gets, before any preference of theirs is known.

Value First-time visitor sees
light The light palette, regardless of their operating system setting.
dark The dark palette, regardless of their operating system setting.
system Whichever their operating system reports.

A visitor who has since made a choice always overrides this — the stored preference wins on every subsequent visit. colorScheme is the default, not the policy.

It is applied before the page's content renders, so a dark-first app does not flash a white page on load.

The Switch

The visitor-facing control is a component, not a theme property: add a theme-toggle to your header and it writes the stored preference that overrides colorScheme.

app.yaml
- type: container
  element: header
  props: { className: 'flex items-center justify-between p-4' }
  children:
    - { type: text, element: span, props: { className: 'font-semibold' }, content: 'Acme' }
    - { type: theme-toggle }

Omit the toggle and the app simply follows colorScheme forever — a legitimate choice for a single-palette design.

Last updated September 1, 2026

This documentation was written with AI, so errors or outdated content are possible. Sovrium is in beta. Contributions and corrections are welcome.

Built with Sovrium