<!-- SOLID CITY · part 2947 -->
layer:{x:W*.30,y:H*.52,vx:0,vy:0},wing:{x:W*.22,y:H*.61},enemies:[],rocks:[],bullets:[],enemyBullets:[],stars:[],particles:[]};
    for(var i=0;i<100;i++)state.stars.push({x:Math.random()*W,y:Math.random()*H,z:.25+Math.random()*.9});
    els.pauseBtn.hidden=true;els.pauseOverlay.hidden=true;els.stage.classList.remove('is-running');pauseStarted=0;pausedReleases.move=pausedReleases.weapon=false;
    applyMode(mode,false); updateHud(); els.logList.innerHTML=''; log('SYS','Rider ready','teal');
  }
  function applyMode(next,write){
    if(state&&state.paused)return;
    mode=next;document.querySelectorAll('.preset').forEach(function(b){b.classList.toggle('active',b.dataset.mode===mode)});
    if(mode==='rider'){setOwner('move','human',write);setOwner('weapon','ai',write)}
    if(mode==='archer'){setOwner('move','ai',write);setOwner('weapon','human',write)}
    if(mode==='manual'){setOwner('move','human',write);setOwner('weapon','human',write)}
    releaseAt.move=releaseAt.weapon=0;updateOwners();
    if(write)log('CFG',mode==='rider'?'Human movement · AI weapons':mode==='archer'?'AI movement · Human weapons':'Human holds both','gold');
  }
  document.querySelectorAll('.preset').forEach(function(b){b.addEventListener('click',function(){applyMode(b.dataset.mode,true)})});

  function now(){return performance.now()}
  function setOwner(task,owner,write){
    if(owners[task]===owner)return;
    owners[task]=owner;if(state){state.handoffs++;els.handoffCount.textContent=state.handoffs}
    if(write!==false)log(task==='move'?'MOVE':'ARMS',owner==='human'?'Human claimed task':'AI resumed task',owner==='human'?'gold':'teal');
    updateOwners();
  }
  function claim(task){
    releaseAt[task]=0;var t0=now();setOwner(task,'human',true);var latency=Math.max(1,Math.round(now()-t0));
    (task==='move'?els.moveLatency:els.weaponLatency).textContent=latency+' ms';updateOwners();
  }
  function release(task){releaseAt[task]=now()+800;log(task==='move'?'MOVE':'ARMS','Release detected · guarded coast','');updateOwners()}
  function updateOwners(){
    [['move',els.moveOwner],['weapon',els.weaponOwner]].forEach(function(pair){var task=pair[0],el=pair[1],releasing=releaseAt[task]>now();el.className='owner '+(releasing?'release':owners[task]);el.textContent=releasing?'HUMAN → AI':owners[task].toUpperCase()});
  }
  function log(tag,text,tone){
    if(!state)return;var li=document.createElement('li');var sec=Math.floor(state.elapsed);var mm=String(Math.floor(sec/60)).padStart(2,'0'),ss=String(sec%60).padStart(2,'0');li.innerHTML='<time>'+mm+':'+ss+'</time><span><b class="'+(tone||'')+'">'+tag+'</b> · '+text+'</span>';els.logList.insertBefore(li,els.logList.firstChild);while(els.logList.children.length>24)els.logList.lastChild.remove();
  }

  function bindPad(id,nub,task){
    var pad=document.getElementById(id),active=null;
    function move(e){if(e.pointerId!==active||state.paused)return;var r=pad.getBoundingClientRect(),x=(e.clientX-r.left)/r.width*2-1,y=(e.clientY-r.top)/r.height*2-1,m=Math.hypot(x,y);if(m>1){x/=m;y/=m}input[task].x=x;input[task].y=y;nub.style.left=((x*.39+.5)*100)+'%';nub.style.top=((y*.39+.5)*100)+'%';if(task==='weapon')input.firing=true}
    pad.addEventListener('pointerdown',function(e){e.preventDefault();if(state.paused)return;active=e.pointerId;pad.setPointerCapture(active);if(task==='move')pointerMove=true;else pointerWeapon=true;claim(task);move(e)});
    pad.addEventListener('pointermove',move);
    function end(e){if(e.pointerId!==active)return;active=null;if(task==='move')pointerMove=false;else pointerWeapon=false;if(state.paused){pausedReleases[task]=true;return}input[task]={x:task==='weapon'?1:0,y:0};input.firing=false;nub.style.left='50%';nub.style.top='50%';release(task)}
    pad.addEventListener('pointerup',end);pad.addEventListener('pointercancel',end);
  }
  bindPad('movePad',document.getElementById('moveNub'),'move');bindPad('weaponPad',document.getElementById('weaponNub'),'weapon');

  window.addEventListener('keydown',function(e){
    var k=e.key.toLowerCase();if(['w','a','s','d','arrowup','arrowdown','arrowleft','arrowright',' '].indexOf(k)>=0)e.preventDefault();
    if(state&&state.paused)return;if(keys[k])return;keys[k]=true;
    if('wasd'.indexOf(k)>=0)claim('move');if(k.indexOf('arrow')===0||k===' ')claim('weapon');
  });
  window.addEventListener('keyup',function(e){
    var k=e.key.toLowerCase(),moveReleased='wasd'.indexOf(k)>=0,weaponReleased=k.indexOf('arrow')===0||k===' ';keys[k]=false;
    var noMove=!['w','a','s','d'].some(function(x){return keys[x]}),noWeapon=!['arrowup','arrowdown','arrowleft','arrowright',' '].some(function(x){return keys[x]});
    if(state&&state.paused){if(moveReleased&&noMove)pausedReleases.move=true;if(weaponReleased&&noWeapon)pausedReleases.weapon=true;return}
    if(moveReleased&&noMove)release('move');if(weaponReleased&&noWeapon)release('weapon');
  });

  function keyboardInput(){
    if(!pointerMove){var x=(keys.d?1:0