<!-- SOLID CITY · part 2960 -->
true);
  buildGarden(frame(410, 5.8), 15, false);

  /* THE FAMILY RING (r 492, inside the outer road) */
  [0.3, 1.95, 2.75, 3.55, 5.15, 5.95].forEach(function (a, i) { house(492, a, DISTRICTS.family, i + 1, i === 2 ? 2 : 1); });
  var hg2 = buildGrand(frame(492, 1.15), DISTRICTS.family, 'hotel', 'THE RING PALACE HOTEL');
  pavilion(492, 0.95, DISTRICTS.family, false);
  buildGarden(frame(492, 2.3), 16, true);
  /* the market plaza */
  var mk = frame(492, 5.62);
  box(solid, mk, 56, 0.22, 32, 0, 0.11, 0, C.conc);
  standRect(mk, 56, 32, BASE + 0.22, 0, 0);
  [5.4, 5.5, 5.74, 5.84].forEach(function (a) { buildStall(frame(479, a)); });
  [5.5, 5.74].forEach(function (a) { buildStall(frame(505, a)); });
  var mf = buildFountain(frame(492, 5.62)); mf.name = 'THE FAMILY MARKET FOUNTAIN'; mf.district = DISTRICTS.family;
  lampAt(492, 5.35, 0); lampAt(492, 5.89, 0);

  /* trees in the green between the houses */
  var treeBands = [
    { r: 170, as: [0.7, 1.95, 3.2, 4.1, 5.65] }, { r: 250, as: [0.5, 1.55, 2.7, 3.6, 4.85] },
    { r: 330, as: [0.95, 2.4, 3.4, 4.7, 5.5] }, { r: 410, as: [0.55, 1.55, 2.7, 3.8, 4.95, 5.65] },
    { r: 492, as: [0.62, 1.55, 2.35, 3.15, 4.0, 4.85, 6.15] }
  ];
  treeBands.forEach(function (tb) { tb.as.forEach(function (a, i) { buildTree(frame(tb.r + (i % 2 ? 9 : -9), a), i % 3 === 0); }); });
  [1.2, 2.5, 3.9, 5.6].forEach(function (a, i) { buildTree(frame(96, a), i % 2 === 0); });

  /* ---------- THE FILLING (the sky twin only) ----------
   * The King's word (~06:18): "fill it with homes, big and
   * small." A second sowing in the lawful gaps of every band —
   * great houses and small cottages between the first city's
   * buildings, under the same law: never on a road's radius,
   * never crowding a sign, never on the processional way. */
  if (opts.dense) {
    house(88, 4.5, DISTRICTS.hearth, 2, 1, 0.62);
    house(86, 1.15, DISTRICTS.hearth, 4, 1, 0.62);
    house(170, 0.7, DISTRICTS.voyagers, 1, 2, 1.45);
    house(170, 2.4, DISTRICTS.voyagers, 3, 1, 0.62);
    house(170, 3.2, DISTRICTS.voyagers, 0, 1, 1);
    house(170, 4.05, DISTRICTS.voyagers, 2, 1, 0.62);
    house(170, 5.65, DISTRICTS.voyagers, 4, 1, 1);
    house(170, 6.15, DISTRICTS.voyagers, 1, 2, 1.45);
    house(250, 0.5, DISTRICTS.chiefs, 2, 1, 1);
    house(250, 1.9, DISTRICTS.chiefs, 0, 1, 0.62);
    house(250, 2.7, DISTRICTS.chiefs, 3, 2, 1.45);
    house(250, 3.6, DISTRICTS.chiefs, 1, 1, 1);
    house(250, 4.75, DISTRICTS.chiefs, 4, 1, 0.62);
    house(330, 0.95, DISTRICTS.unifiers, 1, 1, 0.62);
    house(330, 1.45, DISTRICTS.unifiers, 3, 1, 1);
    house(330, 2.4, DISTRICTS.unifiers, 0, 2, 1.45);
    house(330, 3.4, DISTRICTS.unifiers, 2, 1, 0.62);
    house(330, 6.15, DISTRICTS.unifiers, 4, 1, 1);
    house(410, 0.6, DISTRICTS.builders, 2, 2, 1.45);
    house(410, 1.85, DISTRICTS.builders, 4, 1, 0.62);
    house(410, 3.75, DISTRICTS.builders, 1, 1, 1);
    house(410, 5.6, DISTRICTS.builders, 3, 1, 0.62);
    house(410, 6.25, DISTRICTS.builders, 0, 1, 1);
    house(492, 0.62, DISTRICTS.family, 3, 1, 1);
    house(492, 2.45, DISTRICTS.family, 1, 1, 0.62);
    house(492, 3.15, DISTRICTS.family, 2, 2, 1.45);
    house(492, 4.0, DISTRICTS.family, 0, 1, 1);
    house(492, 4.85, DISTRICTS.family, 4, 1, 0.62);
    house(492, 6.15, DISTRICTS.family, 1, 1, 1);
  }

  /* ---------- THE RING CITY PORT ---------- */
  var portF = frame(492, 4.45);
  cyl(solid, portF, 18, 18, 0.22, 36, 0, 0.11, 0, C.stone);
  var ringGeo = new T.TorusGeometry(15.6, 0.16, 6, 48);
  glow.add(ringGeo, localMatrix(portF, 0, 0.26, 0, Math.PI / 2, 0, 0), C.gold);
  cyl(solid, portF, 0.14, 0.2, 5.4, 6, 0, 2.7, 16.5, C.titanium);
  sph(glow, portF, 0.5, 0, 5.7, 16.5, C.gold);
  footprints.push({ x: portF.x + portF.rx * 16.5, z: portF.z + portF.rz * 16.5, w: 0.4, d: 0.4, a: portF.a, y0: BASE, y1: BASE + 5.4 });
  var port = { name: 'RING CITY PORT', x: portF.x, z: portF.z, y: BASE + 0.22, r: 18 };
  var halo = new T.Mesh(new T.TorusGeometry(20, 0.18, 6, 48), new T.MeshBasicMaterial({ color: C.gold }));
  halo.rotation.x = Math.PI / 2; halo.position.set(portF.x, BASE + 8.5, portF.z);
  group.add(halo);

  /* ---------- THE LIFTING OF THE GROUND CITY ----------
   * The King's word (~06:38): "Lift the ground city too —
   * beautify the terrace to match the sky." The terrace
   * answers its twin: a plaza of stone and gold around the
   * eternal flame; flowering rings in every band, so the city
   * reads in colour from the glass above; rings of lamps
   * answering the keel's gold; and a crown ring at the rim. */
  if (opts.beautify) {
    var cf2 = frame(0, 0);
    disc(solid, cf2, 42, 0.04, C.stone);
    disc(solid, cf2, 30, 0.055, C.stoneDark);
    glow.add(new T.TorusGeometry(42, 0.22, 5, 64), localMatrix(cf2, 0, 0.07, 0, Math.PI / 2, 0, 0), C.gold);
    glow.add(new T.TorusGeometry(23, 0.18, 5, 48), localMatrix(cf2, 0, 0.07, 0, Math.PI / 2, 0, 0), C.gold);
    for (var lk = 0; lk < 8; lk++) buildLamp(frame(36,