Theme tokens
A small, opinionated token system that keeps every block on-brand without per-merchant tweaks.
Why tokens
A merchant chooses a theme once. Every block, every plugin, every transactional email reads from the same token set. Your block stays on-brand even when a merchant flips from a soft pastel theme to a high-contrast one — without you releasing a new version.
Namespaces
| Namespace | Examples | Use for |
|---|---|---|
color | color.bg, color.fg, color.brand, color.muted | Backgrounds, text, accents |
font | font.body, font.display, font.mono | Type families |
size | size.body, size.h1...h4, size.caption | Type scale |
radius | radius.sm, radius.md, radius.lg, radius.full | Border radii |
space | space.1...space.10 | 4px-based spacing scale |
motion | motion.fast, motion.base, motion.slow | Transition durations |
shadow | shadow.subtle, shadow.elevated | Elevation |
Reading tokens
import { css, token } from '@aeonzap/plugin-sdk/styling';
const styles = css({
card: {
background: token('color.bg'),
color: token('color.fg'),
borderRadius: token('radius.lg'),
padding: token('space.4'),
boxShadow: token('shadow.subtle'),
transition: `transform ${token('motion.fast')} ease`,
},
});Inheritance
A merchant theme is a partial override of the platform default. The platform ships a base set of values, themes layer on top, and merchants tweak a small number of leaf values. Resolution always walks bottom-up: merchant override -> theme -> platform default.
Override hierarchy
- platform default — every token has a value here
- theme — installed by the merchant, overrides any subset
- merchant — the live merchant overrides per-token in the editor
- block local — a block can override one token for its own subtree only
Custom tokens
Plugins can declare new tokens under their own id namespace. Other plugins can read them but cannot override them. This is how the Reviews plugin exposes color.com.acme.reviews.star to themes that want star colors to match brand.
definePlugin({
id: 'com.acme.reviews',
// ...
tokens: {
'color.com.acme.reviews.star': { default: '#f5b301', kind: 'color' },
'size.com.acme.reviews.heading': { default: '1.5rem', kind: 'size' },
},
});Dark mode
Every color token has paired light and dark values. Use token("color.bg") and the runtime picks the right value based on the visitor's preference and the merchant's policy. Never branch on a media query inside your block.