<!-- SOLID CITY · part 2132 -->
    br.rotation.y=-Math.atan2(built[j2].z-built[i].z,built[j2].x-built[i].x);
        root.add(br);
        bridges++;
        break;
      }
    }
  }

  // ---- THE HYPER SPIRE (460m) at plaza north edge ----
  var spire=new T.Group();spire.position.set(0,0,-58);
  var sh=460;
  var s1=new T.Mesh(new T.CylinderGeometry(14,26,sh*0.7,12),glassA);s1.position.y=sh*0.35;spire.add(s1);
  var s2=new T.Mesh(new T.CylinderGeometry(8,14,sh*0.22,12),glassB);s2.position.set(0,sh*0.7+sh*0.11,0);spire.add(s2);
  var s3=new T.Mesh(new T.CylinderGeometry(0.8,6,sh*0.08+30,8),gold);s3.position.set(0,sh*0.92+sh*0.04+10,0);spire.add(s3);
  // gold crown rings
  [0.55,0.7,0.82].forEach(function(f){
    var r=new T.Mesh(new T.TorusGeometry(20*(1-f*0.4)+8,1.8,8,32),goldTrim);
    r.rotation.x=Math.PI/2;r.position.y=sh*f;spire.add(r);
  });
  // beacon
  var beacon=new T.Mesh(new T.SphereGeometry(3.2,12,10),new T.MeshBasicMaterial({color:0xffe8a0}));
  beacon.position.y=sh+32;beacon.name='beacon';spire.add(beacon);
  var beam=new T.Mesh(new T.CylinderGeometry(1.2,2.2,120,8,1,true),
    new T.MeshBasicMaterial({color:0xffe8a0,transparent:true,opacity:0.28,side:T.DoubleSide,depthWrite:false}));
  beam.position.y=sh+92;beam.name='beam';spire.add(beam);
  root.add(spire);
  foot.push([0,-58,56,56,36,sh+34+36,0]);
  // Spire interior podium: 70m dia cylinder, 95m tall, full interior + observatory
  spire.position.y=36; // lift spire onto podium (now 496m total — bigger, as the King loves)
  buildInteriorPodium(T,root,foot,elevators,standFloors,Object.assign({},podiumOpts,{
    x:0,z:-58,w:70,d:70,h:36,cyl:true,floors:[0,18,32],
    name:'THE SPIRE LOBBY'
  }));
  var smark=quietMarker(T,'THE HYPER SPIRE');smark.position.set(24,0,-58);root.add(smark);


  // ---- PORTHOLES: the upper facades become portal arrays ----
  // (King: "the rest will be port holes aka portals")
  (function(){
    var pm = new T.MeshBasicMaterial({ map: null, transparent: true, side: T.DoubleSide });
    // Build a shared porthole texture once
    var pc = document.createElement('canvas'); pc.width = pc.height = 128;
    var px = pc.getContext('2d');
    var pgr = px.createRadialGradient(64,64,4,64,64,64);
    pgr.addColorStop(0,'#fff8e8'); pgr.addColorStop(0.25,'#f2c86a');
    pgr.addColorStop(0.5,'#9a6ae8'); pgr.addColorStop(0.75,'#4a6ae8'); pgr.addColorStop(1,'#1a1a3a');
    px.fillStyle = pgr; px.beginPath(); px.arc(64,64,64,0,7); px.fill();
    px.strokeStyle = '#f2c86a'; px.lineWidth = 3;
    for (var pr = 12; pr < 64; pr += 13) { px.beginPath(); px.arc(64,64,pr,0,7); px.stroke(); }
    var ptex = new T.CanvasTexture(pc); ptex.encoding = T.sRGBEncoding;
    var pmat = new T.MeshBasicMaterial({ map: ptex, transparent: true, side: T.DoubleSide });
    window._hyperPortholes = [];
    // Portholes on the 2 podium towers (above podium, every 25m)
    [pickA, pickB].forEach(function(tb){
      if(!tb) return;
      var baseY = 28; // podium top
      for (var py = baseY+18; py < baseY+tb.h; py += 26) {
        for (var f = 0; f < 4; f++) {
          var ang = f*Math.PI/2;
          var rad = tb.w*0.62;
          var hx = tb.x + Math.cos(ang)*rad, hz = tb.z + Math.sin(ang)*rad;
          var hole = new T.Mesh(new T.CircleGeometry(3.2, 20), pmat);
          hole.position.set(hx, py, hz);
          hole.rotation.y = -ang + Math.PI/2;
          // face outward
          hole.lookAt(hx*2-tb.x, py, hz*2-tb.z);
          root.add(hole);
          window._hyperPortholes.push(hole);
        }
      }
    });
    // Portholes on spire upper cylinders (every 30m from y=120 to 480)
    for (var sy = 130; sy < 480; sy += 32) {
      for (var sf = 0; sf < 6; sf++) {
        var sa = sf*Math.PI/3;
        var sr = 20 - (sy/480)*10; // taper
        var shx = Math.cos(sa)*sr, shz = -58 + Math.sin(sa)*sr;
        var shole = new T.Mesh(new T.CircleGeometry(2.8, 20), pmat);
        shole.position.set(shx, sy, shz);
        shole.lookAt(shx*2, sy, shz*2+58);
        root.add(shole);
        window._hyperPortholes.push(shole);
      }
    }
    // Portholes on all other towers (every 30m, 2 per face)
    built.forEach(function(tb){
      if(tb===pickA||tb===pickB) return;
      for (var py2 = 40; py2 < tb.h; py2 += 34) {
        for (var f2 = 0; f2 < 4; f2++) {
          var ang2 = f2*Math.PI/2 + 0.4;
          var rad2 = tb.w*0.6;
          var hx2 = tb.x + Math.cos(ang2)*rad2, hz2 = tb.z + Math.sin(ang2)*rad2;
          var hole2 = new T.Mesh(new T.CircleGeometry(2.6, 20), pmat);
          hole2.position.set(hx2, py2, hz2);
          hole2.lookAt(hx2*2-tb.x, py2, hz2*2-tb.z);
          root.add(hole2);
          window._hyperPortholes.push(hole2);
        }
      }
    });
  })();

  // ---- central plaza: fountain ----
  var plaza=new T.Mesh(new T.CylinderGeometry(42,44,0.8,40),new T.MeshLambertMaterial({color:0x363c46}));
  plaza.position.y=0.5;root.add(plaza);
  var basin=new T.Mesh(new T.CylinderGeometry(12,14,2.4,24),steel);basin.position