Dark mode
Every component swaps on <html data-theme="dark">; persist the choice with an inline script and the ThemeToggler component.
The tokens define light values at the root and dark values under [data-theme='dark']. Toggle that attribute and every component follows.
#Avoid the flash
Set the attribute before first paint with an inline script in app.html:
<script>
(function () {
try {
var t = localStorage.getItem('norns-theme');
if (t === 'dark' || (t === null && window.matchMedia('(prefers-color-scheme: dark)').matches)) {
document.documentElement.dataset.theme = 'dark';
}
} catch (_) {}
})();
</script>#Toggle
ThemeToggler(size="sm")
ThemeToggler(showLabel!="{true}" labelLight="Light" labelDark="Dark")ThemeToggler reads and writes the same norns-theme localStorage key by default (storageKey changes it) and swaps between lightIcon and darkIcon.
#Your own styles
Reach for the role tokens rather than raw colours so your components swap too: var(--color-fg), var(--color-bg-elevated), var(--color-border) and the rest listed under Theming. Scope overrides with [data-theme='dark'] .my-thing { ... } when a token is not enough.