Appearance
Nesting Mechanism
How nesting works
The token system is hierarchical:
text
Seed tone
└─ Surface 0 (tone computed from seed via levelConfig)
├─ Content on Surface 0 (contrast from Surface 0 tone)
├─ Inv-Content on Surface 0 (flipped direction)
├─ Container 0 on Surface 0 (contrast from Surface 0 tone)
│ ├─ Content on Container 0 / Surface 0
│ └─ Inv-Content on Container 0 / Surface 0
├─ Container 1 on Surface 0
│ └─ ...
├─ Inv-Container 0 on Surface 0 (flipped direction)
│ ├─ Content on Inv-Container 0 / Surface 0
│ └─ ...
└─ ...
└─ Surface 1
└─ ... (same structure repeated)
└─ Surface 2
└─ ...Collection mapping
Each nesting combination gets its own Figma collection (in balanced structure — the seeded themes (empty + the brand examples) ship as compact, where everything collapses into one color collection; granular splits per surface/frame level). Collections are flat and theme-agnostic: the top-level segment is the color theme category, not the theme name (a Figma file holds exactly one Systema theme). Direct and inverse tokens are merged into the same collection (inverse tokens use path prefixes). Balanced layout:
color/surfaces-- all surface levels (scrims also merge here)color/containers-- all container levels, with the surface level in the variable path prefix (e.g.surfaces-0/…,surfaces-1/…; direct + inverse viainv/prefix)color/content-- all content tokens (content on surfaces and content on containers), again with the surface level in the path prefix (direct, inverse, on-inv, inv-on-inv)color/meta-- meta tokens
In granular structure these path prefixes each become their own collection -- e.g. color/containers/surfaces-0, color/content-on-surfaces/surfaces-0, color/content-on-containers/surfaces-0/… -- splitting every surface level into a separate collection.
Collection names embed the sanitized entity name rather than the literal word "containers"/"content" — e.g. renaming the Content entity to "Typography" yields
color/typography-on-surfaces/.... The defaults above assume the stock entity names.
Why split per surface level?
Containers on Surface 0 have different tones than containers on Surface 2. A button at 1.6:1 contrast on a near-white surface is a different color than the same 1.6:1 contrast on a darker surface. By splitting per surface level (via the path prefix in balanced, or into separate collections in granular), designers can reference the exact container level they need for each nesting depth.
surfaceScope optimization
If a container or content entity sets surfaceScope: "last" (the editor surfaces this as the Calculate on → Last surface control; values are all / first / last, default all), tokens are only generated for the last (deepest) surface level, reducing collection count significantly. first generates only on the lowest (Surface 0) level. In the preview, all levels still show the same values (computed from the scoped level) for visual consistency.