2026-07-05 — v28 automated UX gallery + assessment gate
Every PR that ships visual changes should come with proof. Up until now, "does this look right?" was answered by trust and convention. This pass wires in a systematic, automated answer: a full UX gallery captured by Playwright on every PR, plus a mandatory written UX assessment in the PR template.
What shipped
-
Dedicated UX gallery capture spec
(
tests/e2e/ux-gallery.e2e.test.ts). Screenshots the full state × theme × viewport matrix: chromatogram hero on load, sidebar expanded and collapsed, Inspect / Map / Analyze / Share panels opened, empty state, loading state, Export menu open, keyboard-focus ring, and hover tooltip — across light and dark themes and desktop (1280×720), tablet (810×1080), and narrow-mobile (360×640) viewports. -
Deterministic capture. Every run forces
prefers-reduced-motion: reduce, emulates a fixed colour scheme before any page navigation, uses the deterministicsample.ab1auto-load, and disables animations in the screenshot call. The loading-state capture uses a routed 300 ms delay so the banner is reliably visible. - Genuineness guards. Every chromatogram screenshot is gated on a non-blank canvas assertion — computed as total pixel deviation from white — before the shutter fires. Panel screenshots assert the expected element is visible. The completeness gate test fails the suite if any required state is missing.
-
Self-contained HTML gallery.
scripts/generate-ux-gallery-html.tsreads the manifest JSON files written by the capture spec and generates a singleindex.htmlwith all screenshots embedded as base64 data URLs, grouped by state → theme → viewport. No external dependencies — the file opens standalone from the CI artifact download. -
CI gate on every PR. The
ux-galleryjob in.github/workflows/ci.ymlruns the capture spec, then the generator, then uploads the entireux-gallery-screenshots/folder — HTML and PNGs — as aux-galleryartifact retained for 30 days. If any capture assertion fails, CI fails. -
Narrow-mobile viewport.
playwright.config.tsnow includes anarrow-mobileproject (360×640,isMobile: true,hasTouch: true) scoped to the gallery spec, so existing tests are unaffected. -
Mandatory PR template.
.github/pull_request_template.mdrequires every PR to link the UX gallery artifact and complete a written UX assessment structured around the heuristics from the merged design-research (#19): visual hierarchy, progressive disclosure, measured a11y, consistency, and delight. The Copilot reviewer and first-mate judge examine this section.
Initial UX assessment — shipped workspace-shell app
The following assessment is grounded in the design-research (#19) and perf-audit (#20) heuristics and reflects the state of the app as of the v27 workspace-shell. Wherever possible, I describe what I see in the gallery screenshots rather than making assumptions.
What works well
- Hero-first information architecture. The chromatogram is immediately above the fold on load in all three viewports. The workspace-shell redesign fixed the most important ordering problem: the thing you came to see is the first thing you see.
- Sidebar progressive disclosure. Collapsing the sidebar reclaims the full width for the trace. The toggle is keyboard-reachable (Tab + Enter), has a clear accessible name ("Hide tools" / "Show tools"), and the aria-expanded / aria-controls pair is correct.
- Dark mode surface parity. The dark-mode gallery screenshots show consistent surface colour (#1e293b) across the shell, the canvas background, and the sidebar — no mismatched regions.
- Measured contrast. The ux-a11y test suite verifies text ≥ 4.5 : 1, UI border ≥ 3 : 1, and focus ring ≥ 3 : 1 in both themes. These are not estimates — they are computed from resolved CSS custom properties at runtime.
What needs to improve
- Narrow-mobile sidebar overflow (P1). At 360×640 the sidebar panels are full-width and stack below the hero canvas. There is no responsive breakpoint to switch to a bottom-sheet or sheet-overlay pattern for narrow viewports. The Inspect panel is likely cut off. Filed as a scoped follow-up.
- Empty-state visual weight (P2). The empty-state dropzone is text-only and blends into the background in dark mode. A light illustrated placeholder or a subtle dashed border around the drop target would improve discoverability and delight.
- Loading-state spinner legibility (P2). The spinner is visible but the surrounding loading banner lacks secondary guidance ("Loading your trace…" with a file name if known). First-time users have no indication of what is happening or how long it will take.
- Export menu discoverability (P2). The Export ▾ button is visually de-emphasised relative to the View controls. On narrow-mobile it may be clipped. Consider promoting the most common export action (FASTA) to a persistent button with the menu serving secondary formats.
- Hover tooltip hit target (P3). The hover tooltip appears only when the pointer is precisely on a base peak. The hit area is one base wide. On high-resolution traces with tight peak spacing, this makes the tooltip feel fussy. A wider hit region with a brief delay would reduce friction.
Accessibility (measured)
- Text contrast: ≥ 4.5 : 1 in both themes (CI-verified).
- UI / border contrast: ≥ 3 : 1 in both themes (CI-verified).
- Focus rings: visible in keyboard-focus gallery screenshots; outline-width ≠ 0 (CI-verified).
- Keyboard operability: sidebar toggle, tab strip, search, and export are all Tab-reachable on desktop.
- Gap: narrow-mobile keyboard operability not tested (touch-only device emulation).
Prioritised follow-ups
- Narrow-mobile responsive sidebar (bottom-sheet or slide-over overlay pattern).
- Empty-state dropzone visual improvement (illustrated placeholder + dashed border).
- Loading-state secondary guidance (file name + progress hint).
- Export menu: promote most-common action to persistent button.
- Hover tooltip: widen hit target + add configurable delay.
CI status after this pass
Lint, typecheck, all Vitest unit tests, all Playwright E2E tests (desktop + tablet), the
perf smoke tests, and the new UX gallery capture spec pass. The ux-gallery CI
job uploads the HTML gallery artifact on every PR.