<!-- SOLID CITY · part 3118 -->
F, cz + Math.sin(ta) * 30, 1.1); }
    /* ---- THE LAYERS: ring terraces against the wall ---- */
    [34, 68].forEach(function (dy, li3) {
      var y = F + dy;
      var SEG = 40, prev = null;
      for (var si = 0; si <= SEG; si++) {
        var a = si / SEG * Math.PI * 2;
        var rOut = contourR(cx, cz, a, y + 7) + 3;
        var rIn = rOut - 27;
        var px = cx + Math.cos(a) * ((rIn + rOut) / 2), pz = cz + Math.sin(a) * ((rIn + rOut) / 2);
        box(solid, (rOut - rIn), 5, Math.PI * 2 * ((rIn + rOut) / 2) / SEG + 1.6, mat4(px, y - 2.5, pz, 0, -a + Math.PI / 2, 0), C.stoneDark);
        box(glow, 0.5, 0.3, Math.PI * 2 * ((rIn + rOut) / 2) / SEG + 1.6, mat4(cx + Math.cos(a) * (rIn + 0.4), y + 0.15, cz + Math.sin(a) * (rIn + 0.4), 0, -a + Math.PI / 2, 0), C.gold);
        if (si % 5 === 0) layers.push({ cx: cx, cz: cz, rIn: rIn - 1, rOut: rOut + 1, y: y });
        prev = rOut;
      }
      var want = li3 === 0 ? 6 : 5;
      for (var lh = 0; lh < want; lh++) {
        var la2 = (lh + li3 * 0.5) / want * Math.PI * 2 + 0.5;
        if (!clear(la2)) continue;
        var lr = contourR(cx, cz, la2, y + 7) - 12;
        house(frameOf(lr, la2, cx, cz), y, 0.92, lh % 2 ? 2 : 1);
      }
      for (var ll = 0; ll < 7; ll++) { var la3 = ll / 7 * Math.PI * 2 + 0.9; if (clear(la3)) { var lr3 = contourR(cx, cz, la3, y + 7) - 25; lamp(cx + Math.cos(la3) * lr3, y, cz + Math.sin(la3) * lr3, 0.9); } }
    });
    /* ---- THE ROOF RING + formations: a marble crown
     * leaving the light shaft open over the plaza ---- */
    var roofY = F + (big ? 118 : 104);
    var SEG2 = 44;
    for (var ri = 0; ri < SEG2; ri++) {
      var ra = ri / SEG2 * Math.PI * 2, rOut2 = contourR(cx, cz, ra, roofY) + 4;
      var mid = (146 + rOut2) / 2;
      box(solid, (rOut2 - 146), 1.6, Math.PI * 2 * mid / SEG2 + 1.8, mat4(cx + Math.cos(ra) * mid, roofY, cz + Math.sin(ra) * mid, 0, -ra + Math.PI / 2, 0), C.stoneDark);
      if (ri % 3 === 0) formation(cx + Math.cos(ra) * 152, roofY - 0.8, cz + Math.sin(ra) * 152, 1.5 + R(), true);
      if (ri % 4 === 1) formation(cx + Math.cos(ra) * (120 + R() * 12), F, cz + Math.sin(ra) * (120 + R() * 12), 1.2 + R() * 0.8, false);
    }
    cyl(glow, 146.5, 146.5, 0.3, 48, mat4(cx, roofY - 0.9, cz, 0, 0, 0), C.gold);
    /* arches over the shaft */
    for (var ai2 = 0; ai2 < 3; ai2++) {
      var arch = new T.Mesh(new T.TorusGeometry(150, 1.1, 6, 40, Math.PI), new T.MeshBasicMaterial({ color: C.gold }));
      arch.position.set(cx, roofY, cz); arch.rotation.y = ai2 * Math.PI / 3; arch.frustumCulled = false; group.add(arch);
    }
    return { roofY: roofY };
  }
  var builtA = buildCity(A_C, true);
  var builtB = buildCity(B_C, false);
  /* THE DEEP'S LOW PASS, WALLED (the gate's finding): the
   * Deep Hollow's south-western rim dips to within 15 m of
   * its floor — a marble palisade closes the stroll-out and
   * keeps the hollow honest. */
  (function () {
    for (var a = 2.45; a <= 3.35; a += 0.09) {
      var px = B_C.x + Math.cos(a) * 148, pz = B_C.z + Math.sin(a) * 148, py = H(px, pz);
      box(solid, 13.5, 13, 2.2, mat4(px, py + 5.5, pz, 0, -a + Math.PI / 2, 0), C.stoneDark);
      box(glow, 13.5, 0.4, 0.5, mat4(px + Math.cos(a) * -1.2, py + 12.1, pz + Math.sin(a) * -1.2, 0, -a + Math.PI / 2, 0), C.gold);
      footprints.push({ x: px, z: pz, w: 13.5, d: 2.4, a: -a + Math.PI / 2, y0: py, y1: py + 12 });
    }
  })();
  /* THE GREAT CRYSTAL of the First Hollow, hanging in the shaft */
  (function () {
    var cx = A_C.x, cz = A_C.z, cy = A_C.f + 96;
    var cr = new T.Mesh(new T.IcosahedronGeometry(8.5, 0), new T.MeshLambertMaterial({ color: C.crystal, emissive: 0x8a6a20, transparent: true, opacity: 0.92 }));
    cr.position.set(cx, cy, cz); cr.frustumCulled = false; group.add(cr); crystals.push(cr);
    var core = new T.Mesh(new T.IcosahedronGeometry(4.2, 0), new T.MeshBasicMaterial({ color: 0xffe9b0 }));
    core.position.set(cx, cy, cz); core.frustumCulled = false; group.add(core); crystals.push(core);
    for (var k = 0; k < 3; k++) { var a = k / 3 * Math.PI * 2 + 0.5; cyl(solid, 0.16, 0.16, 34, 5, mat4(cx + Math.cos(a) * 26, cy + 16, cz + Math.sin(a) * 26, Math.cos(a) * 0.72, 0, -Math.sin(a) * 0.72), C.gold); }
    /* the falls: from the roof ring's edge to a plaza pool */
    var fa = 0.35, fx = cx + Math.cos(fa) * 138, fz = cz + Math.sin(fa) * 138;
    var fall = new T.Mesh(new T.BoxGeometry(2.6, builtA.roofY - A_C.f - 6, 0.5), new T.MeshBasicMaterial({ color: 0xbfe0f2, transparent: true, opacity: 0.4 }));
    fall.position.set(fx, (builtA.roofY + A_C.f) / 2 + 2, fz); fall.lookAt(cx, (builtA.roofY + A_C.f) / 2 + 2, cz); fall.frustumCulled = false; group.add(fall);
    cyl(glow, 6.5, 7.2, 0.35, 16, mat4(cx + Math.cos(fa) * 128, A_C.f + 0.3, cz + Math.sin(fa) * 128, 0, 0, 0), C.water);
  })();
  /* the Deep Hollow's standing crystal cluster + spring pool */
  (function () {
    var cx = B_C.x, cz = B_C.z, F = B_C.f;
    for (var k = 0; k < 3; k