from pathlib import Path
from weasyprint import HTML
import subprocess
root=Path('/mnt/data/next_rc55_work')
qa=root/'qa_static'; shots=root/'qa_screenshots'
qa.mkdir(exist_ok=True); shots.mkdir(exist_ok=True)
CSS=r'''
@page{margin:0}*{box-sizing:border-box}html,body{margin:0;background:#030912;color:#f8fbff;font-family:Arial,Helvetica,sans-serif}body{padding:20px 16px 112px;background:radial-gradient(640px 360px at 86% 0,rgba(43,163,244,.12),transparent 58%),linear-gradient(180deg,#030914,#071426 58%,#020811);overflow:hidden}.top{height:68px;border:1px solid rgba(110,220,255,.26);border-radius:24px;background:linear-gradient(180deg,rgba(10,23,42,.94),rgba(5,13,25,.96));display:flex;align-items:center;justify-content:space-between;padding:0 24px;margin-bottom:14px;box-shadow:0 14px 36px rgba(0,0,0,.24)}.menu,.person{color:#6eeaff;text-align:center;font-size:30px;font-weight:300;line-height:1;width:46px}.logo{text-align:center}.logo b{display:block;font-size:40px;line-height:.75;letter-spacing:.16em}.logo b span{color:#5ce4ff}.logo small{font-size:8px;letter-spacing:.35em;color:#77f0ff;font-weight:800}.page{max-width:1050px;margin:0 auto}.page>*{margin-bottom:10px}.head{padding:0 2px}.head h1{font-size:42px;line-height:.9;margin:0 0 7px;font-weight:900;letter-spacing:-.055em}.head p{font-size:16px;line-height:1.25;margin:0;color:#b9c5d5}.card{border:1px solid rgba(105,220,255,.25);border-radius:21px;background:radial-gradient(620px 260px at 88% -20%,rgba(54,169,255,.14),transparent 62%),linear-gradient(180deg,rgba(12,27,48,.90),rgba(6,15,28,.92));padding:14px;box-shadow:0 18px 42px rgba(0,0,0,.16);overflow:hidden;backdrop-filter:blur(8px)}.label{font-size:11px;text-transform:uppercase;letter-spacing:.22em;color:#7df0ff;font-weight:900;margin:0 0 10px}.titleName{font-size:44px;line-height:.9;margin:0 0 9px;font-weight:900;letter-spacing:-.055em}.muted{color:#b7c4d5}.chips{display:flex;flex-wrap:wrap;gap:7px}.chip{border:1px solid rgba(110,220,255,.27);border-radius:999px;padding:7px 10px;background:rgba(12,30,52,.72);font-weight:800;font-size:13px;line-height:1.05;min-height:30px;display:inline-flex;align-items:center;gap:6px;white-space:nowrap}.activeTop{display:flex;align-items:flex-start;gap:8px}.activeText{flex:1;min-height:102px}.avatar{width:72px;height:72px;border-radius:999px;border:1.5px solid rgba(112,221,255,.65);display:flex;align-items:center;justify-content:center;color:#7df0ff;font-size:34px;background:radial-gradient(circle at 50% 38%,rgba(71,207,255,.16),rgba(6,15,29,.70) 70%);position:relative;flex:0 0 auto}.avatar:after{content:'✎';position:absolute;right:-4px;bottom:3px;width:32px;height:32px;border-radius:999px;border:1px solid rgba(112,221,255,.6);background:rgba(12,31,57,.92);display:flex;align-items:center;justify-content:center;font-size:16px}.activeText p{font-size:15px;line-height:1.32;margin:10px 0 0;max-width:25ch}.actions{display:flex;flex-wrap:wrap;margin:12px -14px -14px;border-top:1px solid rgba(121,214,255,.15)}.act{min-height:44px;display:flex;align-items:center;justify-content:center;text-align:center;padding:8px;border-left:1px solid rgba(121,214,255,.14);font-weight:900;font-size:14px;width:50%}.act.primary{width:calc(100% - 20px);border:1px solid rgba(78,220,255,.8);border-radius:15px;margin:8px 10px;min-height:48px;background:linear-gradient(180deg,rgba(24,84,132,.58),rgba(7,28,51,.78));box-shadow:0 0 18px rgba(0,205,255,.20)}.programFlex{display:grid;grid-template-columns:1fr 1.25fr;gap:14px;align-items:end}.program h3,.compact h3{font-size:28px;margin:0 0 5px;letter-spacing:-.03em;line-height:1.02}.program p,.compact p{font-size:16px;margin:0;color:#b9c6d7}.progTop{display:flex;justify-content:space-between;gap:12px;color:#b9c6d7;font-weight:800;font-size:15px;align-items:flex-end}.progTop b{color:#69e9ff;font-size:30px}.track{height:10px;border-radius:999px;background:rgba(86,142,186,.18);margin:8px 0 10px;overflow:hidden}.track span{display:block;height:100%;border-radius:inherit;background:linear-gradient(90deg,#4bdfff,#7cc9ff)}.statusMeta{display:flex;justify-content:space-between;gap:12px;border-top:1px solid rgba(121,214,255,.10);padding-top:8px;color:#b9c6d7;font-weight:780}.statusMeta b{color:#f4fbff;font-size:15px;font-weight:880}.summaryHead{display:flex;justify-content:space-between;gap:12px;align-items:center;margin-bottom:10px}.summaryHead .label{margin:0}.change{color:#70e8ff;font-weight:900;font-size:15px}.goalFocus{display:block}.goalPart{margin-bottom:10px}.cap{display:block;color:#9eacbd;font-weight:700;margin-bottom:4px;font-size:13px}.value{font-size:20px;font-weight:900}.twogrid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:7px;margin:0}.twogrid .chip{justify-content:center;min-width:0;overflow:hidden;text-overflow:ellipsis}.more{border-style:dashed;color:#8cf2ff;background:rgba(7,17,30,.34)}.rows{border:1px solid rgba(121,214,255,.14);border-radius:16px;overflow:hidden;background:rgba(6,15,29,.34)}.row{height:48px;display:flex;align-items:center;gap:10px;border-bottom:1px solid rgba(121,214,255,.12);padding:0 12px;background:rgba(15,29,49,.55);font-weight:850;font-size:15px}.row:last-child{border-bottom:0}.row span:nth-child(2){flex:1}.row b{font-size:23px;color:#d5e3f0;font-weight:400}.danger .ic{color:#ff6a6a}.ic{color:#69e9ff;font-weight:900}.note{font-size:13px;line-height:1.35;color:#aebccd;margin:10px 0 0}.toggle{width:52px;height:30px;border-radius:999px;background:#159aff;display:inline-block;position:relative}.toggle:after{content:'';position:absolute;right:3px;top:3px;width:24px;height:24px;border-radius:50%;background:white}.formrow{display:block;border-top:1px solid rgba(121,214,255,.10);padding:10px 0}.formrow:first-of-type{border-top:0}.formrow label{display:block;font-weight:850;margin-bottom:8px}.input{height:42px;border:1px solid rgba(121,214,255,.12);border-radius:12px;background:rgba(6,14,27,.42);display:flex;align-items:center;padding:0 14px;font-weight:850}.select{display:flex;flex-wrap:wrap;gap:8px}.opt{min-height:44px;border:1px solid rgba(121,214,255,.16);border-radius:13px;background:rgba(7,17,30,.52);display:flex;align-items:center;justify-content:center;text-align:center;font-weight:850;padding:8px;font-size:14px;min-width:calc(50% - 4px)}.opt.tile{min-height:78px;display:block;padding-top:15px}.sel{border-color:rgba(75,224,255,.94)!important;background:linear-gradient(180deg,rgba(19,83,129,.58),rgba(7,24,44,.72))!important;box-shadow:0 0 18px rgba(0,211,255,.22)}.save{display:grid;grid-template-columns:1fr 1.15fr;gap:12px;position:sticky;bottom:8px}.save .btn{height:54px;border-radius:16px;background:rgba(6,15,29,.88);font-size:16px}.btn{min-height:44px;border:1px solid rgba(121,214,255,.22);border-radius:14px;display:flex;align-items:center;justify-content:center;font-weight:900;background:rgba(8,18,32,.50);padding:8px 7px;text-align:center;font-size:13px}.desktop{padding:24px 24px 56px}.desktop .top{height:90px;border-radius:30px;margin-bottom:22px;padding:0 32px}.desktop .logo b{font-size:54px}.desktop .menu,.desktop .person{font-size:36px}.desktop .head h1{font-size:58px}.desktop .head p{font-size:22px}.desktop .card{padding:18px;border-radius:24px}.desktop .page{max-width:1180px}.desktop .titleName{font-size:58px}.desktop .chip{font-size:16px;padding:9px 13px}.desktop .activeTop{gap:24px}.desktop .avatar{width:136px;height:136px;font-size:64px}.desktop .actions{margin:18px -18px -18px}.desktop .act{min-height:62px;font-size:16px;width:25%}.desktop .act.primary{width:50%;margin:10px}.desktop .programFlex{display:flex;gap:26px;align-items:flex-start}.desktop .programLeft{width:38%}.desktop .programRight{flex:1}.desktop .goalFocus{display:grid;grid-template-columns:190px 1fr;gap:22px}.desktop .twogrid{grid-template-columns:repeat(4,minmax(0,auto));justify-content:start}.desktop .twogrid .chip{justify-content:flex-start}.tablet{padding:24px 24px 56px}.tablet .top{height:88px;border-radius:30px;margin-bottom:20px;padding:0 32px}.tablet .logo b{font-size:54px}.tablet .menu,.tablet .person{font-size:36px}.tablet .head h1{font-size:56px}.tablet .head p{font-size:21px}.tablet .card{padding:18px;border-radius:24px}.tablet .titleName{font-size:58px}.tablet .chip{font-size:15px;padding:8px 12px}.tablet .activeTop{gap:20px}.tablet .avatar{width:128px;height:128px;font-size:60px}.tablet .actions{margin:18px -18px -18px}.tablet .act{min-height:62px;font-size:16px;width:25%}.tablet .act.primary{width:50%;margin:10px}.tablet .programFlex{display:flex;gap:22px;align-items:flex-start}.tablet .programLeft{width:38%}.tablet .programRight{flex:1}.tablet .goalFocus{display:grid;grid-template-columns:190px 1fr;gap:22px}.tablet .twogrid{grid-template-columns:repeat(4,minmax(0,auto));justify-content:start}.tablet .twogrid .chip{justify-content:flex-start}
'''

