<!-- SOLID CITY · part 2617 -->
   // the aprons' ring samples, recorded for the clearance law   // name -> the smith's built road
  function pourSurf(surf, batch, color) {
    if (!surf.pos.length) return;
    var g = new T.BufferGeometry();
    g.setAttribute('position', new T.Float32BufferAttribute(surf.pos, 3));
    g.setAttribute('normal', new T.Float32BufferAttribute(surf.nor, 3));
    batch.add(g, new T.Matrix4(), color);
  }
  function triPush(S, a, b, c) {
    var ux = b[0] - a[0], uy = b[1] - a[1], uz = b[2] - a[2];
    var vx = c[0] - a[0], vy = c[1] - a[1], vz = c[2] - a[2];
    var nx = uy * vz - uz * vy, ny = uz * vx - ux * vz, nz = ux * vy - uy * vx;
    var L = Math.hypot(nx, ny, nz) || 1;
    if (ny < 0) { var t = b; b = c; c = t; nx = -nx; ny = -ny; nz = -nz; }
    S.pos.push(a[0], a[1], a[2], b[0], b[1], b[2], c[0], c[1], c[2]);
    for (var i = 0; i < 3; i++) S.nor.push(nx / L, ny / L, nz / L);
  }
  // a junction APRON: a fan whose rim is stitched to the roads
  // themselves — each rim point takes its height from the nearest
  // stations' own planes (grade along, bank across), the highest
  // claim winning, as the world's standing law also takes the
  // highest — so the apron meets every road on that road's own
  // terms, and its skirts fall to the land. A disc planed from one
  // station is a table wherever the host's own surface curves;
  // an apron stitched to all the roads is a junction.
  function apronAt(x, z, host) {
    var S = { pos: [], nor: [] }, SEG = 20, fr = 7.0, ctr = [x, host.y + 0.03, z];
    var all = [];
    for (var rn in smithRoads) all = all.concat(smithRoads[rn].stations);
    function heightAt(px, pz) {
      var best = null, wsum = 0, ysum = 0;
      for (var q = 0; q < all.length; q++) {
        var s2 = all[q], dx = px - s2.x, dz = pz - s2.z;
        var dd = dx * dx + dz * dz;
        if (dd > 100) continue;
        var y = s2.y + s2.grade * (dx * s2.fx + dz * s2.fz) + Math.tan(s2.bank) * (dx * s2.rx + dz * s2.rz);
        var wgt = 1 / ((dd + 0.5) * (dd + 0.5)); wsum += wgt; ysum += wgt * y;
      }
      best = wsum > 0 ? ysum / wsum : host.y + host.grade * ((px - x) * host.fx + (pz - z) * host.fz) + Math.tan(host.bank) * ((px - x) * host.rx + (pz - z) * host.rz);
      return best + 0.03;
    }
    var rim = [];
    for (var k = 0; k < SEG; k++) { var an = k / SEG * Math.PI * 2, px = x + Math.cos(an) * fr, pz = z + Math.sin(an) * fr; rim.push([px, heightAt(px, pz), pz]); }
    // THE FAIRING OF THE RIM: two passes of a quarter, a half,
    // a quarter around the circle — no single sector is asked
    // to climb the whole braid at once.
    for (var fp = 0; fp < 2; fp++) { var fairs = rim.map(function (r3, ri) { var rp2 = rim[(ri + SEG - 1) % SEG], rn2 = rim[(ri + 1) % SEG]; return [r3[0], rp2[1] * 0.25 + r3[1] * 0.5 + rn2[1] * 0.25, r3[2]]; }); rim = fairs; }
    for (k = 0; k < SEG; k++) {
      var r1 = rim[k], r2 = rim[(k + 1) % SEG];
      triPush(S, ctr, r1, r2);
      standTris.push(ctr[0], ctr[1], ctr[2], r1[0], r1[1], r1[2], r2[0], r2[1], r2[2]);
      var d1 = [r1[0], groundAt(r1[0], r1[2]) - 0.3, r1[2]], d2 = [r2[0], groundAt(r2[0], r2[2]) - 0.3, r2[2]];
      triPush(S, r1, r2, d2); triPush(S, r1, d2, d1);
    }
    for (var rk = 0; rk < 24; rk++) { var ra = rk / 24 * Math.PI * 2, rpx = x + Math.cos(ra) * 5.5, rpz = z + Math.sin(ra) * 5.5; apronSamples.push([rpx, rpz, heightAt(rpx, rpz)]); }
    pourSurf(S, solid, C.mtn);   // LIKE THE MOUNTAIN (2026-10-14): the junction discs are mountain ground too
  }
  function buildRoads() {
    var smith = createRoadSmith({ groundAt: groundAt });
    var triBase = standTris.length;   // the clearance law judges the roads' and aprons' triangles
    function buildOne(name, points, furniture, pinY, pinEndY, pinHost, taperStart, taperEnd) {
      var spec = { points: points, width: 7.6, furniture: furniture };
      if (pinY != null) spec.pinStartY = pinY;
      if (pinEndY != null) spec.pinEndY = pinEndY;
      if (pinHost) spec.pinHost = pinHost;
      if (taperStart) spec.taperStart = taperStart;
      if (taperEnd) spec.taperEnd = taperEnd;
      var built = smith.buildRoad(spec);
      /* LIKE THE MOUNTAIN (the King's word, 2026-10-14 ~01:00):
       * "it should be like the mountain" — on the bench roads
       * the pavement itself wears the mountain dark green, not
       * gray: ribbon and arrival fans alike. The city streets
       * keep their gray and gold; the mountain keeps its green. */
      pourSurf(built.ribbon, solid, furniture === 'bench' ? C.mtn : C.road);
      /* THE SLOPES WEAR THE MOUNTAIN (the King's word, 2026-10-13
       * ~23:47): "these slopes could be grass colored and mesh
       * with the mountain." The whole slope — brow slabs and deep
       * banks alike — pours in lawn green now, one grass hillside
       * from the road's edge to the land it was cut from. The
       * stone brow stands down. */
      pourSurf(built.skirtL, solid, C.mtn); pourSurf(built.skirtR, 