Themes
A website has one theme. Light tokens are the public look. Dual theme lets visitors switch to a separate dark token map. Reads need website access. Writes need update_header_footer.
Dual theme
When dual theme is off, the site uses light tokens only. When it is on, visitors can switch, and dark tokens apply.
Presets
A preset copies its tokens into the light slot, the dark slot, or the single theme. get_theme returns sourceLightDefaultThemeId, sourceLightDefaultThemeName, and the dark pair. Applying a preset does not clear page transitions.
Token layers
Tokens follow the theme editor. Page: background colors (page, surface, surfaceMuted, elevated, overlay), spacing (xs, sm, md, lg, xl, xl2, xl3), block padding, and inline padding (none, xs, sm, md, lg, xl). Text: text colors (primary, secondary, muted, inverse, link, linkHover), font families (body, heading, mono) with an optional typography.fontFace file for each (url, family, weight, style; woff2, woff, ttf, or otf; omitted faces keep the font family string), font sizes (xs through xl3), font weights (normal, medium, semibold, bold), and line heights (tight, normal, relaxed). Elements: accent colors (primary, primaryHover, secondary), border colors (default, subtle, strong, focus), border widths (none, sm, md, lg), radii (none, sm, md, lg, xl, full), and shadows (none, sm, md, lg, xl, inner). Scrollbar: width, track, thumb, thumbHover, and radius.
CSS variables
Each token is published as --site- plus the path with dots replaced by dashes. colors.accent.primary becomes --site-colors-accent-primary.
How blocks use tokens
Blocks do not store raw theme CSS. Font family is theme-heading, theme-body, or theme-mono, which read typography.fontFamily.heading, .body, and .mono. When typography.fontFace has a file and family for that slot, the theme stylesheet emits @font-face and points the font-family variable at the uploaded family. Padding, border width, and radius fields store scale keys (none, sm, md, lg, and xl or full on the scales that have them). Those keys resolve to padding.block, padding.inline, border.width, and border.radius. Filled buttons use colors.accent.primary.
Read theme state, including pageTransition and the source preset ids.
GET /api/v1/{locale}/{websiteId}/themeReplace theme settings.
PUT /api/v1/{locale}/{websiteId}/themeWrites
Send lightTokens, darkTokens, dualThemeEnabled, or any combination. A token object merges into the stored map; omitted keys stay. An invalid value names the token path, such as lightTokens.colors.accent.secondary. An omitted map is left unchanged. dualThemeEnabled can be sent on its own.
Page transitions
The theme editor saves page transitions. type is none, fade, slide, slideUp, or zoom. durationMs is 100–1000. easing is linear, ease, easeIn, easeOut, or easeInOut. get_theme returns pageTransition. save_theme does not accept it.
MCP: get_theme, save_theme.