<!-- SOLID CITY · part 2003 -->
l}}
  function reset(startBattle){ships=[];shots=[];rocks=[];sparks=[];events=[];pendingReleases=[];progress={gold:0,teal:0};selected={gold:null,teal:null};order={gold:'form',teal:'form'};running=startBattle!==false;paused=false;pausedAt=0;totalPaused=0;rngSeed=88421;missionStart=performance.now();eventCounts={handoff:0,rescue:0,formation:0,rejected:0,hit:0};for(var t of ['gold','teal'])for(var i=0;i<4;i++)ships.push(makeShip(t,i));for(var r=0;r<13;r++)rocks.push({x:320+rand()*560,y:50+rand()*620,vx:-18+rand()*36,vy:-15+rand()*30,r:9+rand()*18,spin:rand()*6});document.getElementById('debrief').classList.remove('open');document.getElementById('pauseOverlay').classList.remove('open');document.getElementById('pauseTrigger').hidden=!running;document.querySelectorAll('.orders button').forEach(function(b){b.classList.toggle('active',b.dataset.order==='form')});if(running)log('formation','Both squadrons entered Diamond formation');else updateStats();summit.active=false;summit.phase='none';summit.beaconHp=100;summit.hold=0;summit.wave=0;summit.spawnQueue=0;summit.spawnTimer=0;summit.spawnedThisWave=0;summit.shards=[];summit.choice=null;summit.anchor=null;summit.pulseR=0;summit.ignition=0;summit.choiceTimer=0;summit.lost=[];document.getElementById('summitBar').hidden=true;document.getElementById('summitChoices').hidden=true;document.getElementById('missionLine').textContent='First squadron to secure 100% control wins.';document.querySelectorAll('.objective span').forEach(function(el){el.textContent='BEACON'});resizeAll();updateUI()}
  function teamShips(t){return ships.filter(function(s){return s.team===t})} function enemyTeam(t){return t==='gold'?'teal':'gold'}
  function ownerLabel(s){var human=Object.values(s.owners).filter(function(o){return o==='HUMAN'}).length;return human?(human===4?'HUMAN':'HUMAN · '+human+'/4') : s.pilot}
  function claim(s,parts){parts.forEach(function(p){if(s.owners[p]!=='HUMAN'){s.epochs[p]++;s.owners[p]='HUMAN'}});s.lastHuman=performance.now();selected[s.team]=s.id;log('handoff',s.name+' yielded '+parts.join(' + ')+' to human',s.id);toast(s.name+' · helm acquired');updateUI()}
  function release(s,parts){parts=parts||Object.keys(s.owners);var changed=[];parts.forEach(function(p){if(s.owners[p]==='HUMAN'){s.epochs[p]++;s.owners[p]='AI';changed.push(p)}});if(changed.length){log('handoff',s.name+' returned '+changed.join(' + ')+' to '+s.pilot,s.id);toast(s.name+' · AI resumed safely')}if(parts.length===4)selected[s.team]=null;updateUI()}
  function issueOrder(team,o){order[team]=o;var skipped=0;teamShips(team).forEach(function(s){if(s.disabled>0)return;if(s.owners.movement==='HUMAN'||s.owners.navigation==='HUMAN'){skipped++;return}s.task=({form:'Form Up',attack:'Coordinated Attack',defend:'Defend Beacon',intercept:'Intercept'}[o]);s.epochs.navigation++});document.querySelectorAll('[data-team="'+team+'"][data-order]').forEach(function(b){b.classList.toggle('active',b.dataset.order===o)});log('formation',team.toUpperCase()+' order: '+o.toUpperCase()+(skipped?' · '+skipped+' human helm advised, not overridden':''));toast(o.toUpperCase()+(skipped?' · human helm preserved':''))}
  function nearestEnemy(s){var a=teamShips(enemyTeam(s.team)).filter(function(e){return e.disabled<=0});a.sort(function(x,y){return dist(s,x)-dist(s,y)});return a[0]}
  function desired(s){if(summit.active&&summit.phase!=='done')return unionDesired(s);var mates=teamShips(s.team),leader=mates[0],enemy=nearestEnemy(s),gold=s.team==='gold',baseX=gold?470:730,baseY=360,off=[[-55,-55],[-55,55],[-120,-95],[-120,95]][s.slot];if(!gold)off=[-off[0],off[1]];
    var weak=mates.find(function(m){return m!==s&&m.hull>0&&m.hull<28&&dist(s,m)<330});if(weak&&s.owners.movement==='AI'&&s.hull>45){s.task='Rescue '+weak.name;s.rescueTarget=weak;return{x:weak.x+(gold?-40:40),y:weak.y}}
    s.rescueTarget=null;
    if(order[s.team]==='attack'&&enemy){s.task='Attack '+enemy.name;return{x:enemy.x+(gold?-115:115),y:enemy.y+(s.slot-1.5)*24}}
    if(order[s.team]==='defend'){s.task='Defend Beacon';return{x:BEACON.x+(gold?-1:1)*(115+s.slot*22),y:BEACON.y+(s.slot-1.5)*55}}
    if(order[s.team]==='intercept'&&enemy){s.task='Intercept '+enemy.name;return{x:enemy.x+enemy.vx*2.4,y:enemy.y+enemy.vy*2.4}}
    s.task='Form Up';if(s!==leader&&leader.disabled<=0)return{x:leader.x+off[0],y:leader.y+off[1]};return{x:baseX,y:baseY}}
  function steer(s,target,dt,brake){var dx=target.x-s.x,dy=target.y-s.y,d=Math.max(1,Math.hypot(dx,dy)),arrive=brake&&d<140?0.2+0.8*d/140:1,ax=dx/d*82*arrive,ay=dy/d*82*arrive;for(var r of rocks){var rd=dist(s,r);if(rd<95+r.r){var k=(110+r.r-rd)/110;ax+=(s.x-r.x)/Math.max(1,rd)*180*k;ay+=(s.y-r.y)/Math.max(1,rd)*180*k;s.task=s.owners.movement==='HUMAN'?s.task:'Dodge meteor'}}s.vx+=ax*dt;s.vy+=ay*dt;var sp=Math.hypot(s.vx,s.vy),max=130;if(sp>max){s.vx=s.vx/sp*max;s.vy=s.vy/sp*max}s.a=Math.atan2(s.vy,s.vx)}
  function fire(s,forced){if(s.disabled>0||s.cool>0)return;var e=summitTarget(s);if(!e)return;v