def shell(content,w,h,klass=''):
    return f'<!doctype html><html><head><meta charset="utf-8"><style>@page{{size:{w}px {h}px;margin:0}}{CSS}</style></head><body class="{klass}"><div class="top"><div class="menu">☰</div><div class="logo"><b>NE<span>X</span>T</b><small>ATHLETE OS</small></div><div class="person">◯</div></div>{content}</body></html>'

overview='''<main class="page"><header class="head"><h1>Profil</h1><p>Atlet, mål och inställningar</p></header><section class="card"><div class="label">Aktiv profil</div><div class="activeTop"><div class="activeText"><h2 class="titleName">Isak</h2><div class="chips"><span class="chip">◎ 9–12 år</span><span class="chip">⌞ Hockey</span><span class="chip">▥ Utveckling</span></div><p class="muted">Fokus på snabbhet, reaktion och explosiva rörelser.</p></div><div class="avatar">♙</div></div><div class="actions"><div class="act primary">✎ Redigera profil</div><div class="act">⇄ Byt profil</div><div class="act">＋ Ny profil</div></div></section><section class="card program"><div class="programFlex"><div class="programLeft"><div class="label">Aktivt program</div><h3>9–12 år · Utveckling</h3><p>Fas 1 · Vecka 1</p></div><div class="programRight"><div class="progTop"><span>7 av 12 pass genomförda</span><b>58%</b></div><div class="track"><span style="width:58%"></span></div></div></div><div class="statusMeta"><span>Totalt program</span><b>12 pass</b></div></section><section class="card"><div class="summaryHead"><div class="label">Mål & fokus</div><span class="change">Ändra ›</span></div><div class="goalFocus"><div class="goalPart"><span class="cap">Huvudmål</span><span class="value">Bli snabbare</span></div><div class="goalPart"><span class="cap">Fokus</span><div class="twogrid"><span class="chip">♙ Balans</span><span class="chip">↯ Snabbhet</span><span class="chip">▤ Styrka</span></div></div></div></section><section class="card"><div class="summaryHead"><div class="label">Utrustning</div><span class="change">Ändra ›</span></div><div class="twogrid"><span class="chip">△ koner/markeringar</span><span class="chip">∪ hopprep</span><span class="chip">◉ medicinboll</span><span class="chip">⬚ box</span><span class="chip more">+1 till</span></div></section><section class="card"><div class="label">Data & backup</div><div class="rows"><div class="row"><span class="ic">⇧</span><span>Exportera backup</span><b>›</b></div><div class="row"><span class="ic">⇩</span><span>Importera backup</span><b>›</b></div><div class="row danger"><span class="ic">⌫</span><span>Rensa vald profil</span><b>›</b></div></div><p class="note">Progress och tester sparas lokalt i webbläsaren. Tillfällig profil sparar ingenting.</p></section><section class="card"><div class="label">Inställningar</div><div class="rows"><div class="row"><span class="ic">♩</span><span>Notiser</span><b>›</b></div><div class="row"><span class="ic">☾</span><span>Mörkt läge</span><span class="toggle"></span></div><div class="row"><span class="ic">i</span><span>Om appen</span><b>›</b></div></div></section></main>'''

