Skip to content

Getting started

Theming

Configure light, dark and high-contrast themes in Stance: system detection, persistence, no-flash script, scoped themes and keeping saved preferences.

Stance has three appearance modes. Each is a complete mapping of semantic roles, not just an inverted palette.

  • Light: ivory canvas, indigo text, warm derived neutrals.
  • Dark: indigo canvas, ivory text, surfaces that lighten with elevation.
  • High contrast: every boundary at full indigo strength, body and secondary text at 12:1 or more, 3px focus rings and 2px control borders. Chosen automatically when the OS requests more contrast.

How it works

The theme is a data-theme attribute. On <html> it sets the page theme; on any element it scopes a theme to a subtree.

html
<html data-theme="dark">…</html>
<section data-theme="high-contrast">…</section>

ThemeProvider options

OptionDefaultPurpose
defaultTheme'system'Used when no preference is stored.
storageKey'stance-theme'localStorage key for the preference.
legacyStorageKeys[]Keys read when the main key is empty, to migrate an existing preference.
darkClasstrueAlso toggles a dark class for Tailwind’s class strategy.
respectContrastPreferencetrueSystem mode resolves to high contrast when prefers-contrast: more.
forcedThemeNoneLocks a page to one theme.

Pass the same options to ThemeScript so the pre-paint script and the provider agree.

Keeping an existing preference

An app that already stored 'light' or 'dark' under localStorage.theme keeps working:

tsx
<ThemeScript storageKey="theme" defaultTheme="light" />
<ThemeProvider storageKey="theme" defaultTheme="light">{children}</ThemeProvider>

Scoped themes

tsx
import { Theme } from '@bindshq/stance-react';

<Theme theme="dark">
  <CallToAction />
</Theme>

Popovers, menus and tooltips opened inside a scoped theme inherit it, even though they render in a portal.

Without JavaScript

When no data-theme is set, the token stylesheet follows prefers-color-scheme and prefers-contrast directly. Reduced-motion preferences shorten every Stance duration to zero.