Skip to content

FIGMA-SYNC — MATRIZ Editor UI mirror

Figma file: MATRIZ Editor UI · fileKey bZ17CtfEJ11rcV8UHNGKvh · team “Simao” (pro) › project Design System Published team library (since 2026-08-22): library name “MATRIZ Editor UI”, libraryKey lk-b931c8db22df25b8ee2f083c2054745e097825332ca48818ced9d75442953f04… — 177 assets as last published (2 variable collections + Typography strings, 19 text styles, 5 effect styles, all component sets, 128 icons, 6 panel masters). ⚠️ The published library is STALE: as of 2026-08-29 every sampled component reports CHANGED or UNPUBLISHED, so library consumers still see the 2026-08-22 state. After any sync that changes tokens/components, re-publish: Figma UI → file menu → “Publish library…” (the plugin API cannot publish; it’s a manual/browser-driven step). Created: 2026-08-22, generated from code via the official Figma MCP server (write path: use_figma Plugin-API scripts).

Round 5, 2026-10-16: borderless fields (D:editor-outline-reduction, #1065) + Planned/Mobile pages. Variables (Editor Colors, 82 vars). core/field 418:2 light 94%→92% (#ebebeb), dark a.09→.10. New core/field-hover 436:2 (FRAME_FILL/SHAPE_FILL, WEB var(--field-hover)): light 88% (#e0e0e0), dark white a.14. The six “drift” variables were already correct in Figma (dark core/secondary 208:3 + core/accent 208:5 white a.15, core/secondary-foreground 208:4 + core/accent-foreground 208:6 + sidebar/accent-foreground 208:15 white a.93, sidebar/ring 208:16 white a.75 = index.css .dark), so nothing changed there; the drift was code-side and #1065 fixed it. Older drift found and fixed in the same pass (dark mode, values from index.css .dark): core/background 2:3 →#16161a, core/card 2:5 + core/popover 208:7 →#1d1d22, sidebar/background 2:27 →#1a1a1f, core/highlight 204:2 →#2a2a30 (D:dark-ramp-soft-slate, Figma still had the pure-black ramp), core/destructive-text 204:4 →#f98d8d, and alpha nudges core/input 208:10 + core/control 418:3 .40→.41, core/chip-input 418:4 .50→.55, core/muted-foreground 2:14 / core/primary-faded 98:4029 / core/foreground-tertiary 165:2846 .55→.60. Light values for core/input/core/outline/core/muted already matched (--input 52% #858585, --outline 56% #8f8f8f, --muted 96.1%). Components (edited in place, strokes removed, fills bound to core/field, focus = 1px core/ring stroke, hover = core/field-hover). Input 23:646 and Select / Trigger 23:653: all variants borderless; added state=hover (436:12207 / 436:12211) and state=error (1px core/destructive; 436:12209 / 436:12214) desktop variants. PropertyEditor / FieldShell 26:163 (18 value-unit-input frames; hover members use core/field-hover, focused keeps the ring). Grammar / FieldRow 422:791 fields (PairRow 422:816 inherits), Grammar / AlignmentMatrix 422:836, Grammar / SegmentedControl 422:844 (track core/field, active option 422:838 = core/background + Shadow/sm), PropertyEditor / ClusterSwitch 25:131 (track core/field, active chips 13:50 / 25:121 = core/background + Shadow/sm), Button 10:68 variant=outline (20 members: fill core/field, hover core/field-hover, focus ring; outline-dashed untouched). Mobile page: 12 hand-built textarea/search frames un-stroked. Paint trap, again: binding an alpha variable with a placeholder black paint renders black in the component sets even though it rendered correctly in a scratch frame; setting the paint color to the variable’s resolved dark RGB and opacity to its alpha (in addition to binding) fixed it (rule in Figma MCP gotchas above). Bound paints ignore their own opacity when the variable carries alpha; verified in light and dark. Pages. Mobile 424:2 already existed (built 2026-10; undocumented until now): sections Mobile / Shell 424:3 (TabBar 424:128, ScreenHeader 424:142, ListRow 424:164, SectionLabel 424:167, OpenOnDesktop 424:175, FAB 424:181, ViewBanner 424:193, BottomSheet 424:287), Mobile / Slice parts 426:650, and screen sections Shell 425:110 (Sites = Home list 425:111, More, Team, sheets), Canvas 427:754 (edit + inspector 427:755, layers sheet 427:924, preview, publish confirm, replace image), Email 428:1550 (campaigns, new campaign sheet 428:1696 = send step 1, detail, send confirm sheet 428:1991, block edit/add), CMS 430:2867 (collections, items, item editor 430:3193, image source sheet); each in Dark and Light at 390x844. No page was created. Planned - Formats 438:2 (new): 12 frames labelled “PLANNED (not built)” from D:formats-owner-decisions: S3 438:3, DIFF 438:53, S5 438:89, S7 438:160, S12 438:187, S11 438:233, S13 439:2, F6 439:27, M6 Settings > Access 439:88, BULKCAP 439:122, S8 439:161, M6 phone notice 439:193 (only feature with a phone variant; the Formats workspace is desktop). Hand-built from tokens (no components instanced except Mobile / TabBar in 439:193); they are drafts, not specs. Motion Studio skipped (no concrete UI specified). Remaining gaps. No Figma component for NumberControl, Textarea, standalone ValueUnit; FieldShell has no error member; source-switcher (26:163 children) kept its border (code unverified); Tier 3 holdouts stay bordered by design (EntityPicker 423:954, Grammar Tabs 422:846); ActionToggle 338:7370 default keeps its 8% stroke. Dark bg-white/15 active segment in the decision does not match code (ClusterSwitch.tsx:80 = bg-background); Figma mirrors the code. Library not re-published (plugin API cannot): publish from the Figma UI. A UX review of the synced UI and the planned frames was written to the session scratchpad (not committed); its top findings are in the hand-off report. 2026-09-23 (D:ancestor-state-layer, D:view-switch). The state row gained a trailing + trigger (AncestorLayerMenu.tsx, lucide Plus, text-muted-foreground), rendered by PropertyEditorShell.tsx right AFTER <StateTabBar /> in the same flex row (code: outside the bg-muted pill; the mirror draws it as the set’s last child — a known 2px simplification): every PropertyEditor / StateTabBar variant (13:38, 25:132, 25:143, 25:154, 25:165) got an add-ancestor-layer frame (404:725 / 404:730 / 404:735 / 404:740 / 404:745) holding an icon/Plus 9:96 instance at 12px, strokes bound to core/muted-foreground. The popover it opens (ancestor-state input, group-hover row, hover-group checkbox) is NOT mirrored — same precedent as the other un-drawn popovers. New palette icon icon/LayoutList 404:10 (Icons section 9:128, x=120 y=560, createNodeFromSvg, strokes bound to core/foreground @0.93 like the set) for the Filters family’s “View switch” entry; the add-element palette itself has no mirror. Library not re-published from here (plugin API cannot) — publish from the Figma UI. S30 check, 2026-09-21 (D:list-chrome-section). Two chrome changes to sync: CollectionControlSection.tsx’s Mode pill → plain summary sentence + two new nav-option checkboxes, and a new ListChromeSection.tsx mounted from DataBindingProperties.tsx. Checked PropertyEditor / CollectionControlSection 213:6072 before editing: it only ever depicted the FILTER-role rows (Repeater/Field/Operator/Value) — the Mode pill, Rendered items/Reveal size fields and now the two nav-option checkboxes belong to the loadmore/ legacy-pagination/pager-role rows, which this mirror has never drawn. No edit needed there, same as the S36 check’s precedent. PropertyEditor / DataBindingProperties 213:6008 DID need updating: it lists every Data-tab section as a CollapsibleSection Header (9 before this — Data Source/Entry/Pre-Filters/Default Sort/Group By/Limits & Pagination/Repeater State/Empty & Loading/Visitor Controls, in the same order the code renders them, 3 with example bodies drawn), and the code gained a 10th section between Limits & Pagination and Repeater State. Cloned the VISITOR CONTROLS header instance (213:6063, expanded=false/ overridden=false member of set 26:137), retitled its text node to LIST CHROME, and insertChild’d it at the correct index — 213:6008‘s auto-layout (VERTICAL, primaryAxisSizingMode: AUTO, itemSpacing: 1) grew it 388→420px automatically, and the parent row Row / Data & Logic 209:5178 (HORIZONTAL, counterAxisSizingMode: AUTO) re-hugged to match with no manual resize and no sibling reflow (siblings sit side-by-side on the same axis). New node: INSTANCE 399:11 (title text I399:11;26:118). Verified with get_screenshot before and after the move — no clipping, no overlap, spacing matches its 9 siblings exactly. Deliberately left as a collapsed placeholder, same deferral every other un-bodied header here already carries: the roster, the mode-summary sentence, and the Rendered-items/Reveal-size fields the real section shows are NOT drawn — DataBindingProperties’ own documented state is “4 of 9 sections populated… the remaining deferral,” and List chrome joins the 5 (now 6) that aren’t. No library re-publish needed for this change: an INSTANCE of an already-published component was added and repositioned, no component/variant/token definition changed. S36 check, 2026-09-21 (D:controls-on-data-tab). QuickStylesProperties.tsx’s Style-tab quick section stopped mounting the imported-control section, the native filter family (Filter Bar/Group/Control) and the Carousel/Slider sections — they now mount on the node’s Data tab in PropertyEditorShell.tsx (owner call Q1, 2026-09-20: “nothing in the quick-style section”). Checked the mirror before editing it: no edit was needed. PropertyEditor / CollectionControlSection 213:6072 was already grouped under Group / Data & Logic 209:5176 → Row / Data & Logic 209:5178 (alongside DataBindingProperties/ConditionalVisibilityProperties/LinkProperties), not under the Quick/Style family — the module catalog already modelled the destination this fix moves the live code to. PropertyEditor / QuickStylesProperties 213:5616 only ever showed generic collapsed CollapsibleSection Header placeholders (Text style / Fill / Radius / …), never a literal Slider/Carousel/Filter instance, so nothing there depicted the old (now wrong) placement either. FilterBarSection, FilterControlSection, SliderSection and CarouselSection have no Figma mirror at all — confirmed by listing every PropertyEditor / * component under Property Modules - Page Root 209:5165 (19 total, none named for these four) — a pre-existing gap this change neither introduces nor closes; recorded under “Known gaps” below rather than silently skipped. While checking this, found the page map below stale (Property Modules 208:21 / Property Parts 208:22 no longer exist as top-level pages — merged into Property Editor 368:2354 at some point after the last page-map update); corrected in place. Round 4 (FU-5), 2026-09-13. Mirrored the preview-mode comments chrome that landed on master (D:preview-topbar, D:canvas-comments): the new PreviewTopBar.tsx that replaced the floating PreviewModeControls pill, the AppSidebar “To-do” mode, and the canvas comment pins/thread popover. New: Panel / PreviewTopBar 394:3 (Panels page, 1440×56, same fill/border tokens as Panel / TopBar); Canvas / CommentPin 392:363 (SET, axis kind = Open 392:355 / Resolved 392:357 / Draft 392:359); Canvas / CommentThreadPopover 394:2 (both in Section / Preview & modes 209:97 on Canvas & Overlays, which grew 509→849px, pushing Section / Overlays & menus and Section / Command surfaces down 340px — same page, new absolute y); TodoRow 395:587 (Panels page, MenuRow/TreeRow-style wrapper) holding Status=Open 395:588 / Status=Resolved 395:589; Panel / Todo 395:7853 (Sidebar Panels page, x=3060, the 10th→11th sidebar-mode master, instancing the two TodoRow variants). Panel / IconTray 27:432 gained a mode-todo row (394:7627, icon/ListTodo) between mode-modules and mode-settings — the tray’s spacer child shrank 356→316px to keep the master at its original 844px height and BehaviorSwitcher pinned at y=804, matching the code’s modes array order in AppSidebar.tsx. Five lucide icons were missing and got added to the Icons page (section 9:128, grown 580→620px): icon/ListTodo 387:9, icon/MessageSquare 387:13, icon/MessageSquareOff 387:19, icon/MapPin 387:24, icon/RotateCcw 387:29 — all bound to core/foreground per sync-contract rule 4, built via figma.createNodeFromSvg() (the upload_assets egress block still applies, see gotcha below). Canvas / PreviewModeControls 213:7494 is NOT deleted — its description now says SUPERSEDED (D:preview-topbar), left in place for reference. The CommentComposer face of CommentThreadPopover.tsx is not separately mirrored — only the CommentThread (read) face; noted as a gap below. Library re-publish is pending (adds 5 icons, the CommentPin set, CommentThreadPopover, Panel/PreviewTopBar, Panel/Todo, TodoRow to the count in the header above). Round-2 code→Figma sync, 2026-08-30. Six surfaces that landed on master that day were pushed into the mirror: the QuickToolbar identity-bar rebuild (D:toolbar-identity), the token popover’s new Scope tab (D:token-scopes), the token matrix’s inline rename (D:token-rename), the symbol instance bar’s copy state (Detach→Unlink), and the library variant section’s multi-axis rewrite (D:library-variant-fixes). The three new inventory sections needed no work — round 3 had already mirrored them. Details below under “Round 2 (2026-08-30)”.

Re-synced from the live file 2026-08-29 (round 3 — plans/FIGMA-PARITY-ROUND3-PLAN.md; the audit that triggered it is docs/Research/FIGMA-MIRROR-DRIFT-AUDIT.md). What changed: the dark palette is now alpha-based on BOTH sides (D:alpha-token-rebase), Editor Colors went 52 → 81 variables, and four new pages carry 142 components mirroring the editor surfaces that had never been drawn. The variable-ID map below was regenerated — 22 IDs in the previous revision pointed at deleted variables.

Source of truth: the CODE. The Figma file is a mirror of frontend/src. When they disagree and no intentional design change is in flight, the code wins. When a design change is made by hand in Figma, it flows back to code via the /figma-editor-sync skill, and this doc is updated in the same change.

Sync contract (read this before touching either side)

Section titled “Sync contract (read this before touching either side)”
  1. Editor theme tokens live in frontend/src/index.css (lines ~6–85) + frontend/tailwind.config.js. They are mirrored 1:1 as Figma variables in the collections below. Any change to a CSS variable value, a Tailwind color mapping, or --radius MUST be pushed to the matching Figma variable (both modes), and vice-versa.
  2. Dark is the default mode in Figma (first mode), because the app defaults to dark (index.html FOUC script, themeStore default). Light is the second mode.
  3. Chrome accent semantics (orange=component/override, sky=data, emerald=style-dot, purple=state-dot, teal=dynamic-dot, blue=binding, amber=conditional/warning, violet=variant chip, green=shared-style-linked) are contracts from frontend/src/lib/node-semantics.ts and frontend/src/components/property-editor/registry/DESIGN-SYSTEM.md. They exist as semantic/*, dot/*, state/*, accent/* variables. Their WEB code syntax stores the Tailwind class, not a CSS var, because that is what the code uses.
  4. Icons are lucide-react 0.552.0, uploaded as exact SVGs and componentized at 16×16 with stroke ≈1.333 (24-grid rescaled ×2/3), strokes bound to core/foreground. If the app adds a new lucide icon, regenerate its SVG from frontend/node_modules/lucide-react/dist/esm/icons/ (follow alias re-exports) and add an icon/<PascalName> component. Never redraw icons by hand.
  5. Fonts: Geist / Geist Mono (Google Fonts; loaded in index.html). In Figma the style name is SemiBold (no space) — unlike Inter’s Semi Bold.
  6. No motion to model. tailwind.config.js ships plugins: [] (no tailwindcss-animate), so all shadcn enter/exit animation classes are inert in the app.

Figma object map (node IDs are stable — do not recreate, edit in place)

Section titled “Figma object map (node IDs are stable — do not recreate, edit in place)”
Page ID Holds
_staging (scratch, keep empty) 0:1 —
Cover 6:2 frame 22:432
Foundations (swatch boards, type ramp) 6:3 22:436 / 22:600 / 22:764
--- LIBRARY --- (divider) 6:4 —
Icons 6:5 section 9:128, 152 icon/* components
Components 6:6 39 components in 5 sections (162:4892 UI Primitives · 162:4894 Property Editor · 162:4896 Chrome & Navigation · 162:4898 Sections · 162:4900 CMS)
Chrome Parts 6:7 empty — its 8 components moved onto Components 6:6; the IDs below are unchanged
--- SCREENS --- (divider) 6:8 —
Editor Screen 6:9 full-UI frames 14:2 (dark) / 28:1307 (light)
Panels 27:371 22 masters
CMS 63:2 4 panels + 12 CMS / * components + the owner’s 2026-08-28 exploration
Sidebar Panels 73:2 11 masters, one per AppSidebar.tsx mode (added 2026-09-13: Panel / Todo 395:7853)
--- MICRO-PANELS --- (divider) 208:20 —
Property Editor (found 2026-09-21 as the merged home of the old “Property Modules” 208:21 / “Property Parts” 208:22 pages — those two IDs no longer exist as top-level pages; get_metadata/figma.root.children both confirm) 368:2354 Panel Assembly 368:2355 (Panel/Properties, PropertyTabStrip, SelectionColors, GridRules, AddPropertyButton, TokenDetailPopover); Property Modules - Page Root 209:5165 (19 PropertyEditor / * module components, grouped into Group / <family> sections — PropertyEditor / CollectionControlSection 213:6072 sits in Group / Data & Logic 209:5176 alongside DataBindingProperties/ConditionalVisibilityProperties/LinkProperties, NOT under the Quick/Style family — see D:controls-on-data-tab note below); Property Parts Root 365:2705; WIP / Grid Layout Explorations 368:2356; Data & Logic Sub-editors 368:2357 (the DataBindingProperties sub-editor shelf: DataSourceSelector, QueryBuilder, SortingEditor, GroupByEditor, LimitsEditor, RepeaterStateTabs, PropertyBindingsEditor)
Canvas & Overlays 208:23 22 components
App Surfaces 208:24 44 components
Mobile (documented 2026-10-16) 424:2 phone editor chrome, 5 sections, 390x844 frames Dark+Light (see Round 5 note)
Planned - Formats (2026-10-16) 438:2 12 “PLANNED (not built)” frames, D:formats-owner-decisions
Collection ID Modes
Editor Colors (82 vars, +core/field-hover 436:2: core/*, chart/*, sidebar/*, semantic/*, dot/*, state/*, accent/*, status/*, overlay/*) VariableCollectionId:2:2 Dark 2:0 (default), Light 2:1
Editor Metrics (34 floats: radius/*, layout/*, icon/*, spacing/*px, text/*) VariableCollectionId:4:2 Value
Editor Typography (family/sans = Geist, family/mono = Geist Mono) VariableCollectionId:4:37 Value
Bookbuilder Colors (MISPLACED — relocated to the bookbuilder file, pending deletion here; see “Bookbuilder tokens” below) VariableCollectionId:203:2 Value 203:0

The 2026-08-29 drift check is CLOSED — the hand-rework was adopted, not reverted. An independent code→Figma pass that same day (master d7e0c70) found the Editor Colors collection hand-edited away from code: 22 ledger variables deleted, ~20 added with no WEB code syntax, and every dark neutral rewritten to white-alpha overlays while light still matched index.css. It correctly declined to revert and asked for a direction. The owner’s call was to adopt it, so round 3 pulled it into code (D:alpha-token-rebase — see plans/FIGMA-PARITY-ROUND3-PLAN.md §1 for the Tailwind mechanism that makes token-level alpha survive /opacity modifiers), re-created the deleted variables the app still uses, and gave every variable a WEB code syntax. The full finding is preserved in docs/Research/FIGMA-MIRROR-DRIFT-AUDIT.md; the collection is authoritative again, in both directions.

Also landed by that pass and still true: core/highlight 204:2, core/highlight-foreground 204:3, core/destructive-text 204:4 (FX-9 code tokens that Figma lacked, values from index.css both modes, with swatch rows on both Foundations boards — dark 204:5/204:8/204:11, light 204:14/204:17/204:20); Editor Metrics text/micro-9|label-10|value-11 WEB syntax corrected to text-4xs/text-3xs/text-2xs (the FX-9f micro-type scale); and 10 chrome icons (Icons page below). Checked clean and still clean: --radius 6px = radius/lg, Geist/Geist Mono, and the layout metrics (topbar 56, tray 48, panel 300/240–640, headers 40, control 24/28).

Do not hand-maintain a full variable-ID list here. The previous revision’s list went stale in three days (22 of 54 IDs deleted, 20 added under new IDs). Query the live file by name instead:

const vars = await figma.variables.getLocalVariablesAsync()
const byName = Object.fromEntries(vars.map(v => [v.name, v.id]))

Anchors worth knowing, because code reads them constantly: core/background 2:3, core/foreground 2:4, core/card 2:5, core/primary-foreground 2:10, core/muted 2:13, core/muted-foreground 2:14, core/destructive 2:17, core/border 2:19, core/ring 2:21, chart/1–chart/5 2:22–2:26, sidebar/background 2:27, sidebar/foreground 2:28, sidebar/accent 2:31.

Added 2026-08-29 (round 3): core/{primary 208:2, secondary 208:3, secondary-foreground 208:4, accent 208:5, accent-foreground 208:6, popover 208:7, popover-foreground 208:8, card-foreground 208:9, input 208:10, destructive-foreground 208:11} (re-created — the app still uses them); sidebar/{border 208:12, primary 208:13, primary-foreground 208:14, accent-foreground 208:15, ring 208:16}; status/approved-{bg 208:17, fg 208:18, dot 208:19} (the code has FIVE statuses); semantic/{component-badge-bg 234:6246, data-text 234:6247, data-badge-bg 234:6248, conditional 234:6249} and state/shared-style-linked 234:6250 (restored node-semantics.ts contracts); accent/{insert-flow 234:6251, insert-cross 234:6252, state-lens-ghost 234:6253} — these three expose colours the code hardcodes (CanvasAddButton.tsx:90-91 #3b82f6/#8b5cf6, duplicated in preview.html; StateLensChip.tsx:123 indigo-500, a hue with no family in this system).

Gap, 2026-10-05 (D:brand-logo-lime): --brand (74 92% 54%, #c3f61e) and --brand-foreground (0 0% 3.9%) are in index.css/tailwind.config.js but not yet mirrored — add accent/brand + accent/brand-foreground to Editor Colors (same value both modes) and to both Foundations swatch boards, then record the IDs here.

Added 2026-08-30 (round 2): semantic/override-badge-bg 301:1270 — bg-orange-500/10, the BADGE_TONE_CLASS.override wash behind state/override text. It exists because an INSTANCE drops a manually-set paint opacity when the paint is variable-bound: the identity chip’s badges carried opacity: 0.15 on a paint bound to semantic/component-text, and every instance of them re-resolved to the variable’s own opaque value, rendering solid orange blocks inside Panel / QuickToolbar. The wash has to live IN the variable. The badge fills are now bound to semantic/component-badge-bg 234:6246 / semantic/data-badge-bg 234:6248 / semantic/override-badge-bg 301:1270 / core/muted 2:13 accordingly.

core/secondary-foreground 165:2846 was renamed core/foreground-tertiary — it holds white@32%, which is a tertiary text tone, NOT shadcn’s --secondary-foreground. The real --secondary-foreground is 208:4. Every variable now carries a WEB code syntax; that mapping is the code↔design contract while Code Connect stays plan-blocked.

19 text styles (Micro 9/*, Label 10/*, Value 11/*, XS 12/*, SM 14/*, Base 16/*, LG 18/SemiBold, Mono 9–12/Regular) and 5 effect styles (Shadow/sm|default|md|lg|xl = Tailwind v3 defaults).

Components (Components page) — all interactive sets carry a state axis (2026-08-22)

Section titled “Components (Components page) — all interactive sets carry a state axis (2026-08-22)”
Component ID Variants Code source
Button (set) 10:68 variant(6) × size(4) × state(default/hover/focus/disabled) = 96 ui/button.tsx
Badge (set) 10:81 variant(6) × state(default/hover) = 12 ui/badge.tsx
Input (set) 23:646 state default/focus/disabled/hover/error, borderless (default member = 11:20) ui/input.tsx
Select / Trigger (set) 23:653 state default/focus/disabled/hover/error, borderless (default member = 11:22) ui/select.tsx
Switch (set) 11:31 checked(on/off) × state(default/disabled) ui/switch.tsx
Checkbox (set) 11:37 checked(true/false) × state(default/disabled) ui/checkbox.tsx
Separator / Horizontal 11:38 — ui/separator.tsx
Tooltip 11:39 — ui/tooltip.tsx

State styling encoded from code: hover = /90 (primary,destructive), /80 (secondary, badge fills), bg-accent + text-accent-foreground (outline,ghost), underline (link — default link is NOT underlined); focus = 1px OUTSIDE stroke bound to core/ring; disabled = node opacity 0.5.

Component ID Variants Code source
Sidebar / Mode Button (set) 12:18 state active/idle/hover AppSidebar.tsx IconTray
Panel / Header 12:19 — AppSidebar.tsx ExpandedPanel
DOMTree / Row (set) 12:91 state idle/hover/selected/multi/drop-target/hidden DOMTree.tsx
PropertyEditor / StateTabBar (set) 25:176 active-tab Default/Hover/Active/Focus/Disabled (Default member = 13:38); trailing add-ancestor-layer + (2026-09-23) shared/StateTabBar.tsx
PropertyEditor / ClusterSwitch (set) 25:131 selected Desktop/Mobile (Desktop member = 13:49) shared/ClusterSwitch.tsx
PropertiesPanel / UiModeToggle (set) 25:116 selected Simple/Advanced (Advanced member = 13:63) PropertiesPanel.tsx
PropertyEditor / CollapsibleSection Header (set) 26:137 expanded(t/f) × overridden(t/f) (collapsed+overridden member = 13:89) shared/CollapsibleSection.tsx
PropertyEditor / FieldShell (set) 26:163 state default/modified/bound (default member = 13:97) registry/FieldShell.tsx

Panels page — one editable component per chrome region (masters; the full-UI frames hold INSTANCES, so edits here propagate everywhere)

Section titled “Panels page — one editable component per chrome region (masters; the full-UI frames hold INSTANCES, so edits here propagate everywhere)”
Panel component ID Code source
Panel / TopBar (1440×56) 27:372 TopBar.tsx
Panel / IconTray (48×844) 27:432 AppSidebar.tsx IconTray
Panel / DOMTree (300×844) 27:507 AppSidebar.tsx + DOMTree.tsx
Panel / CanvasColumn (792×844) 27:671 CanvasPanel.tsx + CanvasTabs.tsx + CanvasBottomBar.tsx
Panel / Properties (300×844) 27:764 PropertiesPanel.tsx + PropertyEditorShell.tsx
Panel / PreviewTopBar (1440×56) 394:3 canvas/PreviewTopBar.tsx (D:preview-topbar, added 2026-09-13) — the bar preview mode shows instead of Panel / TopBar, same height/fill/border tokens. left-group (Exit Preview · page tabs) · centre-group (a clone of the BreakpointSelector instance also used in Panel / TopBar) · right-group (language · split · separator · PreviewAsSelector · separator · comment-mode toggle · To-do badge). Supersedes Canvas / PreviewModeControls 213:7494 (left in place, description now says SUPERSEDED)
TodoRow 395:587 comments/TodoPanel.tsx row markup, MenuRow/TreeRow-style wrapper holding Status=Open 395:588 / Status=Resolved 395:589 (checkbox icon · body + meta · delete)
Panel / QuickToolbar (docked) 28:371 canvas/QuickToolbar.tsx — rebuilt 2026-08-30 as the IDENTITY BAR (D:toolbar-identity). Row = 3 handles · separator · identity (an INSTANCE of Canvas / SelectionIdentityChip, capped at the 260px IDENTITY_RESERVE) · separator · actions in the declared priority order of canvas/toolbar-layout.ts, then the ⋯ trigger LAST. 740×40. ⚠️ 61:709 (qt-radius) no longer resolves — radius folded into the compact spacing trigger and the old row was replaced
Popover / PublishMenu 40:426 PublishMenu.tsx PopoverContent
Popover / StatusControl 40:460 TopBar.tsx StatusControl popover
Popover / ProjectSwitcher 40:477 TopBar.tsx ProjectSwitcher popover
Popover / BreakpointSelector 41:459 BreakpointSelector.tsx PopoverContent
Menu / EditorModeSwitcher 41:514 TopBar.tsx EditorModeSwitcher dropdown
Panel / TokenMatrix (FX-1/FX-2) 52:474 theme-editor/TokenMatrix.tsx — states-as-columns grid (member/ghost/editing cells, override dots, prefix group headers)
Section / SelectionColors (FX-5) 53:496 property-editor/sections/SelectionColorsSection.tsx — instance also lives inside Panel / Properties (53:544)
Section / PropertyTabStrip (FX-12a) 60:699 PropertyEditorShell.tsx — variant set: labels=true (strip ≥380px) / labels=false. 5-way taxonomy incl. the NEW Color tab; the icon is unconditional, so a text-only strip is unrepresentable
Panel / TokenDetailPopover (D:token-scopes) 313:1032 (SET, axis tab = Details 312:995 / Scope 313:995) theme-editor/TokenDetailPopover.tsx — Figma’s own Details | Scope shape. Scope is the checkbox tree writing value.$extensions.matriz.scopes; “Show in all supported properties” ON == no authored scopes == pre-feature behaviour, and the per-scope boxes are disabled while it is on. Labels from TOKEN_SCOPE_LABELS (lib/tokens/relevance.ts)
Section / GridRules (FX-12e) 61:650 property-editor/modules/GridRulesSection.tsx — nth layer family (nth<a>[+<b>], first, last) styling the container’s DIRECT CHILDREN

CMS page — the content surfaces (added 2026-08-24)

Section titled “CMS page — the content surfaces (added 2026-08-24)”
Component ID Code source
Panel / CMS Sidebar (220×940) 63:3 cms/CollectionSidebar.tsx — search, Name/Tag sort toggle, Members, grouped collections (FORMS/AUDIENCES/SINGLETONS/COMMERCE/CONTENT/OTHER) with counts
Panel / CMS Table (960×940) 65:97 cms/TableView.tsx — toolbar, schema-derived column headers, entry rows, paging footer
Panel / CMS EntryRail (420×940) 66:167 cms/RowDetail.tsx — status badge + workflow actions, schema-driven fields, timestamps, Connections
Section / Connections (FX-12j) 63:191 cms/RowDetail.tsx ConnectionsSection — lazy backlinks: “Mentioned in N items” (quoted-phrase FTS, in <field>) + “Referenced by N items” (structural refs, via <field>), each row with a collection chip
Full-UI frame ID Mode
CMS — Dark / 1600×1000 66:2566 explicit Dark (2:0) — instances of the three CMS panels + CMSLayout header
CMS — Light / 1600×1000 66:3144 explicit Light (2:1)

Built from the live /ui-lab?view=cmsrow render (ground truth) rather than from code-reading alone.

Related research: docs/Research/FIGMA-VARIABLES-UX.md — captured Figma’s own variables/component-property UX (2026-08-22) with takeaways for MATRIZ’s token editor and FieldShell.

Icons page — icon/<PascalCaseLucideName> (157 components)

Section titled “Icons page — icon/<PascalCaseLucideName> (157 components)”

icon/Box = 8:2, icon/Palette = 15:127, the rest are 9:2 … 9:127 in a single section (9:128, now 540×620 — grown 2026-09-13 for the row below). Added 2026-08-29 (chrome imports that were missing): icon/Clock 206:2, icon/Columns3 206:3, icon/FileSpreadsheet 206:4, icon/HelpCircle 206:5, icon/List 206:6, icon/MoveHorizontal 206:7, icon/MoveVertical 206:8, icon/SortAsc 206:9, icon/SortDesc 206:10, icon/SplitSquareHorizontal 206:11 (aliases followed: HelpCircle→circle-question-mark, SortAsc→arrow-up-narrow-wide, SortDesc→arrow-down-wide-narrow, SplitSquareHorizontal→square-split-horizontal; section grown to 540px tall). Added 2026-08-29 (round-3 follow-up, ids 255:10–255:97): Minimize2, MoreVertical, BarChart2, FileUp, ArrowRight, Save, UserRound, Bot, MousePointerClick, Key, Code, FileCode, Terminal, Sliders. Aliases that bit: MoreVertical→ellipsis-vertical, BarChart2→chart-no-axes-column, Sliders→sliders-vertical. Deliberately NOT added: Users2, Building2, Globe2, ImagePlus — a track wanted them, but no file in frontend/src imports them, and the mirror only carries icons the app actually renders. Layers2 already existed (9:66). Added 2026-09-13 (FU-5, the preview-comments chrome): icon/ListTodo 387:9, icon/MessageSquare 387:13, icon/MessageSquareOff 387:19, icon/MapPin 387:24, icon/RotateCcw 387:29 — no aliasing needed, all five are direct lucide-react 0.552.0 filenames. Built via figma.createNodeFromSvg() (the upload_assets recipe is still blocked in this environment, see the gotcha below), rescaled 24→16 preserving offsets, strokes bound to core/foreground at the same 0.93 opacity as the existing set.

Look up by name with page.query('COMPONENT[name=icon/<Name>]') — names match lucide-react import names (aliases preserved: Layout, Wand2, Loader2, CheckCircle2, MoreHorizontal, Columns, Rows, Filter, Home, Layers3, AlignLeft/Center/Right, FilePlus2, Code2 etc.).

Editor Screen page — full-UI frames composed from Panel instances

Section titled “Editor Screen page — full-UI frames composed from Panel instances”
Frame ID Mode
Editor — Dark / 1440×900 14:2 explicit Dark (2:0) — instances of the 5 panels + floating QuickToolbar instance
Editor — Light / 1440×900 28:1307 explicit Light (2:1) via setExplicitVariableModeForCollection — same panel instances, tokens flip automatically

The original hand-built panel subtrees were converted to components with createComponentFromNode (2026-08-22); the frames now hold instances — edit the masters on the Panels page, both frames update. New full-UI frames = instantiate the 6 panel components + set an explicit Editor Colors mode on the frame.

Canonical state mirrored: Neutral accent, editor mode, tree sidebar mode active, “CTA Button” selected (bg-primary row + canvas selection ring + breadcrumb), Layout property tab active, SIZING expanded, FILL with override dot, Events Grid subtree data-bound (sky) with REPEATER chip.

Micro-panel pages (added 2026-08-29, round 3) — 142 components

Section titled “Micro-panel pages (added 2026-08-29, round 3) — 142 components”

Four pages mirroring the editor surfaces that had never been drawn. Every component’s description is its source file path; names match the code symbol. Look one up by name rather than by ID: page.query('COMPONENT[name=PropertyEditor / LayoutProperties]').

Page ID Contents
Property Modules 208:21 28 components, all 300px (layout/panel-width), from property-editor/modules/* + sections/*. Sections: Layout & Position, Typography & Color, Effects & Style, Data & Logic, Structure & Attributes, Selection Inventories. Anchors: LayoutProperties 213:50, TypographyProperties 213:5479, DataBindingProperties 213:6008, VisibilityTierBadge 213:6167 (SET, axis tier). The 7 data-binding/components/* sub-editors were added 2026-08-29: DataSourceSelector 255:6596, QueryBuilder 255:6618, SortingEditor 255:556, GroupByEditor 255:6666, LimitsEditor 255:6576, PropertyBindingsEditor 255:6716, RepeaterStateTabs 255:6560.
Property Parts 208:22 48 components from property-editor/shared/* (19), property-inputs/* (8), and 21 modals/bars/sections. Anchors: OverrideDot 213:36, StatusBadge 213:49 (SET), FillPicker 213:7068, CmsBindingModal 213:8081. Round 2: SymbolInstanceBar is now COMPONENT_SET 309:6686 (axis role = Master 234:6199 / Copy 309:64) — combined in place, not recreated; LibraryVariantSection 234:6245 rewritten to one select per axis.
Canvas & Overlays 208:23 22 components from canvas/* + the editor chrome overlays. Anchors: SelectionIdentityChip 213:29 (SET), EdgeInsertButton 213:6249 (SET — merges CanvasAddButton + CanvasInsideAddButton, 3 colour intents), CommandPalette 213:8415, UndoHistoryPanel 213:8477. Added round 2: Canvas / IdentityBadge 302:285 (SET, axis tone = Component/Data/Override/Neutral — the BADGE_TONE_CLASS vocabulary) and Canvas / QuickToolbar Overflow 303:277 (the ⋯ popover). Both live in Section / Selection & identity 209:91. Added round 4 (2026-09-13, FU-5): Canvas / CommentPin 392:363 (SET, axis kind = Open/Resolved/Draft) and Canvas / CommentThreadPopover 394:2 (the CommentThread read face only — CommentComposer is not separately mirrored), both in Section / Preview & modes 209:97, which grew 509→849px as a result (pushed Section / Overlays & menus and Section / Command surfaces down 340px on this page).
App Surfaces 208:24 44 components: dashboard/* (8), settings/* + ControlHub (20), 9 dialogs, library-panel/* + import (6). Anchors: TargetCard 213:5407 (SET), ControlHub 213:7165, ConfirmDeleteDialog 234:6445 (SET), Import / ImportWizard 283:6803 (SET, axis step = source/review/members/run — 245:538 is now its step=source variant, combined in place, not recreated), Library / ComponentBrowser 276:506.

Known incomplete, by name, so a follow-up can pick them up:

  • Import / ImportWizard mirrors the Source step only DONE 2026-08-29 — now a COMPONENT_SET 283:6803 with all four steps.
  • ComponentBrowser’s panel shell is not drawn DONE — Library / ComponentBrowser 276:506.
  • FilterBarInsertDialogHost deliberately not drawn: it is a pure conditional wrapper (if (!pending) return null around FilterBarInsertDialog) with no markup of its own, so it has no surface distinct from Dialog / FilterBarInsertDialog 244:506. Do not “fix” this.
  • DataBindingProperties 213:6008 now has 4 of its 10 sections populated (List chrome added 2026-09-21, S30, collapsed-only like 5 of its siblings) and its 7 sub-editors exist as their own components (see the page table above). QuickStylesProperties 213:5616 is still section structure plus representative rows only — the remaining deferral.
  • PropertyEditor / ExpandToggle (DUPLICATE — use 213:5414) 213:5595 is an unreferenced duplicate at the wrong size, left in place rather than deleted. Safe to delete deliberately.

Tracks D and E did not instance the shared masters (FieldShell, CollapsibleSection Header, Button, Badge, Input, Chip, MenuRow, and many icon/*), hand-building lookalikes instead to keep pace. Visually consistent, not DRY. The cleanup is a mechanical instance-swap pass, not a rebuild — do it before anyone treats these pages as a component source.

Bookbuilder tokens (added 2026-08-29, RELOCATED same day)

Section titled “Bookbuilder tokens (added 2026-08-29, RELOCATED same day)”

Bookbuilder’s palette was briefly mirrored into this file as a “Bookbuilder Colors” collection — the wrong home. It now lives in bookbuilder’s own Figma file (bookbuilder — Design System, fileKey BSVfIwIf6MO4Sh53ZesKtJ, Figma project “bookbuilder”), integrated into that file’s Primitives/Color collections with Light+Dark modes and a STATUS swatch section; see ~/Dev/bookbuilder/design/FIGMA-SYNC.md. Pending cleanup in THIS file: delete collection VariableCollectionId:203:2 and Foundations board 203:17 (nothing in MATRIZ references either — verified by a full bound-variable scan before the move).

Round 2 (2026-08-30) — what this sync covered, and what it did not

Section titled “Round 2 (2026-08-30) — what this sync covered, and what it did not”
Code change Mirror Status
QuickToolbar rebuilt as an identity bar Panel / QuickToolbar 28:371, Canvas / IdentityBadge 302:285, Canvas / QuickToolbar Overflow 303:277, Canvas / SelectionIdentityChip 213:29 done
Token popover gained a Scope tab Panel / TokenDetailPopover 313:1032 (new) done
Three new inventory sections SelectionSpacingSection 213:7304, SelectionTypographySection 213:7330, SelectionRadiusSection 213:7352, shared shell InventorySection 213:6559 already mirrored in round 3 — verified against code, no change needed
Symbol surfaces; Detach→Unlink SymbolInstanceBar 309:6686 (SET), SymbolSyncDialog 213:8334 done — the dialog already said “Unlink” and carried the review shape; the instance bar gained its role=Copy state ([Master] [Unlink], sync warning, “What syncs?”)
Inline rename on the matrix name cell Panel / TokenMatrix 52:474 done — row-background’s name cell now renders the ring-bordered rename input, matching how row-primary already showed a value cell mid-edit
Library panel: 9 dead variant switchers + 3 variants removed LibraryVariantSection 234:6245 done — the mirror said “DROPDOWN VARIANT”, and dropdown is one of the switchers that was deleted, so it overstated what exists. Rewritten to the shipped multi-axis shape (Tone + Size, pinning the reported Destructive+Small bug)

Vocabulary split, deliberate — do not “fix” it. PropertyEditor / UnlinkDialog 213:7595 still reads “Detach from shared style?” / “Detach”. That matches the code: the rename to Unlink applies only to SYMBOL surfaces (SymbolInstanceBar.tsx explains why — three different things were all called detach, and two can appear in the same panel). The shared-style dialog keeps “Detach” in shared/UnlinkDialog.tsx despite the file name.

Drift found, logged not fixed (unrelated to this batch): accent/variant-chip-bg 3:15 carries WEB syntax bg-violet-500/15, and its LIGHT value is rgba(139,92,246,0.15) — but its DARK value is rgba(139,92,246,1.00), i.e. the alpha was lost on the dark side. Anything binding it in dark renders an opaque violet block instead of a 15% wash. Compare accent/data-chip-bg 165:2847, which is 0.15 in both modes. Owner’s call whether to correct the dark value.

Also still true: the round-3 note that tracks D and E hand-built lookalikes instead of instancing shared masters. Round 2 pushed against that where it touched: Panel / QuickToolbar now INSTANCES Canvas / SelectionIdentityChip rather than redrawing it, and SymbolInstanceBar’s ◆/↻/✎/⛓ text glyphs were replaced with real icon/* instances (Component 9:35, RefreshCw 9:98, PenLine 9:94, Unlink 9:126) per sync-contract rule 4.

Known gaps / blockers (updated 2026-09-25)

Section titled “Known gaps / blockers (updated 2026-09-25)”
  • PENDING SYNC — Surface ladder (D:surface-ladder, 2026-09-25). Code changed; Figma NOT touched (the rule comes FROM Figma 61:650 / RuleChip 114:4246; this lists what the rest of the file must catch up to). Contract: plans/EDITOR-UI-SPEC.md §14.2 + §14.11; screenshots plans/assets/ui-grammar/surfaces-*.png.

    • New token --chip (frontend/src/index.css): dark = var(--muted) / var(--muted-a) (white 15%, what 114:4246 already binds), light = 0 0% 92% #ebebeb (NOT --muted 96.1%, which does not separate from the 98% panel). Add an Editor Colors variable (suggest surface/chip, WEB hsl(var(--chip))) and rebind 114:4246’s fill from --muted to it, so the light mode resolves. Fields inside a chip stay on --card (both modes).
    • Chips in Figma that still draw a border instead of the fill — re-skin to the ladder (fill surface/chip, radius 4, padding 5, no stroke, rows 3px apart, fields 22px --card r3 no stroke): the Track A RuleChip component (6px + 1px border, see the Track A note below), the Layers-tab layer cards, and the micro-panel frames for shadow / filter / backdrop-filter / transition / transform / grid-track / fill-layer rows (StackEditor, were bg-card + border-input), conditional-visibility rules, property-binding cards and table columns (ListEditorCard, were bg-background/50 + border), list-query filter conditions, node-binding index rows, sort rows, visitor sort options, form derive rules, custom-attribute rows and behavior rows.
    • AddRow dash is --outline (was --border), matching 114:4246’s “Add property”.
    • RuleChip header label is foreground ink (was muted-foreground), matching 114:4246.
  • PENDING SYNC — UI grammar (D:ui-grammar, Track A, 2026-09-25). Code changed; Figma NOT touched on purpose (the owner is editing the file; the Figma pass is Track D). To mirror:

    • New token --mod (frontend/src/index.css :root + .dark, Tailwind mod): 24.6 95% 53.1% = orange-500 #f97316 in BOTH themes. Add an Editor Colors variable (suggest state/modified, WEB syntax hsl(var(--mod))) and bind every modified/override dot to it. Check whether semantic/override-badge-bg 301:1270 should become state/modified @10%.
    • OverrideDot is now 6px bg-mod everywhere (was bg-primary, i.e. black/white; blue on the Desktop/Mobile switch; 4px/8px orange on the cascade rail and field reset dot) — update the dots on the StateTabBar / BreakpointBar / section-header frames.
    • New primitives (components/property-editor/shared/): RuleChip (6px radius, 1px border, no shadow, 20px header: chevron · 10px uppercase label · right slot · ×), AddRow (dashed 24px “+ Add …” row; parameter variant with 20px inputs inside), PresetPill (24px, rounded-full, 10px medium; active = bg-accent + inset ring-primary/40), and ValueUnitInput’s inside-field label (10px foreground-tertiary, left slot). Add them as components on the Components page.
    • Frames that changed: PropertyEditor / Layout Grid Rules (rule cards, dashed add row, pills above it), the Layers tab (layer cards, dashed add rows, pill quick layers), Quick › Radius / Transition “None” active ring, Data › Data Source selects 32 → 28px. Screenshots and the full list: plans/EDITOR-UI-SPEC.md §14.5, plans/assets/ui-grammar/.
  • PENDING SYNC — Grid Rules rule chips (D:ui-grammar Track C + D:grid-rule-breakpoints, 2026-09-25). Code changed; Figma NOT touched (Track D edits Section / GridRules 61:650 in place). Code is GridRulesSection.tsx + RuleChip; screenshots plans/assets/ui-grammar/grid-rules-{before,after}-{dark,light}.png, grid-rules-collapsed-dark.png. What 61:650 lacks, top to bottom inside each chip:

    • Header: the collapse chevron sits LEFT of the label (Track A’s RuleChip), not the ^ beside ×. A match strip sits between label and ×: one 4px dot per child (max 12, then +N), foreground when the rule hits that child, muted-foreground/30 when not. Collapsed, the header reads LABEL · W 50% · H auto (summary in 10px foreground-tertiary, normal case).
    • Active at row (new): 10px label + a segmented control, 6 options Base SM MD LG XL XXL (20px buttons in a 24px bg-muted/40 track); an OFF bucket is struck through in tertiary ink.
    • W / H and Col / Row pairs as in 61:650 (Col/Row now on every chip, unit span).
    • Tie note (new, only when it applies): 10px tertiary text, “W on child 1: First child wins.”
    • Add property is the Layers tab’s picker: a dashed row with property / value inputs and a trailing + (61:650 shows a plain “+ Add property” button); added props list above it as name value × rows.
    • Below the chips: presets First child · Last child · Odd · Even (PresetPill) and the adder “Every [3] rd child, from [3] +” (was “Every [3] th, offset [0] +”).
  • PENDING SYNC — state selector (D:state-selector, Track B, 2026-09-25). Code built FROM state-switcher-wrapper 154:4973; Figma NOT touched. Where the code diverges from 154:4973 (update the node in place, or tell code to change):

    • “+” beside the control — the ancestor-layer menu (D:ancestor-state-layer) must stay reachable; 20×20 Plus, right of “Default ⌄”. 154:4973 has no “+”.
    • “+N” overflow chip after the dots (10px, text-mod when a hidden state has styles; filled bg-background when the current state is behind it) — not in 154:4973.
    • Current-with-styles ring (ring-1 ring-mod around the 6px current dot) — agreed in the plan, not drawn.
    • Dropdown (grouped Built-in / Custom / Ancestor / Motion / Data, check on current, inline OverrideDot per row) and dot tooltip — no Figma frames; add them beside 154:4973.
    • Divider 20px tall, ‹ › have no resting fill (hover bg-accent/60; the drawn prev button shows the hover fill); chevron-down 10px (drawn 8px).
    • Compact variant: same bar at 24px, short labels (“Def”), no “+” — no frame.
    • Placement: its own row under the breakpoint row (the PropertyEditor frames still show the old pill grid next to the breakpoint switch). Screenshots: plans/assets/ui-grammar/state-*.png.
  • Spec-module check, 2026-09-25 (D:editor-ui-spec, slice 4): no sync needed. Layout (Flex Layout, Flex Child/Grid Item, Padding, Margin, Radius), Position, fx › Cursor, Text › Variable Font, Attributes, Link and Video now render from *.panel.json specs. They are pixel-identical to the hand-written sections (239 of 241 /ui-lab captures; the other 2 differ only by a title attribute), and no tokens, icons or chrome layout changed. Two changes appear only on interaction: the existing orange section-override dot now also shows on Position, Stacking, Overflow, Transform and Variable Font for a linked node with overrides, and the Link type select keeps a freshly picked kind. Note the dot on those PropertyEditor / * frames at the next pass (plans/EDITOR-UI-SPEC.md §12).

  • FilterBarSection, FilterControlSection, SliderSection and CarouselSection (native filter family + carousel/slider) have no Figma mirror — no PropertyEditor / * component exists for any of the four under Property Modules - Page Root 209:5165. Surfaced while checking S36’s Data-tab move (D:controls-on-data-tab, 2026-09-21); pre-existing, not introduced by that change. A follow-up mirroring these four alongside the already-mirrored CollectionControlSection 213:6072 would close it. D:compare-slider (2026-09-23): the new CompareSection (same file, one “Initial split” field) joins this gap — no mirror, nothing to edit in place. Its icon and the Insert menu’s “Before/after” row use SplitSquareHorizontal, which already exists as icon/SplitSquareHorizontal 206:11, so no new icon component is needed. S31 check, same day (D:carousel-panel-parity): CarouselSection gained a Type (slide/fade) toggle, a Speed (ms) field, and a conditional read-only “Imported: ‹residue›” line + a static edit-mode note. Re-confirmed LIVE via get_metadata on Property Modules - Page Root 209:5165: still exactly 19 PropertyEditor / * symbols across the 6 groups, none named for CarouselSection/SliderSection/FilterBarSection/FilterControlSection — the gap is unchanged, so there was nothing to edit in place (the golden rule is edit-in-place, never recreate; building these four from scratch is the follow-up already scoped above, out of this item’s reach). The follow-up that mirrors CarouselSection should draw from its CURRENT code (frontend/src/components/property-editor/modules/ListControlSettings.tsx), which already includes the S31 fields — there is no separate “pre-S31” mirror anywhere to reconcile against. Widened by the S29 check below: the new FilterControlTargetDialog (frontend/src/components/filters/FilterControlTargetDialog.tsx, D:filter-panel-ux item 8) is a real dialog with its own markup — unlike FilterBarInsertDialogHost (see the entry below, deliberately not drawn), it is a peer of Dialog / FilterBarInsertDialog 244:506 and belongs in the same follow-up rather than getting a one-off component of its own.

  • S29 check, 2026-09-21 (D:filter-panel-ux). CollectionControlSection.tsx gained a Field picker (was free text), a context chip / “No value needed” / suggested-values shape for Value, a per-mode Mode sentence, and a Clear-conversion switch. Checked PropertyEditor / CollectionControlSection 213:6072 (metadata + screenshot) before editing: no edit was needed. That mirror has only ever been a 4-row schematic (REPEATER/FIELD/OPERATOR/VALUE, each drawn as a plain label + generic value box, with NO widget-type distinction — OPERATOR, a real <Select> in code since before this item, already rendered as plain text “Equals” with no chevron) — so a <Select>-backed FIELD row reads exactly as it already did, and VALUE: "Prints" remains a correct instance of the literal-value branch (unchanged by this item; the new chip/“No value needed” shapes are alternate branches for a DIFFERENT control state). The schematic was already missing the Mode row, the field/target callout paragraphs, the list-chrome block and the liveness caveat before this item — none of those are newly wrong, but a future pass rebuilding this mirror to real fidelity should add: a MODE row, a CLEAR row (the new Field-not-on-collection / “No value needed” text if going for full fidelity), matching the code in CollectionControlSection.tsx.

  • Library not published DONE 2026-08-22 — moved to Simao › Design System and published (see header). Re-publish manually after each sync. A re-publish is pending as of 2026-09-13 and now covers even more (round 4 added 5 icons, Canvas / CommentPin, Canvas / CommentThreadPopover, Panel / PreviewTopBar, Panel / Todo, TodoRow, on top of round 2’s semantic/override-badge-bg and its 3 new/5 edited components): the Bookbuilder Colors collection, Editor Colors 52 → 81 variables, 15 new icons total, the metrics code-syntax fixes, and 142+ new components across the micro-panel pages.

  • UNRESOLVED (2026-08-29): Editor Colors was hand-reworked in Figma RESOLVED — adopted. The owner’s call was to take the alpha re-base into code rather than revert Figma. Done in round 3 (D:alpha-token-rebase): the dark neutrals moved to a paired --<token>-a alpha var multiplied through the Tailwind colour, the deleted variables the app still uses were re-created, core/secondary-foreground was renamed core/foreground-tertiary to stop it colliding with shadcn’s token, and every variable now carries a WEB code syntax. Sidebar Panels 73:2 is recorded in the page map above.

  • Code Connect is plan-blocked, not a to-do. Figma rejects Code Connect writes on Pro: “You need a Dev or Full seat on an Organization or Enterprise plan.” Confirmed via the MCP send_code_connect_mappings call 2026-08-22. Until/unless the team upgrades, the component tables in this doc ARE the code↔design mapping (each Figma component’s description also names its source file).

  • One canonical screen state. CLOSED 2026-08-29 — the eleven sidebar-mode panels live on Sidebar Panels 73:2 (added Panel / Todo 395:7853, 2026-09-13), the popovers/menus on Panels 27:371, and 142+ further surfaces on the four micro-panel pages. Still unmirrored: the UI Lab views, and the incomplete items listed under “Micro-panel pages” above.

  • CommentComposer (the placed-pin, not-yet-saved face of CommentThreadPopover.tsx) is not mirrored — only CommentThread (the read/edit face) became Canvas / CommentThreadPopover 394:2. A follow-up can add a face=Composer variant (textarea + Cancel/Comment pair) combined into the same component.

  • Panel / IconTray’s new mode-todo row (394:7627) is a hand-built lookalike, matching the row style its 11 siblings already use — none of them instance Sidebar / Mode Button 12:18 (the interactive state=active/idle/hover set on the Chrome Parts page). This is the same tracks-D/E gap noted below, not a new one; fixing it is the mechanical instance-swap pass already on file, not a per-row fix.

  • VideoSection (Data tab, element_type: 'video') and the Add Element palette’s new Video item (lucide Video) have no Figma mirror (2026-09-23). Same pre-existing gap as the other per-element Data-tab sections (QrSection, CountdownSection, LanguageSwitcherSection, EmbedSection, CustomCodeSection) and the palette itself, none of which is mirrored — nor are their icons (MonitorPlay, QrCode, TimerReset, …). icon/Video was deliberately NOT added alone: the icon set carries only glyphs a mirrored surface renders. Mirror the palette and these sections together (existing Switch / Select / Trigger / CollapsibleSection masters suffice).

  • 4 lucide icons are still missing (Heading, Repeat, ArrowUpCircle, Rows3) — surfaced while mirroring the data-binding sub-editors, which substituted icon/Plus or omitted the glyph. Add them per sync-contract rule 4, then fix GroupByEditor 255:6666, RepeaterStateTabs 255:6560 and DataSourceSelector 255:6596. Note the recipe’s upload_assets step is currently blocked by this environment’s egress proxy (mcp.figma.com returns 403 by org policy); figma.createNodeFromSvg() with the same extracted __iconNode data is a working substitute that keeps the geometry exact.

  • Switch master 11:31 is now out of date. The code’s thumb was a flat bg-white, which the master mirrors faithfully. That white was invisible in two of four states (light unchecked 1.09:1, dark checked 1.04:1) and the code now uses data-[state=checked]:bg-primary-foreground / data-[state=unchecked]:bg-foreground. The master needs a matching two-state thumb.

  • Binding an alpha-carrying variable can render opaque black. Figma does not apply a COLOR variable’s embedded alpha to a paint automatically, so setBoundVariableForPaint({color:{r:0,g:0,b:0}}, 'color', v) against one of the ~31 alpha variables renders solid black. Set the paint’s color to the variable’s resolved RGB and its opacity to the resolved alpha, in addition to binding. Audited after round 3: only 2 of 1,180 alpha-bound paints across the four micro-panel pages had actually hit this, both since fixed — so this is a trap to avoid, not a backlog.

  • Two shared-master requests, both decided: Button 10:68 has no INSTANCE_SWAP property for its leading/trailing icon, so icon-bearing instances keep a baked-in default — worth adding, but it is a 96-variant edit to the most-instanced master in the file, so it should be done deliberately rather than mid-track. Select / Trigger 23:653 was asked for a width-hug variant and that is declined: the code is w-full (ui/select.tsx:19), so a hug variant would show something the app never renders.

  • Code hardcodes three colours the token system has no home for RESOLVED — the code now uses --accent-insert-flow, --accent-insert-cross and --accent-state-lens-ghost, matching the Figma variable paths 1:1. frontend/public/preview.html deliberately keeps its #3b82f6/#8b5cf6 literals (they also drive the selection outline and drop-indicator gradients, and it has no CSS vars); both files carry a comment saying the two must change in lockstep, and the byte-level parity gate covers it.

  • Some code surfaces bypass the theme tokens — ImportMaterializationPanel.tsx is now fully retokenized. PageFormatDialog was listed here in error: it was already tokenized, and this entry was written from a mirroring report rather than the file. BookletPreviewDialog’s bg-[#52565e] stays on purpose — a theme-invariant “light-table” backdrop behind the page preview, which no current token expresses. Remaining raw-hue offenders, worst first: ComponentInstanceHeader.tsx (11 raw violet-*, which the chrome-accent contract already names as the variant-chip semantic), cms/fields/CellRenderer.tsx (indigo + violet + gray), editors/PageEditor.tsx, registry/controls/RotationControl.tsx, cms/fields/SlugField.tsx.

  • Hover states exist only where modeled as explicit variants (Figma has no CSS hover).

  • Accent presets (themeStore’s 8 accent hues) are not modeled as variable modes (pro plan caps a collection at 4 modes). Neutral is the canonical accent.

  • Icon stroke weight at 14/12/10px: instances keep the 16px-calibrated 1.333 stroke when resized (real render would be 1.167/1/0.833). Visually negligible; noted for pixel-perfection work.

  • Clerk UserButton is a placeholder circle; TipTap/canvas internals are sketches inside the iframe (preview.html) frame.