edit='''<main class="page"><header class="head"><span class="back">← Profil</span><h1>Redigera profil</h1><p>Välj sport, mål, fokus och utrustning</p></header><section class="card"><div class="label">Grundinfo</div><div class="formrow"><label>♙ Namn</label><div class="input">Isak</div></div><div class="formrow"><label>◎ Åldersgrupp</label><div class="select"><div class="opt">7–9 år</div><div class="opt sel">9–12 år</div><div class="opt">12–16 år</div></div></div><div class="formrow"><label>⌞ Sport</label><div class="select"><div class="opt sel">Hockey</div><div class="opt">Fotboll</div><div class="opt">Downhill</div><div class="opt">Allmän atlet</div></div></div><div class="formrow"><label>▥ Nivå</label><div class="select"><div class="opt">Grund</div><div class="opt sel">Utveckling</div><div class="opt">Avancerad</div></div></div><div class="formrow"><label>◯ Avatar</label><div class="select"><div class="opt sel">Hockey</div><div class="opt">Målvakt</div><div class="opt">Downhill</div><div class="opt">Atlet</div></div></div><p class="note">Profilbild körs som färdiga avatarer i denna version. Egen uppladdning kan läggas till senare.</p></section><section class="card"><div class="label">Mål <span style="letter-spacing:0;text-transform:none;color:#aebccd">Välj 1 huvudmål</span></div><div class="select"><div class="opt tile">☺<br>Rörelseglädje</div><div class="opt tile">▦<br>Bygga grund</div><div class="opt tile sel">↯<br>Bli snabbare</div><div class="opt tile">♢<br>Skadeförebyggande</div></div></section><section class="card"><div class="label">Fokusområden <span style="letter-spacing:0;text-transform:none;color:#aebccd">Välj 2–4 fokusområden</span></div><div class="select"><div class="opt">Koordination</div><div class="opt sel">Balans</div><div class="opt sel">Snabbhet</div><div class="opt sel">Styrka</div><div class="opt">Teknik</div><div class="opt">Hopp</div></div></section><section class="card"><div class="label">Utrustning <span style="letter-spacing:0;text-transform:none;color:#aebccd">Välj tillgänglig utrustning</span></div><div class="select"><div class="opt sel">koner/markeringar</div><div class="opt sel">hopprep</div><div class="opt sel">medicinboll</div><div class="opt sel">box</div><div class="opt">lågt räcke/ringar</div><div class="opt">hantlar</div><div class="opt">matta</div></div></section><section class="card compact"><div><div class="label">Aktivt program</div><h3>9–12 år · Utveckling</h3><p>Fas 1 · Vecka 1</p></div><div class="btn">Visa program</div></section><div class="save"><div class="btn">Avbryt</div><div class="btn">✓ Spara profil</div></div></main>'''

renders=[
 ('rc55_profile_overview_mobile_390x844',390,844,overview,''),
 ('rc55_profile_overview_full_mobile_390x1600',390,1600,overview,''),
 ('rc55_profile_edit_mobile_390x844',390,844,edit,''),
 ('rc55_profile_overview_ipad_820x1180',820,1180,overview,'tablet'),
 ('rc55_profile_overview_desktop_1440x1024',1440,1024,overview,'desktop'),
]
for name,w,h,content,klass in renders:
    html=qa/f'{name}.html'; pdf=qa/f'{name}.pdf'; base=shots/name
    html.write_text(shell(content,w,h,klass),encoding='utf-8')
    HTML(filename=str(html), base_url=str(root)).write_pdf(str(pdf))
    subprocess.run(['pdftoppm','-png','-singlefile','-r','144',str(pdf),str(base)],check=True)
    print(shots/f'{name}.png')
