Themes in Depth
The complete theming feature set. For the concept and the render-time model, see Theming; this page catalogs the full surface.
The token dimensions
A ChainRender theme is a set of design tokens (W3C Design Tokens aligned). The full surface:
| Dimension | Tokens |
|---|---|
| Color | 23 semantic colors (bg, surface, fg, muted, border, primary, accent, success, warning, danger, info + their foreground pairs, hover/active/focus/disabled/selected) |
| Series palette | a 6-color ramp for multi-series charts |
| Typography | fontFamily, monoFamily, a size scale (title/heading/body/label/legend), four weights, lineHeight, letterSpacing, textTransform |
| Spacing | xs / sm / md / lg / xl |
| Sizing | control height, icon size, chart min-width, content max-width |
| Border | width, radius, stroke style |
| Elevation | none / sm / md / lg shadows |
| Motion | fast / base / slow durations, easing |
| Layering | z-index scale |
| Breakpoints | responsive breakpoints |
Components reference tokens (var(--cr-space-md)), never hardcoded values — which is why changing one token
re-flows the whole page.
Presets
Three presets ship, all fully on-chain and drift-locked between the SDK and the on-chain generator:
- Light — the default.
- Dark — a genuine dark preset (dark surfaces, light text, brightened series).
- High-contrast — WCAG AAA (near-black on white, thicker borders/focus).
Built-in invariants (an inaccessible theme can't ship)
- Legibility floor — no font size below 12px, enforced.
- Contrast invariant — every key foreground/background pair meets WCAG AA (AAA for high-contrast), enforced as a build-failing check. A low-contrast theme is rejected at build time.
Render-time application (zero gas)
Themes apply via the presentation context at render time — the same app renders with any theme, no redeploy:
// Render with a presentation context (theme/palette/dims) via the on-chain
// renderHashWithContext entrypoint. The context is encoded and passed to the router;
// the app hash is unchanged. (See the runtime reference for the exact call.)
const html = await renderComponent({ rpc, router }, hash); // + presentation context
And for whole-page iteration, override the tokens directly — the token-driven CSS re-flows the entire page in the browser at zero gas, zero chain calls. See Build, Grade & Style Before Deploy.
ThemeSets (the theme registry)
Themes are discoverable + shareable via ThemeSets — an ownerless, staking-aware theme registry. Author a theme, preview it locally, then submit it to a ThemeSet so others can find and use it. Themes are content-addressed, so a theme has a permanent identity like an app.
Generating theme CSS in code
import { lightThemeCss, darkThemeCss, fullThemeCss } from "@chainrender/client/runtime";
const css = fullThemeCss(myTokens); // your token set → the complete component CSS