In the browser — sign in and open the theme builder. Pick your colours, fonts, and shape tokens, save under a name, and set that name as your deck's theme:. No code, and it can't break anything: the builder only writes the safe token block.
As a CSS file — running your own instance? Built-in themes are plain CSS files in src/styles/themes/, and you can add your own.
Either way, every reader of your deck sees your theme — not just you.
A deck names its theme in frontmatter:
theme: operazione-stile
Built-in names map straight to a file — themes/operazione-stile.css. Any other name looks up a theme you built under that name. No match? The deck falls back to default.
Components never hardcode colours — they read --vd-* variables. A theme's whole job is to define that set on :root:
:root {
--vd-bg: #0f172a;
--vd-text: #e2e8f0;
--vd-accent: #818cf8;
}
default.css is the canonical list. The theme builder exposes the same tokens as controls — same contract, no syntax.
--vd-bg, --vd-card-bg, --vd-card-border--vd-text, --vd-text-muted, --vd-heading--vd-accent, --vd-accent-2--vd-font-body, --vd-font-heading, --vd-font-scale--vd-card-max-width, --vd-card-padding, --vd-radius--vd-nav-bg, --vd-progressThe toggle sets data-mode on the page's root element. A theme supports light mode by overriding the same tokens under a matching selector:
:root[data-mode="light"] {
--vd-bg: #f1ecdd;
--vd-text: #2e231b;
}
Define only what changes; everything else inherits from the dark defaults.
In a theme file, you can go beyond colours by targeting a card's body with an ancestor chain — specific enough to beat the components' scoped styles:
.reader__stage .reader__card .card-body--quote {
border-left: 4px solid var(--vd-accent);
font-style: italic;
}
This is how the bespoke themes add stamps, rules, and textures. (The in-browser builder deliberately stays in token territory — that's what keeps it safe.)
my-themedefault.css to themes/my-theme.css and retune the --vd-* values:root[data-mode="light"] block if you want light modetheme: my-theme in a deck and reload↓ Download default.css to start from.
Define the tokens once; every card, the reader, and the nav restyle themselves.
— The theming contract