- Add a headless PropertyGrid primitive with themed app composition
- Keep composite paint details full-width and show remove actions consistently
- Tighten color picker and Design-panel field sizing without clipping values
- 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
- 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
- Let virtualized Layer rows fill the panel width\n- Remove extra root indentation while preserving hierarchy depth\n- Keep icon menu labels beside their icons\n- Refresh reviewed panel snapshots
- Keep Fill and Effects settings inside their shared content rails\n- Use panel spacing tokens instead of ad-hoc offsets\n- Preserve selection when Escape dismisses overlays\n- Label the Font settings trigger for assistive technology
- Rebuild Typography, Variant, Mask, and Page sections with shared labeled fields
- Expose semantic empty states across list sections
- Replace section test hooks with accessible roles and add focused visual coverage
- Share compact item-row and paint-field anatomy across Fill, Stroke, Effects, and Export
- Add COLOR binding transactions with picker rollback and one-step undo
- Replace bespoke panel test hooks with semantic selectors and visual coverage
- Move independent-corner presentation and batched mutations into AppearanceControls
- Rebuild Position and Appearance with aligned panel grids and semantic locators
- Replace type text headers with compact node icons and add visual coverage
- Show one variable picker affordance with a quiet identity pill and accessible combobox
- Keep bound NumberField focus non-destructive until the first value mutation
- Prefer accessible and semantic test selectors over compound test IDs
- Remove ScrubInput aliases, app wrappers, test hooks, and translated legacy references
- Share a Tailwind NumberField demo between Storybook and VitePress
- Generate component API tables from Vue metadata and type-check examples with Twoslash
- Upgrade the docs stack to VitePress 2
- Add selection mask commands, shortcuts, context-menu access, and mask type controls
- Add mixed-selection blend mode editing with single-step undo
- Document the headless mask composable and localize the new controls
- useEditorSetup() / useEditorSetupWithClear() in tests/e2e/fixtures.ts
- Migrated 17 specs to shared fixture, removing ~300 lines of boilerplate
- Moved getSelectedNode/getSelectedNodes to shared store helpers
- Replaced inline getSelectedNode in 4 specs with shared import
- Test duplication: 329 → 308 clones (10.12% → 9.08%)
- Expose window.openPencil.getStore() instead of a direct store property
- Update E2E helpers and specs to use the bridge getter
- Add lint coverage preventing direct window.openPencil.store access
- Remove remaining test non-null assertions and delete the broad test override
- Add explicit guards for canvas, design panel, auto-layout, SVG, Kiwi, hit-test, scene graph, text editor, and clipboard tests
- Validate check plus affected engine and E2E coverage
- Route browser globals through src/app/window-api.ts instead of private __OPEN_PENCIL fields
- Move E2E tests to the public window.openPencil test API
- Add an oxlint rule banning direct window.__OPEN_PENCIL* access
- Replace browser store non-null assertions with explicit initialization guards
- Use expectDefined for optional test resources and tool results
- Clean low-count non-null assertions in font, icon, snap, OKHCL, and visual tests
- Configure oxfmt custom import groups for workspace, app, package, and test aliases
- Keep type imports grouped with their matching source category instead of one global tail group
- Expand the format script to cover formatter config, Vite files, and scripts
- Move top-level engine and e2e prefixed test files under domain folders
- Update fixture path helpers after moving render and pen tests
- Add lint coverage to prevent new top-level prefixed test files
- Refresh testing docs for the new fig and layout paths