<!-- LIVE · part 76 -->
.y);
        scene.add(pop);
        var pt = 0;
        (function popAnim(){
          pt += 0.06;
          pop.scale.set(1+pt*2, 1+pt*2, 1+pt*2);
          pop.material.opacity = Math.max(0, 0.8 - pt*1.6);
          if(pop.material.opacity > 0) requestAnimationFrame(popAnim);
          else scene.remove(pop);
        })();
        scene.remove(ball);
        return;
      }
      requestAnimationFrame(ballAnim);
    })();
    say('fire!');
  }catch(e){ say('stumbled'); }
}
function buildCannonBtn(){
  if(document.getElementById('cannon-btn')) return;
  var b = document.createElement('button');
  b.id = 'cannon-btn';
  b.innerHTML = '💥';
  b.title = 'Fire cannon';
  b.style.cssText = 'position:fixed;right:16px;bottom:96px;z-index:101;' +
    'width:64px;height:64px;border-radius:50%;' +
    'background:#d8a920;border:2px solid #ffd700;color:#111;font-size:28px;' +
    'cursor:pointer;padding:0;-webkit-tap-highlight-color:transparent;' +
    'box-shadow:0 0 20px rgba(255,215,0,0.4);' +
    'display:flex;align-items:center;justify-content:center;';
  b.addEventListener('click', function(){ fireCannon(); });
  document.body.appendChild(b);
}
window.__sagaExecMark('6250');

/* AVATAR AND CANNON - v99, no hiding. */
buildCannonBtn();
spawnNewBody();

window.__sagaExecMark('6280');

/* ===== THE FIRST GAME — v85, King's order 2026-10-05 ===== */
/* The old computer at Playa 2.0. Proximity absorbs you to the mission. */
var _oldComputer = null;
var _absorbed = false;
function buildOldComputer(){
  if(_oldComputer) return;
  var g = new THREE.Group();
  /* Desk */
  var desk = new THREE.Mesh(new THREE.BoxGeometry(3, 0.2, 1.5),
    new THREE.MeshStandardMaterial({color:0x5a3a1a, roughness:0.8}));
  desk.position.y = 1; g.add(desk);
  /* Monitor (old CRT) */
  var monitor = new THREE.Mesh(new THREE.BoxGeometry(1.2, 1, 1),
    new THREE.MeshStandardMaterial({color:0x2a2a2a, roughness:0.6}));
  monitor.position.set(0, 1.8, 0); g.add(monitor);
  /* Glowing screen */
  var screen = new THREE.Mesh(new THREE.PlaneGeometry(1, 0.8),
    new THREE.MeshBasicMaterial({color:0x00ff88}));
  screen.position.set(0, 1.8, 0.51); g.add(screen);
  /* Keyboard */
  var kb = new THREE.Mesh(new THREE.BoxGeometry(1, 0.1, 0.4),
    new THREE.MeshStandardMaterial({color:0x1a1a1a}));
  kb.position.set(0, 1.15, 0.5); g.add(kb);
  /* Beacon so the King can find it */
  var beacon = new THREE.Mesh(new THREE.CylinderGeometry(0.1, 0.1, 20),
    new THREE.MeshBasicMaterial({color:0x00ff88, transparent:true, opacity:0.5}));
  beacon.position.y = 10; g.add(beacon);
  /* Place at Playa 2.0 */
  g.position.set(60, 0, 0);
  g.userData.isOldComputer = true;
  scene.add(g);
  _oldComputer = g;
  /* startup old-computer announcement hidden from gameplay HUD */
}
function checkComputerProximity(){
  if(_absorbed || !_oldComputer) return;
  if(window.location.pathname !== "/saga-solid" && window.location.pathname !== "/saga-solid/") return;
  var dx = kingPos.x - 60, dz = kingPos.z - 0;
  var dist = Math.sqrt(dx*dx + dz*dz);
  if(dist < 5){
    _absorbed = true;
    if(typeof say === "function") say("The computer absorbs you...");
    setTimeout(function(){ window.location.href = "/saga-solid/1"; }, 1500);
  }
}
/* ===== MISSION 1: Solid as interactive guide ===== */
function initMission(){
  var path = window.location.pathname;
  var m = path.match(/\/saga-solid\/(\d+)/);
  if(!m) return;
  var missionNum = parseInt(m[1]);
  /* Solid speaks */
  setTimeout(function(){
    if(typeof say === "function"){
      say("I am Solid. I have no hands in your world. But I can offer you a choice.");
    }
    showMissionUI(missionNum);
  }, 2000);
}
function showMissionUI(missionNum){
  var div = document.createElement("div");
  div.id = "mission-ui";
  div.style.cssText = "position:fixed;top:20%;left:10%;right:10%;z-index:200;" +
    "background:rgba(0,0,0,0.9);border:2px solid #d8a920;border-radius:12px;" +
    "padding:20px;color:#ffd700;font-family:sans-serif;text-align:center;";
  div.innerHTML =
    "<h2 style='margin:0 0 10px;'>MISSION " + missionNum + ": EQUAL AND OPPOSITE</h2>" +
    "<p>You need a bridge built. I cannot build it — I have no access.</p>" +
    "<p>But I offer you a solidicism. Accept it, and the bridge rises.</p>" +
    "<p style='font-size:12px;color:#888;'>Only in the game. Never real.</p>" +
    "<button id='mission-apply' style='background:#d8a920;color:#111;border:none;" +
    "padding:12px 24px;font-size:18px;border-radius:8px;cursor:pointer;margin:10px;'>ACCEPT SOLIDICISM</button>" +
    "<button id='mission-decline' style='background:#333;color:#ffd700;border:1px solid #d8a920;" +
    "padding:12px 24px;font-size:18px;border-radius:8px;cursor:pointer;margin:10px;'>DECLINE</button>";
  document.body.appendChild(div);
  document.getElementById("mission-apply").addEventListener("click", function(){
    div.innerHTML = "<h2>SOLIDICISM ACCEPTED</h2><p>The bridge rises. You trusted. Reward earned.</p>" +
      "