Theming

All colors, radii, shadows and sizes are CSS custom properties (design tokens). Dark mode, high contrast, font scaling, brand colors, multiple tenants and white-labelling are built in, and every component follows them automatically.

Dark / light / auto

auto (default) follows the operating system. The choice is saved per browser (disable with persist: false).

      Orion.theme.setMode('dark');        // 'light' | 'dark' | 'auto'
      Orion.theme.toggle();               // light ⇄ dark
      Orion.theme.cycle();                // light → dark → auto
      Orion.theme.resolved;               // 'light' | 'dark' (what is displayed)
      Orion.on('theme', e => console.log(e.mode, e.resolved));
    

Set the initial mode without JavaScript flashes with <html data-theme="dark"> or <script src="orion.js" data-theme="dark">.

Scoped themes

Add .o-theme-dark or .o-theme-light to any element to theme only that area, for example a dark sidebar on a light page. Floating panels opened from inside it inherit the scope.

Brand colors at runtime

Orion.theme.set() changes tokens live. Readable text colors (--o-on-*) and hover shades are derived automatically.

Multi-tenant & white-label

Register named themes (tokens, branding, default mode) and switch between them. Elements marked with data-o-brand="name" / data-o-brand="logo" are updated automatically, as are the favicon and title.

      Orion.theme.register('acme', {
        primary: '#e11d48', radius: '4px', font: 'Inter, sans-serif', mode: 'light',
        brand: { name: 'ACME Corp', logo: '/acme.svg', logoDark: '/acme-white.svg', favicon: '/acme.ico', title: 'ACME Admin' }
      });
      Orion.theme.use('acme');           // persisted; Orion.theme.reset() to clear
    

High contrast & font size

High contrast strengthens borders, muted text and focus rings (it also follows prefers-contrast: more). The font scale resizes every rem-based size.

      Orion.theme.setContrast(true);
      Orion.theme.setFontScale(1.125);   // 0.75 – 1.5
    

Design tokens

Override tokens in your CSS (:root { --o-primary: … }) or with Orion.theme.set(). Semantic colors have derived variants: -hover, -subtle, -border, -text and --o-on-*.

Token groupVariables
Brand & semantic--o-primary secondary success danger warning info light dark + --o-on-*, -hover, -subtle, -border, -text
Surfaces & text--o-bg --o-surface --o-surface-2 --o-surface-3 --o-elevated --o-border --o-border-strong --o-text --o-text-muted --o-text-subtle --o-backdrop
Typography--o-font-sans --o-font-mono --o-font-scale --o-fs-xs … --o-fs-4xl --o-lh
Shape--o-radius-xs --o-radius-sm --o-radius --o-radius-lg --o-radius-xl --o-radius-pill, --o-shadow-xs … --o-shadow-xl
Controls--o-control-h --o-control-h-sm --o-control-h-lg --o-control-px --o-input-bg --o-input-border --o-ring-width --o-ring-alpha --o-focus
Layout--o-sidebar-w --o-sidebar-w-mini --o-header-h --o-sidebar-bg --o-sidebar-text --o-header-bg --o-container-max
Motion & stacking--o-ease --o-dur-fast --o-dur --o-dur-slow, --o-z-dropdown … --o-z-tooltip
Data visualisation--o-chart-1 … --o-chart-8 (validated categorical order), --o-seq-100 … 700, --o-div-neg/mid/pos, --o-status-good/warning/serious/critical
Color context.o-c-{color} sets --o-c --o-on-c --o-c-subtle --o-c-text --o-c-border, which many components accept (avatars, progress, stat icons, timeline markers).

API

MemberDescription
theme.mode / resolvedCurrent mode (light|dark|auto) and the displayed mode.
theme.setMode(m) / toggle() / cycle()Change the mode (persisted).
theme.set(tokens, scopeEl?)Apply tokens (primary, radius, font… or raw --o-* names).
theme.get(token)Computed token value.
theme.reset()Remove runtime tokens and the active tenant.
theme.register(name, def) / use(name)Multi-tenant themes (tokens + brand + mode).
theme.brand({ name, logo, logoDark, favicon, title })White-label branding.
theme.setContrast(bool) / setFontScale(n)Accessibility preferences (persisted).
theme.exportCSS()CSS snippet of the runtime overrides.
Orion.color.*parse toHex toRgb toHsl fromHsl mix lighten darken alpha luminance contrast readable palette random
data-o-action="theme"data-o-value: light dark auto toggle cycle contrast font+ font- font0 or a tenant name.
EventsOrion.on('theme', fn), DOM event o-theme on document, Orion.on('brand', fn).