The systemLumos 0.0.1
Theming
Four themes that are classes, not settings, and why that means anything can sit inside anything.
Lumos has four color themes: theme-light, theme-dark, theme-brand and theme-invert. Each one redeclares the same set of tokens (background, text, border, button colors, link colors), so anything inside it picks up the right colors without knowing where it is.
<div class="theme-light padding-4">Light</div>
<div class="theme-dark padding-4">Dark</div>
<div class="theme-brand padding-4">Brand</div>
<div class="theme-invert padding-4">The opposite of whatever is around it</div>Each swatch is a plain div with a theme class, and the buttons inside are the same Button component every page uses. Nothing in them is styled per theme: they read the theme's tokens, hover states and all. theme-invert has no colors of its own, so it flips whichever theme it lands in.
Why classes and not a setting
A site-wide dark mode toggle can only answer one question: is the page dark? Real designs need more than that: a dark section in a light page, a brand-colored card inside the dark section, a light panel inside that.
Because a theme is a class, it applies to a subtree. Every level can set its own, and everything inside inherits until something changes it. A Button never asks what page it is on; it reads --button-background, which is whatever the nearest theme says it is.
The four
| Theme | What it is for |
|---|---|
theme-light | Light surfaces. What :root starts as. |
theme-dark | Dark surfaces. |
theme-brand | The brand color as a background, with text chosen for contrast. |
theme-invert | The opposite of its parent. Inside a light theme it is dark; inside a dark theme it is light. |
theme-invert is the one to reach for when a panel should contrast with whatever it lands in: a callout that must stand out in both a light and a dark section, without you having to know which.
Applying one
Section, BaseLayout and Card take a theme prop:
<Section theme="dark">
<Heading tag="h2">On a dark surface</Heading>
<Card theme="brand" heading="And a brand card inside it" />
</Section>Anywhere else, use the class directly. It is just CSS:
<div class="theme-invert padding-5 radius-main">
Contrasts with whatever surrounds it.
</div>The contract
Every theme declares the same tokens. If you add a fifth theme, declare all of them or components inside it will fall back to whatever the parent said.
What a theme sets
| Name | Value | Notes |
|---|---|---|
--background | the surface color | Applied automatically to any element carrying a theme class. |
--background-2 | a raised surface | For cards and panels sitting on the background. |
--background-skeleton | a faint tint | The placeholder behind an image or video while it loads. |
--text | body text | Also the basis for borders and muted text through color-mix. |
--border | hairline color | Derived from the text color, so it works on any surface. |
--heading-accent | accent color | Used by .heading-accent for a highlighted word inside a heading. |
--button-* | background, border, text, and their hover pairs | The primary button set. |
--button-2-* | the same, for the secondary button | Outlined by default. |
--link-* | text and underline colors | Including the hover state. |