<!-- SOLID CITY · part 2139 -->
; py < baseY+tb.h; py += 26) {
        for (var f = 0; f < 4; f++) {
          var ang = f*Math.PI/2;
          var rad = tb.w*0.62;
          var hx = tb.x + Math.cos(ang)*rad, hz = tb.z + Math.sin(ang)*rad;
          var hole = new T.Mesh(new T.CircleGeometry(3.2, 20), pmat);
          hole.position.set(hx, py, hz);
          hole.rotation.y = -ang + Math.PI/2;
          // face outward
          hole.lookAt(hx*2-tb.x, py, hz*2-tb.z);
          root.add(hole);
          window._hyperPortholes.push(hole);
        }
      }
    });
    // Portholes on spire upper cylinders (every 30m from y=120 to 480)
    for (var sy = 130; sy < 480; sy += 32) {
      for (var sf = 0; sf < 6; sf++) {
        var sa = sf*Math.PI/3;
        var sr = 20 - (sy/480)*10; // taper
        var shx = Math.cos(sa)*sr, shz = -58 + Math.sin(sa)*sr;
        var shole = new T.Mesh(new T.CircleGeometry(2.8, 20), pmat);
        shole.position.set(shx, sy, shz);
        shole.lookAt(shx*2, sy, shz*2+58);
        root.add(shole);
        window._hyperPortholes.push(shole);
      }
    }
    // Portholes on all other towers (every 30m, 2 per face)
    built.forEach(function(tb){
      if(tb===pickA||tb===pickB) return;
      for (var py2 = 40; py2 < tb.h; py2 += 34) {
        for (var f2 = 0; f2 < 4; f2++) {
          var ang2 = f2*Math.PI/2 + 0.4;
          var rad2 = tb.w*0.6;
          var hx2 = tb.x + Math.cos(ang2)*rad2, hz2 = tb.z + Math.sin(ang2)*rad2;
          var hole2 = new T.Mesh(new T.CircleGeometry(2.6, 20), pmat);
          hole2.position.set(hx2, py2, hz2);
          hole2.lookAt(hx2*2-tb.x, py2, hz2*2-tb.z);
          root.add(hole2);
          window._hyperPortholes.push(hole2);
        }
      }
    });
  })();

  // ---- central plaza: fountain ----
  var plaza=new T.Mesh(new T.CylinderGeometry(42,44,0.8,40),new T.MeshLambertMaterial({color:0x363c46}));
  plaza.position.y=0.5;root.add(plaza);
  var basin=new T.Mesh(new T.CylinderGeometry(12,14,2.4,24),steel);basin.position.y=1.6;root.add(basin);
  var water=new T.Mesh(new T.CylinderGeometry(11,11,0.6,24),
    new T.MeshBasicMaterial({color:0x6ab8e8,transparent:true,opacity:0.85}));
  water.position.y=2.6;water.name='fountainwater';root.add(water);
  var jet=new T.Mesh(new T.CylinderGeometry(0.8,1.6,16,8),
    new T.MeshBasicMaterial({color:0xbfe4ff,transparent:true,opacity:0.7}));
  jet.position.y=10;jet.name='fountainjet';root.add(jet);
  var obel=new T.Mesh(new T.CylinderGeometry(2,3.4,22,4),gold);
  obel.position.y=11;obel.rotation.y=Math.PI/4;root.add(obel);
  foot.push([0,0,30,30,0,24,0]);
  var dmark=quietMarker(T,'THE HYPER CITY');dmark.position.set(0,0,48);root.add(dmark);

  // ---- waterfront promenade (west edge) ----
  var prom=new T.Mesh(new T.BoxGeometry(36,1.2,380),new T.MeshLambertMaterial({color:0x3a3f47}));
  prom.position.set(-192,0.4,0);root.add(prom);
  // railing (collision so he doesn't stroll into the sea)
  var railM=new T.MeshLambertMaterial({color:0x8a94a0});
  for(var rz=-180;rz<=180;rz+=12){
    var post=new T.Mesh(new T.BoxGeometry(0.5,3,0.5),railM);
    post.position.set(-209,2.2,rz);root.add(post);
  }
  var rail=new T.Mesh(new T.BoxGeometry(0.6,0.5,372),railM);
  rail.position.set(-209,3.8,0);root.add(rail);
  foot.push([-209,0,2,372,0,4,0]);
  // piers + boats
  var boatHullM=new T.MeshLambertMaterial({color:0x5a3a28});
  var boatMastM=new T.MeshLambertMaterial({color:0x8a6a48});
  var sailM=new T.MeshLambertMaterial({color:0xe8e0d0,side:T.DoubleSide});
  [-90,30,120].forEach(function(pz){
    var pier=new T.Mesh(new T.BoxGeometry(70,1.6,10),deckM);
    pier.position.set(-244,0.2,pz);root.add(pier);
    foot.push([-244,pz,70,10,0,1.2,0]);
    for(var b=0;b<2;b++){
      var bx=-244+(b?18:-14), bz=pz+(b?6:-5);
      var hull=new T.Mesh(new T.BoxGeometry(10,3,4),boatHullM);
      hull.position.set(bx,-2.5,bz);hull.name='boat';root.add(hull);
      var mast=new T.Mesh(new T.CylinderGeometry(0.3,0.3,12,6),boatMastM);
      mast.position.set(bx,2,bz);root.add(mast);
      var sail=new T.Mesh(new T.PlaneGeometry(7,9),sailM);
      sail.position.set(bx,5,bz+0.5);root.add(sail);
    }
  });

  // animated bits
  var beaconM=null,beamM=null,fw=null,fj=null;
  root.traverse(function(m){
    if(m.name==='beacon')beaconM=m;
    if(m.name==='beam')beamM=m;
    if(m.name==='fountainwater')fw=m;
    if(m.name==='fountainjet')fj=m;
  });
  var boats=[];root.traverse(function(m){if(m.name==='boat')boats.push(m);});
  root.userData={
    footprint:foot,center:{x:0,z:0},radius:260,height:580,
    elevators:elevators, standFloors:standFloors,
    update:function(t,dt,A){
      if(beaconM){var p=0.6+0.4*Math.sin(t*2.4);beaconM.scale.setScalar(p);}
      if(beamM){beamM.material.opacity=0.2+0.12*Math.sin(t*2.4);}
      if(fw){fw.position.y=2.6+Math.sin(t*3)*0.15;}
      if(fj){fj.scale.y=1+Math.sin(t*5)*0.12;}
      for(var b=0;b<boats.length;b++){boats[b].position.y=-2.5+Math.sin(t*1.2+b*1.7)*0.5;boats[b].rotation.z=Math.sin(t