<!-- SOLID CITY · part 2118 -->
the Hyper City.',8);}catch(e){}
          }
        }
      }
      for(var gd=0;gd<gateDiscs.length;gd++){
        var gdm=gateDiscs[gd];
        gdm.rotation.z=t*0.5+gd*0.3;
        if(gdm.material) gdm.material.opacity=0.9+0.1*Math.sin(t*2.2+gd);
      }
    },
    actHere:function(wx,wz){
      // near an elevator cab? offer the ride
      for(var e=0;e<elevators.length;e++){
        var el=elevators[e];
        if(el.moving)continue;
        var dx=wx-(P.x+el.x), dz=wz-(P.z+el.z);
        if(Math.abs(dx)<4&&Math.abs(dz)<4){
          var nf=(el.idx+1)%el.floors.length;
          var names=el.names||['LOBBY','FLOOR 2','FLOOR 3','FLOOR 4','FLOOR 5','OBSERVATORY','ROOF'];
          return 'ELEVATOR \u2192 '+(names[nf]||('FLOOR '+(nf+1)));
        }
      }
      // plaza portal gate: express to Solid City
      if (portalPlaza) {
        var pdx=wx-(P.x+portalPlaza.x), pdz=wz-(P.z+portalPlaza.z);
        if (Math.abs(pdx)<5 && Math.abs(pdz)<5) return 'PORTAL \u2192 SOLID CITY';
      }
      return null;
    },
    boardElevator:function(wx,wz){
      if (portalPlaza) {
        var pdx=wx-(P.x+portalPlaza.x), pdz=wz-(P.z+portalPlaza.z);
        if (Math.abs(pdx)<5 && Math.abs(pdz)<5) {
          startTransit({x:-380, y:35, z:278, world:true, name:'SOLID CITY'});
          return true;
        }
      }
      for(var e=0;e<elevators.length;e++){
        var el=elevators[e];
        if(el.moving)continue;
        var dx=wx-(P.x+el.x), dz=wz-(P.z+el.z);
        if(Math.abs(dx)<4&&Math.abs(dz)<4){
          el.toIdx=(el.idx+1)%el.floors.length;
          el.from=el.floors[el.idx]; el.to=el.floors[el.toIdx];
          el.t=0; el.moving=true;
          return true;
        }
      }
      return false;
    }
  };
  return root;
}
export default createHyperCity;


===== FILE: public/city/hyper-city.js.bak-interior-20261011 =====
/* SOLID CITY — HYPER CITY (2026-10-11, by order of the King)
 * "You going to build a hyper building city here"
 * A district of futuristic megatowers on the west coast: 24 towers 150-400m,
 * the Hyper Spire (460m), street grid, central plaza, waterfront promenade.
 * Design law: science grown into beautiful art — golden-ratio setbacks,
 * symmetrical crowns, the skyline a composition.
 * True names: THE HYPER CITY (district), THE HYPER SPIRE.
 * Self-contained ES module. Local frame: +X = east (city side), -X = west (ocean).
 */
function mulberry(a){return function(){a|=0;a=a+0x6D2B79F5|0;var t=Math.imul(a^a>>>15,1|a);t=t+Math.imul(t^t>>>7,61|t)^t;return((t^t>>>14)>>>0)/4294967296;};}
function textPlate(T, text, w){
  var c=document.createElement('canvas');c.width=512;c.height=128;
  var g=c.getContext('2d');
  g.fillStyle='#101418';g.fillRect(0,0,512,128);
  g.strokeStyle='#d8aa48';g.lineWidth=5;g.strokeRect(7,7,498,114);
  g.fillStyle='#e8c86a';g.textAlign='center';g.textBaseline='middle';
  g.font='bold 46px Georgia,serif';g.fillText(text,256,66);
  var t=new T.CanvasTexture(c);t.encoding=T.sRGBEncoding;t.anisotropy=4;return t;
}
function quietMarker(T,text){
  var grp=new T.Group();
  var stone=new T.Mesh(new T.BoxGeometry(4.4,0.6,2.2),new T.MeshLambertMaterial({color:0x1e2228}));
  stone.position.y=0.65;stone.rotation.x=-0.45;grp.add(stone);
  var face=new T.Mesh(new T.PlaneGeometry(4.0,1.0),new T.MeshBasicMaterial({map:textPlate(T,text)}));
  face.position.set(0,0.88,0.52);face.rotation.x=-0.45;grp.add(face);
  var base=new T.Mesh(new T.BoxGeometry(4.6,0.3,2.4),new T.MeshLambertMaterial({color:0x14171c}));
  base.position.y=0.15;grp.add(base);
  return grp;
}
// glass 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;
}
export function createHyperCity(o){
  var T=o.THREE,P=o.position||{x:0,y:0,z:0};
  var root=new T.Group();root.name='hyper-city';root.position.set(P.x,P.y,P.z);
  var foot=[];
  var R=mulberry(1379);
  var PHI=1.6180339887;
  // materials
  var glassA=new T.MeshLambertMaterial({map:facadeTex(T),emissive:0x1a2a40,emissiveIntensity:0.35});
  var glassB=new T.MeshLambertMaterial({map:facadeTex(T,'rgba(30,50,80,0.5)'),emissive:0x16263c,emissiveIntensity:0.35});
  var steel=new T.MeshLambertMaterial({color:0x3a4048});
  var darkSteel=new T.MeshLambertMaterial({color:0x23272e});
  var gold=new T.MeshLambertMaterial({color:0xd8aa48,emissive:0x4a2e08,emissiveIntensity:0.7});
  var deckM=new T.