<!-- SOLID CITY · part 3720 -->
=>Math.hypot(p.x-ship.x,p.y-ship.y)<Math.hypot((a||{x:9}).x-ship.x,(a||{y:9}).y-ship.y)?p:a,null);if(nearest){ship.shieldFace=projectileImpactFace(nearest);pointDefense('ai');}else ship.shieldFace='front';}
}
function update(dt){if(!running||paused||ended)return;
  gameClock+=dt*1000;ship.progress=Math.min(1,ship.progress+dt*(.0037+(ship.boost?.0015:0)));ship.boost=false;
  ship.vx+=(ship.navInput*.34-ship.vx*2.8)*dt;ship.x=Math.max(.12,Math.min(.88,ship.x+ship.vx*dt));ship.navInput*=.82;if(!summit||!summit.shieldsDown)ship.shield=Math.min(100,ship.shield+dt*2.2);ship.defCooldown=Math.max(0,ship.defCooldown-dt);
  stars.forEach(s=>{s.y+=dt*(.055+s.z*.09);if(s.y>1){s.y=0;s.x=rand();}});
  nextSpawn-=dt;if(!summit&&nextSpawn<=0){spawnEnemy();if(wave>=3&&rand()<.28)spawnEnemy('cruiser');nextSpawn=Math.max(.55,1.6-wave*.16+rand()*.8);}
  wave=Math.min(4,1+Math.floor(ship.progress*4));
  enemies.forEach(e=>{if(e.dead)return;e.x+=e.vx*dt;e.y+=e.vy*dt;e.fire-=dt;if(e.fire<=0&&e.y<.75){e.fire=1.15+rand()*1.25;const dx=ship.x-e.x,dy=ship.y-e.y,l=Math.hypot(dx,dy)||1;enemyShots.push({id:'P'+Math.floor(rand()*99999),x:e.x,y:e.y,vx:dx/l*.19,vy:dy/l*.19,life:4});emit('enemy_fire',{threat:e.id});}if(e.y>.94){e.dead=true;damageShip(e.kind==='cruiser'?18:9,e.id+' ram',relativeImpactFace(e.x));}});
  shells.forEach(s=>{if(s.hit)return;s.life-=dt;if(s.mirror&&summit&&!summit.mirrorGone){s.tx=summit.x;s.ty=summit.y;const dx=s.tx-s.x,dy=s.ty-s.y,l=Math.hypot(dx,dy)||1;s.x+=dx/l*dt*.82;s.y+=dy/l*dt*.82;if(Math.hypot(s.x-summit.x,s.y-summit.y)<.05)summitShellStrike(s);return;}const target=enemies.find(e=>e.id===s.target&&!e.dead);if(target){s.tx=target.x;s.ty=target.y;}const dx=s.tx-s.x,dy=s.ty-s.y,l=Math.hypot(dx,dy)||1;s.x+=dx/l*dt*.82;s.y+=dy/l*dt*.82;const e=enemies.find(e=>!e.dead&&Math.hypot(e.x-s.x,e.y-s.y)<(e.kind==='cruiser'?.045:.028));if(e)hitEnemy(e,10,s);});
  enemyShots.forEach(p=>{p.x+=p.vx*dt;p.y+=p.vy*dt;p.life-=dt;if(Math.hypot(p.x-ship.x,p.y-ship.y)<.035){p.life=0;damageShip(8,'enemy projectile',projectileImpactFace(p));}});
  particles.forEach(p=>{p.x+=p.vx*dt;p.y+=p.vy*dt;p.vx*=.97;p.vy*=.97;p.life-=dt;});
  enemies=enemies.filter(e=>!e.dead&&e.y<1.05);shells=shells.filter(s=>!s.hit&&s.life>0);enemyShots=enemyShots.filter(p=>p.life>0&&p.y<1.1);particles=particles.filter(p=>p.life>0);
  ai(dt);adviceTick-=dt;if(adviceTick<=0){adviceTick=4.5;const human=Object.entries(coordination.tasks).filter(x=>x[1].owner==='human').map(x=>stationLabel(x[0]));const msg=human.length?'Holding '+(4-human.length)+' stations. Your '+human.join(' + ')+' commands remain isolated.':(enemyShots.length?'Incoming fire tracked. Defense is screening the ship.':'All stations coordinated. Route to Meridian Gate remains clear.');coordination.advisory('crew',msg);}
  if(enemyShots.some(p=>Math.hypot(p.x-ship.x,p.y-ship.y)<.18))showWarning('INCOMING · DEFENSE RECOMMENDS EVASION');
  updateSummit(dt);updateHUD();if(ship.progress>=1&&!summit&&!ended)beginSummit();
}
function draw(){ctx.clearRect(0,0,W,H);const grd=ctx.createLinearGradient(0,0,0,H);grd.addColorStop(0,'#02070c');grd.addColorStop(1,'#0a1c27');ctx.fillStyle=grd;ctx.fillRect(0,0,W,H);
  ctx.fillStyle='#d9f5ff';stars.forEach(s=>{ctx.globalAlpha=.25+s.z*.65;ctx.fillRect(s.x*W,s.y*H,Math.max(1,s.z*1.7),Math.max(1,s.z*3.2));});ctx.globalAlpha=1;
  const gateY=(.08+ship.progress*.03)*H;ctx.strokeStyle='rgba(35,199,217,.28)';ctx.lineWidth=2;ctx.beginPath();ctx.arc(W*.5,gateY,W*(.07+ship.progress*.02),0,Math.PI*2);ctx.stroke();ctx.fillStyle='rgba(35,199,217,.12)';ctx.beginPath();ctx.arc(W*.5,gateY,W*.04,0,Math.PI*2);ctx.fill();
  enemyShots.forEach(p=>{ctx.strokeStyle='#ff674e';ctx.lineWidth=2;ctx.beginPath();ctx.moveTo(p.x*W,p.y*H);ctx.lineTo((p.x-p.vx*.06)*W,(p.y-p.vy*.06)*H);ctx.stroke();});
  shells.forEach(s=>{ctx.strokeStyle=s.battery==='batteryA'?'#59eaff':'#ffd166';ctx.lineWidth=2;ctx.beginPath();ctx.moveTo(s.x*W,s.y*H);ctx.lineTo((s.x-(s.tx-s.x)*.08)*W,(s.y-(s.ty-s.y)*.08)*H);ctx.stroke();});
  enemies.forEach(e=>drawEnemy(e));if(summit)drawSummit();drawShip();particles.forEach(drawParticle);
  const humanTargets=['batteryA','batteryB'].filter(n=>coordination.tasks[n].owner==='human');humanTargets.forEach(n=>{const live=enemies.filter(e=>!e.dead),idx=n==='batteryA'?ship.targetA:ship.targetB,e=live[idx%live.length];if(e){ctx.strokeStyle=n==='batteryA'?'#59eaff':'#ffd166';ctx.lineWidth=1;ctx.setLineDash([5,5]);ctx.beginPath();ctx.arc(e.x*W,e.y*H,24,0,Math.PI*2);ctx.stroke();ctx.setLineDash([]);}});
  if(summit&&!summit.mirrorGone)['batteryA','batteryB'].filter(n=>coordination.tasks[n].owner==='human').forEach(n=>{ctx.strokeStyle=n==='batteryA'?'#59eaff':'#ffd166';ctx.lineWidth=1;ctx.setLineDash([5,5]);ctx.beginPath();ctx.arc(summit.x*W,summit.y*H,30,0,Math.PI*2);ctx.stroke();ctx.setLineDash([]);});
}
function drawEnemy(e){const x=e.x*W,y=e.y*H,s=e.kind==='cruiser'?18:11;ctx.save();ctx.translate(x,y);ctx.fillStyle=e.kind==='cruiser'?'#c6503d':'#8f405