<!-- SOLID CITY · part 3010 -->
[2]); }

  /* ---------- THE ALIGNMENT — the corridor's spine ----------
   * Highway Geometric Design, learned the night the King sent
   * the curriculum (2026-10-13): a road is not a spline through
   * points. It is a chain of ELEMENTS — straights, circular arcs,
   * and CLOTHOID transitions whose curvature grows linearly with
   * distance — fitted to the surveyed line. Curvature on a
   * clothoid ramps; it cannot spike, so the two-metre radii the
   * splines invented under the hairpins cannot exist here.
   * The fitter: every surveyed vertex with a true turn becomes a
   * curve site. Its radius is the largest its tangent room
   * affords (the crew wants 26 m; the land decides), its spirals
   * are sized to the turn and shrunk gracefully where the legs
   * are short, down to a bare arc at the tightest knobs. The
   * chain is then integrated at a fine step with analytic heading
   * and curvature, closed on the final surveyed point by the
   * surveyor's own compass rule, and sampled at the corridor's
   * frequency: close in curvature, easy on the straights. */
  function fitAlignment(pts, stepCurve, stepStraight) {
    var V = pts, nv = V.length;
    var leg = [], phi = [];
    for (var li = 0; li < nv - 1; li++) {
      var dx = V[li + 1][0] - V[li][0], dz = V[li + 1][1] - V[li][1];
      leg.push(Math.hypot(dx, dz)); phi.push(Math.atan2(dx, dz));
    }
    /* curve sites with tangent rooms: each leg is shared by the
     * sites at its two ends (end legs serve one site nearly whole) */
    var sites = [];
    for (var vi = 1; vi < nv - 1; vi++) {
      var D = wrapAngle(phi[vi] - phi[vi - 1]);
      if (Math.abs(D) < 0.055) continue;
      var prevSite = sites.length && sites[sites.length - 1].v === vi - 1;
      var nextSite = false; // resolved below by leg sharing
      var roomIn = leg[vi - 1] * (prevSite ? 0.5 : 0.94);
      sites.push({ v: vi, D: D, roomIn: roomIn, roomOut: 0 });
    }
    for (var si = 0; si < sites.length; si++) {
      var s2 = sites[si];
      var hasNext = si + 1 < sites.length && sites[si + 1].v === s2.v + 1;
      s2.roomOut = leg[s2.v] * (hasNext ? 0.5 : 0.94);
      s2.room = Math.min(s2.roomIn, s2.roomOut);
    }
    /* per-site design: radius and spirals within the room */
    for (si = 0; si < sites.length; si++) {
      var s3 = sites[si], aD = Math.abs(s3.D), tanH = Math.tan(aD / 2);
      var R = Math.min(26, Math.max(6.5, s3.room * 0.92 / Math.max(tanH, 1e-3)));
      var Ls = Math.min(14, Math.max(2.5, 0.55 * R * aD));
      /* THE DEVIATION CAP — the surveyed points on the mountain
       * legs are PATH points, not PIs of an imagined design: a
       * generous arc on a hard turn swings metres inside the
       * vertex, through ground the district has already given to
       * homes. The arc's apex may stand at most ~3 m from the
       * surveyed vertex (the spline's own habit), so R shrinks
       * until the geometry honours it — at a true hairpin the
       * survey's own radius was always small, and the chain
       * degrades to it honestly. */
      var TOL_DEV = 2.0, R_FLOOR = 4.5;
      for (var dv = 0; dv < 6; dv++) {
        if (R <= R_FLOOR) break;   // the cap yields at true hairpins: a civil radius swinging wide beats a crushed kink
        var pShift = Ls * Ls / (24 * R);
        var dev = (R + pShift) * (1 / Math.cos(aD / 2) - 1);
        if (dev <= TOL_DEV) break;
        var scale = Math.max(0.45, TOL_DEV / dev * 0.92);
        R *= scale; Ls *= scale;
        if (R < R_FLOOR) { Ls *= R_FLOOR / R; R = R_FLOOR; }
      }
      function consumed(Rx, Lx) { return (Rx + Lx * Lx / (24 * Rx)) * tanH + Lx / 2 - Math.pow(Lx, 3) / (240 * Rx * Rx); }
      var guard = 0;
      while (consumed(R, Ls) > s3.room && guard++ < 6) { Ls *= 0.6; if (Ls < 1.2) { Ls = 0; break; } }
      if (consumed(R, Ls) > s3.room) { R = Math.max(4.5, s3.room / Math.max(tanH, 1e-3)); Ls = 0; }
      if (Ls > 0 && Ls / R > aD * 0.9) Ls = 0.9 * R * aD;   // the spirals may not eat the arc
      s3.R = R; s3.Ls = Ls; s3.T = consumed(R, Ls);
    }
    /* the element chain, walked forward from the first point */
    var els = [];   // {kind, len, k0, k1, h0} — curvature linear in s for clothoids
    var px = V[0][0], pz = V[0][1], hdg = phi[0];
    function pushLine(toX, toZ) {
      var d = Math.hypot(toX - px, toZ - pz);
      if (d > 0.01) els.push({ kind: 'line', len: d, k0: 0, k1: 0, h0: hdg });
      px = toX; pz = toZ;
    }
    for (si = 0; si < sites.length; si++) {
      var s4 = sites[si], vv = s4.v;
      var inX = V[vv][0] - Math.sin(phi[vv - 1]) * s4.T, inZ = V[vv][1] - Math.cos(phi[vv - 1]) * s4.T;
      pushLine(inX, inZ);
      var sgn = Math.sign(s4.D), kArc = sgn / s4.R;
      if (s4.Ls > 0.01) { els.push({ kind: 'cloth', len: s4.Ls, k0: 0, k1: kArc, h0: hdg }); hdg += kArc * s4.Ls / 2; }
      var arcSweep = s4.D - (s4.Ls > 0.01 ? kArc * s4.Ls : 0);
      if (Math.abs(arcSweep) > 1e-4) { els.push({ kind: 'arc', len: 