Theming#

The site’s colors are a small set of semantic token pairs with light and dark variants. You edit them in the GUI’s Theme tab; the result is merged onto the base palette and contrast-validated at build time.

Tokens#

Each semantic role has a background (-bg) and foreground (-fg) token, in both light and dark modes. The full set covers page, primary, accent, success, warning, and error — twelve tokens per mode. You only set the ones you want to change; the rest come from the base palette.

The Theme tab lays them out as a grid of hex values, light beside dark:

Token

Light

Dark

page-bg

#f6f0fc

#1a1026

page-fg

#2c1741

#f0e6fa

primary-bg

#ece0f8

#2d1b45

primary-fg

#5b2a86

#d5b4f5

accent-bg

#fde4f2

#3d1330

accent-fg

#a11362

#ff9ed2

Contrast validation#

The design rule is stricter than it first looks: within a mode, every -fg must be legible on every -bg — not just on the background it’s paired with. Components separate surfaces with borders and shadows rather than background contrast, so a text color can land on any surface and has to stay readable everywhere.

“Legible” means the WCAG AA ratio for normal text, 4.5:1. The merged palette is checked at build time, so a low-contrast override fails the build rather than shipping an unreadable site, and the error names every pair that fell short with its actual ratio.

In practice: keep all six -bg values in one lightness band and all six -fg values in the opposite band. A primary-fg that only looks good on primary-bg will fail against page-bg.

Custom CSS#

For anything the tokens don’t reach, the Theme tab has Edit custom CSS…, which opens a user.css that overrides every style the site ships — no !important needed. Show in folder opens its location. This is an escape hatch, not the first stop: colors set through the tokens stay contrast-checked, and CSS written here does not.

Light / dark at runtime#

Viewers get a color-mode selector (auto / light / dark) in the header. Their choice is remembered in their own browser — which is why every token is defined for both modes.

The values above are the example theme that ships with the repo’s development config — a starting point, not a requirement.