Appearance
Token Engine
Located in src/lib/token-engine.ts. Generation runs entirely in the UI thread (not the sandbox) and produces a flat array of GeneratedToken objects.
Generation Phases
The current pipeline has six phases, mirrored in src/lib/token-engine.ts (search "Phase N:" inline). Collections use the flat layout under color/... (theme-name is no longer prefixed onto the collection path under the single-theme-in-Figma policy).
| Phase | What | Collection pattern |
|---|---|---|
| 0: Meta | theme-name (STRING, theme-level) and seed-color (COLOR, color-category) plus per-entity meta if Push meta is on. | meta, color/meta |
| 1: Surfaces | Level entities from seed color. Condition + interaction segments skipped — surfaces don't iterate either axis. | color/{entity} |
| 2: Containers | Frame entities per surface level. Iterates conditions × interactions when the active conditions are interactive. | color/{entity}/{surface}-{level} |
| 2b: Inv-containers | Same frames computed with flipped direction. Merged into the same collection as Phase 2 with an inv/ prefix on the variable path (no separate inv- collection). | color/{entity}/{surface}-{level} (paths gain inv/ prefix) |
| 3: Content | Top-layer entities on surfaces, containers, and inv-containers. Both directions; inverse merged with inv/ prefix. | color/{entity}-on-{parent}/{surface}-{level}[/{containers}-{level}] |
| 4: Scrims | Overlay entities from seed color. Condition + interaction segments skipped. | color/{entity} |
| 5: Fixed colours | Mode-invariant flavour for frame / top-layer entities when Enable Fixed colors is on. Synthetic single-mode collection. | color/fixed/{entity} |
Token Path Structure
text
color/{collectionName}/{conditionName?}/{interactionName?}/c-{contrastIndex}/{colorId}- Static condition (e.g.
Disabled,interactive: false) → no interaction segment:color/{entity}/disabled/c-N/color-name. - Interactive condition (e.g.
Enabled) → both segments:color/{entity}/enabled/{interactionName}/c-N/color-name. - Inverse tokens add an
inv/prefix anywhere along the path. - Surfaces / scrims skip both segments — they don't iterate conditions or interactions:
color/{entity}/c-N/color-name.
Deduplication
Two levels of deduplication:
- Generation-time -- within each (condition, interaction) group, if a token produces identical RGBA values across all modes as a previously generated token with the same dedup key, it is skipped. The count is tracked in
skippedDuplicates. The Skip duplicate tokens switch in Color Settings (default on) controls this. - Push-time (FNV-1a hash) -- each collection's token set is hashed. If the hash matches the stored hash from the previous push (
systema_hashplugin data on the collection), the entire collection is skipped.
The Skip low-contrast tokens switch (default on) is a third filter — independent from dedup — that prunes tokens whose actual contrast against parent falls below the entity's smallest contrast step in EVERY mode (direct AND inverse axis). See Skip low-contrast tokens above.
surfaceScope Filtering
For frame and top-layer entities, the surfaceScope property (all, first, last) determines which surface level indices are included in generation, reducing output for entities that only need to appear on specific levels.
Disabled Filtering
The following are excluded from generation:
- Colors with
enabled === false - Conditions with
enabled === false(note:Enabledcondition is undeletable, but can be disabled to suppress its tokens) - Interactions with
enabled === false - Modes with
enabled === false