<!-- SOLID CITY · part 2935 -->
w',state.warningOn)}
  function finish(success){if(!state.running)return;state.running=false;els.debrief.hidden=false;els.debriefEyebrow.textContent=success?'ROUTE COMPLETE':'MISSION INTERRUPTED';els.debriefTitle.textContent=success?'Aster Gate reached.':'Rider lost before the gate.';els.scoreHull.textContent=Math.round(state.hull)+'%';els.scoreHandoffs.textContent=state.handoffs;els.scoreTime.textContent=Math.round(state.elapsed)+'s';}

  function ship(x,y,angle,color,scale){ctx.save();ctx.translate(x,y);ctx.rotate(angle);ctx.scale(scale,scale);ctx.shadowBlur=12;ctx.shadowColor=color;ctx.strokeStyle=color;ctx.fillStyle='rgba(6,16,15,.95)';ctx.lineWidth=2;ctx.beginPath();ctx.moveTo(22,0);ctx.lineTo(-12,-10);ctx.lineTo(-6,0);ctx.lineTo(-12,10);ctx.closePath();ctx.fill();ctx.stroke();ctx.beginPath();ctx.moveTo(-9,-5);ctx.lineTo(-22,-3);ctx.moveTo(-9,5);ctx.lineTo(-22,3);ctx.stroke();ctx.restore()}
  function draw(){
    ctx.setTransform(dpr,0,0,dpr,0,0);ctx.clearRect(0,0,W,H);var g=ctx.createLinearGradient(0,0,W,H);g.addColorStop(0,'#06100f');g.addColorStop(1,'#0b1d1a');ctx.fillStyle=g;ctx.fillRect(0,0,W,H);
    state.stars.forEach(function(s){s.x-=s.z*(.3+state.player.vx/160);if(s.x<0)s.x=W;ctx.fillStyle='rgba(183,231,220,'+(.2+s.z*.5)+')';ctx.fillRect(s.x,s.y,s.z*1.4,s.z*1.4)});
    ctx.strokeStyle='rgba(65,199,187,.08)';ctx.lineWidth=1;for(var i=0;i<7;i++){var yy=(i+1)*H/8;ctx.beginPath();ctx.moveTo(0,yy);ctx.lineTo(W,yy);ctx.stroke()}
    var remain=state.target-state.progress;if(remain<800){var gx=W-(remain/800)*(W*.55);ctx.save();ctx.translate(gx,H*.5);ctx.strokeStyle=colors.teal;ctx.shadowBlur=18;ctx.shadowColor=colors.teal;ctx.lineWidth=2;ctx.beginPath();ctx.ellipse(0,0,28,74,0,0,6.28);ctx.stroke();ctx.strokeStyle='rgba(67,216,207,.3)';ctx.beginPath();ctx.ellipse(0,0,46,102,0,0,6.28);ctx.stroke();ctx.restore()}
    state.rocks.forEach(function(r){ctx.save();ctx.translate(r.x,r.y);ctx.rotate(r.rot);ctx.fillStyle='#22302d';ctx.strokeStyle='#69817b';ctx.lineWidth=1;ctx.beginPath();for(var i=0;i<7;i++){var a=i/7*6.28,rr=r.r*(.77+(i%3)*.11);ctx.lineTo(Math.cos(a)*rr,Math.sin(a)*rr)}ctx.closePath();ctx.fill();ctx.stroke();ctx.restore()});
    state.enemies.forEach(function(e){ship(e.x,e.y,Math.PI,'#ff6f66',.8)});
    state.bullets.forEach(function(b){ctx.strokeStyle=colors.gold2;ctx.lineWidth=2;ctx.beginPath();ctx.moveTo(b.x,b.y);ctx.lineTo(b.x-b.vx*.025,b.y-b.vy*.025);ctx.stroke()});
    state.enemyBullets.forEach(function(b){ctx.fillStyle=colors.red;ctx.beginPath();ctx.arc(b.x,b.y,3,0,6.28);ctx.fill()});
    var mvangle=Math.atan2(state.player.vy,state.player.vx||100)*.25;ship(state.wing.x,state.wing.y,mvangle,colors.teal,.72);ship(state.player.x,state.player.y,mvangle,colors.gold,1.05);
    state.particles.forEach(function(p){ctx.globalAlpha=Math.max(0,p.life);ctx.fillStyle=p.c;ctx.fillRect(p.x,p.y,2,2)});ctx.globalAlpha=1;
    var wp=owners.weapon==='human'?input.weapon:aiWeapon();ctx.strokeStyle=owners.weapon==='human'?colors.gold:colors.teal;ctx.globalAlpha=.45;ctx.setLineDash([4,6]);ctx.beginPath();ctx.moveTo(state.player.x,state.player.y);ctx.lineTo(state.player.x+wp.x*110,state.player.y+wp.y*110);ctx.stroke();ctx.setLineDash([]);ctx.globalAlpha=1;
  }
  function loop(t){var dt=Math.min(.033,(t-last)/1000||.016);last=t;update(dt);draw();if(state.running)raf=requestAnimationFrame(loop)}
  reset();draw();
})();
</script>
</body>
</html>


===== FILE: public/city/rider/index.html.bak-deploy-20261011 =====
<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover, maximum-scale=1" />
  <meta name="color-scheme" content="light dark" />
  <link rel="icon" href="data:," />
  <link rel="preconnect" href="https://fonts.googleapis.com">
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
  <link href="https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;500;600&family=Oxanium:wght@500;600;700&display=swap" rel="stylesheet">
  <title>Double Strike: Rider System Prototype</title>
  <style>
    :root {
      color-scheme: light dark;
      --page:#edf1ef; --panel:#f8faf9; --panel-2:#e4eae7; --ink:#101716; --muted:#50605d;
      --line:#b8c4c0; --gold:#9b6800; --gold-bright:#d59b15; --teal:#007d7c; --teal-bright:#00a8a2;
      --danger:#c43c34; --ok:#1f7a51; --shadow:0 18px 48px rgba(15,29,26,.15);
      --canvas:#07100f; --canvas-ink:#eefbf7;
    }
    @media (prefers-color-scheme: dark) {
      :root {
        --page:#07100f; --panel:#0d1716; --panel-2:#132220; --ink:#eff8f5; --muted:#91a7a2;
        --line:#29413d; --gold:#f1b93b; --gold-bright:#ffd66f; --teal:#42d9d0; --teal-bright:#77fff3;
        --danger:#ff7469; --ok:#59d99b; --shadow:0 20px 64px rgba(0,0,0,.35);
      }
    }
    *{box-sizing:border-box}
    html{background:var(--page);font-family:"IBM Plex Mono",monospace}
    body{margin:0;color:var(--ink);background:
      linear-gradient(rgba