<!-- SOLID CITY · part 1807 -->
head in
   * its own time, walking the land by the land's own law. */
  function sheepGeometry(ram) {
    var b = new Batch();
    var wool = 0xf2ede2, face = 0xd9cfba, hornC = 0x9a7d55, leg = 0xcfc4ae;
    b.add(new T.SphereGeometry(0.85, 10, 7), mat4(0, 0.98, 0, 0, 0, 0, 0.72, 0.62, 1.0), wool);
    b.add(new T.SphereGeometry(0.27, 8, 6), mat4(0, 1.18, 0.98, 0, 0, 0, 0.8, 0.85, 1.15), face);
    b.add(new T.BoxGeometry(0.2, 0.16, 0.24), mat4(0, 1.06, 1.22, 0, 0, 0), face);
    b.add(new T.BoxGeometry(0.22, 0.07, 0.12), mat4(-0.3, 1.3, 0.9, 0, 0, 0.5), face);
    b.add(new T.BoxGeometry(0.22, 0.07, 0.12), mat4(0.3, 1.3, 0.9, 0, 0, -0.5), face);
    if (ram) {
      b.add(new T.TorusGeometry(0.31, 0.085, 6, 12, 4.1), mat4(-0.27, 1.32, 0.88, 0, Math.PI / 2, 2.2), hornC);
      b.add(new T.TorusGeometry(0.31, 0.085, 6, 12, 4.1), mat4(0.27, 1.32, 0.88, 0, Math.PI / 2, -2.2 + Math.PI), hornC);
    }
    [[-0.28, 0.42], [0.28, 0.42], [-0.28, -0.42], [0.28, -0.42]].forEach(function (lp) {
      b.add(new T.CylinderGeometry(0.07, 0.06, 0.78, 5), mat4(lp[0], 0.39, lp[1], 0, 0, 0), leg);
    });
    b.add(new T.SphereGeometry(0.16, 6, 5), mat4(0, 1.1, -0.85, 0, 0, 0), wool);
    return b.build(new T.MeshLambertMaterial({ vertexColors: true })).geometry;
  }
  var ramGeo = sheepGeometry(true), eweGeo = sheepGeometry(false);
  var herd = { r: 200, a: 1.55 };
  var flock = [];
  for (var fi = 0; fi < 9; fi++) {
    var fm3 = new T.Mesh(fi % 2 ? eweGeo : ramGeo, new T.MeshLambertMaterial({ vertexColors: true }));
    fm3.scale.setScalar(1.5); fm3.frustumCulled = false;
    group.add(fm3);
    var fa = herd.a + (R() - 0.5) * 0.5, fr = herd.r + (R() - 0.5) * 60;
    flock.push({ mesh: fm3, x: CX + Math.cos(fa) * fr, z: CZ + Math.sin(fa) * fr, head: R() * Math.PI * 2, seed: fi * 1.7 + R() * 3 });
  }

  /* ---------- the falls and the rain ---------- */
  var fallMats = [];
  var falls = [];
  CROWN_RIVERS.forEach(function (ra) {
    var fx = px(331, ra), fz = pz(331, ra);
    var topY = BASE + crownHeight(326, ra) + 0.4, botY = FLOOR + 4;
    var hgt = topY - botY;
    var fm = new T.MeshBasicMaterial({ color: 0xbfe0f2, transparent: true, opacity: 0.34, depthWrite: false });
    var fall = new T.Mesh(new T.CylinderGeometry(1.5, 3.4, hgt, 10, 1, true), fm);
    fall.position.set(fx, botY + hgt / 2, fz); fall.frustumCulled = false; group.add(fall);
    var fm2 = new T.MeshBasicMaterial({ color: 0xeaf6ff, transparent: true, opacity: 0.5, depthWrite: false });
    var core = new T.Mesh(new T.CylinderGeometry(0.7, 1.6, hgt, 8, 1, true), fm2);
    core.position.set(fx, botY + hgt / 2, fz); core.frustumCulled = false; group.add(core);
    var foam = new T.Mesh(new T.CircleGeometry(5.5, 18), new T.MeshBasicMaterial({ color: 0xeaf6ff, transparent: true, opacity: 0.4, depthWrite: false }));
    foam.rotation.x = -Math.PI / 2; foam.position.set(fx, FLOOR + 0.35, fz); foam.frustumCulled = false; group.add(foam);
    fallMats.push(fm, fm2);
    falls.push({ x: fx, z: fz, top: topY, bottom: botY });
  });
  var RAIN_N = 700, rainPos = new Float32Array(RAIN_N * 3), rainSpd = new Float32Array(RAIN_N);
  for (var rn = 0; rn < RAIN_N; rn++) {
    var rra = R() * Math.PI * 2, rrr = Math.sqrt(R()) * 322;
    rainPos[rn * 3] = CX + Math.cos(rra) * rrr;
    rainPos[rn * 3 + 1] = FLOOR + 6 + R() * (BASE - FLOOR - 12);
    rainPos[rn * 3 + 2] = CZ + Math.sin(rra) * rrr;
    rainSpd[rn] = 38 + R() * 22;
  }
  var rainGeo = new T.BufferGeometry();
  rainGeo.setAttribute('position', new T.BufferAttribute(rainPos, 3));
  var rain = new T.Points(rainGeo, new T.PointsMaterial({ color: 0xa8c8e8, size: 2.1, transparent: true, opacity: 0.45, depthWrite: false }));
  rain.frustumCulled = false; group.add(rain);

  /* ---------- THE WORMHOLE (the King's word: "a worm hole
   * to travel to it") — two mouths of gold and titanium with
   * turning violet hearts: one at the head of the terrace's
   * processional way, one on the Crown's spring plateau.
   * Step into either and the world puts you at the other. */
  var GY0 = opts.groundY;
  var portalDiscs = [];
  function buildMouth(r, a, baseY) {
    var x = px(r, a), z = pz(r, a), phi = Math.atan2(Math.cos(a), Math.sin(a));
    glow.add(new T.TorusGeometry(3.4, 0.14, 6, 32), mat4(x, baseY + 0.12, z, Math.PI / 2, 0, 0), C.gold);
    solid.add(new T.TorusGeometry(3.0, 0.17, 6, 32), mat4(x, baseY + 3.1, z, 0, phi, 0), C.stone);
    var disc = new T.Mesh(new T.CircleGeometry(2.85, 28), new T.MeshBasicMaterial({ color: 0x8a6aff, transparent: true, opacity: 0.5, side: T.DoubleSide, depthWrite: false }));
    disc.position.set(x, baseY + 3.1, z); disc.rotation.y = phi; disc.frustumCulled = false; group.add(disc);
    var inner = new T.Mesh(new T.TorusGeometry(1.6, 0.06, 5, 28), new T.MeshBasicMaterial({ color: 0xd8e6ff }));
    inner.position.set(x, baseY + 3.1, z); inner.rotation.y = phi; inner.frustumCulled = false; group.add(inner);
    portalDiscs.push(disc, inner);
    return