Severity: Blocking — we cannot adopt extended collections
The problem
A node holds one mode entry per collection family, and an extension's mode IDs are encoded with the collection ID. So choosing a brand and choosing a mode are one choice, not two. A node cannot say "use Brand B, keep the mode you inherit" — or "use Hover, keep the brand you inherit".
This is not a broken lookup: ExtendedVariableCollection.modes[] exposes parentModeId, so the parent↔extension mode mapping already exists. The problem is that there is only one slot to write it to.
The ask: decouple the data source (collection variant) from the context state (mode), each independently settable and inheritable.
Our setup
One mode axis per collection, because modes are per-collection and mode counts are capped:
| Collection | Axis | Mode set by |
|---|---|---|
| Semantic | Light / Dark | designer, on the artboard |
| Viewport | s / m / l / xl | component (responsive variants) |
| Interaction state | Idle / Hover / Pressed | component (state variants) |
Brand is a fourth, orthogonal axis. Component-set modes are intentional — a variant sets the mode so nested components switch with it.
Repro A — switching brand discards the inherited mode
- Collection
Semantic(Light,Dark), extended asBrand B. - Frame set to
Brand A → Dark; on a child frame, switch the variant toBrand B.
Observed: child resolves to Brand B → Light. Expected: variant changes, mode keeps inheriting. (Also: https://forum.figma.com/share-your-feedback-26/extended-collections-doesn-t-respect-mode-hierarchy-48123)
Repro B — the blocking one
- Collections
Interaction state(Idle,Hover) andSemantic(Light,Dark), both extended asBrand B. - A component's
Hovervariant sets an explicit modeInteraction state → Hover. - Set a top-level frame to
Brand B, insert an instance, switch it toHover.
Observed: the instance resolves state variables against the parent collection — the pin authored in the component carries the parent collection with it and silently overrides the brand, in every instance and every file. Expected: the pin selects the mode; the variant keeps inheriting.
The rule this produces: a collection may either be extended, or have its modes pinned by components — never both. Every state and viewport collection we have falls on the wrong side.
No plugin workaround
parentModeId makes rewriting artboard modes trivial, but not Repro B: rewriting a component's pin hard-codes a brand into the component; clearing it removes the state behaviour the component exists for. setExplicitVariableModeForCollection has no way to express "pin the mode, inherit the variant".
What a narrow fix would miss
Preserving the mode when a user switches variant fixes Repro A and leaves us exactly as blocked. The reset is the symptom; the coupled slot is the cause. Any fix keeping one slot per family still cannot express a component that pins state while inheriting brand — and that is what modes were built for.
Why it matters beyond our file
Splitting axes across collections is what Figma's own constraints push teams toward. Extended collections are only applicable to collections no component ever pins — in practice, a single colour layer. The more carefully a system was factored before the release, the less of it survives.
Same on the code side: token pipelines model brand and theme as independent dimensions (in DTCG, a brand resolver overriding sets, with theme/viewport/state as modifiers). Value-level sync works well; what breaks is the node-level assignment, which has to be flattened into one coupled slot on import — irreversibly. Decoupling the two dimensions would make extended collections the structural mirror of how tokens are already authored in code.
