Skip to content
Get started

Themes

Fourteen glazes, one token system, and no component that knows about any of them.

Set one word:

site.yaml
theme: cupertino

The theme picker in the bar above changes it live. That is the fastest way to understand what a theme actually does here — every page on this site restyles, including this one.

The fourteen

NameWhat it is
midnightDark, electric accent, tight geometry — a product-tool aesthetic.
paperLight, warm, editorial serif headings over a cream page.
terracottaWarm Moroccan palette with generous curves — the Shebka house style.
monoAustere black and white with a single hot accent and brutalist edges.
auroraDark with soft gradient glows and glassy surfaces.
slateCool corporate blue-grey — enterprise-safe and unfussy.
forestDeep greens, natural and calm.
sunburstLight and high-energy, playful radius and a hot warm accent.
carbonNear-black developer-tool aesthetic with monospace-flavoured headings.
porcelainUltra-minimal light, hairline borders, quiet luxury.
cupertinoVery large tight headlines, centred compositions, huge breathing room.
studioEditorial creative studio — warm paper, monochrome type, a luminous violet.
irisBright enterprise SaaS — near-white neutrals, roomy surfaces, a violet brand.
meridianWarm cream over deep navy ink with an electric blue — calm and human.

What a theme controls

A theme is a token set, emitted as CSS custom properties. No component contains a colour, a font, a radius or a duration.

Per colour mode: bg, fg, muted, surface, border, accent, accent-fg, inverted-bg, inverted-fg.

css
--zellij-bg: #ffffff;
--zellij-accent: #0071e3;
--zellij-inverted-bg: #1d1d1f;

Light and dark

site.yaml
mode: system     # light | dark | system

Every theme defines both palettes. system follows the operating system and can still be overridden by the visitor with nav.themeToggle: true; the choice is remembered.

Code blocks follow the mode too — Shiki emits both palettes at build time and a CSS variable picks between them, so switching is instant and no highlighter runs in the browser.

Overrides

Tweak a theme without forking it:

site.yaml
overrides:
  accent: "#E86A33"
  accentForeground: "#ffffff"
  radius: lg              # none | sm | md | lg | xl
  fontHeading: "Georgia, serif"
  fontBody: "system-ui, sans-serif"

Values are validated before they reach the stylesheet. They come from a config file rather than a request, but they are interpolated into CSS, so they are checked rather than trusted.

The runtime picker

site.yaml
nav:
  themeSwitcher: true

Per-page themes

A page may override the site theme:

pages.yaml
- name: launch
  theme: aurora
  sections: [launch/hero]

Use it sparingly. A site where every page looks different is the problem Zellij exists to prevent.

Adding a theme

Themes live in the engine, not in content. A new one is a token set added to THEMES and a name added to THEME_NAMES — no component changes, and a test asserts every theme emits every token and clears the contrast floor.