<!-- SOLID CITY · part 2909 -->
s.hp+10);if(s.cargo)s.cargo.hp=Math.min(100,s.cargo.hp+8);recordEvent('repair',{owner});
  }
  function updateSupport(dt){
    const s=state.ship;if(coordination.owner('support')==='ai'&&s.repairCd<=0&&(s.hp<72||(s.cargo&&s.cargo.hp<65)))repair('ai');
    if(adviceTimer<=0){
      const p=nearestPod(),e=nearestEnemy();
      if(e&&dist(s,e)<180)setAdvice('Interceptor closing. Protection station has a firing solution.');
      else if(s.cargo)setAdvice(s.cargo.id+' is aboard. Hold course for the blue rescue gate.');
      else if(p)setAdvice(p.id+' is '+Math.round(dist(s,p))+' meters away. Approach inside the rescue ring.');
      adviceTimer=4;
    }
  }

  function updateWorld(dt){
    const s=state.ship;
    state.debris.forEach(d=>{d.x+=d.vx*dt;d.y+=d.vy*dt;if(d.x<170)d.x=850;if(d.y<60)d.y=530;if(d.y>540)d.y=70;if(dist(s,d)<d.r+15){damageShip(4*dt)}});
    state.hazards.forEach(h=>{h.spin+=dt*.35;if(dist(s,h)<h.r){damageShip(11*dt);if(s.cargo)s.cargo.hp-=7*dt}});
    if(spawnTimer<=0&&state.enemies.length<6){
      const livePods=state.pods.some(p=>p.status==='adrift'||p.status==='cargo');if(livePods){state.enemies.push({x:W+25,y:80+Math.random()*440,hp:36,vx:-22-Math.random()*14,phase:Math.random()*6});spawnTimer=5.5+Math.random()*3}
    }
    state.enemies.forEach(e=>{
      if(e.hp<=0)return;e.phase+=dt;e.x+=e.vx*dt;e.y+=Math.sin(e.phase*1.7)*15*dt;
      const target=state.ship.cargo?state.ship:(nearestPod()||state.ship),d=dist(e,target);if(d<185){e.x+=(target.x-e.x)/d*24*dt;e.y+=(target.y-e.y)/d*24*dt}
      if(dist(e,s)<30){damageShip(16*dt);e.hp=0}
      state.pods.filter(p=>p.status==='adrift').forEach(p=>{if(dist(e,p)<75)p.hp-=5*dt});
    });
    state.shots.forEach(sh=>{if(!sh.target||sh.target.hp<=0){sh.dead=true;return}const dx=sh.target.x-sh.x,dy=sh.target.y-sh.y,d=Math.max(1,Math.hypot(dx,dy));sh.x+=dx/d*470*dt;sh.y+=dy/d*470*dt;if(d<16){sh.target.hp-=18;sh.dead=true;if(sh.target.hp<=0)recordEvent('interception',{owner:sh.owner})}});
    state.shots=state.shots.filter(x=>!x.dead);state.enemies=state.enemies.filter(e=>e.hp>0&&e.x>-50);
    state.pods.forEach(p=>{if(p.status==='adrift')p.hp-=.34*dt;if(p.hp<=0&&p.status==='adrift'){p.hp=0;p.status='lost';state.lost++;recordEvent('lost',{pod:p.id})}});
    if(s.cargo){s.cargo.x=s.x-22;s.cargo.y=s.y+21;if(s.cargo.hp<=0){s.cargo.status='lost';state.lost++;recordEvent('lost',{pod:s.cargo.id});s.cargo=null}}
    if(s.cargo&&dist(s,state.gate)<state.gate.r){const p=s.cargo;p.status='rescued';state.rescued++;s.cargo=null;recordEvent('rescue',{pod:p.id});setAdvice(p.id+' is safe. Returning for the next pilot.');}
  }
  function damageShip(amount){const s=state.ship;if(s.pulse>0)amount*=.25;if(s.shield>0){const take=Math.min(s.shield,amount);s.shield-=take;amount-=take}s.hp=Math.max(0,s.hp-amount)}
  function updateRisk(){state.risk=state.pods.filter(p=>(p.status==='adrift'||p.status==='cargo')&&p.hp<42).length}
  function checkEnd(){
    const done=state.pods.every(p=>p.status==='rescued'||p.status==='lost');
    if(state.ship.hp<=0){endMission(false,'The vessel was lost in the corridor. '+state.rescued+' pilot'+(state.rescued===1?'':'s')+' reached safety.');}
    else if(done&&!state.ship.cargo){finishTimer+=.016;if(finishTimer>.25)endMission(state.rescued>0,state.rescued+' of 3 pilots reached the gate. '+(state.lost?state.lost+' could not be recovered.':'Every life came home.'));}
  }
  function endMission(success,copy){if(state.missionEnd)return;state.missionEnd=true;running=false;recordEvent('mission',{success,rescued:state.rescued,lost:state.lost});$('#resultTitle').textContent=success?(state.rescued===3?'All hands rescued':'Mission ended'):'Vessel lost';$('#resultCopy').textContent=copy;$('#result').classList.add('show')}

  function draw(){
    const g=ctx.createLinearGradient(0,0,W,H);g.addColorStop(0,'#06151e');g.addColorStop(1,'#02070c');ctx.fillStyle=g;ctx.fillRect(0,0,W,H);
    drawStars();drawGate();state.hazards.forEach(drawHazard);state.debris.forEach(drawDebris);state.pods.forEach(drawPod);state.enemies.forEach(drawEnemy);state.shots.forEach(drawShot);drawShip();
  }
  function drawStars(){ctx.save();for(let i=0;i<90;i++){const x=(i*113)%W,y=(i*67)%H,a=.2+(i%5)*.12;ctx.fillStyle='rgba(177,230,239,'+a+')';ctx.fillRect(x,y,i%13===0?2:1,i%13===0?2:1)}ctx.restore()}
  function drawGate(){const g=state.gate;ctx.save();ctx.translate(g.x,g.y);ctx.strokeStyle='#57e7ff';ctx.lineWidth=6;ctx.shadowColor='#32d9ff';ctx.shadowBlur=22;ctx.beginPath();ctx.arc(0,0,g.r,-1.2,1.2);ctx.stroke();ctx.beginPath();ctx.arc(0,0,g.r,1.94,4.34);ctx.stroke();ctx.shadowBlur=0;ctx.fillStyle='#b8f7ff';ctx.font='700 13px "Arial Narrow"';ctx.textAlign='center';ctx.fillText('RESCUE GATE',0,-g.r-12);ctx.restore()}
  function drawHazard(h){ctx.save();ctx.translate(h.x,h.y);ctx.rotate(h.spin);ctx.strokeStyle='rgba(255,99,117,.48)';ctx.fillStyle='rgba(255,70,92,.05)';ctx.lineWidth=2;ctx.setLineDash([8,8]);ctx.beginPath();ctx.arc(0,0,h.r,0,Mat