Theming
Every visual decision in Rime is a CSS custom property. A theme is a short theme.css that changes the values you care about; everything else recomputes from them.
Token layers
- Primitives: the palette (--brand, --brand-action, --brand-strong, --brand-deep, --brand-soft, --support, --danger-base) and its rgb channels (--rgb-brand), fonts, the chart palette.
- Semantic: ink (--ink-*), surfaces and glass (--page-background, --glass-fill, --surface-solid), lines, status, focus, gradients.
- Scales: radius (--r-*), --density, control heights, borders, shadows, blurs, motion.
- Per component: --button-radius, --input-height-md, --table-head-fill and the rest. Undeclared by default: each module reads them with a fallback, so setting one restyles every instance. Each component page lists its own.
Presets and modes
Theme = preset x mode. Rime Default (frosted glass in Frost blue) is the base; data-theme="flat" switches to Rime Flat (opaque, small radii, no blur). Dark mode is data-mode="dark" or the .dark class, with either preset.
<html data-theme="flat" class="dark"> {/* Rime Flat, dark mode */}Make a theme
Open Rime Studio: start from a preset, drop in a logo or screenshot to extract a palette, tune shape, glass, shadows and hover, check contrast in both modes, save it by name and export theme.css. Load it after tokens.css.
/* Acme: generated by Rime Studio. Base: Rime Default. */
:root {
--brand: #0f9b8e;
--brand-action: #0b7a70;
--brand-strong: #075f57;
--rgb-brand: 15, 155, 142;
--r-md: 6px;
--button-radius: 999px;
}
.dark, [data-mode="dark"] {
--brand: #3fc6b8;
--rgb-brand: 63, 198, 184;
}The one CSS rule
A custom property resolves var() where it is declared. --wash-hover is rgba(var(--rgb-brand), 0.05) on :root, so a theme that changes --rgb-brand must also be declared on :root (then the wash recomputes), or redeclare the composites it affects. The Studio's default export (only what changed, at :root) is right.