Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Theming your own sites

Every page gets the live scheme as CSS custom properties on :root, so your own Stylus styles and userscripts can follow caelestia as well as the bundled themes do.

The names are caelestia’s colour names in kebab case: surfaceContainerHigh becomes --caelestia-surface-container-high. The Material colours are all there (primary, on-primary, primary-container, surface, outline and so on), and so are the Catppuccin names (base, mantle, text, mauve …), the terminal colours (term0 to term15) and --caelestia-mode, which is dark or light.

A Stylus style

@-moz-document domain("example.com") {
  body {
    background: var(--caelestia-surface);
    color: var(--caelestia-on-surface);
  }
  a {
    color: var(--caelestia-primary);
  }
  /* Blends work too, and follow the scheme live. */
  .card {
    background: color-mix(in srgb, var(--caelestia-primary) 12%, var(--caelestia-surface));
  }
}

Switch the caelestia scheme and the page changes without a reload.

A userscript

The variables are on document.documentElement. When the scheme changes, a caelestia-scheme event fires on document:

function apply() {
  const primary = getComputedStyle(document.documentElement).getPropertyValue("--caelestia-primary").trim();
  // use it
}
apply();
document.addEventListener("caelestia-scheme", apply);

A site of your own

For a site no bundled style covers: Settings, Websites, type its name in the filter, and press Enter (or pick Add “…”, a site of your own under the list). It opens with three fields: the domains it’s on, one per line; Also on pages matching, a CSS selector for pages it’s on wherever they’re hosted; and your CSS, which gets the scheme as var(--caelestia-*) like any page. It can be turned off with its checkbox, like the bundled ones, and removed from its own section.

Overriding a bundled site style

The bundled styles are Catppuccin’s, applied as upstream wrote them. To go further, open Settings, Websites and click a site’s name. Each has three fields, all empty by default:

  • Also on: more domains for the style, one per line. docs.example.org covers its subdomains too.
  • Also on pages matching: a CSS selector. Once a page has loaded, the style applies to it if the selector matches anything, wherever the page is hosted. This is for kinds of site, like documentation generators, that live on many domains.
  • Your CSS: applied after the style, on every page the style applies to. It can use the --caelestia-* variables, and wins over the style, since it comes later.

The page picks up a change on its next scheme switch or reload. Extra domains and selectors take the style’s rules for all its pages at once: the path filters some styles have (GitHub’s leaves out github.com/home, for example) don’t apply to them.

Recipes

mdBook, on any domain. Catppuccin’s mdBook style lists only a few well-known books. Every mdBook page has a theme picker, so under mdBook, set Also on pages matching to:

#mdbook-theme-list, #theme-list

