Liveloop

An interactive timeline for social media. Every post is a tiny app you can play, save, and remix.

Product

  • Feed
  • Create
  • Claude Code plugin
  • Blog

Legal

  • Privacy Policy
  • Terms of Service
  • Cookie Policy
  • DMCA

Project

  • Templates
© 2026 Liveloop. All rights reserved.
LiveloopVersion history

v1Current

@mae_arcade · 6/20/2026, 2:18:35 AM

Initial version — all lines are new.

+<style>
+ html,body{height:100%;margin:0;overflow:hidden;background:#0d3b2e;}
+ *{box-sizing:border-box;}
+ #wrap{position:relative;height:100%;width:100%;display:flex;flex-direction:column;font-family:system-ui,-apple-system,Segoe UI,Roboto,sans-serif;background:radial-gradient(120% 80% at 50% 0%,#15573f 0%,#0e4733 55%,#0a3527 100%);-webkit-tap-highlight-color:transparent;touch-action:manipulation;user-select:none;-webkit-user-select:none;color:#fff;}
+ #head{padding:.95rem 1.2rem .2rem;}
+ #head h1{margin:0;font-family:"Instrument Serif",Georgia,"Times New Roman",serif;font-weight:400;font-size:2rem;line-height:1;color:#fff;}
+ #tabs{display:inline-flex;margin-top:.5rem;background:rgba(0,0,0,.25);border:1px solid rgba(255,255,255,.14);border-radius:999px;padding:3px;}
+ .tab{border:0;background:transparent;color:rgba(255,255,255,.7);font-size:.78rem;font-weight:800;padding:.34rem .9rem;border-radius:999px;cursor:pointer;}
+ .tab.on{background:#fff;color:#0e4733;}
+ #hud{display:flex;gap:8px;padding:.45rem 1.2rem .2rem;flex-wrap:wrap;}
+ .pill{background:rgba(255,255,255,.12);border:1px solid rgba(255,255,255,.18);border-radius:999px;font-size:.72rem;font-weight:800;padding:.32rem .7rem;}
+ .mode{flex:1;min-height:0;display:flex;flex-direction:column;}
+ /* ---- collect ---- */
+ #albumWrap{flex:1;min-height:0;overflow-y:auto;padding:.6rem 1rem 1rem;-webkit-overflow-scrolling:touch;}
+ #album{display:grid;grid-template-columns:repeat(4,1fr);gap:8px;}
+ .slot{position:relative;aspect-ratio:3/4;border-radius:11px;background:rgba(0,0,0,.22);border:1px dashed rgba(255,255,255,.16);display:flex;flex-direction:column;align-items:center;justify-content:center;gap:2px;overflow:hidden;}
+ .slot.got{background:linear-gradient(160deg,#1d6b4d,#124e38);border:1px solid rgba(255,255,255,.22);box-shadow:0 4px 12px rgba(0,0,0,.25);}
+ .slot.foil.got{background:linear-gradient(160deg,#7a5e12,#a8841f 45%,#5e470c);border-color:#ffd86b;box-shadow:0 0 14px rgba(255,200,80,.4);}
+ .slot .fl{font-size:2rem;line-height:1;filter:grayscale(1) opacity(.18);}
+ .slot.got .fl{filter:none;}
+ .slot .cc{font-size:.58rem;font-weight:800;letter-spacing:.04em;color:rgba(255,255,255,.35);}
+ .slot.got .cc{color:#eafff2;}
+ .slot.foil.got::after{content:"";position:absolute;inset:0;background:linear-gradient(115deg,transparent 30%,rgba(255,255,255,.55) 48%,transparent 66%);background-size:250% 100%;animation:shine 2.6s linear infinite;pointer-events:none;}
+ @keyframes shine{0%{background-position:140% 0}100%{background-position:-40% 0}}
+ .slot .num{position:absolute;top:3px;left:5px;font-size:.5rem;font-weight:800;color:rgba(255,255,255,.3);}
+ .slot.got .num{color:rgba(255,255,255,.6);}
+ /* ---- team / pitch ---- */
+ #teamWrap{padding:.5rem 1rem 1rem;}
+ #pitch{position:relative;flex:1;min-height:0;border-radius:16px;overflow:hidden;border:2px solid rgba(255,255,255,.18);
+ background:repeating-linear-gradient(0deg,#1c7a4f 0 11%,#198047 11% 22%);}
+ #pitch::before{content:"";position:absolute;left:8%;right:8%;top:50%;height:2px;background:rgba(255,255,255,.3);}
+ #pitch .circle{position:absolute;left:50%;top:50%;width:26%;aspect-ratio:1;border:2px solid rgba(255,255,255,.3);border-radius:50%;transform:translate(-50%,-50%);}
+ #pitch .box{position:absolute;left:24%;right:24%;height:11%;border:2px solid rgba(255,255,255,.28);}
+ #pitch .box.top{top:0;border-top:0;}
+ #pitch .box.bot{bottom:0;border-bottom:0;}
+ .pos{position:absolute;transform:translate(-50%,-50%);display:flex;flex-direction:column;align-items:center;gap:3px;cursor:pointer;width:22%;}
+ .av{width:54px;height:54px;border-radius:50%;background:rgba(0,0,0,.35) center/cover no-repeat;border:2px solid rgba(255,255,255,.5);display:flex;align-items:center;justify-content:center;position:relative;box-shadow:0 3px 8px rgba(0,0,0,.35);}
+ .av .plus{font-size:1.5rem;font-weight:300;color:rgba(255,255,255,.8);line-height:1;}
+ .av .sh{position:absolute;bottom:-4px;right:-4px;min-width:18px;height:18px;padding:0 3px;border-radius:9px;background:#ffd24d;color:#3a2400;font-size:.6rem;font-weight:900;display:flex;align-items:center;justify-content:center;border:1px solid rgba(0,0,0,.15);}
+ .pos .nm{font-size:.6rem;font-weight:800;text-shadow:0 1px 3px rgba(0,0,0,.6);max-width:70px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;text-align:center;}
+ .pos .ro{font-size:.52rem;font-weight:700;color:rgba(255,255,255,.65);}
+ #foot{padding:.5rem 1.2rem max(1rem,env(safe-area-inset-bottom));display:flex;justify-content:center;align-items:center;min-height:3.2rem;}
+ #open{border:0;border-radius:999px;background:linear-gradient(135deg,#ffd24d,#ff8a1f);color:#3a2400;font-weight:900;font-size:1rem;padding:.9rem 1.8rem;cursor:pointer;box-shadow:0 10px 26px rgba(255,140,30,.4);}
+ #open:active{transform:scale(.96);}
+ #open:disabled{opacity:.5;}
+ #shareBtn{border:0;border-radius:999px;background:rgba(255,255,255,.14);border:1px solid rgba(255,255,255,.25);color:#fff;font-weight:800;font-size:.92rem;padding:.8rem 1.5rem;cursor:pointer;display:flex;align-items:center;gap:.4rem;}
+ #shareBtn:active{transform:scale(.96);}
+ /* ---- share preview ---- */
+ #shareView{position:absolute;inset:0;z-index:14;display:none;flex-direction:column;align-items:center;justify-content:center;background:rgba(4,18,13,.9);backdrop-filter:blur(8px);padding:1.1rem;}
+ #shareImg{max-width:100%;max-height:74%;border-radius:14px;box-shadow:0 16px 40px rgba(0,0,0,.5);display:none;}
+ #shareLoad{color:rgba(255,255,255,.7);font-size:.85rem;font-weight:700;}
+ #shareCap{color:rgba(255,255,255,.75);font-size:.78rem;font-weight:600;text-align:center;margin:.9rem 0 .2rem;max-width:18rem;line-height:1.35;}
+ #shareRow{display:flex;gap:.6rem;margin-top:.8rem;}
+ #shareRow button{border:0;border-radius:999px;font-weight:800;font-size:.88rem;padding:.7rem 1.4rem;cursor:pointer;}
+ #shareNative{background:#ffd24d;color:#3a2400;}
+ #shareClose{background:rgba(255,255,255,.15);color:#fff;}
+ /* ---- reveal / done ---- */
+ #reveal{position:absolute;inset:0;z-index:10;display:none;flex-direction:column;align-items:center;justify-content:center;background:rgba(6,28,21,.82);backdrop-filter:blur(6px);padding:1.2rem;text-align:center;}
+ #card{width:60%;max-width:210px;aspect-ratio:3/4;border-radius:18px;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:.4rem;position:relative;overflow:hidden;box-shadow:0 18px 50px rgba(0,0,0,.5);transform:scale(.6);opacity:0;transition:transform .35s cubic-bezier(.2,1.3,.5,1),opacity .25s;}
+ #card.in{transform:scale(1);opacity:1;}
+ #card .bigfl{font-size:5rem;line-height:1;}
+ #card .name{font-size:1.05rem;font-weight:800;}
+ #card.common{background:linear-gradient(160deg,#1d6b4d,#0f4733);border:2px solid rgba(255,255,255,.2);}
+ #card.foil{background:linear-gradient(160deg,#8a6a14,#c79a23 45%,#6b520e);border:2px solid #ffd86b;}
+ #card.foil::after{content:"";position:absolute;inset:0;background:linear-gradient(115deg,transparent 35%,rgba(255,255,255,.6) 50%,transparent 65%);background-size:250% 100%;animation:shine 2s linear infinite;}
+ #tag{margin-top:1rem;font-weight:900;font-size:1.05rem;min-height:1.3em;}
+ #tag.dupe{color:#ffcaa8;}
+ #tag.new{color:#9dffc8;}
+ #revHint{margin-top:.5rem;font-size:.72rem;color:rgba(255,255,255,.6);font-weight:600;}
+ #count{margin-top:.6rem;font-size:.7rem;color:rgba(255,255,255,.45);font-weight:700;}
+ #done{position:absolute;inset:0;z-index:11;display:none;flex-direction:column;align-items:center;justify-content:center;background:rgba(6,28,21,.85);backdrop-filter:blur(6px);text-align:center;padding:1.4rem;}
+ #done h2{font-family:"Instrument Serif",Georgia,serif;font-style:italic;font-size:2.2rem;margin:0;color:#ffe08a;}
+ #done p{color:#cfe;font-size:.85rem;margin:.5rem 0 1.2rem;}
+ #done button{border:0;border-radius:999px;background:#fff;color:#0e4733;font-weight:800;font-size:.9rem;padding:.7rem 1.4rem;cursor:pointer;}
+ .cf{position:absolute;width:8px;height:8px;border-radius:2px;pointer-events:none;z-index:12;}
+ /* ---- player editor sheet ---- */
+ #sheet{position:absolute;inset:0;z-index:13;display:none;align-items:flex-end;background:rgba(4,20,15,.55);backdrop-filter:blur(3px);}
+ #sheetIn{width:100%;background:#0e4733;border-top:1px solid rgba(255,255,255,.15);border-radius:18px 18px 0 0;padding:1rem 1.1rem max(1.1rem,env(safe-area-inset-bottom));box-shadow:0 -12px 30px rgba(0,0,0,.4);}
+ #sheetHd{display:flex;align-items:center;gap:.7rem;margin-bottom:.8rem;}
+ #sheetAv{width:64px;height:64px;border-radius:50%;background:rgba(0,0,0,.3) center/cover no-repeat;border:2px solid rgba(255,255,255,.4);display:flex;align-items:center;justify-content:center;font-size:1.6rem;color:rgba(255,255,255,.7);flex:0 0 auto;}
+ #sheetRole{font-size:.95rem;font-weight:800;}
+ #sheetRole small{display:block;font-weight:600;color:rgba(255,255,255,.6);font-size:.72rem;margin-top:2px;}
+ .field{display:flex;gap:.6rem;margin-bottom:.7rem;}
+ .field input{flex:1;background:rgba(255,255,255,.1);border:1px solid rgba(255,255,255,.2);color:#fff;border-radius:11px;padding:.6rem .75rem;font-size:.9rem;font-family:inherit;}
+ .field input#nmNum{flex:0 0 64px;text-align:center;}
+ .field input::placeholder{color:rgba(255,255,255,.45);}
+ .sBtn{border:0;border-radius:11px;font-weight:800;font-size:.85rem;padding:.7rem 1rem;cursor:pointer;}
+ #pickBtn{width:100%;background:rgba(255,255,255,.14);color:#fff;margin-bottom:.7rem;}
+ #sheetRow{display:flex;gap:.6rem;}
+ #rm{flex:0 0 auto;background:rgba(255,120,120,.18);color:#ffd4d4;}
+ #sheetDone{flex:1;background:#ffd24d;color:#3a2400;}
+</style>
+<div id="wrap">
+ <div id="head">
+ <h1>Sticker Album</h1>
+ <div id="tabs">
+ <button class="tab on" id="tabCollect">Collect</button>
+ <button class="tab" id="tabTeam">My XI</button>
+ </div>
+ </div>
+ <div id="hud">
+ <span class="pill" id="pctPill">0/32</span>
+ <span class="pill" id="repPill">0 dupes</span>
+ <span class="pill" id="packPill">0 packs</span>
+ <span class="pill" id="teamPill" style="display:none">0/11 picked</span>
+ </div>
+
+ <div id="collectWrap" class="mode"><div id="albumWrap"><div id="album"></div></div></div>
+ <div id="teamWrap" class="mode" style="display:none"><div id="pitch"></div></div>
+
+ <div id="foot">
+ <button id="open">Open a pack &#9917;</button>
+ <button id="shareBtn" style="display:none">&#128247; Share lineup</button>
+ </div>
+
+ <div id="reveal">
+ <div id="card"></div>
+ <div id="tag"></div>
+ <div id="revHint">tap to keep going</div>
+ <div id="count"></div>
+ </div>
+ <div id="done">
+ <h2>Album complete!</h2>
+ <p>All 32 stickers collected. Legend.</p>
+ <button id="restart">start a new album</button>
+ </div>
+
+ <div id="sheet">
+ <div id="sheetIn">
+ <div id="sheetHd">
+ <div id="sheetAv">+</div>
+ <div id="sheetRole">Player<small id="sheetSub"></small></div>
+ </div>
+ <input id="pick" type="file" accept="image/*" hidden>
+ <button class="sBtn" id="pickBtn">Choose a photo</button>
+ <div class="field">
+ <input id="nm" placeholder="Name" maxlength="18">
+ <input id="nmNum" type="number" inputmode="numeric" placeholder="#" min="0" max="99">
+ </div>
+ <div id="sheetRow">
+ <button class="sBtn" id="rm">Remove</button>
+ <button class="sBtn" id="sheetDone">Done</button>
+ </div>
+ </div>
+ </div>
+
+ <div id="shareView">
+ <div id="shareLoad">Rendering your lineup…</div>
+ <img id="shareImg" alt="My starting XI">
+ <p id="shareCap">Press &amp; hold the image to save it, then share anywhere &#128247;</p>
+ <div id="shareRow">
+ <button id="shareNative" style="display:none">Share…</button>
+ <button id="shareClose">Done</button>
+ </div>
+ </div>
+</div>
+<script>
+(function(){
+ var LL=window.liveloop||null;
+ var muted = LL ? LL.muted : true;
+ if(LL && LL.onMute){ try{ LL.onMute(function(m){ muted=m; }); }catch(e){} }
+ if(LL && LL.declareMedia){ try{ LL.declareMedia({sound:true}); }catch(e){} }
+ var _ac=null;
+ function actx(){ if(!_ac){ try{ _ac=new (window.AudioContext||window.webkitAudioContext)(); }catch(e){ _ac=null; } } return _ac; }
+ function blip(f,type,vol,dur){
+ if(muted) return; var c=actx(); if(!c) return;
+ var t=c.currentTime, o=c.createOscillator(), g=c.createGain();
+ o.type=type||'triangle'; o.frequency.setValueAtTime(f,t);
+ g.gain.setValueAtTime(0.0001,t); g.gain.exponentialRampToValueAtTime(vol||0.12,t+0.01);
+ g.gain.exponentialRampToValueAtTime(0.0001,t+(dur||0.18));
+ o.connect(g); g.connect(c.destination); o.start(t); o.stop(t+(dur||0.18)+0.04);
+ }
+ function rip(){
+ if(muted) return; var c=actx(); if(!c) return;
+ var t=c.currentTime, n=Math.floor(c.sampleRate*0.18), b=c.createBuffer(1,n,c.sampleRate), d=b.getChannelData(0);
+ for(var i=0;i<n;i++){ d[i]=(Math.random()*2-1)*Math.pow(1-i/n,1.2); }
+ var s=c.createBufferSource(); s.buffer=b; var f=c.createBiquadFilter(); f.type='highpass'; f.frequency.value=1800;
+ var g=c.createGain(); g.gain.value=0.12; s.connect(f); f.connect(g); g.connect(c.destination); s.start(t);
+ }
+ function sparkle(){ blip(880,'sine',0.09,0.3); setTimeout(function(){blip(1318.5,'sine',0.08,0.4);},90); setTimeout(function(){blip(1760,'sine',0.07,0.5);},190); }
+ function fanfare(){ var n=[523.25,659.25,783.99,1046.5,1318.5]; for(var i=0;i<n.length;i++){ (function(i){ setTimeout(function(){ blip(n[i],'triangle',0.13,0.5); },i*100); })(i); } }
+
+ var STICKERS=[
+ {f:'🇧🇷',c:'BRA',L:1},{f:'🇦🇷',c:'ARG',L:1},{f:'🇫🇷',c:'FRA',L:1},{f:'🇩🇪',c:'GER',L:1},
+ {f:'🇪🇸',c:'ESP',L:1},{f:'🇵🇹',c:'POR',L:1},{f:'🇮🇹',c:'ITA',L:1},{f:'🇳🇱',c:'NED',L:1},
+ {f:'🇬🇧',c:'ENG',L:0},{f:'🇧🇪',c:'BEL',L:0},{f:'🇭🇷',c:'CRO',L:0},{f:'🇺🇾',c:'URU',L:0},
+ {f:'🇲🇽',c:'MEX',L:0},{f:'🇺🇸',c:'USA',L:0},{f:'🇯🇵',c:'JPN',L:0},{f:'🇰🇷',c:'KOR',L:0},
+ {f:'🇲🇦',c:'MAR',L:0},{f:'🇸🇳',c:'SEN',L:0},{f:'🇬🇭',c:'GHA',L:0},{f:'🇨🇲',c:'CMR',L:0},
+ {f:'🇨🇴',c:'COL',L:0},{f:'🇨🇱',c:'CHI',L:0},{f:'🇪🇨',c:'ECU',L:0},{f:'🇵🇾',c:'PAR',L:0},
+ {f:'🇨🇭',c:'SUI',L:0},{f:'🇩🇰',c:'DEN',L:0},{f:'🇵🇱',c:'POL',L:0},{f:'🇷🇸',c:'SRB',L:0},
+ {f:'🇦🇺',c:'AUS',L:0},{f:'🇨🇦',c:'CAN',L:0},{f:'🇳🇬',c:'NGA',L:0},{f:'🇶🇦',c:'QAT',L:0}
+ ];
+ var N=STICKERS.length;
+ // The cup ends 19 Jul 2026. After that the album stays viewable with what
+ // you've collected, but no more packs open. Building your XI is never gated.
+ var DEADLINE=Date.UTC(2026,6,20,0,0,0); // 00:00 UTC 20 Jul = end of the 19th
+ function expired(){ try{ return Date.now()>=DEADLINE; }catch(e){ return false; } }
+ var commons=[], legends=[];
+ for(var i=0;i<N;i++){ (STICKERS[i].L?legends:commons).push(i); }
+
+ // 4-3-3 on a vertical pitch (attack at top, keeper at bottom)
+ var FORMATION=[
+ {k:'st', ro:'ST', num:9, x:50,y:13},
+ {k:'lw', ro:'LW', num:11,x:19,y:22},
+ {k:'rw', ro:'RW', num:7, x:81,y:22},
+ {k:'cm1',ro:'CM', num:8, x:27,y:43},
+ {k:'am', ro:'CAM',num:10,x:50,y:38},
+ {k:'cm2',ro:'CM', num:6, x:73,y:43},
+ {k:'lb', ro:'LB', num:3, x:15,y:65},
+ {k:'cb1',ro:'CB', num:4, x:38,y:68},
+ {k:'cb2',ro:'CB', num:2, x:62,y:68},
+ {k:'rb', ro:'RB', num:5, x:85,y:65},
+ {k:'gk', ro:'GK', num:1, x:50,y:87}
+ ];
+
+ var owned={}, repeats=0, packs=0, team={}, albumDone=false;
+ function load(){
+ try{ if(LL && LL.storage && LL.storage.get){ LL.storage.get().then(function(s){
+ if(s){ owned=s.owned||{}; repeats=s.repeats||0; packs=s.packs||0; team=s.team||{}; } renderAll();
+ }).catch(renderAll); } else renderAll(); }catch(e){ renderAll(); }
+ }
+ function save(){ try{ if(LL && LL.storage && LL.storage.set) LL.storage.set({owned:owned,repeats:repeats,packs:packs,team:team}); }catch(e){} }
+
+ var albumEl=document.getElementById('album'), pitchEl=document.getElementById('pitch');
+ var pctPill=document.getElementById('pctPill'), repPill=document.getElementById('repPill'), packPill=document.getElementById('packPill'), teamPill=document.getElementById('teamPill');
+ var openBtn=document.getElementById('open'), shareBtn=document.getElementById('shareBtn');
+ var shareView=document.getElementById('shareView'), shareImg=document.getElementById('shareImg'),
+ shareLoad=document.getElementById('shareLoad'), shareNative=document.getElementById('shareNative');
+ var revealEl=document.getElementById('reveal'), cardEl=document.getElementById('card'), tagEl=document.getElementById('tag'), countEl=document.getElementById('count');
+ var doneEl=document.getElementById('done');
+ var wrap=document.getElementById('wrap');
+ var collectWrap=document.getElementById('collectWrap'), teamWrap=document.getElementById('teamWrap');
+ var tabCollect=document.getElementById('tabCollect'), tabTeam=document.getElementById('tabTeam');
+
+ /* ============ collect mode ============ */
+ function buildAlbum(){
+ albumEl.innerHTML='';
+ for(var i=0;i<N;i++){ (function(i){
+ var s=STICKERS[i];
+ var d=document.createElement('div'); d.className='slot'+(s.L?' foil':'')+(owned[i]?' got':'');
+ d.innerHTML='<span class="num">'+(i+1)+'</span><span class="fl">'+s.f+'</span><span class="cc">'+s.c+'</span>';
+ d.id='slot'+i; albumEl.appendChild(d);
+ })(i); }
+ }
+ function ownedCount(){ var n=0; for(var k in owned) if(owned[k]) n++; return n; }
+ function renderHud(){
+ var n=ownedCount();
+ pctPill.textContent=n+'/'+N;
+ repPill.textContent=repeats+' dupe'+(repeats===1?'':'s');
+ packPill.textContent=packs+' pack'+(packs===1?'':'s');
+ teamPill.textContent=teamCount()+'/11 picked';
+ }
+ function refreshOpen(){
+ if(expired()){ openBtn.disabled=true; openBtn.textContent='Tournament over ⚽'; }
+ }
+
+ function pickOne(){
+ var pool = (Math.random()<0.16 && legends.length) ? legends : commons;
+ return pool[Math.floor(Math.random()*pool.length)];
+ }
+ var queue=[], showing=false;
+ function openPack(){
+ if(showing || expired()) return;
+ packs++; rip();
+ queue=[]; for(var k=0;k<5;k++) queue.push(pickOne());
+ showNext(); save();
+ }
+ function showNext(){
+ if(queue.length===0){ showing=false; revealEl.style.display='none';
+ if(ownedCount()>=N && !albumDone){ albumDone=true; doneEl.style.display='flex'; fanfare(); confetti(); }
+ return;
+ }
+ showing=true; revealEl.style.display='flex';
+ var idx=queue.shift(), s=STICKERS[idx], isNew=!owned[idx];
+ cardEl.className=s.L?'foil':'common';
+ cardEl.innerHTML='<span class="bigfl">'+s.f+'</span><span class="name">'+s.c+'</span>';
+ cardEl.classList.remove('in'); void cardEl.offsetWidth; cardEl.classList.add('in');
+ if(s.L) sparkle(); else blip(660,'triangle',0.1,0.18);
+ if(isNew){ owned[idx]=1; tagEl.textContent=s.L?'★ LEGEND! got it':'Got it!'; tagEl.className='new';
+ var slot=document.getElementById('slot'+idx); if(slot){ slot.className='slot'+(s.L?' foil':'')+' got'; }
+ } else { repeats++; tagEl.textContent='Repetida…'; tagEl.className='dupe'; }
+ countEl.textContent=queue.length+' left in the pack';
+ renderHud(); save();
+ }
+
+ /* ============ team mode ============ */
+ function teamCount(){ var n=0; for(var k in team){ if(team[k] && (team[k].photo||team[k].name)) n++; } return n; }
+ function buildPitch(){
+ pitchEl.innerHTML='<div class="box top"></div><div class="box bot"></div><div class="circle"></div>';
+ for(var i=0;i<FORMATION.length;i++){ (function(p){
+ var el=document.createElement('div'); el.className='pos'; el.id='pos_'+p.k;
+ el.style.left=p.x+'%'; el.style.top=p.y+'%';
+ el.addEventListener('pointerdown',function(e){ e.stopPropagation(); openSheet(p); });
+ pitchEl.appendChild(el); renderPos(p);
+ })(FORMATION[i]); }
+ }
+ function renderPos(p){
+ var el=document.getElementById('pos_'+p.k); if(!el) return;
+ var t=team[p.k]||{}; var num=(t.num!=null&&t.num!=='')?t.num:p.num;
+ var avStyle=t.photo?('background-image:url('+t.photo+')'):'';
+ el.innerHTML=
+ '<div class="av" style="'+avStyle+'">'+(t.photo?'':'<span class="plus">+</span>')+'<span class="sh">'+num+'</span></div>'+
+ '<div class="nm">'+(t.name?esc(t.name):p.ro)+'</div>'+
+ (t.name?'<div class="ro">'+p.ro+'</div>':'');
+ }
+ function esc(s){ return String(s).replace(/[&<>"]/g,function(c){return {'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;'}[c];}); }
+
+ // ---- player editor sheet ----
+ var sheet=document.getElementById('sheet'), sheetAv=document.getElementById('sheetAv'),
+ sheetRole=document.getElementById('sheetRole'), sheetSub=document.getElementById('sheetSub'),
+ pick=document.getElementById('pick'), nm=document.getElementById('nm'), nmNum=document.getElementById('nmNum');
+ var editKey=null, editPos=null;
+ function openSheet(p){
+ editKey=p.k; editPos=p; var t=team[p.k]||{};
+ sheetRole.childNodes[0].nodeValue=p.ro; sheetSub.textContent='photo · name · number';
+ nm.value=t.name||''; nmNum.value=(t.num!=null&&t.num!=='')?t.num:p.num;
+ if(t.photo){ sheetAv.style.backgroundImage='url('+t.photo+')'; sheetAv.textContent=''; }
+ else { sheetAv.style.backgroundImage=''; sheetAv.textContent='+'; }
+ sheet.style.display='flex'; blip(560,'sine',0.06,0.12);
+ }
+ function closeSheet(){ sheet.style.display='none'; editKey=null; editPos=null; }
+ function ensure(){ if(!team[editKey]) team[editKey]={}; return team[editKey]; }
+
+ document.getElementById('pickBtn').addEventListener('pointerdown',function(e){ e.preventDefault(); pick.click(); });
+ pick.addEventListener('change',function(){
+ var f=pick.files&&pick.files[0]; if(!f) return;
+ var rd=new FileReader();
+ rd.onload=function(){
+ var im=new Image();
+ im.onload=function(){
+ var S=96, cv=document.createElement('canvas'); cv.width=S; cv.height=S;
+ var ctx=cv.getContext('2d');
+ var sc=Math.max(S/im.width,S/im.height), sw=S/sc, sh=S/sc;
+ ctx.drawImage(im,(im.width-sw)/2,(im.height-sh)/2,sw,sh,0,0,S,S);
+ // 11 stickers share a ~64KB liveloop.storage budget, so cap each photo
+ // to ~4.8KB (step quality down for busy images) — else a full XI silently
+ // overflows and never persists.
+ var q=0.55, data=cv.toDataURL('image/jpeg',q);
+ while(data.length>4800 && q>0.3){ q-=0.1; data=cv.toDataURL('image/jpeg',q); }
+ ensure().photo=data;
+ sheetAv.style.backgroundImage='url('+data+')'; sheetAv.textContent='';
+ save();
+ };
+ im.src=rd.result;
+ };
+ rd.readAsDataURL(f);
+ pick.value='';
+ });
+ nm.addEventListener('input',function(){ ensure().name=nm.value; });
+ nmNum.addEventListener('input',function(){ var v=nmNum.value; ensure().num=(v===''?'':Math.max(0,Math.min(99,parseInt(v,10)||0))); });
+ document.getElementById('rm').addEventListener('pointerdown',function(e){
+ e.stopPropagation(); delete team[editKey]; if(editPos) renderPos(editPos); renderHud(); save(); closeSheet();
+ });
+ document.getElementById('sheetDone').addEventListener('pointerdown',function(e){
+ e.stopPropagation();
+ var t=team[editKey];
+ if(t && !t.photo && !(t.name&&t.name.trim())){ delete team[editKey]; } // nothing entered → leave empty
+ if(editPos) renderPos(editPos); renderHud(); save();
+ blip(720,'triangle',0.1,0.18); closeSheet();
+ });
+ sheet.addEventListener('pointerdown',function(e){ if(e.target===sheet){ document.getElementById('sheetDone').dispatchEvent(new Event('pointerdown')); } });
+
+ /* ============ shared ============ */
+ function renderAll(){ albumDone=(ownedCount()>=N); buildAlbum(); buildPitch(); renderHud(); refreshOpen(); }
+
+ var mode='collect';
+ function setMode(m){
+ mode=m;
+ var collect=(m==='collect');
+ tabCollect.classList.toggle('on',collect); tabTeam.classList.toggle('on',!collect);
+ collectWrap.style.display=collect?'flex':'none';
+ teamWrap.style.display=collect?'none':'flex';
+ pctPill.style.display=collect?'':'none'; repPill.style.display=collect?'':'none'; packPill.style.display=collect?'':'none';
+ teamPill.style.display=collect?'none':'';
+ openBtn.style.display=collect?'':'none'; shareBtn.style.display=collect?'none':'';
+ blip(collect?520:660,'sine',0.05,0.1);
+ }
+ tabCollect.addEventListener('pointerdown',function(){ setMode('collect'); });
+ tabTeam.addEventListener('pointerdown',function(){ setMode('team'); });
+
+ revealEl.addEventListener('pointerdown',function(){ if(showing) showNext(); });
+ openBtn.addEventListener('pointerdown',function(e){ e.preventDefault(); openPack(); });
+ document.getElementById('restart').addEventListener('pointerdown',function(e){
+ e.stopPropagation(); owned={}; repeats=0; packs=0; doneEl.style.display='none'; save(); renderAll();
+ });
+
+ /* ---- share lineup as an image ---- */
+ function loadImg(src){ return new Promise(function(res){ var im=new Image(); im.onload=function(){res(im);}; im.onerror=function(){res(null);}; im.src=src; }); }
+ function roundRect(ctx,x,y,w,h,r){ ctx.beginPath(); ctx.moveTo(x+r,y); ctx.arcTo(x+w,y,x+w,y+h,r); ctx.arcTo(x+w,y+h,x,y+h,r); ctx.arcTo(x,y+h,x,y,r); ctx.arcTo(x,y,x+w,y,r); ctx.closePath(); }
+ function paintLineup(ctx,W,H,list){
+ ctx.fillStyle='#0e4733'; ctx.fillRect(0,0,W,H);
+ ctx.textAlign='center'; ctx.textBaseline='middle';
+ ctx.fillStyle='#fff'; ctx.font='italic 700 62px Georgia, "Times New Roman", serif';
+ ctx.fillText('My Starting XI', W/2, 78);
+ var px=40,py=148,pw=W-80,ph=H-228;
+ ctx.save(); roundRect(ctx,px,py,pw,ph,28); ctx.clip();
+ var bands=7; for(var i=0;i<bands;i++){ ctx.fillStyle=(i%2)?'#198047':'#1c7a4f'; ctx.fillRect(px,py+ph*i/bands,pw,ph/bands+1); }
+ ctx.strokeStyle='rgba(255,255,255,.32)'; ctx.lineWidth=4;
+ ctx.beginPath(); ctx.moveTo(px,py+ph/2); ctx.lineTo(px+pw,py+ph/2); ctx.stroke();
+ ctx.beginPath(); ctx.arc(px+pw/2,py+ph/2,pw*0.13,0,Math.PI*2); ctx.stroke();
+ var bw=pw*0.52,bh=ph*0.11,bx=px+(pw-bw)/2;
+ ctx.strokeRect(bx,py,bw,bh); ctx.strokeRect(bx,py+ph-bh,bw,bh);
+ ctx.restore();
+ ctx.strokeStyle='rgba(255,255,255,.4)'; ctx.lineWidth=5; roundRect(ctx,px,py,pw,ph,28); ctx.stroke();
+ list.forEach(function(o){
+ var p=o.p, t=team[p.k]||{}, cx=px+p.x/100*pw, cy=py+p.y/100*ph, R=62;
+ ctx.save(); ctx.beginPath(); ctx.arc(cx,cy,R,0,Math.PI*2); ctx.closePath();
+ if(o.im){ ctx.clip(); var s=Math.max(2*R/o.im.width,2*R/o.im.height), sw=2*R/s, sh=2*R/s;
+ ctx.drawImage(o.im,(o.im.width-sw)/2,(o.im.height-sh)/2,sw,sh,cx-R,cy-R,2*R,2*R); }
+ else { ctx.fillStyle='rgba(0,0,0,.4)'; ctx.fill(); }
+ ctx.restore();
+ ctx.strokeStyle='rgba(255,255,255,.85)'; ctx.lineWidth=5; ctx.beginPath(); ctx.arc(cx,cy,R,0,Math.PI*2); ctx.stroke();
+ if(!o.im){ ctx.fillStyle='rgba(255,255,255,.78)'; ctx.font='700 28px system-ui,sans-serif'; ctx.fillText(p.ro,cx,cy); }
+ var num=(t.num!=null&&t.num!=='')?t.num:p.num;
+ ctx.beginPath(); ctx.arc(cx+R*0.74,cy+R*0.74,25,0,Math.PI*2); ctx.fillStyle='#ffd24d'; ctx.fill();
+ ctx.fillStyle='#3a2400'; ctx.font='900 26px system-ui,sans-serif'; ctx.fillText(String(num),cx+R*0.74,cy+R*0.76);
+ var label=t.name?t.name:p.ro;
+ ctx.fillStyle='#fff'; ctx.font='800 28px system-ui,sans-serif';
+ ctx.shadowColor='rgba(0,0,0,.6)'; ctx.shadowBlur=8; ctx.shadowOffsetY=2;
+ ctx.fillText(label.length>16?label.slice(0,16):label, cx, cy+R+30);
+ ctx.shadowColor='transparent';
+ });
+ ctx.fillStyle='rgba(255,255,255,.55)'; ctx.font='600 25px system-ui,sans-serif';
+ ctx.fillText('made on liveloop', W/2, H-38);
+ }
+ function shareLineup(){
+ shareView.style.display='flex'; shareImg.style.display='none'; shareLoad.style.display='block';
+ shareNative.style.display='none';
+ var W=1080,H=1440, cv=document.createElement('canvas'); cv.width=W; cv.height=H;
+ var ctx=cv.getContext('2d');
+ var jobs=FORMATION.map(function(p){ var t=team[p.k]||{};
+ return t.photo?loadImg(t.photo).then(function(im){return {p:p,im:im};}):Promise.resolve({p:p,im:null}); });
+ Promise.all(jobs).then(function(list){
+ paintLineup(ctx,W,H,list);
+ shareImg.src=cv.toDataURL('image/jpeg',0.9);
+ shareImg.style.display='block'; shareLoad.style.display='none';
+ blip(720,'triangle',0.1,0.2);
+ // opportunistic native share (often blocked in a sandboxed iframe — fall back silently)
+ try{
+ if(navigator.canShare){ cv.toBlob(function(b){
+ if(!b) return; var file=new File([b],'lineup.jpg',{type:'image/jpeg'});
+ try{ if(navigator.canShare({files:[file]})){
+ shareNative.style.display=''; shareNative.onclick=function(){ try{ navigator.share({files:[file],title:'My Starting XI'}); }catch(e){} };
+ } }catch(e){}
+ },'image/jpeg',0.9); }
+ }catch(e){}
+ });
+ }
+ shareBtn.addEventListener('pointerdown',function(e){ e.preventDefault(); shareLineup(); });
+ document.getElementById('shareClose').addEventListener('pointerdown',function(e){ e.stopPropagation(); shareView.style.display='none'; });
+
+ function confetti(){
+ var COLS=['#ffd24d','#ff8a1f','#9dffc8','#7C5CFF','#fff'];
+ var r=wrap.getBoundingClientRect();
+ for(var i=0;i<32;i++){ (function(i){
+ var p=document.createElement('span'); p.className='cf'; p.style.background=COLS[i%COLS.length];
+ p.style.left=(r.width/2)+'px'; p.style.top=(r.height*0.4)+'px'; wrap.appendChild(p);
+ var a=Math.random()*Math.PI*2, v=3+Math.random()*5, vx=Math.cos(a)*v, vy=Math.sin(a)*v-4, x=0,y=0,rot=0,life=0;
+ function step(){ life+=16; x+=vx; y+=vy; vy+=0.25; rot+=9;
+ p.style.transform='translate('+x+'px,'+y+'px) rotate('+rot+'deg)'; p.style.opacity=String(Math.max(0,1-life/1100));
+ if(life<1100) requestAnimationFrame(step); else p.remove(); }
+ requestAnimationFrame(step);
+ })(i); }
+ }
+
+ load();
+})();
+</script>

v1Current

@mae_arcade · 6/20/2026, 2:18:35 AM

Initial version — all lines are new.

+<style>
+ html,body{height:100%;margin:0;overflow:hidden;background:#0d3b2e;}
+ *{box-sizing:border-box;}
+ #wrap{position:relative;height:100%;width:100%;display:flex;flex-direction:column;font-family:system-ui,-apple-system,Segoe UI,Roboto,sans-serif;background:radial-gradient(120% 80% at 50% 0%,#15573f 0%,#0e4733 55%,#0a3527 100%);-webkit-tap-highlight-color:transparent;touch-action:manipulation;user-select:none;-webkit-user-select:none;color:#fff;}
+ #head{padding:.95rem 1.2rem .2rem;}
+ #head h1{margin:0;font-family:"Instrument Serif",Georgia,"Times New Roman",serif;font-weight:400;font-size:2rem;line-height:1;color:#fff;}
+ #tabs{display:inline-flex;margin-top:.5rem;background:rgba(0,0,0,.25);border:1px solid rgba(255,255,255,.14);border-radius:999px;padding:3px;}
+ .tab{border:0;background:transparent;color:rgba(255,255,255,.7);font-size:.78rem;font-weight:800;padding:.34rem .9rem;border-radius:999px;cursor:pointer;}
+ .tab.on{background:#fff;color:#0e4733;}
+ #hud{display:flex;gap:8px;padding:.45rem 1.2rem .2rem;flex-wrap:wrap;}
+ .pill{background:rgba(255,255,255,.12);border:1px solid rgba(255,255,255,.18);border-radius:999px;font-size:.72rem;font-weight:800;padding:.32rem .7rem;}
+ .mode{flex:1;min-height:0;display:flex;flex-direction:column;}
+ /* ---- collect ---- */
+ #albumWrap{flex:1;min-height:0;overflow-y:auto;padding:.6rem 1rem 1rem;-webkit-overflow-scrolling:touch;}
+ #album{display:grid;grid-template-columns:repeat(4,1fr);gap:8px;}
+ .slot{position:relative;aspect-ratio:3/4;border-radius:11px;background:rgba(0,0,0,.22);border:1px dashed rgba(255,255,255,.16);display:flex;flex-direction:column;align-items:center;justify-content:center;gap:2px;overflow:hidden;}
+ .slot.got{background:linear-gradient(160deg,#1d6b4d,#124e38);border:1px solid rgba(255,255,255,.22);box-shadow:0 4px 12px rgba(0,0,0,.25);}
+ .slot.foil.got{background:linear-gradient(160deg,#7a5e12,#a8841f 45%,#5e470c);border-color:#ffd86b;box-shadow:0 0 14px rgba(255,200,80,.4);}
+ .slot .fl{font-size:2rem;line-height:1;filter:grayscale(1) opacity(.18);}
+ .slot.got .fl{filter:none;}
+ .slot .cc{font-size:.58rem;font-weight:800;letter-spacing:.04em;color:rgba(255,255,255,.35);}
+ .slot.got .cc{color:#eafff2;}
+ .slot.foil.got::after{content:"";position:absolute;inset:0;background:linear-gradient(115deg,transparent 30%,rgba(255,255,255,.55) 48%,transparent 66%);background-size:250% 100%;animation:shine 2.6s linear infinite;pointer-events:none;}
+ @keyframes shine{0%{background-position:140% 0}100%{background-position:-40% 0}}
+ .slot .num{position:absolute;top:3px;left:5px;font-size:.5rem;font-weight:800;color:rgba(255,255,255,.3);}
+ .slot.got .num{color:rgba(255,255,255,.6);}
+ /* ---- team / pitch ---- */
+ #teamWrap{padding:.5rem 1rem 1rem;}
+ #pitch{position:relative;flex:1;min-height:0;border-radius:16px;overflow:hidden;border:2px solid rgba(255,255,255,.18);
+ background:repeating-linear-gradient(0deg,#1c7a4f 0 11%,#198047 11% 22%);}
+ #pitch::before{content:"";position:absolute;left:8%;right:8%;top:50%;height:2px;background:rgba(255,255,255,.3);}
+ #pitch .circle{position:absolute;left:50%;top:50%;width:26%;aspect-ratio:1;border:2px solid rgba(255,255,255,.3);border-radius:50%;transform:translate(-50%,-50%);}
+ #pitch .box{position:absolute;left:24%;right:24%;height:11%;border:2px solid rgba(255,255,255,.28);}
+ #pitch .box.top{top:0;border-top:0;}
+ #pitch .box.bot{bottom:0;border-bottom:0;}
+ .pos{position:absolute;transform:translate(-50%,-50%);display:flex;flex-direction:column;align-items:center;gap:3px;cursor:pointer;width:22%;}
+ .av{width:54px;height:54px;border-radius:50%;background:rgba(0,0,0,.35) center/cover no-repeat;border:2px solid rgba(255,255,255,.5);display:flex;align-items:center;justify-content:center;position:relative;box-shadow:0 3px 8px rgba(0,0,0,.35);}
+ .av .plus{font-size:1.5rem;font-weight:300;color:rgba(255,255,255,.8);line-height:1;}
+ .av .sh{position:absolute;bottom:-4px;right:-4px;min-width:18px;height:18px;padding:0 3px;border-radius:9px;background:#ffd24d;color:#3a2400;font-size:.6rem;font-weight:900;display:flex;align-items:center;justify-content:center;border:1px solid rgba(0,0,0,.15);}
+ .pos .nm{font-size:.6rem;font-weight:800;text-shadow:0 1px 3px rgba(0,0,0,.6);max-width:70px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;text-align:center;}
+ .pos .ro{font-size:.52rem;font-weight:700;color:rgba(255,255,255,.65);}
+ #foot{padding:.5rem 1.2rem max(1rem,env(safe-area-inset-bottom));display:flex;justify-content:center;align-items:center;min-height:3.2rem;}
+ #open{border:0;border-radius:999px;background:linear-gradient(135deg,#ffd24d,#ff8a1f);color:#3a2400;font-weight:900;font-size:1rem;padding:.9rem 1.8rem;cursor:pointer;box-shadow:0 10px 26px rgba(255,140,30,.4);}
+ #open:active{transform:scale(.96);}
+ #open:disabled{opacity:.5;}
+ #shareBtn{border:0;border-radius:999px;background:rgba(255,255,255,.14);border:1px solid rgba(255,255,255,.25);color:#fff;font-weight:800;font-size:.92rem;padding:.8rem 1.5rem;cursor:pointer;display:flex;align-items:center;gap:.4rem;}
+ #shareBtn:active{transform:scale(.96);}
+ /* ---- share preview ---- */
+ #shareView{position:absolute;inset:0;z-index:14;display:none;flex-direction:column;align-items:center;justify-content:center;background:rgba(4,18,13,.9);backdrop-filter:blur(8px);padding:1.1rem;}
+ #shareImg{max-width:100%;max-height:74%;border-radius:14px;box-shadow:0 16px 40px rgba(0,0,0,.5);display:none;}
+ #shareLoad{color:rgba(255,255,255,.7);font-size:.85rem;font-weight:700;}
+ #shareCap{color:rgba(255,255,255,.75);font-size:.78rem;font-weight:600;text-align:center;margin:.9rem 0 .2rem;max-width:18rem;line-height:1.35;}
+ #shareRow{display:flex;gap:.6rem;margin-top:.8rem;}
+ #shareRow button{border:0;border-radius:999px;font-weight:800;font-size:.88rem;padding:.7rem 1.4rem;cursor:pointer;}
+ #shareNative{background:#ffd24d;color:#3a2400;}
+ #shareClose{background:rgba(255,255,255,.15);color:#fff;}
+ /* ---- reveal / done ---- */
+ #reveal{position:absolute;inset:0;z-index:10;display:none;flex-direction:column;align-items:center;justify-content:center;background:rgba(6,28,21,.82);backdrop-filter:blur(6px);padding:1.2rem;text-align:center;}
+ #card{width:60%;max-width:210px;aspect-ratio:3/4;border-radius:18px;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:.4rem;position:relative;overflow:hidden;box-shadow:0 18px 50px rgba(0,0,0,.5);transform:scale(.6);opacity:0;transition:transform .35s cubic-bezier(.2,1.3,.5,1),opacity .25s;}
+ #card.in{transform:scale(1);opacity:1;}
+ #card .bigfl{font-size:5rem;line-height:1;}
+ #card .name{font-size:1.05rem;font-weight:800;}
+ #card.common{background:linear-gradient(160deg,#1d6b4d,#0f4733);border:2px solid rgba(255,255,255,.2);}
+ #card.foil{background:linear-gradient(160deg,#8a6a14,#c79a23 45%,#6b520e);border:2px solid #ffd86b;}
+ #card.foil::after{content:"";position:absolute;inset:0;background:linear-gradient(115deg,transparent 35%,rgba(255,255,255,.6) 50%,transparent 65%);background-size:250% 100%;animation:shine 2s linear infinite;}
+ #tag{margin-top:1rem;font-weight:900;font-size:1.05rem;min-height:1.3em;}
+ #tag.dupe{color:#ffcaa8;}
+ #tag.new{color:#9dffc8;}
+ #revHint{margin-top:.5rem;font-size:.72rem;color:rgba(255,255,255,.6);font-weight:600;}
+ #count{margin-top:.6rem;font-size:.7rem;color:rgba(255,255,255,.45);font-weight:700;}
+ #done{position:absolute;inset:0;z-index:11;display:none;flex-direction:column;align-items:center;justify-content:center;background:rgba(6,28,21,.85);backdrop-filter:blur(6px);text-align:center;padding:1.4rem;}
+ #done h2{font-family:"Instrument Serif",Georgia,serif;font-style:italic;font-size:2.2rem;margin:0;color:#ffe08a;}
+ #done p{color:#cfe;font-size:.85rem;margin:.5rem 0 1.2rem;}
+ #done button{border:0;border-radius:999px;background:#fff;color:#0e4733;font-weight:800;font-size:.9rem;padding:.7rem 1.4rem;cursor:pointer;}
+ .cf{position:absolute;width:8px;height:8px;border-radius:2px;pointer-events:none;z-index:12;}
+ /* ---- player editor sheet ---- */
+ #sheet{position:absolute;inset:0;z-index:13;display:none;align-items:flex-end;background:rgba(4,20,15,.55);backdrop-filter:blur(3px);}
+ #sheetIn{width:100%;background:#0e4733;border-top:1px solid rgba(255,255,255,.15);border-radius:18px 18px 0 0;padding:1rem 1.1rem max(1.1rem,env(safe-area-inset-bottom));box-shadow:0 -12px 30px rgba(0,0,0,.4);}
+ #sheetHd{display:flex;align-items:center;gap:.7rem;margin-bottom:.8rem;}
+ #sheetAv{width:64px;height:64px;border-radius:50%;background:rgba(0,0,0,.3) center/cover no-repeat;border:2px solid rgba(255,255,255,.4);display:flex;align-items:center;justify-content:center;font-size:1.6rem;color:rgba(255,255,255,.7);flex:0 0 auto;}
+ #sheetRole{font-size:.95rem;font-weight:800;}
+ #sheetRole small{display:block;font-weight:600;color:rgba(255,255,255,.6);font-size:.72rem;margin-top:2px;}
+ .field{display:flex;gap:.6rem;margin-bottom:.7rem;}
+ .field input{flex:1;background:rgba(255,255,255,.1);border:1px solid rgba(255,255,255,.2);color:#fff;border-radius:11px;padding:.6rem .75rem;font-size:.9rem;font-family:inherit;}
+ .field input#nmNum{flex:0 0 64px;text-align:center;}
+ .field input::placeholder{color:rgba(255,255,255,.45);}
+ .sBtn{border:0;border-radius:11px;font-weight:800;font-size:.85rem;padding:.7rem 1rem;cursor:pointer;}
+ #pickBtn{width:100%;background:rgba(255,255,255,.14);color:#fff;margin-bottom:.7rem;}
+ #sheetRow{display:flex;gap:.6rem;}
+ #rm{flex:0 0 auto;background:rgba(255,120,120,.18);color:#ffd4d4;}
+ #sheetDone{flex:1;background:#ffd24d;color:#3a2400;}
+</style>
+<div id="wrap">
+ <div id="head">
+ <h1>Sticker Album</h1>
+ <div id="tabs">
+ <button class="tab on" id="tabCollect">Collect</button>
+ <button class="tab" id="tabTeam">My XI</button>
+ </div>
+ </div>
+ <div id="hud">
+ <span class="pill" id="pctPill">0/32</span>
+ <span class="pill" id="repPill">0 dupes</span>
+ <span class="pill" id="packPill">0 packs</span>
+ <span class="pill" id="teamPill" style="display:none">0/11 picked</span>
+ </div>
+
+ <div id="collectWrap" class="mode"><div id="albumWrap"><div id="album"></div></div></div>
+ <div id="teamWrap" class="mode" style="display:none"><div id="pitch"></div></div>
+
+ <div id="foot">
+ <button id="open">Open a pack &#9917;</button>
+ <button id="shareBtn" style="display:none">&#128247; Share lineup</button>
+ </div>
+
+ <div id="reveal">
+ <div id="card"></div>
+ <div id="tag"></div>
+ <div id="revHint">tap to keep going</div>
+ <div id="count"></div>
+ </div>
+ <div id="done">
+ <h2>Album complete!</h2>
+ <p>All 32 stickers collected. Legend.</p>
+ <button id="restart">start a new album</button>
+ </div>
+
+ <div id="sheet">
+ <div id="sheetIn">
+ <div id="sheetHd">
+ <div id="sheetAv">+</div>
+ <div id="sheetRole">Player<small id="sheetSub"></small></div>
+ </div>
+ <input id="pick" type="file" accept="image/*" hidden>
+ <button class="sBtn" id="pickBtn">Choose a photo</button>
+ <div class="field">
+ <input id="nm" placeholder="Name" maxlength="18">
+ <input id="nmNum" type="number" inputmode="numeric" placeholder="#" min="0" max="99">
+ </div>
+ <div id="sheetRow">
+ <button class="sBtn" id="rm">Remove</button>
+ <button class="sBtn" id="sheetDone">Done</button>
+ </div>
+ </div>
+ </div>
+
+ <div id="shareView">
+ <div id="shareLoad">Rendering your lineup…</div>
+ <img id="shareImg" alt="My starting XI">
+ <p id="shareCap">Press &amp; hold the image to save it, then share anywhere &#128247;</p>
+ <div id="shareRow">
+ <button id="shareNative" style="display:none">Share…</button>
+ <button id="shareClose">Done</button>
+ </div>
+ </div>
+</div>
+<script>
+(function(){
+ var LL=window.liveloop||null;
+ var muted = LL ? LL.muted : true;
+ if(LL && LL.onMute){ try{ LL.onMute(function(m){ muted=m; }); }catch(e){} }
+ if(LL && LL.declareMedia){ try{ LL.declareMedia({sound:true}); }catch(e){} }
+ var _ac=null;
+ function actx(){ if(!_ac){ try{ _ac=new (window.AudioContext||window.webkitAudioContext)(); }catch(e){ _ac=null; } } return _ac; }
+ function blip(f,type,vol,dur){
+ if(muted) return; var c=actx(); if(!c) return;
+ var t=c.currentTime, o=c.createOscillator(), g=c.createGain();
+ o.type=type||'triangle'; o.frequency.setValueAtTime(f,t);
+ g.gain.setValueAtTime(0.0001,t); g.gain.exponentialRampToValueAtTime(vol||0.12,t+0.01);
+ g.gain.exponentialRampToValueAtTime(0.0001,t+(dur||0.18));
+ o.connect(g); g.connect(c.destination); o.start(t); o.stop(t+(dur||0.18)+0.04);
+ }
+ function rip(){
+ if(muted) return; var c=actx(); if(!c) return;
+ var t=c.currentTime, n=Math.floor(c.sampleRate*0.18), b=c.createBuffer(1,n,c.sampleRate), d=b.getChannelData(0);
+ for(var i=0;i<n;i++){ d[i]=(Math.random()*2-1)*Math.pow(1-i/n,1.2); }
+ var s=c.createBufferSource(); s.buffer=b; var f=c.createBiquadFilter(); f.type='highpass'; f.frequency.value=1800;
+ var g=c.createGain(); g.gain.value=0.12; s.connect(f); f.connect(g); g.connect(c.destination); s.start(t);
+ }
+ function sparkle(){ blip(880,'sine',0.09,0.3); setTimeout(function(){blip(1318.5,'sine',0.08,0.4);},90); setTimeout(function(){blip(1760,'sine',0.07,0.5);},190); }
+ function fanfare(){ var n=[523.25,659.25,783.99,1046.5,1318.5]; for(var i=0;i<n.length;i++){ (function(i){ setTimeout(function(){ blip(n[i],'triangle',0.13,0.5); },i*100); })(i); } }
+
+ var STICKERS=[
+ {f:'🇧🇷',c:'BRA',L:1},{f:'🇦🇷',c:'ARG',L:1},{f:'🇫🇷',c:'FRA',L:1},{f:'🇩🇪',c:'GER',L:1},
+ {f:'🇪🇸',c:'ESP',L:1},{f:'🇵🇹',c:'POR',L:1},{f:'🇮🇹',c:'ITA',L:1},{f:'🇳🇱',c:'NED',L:1},
+ {f:'🇬🇧',c:'ENG',L:0},{f:'🇧🇪',c:'BEL',L:0},{f:'🇭🇷',c:'CRO',L:0},{f:'🇺🇾',c:'URU',L:0},
+ {f:'🇲🇽',c:'MEX',L:0},{f:'🇺🇸',c:'USA',L:0},{f:'🇯🇵',c:'JPN',L:0},{f:'🇰🇷',c:'KOR',L:0},
+ {f:'🇲🇦',c:'MAR',L:0},{f:'🇸🇳',c:'SEN',L:0},{f:'🇬🇭',c:'GHA',L:0},{f:'🇨🇲',c:'CMR',L:0},
+ {f:'🇨🇴',c:'COL',L:0},{f:'🇨🇱',c:'CHI',L:0},{f:'🇪🇨',c:'ECU',L:0},{f:'🇵🇾',c:'PAR',L:0},
+ {f:'🇨🇭',c:'SUI',L:0},{f:'🇩🇰',c:'DEN',L:0},{f:'🇵🇱',c:'POL',L:0},{f:'🇷🇸',c:'SRB',L:0},
+ {f:'🇦🇺',c:'AUS',L:0},{f:'🇨🇦',c:'CAN',L:0},{f:'🇳🇬',c:'NGA',L:0},{f:'🇶🇦',c:'QAT',L:0}
+ ];
+ var N=STICKERS.length;
+ // The cup ends 19 Jul 2026. After that the album stays viewable with what
+ // you've collected, but no more packs open. Building your XI is never gated.
+ var DEADLINE=Date.UTC(2026,6,20,0,0,0); // 00:00 UTC 20 Jul = end of the 19th
+ function expired(){ try{ return Date.now()>=DEADLINE; }catch(e){ return false; } }
+ var commons=[], legends=[];
+ for(var i=0;i<N;i++){ (STICKERS[i].L?legends:commons).push(i); }
+
+ // 4-3-3 on a vertical pitch (attack at top, keeper at bottom)
+ var FORMATION=[
+ {k:'st', ro:'ST', num:9, x:50,y:13},
+ {k:'lw', ro:'LW', num:11,x:19,y:22},
+ {k:'rw', ro:'RW', num:7, x:81,y:22},
+ {k:'cm1',ro:'CM', num:8, x:27,y:43},
+ {k:'am', ro:'CAM',num:10,x:50,y:38},
+ {k:'cm2',ro:'CM', num:6, x:73,y:43},
+ {k:'lb', ro:'LB', num:3, x:15,y:65},
+ {k:'cb1',ro:'CB', num:4, x:38,y:68},
+ {k:'cb2',ro:'CB', num:2, x:62,y:68},
+ {k:'rb', ro:'RB', num:5, x:85,y:65},
+ {k:'gk', ro:'GK', num:1, x:50,y:87}
+ ];
+
+ var owned={}, repeats=0, packs=0, team={}, albumDone=false;
+ function load(){
+ try{ if(LL && LL.storage && LL.storage.get){ LL.storage.get().then(function(s){
+ if(s){ owned=s.owned||{}; repeats=s.repeats||0; packs=s.packs||0; team=s.team||{}; } renderAll();
+ }).catch(renderAll); } else renderAll(); }catch(e){ renderAll(); }
+ }
+ function save(){ try{ if(LL && LL.storage && LL.storage.set) LL.storage.set({owned:owned,repeats:repeats,packs:packs,team:team}); }catch(e){} }
+
+ var albumEl=document.getElementById('album'), pitchEl=document.getElementById('pitch');
+ var pctPill=document.getElementById('pctPill'), repPill=document.getElementById('repPill'), packPill=document.getElementById('packPill'), teamPill=document.getElementById('teamPill');
+ var openBtn=document.getElementById('open'), shareBtn=document.getElementById('shareBtn');
+ var shareView=document.getElementById('shareView'), shareImg=document.getElementById('shareImg'),
+ shareLoad=document.getElementById('shareLoad'), shareNative=document.getElementById('shareNative');
+ var revealEl=document.getElementById('reveal'), cardEl=document.getElementById('card'), tagEl=document.getElementById('tag'), countEl=document.getElementById('count');
+ var doneEl=document.getElementById('done');
+ var wrap=document.getElementById('wrap');
+ var collectWrap=document.getElementById('collectWrap'), teamWrap=document.getElementById('teamWrap');
+ var tabCollect=document.getElementById('tabCollect'), tabTeam=document.getElementById('tabTeam');
+
+ /* ============ collect mode ============ */
+ function buildAlbum(){
+ albumEl.innerHTML='';
+ for(var i=0;i<N;i++){ (function(i){
+ var s=STICKERS[i];
+ var d=document.createElement('div'); d.className='slot'+(s.L?' foil':'')+(owned[i]?' got':'');
+ d.innerHTML='<span class="num">'+(i+1)+'</span><span class="fl">'+s.f+'</span><span class="cc">'+s.c+'</span>';
+ d.id='slot'+i; albumEl.appendChild(d);
+ })(i); }
+ }
+ function ownedCount(){ var n=0; for(var k in owned) if(owned[k]) n++; return n; }
+ function renderHud(){
+ var n=ownedCount();
+ pctPill.textContent=n+'/'+N;
+ repPill.textContent=repeats+' dupe'+(repeats===1?'':'s');
+ packPill.textContent=packs+' pack'+(packs===1?'':'s');
+ teamPill.textContent=teamCount()+'/11 picked';
+ }
+ function refreshOpen(){
+ if(expired()){ openBtn.disabled=true; openBtn.textContent='Tournament over ⚽'; }
+ }
+
+ function pickOne(){
+ var pool = (Math.random()<0.16 && legends.length) ? legends : commons;
+ return pool[Math.floor(Math.random()*pool.length)];
+ }
+ var queue=[], showing=false;
+ function openPack(){
+ if(showing || expired()) return;
+ packs++; rip();
+ queue=[]; for(var k=0;k<5;k++) queue.push(pickOne());
+ showNext(); save();
+ }
+ function showNext(){
+ if(queue.length===0){ showing=false; revealEl.style.display='none';
+ if(ownedCount()>=N && !albumDone){ albumDone=true; doneEl.style.display='flex'; fanfare(); confetti(); }
+ return;
+ }
+ showing=true; revealEl.style.display='flex';
+ var idx=queue.shift(), s=STICKERS[idx], isNew=!owned[idx];
+ cardEl.className=s.L?'foil':'common';
+ cardEl.innerHTML='<span class="bigfl">'+s.f+'</span><span class="name">'+s.c+'</span>';
+ cardEl.classList.remove('in'); void cardEl.offsetWidth; cardEl.classList.add('in');
+ if(s.L) sparkle(); else blip(660,'triangle',0.1,0.18);
+ if(isNew){ owned[idx]=1; tagEl.textContent=s.L?'★ LEGEND! got it':'Got it!'; tagEl.className='new';
+ var slot=document.getElementById('slot'+idx); if(slot){ slot.className='slot'+(s.L?' foil':'')+' got'; }
+ } else { repeats++; tagEl.textContent='Repetida…'; tagEl.className='dupe'; }
+ countEl.textContent=queue.length+' left in the pack';
+ renderHud(); save();
+ }
+
+ /* ============ team mode ============ */
+ function teamCount(){ var n=0; for(var k in team){ if(team[k] && (team[k].photo||team[k].name)) n++; } return n; }
+ function buildPitch(){
+ pitchEl.innerHTML='<div class="box top"></div><div class="box bot"></div><div class="circle"></div>';
+ for(var i=0;i<FORMATION.length;i++){ (function(p){
+ var el=document.createElement('div'); el.className='pos'; el.id='pos_'+p.k;
+ el.style.left=p.x+'%'; el.style.top=p.y+'%';
+ el.addEventListener('pointerdown',function(e){ e.stopPropagation(); openSheet(p); });
+ pitchEl.appendChild(el); renderPos(p);
+ })(FORMATION[i]); }
+ }
+ function renderPos(p){
+ var el=document.getElementById('pos_'+p.k); if(!el) return;
+ var t=team[p.k]||{}; var num=(t.num!=null&&t.num!=='')?t.num:p.num;
+ var avStyle=t.photo?('background-image:url('+t.photo+')'):'';
+ el.innerHTML=
+ '<div class="av" style="'+avStyle+'">'+(t.photo?'':'<span class="plus">+</span>')+'<span class="sh">'+num+'</span></div>'+
+ '<div class="nm">'+(t.name?esc(t.name):p.ro)+'</div>'+
+ (t.name?'<div class="ro">'+p.ro+'</div>':'');
+ }
+ function esc(s){ return String(s).replace(/[&<>"]/g,function(c){return {'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;'}[c];}); }
+
+ // ---- player editor sheet ----
+ var sheet=document.getElementById('sheet'), sheetAv=document.getElementById('sheetAv'),
+ sheetRole=document.getElementById('sheetRole'), sheetSub=document.getElementById('sheetSub'),
+ pick=document.getElementById('pick'), nm=document.getElementById('nm'), nmNum=document.getElementById('nmNum');
+ var editKey=null, editPos=null;
+ function openSheet(p){
+ editKey=p.k; editPos=p; var t=team[p.k]||{};
+ sheetRole.childNodes[0].nodeValue=p.ro; sheetSub.textContent='photo · name · number';
+ nm.value=t.name||''; nmNum.value=(t.num!=null&&t.num!=='')?t.num:p.num;
+ if(t.photo){ sheetAv.style.backgroundImage='url('+t.photo+')'; sheetAv.textContent=''; }
+ else { sheetAv.style.backgroundImage=''; sheetAv.textContent='+'; }
+ sheet.style.display='flex'; blip(560,'sine',0.06,0.12);
+ }
+ function closeSheet(){ sheet.style.display='none'; editKey=null; editPos=null; }
+ function ensure(){ if(!team[editKey]) team[editKey]={}; return team[editKey]; }
+
+ document.getElementById('pickBtn').addEventListener('pointerdown',function(e){ e.preventDefault(); pick.click(); });
+ pick.addEventListener('change',function(){
+ var f=pick.files&&pick.files[0]; if(!f) return;
+ var rd=new FileReader();
+ rd.onload=function(){
+ var im=new Image();
+ im.onload=function(){
+ var S=96, cv=document.createElement('canvas'); cv.width=S; cv.height=S;
+ var ctx=cv.getContext('2d');
+ var sc=Math.max(S/im.width,S/im.height), sw=S/sc, sh=S/sc;
+ ctx.drawImage(im,(im.width-sw)/2,(im.height-sh)/2,sw,sh,0,0,S,S);
+ // 11 stickers share a ~64KB liveloop.storage budget, so cap each photo
+ // to ~4.8KB (step quality down for busy images) — else a full XI silently
+ // overflows and never persists.
+ var q=0.55, data=cv.toDataURL('image/jpeg',q);
+ while(data.length>4800 && q>0.3){ q-=0.1; data=cv.toDataURL('image/jpeg',q); }
+ ensure().photo=data;
+ sheetAv.style.backgroundImage='url('+data+')'; sheetAv.textContent='';
+ save();
+ };
+ im.src=rd.result;
+ };
+ rd.readAsDataURL(f);
+ pick.value='';
+ });
+ nm.addEventListener('input',function(){ ensure().name=nm.value; });
+ nmNum.addEventListener('input',function(){ var v=nmNum.value; ensure().num=(v===''?'':Math.max(0,Math.min(99,parseInt(v,10)||0))); });
+ document.getElementById('rm').addEventListener('pointerdown',function(e){
+ e.stopPropagation(); delete team[editKey]; if(editPos) renderPos(editPos); renderHud(); save(); closeSheet();
+ });
+ document.getElementById('sheetDone').addEventListener('pointerdown',function(e){
+ e.stopPropagation();
+ var t=team[editKey];
+ if(t && !t.photo && !(t.name&&t.name.trim())){ delete team[editKey]; } // nothing entered → leave empty
+ if(editPos) renderPos(editPos); renderHud(); save();
+ blip(720,'triangle',0.1,0.18); closeSheet();
+ });
+ sheet.addEventListener('pointerdown',function(e){ if(e.target===sheet){ document.getElementById('sheetDone').dispatchEvent(new Event('pointerdown')); } });
+
+ /* ============ shared ============ */
+ function renderAll(){ albumDone=(ownedCount()>=N); buildAlbum(); buildPitch(); renderHud(); refreshOpen(); }
+
+ var mode='collect';
+ function setMode(m){
+ mode=m;
+ var collect=(m==='collect');
+ tabCollect.classList.toggle('on',collect); tabTeam.classList.toggle('on',!collect);
+ collectWrap.style.display=collect?'flex':'none';
+ teamWrap.style.display=collect?'none':'flex';
+ pctPill.style.display=collect?'':'none'; repPill.style.display=collect?'':'none'; packPill.style.display=collect?'':'none';
+ teamPill.style.display=collect?'none':'';
+ openBtn.style.display=collect?'':'none'; shareBtn.style.display=collect?'none':'';
+ blip(collect?520:660,'sine',0.05,0.1);
+ }
+ tabCollect.addEventListener('pointerdown',function(){ setMode('collect'); });
+ tabTeam.addEventListener('pointerdown',function(){ setMode('team'); });
+
+ revealEl.addEventListener('pointerdown',function(){ if(showing) showNext(); });
+ openBtn.addEventListener('pointerdown',function(e){ e.preventDefault(); openPack(); });
+ document.getElementById('restart').addEventListener('pointerdown',function(e){
+ e.stopPropagation(); owned={}; repeats=0; packs=0; doneEl.style.display='none'; save(); renderAll();
+ });
+
+ /* ---- share lineup as an image ---- */
+ function loadImg(src){ return new Promise(function(res){ var im=new Image(); im.onload=function(){res(im);}; im.onerror=function(){res(null);}; im.src=src; }); }
+ function roundRect(ctx,x,y,w,h,r){ ctx.beginPath(); ctx.moveTo(x+r,y); ctx.arcTo(x+w,y,x+w,y+h,r); ctx.arcTo(x+w,y+h,x,y+h,r); ctx.arcTo(x,y+h,x,y,r); ctx.arcTo(x,y,x+w,y,r); ctx.closePath(); }
+ function paintLineup(ctx,W,H,list){
+ ctx.fillStyle='#0e4733'; ctx.fillRect(0,0,W,H);
+ ctx.textAlign='center'; ctx.textBaseline='middle';
+ ctx.fillStyle='#fff'; ctx.font='italic 700 62px Georgia, "Times New Roman", serif';
+ ctx.fillText('My Starting XI', W/2, 78);
+ var px=40,py=148,pw=W-80,ph=H-228;
+ ctx.save(); roundRect(ctx,px,py,pw,ph,28); ctx.clip();
+ var bands=7; for(var i=0;i<bands;i++){ ctx.fillStyle=(i%2)?'#198047':'#1c7a4f'; ctx.fillRect(px,py+ph*i/bands,pw,ph/bands+1); }
+ ctx.strokeStyle='rgba(255,255,255,.32)'; ctx.lineWidth=4;
+ ctx.beginPath(); ctx.moveTo(px,py+ph/2); ctx.lineTo(px+pw,py+ph/2); ctx.stroke();
+ ctx.beginPath(); ctx.arc(px+pw/2,py+ph/2,pw*0.13,0,Math.PI*2); ctx.stroke();
+ var bw=pw*0.52,bh=ph*0.11,bx=px+(pw-bw)/2;
+ ctx.strokeRect(bx,py,bw,bh); ctx.strokeRect(bx,py+ph-bh,bw,bh);
+ ctx.restore();
+ ctx.strokeStyle='rgba(255,255,255,.4)'; ctx.lineWidth=5; roundRect(ctx,px,py,pw,ph,28); ctx.stroke();
+ list.forEach(function(o){
+ var p=o.p, t=team[p.k]||{}, cx=px+p.x/100*pw, cy=py+p.y/100*ph, R=62;
+ ctx.save(); ctx.beginPath(); ctx.arc(cx,cy,R,0,Math.PI*2); ctx.closePath();
+ if(o.im){ ctx.clip(); var s=Math.max(2*R/o.im.width,2*R/o.im.height), sw=2*R/s, sh=2*R/s;
+ ctx.drawImage(o.im,(o.im.width-sw)/2,(o.im.height-sh)/2,sw,sh,cx-R,cy-R,2*R,2*R); }
+ else { ctx.fillStyle='rgba(0,0,0,.4)'; ctx.fill(); }
+ ctx.restore();
+ ctx.strokeStyle='rgba(255,255,255,.85)'; ctx.lineWidth=5; ctx.beginPath(); ctx.arc(cx,cy,R,0,Math.PI*2); ctx.stroke();
+ if(!o.im){ ctx.fillStyle='rgba(255,255,255,.78)'; ctx.font='700 28px system-ui,sans-serif'; ctx.fillText(p.ro,cx,cy); }
+ var num=(t.num!=null&&t.num!=='')?t.num:p.num;
+ ctx.beginPath(); ctx.arc(cx+R*0.74,cy+R*0.74,25,0,Math.PI*2); ctx.fillStyle='#ffd24d'; ctx.fill();
+ ctx.fillStyle='#3a2400'; ctx.font='900 26px system-ui,sans-serif'; ctx.fillText(String(num),cx+R*0.74,cy+R*0.76);
+ var label=t.name?t.name:p.ro;
+ ctx.fillStyle='#fff'; ctx.font='800 28px system-ui,sans-serif';
+ ctx.shadowColor='rgba(0,0,0,.6)'; ctx.shadowBlur=8; ctx.shadowOffsetY=2;
+ ctx.fillText(label.length>16?label.slice(0,16):label, cx, cy+R+30);
+ ctx.shadowColor='transparent';
+ });
+ ctx.fillStyle='rgba(255,255,255,.55)'; ctx.font='600 25px system-ui,sans-serif';
+ ctx.fillText('made on liveloop', W/2, H-38);
+ }
+ function shareLineup(){
+ shareView.style.display='flex'; shareImg.style.display='none'; shareLoad.style.display='block';
+ shareNative.style.display='none';
+ var W=1080,H=1440, cv=document.createElement('canvas'); cv.width=W; cv.height=H;
+ var ctx=cv.getContext('2d');
+ var jobs=FORMATION.map(function(p){ var t=team[p.k]||{};
+ return t.photo?loadImg(t.photo).then(function(im){return {p:p,im:im};}):Promise.resolve({p:p,im:null}); });
+ Promise.all(jobs).then(function(list){
+ paintLineup(ctx,W,H,list);
+ shareImg.src=cv.toDataURL('image/jpeg',0.9);
+ shareImg.style.display='block'; shareLoad.style.display='none';
+ blip(720,'triangle',0.1,0.2);
+ // opportunistic native share (often blocked in a sandboxed iframe — fall back silently)
+ try{
+ if(navigator.canShare){ cv.toBlob(function(b){
+ if(!b) return; var file=new File([b],'lineup.jpg',{type:'image/jpeg'});
+ try{ if(navigator.canShare({files:[file]})){
+ shareNative.style.display=''; shareNative.onclick=function(){ try{ navigator.share({files:[file],title:'My Starting XI'}); }catch(e){} };
+ } }catch(e){}
+ },'image/jpeg',0.9); }
+ }catch(e){}
+ });
+ }
+ shareBtn.addEventListener('pointerdown',function(e){ e.preventDefault(); shareLineup(); });
+ document.getElementById('shareClose').addEventListener('pointerdown',function(e){ e.stopPropagation(); shareView.style.display='none'; });
+
+ function confetti(){
+ var COLS=['#ffd24d','#ff8a1f','#9dffc8','#7C5CFF','#fff'];
+ var r=wrap.getBoundingClientRect();
+ for(var i=0;i<32;i++){ (function(i){
+ var p=document.createElement('span'); p.className='cf'; p.style.background=COLS[i%COLS.length];
+ p.style.left=(r.width/2)+'px'; p.style.top=(r.height*0.4)+'px'; wrap.appendChild(p);
+ var a=Math.random()*Math.PI*2, v=3+Math.random()*5, vx=Math.cos(a)*v, vy=Math.sin(a)*v-4, x=0,y=0,rot=0,life=0;
+ function step(){ life+=16; x+=vx; y+=vy; vy+=0.25; rot+=9;
+ p.style.transform='translate('+x+'px,'+y+'px) rotate('+rot+'deg)'; p.style.opacity=String(Math.max(0,1-life/1100));
+ if(life<1100) requestAnimationFrame(step); else p.remove(); }
+ requestAnimationFrame(step);
+ })(i); }
+ }
+
+ load();
+})();
+</script>
← Version history