<!-- SOLID CITY · part 2135 -->
w, h, d), mat);
    m.position.set(x, y, z); if (ry) m.rotation.y = ry;
    g.add(m); return m;
  }
  function solid(cx, cz, w, d, y0, y1) {
    foot.push([o.x + cx, o.z + cz, w, d, y0, y1, 0]);
  }
  // Porthole texture: swirling gold/violet/blue (wormhole language)
  function portholeTex() {
    var c = document.createElement('canvas'); c.width = c.height = 128;
    var ctx = c.getContext('2d');
    var gr = ctx.createRadialGradient(64,64,4,64,64,64);
    gr.addColorStop(0, '#fff8e8'); gr.addColorStop(0.25, '#f2c86a');
    gr.addColorStop(0.5, '#9a6ae8'); gr.addColorStop(0.75, '#4a6ae8');
    gr.addColorStop(1, '#1a1a3a');
    ctx.fillStyle = gr; ctx.beginPath(); ctx.arc(64,64,64,0,7); ctx.fill();
    ctx.strokeStyle = '#f2c86a'; ctx.lineWidth = 3;
    for (var r = 12; r < 64; r += 13) { ctx.beginPath(); ctx.arc(64,64,r,0,7); ctx.stroke(); }
    var t = new T.CanvasTexture(c); t.encoding = T.sRGBEncoding; return t;
  }
  var portTex = portholeTex();
  var portholes = [];

  if (!isCyl) {
    // ============ BOX PODIUM ============
    var t = 0.8, lobbyH = 12, f2y = floors[1], roofY = floors[2];
    var doorW = 8;
    // Facade walls
    box(W, H, t, glassA, 0, H/2, -D/2); solid(0, -D/2, W, t, 0, H); // north
    box((W-doorW)/2, lobbyH, t, glassA, -(doorW/2+(W-doorW)/4), lobbyH/2, D/2); // south L (door gap)
    box((W-doorW)/2, lobbyH, t, glassA, (doorW/2+(W-doorW)/4), lobbyH/2, D/2); // south R (door gap)
    solid(-(doorW/2+(W-doorW)/4), D/2, (W-doorW)/2, t, 0, lobbyH);
    solid((doorW/2+(W-doorW)/4), D/2, (W-doorW)/2, t, 0, lobbyH);
    box(W, H-lobbyH, t, glassA, 0, lobbyH+(H-lobbyH)/2, D/2); solid(0, D/2, W, t, lobbyH, H); // south upper
    box(t, H, D, glassA, W/2, H/2, 0); solid(W/2, 0, t, D, 0, H); // east
    box(t, H, D, glassA, -W/2, H/2, 0); solid(-W/2, 0, t, D, 0, H); // west
    // Gold door frame
    box(doorW+1, 1, t+0.4, gold, 0, lobbyH-0.5, D/2);
    box(0.6, lobbyH, t+0.4, gold, -doorW/2, lobbyH/2, D/2);
    box(0.6, lobbyH, t+0.4, gold, doorW/2, lobbyH/2, D/2);

    // LOBBY
    [[-12,-12],[12,-12],[-12,12],[12,12]].forEach(function(p){
      var c = new T.Mesh(new T.CylinderGeometry(0.9,1.1,lobbyH,8), gold);
      c.position.set(p[0], lobbyH/2, p[1]); g.add(c);
      solid(p[0], p[1], 2.2, 2.2, 0, lobbyH);
    });
    box(10, 1.2, 2.5, deskM, 0, 0.6, -8); solid(0, -8, 10, 2.5, 0, 1.2);
    [[-10,5],[10,5]].forEach(function(p){
      box(4, 0.8, 1.5, deskM, p[0], 0.4, p[1]); solid(p[0], p[1], 4, 1.5, 0, 0.8);
    });
    box(W, 1, D, ceilM, 0, lobbyH+0.5, 0);
    var plq = new T.Mesh(new T.PlaneGeometry(8,2),
      new T.MeshBasicMaterial({ map: o.textPlate(o.name), side: T.DoubleSide }));
    plq.position.set(0, 6, D/2-1); plq.rotation.y = Math.PI; g.add(plq);

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

    // FLOOR 2 (offices) — slab with 2 elevator shaft openings
    box(W, 1, 42.7, floorM, 0, f2y-0.5, 3.65); // south of shafts (z -17.7..25)
    box(13.5, 1, 7.3, floorM, -18.25, f2y-0.5, -21.35); // NW of shafts
    box(9, 1, 7.3, floorM, 0, f2y-0.5, -21.35); // between shafts
    box(13.5, 1, 7.3, floorM, 18.25, f2y-0.5, -21.35); // NE of shafts
    standFloors.push({ x0: o.x-W/2, x1: o.x+W/2, z0: o.z-D/2, z1: o.z+D/2, y: f2y });
    for (j = 0; j < 3; j++) {
      var ox = -15 + j*15;
      // North offices
      box(12, 3, 0.4, partM, ox, f2y+1.5, -10); solid(ox, -10, 12, 0.4, f2y, f2y+3);
      box(0.4, 3, 10, partM, ox-6, f2y+1.5, -15); solid(ox-6, -15, 0.4, 10, f2y, f2y+3);
      box(0.4, 3, 10, partM, ox+6, f2y+1.5, -15); solid(ox+6, -15, 0.4, 10, f2y, f2y+3);
      box(4, 1, 2, deskM, ox, f2y+0.5, -16); solid(ox, -16, 4, 2, f2y, f2y+1);
      // South offices
      box(12, 3, 0.4, partM, ox, f2y+1.5, 10); solid(ox, 10, 12, 0.4, f2y, f2y+3);
      box(0.4, 3, 10, partM, ox-6, f2y+1.5, 15); solid(ox-6, 15, 0.4, 10, f2y, f2y+3);
      box(0.4, 3, 10, partM, ox+6, f2y+1.5, 15); solid(ox+6, 15, 0.4, 10, f2y, f2y+3);
      box(4, 1, 2, deskM, ox, f2y+0.5, 16); solid(ox, 16, 4, 2, f2y, f2y+1);
    }

    // ROOF DECK — slab with 2 elevator shaft openings
    box(W, 1, 42.7, floorM, 0, roofY-0.5, 3.65);
    box(13.5, 1, 7.3, floorM, -18.25, roofY-0.5, -21.35);
    box(9, 1, 7.3, floorM, 0, roofY-0.5, -21.35);
    box(13.5, 1, 7.3, floorM, 18.25, roofY-0.5, -21.35);
    standFloors.push({ x0: o.x-W/2, x1: o.x+W/2, z0: o.z-D/2, z1: o.z+D/2, y: roofY });
    box(W, 1.2, 0.4, steel, 0, roofY+0.6, -D/2+0.2); solid(0, -D/2+0.2, W, 0.4, roofY, roofY+1.2);
    