Theming
Identical JSON, three looks. Consumers own the look: override --baht-* tokens for the quick
wins, or target the frozen .baht-* classes for anything deeper (light DOM — your CSS reaches
every node). Try the knobs live in the theme lab.
Default tokens.css as shipped
Bank token overrides
Terminal tokens + .baht-* classes
How the bank theme is done
Section titled “How the bank theme is done”Three tiers of tokens, top down: raw scales (--baht-green-600), the palette
(--baht-primary, --baht-base-100, --baht-error, …) and the semantic colours the
components read (--baht-color-primary-hover, --baht-color-border). The palette → semantic
derivation (color-mix for hover, tint, wash, focus) runs once on :root, so:
- Whole app: set the palette on
:root— one--baht-primaryswap rethemes everything. The theme lab does exactly this. - One scope (a card, a page section): set the semantic
--baht-color-*tokens directly, as the bank theme below does. Shape tokens (--baht-radius-*,--baht-size-field) work at either level.
.theme-bank { --baht-color-primary: #047857; --baht-color-primary-hover: #065f46; --baht-color-primary-tint: #d1fae5; --baht-color-focus: #047857; --baht-color-surface: #f0fdf4; /* inputs, cards */ --baht-color-border: #a7f3d0; --baht-color-border-control: #6ee7b7; --baht-radius-field: 12px; /* inputs, buttons */ --baht-radius-selector: 4px; /* checkbox, toggle, badge */ --baht-size-field: 2.625rem; /* control height (42px) */ --baht-font-family: Georgia, serif;}The terminal look goes one step further and styles the frozen light-DOM classes directly:
.theme-terminal .baht-label { text-transform: uppercase; letter-spacing: 0.08em;}.theme-terminal .baht-control { border-style: dashed;}Dark mode is the same mechanism: bank20baht-ui/tokens.css re-declares the palette under
[data-baht-theme='dark'], so set that attribute on <html> (this site mirrors Starlight’s
theme picker into it).
How the banknote themes are wired
Section titled “How the banknote themes are wired”Pick a banknote up in the corner — the whole site and this snippet swap together. That is all “CSS on the fly” is: override the raw scale on a scope and every semantic token derives from it.