<!-- SOLID CITY · part 2756 -->
// the verge law judges the BUILT line: ROAD_SEGS is rebuilt from
    // the smith's stations, so a home is cleared against the road as
    // it truly runs, not the polyline it was drawn from.
    ROAD_SEGS.length = 0;
    Object.keys(smithRoads).forEach(function (nm) {
      var sts = smithRoads[nm].stations;
      for (var i = 0; i < sts.length - 1; i++) ROAD_SEGS.push([[sts[i].x, sts[i].z], [sts[i + 1].x, sts[i + 1].z]]);
    });
  }
  function nearestRoad(x, z) {
    var best = null, bd = 1e12;
    for (var i = 0; i < roadPts.length; i++) {
      var dx = roadPts[i][0] - x, dz = roadPts[i][1] - z, dd = dx * dx + dz * dz;
      if (dd < bd) { bd = dd; best = roadPts[i]; }
    }
    return { x: best[0], z: best[1], dist: Math.sqrt(bd) };
  }
  function steppedPath(x0, z0, x1, z1, wdt, col, stepLen, endY) {
    var len = Math.hypot(x1 - x0, z1 - z0), n = Math.max(1, Math.round(len / stepLen)), ang = Math.atan2(x1 - x0, z1 - z0), run = len / n;
    for (var j = 0; j < n; j++) {
      var t = (j + 0.5) / n, px = x0 + (x1 - x0) * t, pz = z0 + (z1 - z0) * t;
      // THE ONE ROAD reaches the driveways too: each stone pitches between
      // the same sampled ends its neighbours use — a path of ramps that
      // follow the land, not a staircase dropped on it.
      var ga = groundAt(x0 + (x1 - x0) * (j / n), z0 + (z1 - z0) * (j / n));
      // a driveway's last stone lands ON the road: when the caller
      // names the carriageway's height, the final stone's far end
      // is that height, and the drive meets the road flush.
      var gb = (endY != null && j === n - 1) ? endY - 0.08 : groundAt(x0 + (x1 - x0) * ((j + 1) / n), z0 + (z1 - z0) * ((j + 1) / n));
      var rx = -Math.atan2(gb - ga, run);   // pitch truth (2026-10-13): atan2, as above
      BASE = M4(px, (ga + gb) / 2 + 0.08, pz, ang, rx, 0);
      box(solid, wdt, 0.18, stepLen + 0.7, 0, 0, 0, col);
      standQuad(px, (ga + gb) / 2 + 0.08, pz, ang, rx, wdt, stepLen + 0.7, 0.09);
      BASE = new T.Matrix4();
    }
  }

  /* ================= SITING — the placement law, enforced ================= */
  var EXCLUDE = [   // [x, z, radius] — structures and ground that stay untouched
    [0, -1600, 578],      // THE ANCESTRAL ROADS terrace (platform r=560)
    [0, -3200, 430],      // Imperial Colosseum
    [0, 0, 1060],         // the capital
    [0, -950, 205],       // Gate of Ancestors
    [450, -1150, 205],    // Compass Meridian
    [750, -1600, 255],    // Overlook Mira
    [-750, -1600, 255],   // Roost Keel
    [-700, -700, 290]     // Quadrant Crown
  ];
  var placed = [];
  function clearOf(x, z, r) {
    for (var i = 0; i < EXCLUDE.length; i++) {
      var e = EXCLUDE[i];
      if (Math.hypot(x - e[0], z - e[1]) < e[2] + r) return false;
    }
    for (var j = 0; j < placed.length; j++) {
      if (Math.hypot(x - placed[j][0], z - placed[j][1]) < placed[j][2] + r) return false;
    }
    return true;
  }
  function findSpot(cx, cz, rad, lotR) {
    for (var ring = 0; ring < 11; ring++) {
      var rr = rad * ring / 10;
      for (var k = 0; k < 16; k++) {
        var a = (k / 16) * Math.PI * 2 + ring * 0.7 + R() * 0.3;
        var x = cx + Math.cos(a) * rr, z = cz + Math.sin(a) * rr;
        if (benchAt(x, z, lotR) >= 0 && clearOf(x, z, lotR + 4) && roadClear(x, z, lotR)) return [x, z];
      }
    }
    // the lattice fallback: where the polar search cannot see a
    // lawful pocket, walk the disc plainly before refusing the home.
    for (var gx = -rad; gx <= rad; gx += 6) for (var gz = -rad; gz <= rad; gz += 6) {
      if (gx * gx + gz * gz > rad * rad) continue;
      var x2 = cx + gx, z2 = cz + gz;
      if (benchAt(x2, z2, lotR) >= 0 && clearOf(x2, z2, lotR + 4) && roadClear(x2, z2, lotR)) return [x2, z2];
    }
    return null;
  }
  function faceAngle(x, z, tx, tz) { return Math.atan2(tx - x, tz - z); }
  function plantAt(x, z, fn) {
    BASE = M4(x, groundAt(x, z) - 0.15, z, R() * Math.PI * 2, 0, 0); PLANTBODY = true; fn(); PLANTBODY = false; BASE = new T.Matrix4();
  }
  /* THE BODY OF THE TREE (the King's finding, 2026-10-13 ~23:34:
   * "Why is collision not on for the road solid? I can walk through
   * it"). The city's own comment says everything visible is solid —
   * but the trees were drawn and never registered. A trunk planted
   * by plantAt or set by a home's dressing now registers its body:
   * a 0.9 m square from the ground to 2.4 m, where the wood is. The
   * canopy stays unbodies — a walker passes under a tree, never
   * through it. */
  function trunkBody() {
    if (!PLANTBODY || !BASE || !BASE.elements) return;
    var bx = BASE.elements[12], bz = BASE.elements[14], bgy = groundAt(bx, bz);
    foot.push([bx, bz, 0.9, 0.9, bgy - 0.2, bgy + 2.4, 0]);
  }

  // drive + parking + path for one home (the placement law: every house has a driveway)
  function serveHome(rec, roadPt) {
    var fx = Math.sin(rec.ry), fz = Math.cos(rec.ry);            // front dir
    var rx = Math.cos(