<!-- SOLID CITY · part 2035 -->
0){toast(s.name+' · shield already active');return}claim(s,['defense']);s.shield=Math.min(100,s.shield+24);s.shieldWindow=1.6;s.task='Shield active · 1.6s';log('handoff',s.name+' momentary shield engaged',s.id);toast(s.name+' · shield absorbing damage')}if(b.dataset.action==='release')release(s)}});
  document.addEventListener('pointerup',function(e){var b=e.target.closest&&e.target.closest('[data-action="fire"]');if(b){var s=ships.find(function(x){return x.id===selected[b.dataset.team]});if(s)pendingReleases.push({shipId:s.id,remaining:.22})}});
  document.getElementById('pauseTrigger').addEventListener('click',function(){if(!running)return;running=false;paused=true;pausedAt=performance.now();document.getElementById('pauseOverlay').classList.add('open');document.getElementById('resumeBattle').focus()});
  document.getElementById('resumeBattle').addEventListener('click',function(){if(!paused)return;totalPaused+=performance.now()-pausedAt;pausedAt=0;paused=false;running=true;last=performance.now();document.getElementById('pauseOverlay').classList.remove('open');document.getElementById('pauseTrigger').focus()});
  document.getElementById('launch').addEventListener('click',function(){var mode=document.getElementById('mode').value;document.getElementById('startOverlay').classList.add('closed');reset(true);if(mode==='auto'){log('handoff','AI + AI command configuration engaged');toast('AI + AI · tap any fighter to intervene')}else log('handoff','Human + AI configuration engaged · Gold available')});
  function toast(t){var el=document.getElementById('toast');el.textContent=t;el.classList.add('show');clearTimeout(toast.t);toast.t=setTimeout(function(){el.classList.remove('show')},1500)}
  function updateUI(){for(var t of ['gold','teal']){var ready=teamShips(t).filter(function(s){return s.disabled<=0}).length;var activeShip=ships.find(function(x){return x.id===selected[t]});document.querySelector('[data-team="'+t+'"][data-action="shield"]').classList.toggle('active',!!(activeShip&&activeShip.shieldWindow>0));document.getElementById(t+'Health').textContent=ready+' ships combat-ready';document.getElementById(t+'Meter').style.width=progress[t]+'%';document.getElementById(t+'Progress').textContent=Math.floor(progress[t])+'%';var s=ships.find(function(x){return x.id===selected[t]}),el=document.getElementById(t+'Selected');el.innerHTML=s?'<strong>'+s.name+'</strong> · '+ownerLabel(s)+' · '+s.task:'<strong>Tap a '+(t==='gold'?'Gold':'Teal')+' fighter</strong> to '+(t==='gold'?'take its helm':'intervene')}}
  function updateStats(){document.getElementById('goldScore').textContent=Math.floor(progress.gold)+'%';document.getElementById('tealScore').textContent=Math.floor(progress.teal)+'%';document.getElementById('shipStats').innerHTML=ships.map(function(s){var own=ownerLabel(s),cls=own.indexOf('HUMAN')===0?'human':'ai';return '<div class="shiprow"><strong style="color:'+shipColor(s.team)+'">'+s.name+'</strong><span class="owner '+cls+'">'+own+'</span><div><div class="hullbar"><i style="width:'+Math.round(s.hull)+'%;background:'+(s.hull<30?'var(--danger)':'var(--ok)')+'"></i></div><small>Hull '+Math.round(s.hull)+'% · '+s.formation+' · slot '+(s.slot+1)+'</small></div><small class="task">'+s.task+'<br>epoch '+Math.max.apply(null,Object.values(s.epochs))+'</small></div>'}).join('');var ev=document.getElementById('events');ev.innerHTML=events.length?events.slice(0,30).map(function(e){return '<div class="event"><time>'+e.time+'</time><span>'+e.text+'</span><em>'+e.ship+'</em></div>'}).join(''):'<div class="empty">No events recorded yet.</div>'}
  document.getElementById('statsOpen').onclick=function(){updateStats();document.getElementById('drawer').classList.add('open')};document.getElementById('statsClose').onclick=function(){document.getElementById('drawer').classList.remove('open')};document.getElementById('drawer').addEventListener('click',function(e){if(e.target===this)this.classList.remove('open')});document.getElementById('again').onclick=reset;
  window.addEventListener('resize',resizeAll);if(window.ResizeObserver){new ResizeObserver(resizeAll).observe(document.querySelector('.battlefield'))}
  function loop(now){var dt=Math.min(.033,(now-last)/1000);last=now;update(dt);for(var t of ['gold','teal']){draw(contexts[t],t,canvases[t]._w||1,canvases[t]._h||1)}updateUI();requestAnimationFrame(loop)}
  reset(false);requestAnimationFrame(loop);setInterval(updateStats,500);document.getElementById('launch').focus();
})();
</script>
</body>
</html>

===== FILE: public/city/fonts/OFL-RobotoCondensed.txt =====
Copyright 2011 The Roboto Project Authors (https://github.com/googlefonts/roboto-classic)

This Font Software is licensed under the SIL Open Font License, Version 1.1.
This license is copied below, and is also available with a FAQ at:
http://scripts.sil.org/OFL


-----------------------------------------------------------
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
---------------------