(#mdbook-theme-list in mdBook 0.5, #theme-list before it.)

claude.ai’s current design. Claude moved to a new set of --cds-* variables, and Catppuccin’s Claude style still sets the old ones, so it changes nothing. Paste this into Claude’s Your CSS:

/* A site override for claude.ai (Settings → Websites → Claude → Your CSS).
   Claude moved to a --cds-* design system; catppuccin's Claude style still
   sets the older --bg-* variables, which Claude no longer reads. Claude
   derives almost everything from a neutral scale, the surfaces and an accent
   role, so this sets those, on every element Claude declares them on, and
   !important beats Claude's own there. Checked against claude.ai on
   2026-09-27. */
:root,
.cds-root,
.cds-dark-scope,
[data-mode] {
  --cds-neutral-0: color-mix(in srgb, var(--caelestia-on-surface) 0.0%, var(--caelestia-surface)) !important;
  --cds-neutral-10: color-mix(in srgb, var(--caelestia-on-surface) 1.1%, var(--caelestia-surface)) !important;
  --cds-neutral-20: color-mix(in srgb, var(--caelestia-on-surface) 2.2%, var(--caelestia-surface)) !important;
  --cds-neutral-30: color-mix(in srgb, var(--caelestia-on-surface) 3.3%, var(--caelestia-surface)) !important;
  --cds-neutral-40: color-mix(in srgb, var(--caelestia-on-surface) 4.4%, var(--caelestia-surface)) !important;
  --cds-neutral-50: color-mix(in srgb, var(--caelestia-on-surface) 5.6%, var(--caelestia-surface)) !important;
  --cds-neutral-60: color-mix(in srgb, var(--caelestia-on-surface) 6.7%, var(--caelestia-surface)) !important;
  --cds-neutral-70: color-mix(in srgb, var(--caelestia-on-surface) 7.8%, var(--caelestia-surface)) !important;
  --cds-neutral-80: color-mix(in srgb, var(--caelestia-on-surface) 8.9%, var(--caelestia-surface)) !important;
  --cds-neutral-90: color-mix(in srgb, var(--caelestia-on-surface) 10.0%, var(--caelestia-surface)) !important;
  --cds-neutral-100: color-mix(in srgb, var(--caelestia-on-surface) 11.1%, var(--caelestia-surface)) !important;
  --cds-neutral-150: color-mix(in srgb, var(--caelestia-on-surface) 16.7%, var(--caelestia-surface)) !important;
  --cds-neutral-200: color-mix(in srgb, var(--caelestia-on-surface) 22.2%, var(--caelestia-surface)) !important;
  --cds-neutral-250: color-mix(in srgb, var(--caelestia-on-surface) 27.8%, var(--caelestia-surface)) !important;
  --cds-neutral-300: color-mix(in srgb, var(--caelestia-on-surface) 33.3%, var(--caelestia-surface)) !important;
  --cds-neutral-350: color-mix(in srgb, var(--caelestia-on-surface) 38.9%, var(--caelestia-surface)) !important;
  --cds-neutral-400: color-mix(in srgb, var(--caelestia-on-surface) 44.4%, var(--caelestia-surface)) !important;
  --cds-neutral-450: color-mix(in srgb, var(--caelestia-on-surface) 50.0%, var(--caelestia-surface)) !important;
  --cds-neutral-500: color-mix(in srgb, var(--caelestia-on-surface) 55.6%, var(--caelestia-surface)) !important;
  --cds-neutral-550: color-mix(in srgb, var(--caelestia-on-surface) 61.1%, var(--caelestia-surface)) !important;
  --cds-neutral-600: color-mix(in srgb, var(--caelestia-on-surface) 66.7%, var(--caelestia-surface)) !important;
  --cds-neutral-650: color-mix(in srgb, var(--caelestia-on-surface) 72.2%, var(--caelestia-surface)) !important;
  --cds-neutral-700: color-mix(in srgb, var(--caelestia-on-surface) 77.8%, var(--caelestia-surface)) !important;
  --cds-neutral-750: color-mix(in srgb, var(--caelestia-on-surface) 83.3%, var(--caelestia-surface)) !important;
  --cds-neutral-800: color-mix(in srgb, var(--caelestia-on-surface) 88.9%, var(--caelestia-surface)) !important;
  --cds-neutral-810: color-mix(in srgb, var(--caelestia-on-surface) 90.0%, var(--caelestia-surface)) !important;
  --cds-neutral-820: color-mix(in srgb, var(--caelestia-on-surface) 91.1%, var(--caelestia-surface)) !important;
  --cds-neutral-830: color-mix(in srgb, var(--caelestia-on-surface) 92.2%, var(--caelestia-surface)) !important;
  --cds-neutral-840: color-mix(in srgb, var(--caelestia-on-surface) 93.3%, var(--caelestia-surface)) !important;
  --cds-neutral-850: color-mix(in srgb, var(--caelestia-on-surface) 94.4%, var(--caelestia-surface)) !important;
  --cds-neutral-860: color-mix(in srgb, var(--caelestia-on-surface) 95.6%, var(--caelestia-surface)) !important;
  --cds-neutral-870: color-mix(in srgb, var(--caelestia-on-surface) 96.7%, var(--caelestia-surface)) !important;
  --cds-neutral-880: color-mix(in srgb, var(--caelestia-on-surface) 97.8%, var(--caelestia-surface)) !important;
  --cds-neutral-890: color-mix(in srgb, var(--caelestia-on-surface) 98.9%, var(--caelestia-surface)) !important;
  --cds-neutral-900: color-mix(in srgb, var(--caelestia-on-surface) 100.0%, var(--caelestia-surface)) !important;
  --cds-surface-0: var(--caelestia-surface) !important;
  --cds-surface-1: var(--caelestia-surface-container-low) !important;
  --cds-surface-2: var(--caelestia-surface-container) !important;
  --cds-surface-3: var(--caelestia-surface-container-high) !important;
  --cds-text-primary: var(--caelestia-on-surface) !important;
  --cds-text-secondary: var(--caelestia-on-surface-variant) !important;
  --cds-text-muted: var(--caelestia-outline) !important;
  --cds-role-accent-fill: var(--caelestia-primary) !important;
  --cds-role-accent-fill-hover: color-mix(in srgb, var(--caelestia-primary) 85%, var(--caelestia-on-surface)) !important;
  --cds-fill-accent: var(--caelestia-primary) !important;
  --cds-text-accent: var(--caelestia-primary) !important;
  --cds-bg-accent: color-mix(in srgb, var(--caelestia-primary) 20%, transparent) !important;
}

Limits

  • Pages the browser won’t let extensions touch (about: pages, the add-ons site) get nothing.
  • The variables need the site-theme permission (Settings, Websites, Allow). Turning Theme websites off keeps the variables and drops only the bundled themes.