#!/usr/bin/env python3 """Build the cover-art picker page (self-contained, images inlined as webp data URIs). Judged on the same dark ground the cards actually live on, and at the true 172px tile size, because that is the only size that matters on the real page. """ import base64, io, json, os, subprocess, sys, tempfile CARDS = sys.argv[1] CURRENT = sys.argv[2] # dir of existing covers for comparison PROFILES = json.load(open(sys.argv[3])) OUT = sys.argv[4] VARIANTS = ['neon', 'vector', 'comic', 'paint'] LABELS = {'neon': 'neon box art', 'vector': 'vector side art', 'comic': 'amiga comic', 'paint': '80s airbrush'} # tiles the arcade page shows for each game id TITLES = {p['id']: p.get('title', p['id']) for p in PROFILES} def webp(path, width=380, q=72): """Downscale to a data URI (macOS sips cannot WRITE webp — use cwebp).""" if not os.path.exists(path): return None with tempfile.TemporaryDirectory() as td: dst = os.path.join(td, 'o.webp') r = subprocess.run(['cwebp', '-q', str(q), '-resize', str(width), '0', path, '-o', dst], capture_output=True) if r.returncode != 0 or not os.path.exists(dst): return None b = open(dst, 'rb').read() return 'data:image/webp;base64,' + base64.b64encode(b).decode() rows = [] for p in PROFILES: gid = p['id'] cells = [] wide = p.get('aspect') == 'wide' src_dir = os.path.join(os.path.dirname(CARDS), 'hero') if wide else CARDS cur = webp(os.path.join(CURRENT, p.get('current_cover', gid) + '.jpg'), 620 if wide else 300, 70) for v in VARIANTS: d = webp(os.path.join(src_dir, f'{gid}__{v}.png'), 560 if wide else 380) if d: cells.append({'v': v, 'src': d}) if cells: rows.append({'id': gid, 'title': TITLES.get(gid, gid), 'cur': cur, 'cells': cells, 'wide': wide}) total_kb = sum(len(c['src']) for r in rows for c in r['cells']) // 1024 print(f'{len(rows)} games, {sum(len(r["cells"]) for r in rows)} variants, ~{total_kb//1024}MB inlined') html = ['''
Four directions per game, generated clean on the farm. The old covers had garbled AI lettering baked in; these carry no type at all, because the site already draws every title in HTML. Judge them small — that grey card is the cover you have now.
pick a cover in each row - your choices collect here