Skip to main content

Theming

Silva UI components resolve CSS variables from the nearest theme scope. Use a built-in Theme 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 are light, 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.

Semantic tokens first

Choose semantic tokens when a colour describes a UI role rather than a specific hue. A primary 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

The wrapper provides 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.