<!-- SOLID CITY · part 1901 -->
pawnSpeedRing(0);spawnSpeedRing(1);progression.pursuer={x:430,y:800,vx:0,vy:0,a:0,r:42,lastHit:0}}
    if(n===3){hazards=[{x:420,y:350,r:150,type:'ion',color:'#755dff',stage:2},{x:1930,y:1180,r:180,type:'rift',color:'#ff4f88',stage:3}];for(var j=0;j<9;j++)spawnEnemy()}
    if(n===4){for(var k=0;k<10;k++)spawnEnemy();for(k=0;k<4;k++)spawnMeteor(true);progression.boss={id:nextId++,x:1950,y:800,vx:0,vy:0,a:Math.PI,hull:420,maxHull:420,r:60,fire:.7,targetIndex:0,threatTargetIndex:0,rescuePilot:-1,rescueBroke:false,lastHitBy:-1,lastHitAt:0,coordAt:0};enemies.push(progression.boss);for(k=0;k<2;k++){spawnSpeedRing(0);spawnSpeedRing(1)}}
    if(n===5){for(var q=0;q<110;q++)corridorStars.push({x:Math.random()*2-1,y:Math.random()*2-1,z:.08+Math.random()*.92,r:.4+Math.random()*1.4});spawnCorridorRun();notify(0,'DEPTH BEGINS HERE',1800);notify(1,'DEPTH BEGINS HERE',1800)}
    setLevelHUD();levelBeat.hidden=true;running=true;last=performance.now();notify(0,'LEVEL '+n+' · '+levelInfo[n].name,1400);notify(1,'LEVEL '+n+' · '+levelInfo[n].name,1400)
  }
  function completeLevel(){
    if(transitioning)return;transitioning=true;running=false;burst(ships[0].x,ships[0].y,'#fff2a8',34);burst(ships[1].x,ships[1].y,'#b8fff7',34);
    if(level<4){showLevelBrief(level+1)}else if(level===4){showFuture()}else{showDepthComplete()}
  }
  function showFuture(){
    document.querySelector('#levelNo').textContent='FOUR LEVELS COMPLETE';document.querySelector('#levelTitle').textContent='3D UNLOCKED';document.querySelector('#levelCopy').textContent='Depth begins here. The arena falls away into a forward corridor: threats meet you head-on, and survival means learning to rise above or dive below.';document.querySelector('#continueLevel').textContent='BEGIN FORWARD FLIGHT';document.querySelector('#levelCard').classList.add('future');levelBeat.dataset.next='5';levelBeat.hidden=false
  }
  function showDepthComplete(){
    document.querySelector('#levelNo').textContent='FIRST DEPTH LESSON COMPLETE';document.querySelector('#levelTitle').textContent='UNDER & OVER';document.querySelector('#levelCopy').textContent='The Twin Lightnings crossed the corridor as one formation — above, alongside, and below. The flat sky is behind you.';document.querySelector('#continueLevel').textContent='VIEW DEBRIEF';document.querySelector('#levelCard').classList.add('future');levelBeat.dataset.next='depthComplete';levelBeat.hidden=false
  }
  function spawnSpeedRing(owner){var s=ships[owner],a=Math.hypot(s.vx,s.vy)>30?Math.atan2(s.vy,s.vx):s.a+(Math.random()-.5)*.8,d=210+Math.random()*120;rings.push({id:nextId++,owner:owner,x:wrapX(s.x+Math.cos(a)*d),y:wrapY(s.y+Math.sin(a)*d),r:30,phase:Math.random()*6.28})}
  function spawnMeteor(targeted){
    var targetIndex=targeted&&Math.random()<.28?1:0,target=ships[targetIndex],ang=Math.random()*Math.PI*2;
    var dist=650+Math.random()*350,x=target.x+Math.cos(ang)*dist,y=target.y+Math.sin(ang)*dist;
    var aim=targeted?Math.atan2(target.y+target.vy*1.1-y,target.x+target.vx*1.1-x):ang+Math.PI+(Math.random()-.5)*1.1;
    var sp=360+wave*28+Math.random()*110;
    meteors.push({id:nextId++,x:wrapX(x),y:wrapY(y),vx:Math.cos(aim)*sp,vy:Math.sin(aim)*sp,r:18+Math.random()*15,hull:2,rot:Math.random()*6,spin:(Math.random()-.5)*2,threat:false,targetIndex:targeted?targetIndex:-1,threatTargetIndex:targeted?targetIndex:-1,rescuePilot:-1,rescueBroke:false,lastHitBy:-1,lastHitAt:0,coordAt:0,resolved:false,action:'none'});
  }
  function wrapX(x){return (x+WORLD.w)%WORLD.w}function wrapY(y){return (y+WORLD.h)%WORLD.h}
  function delta(a,b,size){var d=a-b;if(d>size/2)d-=size;if(d<-size/2)d+=size;return d}
  function distObj(a,b){var dx=delta(a.x,b.x,WORLD.w),dy=delta(a.y,b.y,WORLD.h);return Math.hypot(dx,dy)}
  function collisionCourse(o,s,windowSec,margin){var rx=delta(o.x,s.x,WORLD.w),ry=delta(o.y,s.y,WORLD.h),rvx=o.vx-s.vx,rvy=o.vy-s.vy,rv2=rvx*rvx+rvy*rvy;if(rv2<1)return false;var t=-(rx*rvx+ry*rvy)/rv2,cx=rx+rvx*t,cy=ry+rvy*t;return t>0&&t<(windowSec||1.8)&&Math.hypot(cx,cy)<(o.r||12)+(margin||28)}
  function nearest(from,list,max){var best=null,bd=max||1e9;list.forEach(function(o){var d=distObj(from,o);if(d<bd){bd=d;best=o}});return best}
  function updateFlight(dt){
    var d=distObj(ships[0],ships[1]);flight.lastDistance=d;
    if(flight.mode==='formation'){
      metrics.formationTime+=dt;
      if(d>470){flight.mode='separation';flight.wasSeparated=true;metrics.separations++;if(ships[1].coveringTarget!==null)ships[1].coverBroke=true;enemies.concat(meteors).forEach(function(o){if(o.rescuePilot>=0)o.rescueBroke=true;o.lastHitBy=-1;o.lastHitAt=0});flightStateEl.textContent='SEPARATION';flightStateEl.className='flight-state separation';notify(0,'DIRECTION HOME',850);notify(1,'DIRECTION HOME',850)}
    }else if(flight.mode==='separation'&&d<330){
      flight.mode='formation';flight.reunionUntil=performance.now()+1500;metrics.reunions++;metrics.reunionBonus+=150;ships[0].score+=75;ships[1].score+=75;flig