Eunomia v1.0.0-beta.2
AllAngularReactNext.jsJavaScriptVue
EunomiaSalmonForestVioletOceanGoldFireCustom…
🇬🇧 English🇫🇷 Français

Theming

Every visual choice in Eunomia, colors, spacing, corner rounding, shadows, fonts, comes from a single design system rather than being fixed inside each component. Switch the active brand or flip between light and dark, and everything on the page updates immediately: no rebuild, no page reload, no per-component work. That's what lets this whole site re-theme itself live from the toolbar above, and it's the same mechanism your own app gets, whether you install one of the 7 prebuilt themes as-is or generate a custom one from your own brand colors.

How tokens are named

Every one of those values, a color, a spacing value, a font size, is exposed as a small, named unit called a token. In plain CSS terms a token is just a variable: a name that stands in for a value, so the actual color or size only has to be defined once and can then be reused, and swapped, everywhere. Every token name starts with --eun- and follows the same shape after that, --eun-[what it is]-[which variant], for example --eun-color-primary-500 (the primary brand color, at its "500" shade), --eun-space-m (a medium spacing value), or --eun-fontSize-s (a small font size). Learn a handful of these and you can usually guess the name of any other one.

Because tokens are plain CSS, not compiled values baked in ahead of time, switching a theme never needs a rebuild: the browser just looks up the same token names against a different set of values.

How switching works

Two independent attributes on <html> control the active theme:

<html data-brand="eunomia" data-theme="light"></html>
  • data-brand selects one of the 7 prebuilt palettes (eunomia, salmon, forest, violet, ocean, gold, fire), or custom.
  • data-theme is light or dark.

The toolbar at the top of this site sets both attributes live. Try switching brand or mode with it: everything below reacts instantly, with no reload. The choice persists (via `localStorage`) across pages and reloads.

Primary these three all read straight off the active brand/mode

This differs slightly from how the underlying component library ships its CSS: there, each prebuilt theme is a .eunomia-<name>-theme / .eunomia-<name>-theme--dark class you add to <body>, meant to be combined with a separate base .eunomia-theme class for full token coverage (fonts, spacing, radius, shadows; the class alone only carries colors). This site instead compiles each theme's full token bundle into one [data-brand][data-theme] selector (styles/eunomia-themes.scss), so a single attribute pair is always enough. See Prebuilt themes for the class-based option if you're consuming the library directly instead of this attribute convention.

For component authors

Reference tokens directly. Never hardcode a color, size, or radius:

.eunomia-button {
  background: var(--eun-color-primary-500);
  color: var(--eun-color-on-primary-500);
  border-radius: var(--eun-borderRadius-m);
  padding: var(--eun-space-xs) var(--eun-space-m);
  font-family: var(--eun-font-family);
}

.eunomia-button:hover {
  background: var(--eun-color-primary-600);
}

Because the token exists on every brand and mode, the component repaints correctly no matter which theme is active. Nothing in the component itself needs to know about brands or dark mode.

Sections

Prebuilt themes

7 ready-made palettes to preview and pick from

Custom theme

Build your own palette from two brand colors

Light & dark via transparency

How colors adapt automatically between light and dark mode

Color

The shared colors every theme has in common