<!-- SOLID CITY · part 3447 -->
activeOrder==='SCATTER'){tx=.22+(index%6)*.11;ty=.23+Math.floor(index/6)*.5}
    else if(activeOrder==='REGROUP'){tx=convoyX+.12+(index%4)*.035;ty=.39+Math.floor(index/4)*.11}
    else if(activeOrder==='GUARD'){var a=index/12*Math.PI*2;tx=convoyX+.11+Math.cos(a)*.11;ty=.5+Math.sin(a)*.25}
    else if(activeOrder==='LATTICE'&&summit&&summit._sp){var tgt=summit.assignTarget[d.id];if(summit.phase==='collapse'||tgt==null){tx=d.x;ty=d.y}else{tx=summit._sp[tgt].x;ty=summit._sp[tgt].y}}
    var dx=tx-d.x,dy=ty-d.y,m=Math.hypot(dx,dy)||1;d.vx+=(dx/m)*.10*dt;d.vy+=(dy/m)*.10*dt;var sp=Math.hypot(d.vx,d.vy),max=activeOrder==='LATTICE'?.11:.075;if(sp>max){d.vx=d.vx/sp*max;d.vy=d.vy/sp*max}
    var target=nearestDebris(d);if(target&&Math.hypot(target.x-d.x,target.y-d.y)<.085){target.hp-=dt*(activeOrder==='CONVERGE'?30:18);d.pulse=.22;if(target.hp<=0)clearDebris(target,d.name)}
  }
  function nearestDebris(d){var best=null,bd=99;debris.forEach(function(o){var v=Math.hypot(o.x-d.x,o.y-d.y);if(v<bd){bd=v;best=o}});return best}
  function clearDebris(o,by){var idx=debris.indexOf(o);if(idx<0)return;debris.splice(idx,1);for(var i=0;i<9;i++)particles.push({x:o.x,y:o.y,vx:(Math.random()-.5)*.09,vy:(Math.random()-.5)*.09,life:.8});addEvent('CLEARED',by,'Hazard '+String(o.id).slice(-3)+' cleared from convoy lane')}
  function firePulse(){
    if(paused)return;var d=drones.find(function(x){return x.id===selectedId});if(!d||d.owner!=='HUMAN'||d.status!=='ACTIVE')return;d.pulse=.45;var hit=0;debris.slice().forEach(function(o){var dist=Math.hypot(o.x-d.x,o.y-d.y);if(dist<.12){o.hp-=42*(1-dist/.14);hit++;if(o.hp<=0)clearDebris(o,d.name)}});addEvent('PULSE',d.name,'Human clear pulse engaged '+(hit?'on '+hit+' hazard'+(hit===1?'':'s'):'with no hazard in range'));
    if(summit&&(summit.phase==='strain'||summit.phase==='cage')&&!summit.core.dead){var cdx=d.x-summit.core.x,cdy=d.y-summit.core.y;if(Math.hypot(cdx,cdy)<0.28){summit.core.surgePower=Math.max(0.45,summit.core.surgePower*0.55);summit.core.strain=Math.max(0,summit.core.strain-0.25);addEvent('DISRUPT',d.name,'Pulse disrupted the core; next surge weakened')}}
  }
  function disableDrone(d,cause){if(d.status!=='ACTIVE')return;d.status='DISABLED';d.hp=0;d.vx=d.vy=0;d.recover=0;d.lostReason=cause;addEvent('LOST',d.name,'Drone disabled by '+cause+'; recoverable through REGROUP');if(selectedId===d.id)selectedId=null}
  function recoverLogic(dt){var lat=summit&&activeOrder==='LATTICE'&&(summit.phase==='lattice'||summit.phase==='strain');if(activeOrder!=='REGROUP'&&!lat)return;var helpers=drones.filter(function(d){return d.status==='ACTIVE'&&d.owner==='AI'}).length;drones.forEach(function(d){if(d.status!=='DISABLED')return;d.recover+=dt*Math.max(.45,helpers/8);if(d.recover>=7){d.status='ACTIVE';d.hp=55;d.owner='AI';d.epoch++;d.task=lat?'LATTICE':'REGROUP';if(lat&&summit){d.x=summit.core.x-.22+Math.random()*.06;d.y=.3+Math.random()*.4}else{d.x=convoyX+.14+Math.random()*.05;d.y=.42+Math.random()*.16}addEvent('RECOVERED',d.name,'Recovered by AI sub-commanders; resumed at epoch '+d.epoch)}})}
  function update(dt){
    elapsed=(performance.now()-missionStart)/1000;processQueue();
    drones.forEach(function(d,i){if(d.status!=='ACTIVE')return;if(d.handoffAt&&elapsed>=d.handoffAt){d.handoffAt=0;d.task=activeOrder;updateAllUI()}if(d.owner==='HUMAN')humanControl(d,dt);else aiControl(d,dt,i);d.vx*=Math.pow(.16,dt);d.vy*=Math.pow(.16,dt);d.x+=d.vx*dt;d.y+=d.vy*dt;d.x=Math.max(.05,Math.min(.96,d.x));d.y=Math.max(.12,Math.min(.91,d.y));d.pulse=Math.max(0,d.pulse-dt);d.hit=Math.max(0,d.hit-dt)});
    if(summit)updateSummit(dt);else debris.slice().forEach(function(o){o.x+=o.vx*dt;o.y+=o.vy*dt;o.angle+=o.spin*dt;if(o.y<.12||o.y>.91)o.vy*=-1;if(o.x<.06){debris.splice(debris.indexOf(o),1);progress=Math.max(0,progress-1.8);addEvent('BREACH','CONVOY','Uncleared debris crossed the protection line');}
      drones.forEach(function(d){if(d.status!=='ACTIVE'||d.hit>0)return;var dist=Math.hypot(o.x-d.x,o.y-d.y);if(dist<o.r+.015){d.hp-=16+wave*3;d.hit=.7;o.vx*=-.55;o.vy+=(Math.random()-.5)*.05;addEvent('IMPACT',d.name,'Hull impact; integrity now '+Math.max(0,Math.round(d.hp))+'%');if(d.hp<=0)disableDrone(d,'debris impact')}})
    });
    particles.forEach(function(p){p.x+=p.vx*dt;p.y+=p.vy*dt;p.life-=dt});particles=particles.filter(function(p){return p.life>0});recoverLogic(dt);
    var active=drones.filter(function(d){return d.status==='ACTIVE'}).length;if(!summit){var pressure=Math.max(0,1-debris.length/(7+wave*2));progress+=dt*(.22+.24*pressure)*(active/12);convoyX=.12+progress/100*.65;
    if(progress>=wave*25&&wave<4){wave++;spawnWave(wave);announce('Wave '+wave+' incoming. '+debris.length+' hazards tracked.')}
    if(elapsed>=nextHazardAt){nextHazardAt=elapsed+Math.max(4.5,8-wave);if(wave>=2)debris.push({id:++uid,x:.98,y:.14+Math.random()*.75,r:.012+Math.random()*.012,hp:40+wave*13,max:40+wave*13,vx:-.006-wave*.001,vy:(Math.random()-.5)*.008,spin:(Math.random()-.5)*2,angle