<!-- SOLID CITY · part 3407 -->
{ x: CITY.x - 700, z: CITY.z - 80 }].forEach((t) => {
    const dx = t.x - P.x, dz = t.z - P.z, L = Math.hypot(dx, dz), a = Math.atan2(dx, dz);
    const road = new THREE.Mesh(new THREE.PlaneGeometry(14, L), roadMat); road.rotation.set(-Math.PI / 2, 0, a); road.position.set(P.x + dx / 2, 0.06, P.z + dz / 2); scene.add(road);
  });
  const plaza = new THREE.Mesh(new THREE.RingGeometry(106, 111, 64), M.glowGold); plaza.rotation.x = -Math.PI / 2; plaza.position.set(P.x, 0.15, P.z); scene.add(plaza);
  const ob = new THREE.Mesh(new THREE.CylinderGeometry(0.2, 1.6, 26, 4), M.black); ob.position.set(P.x, 16, P.z + 22); scene.add(ob);
  const tw = new THREE.Mesh(new THREE.CylinderGeometry(16, 22, 230, 8), new THREE.MeshLambertMaterial({ color: 0x1a1418, emissive: 0xffffff, emissiveMap: TEX_WIN })); tw.position.set(studio.x, 121, studio.z); scene.add(tw);
  for (let k = 0; k < 7; k++) { const rg = new THREE.Mesh(new THREE.TorusGeometry(21 - k * 0.7, 0.6, 6, 40), k % 2 ? M.glowGold : M.red); rg.rotation.x = Math.PI / 2; rg.position.set(studio.x, 30 + k * 30, studio.z); scene.add(rg); }
  const sp = new THREE.Mesh(new THREE.ConeGeometry(4, 40, 8), M.gold); sp.position.set(studio.x, 256, studio.z); scene.add(sp);
  const pp = new THREE.Mesh(new THREE.CylinderGeometry(42, 44, 2, 40), new THREE.MeshLambertMaterial({ color: 0x0a080b })); pp.position.set(port.x, 1, port.z); scene.add(pp);
  for (let k = 0; k < 3; k++) { const r = new THREE.Mesh(new THREE.RingGeometry(14 + k * 9, 15 + k * 9, 48), k === 1 ? M.red : M.glowGold); r.rotation.x = -Math.PI / 2; r.position.set(port.x, 2.1, port.z); scene.add(r); }
  addBox(4, 70, 4, M.black, port.x + 30, 0, port.z - 6);
  const ct = new THREE.Mesh(new THREE.CylinderGeometry(6, 8, 46, 6), M.black); ct.position.set(port.x - 60, 23, port.z - 30); scene.add(ct);
  const cab = new THREE.Mesh(new THREE.CylinderGeometry(12, 9, 8, 6), new THREE.MeshLambertMaterial({ color: 0x220408, emissive: 0x5a0410 })); cab.position.set(port.x - 60, 50, port.z - 30); scene.add(cab);
  for (let k = 0; k < 4; k++) addBox(1.2, 18, 1.2, M.black, hangar.x - 15 + (k & 1) * 30, 0, hangar.z - 15 + (k >> 1) * 30);
  addBox(34, 1, 34, M.gold, hangar.x, 18, hangar.z);
  const geo = new THREE.BoxGeometry(1, 1, 1); geo.translate(0, 0.5, 0);
  const MAXB = MOBILE ? 200 : 300, inst = new THREE.InstancedMesh(geo, new THREE.MeshLambertMaterial({ color: 0x1e171c, emissive: 0xffffff, emissiveMap: TEX_WIN }), MAXB);
  const mtx = new THREE.Matrix4(), q = new THREE.Quaternion(), Y = new V3(0, 1, 0), rb = mulberry(99); let placed = 0;
  const avoid = [[0, 0, 140], [430, -170, 70], [-380, 330, 120], [-307, 365, 44], [-307, 410, 46], [210, 170, 52]];
  for (let tries = 0; tries < 5000 && placed < MAXB; tries++) {
    const ang = rb() * Math.PI * 2, rr = 170 + Math.pow(rb(), 0.8) * 600, bx = Math.cos(ang) * rr, bz = Math.sin(ang) * rr;
    const w = 14 + rb() * 22, d = 14 + rb() * 22, h = (24 + rb() * 120) * (1.2 - rr / 900);
    let bad = false; for (const a of avoid) if (Math.hypot(bx - a[0], bz - a[1]) < a[2] + w) bad = true;
    for (const t of [[430, -170], [-380, 330], [0, -700], [-700, -80]]) { const L = Math.hypot(t[0], t[1]), ux = t[0] / L, uz = t[1] / L, along = bx * ux + bz * uz, perp = Math.abs(-bx * uz + bz * ux); if (along > 0 && along < L && perp < 16 + w) bad = true; }
    if (bad) continue;
    mtx.compose(new V3(bx + CITY.x, 0, bz + CITY.z), q.setFromAxisAngle(Y, rb() * 0.5), new V3(w, h, d)); inst.setMatrixAt(placed++, mtx);
  }
  inst.count = placed; inst.instanceMatrix.needsUpdate = true; inst.frustumCulled = false; scene.add(inst);
}

/* --- the Hangar landing pad: glowing circle + beacon --- */
const pad = { group: new THREE.Group(), glow: null, beam: null, rings: [] };
function buildPad() {
  const g = pad.group; scene.add(g);
  const disc = new THREE.Mesh(new THREE.CylinderGeometry(16, 17, 0.5, 48), new THREE.MeshPhongMaterial({ color: 0x141016, shininess: 30 })); g.add(disc);
  const add = () => new THREE.MeshBasicMaterial({ color: new THREE.Color(1.7, 1.05, 0.32), transparent: true, blending: THREE.AdditiveBlending, depthWrite: false });
  const rimMat = add(), redMat = add(); redMat.color.setRGB(1.9, 0.12, 0.18);
  [[13.2, 14.6, rimMat], [8.2, 8.9, redMat], [3.2, 3.7, rimMat]].forEach(([a, b, mat]) => { const r = new THREE.Mesh(new THREE.RingGeometry(a, b, 64), mat); r.rotation.x = -Math.PI / 2; r.position.y = 0.3; g.add(r); pad.rings.push(r); });
  for (let k = 0; k < 8; k++) { const a = k / 8 * Math.PI * 2, s = new THREE.Mesh(new THREE.BoxGeometry(0.7, 0.1, 2.6), rimMat); s.position.set(Math.cos(a) * 11, 0.32, Math.sin(a) * 11); s.rotation.y = -a + Math.PI / 2; g.add(s); }
  pad.glow = new THREE.Mesh(new THREE.CircleGeometry(15, 48), new THREE.MeshBasicMaterial({ color: 0xffb040, transparent: true, opacity: 0.18, blending: THREE.AdditiveBlending, depthWrite: false }));
  pad.glow.rotation.x = -Math.PI / 2; pad.glow.position.y = 0.28; g.add(pad.glow);
  pad.beam = 