Theming
Silva UI components resolve CSS variables from the nearest theme scope. Use a built-inTheme for a ready-made palette, or compile a custom variable class with Vanilla Extract. The same semantic tokens power surfaces, text, component variants, and theme-aware gradients.
Built-in themes
Available names arelight, dark, emerald, emerald-dark, and midnight. Theme scopes can nest, so a local section can use a different palette without changing the rest of the page.
- Preview
- Code
Semantic tokens first
Choose semantic tokens when a colour describes a UI role rather than a specific hue. Aprimary button or card surface can change with the active theme without changing component code. Use Radix scale tokens such as violet9 only when the hue itself is intentional, for example a decorative accent.
themeColors is the full CSS-variable contract behind these values. colorTokens and darkColorTokens provide the Radix scale defaults; lightColors and darkColors provide the semantic defaults for a theme.
Custom themes with createTheme
createTheme is Vanilla Extract’s build-time API. It creates a CSS class with the same variable contract as Silva UI. Add that class to a normal wrapper around components and they inherit its token values automatically.
1. Add Vanilla Extract
vite.config.ts
2. Create the theme in a CSS module
Use a*.css.ts file so Vanilla Extract can compile it. Spreading the Silva UI exports fills the complete token contract, then your semantic overrides define the brand.
src/brand-theme.css.ts
3. Apply the custom scope
- Preview
- Code
primary, card, border, and the other variables. Any nested Silva UI component resolves them from that wrapper. You can put it inside a built-in Theme or make it the outer application scope.
Dark custom theme
Start a dark version from the dark defaults.src/brand-dark-theme.css.ts
createThemes versus createTheme
createThemes generates plain palette/template value records. It does not emit a CSS class. Use it when generating values, then pass the final record through createTheme before applying it to a wrapper. For most apps, start with themeColors so custom and built-in themes use the same variable names.