<!-- SOLID CITY · part 2114 -->
var pole2=new T.Mesh(lampG,lampM);pole2.position.set(x,4.5,lz);root.add(pole2);
      var bulb2=new T.Mesh(new T.SphereGeometry(0.7,8,6),bulbM);bulb2.position.set(x,9.2,lz);root.add(bulb2);
      foot.push([x,lz,1,1,0,9,0]);
    });
  }
  // planters
  var planterM=new T.MeshLambertMaterial({color:0x3a3226});
  var leafM=new T.MeshLambertMaterial({color:0x2e6a34});
  for(i=0;i<16;i++){
    var px=-180+R()*360, pz=-160+R()*320;
    if(Math.abs(px)<30&&Math.abs(pz)<30)continue;
    if(px<-150)continue; // not on promenade
    var pl=new T.Mesh(new T.BoxGeometry(4,2,4),planterM);pl.position.set(px,1,pz);root.add(pl);
    var lf=new T.Mesh(new T.SphereGeometry(2.2,8,6),leafM);lf.position.set(px,3.4,pz);root.add(lf);
    foot.push([px,pz,4,4,0,2,0]);
  }

  // ---- THE 24 MEGATOWERS ----
  // jittered grid positions, avoiding plaza (r<45) and promenade (x<-150)
  var spots=[];
  var gx,gz,tries=0;
  while(spots.length<24&&tries<400){
    tries++;
    gx=-190+R()*380; gz=-170+R()*340;
    if(Math.hypot(gx,gz)<55)continue;          // plaza
    if(gx<-150)continue;                        // promenade
    var ok=true;
    for(var s=0;s<spots.length;s++){ if(Math.hypot(gx-spots[s][0],gz-spots[s][1])<52){ok=false;break;} }
    if(ok)spots.push([gx,gz]);
  }
  function tower(x,z,h,type){
    var g=new T.Group();g.position.set(x,0,z);
    var w=18+R()*22, d=18+R()*22;
    var mat=R()<0.5?glassA:glassB;
    if(type===0){ // needle: tapered
      var nd=new T.Mesh(new T.CylinderGeometry(w*0.28,w*0.55,h,8),mat);
      nd.position.y=h/2;g.add(nd);
      var tip=new T.Mesh(new T.CylinderGeometry(0.8,2.5,26,6),gold);
      tip.position.y=h+13;g.add(tip);
      foot.push([x,z,w*1.2,w*1.2,0,h+26,0]);
    }else if(type===1){ // slab with golden-ratio setbacks
      var w1=w,d1=d,h1=h*0.55;
      var b1=new T.Mesh(new T.BoxGeometry(w1,h1,d1),mat);b1.position.y=h1/2;g.add(b1);
      var w2=w1/PHI,d2=d1/PHI,h2=h*0.3;
      var b2=new T.Mesh(new T.BoxGeometry(w2,h2,d2),mat);b2.position.set(0,h1+h2/2,0);g.add(b2);
      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'
    }));
  });
  pickA.lift=28; pickB.lift=28;
  // ---- PHASE 2 (GO FOR LAUNCH): every remaining tower gets 2 real floors ----
  // The King's words: "Hyper city go for launch." 2 real floors, then portholes.
  var P2_LIFT = 24;
  var p2gates = [];
  var p2special = { 0:{w:34,ox:0,oz:-16}, 5:{w:36,ox:0,oz:0}, 18:{w:36,ox:-5,oz:11} };
  built.forEach(function(tb, idx){
    if (tb===pickA || tb===pickB) return;
    if (idx===7) { p2gates.push(