<!-- SOLID CITY · part 2103 -->
lass facade texture: daytime reflective blue-glass with window grid
function facadeTex(T, tint){
  var c=document.createElement('canvas');c.width=128;c.height=256;
  var g=c.getContext('2d');
  var gr=g.createLinearGradient(0,0,0,256);
  gr.addColorStop(0,'#9fc4e8');gr.addColorStop(0.5,'#7aa8d8');gr.addColorStop(1,'#5a88c0');
  g.fillStyle=gr;g.fillRect(0,0,128,256);
  g.fillStyle=tint||'rgba(20,40,70,0.55)';
  for(var y=6;y<256;y+=14)for(var x=4;x<128;x+=12){ g.fillRect(x,y,8,9); }
  g.fillStyle='rgba(255,255,255,0.25)';
  for(var y2=6;y2<256;y2+=14)for(var x2=4;x2<128;x2+=12){ g.fillRect(x2,y2,8,2); }
  var t=new T.CanvasTexture(c);t.encoding=T.sRGBEncoding;
  t.wrapS=t.wrapT=T.RepeatWrapping;return t;
}
/* Interior podium builder for Hyper City — adds REAL building interiors.
 * Appended to hyper-city.js. Builds 3 podium+tower structures:
 * - Spire podium (cylindrical, 70m dia, 95m tall): lobby, 4 floors, observatory
 * - 2 tower podiums (box, 50x50m, 60m tall): lobby, 3 floors, roof deck
 * Each with: doors, lobby fit-out, elevator (rideable), rooms, roof.
 */
/* Interior podium builder v2 — TWO REAL FLOORS, then portholes.
 * The King's refinement: "I just need the first 2 floors for the buildings
 * the rest will be port holes aka portals."
 * - Floor 1 (lobby): REAL — doors, columns, desk, full fit-out
 * - Floor 2: REAL — corridors, offices/rooms
 * - Roof/Observatory: REAL deck
 * - Above: porthole discs (glowing portals) on the facade, wormhole aesthetic
 */
function buildInteriorPodium(T, root, foot, elevators, standFloors, o) {
  var R = o.R;
  var glassA = o.glassA, gold = o.gold, steel = o.steel;
  var deckM = new T.MeshLambertMaterial({ color: 0x2c313a });
  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 isCyl = !!o.cyl;
  var W = o.w, D = o.d, H = o.h;
  var floors = o.floors; // [0, floor2Y, roofY]
  var i, j;

  function box(w, h, d, mat, x, y, z, ry) {
    var m = new T.Mesh(new T.BoxGeometry(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: textPlate(T, o.name), side: T.DoubleSide }));
    plq.position.set(0, 6, D/2-1)