Skip to content

Custom Themes

The createTheme() utility lets you build a brand-specific theme by overriding only the values that differ from a built-in base. Everything you don’t override inherits from the base theme.

import { createTheme } from '@/tokens/themes/createTheme';

createTheme(base, overrides) performs a deep merge — you only need to specify the keys that change.

The most common customisation is swapping the accent color:

import { createTheme } from '@/tokens/themes/createTheme';
import { slateThemeLight, slateThemeDark } from '@/tokens/themes/slate';
export const brandLight = createTheme(slateThemeLight, {
colors: {
accent: '#E11D48', // rose
accentHover: '#BE123C',
accentSubtle: '#FFF1F2',
},
});
export const brandDark = createTheme(slateThemeDark, {
colors: {
accent: '#FB7185',
accentHover: '#F43F5E',
accentSubtle: '#4C0519',
},
});

Add one entry to THEME_REGISTRY:

src/tokens/themes/registry.ts
import { brandLight, brandDark } from './brand';
export const THEME_REGISTRY = [
// ... existing themes
{ name: 'brand', label: 'Brand', light: brandLight, dark: brandDark },
];

That’s it. setTheme('brand') now works. TypeScript infers the 'brand' name from the registry automatically.

Any key in the AppTheme interface can be overridden:

export const customTheme = createTheme(slateThemeLight, {
colors: {
accent: '#0EA5E9',
accentHover: '#0284C7',
accentSubtle: '#F0F9FF',
},
radius: {
md: 12, // rounder corners than Slate's 8
},
buttonShape: 'default', // square instead of pill
iconWeight: 'bold', // heavier icons
});

Stratum is designed around one accent hue per theme. Resist adding a second accent — secondary buttons use ghost or outline treatments of the same accent. Signal colors (success, warning, error) appear only for status — never as decoration.

If your brand requires a second color (e.g., a separate destructive hue), extend the AppTheme interface in theme-protocol.ts and add the new slot to all theme files.

  • Theme Registry — how THEME_REGISTRY works
  • Theming — AppTheme interface reference
  • Slate — clean base for most brand themes
  • Obsidian — structural base for editorial brands