#!/usr/bin/env python3
from pathlib import Path
import json,html,sys
root=Path('/tmp/lead-27840-r1/capture');u=json.loads((root/'uploads.json').read_text())
def md(name):return u[name]['markdown']
def url(name):return u[name]['url']
rows=['R1-1440-dark','R1-1440-light','R1-390-dark','R1-390-light','R2-1440-dark','R3-1440-dark','R4-1440-dark','R5-1440-dark']
env='Chrome 156.0.0.0 on Linux x86_64 through T3 Browser panel; no device emulation; DPR 2; 100% font scaling, 16px root/Inter; fixed JS clock 2026-11-03T12:00:00Z. Native reduced-motion override unavailable: JS preference emulated, CSS motion disabled. Fonts ready + 1s resource-idle, then two pixel-identical frames ≥500ms apart for every still.'
changes=['R1: GitLab status dot becomes green, Not authenticated badge and sign-in instructions become Authenticated as the app-blurred julius54 account, and its switch becomes blue/on. The shorter row moves GitCafe, Forgejo/Gitea, Bitbucket, Azure DevOps and Writing & review (including Advanced) upward; their content stays the same. Borders/shadows and whitespace move with those rows.', 'R2: Setup Required disappears and the GitLab icon/title/description become fully opaque as the source is enabled. Search query is GitLab on both sides.', 'R3/R4/R5: zero changed pixels across each entire captured frame. R6: only case (a) gains auth status --all; case (b) does not retry. No unrelated visible differences found at zero threshold.']
before='[c6ef3b46eb](https://git.cafe/pingdotgg/t3code/commit/c6ef3b46ebed34fbefa1706674fe5748254cee18)'
after='[e9312167e2](https://git.cafe/pingdotgg/t3code/commit/e9312167e26f2de6984c604c7f07902e287caa58)'
lines=['## Evidence','',f'6/6 matrix rows captured: eight visual pairs and both R6 argv cases. Unverified rows: none. Before {before}; after {after}.','',env,'','Desktop: 1440×1100 CSS, saved PNG 1280×978 (Browser panel downsampling). Narrow: 390×2600 CSS, saved PNG 780×5200. R1 narrow uses zero scroll; Settings desktop uses scrollTop 494; R2 uses zero scroll. Same fresh empty server data per side, auto project creation off; no live T3 data copied. All captures and diffs opened and inspected.','',f'| Row / CSS viewport / theme | Before<br>{before} | After<br>{after} | Diff0<br>{before} → {after} | DiffT<br>{before} → {after} |','|---|---|---|---|---|']
for row in rows:
    width=390 if '-390-' in row else 1440;height=2600 if width==390 else 1100
    label=f'{row.split("-")[0]} · {width}×{height} · {row.split("-")[-1]}'
    lines.append('| '+label+' | '+' | '.join(md(row+'-'+suffix+'.png') for suffix in ['before','after','diff0','diffT16'])+' |')
lines+=['','Diff0 = absolute per-channel RGB difference ×32, zero threshold (a one-level difference is visible). DiffT = max-channel difference >16/255 in pink over a dimmed before frame.','',f'Modern glab 1.124 is used for R1/R2/R3/R6; genuine glab 1.78 for R4/R5. Version/rejection and all fixture checks: {md("fixture-transcript.txt")}. Genuine release tarball SHA-256 is in {md("run-manifest.json")}.','',f'| R6 text fixture | Before<br>{before} | After<br>{after} |','|---|---|---|']
for case in ['R6a','R6b']:
    lines.append('| '+case+' · '+('signed-out default, signed-in gitlab.com' if case=='R6a' else 'signed-in current host')+' | '+md(case+'-before-argv.txt')+'; '+md(case+'-before-wrapper.sh')+' | '+md(case+'-after-argv.txt')+'; '+md(case+'-after-wrapper.sh')+' |')
lines+=['','What else changed:','']+['- '+x for x in changes]
lines+=['','Final settle pairs are archived below. The first-pass archive contains superseded drafts and is excluded from the comparison tables.','',f'Cleanup complete: servers stopped, base checkout removed, private glab configs deleted, PR tracked files unchanged. {md("cleanup.json")}.','','Sheets (Before/After top; Diff0/DiffT bottom):','']+[md(row+'-sheet.png') for row in rows]
lines+=['','Rebuild scripts and support:','']+[md(n) for n in ['seed-glab.py','fixture-server.py','prepare-frame.js','preview-driver.mjs','replay-pair.mjs','make-diffs.py','collect-support.py','upload-artifacts.py','build-report.py','two-host-glab-config-REDACTED.yml','signed-out-glab-config-REDACTED.yml','signed-in-glab-config-REDACTED.yml','run-manifest.json','diff-stats.json','settle-pairs.zip','first-pass-frames.zip']]
if len(sys.argv)>1:lines+=['',f'Index: [index.html]({sys.argv[1]}).']
lines += ['', 'Captured by gpt-6.1-sol via the Codex harness.']
(root/'evidence.md').write_text('\n'.join(lines)+'\n')
parts=['<!doctype html><html><head><meta charset="utf-8"><title>Evidence for PR 27840</title><style>body{margin:0;font:14px/1.5 system-ui;color:var(--foreground,#ddd)}h1{font-size:20px}a{color:var(--primary,#8eaeff)}details{padding:16px;margin-block:12px;border-radius:var(--radius,10px);background:var(--card,#18181c)}summary{cursor:pointer;font-weight:600}img{display:block;width:100%;height:auto;margin-top:12px}ul{padding-left:20px}code{font-size:12px}</style></head><body><main><h1>Evidence: <a href="https://git.cafe/pingdotgg/t3code/pull/27840">#27840</a></h1><p>6/6 rows captured · 8 visual pairs · R6(a/b) verified · no unverified rows.</p><p>'+html.escape(env)+'</p><p>1440×1100 CSS (1280×978 PNG); 390×2600 CSS (780×5200 PNG). Full viewport captures; no device emulation.</p><ul>']
parts += ['<li>'+html.escape(x)+'</li>' for x in changes];parts+=['</ul>']
for i,row in enumerate(rows):
    parts.append('<details'+(' open' if i==0 else '')+'><summary>'+row+'</summary><p>'+' · '.join('<a href="'+url(row+'-'+s+'.png')+'">'+s+'</a>' for s in ['before','after','diff0','diffT16'])+'</p><a href="'+url(row+'-sheet.png')+'"><img src="'+url(row+'-sheet.png')+'" alt="'+row+' Before and After above zero-threshold and threshold-16 differences"></a></details>')
parts+=['<details><summary>R6 logs, CLI transcript, scripts and support files</summary><ul>']
for name,item in u.items():
    if not name.endswith('.png'):parts.append('<li><a href="'+item['url']+'">'+html.escape(name)+'</a></li>')
parts+=['</ul></details></main></body></html>'];(root/'index.html').write_text(''.join(parts))
print('Evidence lines:',len(lines))
