Theme Customizer Guide

Vanduo themes by writing data-* attributes on <html> — the CSS reads them. In Vue 3 the useThemePreference() singleton sets those attributes, persists the choice to localStorage, and re-applies it on load.

Setting the theme
// vd3 theming is a reactive singleton, not global JS calls
import { useThemePreference } from '@vanduo-oss/vd3';

const theme = useThemePreference();
theme.setTheme('dark');       // 'system' | 'light' | 'dark'
theme.setPrimary('violet');   // brand hue
theme.setNeutral('slate');    // neutral ramp
theme.setRadius('0.5');       // corner radius scale
theme.setFont('lato');        // base font family
theme.reset();                // back to defaults
What it sets

useThemePreference() writes these attributes; the framework CSS does the rest:

<!-- The framework CSS reads these attributes on <html> -->
<html
  data-theme="dark"
  data-primary="violet"
  data-neutral="slate"
  data-radius="0.5"
  data-font="lato">
Customization attributes
AttributeValuesControls
data-themesystem · light · darkColour mode (system defers to prefers-color-scheme)
data-primary18 hues (e.g. violet, teal)Brand colour ramp
data-neutral6 ramps (e.g. slate, gray)Neutral / surface colours
data-radius0 · 0.125 · 0.25 · 0.375 · 0.5Corner-radius scale (rem)
data-fontubuntu, lato, …Base font family

The option lists (hue names, neutrals, radii, fonts) come from @vanduo-oss/vd3 so they match its token catalog exactly — see The Vanduo Ecosystem.

Persistence
// Preferences persist in localStorage and re-hydrate automatically. Keys:
//   vanduo-palette, vanduo-primary-color, vanduo-neutral-color,
//   vanduo-radius, vanduo-font-preference, vanduo-theme-preference
// useThemePreference() reads them on first client access — there is no init().