ThemeInit prevents FOUC, ThemeProvider persists style knobs to localStorage, and data-* attributes on html drive every token in theme.scss.
How theming works
Once UI does not rely on CSS-in-JS for theme switching. Instead:
ThemeInit — blocking inline script in the document head sets data-theme, data-brand, data-accent, etc. before first paint
ThemeProvider — client context that reads/writes the same data-* keys to localStorage
tokens/theme.scss — selectors like [data-theme="dark"][data-brand="blue"] map to CSS variables
This means zero flash of wrong theme and no prop-drilling for colors.
ThemeInit in your root layout
Render ThemeInit inside html before body. Pass defaults that match your brand — users can override via localStorage or a settings panel.Priority order: localStorage → config defaults → system preference (for theme: "system").
ThemeProvider for interactive apps
Wrap client subtrees with ThemeProvider. Use useTheme() for light/dark/system and useStyle() for brand, accent, border style, surface, scaling, and more.Default props to match ThemeInit: theme="system", brand="blue", accent="indigo".setStyle({ border: "conservative", scaling: "105" }) updates both the DOM attribute and localStorage so refreshes keep the choice.
Style dimensions at a glance
Attribute
Options
Effect
`data-theme`
light, dark, system
Color scheme
`data-brand` / `data-accent`
scheme tokens
Primary + highlight hues
`data-neutral`
sand, gray, slate
Gray ramp
`data-border`
rounded, playful, conservative
Corner radius scale
`data-surface`
filled, translucent
Panel opacity
`data-scaling`
90–110
Global size multiplier
`data-viz-style`
categorical, divergent, sequential
Chart color ramps
color-and-surfaces covers which token to pick — this page covers how they get applied at runtime.
Charts follow data theme
Wrap dashboard routes with DataThemeProvider and read useDataTheme() inside chart pages. LineChart and siblings pick categorical vs sequential palettes from automatically.
Build a chart section with Column + Heading + LineChart — pass data, xKey, yKey, and height. Toggle viz-style in your settings panel to verify chart colors track the global data theme.
Built-in UI switchers
Core ships ThemeSwitcher and StylePanel for full settings surfaces. Drop them in a header dropdown or a /settings/appearance route — both call the same setStyle API under the hood.
For minimal headers, a three-option SegmentedControl (light / system / dark) wired to setTheme is enough.