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 data-theme="dark">…</html>
<section data-theme="high-contrast">…</section>ThemeProvider options
| Option | Default | Purpose |
|---|---|---|
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. |
darkClass | true | Also toggles a dark class for Tailwind’s class strategy. |
respectContrastPreference | true | System mode resolves to high contrast when prefers-contrast: more. |
forcedTheme | None | Locks 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:
<ThemeScript storageKey="theme" defaultTheme="light" />
<ThemeProvider storageKey="theme" defaultTheme="light">{children}</ThemeProvider>Scoped themes
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.