<!-- SOLID CITY · part 2651 -->
lice();
      Object.keys(smithRoads).forEach(function (nm) {
        var sts = smithRoads[nm].stations;
        for (var i2 = 0; i2 < sts.length - 1; i2++) {
          var A = sts[i2], B = sts[i2 + 1];
          var segLen = Math.hypot(B.x - A.x, B.z - A.z), n = Math.max(1, Math.round(segLen / 0.5));
          for (var j = 0; j <= n; j++) { var t2 = j / n; samples.push([A.x + (B.x - A.x) * t2, A.z + (B.z - A.z) * t2, A.y + (B.y - A.y) * t2]); }
        }
      });
      for (var pass = 0; pass < 4; pass++) {
        var struck = 0;
        for (var si = 0; si < samples.length; si++) {
          var sm = samples[si], hit = triYAtLocal(sm[0], sm[1]);
          if (hit && hit.y - sm[2] > 1.6) { hit.t.drop = true; struck++; }
        }
        if (!struck) break;
      }
      var kept = standTris.slice(0, triBase);
      tris.forEach(function (t) { if (t.drop) return; for (var v = 0; v < 9; v++) kept.push(standTris[t.i + v]); });
      standTris.length = 0;
      for (var w = 0; w < kept.length; w++) standTris.push(kept[w]);
    })();
    // street lights along the smith's stations: one every ~63 m of
    // travel, alternating sides, perched perpendicular — a lamp is a
    // post at the verge, never a ghost in the carriageway.
    ['B1', 'B2', 'C', 'S', 'A1', 'A2'].forEach(function (nm) {
      var sts = smithRoads[nm].stations, acc = 0, side = 1;
      for (var i = 1; i < sts.length; i++) {
        acc += sts[i].ds;
        if (acc < 63) continue;
        acc = 0; side = -side;
        var s = sts[i];
        var lx = 0, lz = 0, okP = false;
        for (var tr = 0; tr < 2 && !okP; tr++) {
          var sd2 = tr ? -side : side;
          lx = s.x + s.rx * sd2 * 5.2; lz = s.z + s.rz * sd2 * 5.2;
          okP = true;
          for (var rn in smithRoads) { var sts2 = smithRoads[rn].stations; for (var q = 0; q < sts2.length; q += 2) { var ddx = sts2[q].x - lx, ddz = sts2[q].z - lz; if (ddx * ddx + ddz * ddz < 19.4) { okP = false; break; } } if (!okP) break; }
        }
        if (!okP) continue;
        var ly = groundAt(lx, lz);
        BASE = M4(lx, ly - 0.1, lz, R() * 3, 0, 0);
        streetLight();
        BASE = new T.Matrix4();
        foot.push([lx, lz, 0.3, 0.3, ly - 0.1, ly + 5.1, 0]);
      }
    });
    // 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 -