<!-- SOLID CITY · part 2530 -->
on cflush() {
          if (!crun) return;
          var dx = crun.x1 - crun.x0, dz = crun.z1 - crun.z0;
          foot.push([(crun.x0 + crun.x1) / 2, (crun.z0 + crun.z1) / 2, Math.hypot(dx, dz) + 0.2, 1.1, crun.y0, crun.y1, Math.atan2(-dz, dx)]);
          crun = null;
        }
        for (var i = 0; i < sts.length - 1; i++) {
          var A = sts[i], B = sts[i + 1];
          var ca = sd < 0 ? A.L : A.R, cb = sd < 0 ? B.L : B.R;
          var mx = (ca[0] + cb[0]) / 2, mz = (ca[2] + cb[2]) / 2;
          var rx = (A.rx + B.rx) / 2, rz = (A.rz + B.rz) / 2, rl = Math.hypot(rx, rz) || 1; rx /= rl; rz /= rl;
          var edgeY = (ca[1] + cb[1]) / 2;
          var drop = edgeY - groundAt(mx + sd * rx * 2.2, mz + sd * rz * 2.2);
          var skip = drop < 1.0;
          if (!skip) for (var j = 0; j < JX.length && !skip; j++) { if (Math.hypot(ca[0] - JX[j][0], ca[2] - JX[j][1]) < 11 || Math.hypot(cb[0] - JX[j][0], cb[2] - JX[j][1]) < 11) skip = true; }
          if (!skip) for (var k = 0; k < driveMouths.length && !skip; k++) if (Math.hypot(mx - driveMouths[k][0], mz - driveMouths[k][1]) < 4.5) skip = true;
          if (!skip && (!foreignClear(ca[0], ca[2], nm, i) || !foreignClear(cb[0], cb[2], nm, i))) skip = true;
          if (skip) { flush(); }
          else {
            var y1 = Math.max(ca[1], cb[1]) - 0.5, y0 = Math.min(groundAt(ca[0], ca[2]), groundAt(cb[0], cb[2])) - 0.6;
            if (y1 - y0 < 0.7) { flush(); }
            else {
              if (run) {
                var adx = cb[0] - run.x1, adz = cb[2] - run.z1, rdx = run.x1 - run.x0, rdz = run.z1 - run.z0;
                var turn = Math.abs(Math.atan2(-adz, adx) - Math.atan2(-rdz, rdx));
                /* a merged body is ONE straight box: if the true
                 * line's last joint strays more than 0.25 m from
                 * the chord the box would draw, the run ends —
                 * a chord may never cut a bend into a neighbour's
                 * carriageway (one cut 0.62 m into Road C's edge,
                 * measured) — and no run outlasts 4 m */
                var chx = cb[0] - run.x0, chz = cb[2] - run.z0, chl = Math.hypot(chx, chz) || 1;
                var dev = Math.abs((run.x1 - run.x0) * chz - (run.z1 - run.z0) * chx) / chl;
                if (turn > 0.06 || Math.hypot(run.x1 - run.x0, run.z1 - run.z0) > 4 || dev > 0.25) flush();
              }
              /* a run's rise is capped at 0.8 m: the body's top is set
               * by its highest edge, and at the run's low end that top
               * must stay a full metre under the local surface, or the
               * collision step would nudge a walker on the shoulder.
               * On steep ground the runs simply shorten. */
              var segHi = Math.max(ca[1], cb[1]), segLo = Math.min(ca[1], cb[1]);
              if (run && (Math.max(run.hi, segHi) - Math.min(run.lo, segLo) > 0.8)) flush();
              if (!run) run = { x0: ca[0], z0: ca[2], x1: cb[0], z1: cb[2], y0: y0, y1: y1, hi: segHi, lo: segLo };
              else { run.x1 = cb[0]; run.z1 = cb[2]; if (y0 < run.y0) run.y0 = y0; if (y1 > run.y1) run.y1 = y1; if (segHi > run.hi) run.hi = segHi; if (segLo < run.lo) run.lo = segLo; }
            }
          }
          /* THE BANK'S BODY (first built as THE CLIFF'S BODY for
           * deep cuts only; widened by the King's word, 2026-10-14
           * ~00:57: "turned on collision on these roads and banks
           * and slopes but not the rails"). Now EVERY bank face
           * that rises a metre — near sample at 2.2 m out or far
           * sample at 5 m out — carries the plumb body: centred
           * 1.5 m out, from just under the road to just under the
           * land the face meets. A raycast, a walker, a car: all
           * meet the bank as a solid thing, the way they already
           * met the cliff. The shoulder keeps its air: the body's
           * inboard face stands a full metre out from the edge
           * line. Gentle aprons under a metre's rise stay open
           * ground — they are the land itself, not a face. */
          var cxp = mx + sd * rx * 1.5, czp = mz + sd * rz * 1.5;
          var riseNear = groundAt(mx + sd * rx * 2.2, mz + sd * rz * 2.2) - edgeY;
          var riseFar = groundAt(mx + sd * rx * 5, mz + sd * rz * 5) - edgeY;
          var cskip = riseNear <= 0.9 && riseFar <= 0.9;
          if (!cskip) for (var j2 = 0; j2 < JX.length && !cskip; j2++) if (Math.hypot(cxp - JX[j2][0], czp - JX[j2][1]) < 11) cskip = true;
          if (!cskip) for (var k2 = 0; k2 < driveMouths.length && !cskip; k2++) if (Math.hypot(cxp - driveMouths[k2][0], czp - driveMouths[k2][1]) < 4.5) cskip = true;
          if (!cskip && !foreignClear(cxp, czp, nm, i)) cskip = true;
          if (cskip) { cflush(); continue; }
          var cy1 = edgeY + Math.min(Math.max(riseNear, riseFar, groundAt(cxp, czp) - edgeY), 7) - 0.3, cy0 = edgeY - 0.6;
          if (cy1 - cy0 < 1.2) { cflush();