<!-- SOLID CITY · part 2144 -->
     var w3=w2/PHI,d3=d2/PHI,h3=h*0.15;
      var b3=new T.Mesh(new T.BoxGeometry(w3,h3,d3),gold);b3.position.set(0,h1+h2+h3/2,0);g.add(b3);
      foot.push([x,z,Math.max(w1,d1),Math.max(w1,d1),0,h,0]);
    }else if(type===2){ // twisted: 5 rotated segments
      var seg=h/5;
      for(var k=0;k<5;k++){
        var sw=w*(1-k*0.09),sd=d*(1-k*0.09);
        var sg=new T.Mesh(new T.BoxGeometry(sw,seg,sd),mat);
        sg.position.y=seg*(k+0.5);sg.rotation.y=k*0.16;g.add(sg);
      }
      var cap=new T.Mesh(new T.BoxGeometry(w*0.5,4,d*0.5),gold);
      cap.position.y=h+2;g.add(cap);
      foot.push([x,z,w*1.15,w*1.15,0,h+4,0]);
    }else{ // crown: tower + glowing crown ring + spire
      var bd=new T.Mesh(new T.BoxGeometry(w,h*0.82,d),mat);bd.position.y=h*0.41;g.add(bd);
      var ring=new T.Mesh(new T.TorusGeometry(Math.max(w,d)*0.42,1.6,8,24),goldTrim);
      ring.rotation.x=Math.PI/2;ring.position.y=h*0.86;g.add(ring);
      var sp=new T.Mesh(new T.CylinderGeometry(1,3,h*0.18,6),steel);
      sp.position.y=h*0.91+h*0.09;g.add(sp);
      foot.push([x,z,Math.max(w,d),Math.max(w,d),0,h,0]);
    }
    root.add(g);
    return {x:x,z:z,h:h,w:Math.max(w,d),g:g,tp:type};
  }
  var built=[];
  var types=[0,1,2,3];
  for(i=0;i<spots.length;i++){
    var h=150+R()*250; // 150-400m
    var tp=types[i%4];
    // taller near center: scale by proximity
    var dc=Math.hypot(spots[i][0],spots[i][1]);
    if(dc<120)h=Math.min(400,h+60);
    built.push(tower(spots[i][0],spots[i][1],h,tp));
  }
  // ---- INTERIOR PODIUMS (Phase 1): 2 towers + spire get REAL interiors ----
  var elevators=[], standFloors=[];
  var podiumOpts={ R:R, glassA:glassA, glassB:glassB, gold:gold, steel:steel, textPlate:textPlate };
  // Pick: first slab (type1) and first crown (type3) for box podiums
  var pickA=null, pickB=null;
  for(var pi=0;pi<built.length;pi++){
    if(!pickA&&built[pi].tp===1)pickA=built[pi];
    if(!pickB&&built[pi].tp===3)pickB=built[pi];
  }
  [pickA,pickB].forEach(function(tb,idx){
    if(!tb)return;
    tb.g.position.y=28; // lift tower onto podium
    // fix footprint: was [x,z,w,d,0,h,0], now starts at 60
    for(var fi=0;fi<foot.length;fi++){
      if(Math.abs(foot[fi][0]-tb.x)<1&&Math.abs(foot[fi][1]-tb.z)<1&&foot[fi][4]===0){
        foot[fi][4]=28; break;
      }
    }
    buildInteriorPodium(T,root,foot,elevators,standFloors,Object.assign({},podiumOpts,{
      x:tb.x,z:tb.z,w:50,d:50,h:28,floors:[0,14,26],
      name:idx===0?'TOWER ONE LOBBY':'TOWER TWO LOBBY'
    }));
  });
  // skybridges: connect 4 pairs at ~60% height
  var bridges=0;
  for(i=0;i<built.length&&bridges<4;i++){
    for(var j2=i+1;j2<built.length;j2++){
      var dd=Math.hypot(built[i].x-built[j2].x,built[i].z-built[j2].z);
      if(dd>55&&dd<95){
        var by=Math.min(built[i].h,built[j2].h)*0.62;
        var mx=(built[i].x+built[j2].x)/2, mz=(built[i].z+built[j2].z)/2;
        var bl=Math.hypot(built[i].x-built[j2].x,built[i].z-built[j2].z);
        var br=new T.Mesh(new T.BoxGeometry(bl,5,7),glassB);
        br.position.set(mx,by,mz);
        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