<!-- SOLID CITY · part 3033 -->
ts[fk], pa, pb); if (dv > fd) fd = dv; }
          faceDev[i2] = fd;
        }
        else { prof[i2] = null; brow[i2] = null; foot[i2] = null; mid[i2] = null; low[i2] = null; faceDev[i2] = 99; }
      }
      function dev3(p, a, b) {
        var abx = b[0] - a[0], aby = b[1] - a[1], abz = b[2] - a[2];
        var t = ((p[0] - a[0]) * abx + (p[1] - a[1]) * aby + (p[2] - a[2]) * abz) / (abx * abx + aby * aby + abz * abz || 1);
        t = Math.max(0, Math.min(1, t));
        var dx = p[0] - (a[0] + abx * t), dy = p[1] - (a[1] + aby * t), dz = p[2] - (a[2] + abz * t);
        return Math.sqrt(dx * dx + dy * dy + dz * dz);
      }
      function skinQuad(iA, iB) {
        var pA = prof[iA], pB = prof[iB];
        var outw = [sdSign * st[iA].rx, sdSign * st[iA].rz];
        var nSeg = Math.min(pA.length, pB.length) - 1;
        for (var dk = 2; dk < nSeg; dk++) {
          var sf3 = stepSurf(pA, pB, dk, bankGrass);
          quad(sf3, pA[dk], pB[dk], pB[dk + 1], pA[dk + 1], outw);
          quad(sf3, pB[dk], pA[dk], pA[dk + 1], pB[dk + 1], outw);
        }
      }
      var a3 = 0;
      while (a3 < N - 1) {
        if (!prof[a3]) { a3++; continue; }
        var tame = a3;
        /* THE SLAB MEASURE (the King's word, 2026-10-13 ~23:45):
         * the tame run now reaches 40 stations — a fifty-metre
         * slab where the hillside runs true — and FOUR surveyed
         * lines guard it: brow, mid-slope, NEAR-FOOT, and foot
         * must each hold within 0.45 m of straight, so a long slab
         * can never bridge a hollow the stitch would have tucked
         * into. (The near-foot line was added after the study's
         * probe audit: the unguarded foot half of the face was
         * where the last metre-scale bows lived.) */
        while (tame < N - 1 && tame - a3 < 40) {
          var nx = tame + 1;
          if (!prof[nx]) break;
          var bad = false;
          for (var m = a3 + 1; m < nx; m++) {
            if (!prof[m]) { bad = true; break; }
            if (dev3(brow[m], brow[a3], brow[nx]) > 0.45 || dev3(foot[m], foot[a3], foot[nx]) > 0.45 || dev3(mid[m], mid[a3], mid[nx]) > 0.45 || dev3(low[m], low[a3], low[nx]) > 0.45) { bad = true; break; }
          }
          if (!bad && (faceDev[a3] > 0.45 || faceDev[nx] > 0.45)) bad = true;
          if (!bad) for (var m2 = a3 + 1; m2 < nx; m2++) if (faceDev[m2] > 0.6) { bad = true; break; }
          if (bad) break;
          tame = nx;
        }
        if (tame > a3 + 1) {
          var outw3 = [sdSign * st[a3].rx, sdSign * st[a3].rz];
          /* a tame face that RISES as one wall (a uniform cliff)
           * pours as stone, not grass */
          var sfT = bankGrass;
          var runA = Math.hypot(foot[a3][0] - brow[a3][0], foot[a3][2] - brow[a3][2]), runB = Math.hypot(foot[tame][0] - brow[tame][0], foot[tame][2] - brow[tame][2]);
          if (((foot[a3][1] - brow[a3][1]) / Math.max(runA, 0.01)) >= 1.2 || ((foot[tame][1] - brow[tame][1]) / Math.max(runB, 0.01)) >= 1.2) sfT = cliffW;
          quad(sfT, brow[a3], brow[tame], foot[tame], foot[a3], outw3);
          quad(sfT, brow[tame], brow[a3], foot[a3], foot[tame], outw3);
          a3 = tame;
        } else {
          if (prof[a3 + 1]) skinQuad(a3, a3 + 1);
          a3++;
        }
      }
    }
    bankSkin(drapeCacheL, -1); bankSkin(drapeCacheR, 1);
    /* arrival fans at both ends. A fan is not a flat disc dropped on
     * the ramp's end — the first drive-through caught that step
     * (0.9 m at the seam). The fan is the road's own PLANE extended:
     * each rim vertex carries the end grade along the road's axis
     * and the end bank across it, so ribbon and fan meet as one
     * surface. Rim skirts below, so they never float. */
    var ends = [st[0], st[N - 1]];
    for (var e = 0; e < 2; e++) {
      var C0 = ends[e], fr = C0.hw + 0.9, SEG = 14;
      var src = e === 0 ? st[1] : st[N - 2];
      var fGrade = e === 0 ? src.grade : st[N - 1].grade;
      var fBank = Math.tan(src.bank);
      var rim = [];
      for (var k2 = 0; k2 < SEG; k2++) {
        var an = k2 / SEG * Math.PI * 2;
        var dxr = Math.cos(an) * fr, dzr = Math.sin(an) * fr;
        var along = dxr * C0.fx + dzr * C0.fz, across = dxr * C0.rx + dzr * C0.rz;
        rim.push([C0.x + dxr, C0.y + fGrade * along + fBank * across, C0.z + dzr]);
      }
      var rimProf = rim.map(function (rp) { var dl = Math.hypot(rp[0] - C0.x, rp[2] - C0.z) || 1; return drapeFrom(rp, (rp[0] - C0.x) / dl, (rp[2] - C0.z) / dl).pts; });
      /* the fan's centre stays wedged (it is standing truth), but
       * its rim is slabbed like the banks (the Slab Pass): wedges
       * group while rim and brow lines hold within 0.3 m of the
       * group's chord, up to six wedges a slab */
      function fdev(p, a, b) {
        var abx = b[0] - a[0], aby = b[1] - a[1], abz = b[2] - a[2];
        var t = ((p[0] - a[0]) * abx + (p[1] - a[1]) * aby + (p[2] - a[2]) * abz) / (abx * abx + aby * aby + abz