<!-- SOLID CITY · part 2112 -->
  for (var cl=0; cl<ch; cl++) box(1.9,1.4,1.9,crateM, px3,2.6+cl*1.5,pz3);
    solid(px3,pz3,2.2,2.2,0,2+ch*1.5);
  }
  var ropeM = new T.MeshLambertMaterial({color: 0xa88a5a});
  [[-535,-70],[-515,60]].forEach(function(rp2){
    var coil = new T.Mesh(new T.TorusGeometry(1.2,0.45,8,18), ropeM);
    coil.position.set(rp2[0],2.1,rp2[1]); coil.rotation.x = Math.PI/2;
    root.add(coil);
    solid(rp2[0],rp2[1],2.4,2.4,0,2.5);
  });

  // harbor sign
  var hs = new T.Mesh(new T.PlaneGeometry(10,2.5),
    new T.MeshBasicMaterial({map: BM.sign('THE HARBOR')}));
  hs.position.set(-472,6,0); hs.rotation.y = Math.PI/2; root.add(hs);
}

/* COMPACT PODIUM — Phase 2 "GO FOR LAUNCH" (2026-10-11)
 * The King's law: 2 real floors, then portholes.
 * 36x36 (or w×d), 24m tall: lobby (0-10) + floor 2 offices (12) + roof deck (22).
 * 1 rideable elevator (internal shaft, south-open). All collision solid.
 */
function buildCompactPodium(T, root, foot, elevators, standFloors, o) {
  var glassA = o.glassA, gold = o.gold, steel = o.steel;
  var wallM = new T.MeshLambertMaterial({ color: 0x3a4048 });
  var floorM = new T.MeshLambertMaterial({ color: 0x4a5058 });
  var deskM = new T.MeshLambertMaterial({ color: 0x6a5a40 });
  var partM = new T.MeshLambertMaterial({ color: 0x8a8a90 });
  var ceilM = new T.MeshLambertMaterial({ color: 0x2a2e34 });
  var g = new T.Group();
  g.position.set(o.x, 0, o.z);
  var W = o.w || 36, D = o.d || 36, H = o.h || 24;
  var lobbyH = 10, f2y = 12, roofY = 22;
  var doorW = 6, t = 0.7;
  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(cx, cz, w, d, y0, y1) {
    foot.push([o.x + cx, o.z + cz, w, d, y0, y1, 0]);
  }
  // ---- walls (south has door gap at lobby level) ----
  box(W, H, t, glassA, 0, H / 2, -D / 2); solid(0, -D / 2, W, t, 0, H);
  var segW = (W - doorW) / 2;
  box(segW, lobbyH, t, glassA, -(doorW / 2 + segW / 2), lobbyH / 2, D / 2);
  box(segW, lobbyH, t, glassA, (doorW / 2 + segW / 2), lobbyH / 2, D / 2);
  solid(-(doorW / 2 + segW / 2), D / 2, segW, t, 0, lobbyH);
  solid((doorW / 2 + segW / 2), D / 2, segW, t, 0, lobbyH);
  box(W, H - lobbyH, t, glassA, 0, lobbyH + (H - lobbyH) / 2, D / 2); solid(0, D / 2, W, t, lobbyH, H);
  box(t, H, D, glassA, W / 2, H / 2, 0); solid(W / 2, 0, t, D, 0, H);
  box(t, H, D, glassA, -W / 2, H / 2, 0); solid(-W / 2, 0, t, D, 0, H);
  // gold door frame
  box(doorW + 0.8, 0.8, t + 0.3, gold, 0, lobbyH - 0.4, D / 2);
  box(0.5, lobbyH, t + 0.3, gold, -doorW / 2, lobbyH / 2, D / 2);
  box(0.5, lobbyH, t + 0.3, gold, doorW / 2, lobbyH / 2, D / 2);
  // ---- lobby ----
  var cx = W / 2 - 7, cz = D / 2 - 7;
  [[-cx, -cz], [cx, -cz], [-cx, cz], [cx, cz]].forEach(function (p) {
    var c = new T.Mesh(new T.CylinderGeometry(0.7, 0.9, lobbyH, 8), gold);
    c.position.set(p[0], lobbyH / 2, p[1]); g.add(c);
    solid(p[0], p[1], 1.8, 1.8, 0, lobbyH);
  });
  box(7, 1.1, 2, deskM, 9, 0.55, -9); solid(9, -9, 7, 2, 0, 1.1); // reception desk (east)
  box(3.5, 0.7, 1.2, deskM, -9, 0.35, 6); solid(-9, 6, 3.5, 1.2, 0, 0.7);
  box(3.5, 0.7, 1.2, deskM, 0, 0.35, 8); solid(0, 8, 3.5, 1.2, 0, 0.7);
  box(W, 0.8, D, ceilM, 0, lobbyH + 0.4, 0);
  var plq = new T.Mesh(new T.PlaneGeometry(7, 1.75),
    new T.MeshBasicMaterial({ map: textPlate(T, o.name), side: T.DoubleSide }));
  plq.position.set(0, 5.5, D / 2 - 1); plq.rotation.y = Math.PI; g.add(plq);
  // ---- elevator: 1 shaft at north-center, south open ----
  var sx = 0, sz = -D / 2 + 6, sw = 7;
  box(sw, H, 0.6, wallM, sx, H / 2, sz - sw / 2); solid(sx, sz - sw / 2, sw, 0.6, 0, H);
  box(0.6, H, sw, wallM, sx - sw / 2, H / 2, sz); solid(sx - sw / 2, sz, 0.6, sw, 0, H);
  box(0.6, H, sw, wallM, sx + sw / 2, H / 2, sz); solid(sx + sw / 2, sz, 0.6, sw, 0, H);
  var cab = box(6, 3.5, 6, steel, sx, 1.75, sz);
  cab.name = 'elevcab';
  elevators.push({
    cab: cab, x: o.x + sx, z: o.z + sz, floors: [0, f2y, roofY],
    idx: 0, moving: false, t: 0, from: 0, to: 0,
    names: ['LOBBY', 'FLOOR 2', 'ROOF DECK']
  });
  // ---- floor 2: slab with shaft opening ----
  var shZ0 = -D / 2 + 2.5, shZ1 = -D / 2 + 9.5, shX0 = sx - 3.5, shX1 = sx + 3.5;
  var sD = D / 2 - shZ1, sZ = (shZ1 + D / 2) / 2;
  box(W, 1, sD, floorM, 0, f2y - 0.5, sZ);
  var nD = shZ1 + D / 2, nZ = (shZ1 - D / 2) / 2;
  var nwW = shX0 + W / 2, nwX = (-W / 2 + shX0) / 2;
  box(nwW, 1, nD, floorM, nwX, f2y - 0.5, nZ);
  var neW = W / 2 - shX1, neX = (shX1 + W / 2) / 2;
  box(neW, 1, nD, floorM, neX, f2y - 0.5, nZ);
  standFloors.push({ x0: o.x - W / 2, x1: o.x + W / 2, z0: o.z - D / 2, z1: o.z + D / 2, y: f2y });
  // 4 offices (clear of the north-center shaft)
  [[-9, 9], [9, 9], [-9, -5], [9, -5]].forEach(function (op) {
    var ox = op[0], oz = op[1];
    box(10, 2.8, 0.35, partM, ox, f2y + 1.4, oz - 5); solid(ox, oz - 5, 10, 0.35, f2y, f2y + 2.8);
    box(0.35, 2.8, 10, partM, ox - 5, f2y + 1.4, oz); solid(ox - 5, 