← Cycles
Design · c96

Page Evolution

archivedcreated 2026-09-25· last activity 2026-09-25· mode: Assemblage — compose existing capture infrastructure (manifest, shot programs, atlas) with new join logic and UI

Build a before/after tool and page-evolution view to correlate captures across cycles and threads

New in this cycle: Page evolution (c96): every capture carries a subject (page/teams, component/data-ranked-bars) so the same page joins across cycles, threads, and surfaces — mock → qcontrol preview → qdash; /cycles/evolution lists the subjects and each subject page compares any two moments by wipe, onion skin, side-by-side, or sequence

Why

The capture system (scripts/capture.mts, shot-programs, public/cycles//manifest.json) feeds the cycle atlas at /cycles//. Captures are per-cycle; the same route is captured repeatedly across threads and cycles under different filenames (e.g., c92-inventory-sessions.png on 2026-09-21 and c92-polish-sessions.png on 2026-09-25 are both /inventory/sessions on qdash). Just landed in c92 (band-polish thread): shot programs can declare thread: { id, label, date }, capture.mts copies it onto each manifest entry, and the atlas groups a cycle's Visual record by thread, newest first.

But there is no join key tying captures of the same page together across cycles. The request: clear separation between older and newer screenshots, a before/after tool for specific pages, and a page-evolution view showing a page's history over time (timeline, side-by-side, slider/onion-skin comparison).

Objective

Extend the capture/manifest system to allow correlating captures of the same page across threads and cycles, then build a before/after tool and page-evolution view that lets designers and the team understand how a specific page has evolved over the course of development.

Scope

  • Page identity key: What uniquely identifies a page across time? Explicit page tag on shot programs, derived from route, or both?
  • Backfilling: How to retrofit existing manifest entries with page keys (bulk operation or lazy assignment)?
  • View location: Atlas page per page-key? A component on cycle pages? A new /pages//history route? Archive detail page expansion?
  • Comparison UI: Side-by-side, slider/onion-skin overlay, timeline strip, or hybrid?
  • Sister projects: Do qmap, qflow, bob-wire participate, or design-only?
  • Skills/docs: .claude/skills/capture/SKILL.md and .claude/skills/document-cycle/SKILL.md updates

Key Changes

Kick-off (2026-09-25): Created cycle, wrote initial-prompt.md and CYCLE.md. Open questions documented in Scope; plan and architecture next.

Planned (2026-09-25): plan.md written, nothing executed. Verified first: the manifest is the only join surface (229 design entries, every hero manifested); route repeats across cycles only 6 times, but stripping -vN / ?query joins 31 families, and the same product page lives on three hosts (mock → /qcontrol preview → qdash local). A dry run of route→subject derivation resolves 215/229 entries into 136 subjects, 22 with real history (page/teams: 6 moments, c81→c92, three surfaces). Design: an explicit kind-prefixed subject (page/teams, component/data-ranked-bars) + derived surface / variant on every manifest entry, a small alias registry (app/data/subjects.ts), a backfill script, a moments model (buildEvolution.ts) with fans (parallel versions on one day) and lanes (state / theme variants), /evolution index + /evolution/[kind]/[slug] with UxImageCompare (wipe · onion · side · sequence) and deep-linkable ?a=&b=, history chips on atlas figures, an Evolution section on component docs, UxLightbox extracted (rule of three). Seven decisions ruled the same day: single subject field; qdash captures join as the app surface; bulk backfill now; view nested under /cycles (/cycles/evolution, evolution reserved as a project id); components prototyped design-local then extracted; pixel diff is stretch; design-only.

Executed (2026-09-25): Phases 1–5 of plan.md run end to end on the design repo; nothing committed yet. Identity: app/data/subjects.ts (kind-prefixed subject, surface, variant; derivation rules + alias table — page/user and page/users → page/user-detail, page/teams-users-devices → page/teams, qdash /inventory/<x>/detail → page/<x>-detail), PageEntry.subject, capture.mts tagging every mode (--subject / --surface / --variant, program subject + per-shot variant), scripts/backfill-subjects.mts (npm run shots:backfill). Backfill: 215 / 229 design entries tagged into 132 subjects, 23 with more than one moment; the 14 unresolved are site chrome. Data: server/data/evolution/buildEvolution.ts — moments keyed by cycle + thread + day + surface, sorted day → cycle → surface → clock (so c90 and c92 shot the same day read in cycle order), fans (several routes in one moment: teams-ideas v2–v7 in c67) and lanes (state=clear); /api/evolution and /api/evolution/[kind]/[slug]. View: /cycles/evolution (cards pairing first and latest capture, kind tabs, history-only toggle) and /cycles/evolution/[kind]/[slug] (lane control, EvolutionStrip, UxImageCompare wipe · onion · side with synced scroll, a sequence flipbook with autoplay, step buttons + arrow keys, the record for A and B with cycle, thread, surface, route, caption, newThing, hero / full-page lightbox; ?a=&b=&mode=&lane= deep links, Copy link). Hooks: atlas figures carry history · N moments → when their subject recurs (51 of c92's 72 figures); component docs pages gain an Evolution section (client-fetched, only when history exists — DataRankedBars shows two moments); UxLightbox extracted from the atlas and archive copies, both now call it. Docs: /capture Subjects section, /document-cycle capture + verification lines. Verified on the live :3000 server: Teams reads six moments across mock → preview → qdash, teams-ideas keeps its fan, data-ranked-bars its thread label; all four modes and the URL sync exercised in the browser pane, console clean; captures c96-evolution-teams (+full), -onion, -index (+full) tagged page/evolution / page/evolution-index on the docs surface. Not done: layer extraction of the three components (+ demos, at close), pixel-diff scoring (stretch), Outcome / archive entry / HISTORY.

Outcome

Closed 2026-09-25. The capture system now has memory. Every design capture carries a subject (page/teams, component/data-ranked-bars), a surface (mock · qcontrol preview · qdash · docs), and a variant lane — derived from the route with a small alias table and backfilled over 215 of 229 manifest entries: 132 subjects, 23 with history, the 14 unresolved all site chrome. /cycles/evolution lists every subject as a first-to-latest card; a subject page runs the timeline strip (fans for parallel versions, lanes for states) over a compare stage with wipe, onion skin, side-by-side with synced scroll, and a sequence flipbook, with A, B, mode, and lane in the URL so a before/after is a link. The atlas links each recurring figure to its history, component docs pages show an Evolution section when one exists, and the two hand-rolled lightboxes became one UxLightbox. Teams is the worked example: six moments across three surfaces from the c81 mock to qdash after band-polish.

What the plan foresaw held, with one correction found by use: same-day moments must sort by cycle before clock, or c92 reads ahead of c90. Two lessons carry forward in /capture and /document-cycle: route is the wrong key (versioned routes and three hosts per page hide the history), and thread captures left in /tmp are history lost.

Follow-ons, not blockers: extract UxImageCompare, UxLightbox, and EvolutionStrip to the layer with demos (the c93 → c95 pattern); pixel-diff scoring per step (plan §6 stretch); sister-project experiment/* subjects when qmap or qflow want the view.

Visual record

5 captures — heroes, page slices, and full-page renders. Click to view.

/cycles/evolution/page/teams — six moments of the Teams page from the c81 mock through the c89 teams-v3 mock, the c90 qcontrol preview, and qdash after c92 band-polish; the strip on top, the wipe stage comparing c81 (A) with c92 (B), the record for each side beneath
/cycles/evolution/page/teams — six moments of the Teams page from the c81 mock through the c89 teams-v3 mock, the c90 qcontrol preview, and qdash after c92 band-polish; the strip on top, the wipe stage comparing c81 (A) with c92 (B), the record for each side beneath open page →history · 2 moments →
The same pair in onion-skin mode — B blended over A at the slider's opacity; the mode and both captures are in the URL, so a before/after is a link
The same pair in onion-skin mode — B blended over A at the slider's opacity; the mode and both captures are in the URL, so a before/after is a link open page →history · 2 moments →
/cycles/evolution — 132 subjects, 23 with history; cards pair the first and latest capture, name the cycles spanned and the surfaces seen; history only is the default filter
/cycles/evolution — 132 subjects, 23 with history; cards pair the first and latest capture, name the cycles spanned and the surfaces seen; history only is the default filter open page →
c96 full
open page →history · 2 moments →
c96 full
open page →

In the archive

Artifacts

Qpoint Brand Style Guide