<!-- SOLID CITY · part 3465 -->
pan></div><div class="metric"><b id="metricCleared">0</b><span>cleared</span></div><div class="metric"><b id="metricRejected">0</b><span>stale rejected</span></div></div>
      </section>
    </aside>
  </div>
</main>

<dialog id="statsDialog" aria-labelledby="statsTitle">
  <div class="dialog-head"><h2 id="statsTitle">Event-derived mission STATS</h2><button class="close" id="closeStats" aria-label="Close stats">✕</button></div>
  <div class="stats-body">
    <div class="stats-summary" id="statsSummary"></div>
    <section class="stats-section"><h3>Per-drone control record</h3><div style="overflow:auto"><table class="drone-table"><thead><tr><th>Drone</th><th>Owner</th><th>Epoch</th><th>Task</th><th>Status</th><th>Hull</th></tr></thead><tbody id="droneRows"></tbody></table></div></section>
    <section class="stats-section"><h3>Coordination events · newest first</h3><div class="event-list" id="eventList"></div></section>
  </div>
</dialog>

<script>
(function(){
  'use strict';
  var canvas=document.getElementById('field'),ctx=canvas.getContext('2d');
  var startScreen=document.getElementById('startScreen'),debrief=document.getElementById('debrief');
  var running=false,last=0,missionStart=0,elapsed=0,progress=0,wave=1,activeOrder='FORM UP',selectedId=null;
  var drones=[],debris=[],particles=[],events=[],commandQueue=[],pressed={up:false,down:false,left:false,right:false};
  var nextHazardAt=0,nextAdvisoryAt=0,convoyX=.12,canvasW=0,canvasH=0,dpr=1,uid=0;
  var GROUPS=['ALPHA','BETA','GAMMA'];
  var colors={gold:'#ffc34d',teal:'#52e0d0',red:'#ff625f',white:'#eaf9f7',deep:'#031012'};

  function nowStamp(){var s=Math.max(0,Math.floor(elapsed));return String(Math.floor(s/60)).padStart(2,'0')+':'+String(s%60).padStart(2,'0')}
  function addEvent(type,subject,detail){events.push({id:++uid,time:nowStamp(),type:type,subject:subject,detail:detail});if(events.length>180)events.shift();updateMetrics()}
  function count(type){return events.filter(function(e){return e.type===type}).length}
  function setup(){
    progress=0;wave=1;activeOrder='FORM UP';selectedId=null;events=[];commandQueue=[];debris=[];particles=[];convoyX=.12;elapsed=0;nextHazardAt=1.4;nextAdvisoryAt=4;
    drones=[];
    for(var i=0;i<12;i++)drones.push({id:i+1,name:'D-'+String(i+1).padStart(2,'0'),group:GROUPS[Math.floor(i/4)],x:.20+(i%4)*.035,y:.32+Math.floor(i/4)*.18+(i%2)*.025,vx:0,vy:0,owner:'AI',epoch:1,task:'ESCORT',status:'ACTIVE',hp:100,recover:0,pulse:0,hit:0});
    addEvent('MISSION','CONTROL','Swarm registry initialized: 12 independent tasks');
    addEvent('ORDER','AI COMMAND','FORM UP issued to 12 AI-held drones');
    spawnWave(1);updateAllUI();
  }
  function resize(){
    var r=canvas.getBoundingClientRect();dpr=Math.min(window.devicePixelRatio||1,2);canvas.width=Math.max(1,Math.floor(r.width*dpr));canvas.height=Math.max(1,Math.floor(r.height*dpr));canvasW=r.width;canvasH=r.height;ctx.setTransform(dpr,0,0,dpr,0,0)
  }
  window.addEventListener('resize',resize);

  function spawnWave(n){
    var amount=5+n*2;
    for(var i=0;i<amount;i++)debris.push({id:++uid,x:.52+Math.random()*.44,y:.16+Math.random()*.69,r:.013+Math.random()*.014,hp:45+n*14,max:45+n*14,vx:-(.003+n*.0008)*(0.6+Math.random()*.8),vy:(Math.random()-.5)*.005,spin:(Math.random()-.5)*2,angle:Math.random()*6.28});
    addEvent('WAVE','FIELD','Wave '+n+' entered with '+amount+' tracked hazards');
  }
  function issueOrder(order){
    if(!running)return;
    activeOrder=order;var ai=drones.filter(function(d){return d.owner==='AI'&&d.status==='ACTIVE'});var held=drones.filter(function(d){return d.owner==='HUMAN'&&d.status==='ACTIVE'});
    ai.forEach(function(d){d.task=order;commandQueue.push({id:++uid,drone:d.id,epoch:d.epoch,order:order,at:elapsed+.08+Math.random()*.25})});
    addEvent('ORDER','HUMAN COMMAND',order+' issued to '+ai.length+' AI-held drones; '+held.length+' human-held excluded');
    document.getElementById('orderNote').textContent=held.length?held.length+' human-held drone'+(held.length===1?' is':'s are')+' visibly excluded from '+order+'.':'Order routed to all active AI-held drones.';
    updateAllUI();
  }
  function claimDrone(id){
    if(!running)return;var d=drones.find(function(x){return x.id===id});if(!d||d.status!=='ACTIVE')return;
    selectedId=id;
    if(d.owner!=='HUMAN'){
      var oldEpoch=d.epoch;d.owner='HUMAN';d.epoch++;d.task='DIRECT';d.vx=0;d.vy=0;
      addEvent('TAKEOVER',d.name,'Human claimed task; epoch '+oldEpoch+' → '+d.epoch+'; '+d.group+' AI yielded instantly');
    }
    updateAllUI();
  }
  function releaseSelected(){
    var d=drones.find(function(x){return x.id===selectedId});if(!d||d.owner!=='HUMAN'||d.status!=='ACTIVE')return;
    d.owner='AI';d.epoch++;d.task='HANDOFF';d.vx=0;d.vy=0;addEvent('HANDOFF',d.name,'Safe release accepted; AI resumes at epoch '+d.epoch);selectedId=null;setTimeout(function(){if(d.owner==='AI'&&d.status==='ACTIVE')d.task=activeOrder;updateAllUI()},450);updateAllUI();
