<!-- SOLID CITY · part 2926 -->
sk]){releaseAt[task]=0;setOwner(task,'ai',true)}
    updateOwners();
    if(task==='move')return owners.move==='human'?input.move:aiMove();
    return owners.weapon==='human'?{x:input.weapon.x,y:input.weapon.y,fire:input.firing}:aiWeapon();
  }

  function spawnEnemy(){var y=55+Math.random()*(H-110);state.enemies.push({x:W+35,y:y,vx:-45-Math.random()*25,phase:Math.random()*6.28,hp:2,shot:.7+Math.random()});if(Math.random()<.45)state.rocks.push({x:W+70,y:40+Math.random()*(H-80),vx:-85-Math.random()*50,r:13+Math.random()*13,rot:0})}
  function particle(x,y,c,n){for(var i=0;i<n;i++)state.particles.push({x:x,y:y,vx:(Math.random()-.5)*160,vy:(Math.random()-.5)*160,life:.35+Math.random()*.5,c:c})}
  function hitCircle(a,b,r){return Math.hypot(a.x-b.x,a.y-b.y)<r}
  function damage(n){state.hull=Math.max(0,state.hull-n);particle(state.player.x,state.player.y,colors.red,9);if(state.hull<=0)finish(false)}

  function startSummit(){
    var sm=state.summit;if(sm.active)return;
    sm.active=true;sm.phase='mirror';sm.wing='absorbed';
    sm.twin={x:W*.80,y:H*.5,vx:0,vy:0,hp:26,max:26,phase:0,shot:1.5,nova:5,seed:0};
    els.mirrorWrap.hidden=false;updateMirrorHud();
    log('SUMMIT','The Mirror decloaks at Aster Gate','gold');
    summitAlert('THE MIRROR · HOLD BOTH REINS',2600);
  }
  function summitAlert(text,ms){state.summitAlert={text:text,until:now()+ms}}
  function updateMirrorHud(){var tw=state.summit.twin;if(!tw)return;var p=Math.max(0,tw.hp/tw.max);els.mirrorBar.style.width=(p*100)+'%';els.mirrorText.textContent=Math.round(p*100)+'%'}
  function twinMove(dt){
    var tw=state.summit.twin;if(!tw)return;
    var tx=(W*.78-tw.x)/W*.9,ty=(H*.5-tw.y)/H*.9;
    function repel(px,py,rad,str){var dx=tw.x-px,dy=tw.y-py,d=Math.hypot(dx,dy)||1;if(d<rad){var f=(1-d/rad)*str;tx+=dx/d*f;ty+=dy/d*f}}
    repel(state.player.x,state.player.y,130,1.7);
    for(var i=0;i<state.bullets.length;i++){var b=state.bullets[i];if(!b.ai)repel(b.x,b.y,80,2.0)}
    var m=Math.hypot(tx,ty);if(m>1){tx/=m;ty/=m}
    tw.vx+=(tx*155-tw.vx)*Math.min(1,dt*3.2);tw.vy+=(ty*205-tw.vy)*Math.min(1,dt*3.2);
    tw.x=Math.max(W*.55,Math.min(W*.94,tw.x+tw.vx*dt));tw.y=Math.max(52,Math.min(H-52,tw.y+tw.vy*dt));
    tw.seed+=dt*2;
  }
  function twinFire(dt){
    var tw=state.summit.twin;if(!tw||tw.hp<=0)return;
    tw.shot-=dt;
    if(tw.shot<=0){
      tw.shot=[1.3,1.0,0.75][tw.phase]+Math.random()*.3;
      var dx=state.player.x-tw.x,dy=state.player.y-tw.y,d=Math.hypot(dx,dy)||1,bs=235,lead=d/bs;
      var ax=state.player.x+state.player.vx*lead-tw.x,ay=state.player.y+state.player.vy*lead-tw.y,am=Math.hypot(ax,ay)||1;
      state.enemyBullets.push({x:tw.x,y:tw.y,vx:ax/am*bs,vy:ay/am*bs,life:3.2,twin:true});
      particle(tw.x,tw.y,'#ffc46b',3);
    }
    tw.nova-=dt;
    if(tw.nova<=0){tw.nova=[7,5.5,4][tw.phase];state.novas.push({x:tw.x,y:tw.y,r:16,hit:false})}
  }
  function twinHit(x,y){
    var tw=state.summit.twin;if(!tw||tw.hp<=0)return;
    tw.hp--;particle(x,y,colors.gold2,7);updateMirrorHud();
    if(tw.hp<=0)onTwinKilled();
  }
  function twinFizzle(x,y){
    particle(x,y,colors.teal,4);
    if(!state.summit.fizzleWarned){state.summit.fizzleWarned=true;log('ARMS','Teal fire cannot touch the Mirror','teal')}
  }
  function onTwinKilled(){
    var sm=state.summit,tw=sm.twin;sm.twin=null;sm.phase='choice';
    particle(tw.x,tw.y,colors.gold,40);particle(tw.x,tw.y,colors.teal,26);particle(tw.x,tw.y,'#ff6259',20);
    sm.core={x:tw.x,y:tw.y,vx:-120,vy:(tw.y>=state.player.y?1:-1)*130,pulse:0};
    els.mirrorWrap.hidden=true;
    for(var i=0;i<3;i++)state.rocks.push({x:W+70+i*90,y:60+Math.random()*(H-120),vx:-95-Math.random()*40,r:12+Math.random()*10,rot:0});
    log('SUMMIT','The Mirror breaks · the wing core is adrift','gold');
    summitAlert('WING CORE ADRIFT · RECOVER IT',3000);
  }
  function summitTick(dt){
    var sm=state.summit;if(!sm.active||sm.phase==='done')return;
    var tw=sm.twin;
    if(tw&&tw.hp>0){
      var ph=tw.hp>20?0:tw.hp>10?1:2;
      if(ph!==tw.phase){tw.phase=ph;log('MIRROR',ph===1?'Phase II':'Phase III','gold');particle(tw.x,tw.y,ph===2?'#ff6259':'#ffc46b',16)}
      twinMove(dt);twinFire(dt);
    }
    for(var n=0;n<state.novas.length;n++){var nv=state.novas[n];nv.r+=265*dt;if(!nv.hit&&Math.abs(Math.hypot(state.player.x-nv.x,state.player.y-nv.y)-nv.r)<18){nv.hit=true;damage(9)}}
    state.novas=state.novas.filter(function(nv){return nv.r<470});
    var c=sm.core;
    if(c){c.x+=c.vx*dt;c.y+=c.vy*dt;if(c.y<46||c.y>H-46)c.vy*=-1;c.y=Math.max(40,Math.min(H-40,c.y));c.pulse+=dt*6;
      if(hitCircle(c,state.player,32)){sm.core=null;sm.wing='formation';log('WING','The wing is aboard','teal');particle(state.player.x,state.player.y,colors.teal,26)}
      else if(c.x<-50){sm.core=null;sm.wing='lost';log('WING','Signal lost','')}
    }
  }

  function update(dt){
    if(!state.running)return;state.elapsed+=dt;keyboardInput();var mv=blendInput('move',dt),wp=blendInput('weapon',dt);
    var targetV