<!-- SOLID CITY · part 2919 -->
updateStats(){const d=derived();$('#statRescued').textContent=d.rescued;$('#statLost').textContent=d.lost;$('#statHuman').textContent=d.human;$('#statAI').textContent=d.ai;$('#statIntercept').textContent=d.intercepts;$('#statHandoffs').textContent=d.handoffs;$('#statRejected').textContent=d.rejected;$('#statRepairs').textContent=d.repairs;$('#statEvents').textContent=d.events;$('#statLatency').textContent=d.latency===null?'—':d.latency.toFixed(2)}
  function renderLog(){
    const labels={handoff:'Handoff',rejected:'Rejected',interception:'Defense',extraction:'Extracted',repair:'Repair',rescue:'Rescued',lost:'Lost',mission:'Mission'};
    const relevant=events.filter(e=>labels[e.type]).slice(-30).reverse();$('#eventLog').innerHTML=relevant.length?relevant.map(e=>{
      const d=e.data;let txt='';if(e.type==='handoff')txt=pretty(d.task)+': '+d.from+' → '+d.to+' · epoch '+d.epoch+' · '+d.latency.toFixed(2)+' ms';if(e.type==='rejected')txt=pretty(d.task)+' '+d.reason;if(e.type==='interception')txt='Interceptor stopped by '+d.owner;if(e.type==='extraction')txt=d.pod+' recovered by '+d.owner;if(e.type==='repair')txt='Vessel systems restored by '+d.owner;if(e.type==='rescue')txt=d.pod+' delivered to gate';if(e.type==='lost')txt=d.pod+' life signal ended';if(e.type==='mission')txt=d.rescued+' rescued · '+d.lost+' lost';const cls=e.type==='rejected'?'interference':(e.type==='rescue'?'rescue':'');return '<div class="event '+cls+'"><time>T+'+e.t.toFixed(1)+'s</time><div><b>'+labels[e.type]+'</b>'+txt+'</div></div>'}).join(''):'<div class="event"><time>Ready</time><div>Coordination events will appear when the mission begins.</div></div>';updateStats();
  }

  function loop(ts){const dt=Math.min(.033,(ts-last)/1000||0);last=ts;update(dt);draw();requestAnimationFrame(loop)}
  function launch(){resetState();running=true;last=performance.now();$('#startScreen').classList.add('hidden');$('#result').classList.remove('show');recordEvent('missionStart',{});setAdvice('Launching now. AI pilot has the first pod plotted.');}
  $('#launchBtn').addEventListener('click',launch);$('#againBtn').addEventListener('click',launch);

  const keyMap={ArrowUp:'up',ArrowDown:'down',ArrowLeft:'left',ArrowRight:'right',w:'w',a:'a',s:'s',d:'d',' ':'boost'};
  window.addEventListener('keydown',e=>{if(keyMap[e.key]&&coordination.owner('navigation')==='human'){state.keys[keyMap[e.key]]=true;e.preventDefault()}if((e.key==='f'||e.key==='F')&&coordination.owner('protection')==='human'){e.preventDefault();humanFire()}});
  window.addEventListener('keyup',e=>{if(keyMap[e.key])state.keys[keyMap[e.key]]=false});
  $$('[data-move]').forEach(b=>{const k=b.dataset.move;const on=e=>{e.preventDefault();state.keys[k]=true;b.classList.add('pressed')},off=e=>{e.preventDefault();state.keys[k]=false;b.classList.remove('pressed')};b.addEventListener('pointerdown',on);b.addEventListener('pointerup',off);b.addEventListener('pointercancel',off);b.addEventListener('pointerleave',off)});
  function heldButton(el,key){const on=e=>{e.preventDefault();state[key]=true;el.classList.add('pressed')},off=e=>{e.preventDefault();state[key]=false;el.classList.remove('pressed')};el.addEventListener('pointerdown',on);el.addEventListener('pointerup',off);el.addEventListener('pointercancel',off);el.addEventListener('pointerleave',off)}
  heldButton($('#stabilizeBtn'),'stabilizeHeld');heldButton($('#tractorBtn'),'extractHeld');
  function humanFire(){humanAction('protection','fire',()=>{const e=nearestEnemy();if(e)fireAt(e,'human');else showToast('No interceptor in range.')})}
  $('#fireBtn').addEventListener('click',humanFire);$('#pulseBtn').addEventListener('click',()=>humanAction('protection','pulse',()=>{state.ship.pulse=1.4;state.ship.shield=Math.min(100,state.ship.shield+22);recordEvent('shield',{owner:'human'})}));
  $('#repairBtn').addEventListener('click',()=>humanAction('support','repair',()=>repair('human')));$('#lifeBtn').addEventListener('click',()=>humanAction('support','life-support',()=>{if(state.ship.cargo){state.ship.cargo.hp=Math.min(100,state.ship.cargo.hp+16);recordEvent('lifeSupport',{owner:'human'})}else showToast('No pod aboard.')}));

  resetState();draw();requestAnimationFrame(loop);
})();
</script>
</body>
</html>


===== FILE: public/city/rider/index.html =====
<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover, maximum-scale=1" />
  <meta name="color-scheme" content="light dark" />
  <link rel="icon" href="data:," />
  <link rel="preconnect" href="https://fonts.googleapis.com">
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
  <link href="https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;500;600&family=Oxanium:wght@500;600;700&display=swap" rel="stylesheet">
  <title>Rider</title>
  <style>
    :root {
      color-scheme: light dark;
      --page:#edf1ef; --panel:#f8faf9; --panel-2:#e4e