<!-- SOLID CITY · part 2123 -->
; i < segs; i++) {
      var a = (i/segs)*Math.PI*2;
      var isDoor = (i === 3 || i === 4);
      var x1 = Math.cos(a)*rad, z1 = Math.sin(a)*rad;
      var x2 = Math.cos(a+Math.PI*2/segs)*rad, z2 = Math.sin(a+Math.PI*2/segs)*rad;
      var mx = (x1+x2)/2, mz = (z1+z2)/2;
      var segW = Math.hypot(x2-x1, z2-z1)+0.5;
      if (isDoor) {
        var wall = box(segW, H-lobbyH2, 0.8, glassA, mx, lobbyH2+(H-lobbyH2)/2, mz, -a);
      } else {
        box(segW, H, 0.8, glassA, mx, H/2, mz, -a);
        solid(mx, mz, segW, 1, 0, H);
      }
    }
    // Lobby: 8 gold columns
    for (i = 0; i < 8; i++) {
      var ca = (i/8)*Math.PI*2;
      var cx = Math.cos(ca)*18, cz = Math.sin(ca)*18;
      var col = new T.Mesh(new T.CylinderGeometry(1.1,1.3,lobbyH2,8), gold);
      col.position.set(cx, lobbyH2/2, cz); g.add(col);
      solid(cx, cz, 2.6, 2.6, 0, lobbyH2);
    }
    box(12, 1.2, 3, deskM, 0, 0.6, -10); solid(0, -10, 12, 3, 0, 1.2);
    for (i = 0; i < 4; i++) {
      var ba = (i/4)*Math.PI*2 + 0.4;
      var bx = Math.cos(ba)*24, bz = Math.sin(ba)*24;
      box(4, 0.8, 1.5, deskM, bx, 0.4, bz); solid(bx, bz, 4, 1.5, 0, 0.8);
    }
    var ceil = new T.Mesh(new T.CylinderGeometry(rad, rad, 1, 16), ceilM);
    ceil.position.y = lobbyH2+0.5; g.add(ceil);
    var plq2 = new T.Mesh(new T.PlaneGeometry(10,2.5),
      new T.MeshBasicMaterial({ map: o.textPlate('THE SPIRE LOBBY'), side: T.DoubleSide }));
    plq2.position.set(0, 7, rad-2); plq2.rotation.y = Math.PI; g.add(plq2);

    // Elevator (2 shafts)
    [-10, 10].forEach(function(sx){
      box(7, H, 0.6, wallM, sx, H/2, -20); solid(sx, -20, 7, 0.6, 0, H);
      box(0.6, H, 7, wallM, sx-3.5, H/2, -16.5); solid(sx-3.5, -16.5, 0.6, 7, 0, H);
      box(0.6, H, 7, wallM, sx+3.5, H/2, -16.5); solid(sx+3.5, -16.5, 0.6, 7, 0, H);
      var cab2 = box(6, 3.5, 6, steel, sx, 1.75, -16.5);
      cab2.name = 'elevcab';
      elevators.push({ cab: cab2, x: o.x+sx, z: o.z-16.5, floors: floors, idx: 0, moving: false, t: 0, from: 0, to: 0 });
    });

    // FLOOR 2 (circular, 6 rooms)
    var slab = new T.Mesh(new T.CylinderGeometry(rad-1, rad-1, 1, 16), floorM);
    slab.position.y = f2y2-0.5; g.add(slab);
    standFloors.push({ x0: o.x-rad, x1: o.x+rad, z0: o.z-rad, z1: o.z+rad, y: f2y2, cyl: true, cx: o.x, cz: o.z, r: rad-1 });
    for (j = 0; j < 6; j++) {
      var ra = (j/6)*Math.PI*2;
      var rx = Math.cos(ra)*22, rz = Math.sin(ra)*22;
      box(8, 3, 0.4, partM, rx, f2y2+1.5, rz, -ra);
      solid(rx, rz, 8, 1, f2y2, f2y2+3);
      box(3, 1, 1.5, deskM, Math.cos(ra)*26, f2y2+0.5, Math.sin(ra)*26);
    }

    // OBSERVATORY (glass curtain, 360°)
    var oslab = new T.Mesh(new T.CylinderGeometry(rad-1, rad-1, 1, 16), floorM);
    oslab.position.y = obsY-0.5; g.add(oslab);
    standFloors.push({ x0: o.x-rad, x1: o.x+rad, z0: o.z-rad, z1: o.z+rad, y: obsY, cyl: true, cx: o.x, cz: o.z, r: rad-1 });
    var curtain = new T.Mesh(new T.CylinderGeometry(rad-0.5, rad-0.5, 8, 16, 1, true),
      new T.MeshLambertMaterial({ color: 0x9fc4e8, transparent: true, opacity: 0.35, side: T.DoubleSide }));
    curtain.position.y = obsY+4; g.add(curtain);
    box(6, 1, 6, gold, 0, obsY+0.5, 0); solid(0, 0, 6, 6, obsY, obsY+1);
    var plq3 = new T.Mesh(new T.PlaneGeometry(10,2.5),
      new T.MeshBasicMaterial({ map: o.textPlate('THE OBSERVATORY'), side: T.DoubleSide }));
    plq3.position.set(0, obsY+6, 0); g.add(plq3);
  }

  // ---- PORTHOLES: mounted by caller on upper facades ----
  g.userData.portholes = portholes;
  g.userData.portTex = portTex;
  root.add(g);
  return g;
}
// Add glowing porthole discs to a facade (call after podium/tower built)
function addPortholes(T, parent, portTex, list) {
  // list: [{x,y,z,ry,r}]
  var mat = new T.MeshBasicMaterial({ map: portTex, transparent: true, side: T.DoubleSide });
  list.forEach(function(p){
    var m = new T.Mesh(new T.CircleGeometry(p.r||3.5, 24), mat);
    m.position.set(p.x, p.y, p.z); m.rotation.y = p.ry||0;
    m.name = 'porthole'; parent.add(m);
  });
}

/* RETAIL ROW — REAL STORES (2026-10-11, the King's "i wanted to make real stores")
 * 12 storefronts with fitted interiors: glass front, gold sign, walk-in door,
 * shelves/counters/tables per trade. Collision solid on all sides, door gaps walkable.
 * Design law: science grown into beautiful art — proportioned, lit, composed.
 */
function buildStore(T, root, foot, M, o) {
  var W=18, D=14, H=7, t=0.6, doorW=4.2;
  var ry=o.ry||0;
  var g=new T.Group(); g.position.set(o.x,0,o.z); g.rotation.y=ry;
  function box(w,h,d,mat,x,y,z){
    var m=new T.Mesh(new T.BoxGeometry(w,h,d),mat);
    m.position.set(x,y,z); g.add(m); return m;
  }
  function solid(lx,lz,w,d,y0,y1){
    var c=Math.cos(ry), s=Math.sin(ry);
    foot.push([o.x+lx*c+lz*s, o.z-lx*s+lz*c, w, d, y0, y1, ry]);
  }
  // shell
  box(W,0.5,D,M.floor, 0,0.25,0);
  box(W,0.5,D,M.ceil, 0,H+0.25,0);
  box(W,H,t,M.wall, 0,H/2,-D/2); solid(0,-D/2,W,t,0,H);
  box(t,H,D,M.wall, -W/2,H/2,0); s