A wider screen, please

This page features interactive demos and side-by-side code samples that need at least 340 pixels of horizontal space. Please widen your browser window, or rotate your device, to continue.

Morpheus v0.1.0
v0.1.0

Theming#

Themes are plain CSS. Every component reads a small set of :root custom properties; switching theme or mode just toggles a class on <html>.

Open the settings sidebar and flip theme or mode: the whole preview updates at once.

DefaultPrimarySecondaryDangerGhost DefaultPrimarySecondaryDangerOutline

Each chip's fill is var(--<name>), so the grid tracks theme swaps with no JS.

--accent --accent-fg --page-bg --page-fg --muted --btn-bg --btn-fg --btn-border --btn-hover-bg --danger-bg --danger-fg --danger-hover-bg

Default theme#

The full default palette as it ships in theme-default.css: every variable a custom theme can override:

How it works#

Two class hooks on <html> drive every visual choice:

  • theme-<name>: the palette. No theme-* class means the kit's default.
  • light / dark: the colour mode. No class lets prefers-color-scheme pick from the OS, so a no-JS visit still respects dark mode.

Each palette is one file (e.g. theme-ocean.css) with a :root.theme-ocean rule for light and a :root.theme-ocean.dark rule for dark overrides. Structural defaults (--page-radius, --page-spacing, --page-font-family) live in morpheus.css; themes only redeclare what they change.

Switching at runtime#

No kit-owned theme component; anything that writes the two classes works. This site's picker is a Datastar component holding two signals ($_theme, $_mode); a data-effect writes the classes to document.documentElement and persists them to localStorage.

System mode#

Mode also accepts "system": the saved value stays "system" while <html> wears whichever of light or dark matches the OS. A matchMedia listener re-resolves on OS flips; explicit "light" or "dark" are never overridden.

Best practice#

  • Apply the classes from an inline <script> at the top of <head>, before stylesheets, for no FOUC once your framework hydrates.
  • Keep the default palette on bare :root (no class) so a pre-JS render still looks right.
  • Pair every :root.theme-X with a :root.theme-X.dark that only overrides what dark mode changes. The cascade carries the rest.
  • Touch the structural vars (--page-radius, --page-spacing, --page-font-family) only when a theme wants a different feel.
  • Set color-scheme so native controls and scrollbars match.

Settings

Theme

Default Sunshine Ocean Matrix Rose

Accessibility

Playgrounds

Server Simulator