<!-- SOLID CITY · part 2917 -->
raction');
    let stabilizing=false,tractoring=false;
    if(owner==='ai'&&d<92){stabilizing=true;if(p.stabilize>=100)tractoring=true}
    if(owner==='human'){stabilizing=state.stabilizeHeld;tractoring=state.extractHeld}
    if(stabilizing&&d<105){p.stabilize=Math.min(100,p.stabilize+dt*(owner==='ai'?29:38));if(adviceTimer<=0){setAdvice('Holding '+p.id+' steady — stabilization '+Math.floor(p.stabilize)+'%.');adviceTimer=2.5}}
    else p.stabilize=Math.max(0,p.stabilize-dt*5);
    if(tractoring&&d<92&&p.stabilize>=100){
      p.status='cargo';state.ship.cargo=p;recordEvent('extraction',{pod:p.id,owner});setAdvice(p.id+' is aboard. Protect the pod and make for the blue gate.');
    }
  }

  function fireAt(target,owner){
    const s=state.ship;if(s.fireCd>0||!target)return;s.fireCd=.28;
    state.shots.push({x:s.x,y:s.y,target,vx:0,vy:0,owner});
    recordEvent('shot',{owner});
  }
  function updateProtection(dt){
    const e=nearestEnemy();
    if(coordination.owner('protection')==='ai'&&e&&dist(state.ship,e)<270)fireAt(e,'ai');
  }
  function repair(owner){
    const s=state.ship;if(s.repairCd>0)return;s.repairCd=3.2;s.hp=Math.min(100,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