# Reproduce marketing download evidence

Run on Linux x86_64 with Xvfb, Node, Python (Pillow 12.3.0 + numpy), and installed repository dependencies. No T3 server or userdata is used.

1. Obtain a clean checkout at `69b0eb2c4c9b20210a40c1fad35977ba056aa946`, including git object `c4fa4629eb645b95aae2beef56c70f705b736049`; install the checkout's locked dependencies using its normal setup. Do not use an active app-data directory.
2. Place `run.py`, `capture.mjs`, `process.py`, and `fixtures.json` together in a new scratch directory OUTSIDE the checkout. `npm install --prefix <scratch> playwright@1.58.2`, then `<scratch>/node_modules/.bin/playwright install chromium` (full Chromium, not headless shell).
3. `CAPTURE_REPO=/path/to/clean/checkout python <scratch>/run.py`. To independently rebuild just one pair, prefix `CAPTURE_ROWS=M05` (or any static matrix ID). No git operations occur while either server runs. The runner asserts the clean head, archives the baseline to `<scratch>/before`, shares installed node_modules via symlinks, stages installers and starts two real Astro dev servers on unused loopback ports. It launches Xvfb using `-displayfd`; Playwright starts headed Chromium with --disable-gpu for software compositing and --hide-scrollbars to keep the original layout width during document-height expansion. The runner disables the unrelated Astro development toolbar and update check using a scratch-only XDG_CONFIG_HOME/astro/settings.json preference file, without modifying global preferences or application source. All directly spawned processes are stopped in `finally`; browser closes in its own `finally`.
4. `python <scratch>/process.py` builds diffs and contact sheets for pairs that exist. File naming is stable. `environment.json`, each `captures/<row>-<side>.json`, `diff-stats.json`, and `cleanup.json` record observed conditions and provenance. Origins/display/PIDs vary on recapture; they are not inputs to rendering.

The fixed release fixture intercepts ONLY the actual latest-release GitHub request. Missing-assets uses the same JSON with `assets=[]`; network-error aborts it. These proof asset URLs are nonexistent and never activated. Other assets are served by real Astro.

CDP `Emulation.setTouchEmulationEnabled` sets maxTouchPoints=5 before navigation; no navigator injection, no application state or routing overrides, no source/CSS edits. Device emulation uses fixture DPR and mobile flags. Natural Chromium font autosizing is retained. UA-CH remains Chromium's effective default, recorded verbatim. Safari UAs are Chromium emulation, not native Safari/WebKit evidence.

Images visible within the horizontal page surface are loaded by scrolling the actual page in viewport-height steps using explicit instant scroll (the site otherwise requests smooth scrolling), decoded, and returned to top before capture. Hidden and horizontally clipped lazy marquee avatars are intentionally not forced to load; their state is recorded. Fonts are awaited with document.fonts.ready. All shots use reduced motion. Network idle, both settled hrefs, exact effective UA/touch, labels and platform are checked. A full-page frame is accepted only after two byte-identical native CDP Page.captureScreenshot PNGs at scale=1 CSS raster output (fromSurface, captureBeyondViewport=false). The fixture DPR stays 3/2/1 as specified and is verified in navigator/devicePixelRatio. Raster dimensions are CSS pixels, not device pixels. After recording the original viewport DOM, the driver expands the viewport height once to document scrollHeight to render all compositor layers; it does not resize between the two frames. This full-document capture viewport is also recorded. The driver asserts hero, lower CTA and hint rectangles remain exactly equal to the original viewport values separated by 500 ms; SHA256 for both frames is recorded. The pointer stays at (0,0), off both CTAs. Only one identical copy is retained.

Diff0 marks ANY nonzero max absolute RGB channel delta in saturated magenta on black (amplifying even 1/255); DiffT marks pixels with max absolute RGB delta >16/255 with the same colors. PNGs are compared in native CSS-raster pixels without resizing or alignment. Contact sheets are supplemental scaled views; the individual full-size PNGs remain authoritative. Section sheets use recorded CSS coordinates for hero, git hint, lower CTA and footer.

Scope: settled rendering and independently read hero/lower CTA hrefs, icons, hint, environment values and network paths. T01/T02 transient/no-flash/early-tap timing, I01 actual activation/navigation, I02 hover/focus/active/resize/scroll motion, T03 JS-disabled and native Safari are explicitly unverified. The loading scroll is preparation, not interaction or smoothness evidence.
