- Populate requested pages for scoped reads and all pages for document-wide operations
- Export whole FIG documents by default while keeping explicit page exports partial
Rebuild the demo as a cohesive product showcase:
- Component Library: Button/Badge/Avatar/Nav/Toggle as real components
- App — Analytics: a modern dashboard assembled from instances with real
auto-layout and semantic variables, teaching the OpenPencil workflow
- Correct stat badge tones and component captions
Apply success/accent/danger tones to the stat badges after layout with the
label fill recorded as an override, so component sync preserves them.
Badges now read +14% green, +8% blue, -3% red.
- Remap descendant clone sources when instance branches are repopulated
- Keep same-name component-property siblings distinct
- Name swapped variants after their component sets
Replace the grab-bag demo (3 disconnected feature boxes) with a real product
screen that teaches the OpenPencil workflow by example:
- Component Library: Button (primary/secondary), Badge, Avatar, Nav item,
Toggle as actual COMPONENTs
- App — Analytics: a modern dashboard assembled from INSTANCEs of those
components, laid out with real auto-layout (sidebar, stat row, chart,
callout), themed via bound semantic variables
- Single restrained palette (one accent + surfaces/text/semantic tones)
- Instance text set with recorded overrides so component sync keeps labels
Editing a variable re-themes the screen; resizing frames demonstrates live
auto-layout reflow.
- Reuse imported collection, mode, and variable GUIDs when safe
- Keep raw paint asset refs instead of promoting incomplete library bindings
- Retain GUID conversion only for effect aliases required by Kiwi
- Import and round-trip per-node variable mode overrides
- Resolve fill and stroke aliases through the nearest mode scope
- Preserve mode maps across cloning and instance synchronization
- Section titles are no longer collapsible triggers — they render as static
text like Figma, so clicking a section header no longer collapses it
- Drop the 'Font features' group title; ligature/kerning toggles sit
directly in the Typography flow
- Update panel specs and snapshots for always-expanded sections
The B/I/U/S toggle buttons were borderless ghosts while the alignment
controls used a filled segmented container. Wrap them in the same
bg-panel-field container so both toggle groups share one visual style.
The group header and the toggle rows under it shared the same muted 11px
style, flattening the hierarchy. The OpenType features label is now
semibold surface text while items stay muted.
- Layout: gap between the Resizing segmented control and the W/H size fields
- Typography: breathing room between OpenType feature toggle rows and above
the Text formatting toolbar
Within-group label→field stays 4px; between-group margin rises from 6px to
12px so each property reads as a distinct unit instead of merging into a
continuous column. Matches Figma's grouping structure without removing the
labels.
- Isolate the Copy/Paste submenu scenario from prior context-menu state
- Close shared fixture pages safely when a project-level skip bypasses setup
- Refresh the reviewed typography panel snapshot
- Keep the development MCP bridge alive until Vite shuts down
- Ignore empty host-font responses and cover current browser font policy
- Update interaction selectors, menu labels, resize accounting, and reviewed UI snapshots
Fields previously used a transparent idle fill (a misread of Figma, whose
inputs actually keep a visible fill at idle). Editable controls now read as
controls: idle fill #383838 (dark) / #f0f1f3 (light), one step up from the
panel, with a slightly stronger hover and the accent focus border.
- Iterate assignment-bearing instances instead of rescanning the expanded graph
- Build clone indexes from the SceneGraph instance index
- Reuse static component property maps across convergence passes
- Populate only the first page during initial document reads
- Avoid duplicating immutable instance payloads and opaque source metadata
- Propagate derived text through source-ordered clone chains
- Move the Auto layout add/remove button from the section body into the
section header actions, matching the Layout grid and every other section
- Drop leading-none on section titles so descenders ('g' in 'Layout grid')
are not clipped by the 32px header band
Wire two engine-supported features into the properties panel:
- Text auto-resize: a Resizing segmented control for text nodes (Auto width
/ Auto height / Fixed size) backed by the existing textAutoResize engine
- Layout grids: a full editor section for frames (pattern, count, gutter/
section size, margin, visibility) using the existing canvas renderer
Add a Layout grid section for frames/components with pattern (columns/rows/
grid), count, gutter/section size, and margin, plus visibility and remove
actions. The canvas already rendered layout grids from imported files; this
wires creation and editing through the standard panel list pattern with
undo support and icon+tooltip pattern options.
Surface the engine's textAutoResize as a Resizing segmented control for
text nodes, mapping Figma's three modes: Auto width (WIDTH_AND_HEIGHT),
Auto height/wrap (HEIGHT), Fixed size (NONE). Icon + tooltip options match
the panel's segmented-control language. The engine already reflows text on
content changes; this wires the control to it with undo support.
- Update design/properties panel snapshots for the 24px control height and
section header bands, and the appearance field test to expect 24px
- Add a light-theme regression test asserting the canvas ruler theme tracks
the active theme tokens instead of staying on the dark fallback
Layer lock/visibility actions, toolbar tools, tool flyout triggers, and
the app UI toggle rendered icon-only buttons with no accessible name, so
screen readers and role-based selectors could not identify them. Each now
exposes an aria-label from the existing i18n/tool labels.
- Menubar items render in surface text instead of muted (looked disabled),
at the 11px UI scale
- Menu items, document tabs, and tooltips normalized to 11px to match the
panel type scale; menu items use the 5px control radius
- Share button uses the control radius and 11px; presence popover drops its
border for the floating shadow
The segmented-control root used the field recipe, so text-alignment and
vertical-alignment toggles rendered as one heavy dark bar. The root is now
transparent at idle with a hover wash, and only the active segment carries
the subtle fill — matching Figma's segmented-toggle appearance.
- Section headers become full 32px bands (title + trailing actions
vertically centered) instead of an 11px line crammed against fields,
giving each section a clear structural band like Figma
- Select dropdowns adopt the floating-surface elevation (12px radius, no
border, deep shadow), 24px flush items, and scroll up/down buttons for
long lists (blend modes)
- Font-settings gear trigger drops its hardcoded dark bg+border for the
ghost icon-button recipe
- Segmented-control active state uses neutral hover fill instead of the
blue-grey selection color
- Menus, popovers, dialogs, tooltips, and the toolbar drop the hard 1px
border for the established deep floating shadow (0 8px 30px /40%) and a
unified rounded-xl, so overlays read as floating rather than outlined
- Appearance section pairs Blend mode with Opacity on a 7fr/5fr grid so
'Pass through' no longer truncates at the denser 24px control height
- Normalize AppSelect text to 11px to match the panel type scale