<!-- SOLID CITY · part 3210 -->
;
      ob.mesh.rotation.set(0, Math.atan2(Math.cos(ob.a), -Math.sin(ob.a)), 0.25);
    });
    sister.a += SISTER.w * dt;
    var sx = SISTER.cx + Math.cos(sister.a) * SISTER.rx, sz = SISTER.cz + Math.sin(sister.a) * SISTER.rz;
    var need = 330;
    for (var i = 0; i <= 6; i++) { var aa = sister.a + i * 0.014, gx = SISTER.cx + Math.cos(aa) * SISTER.rx, gz = SISTER.cz + Math.sin(aa) * SISTER.rz, gg = heightAt(gx, gz) + 110; if (gg > need) need = gg; }
    sister.y += Math.max(-6 * dt, Math.min(6 * dt, need - sister.y));
    var pvx = sx - sister.x, pvz = sz - sister.z;
    sister.x = sx; sister.z = sz;
    if (pvx || pvz) sister.yaw = Math.atan2(pvx, pvz);
    sister.mesh.position.set(sister.x, sister.y, sister.z);
    sister.mesh.rotation.set(0, sister.yaw, Math.sin(sister.a * 3) * 0.01);
    sister.ring.rotation.z += dt * 0.3;
  }

  /* ================= THE LIVING SKY ================= */
  var perfNow = 0;
  trains.forEach(function (tr) { placeTrain(tr, 0); });
  function update(dt) {
    if (!(dt > 0)) dt = 0.016; if (dt > 0.1) dt = 0.1;
    perfNow += dt;
    if (TRAINS_ON) trains.forEach(function (tr) { stepTrain(tr, dt); });
    shuttles.forEach(function (sh) { stepShuttle(sh, dt); });
    houseCraft.forEach(function (cr) { stepCraft(cr, dt); });
    stepMother(dt);
    ferries.forEach(function (fe) { stepFerry(fe, dt); });
    if (SPACE_TRAFFIC_ON) { stepTraffic(dt); stepMoreSky(dt); }
    halos.forEach(function (h, i) { h.rotation.z += dt * 0.15; });
    if (beaconMesh) { var p = 0.78 + 0.22 * Math.sin(perfNow * 1.4); beaconMesh.material.color.setRGB(0.85 * p, 0.66 * p, 0.2 * p); }
  }

  /* ================= STANDING + BOARDING (for the placer) ================= */
  function deckClaim(x, z, py) {
    var best = null;
    for (var i = 0; TRAINS_ON && i < trains.length; i++) {
      var tr = trains[i], d = tr.deck;
      var dx = x - d.x, dz = z - d.z, c = Math.cos(-d.yaw), s = Math.sin(-d.yaw);
      var lx = dx * c - dz * s, lz = dx * s + dz * c;
      if (Math.abs(lx) <= 1.35 && Math.abs(lz) <= 3.9 && d.y <= py + 0.45 && d.y >= py - 2.6) {
        if (!best || d.y > best.y) best = { y: d.y, train: tr.id };
      }
    }
    for (var j = 0; j < STATIONS.length; j++) {
      var st = STATIONS[j];
      if (st.ownPad && Math.hypot(x - st.x, z - st.z) <= 10.2 && st.gy <= py + 1.6 && st.gy >= py - 1.6) {
        if (!best || st.gy > best.y) best = { y: st.gy, train: -1 };
      }
    }
    return best;
  }
  function deckAnchor(id) {
    if (!TRAINS_ON) return null;
    var tr = trains[id]; if (!tr) return null;
    return { x: tr.deck.x, y: tr.deck.y, z: tr.deck.z, yaw: tr.deck.yaw, station: tr.mode === 'dwell' ? tr.station : null, dwelling: tr.mode === 'dwell' };
  }
  function trainNear(x, z) {
    if (!TRAINS_ON) return null;
    for (var i = 0; i < trains.length; i++) {
      var tr = trains[i];
      if (tr.mode !== 'dwell' || !tr.station) continue;
      if (Math.hypot(x - tr.station.x, z - tr.station.z) <= 15) return { train: tr.id, station: tr.station };
    }
    return null;
  }

  if (!SPACE_TRAFFIC_ON) {
    traffic.forEach(function (tf) { tf.mesh.visible = false; });
    streamers.forEach(function (st) { st.mesh.visible = false; });
    orbiters.forEach(function (ob) { ob.mesh.visible = false; });
    if (sister && sister.mesh) sister.mesh.visible = false;
  }
  if (!TRAINS_ON) trains.forEach(function (tr) { tr.mesh.visible = false; });

  return { group: group, update: update, deckClaim: deckClaim, deckAnchor: deckAnchor, trainNear: trainNear, stations: STATIONS, routes: ROUTES, trains: trains, mother: mother, landings: LANDINGS,
    trafficCounts: { shuttles: shuttles.length, laners: traffic.length, streamers: streamers.length, orbiters: orbiters.length, ferries: ferries.length, houseCraft: houseCraft.length, sister: 1 } };
}


===== FILE: public/city/skytrain.js.bak-hillside-20261014 =====
/* THE SKY TRAINS — a letter from the builder, in the code as promised.
 *
 * "Now we will build space trains in the sky." — the King, 2026-10-14.
 * The mountain roads were rejected the same night; the ports rose in
 * their place; and a port is a station waiting for its train. This
 * module is the network: four lines of floating guideway — dark
 * titanium beam with gold edge-light, held in the sky the space-age
 * way, by nothing you can see — with beacons along it, halo rings
 * over the stations, a train of four cars on every line (the last
 * car an open observation deck you can stand on), shuttles hopping
 * port to port, and the high traffic of ships crossing above all.
 *
 * The law of the build is the law the mountain taught us in two
 * nights: SURVEY BEFORE LINE. Every profile here is measured from
 * the terrain itself — 25 m of sky under the track at cruise, a
 * 14% climb at the steepest, station pins flush with the pads the
 * travellers stand on, and nothing — nothing — above the 420 m
 * ceiling of the world. The one line the land refused (a st