<!-- SOLID CITY · part 3205 -->
;
        xs.push(a.x + (b.x - a.x) * t); zs.push(a.z + (b.z - a.z) * t);
        var st = (j === 0 && a.station) ? a.station : (j === n && b.station) ? b.station : null;
        pin.push(st ? st.gy - 0.55 : null); isPin.push(!!st);
      }
    }
    var N = xs.length, y = new Array(N), terr = new Array(N);
    for (var i2 = 0; i2 < N; i2++) { terr[i2] = heightAt(xs[i2], zs[i2]); y[i2] = terr[i2] + 25; }
    for (var i3 = 0; i3 < N; i3++) if (pin[i3] !== null) y[i3] = pin[i3];
    for (var pass = 0; pass < 6; pass++) {
      for (var f = 1; f < N; f++) { var mx = y[f - 1] + 8 * 0.14; if (y[f] > mx) y[f] = mx; if (pin[f] !== null) y[f] = pin[f]; }
      for (var bk = N - 2; bk >= 0; bk--) { var mx2 = y[bk + 1] + 8 * 0.14; if (y[bk] > mx2) y[bk] = mx2; if (pin[bk] !== null) y[bk] = pin[bk]; }
    }
    for (var i4 = 0; i4 < N; i4++) if (pin[i4] === null) { var floor = Math.min(terr[i4] + 25, terr[i4] + 10); if (y[i4] < floor) y[i4] = floor; }
    var cum = [0];
    for (var i5 = 1; i5 < N; i5++) cum.push(cum[i5 - 1] + Math.hypot(xs[i5] - xs[i5 - 1], zs[i5] - zs[i5 - 1], y[i5] - y[i5 - 1]));
    var stationsAt = [];
    for (var i6 = 0; i6 < N; i6++) if (pin[i6] !== null) {
      /* recover which station: nearest pinned node */
    }
    route.pts = { xs: xs, ys: y, zs: zs, cum: cum, len: cum[N - 1], pin: pin };
    route.stops = [];
    var nodeIdx = 0;
    route.nodes.forEach(function (nd) {
      if (typeof nd !== 'string') return;
      var s = ST[nd];
      var best = 0, bd = 1e12;
      for (var q = 0; q < N; q++) { var d = (xs[q] - s.x) * (xs[q] - s.x) + (zs[q] - s.z) * (zs[q] - s.z); if (d < bd) { bd = d; best = q; } }
      route.stops.push({ station: s, s: cum[best], idx: best });
      nodeIdx++;
    });
    route.stops.sort(function (p, q2) { return p.s - q2.s; });
    return route;
  }
  ROUTES.forEach(buildProfile);

  function sample(route, s) {
    var P = route.pts;
    if (s <= 0) s = 0; if (s > P.len) s = P.len;
    var lo = 0, hi = P.cum.length - 1;
    while (lo < hi - 1) { var mid = (lo + hi) >> 1; if (P.cum[mid] <= s) lo = mid; else hi = mid; }
    var span = P.cum[hi] - P.cum[lo] || 1, t = (s - P.cum[lo]) / span;
    return {
      x: P.xs[lo] + (P.xs[hi] - P.xs[lo]) * t,
      y: P.ys[lo] + (P.ys[hi] - P.ys[lo]) * t,
      z: P.zs[lo] + (P.zs[hi] - P.zs[lo]) * t,
      tx: P.xs[hi] - P.xs[lo], ty: P.ys[hi] - P.ys[lo], tz: P.zs[hi] - P.zs[lo]
    };
  }

  /* ================= THE TRACK =================
   * A floating guideway: titanium beam, gold edge-light, and a
   * beacon every ~120 m — an octahedron of gold light hung just
   * above the beam, pulsing slow, so the line can be read from
   * the ground at noon and from the sky at speed. */
  var beaconPos = [];
  ROUTES.forEach(function (route) {
    var P = route.pts, pos = [], strip = [];
    function quad(arr, a, b, c, d) { arr.push(a[0], a[1], a[2], b[0], b[1], b[2], c[0], c[1], c[2], a[0], a[1], a[2], c[0], c[1], c[2], d[0], d[1], d[2]); }
    for (var i = 0; i < P.xs.length - 1; i++) {
      var ax = P.xs[i], ay = P.ys[i], az = P.zs[i], bx = P.xs[i + 1], by = P.ys[i + 1], bz = P.zs[i + 1];
      var dx = bx - ax, dz = bz - az, dl = Math.hypot(dx, dz) || 1, rx = -dz / dl, rz = dx / dl;
      var w = 0.85, dep = 0.55;
      var A1 = [ax + rx * w, ay, az + rz * w], A2 = [ax - rx * w, ay, az - rz * w], B1 = [bx + rx * w, by, bz + rz * w], B2 = [bx - rx * w, by, bz - rz * w];
      var A1b = [A1[0], ay - dep, A1[2]], A2b = [A2[0], ay - dep, A2[2]], B1b = [B1[0], by - dep, B1[2]], B2b = [B2[0], by - dep, B2[2]];
      quad(pos, A2, B2, B1, A1);              // top
      quad(pos, A1, B1, B1b, A1b);            // right side
      quad(pos, B2, A2, A2b, B2b);            // left side
      quad(pos, B1b, B2b, A2b, A1b);          // underside
      var gw = 0.16, go = w - 0.12;
      var G1 = [ax + rx * go, ay + 0.02, az + rz * go], G2 = [bx + rx * go, by + 0.02, bz + rz * go], G3 = [ax + rx * (go - gw), ay + 0.02, az + rz * (go - gw)], G4 = [bx + rx * (go - gw), by + 0.02, bz + rz * (go - gw)];
      quad(strip, G3, G4, G2, G1);
      var H1 = [ax - rx * go, ay + 0.02, az - rz * go], H2 = [bx - rx * go, by + 0.02, bz - rz * go], H3 = [ax - rx * (go - gw), ay + 0.02, az - rz * (go - gw)], H4 = [bx - rx * (go - gw), by + 0.02, bz - rz * (go - gw)];
      quad(strip, H2, H1, H3, H4);
    }
    var g1 = new T.BufferGeometry(); g1.setAttribute('position', new T.Float32BufferAttribute(pos, 3)); g1.computeVertexNormals();
    var beam = new T.Mesh(g1, MAT.titanium); beam.frustumCulled = false; group.add(beam);
    var g2 = new T.BufferGeometry(); g2.setAttribute('position', new T.Float32BufferAttribute(strip, 3)); g2.computeVertexNormals();
    var sm = new T.Mesh(g2, MAT.gold); sm.frustumCulled = false; group.add(sm);
    for (var bs = 60; bs < route.pts.len - 30; bs += 120) { var bp = sample(route, bs); beaconPos.push([bp.x, bp.y + 2.2, bp.z]); }
  });
  var beaconMesh = null;
  if (beaconPos.length) {
  