Building with Terrazzo
Terrazzo reads Scalar’s scalar.resolver.json directly, so it builds every
mode from one input with no extra scripts.
The config below is tested automatically with @terrazzo/cli and @terrazzo/plugin-css 2.10.0,
against Scalar’s sample export (two multi-mode collections, every token and style type).
Give it the resolver, and only the resolver
Section titled “Give it the resolver, and only the resolver”import css from '@terrazzo/plugin-css';
export default { tokens: ['./tokens/scalar.resolver.json'], // the resolver alone outDir: './build', plugins: [ css({ filename: 'tokens.css', permutations: [ { input: { theme: 'Light' }, prepare: (css) => `:root {\n${css}\n}` }, { input: { theme: 'Dark' }, prepare: (css) => `:root[data-theme="dark"] {\n${css}\n}` }, ], }), ],};npx terrazzo buildThis writes one tokens.css with a :root block for Light and a [data-theme="dark"] block for
Dark. References between tokens, across files, become var() chains.
Don’t list the token files next to the resolver. Terrazzo only reads modes when the resolver is
its only input. With other files beside it, it errors with Resolver must be the only input; a
glob that happens to match the resolver and the token files does the same.
Matching your modes
Section titled “Matching your modes”Each entry in permutations picks one context per modifier in the resolver. A modifier is one
multi-mode Figma collection, named after it; its contexts are the mode names, exactly as in Figma.
Open scalar.resolver.json and look under modifiers to see yours:
"modifiers": { "theme": { "contexts": { "Dark": [ … ], "Light": [ … ] }, "default": "Light" }}- One multi-mode collection: one permutation per mode, as above.
- Several: each permutation names a context for every modifier, for example
{ theme: 'Dark', density: 'Compact' }, with a selector to match. - No multi-mode collections: there are no modifiers, so use a single permutation with
input: {}and a:rootselector.
Naming warnings
Section titled “Naming warnings”Terrazzo’s linter warns about token names that aren’t kebab-case. Scalar keeps your Figma names’
casing, and style names are often capitalized (Heading/Large), so expect these warnings. The
build still succeeds; to silence them, turn the rule off:
lint: { rules: { 'core/consistent-naming': 'off' } },Things to know
Section titled “Things to know”$roottokens (a token with tokens nested under it) are named after their group (--text-warning), and references to them work. Nothing to set up.- Gradients come out as their color stops (
var(--color-red-500) 0%, rgb(96% 62% 4%) 100%). The format doesn’t carry the direction, so wrap them inlinear-gradient(<angle>, …)where you use them. - Typography extras (italic, text case, decoration) live in
$extensions, which the CSS plugin doesn’t read. See Known limitations. - A
numbertoken that points to a size token stops Terrazzo with a type error. This happens when an unscoped number variable aliases a size variable; give the number variable a size scope in Figma.