Theming with Modifiers
The Modifier System
Section titled “The Modifier System”The resolver’s modifier system enables theming without token duplication. Define base tokens once, then overlay context-specific overrides for themes, densities, and brands.
Basic Light/Dark Theming
Section titled “Basic Light/Dark Theming”- Create a resolver with a
thememodifier (light/dark contexts) - Define base tokens with raw color values
- Define theme tokens as semantic aliases that switch per theme
{ "version": "2025.10", "sets": { "base": { "sources": [{ "$ref": "./tokens/base.json" }] }, "alias": { "sources": [{ "$ref": "./tokens/semantic.json" }] } }, "modifiers": { "theme": { "default": "light", "contexts": { "light": [{ "$ref": "./tokens/themes/light.json" }], "dark": [{ "$ref": "./tokens/themes/dark.json" }] } } }, "resolutionOrder": [ { "$ref": "#/sets/base" }, { "$ref": "#/modifiers/theme" }, { "$ref": "#/sets/alias" } ]}Multi-Dimensional Theming: Theme × Density
Section titled “Multi-Dimensional Theming: Theme × Density”Use multiple modifiers for theme × density (or theme × brand):
- Resolver with
themeanddensitymodifiers - Resolution order: base → density → theme → semantic
Each permutation (e.g. light+compact, dark+comfortable) produces a complete token set.
CSS Bundle with Dynamic Selectors
Section titled “CSS Bundle with Dynamic Selectors”Use a dynamic selector function so the base maps to :root and each modifier maps to a data attribute:
css({ name: 'themed', file: 'tokens.css', preset: 'bundle', selector: (modifierName, context, isBase, allModifierInputs) => { if (isBase) return ':root' return `[data-${modifierName}="${context}"]` },})Output:
:root { --color-background: #ffffff; }[data-theme="dark"] { --color-background: #111111; }[data-density="compact"] { --spacing-medium: 12px; }CSS with Media Query for prefers-color-scheme
Section titled “CSS with Media Query for prefers-color-scheme”Use mediaQuery to have dark theme apply automatically when the user prefers dark mode:
css({ name: 'auto-theme', file: 'tokens.css', preset: 'bundle', mediaQuery: (modifierName, context, isBase, allModifierInputs) => { if (modifierName === 'theme' && context === 'dark') { return '(prefers-color-scheme: dark)' } return '' },})Standalone Files per Theme
Section titled “Standalone Files per Theme”For platform-specific builds, use the standalone preset with dynamic file patterns:
- JSON:
file: 'tokens-{theme}.json'→tokens-light.json,tokens-dark.json - Swift:
file: 'DesignTokens-{theme}.swift' - Kotlin:
file: 'DesignTokens-{theme}.kt'
Modifier Preset for Overlay CSS
Section titled “Modifier Preset for Overlay CSS”Use preset: 'modifier' to output only tokens that differ between base and each modifier. Useful for overlay/patch files that layer on top of a base stylesheet.