<!-- SOLID CITY · part 2120 -->
h+60);
    built.push(tower(spots[i][0],spots[i][1],h,tp));
  }
  // skybridges: connect 4 pairs at ~60% height
  var bridges=0;
  for(i=0;i<built.length&&bridges<4;i++){
    for(var j2=i+1;j2<built.length;j2++){
      var dd=Math.hypot(built[i].x-built[j2].x,built[i].z-built[j2].z);
      if(dd>55&&dd<95){
        var by=Math.min(built[i].h,built[j2].h)*0.62;
        var mx=(built[i].x+built[j2].x)/2, mz=(built[i].z+built[j2].z)/2;
        var bl=Math.hypot(built[i].x-built[j2].x,built[i].z-built[j2].z);
        var br=new T.Mesh(new T.BoxGeometry(bl,5,7),glassB);
        br.position.set(mx,by,mz);
        br.rotation.y=-Math.atan2(built[j2].z-built[i].z,built[j2].x-built[i].x);
        root.add(br);
        bridges++;
        break;
      }
    }
  }

  // ---- THE HYPER SPIRE (460m) at plaza north edge ----
  var spire=new T.Group();spire.position.set(0,0,-58);
  var sh=460;
  var s1=new T.Mesh(new T.CylinderGeometry(14,26,sh*0.7,12),glassA);s1.position.y=sh*0.35;spire.add(s1);
  var s2=new T.Mesh(new T.CylinderGeometry(8,14,sh*0.22,12),glassB);s2.position.set(0,sh*0.7+sh*0.11,0);spire.add(s2);
  var s3=new T.Mesh(new T.CylinderGeometry(0.8,6,sh*0.08+30,8),gold);s3.position.set(0,sh*0.92+sh*0.04+10,0);spire.add(s3);
  // gold crown rings
  [0.55,0.7,0.82].forEach(function(f){
    var r=new T.Mesh(new T.TorusGeometry(20*(1-f*0.4)+8,1.8,8,32),goldTrim);
    r.rotation.x=Math.PI/2;r.position.y=sh*f;spire.add(r);
  });
  // beacon
  var beacon=new T.Mesh(new T.SphereGeometry(3.2,12,10),new T.MeshBasicMaterial({color:0xffe8a0}));
  beacon.position.y=sh+32;beacon.name='beacon';spire.add(beacon);
  var beam=new T.Mesh(new T.CylinderGeometry(1.2,2.2,120,8,1,true),
    new T.MeshBasicMaterial({color:0xffe8a0,transparent:true,opacity:0.28,side:T.DoubleSide,depthWrite:false}));
  beam.position.y=sh+92;beam.name='beam';spire.add(beam);
  root.add(spire);
  foot.push([0,-58,56,56,0,sh+34,0]);
  var smark=quietMarker(T,'THE HYPER SPIRE');smark.position.set(24,0,-58);root.add(smark);

  // ---- 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:480,
    update:function(t){
      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(