<!-- SOLID CITY · part 2149 -->
]);
  var arrTrim = new T.Mesh(new T.TorusGeometry(9, 0.22, 8, 40), goldBasic);
  arrTrim.rotation.x = Math.PI / 2; arrTrim.position.set(0, 1.02, Z_ARRIVAL); root.add(arrTrim);
  var arrPlaque = namePlaque(T, 'THE ARRIVAL', 7, stoneMat);
  arrPlaque.position.set(11.5, 2.6, Z_ARRIVAL); arrPlaque.rotation.y = 0.55; root.add(arrPlaque);
  foot.push([11.5, Z_ARRIVAL, 2, 2, 0, 4, 0]);
  var arrLamp = new T.PointLight(0xffd9a0, 1.2, 30); arrLamp.position.set(0, 5, Z_ARRIVAL); root.add(arrLamp);

  // transit overlay (fullscreen bloom)
  var overlay = document.createElement('div');
  overlay.style.cssText = 'position:fixed;inset:0;pointer-events:none;z-index:9998;opacity:0;' +
    'background:radial-gradient(circle at 50% 50%, rgba(255,252,245,1) 0%, rgba(255,240,210,0.85) 30%, rgba(150,120,255,0.35) 65%, rgba(0,0,0,0) 100%);' +
    'transition:opacity 0.45s ease;';
  document.body.appendChild(overlay);

  // ================= state =================
  var ST = {
    mode: 'docked-station', // docked-station | ride-out | transit-out | docked-arrival | ride-back | transit-back
    t: 0, transitT: 0, s: 0, // s = distance along ride
    dir: 1
  };
  function trainWorld() {
    return { x: P.x + train.position.x, z: P.z + train.position.z };
  }
  function setRiding(on) {
    try {
      var av = window.SC && SC.api && SC.api.avatar;
      if (av) av.visible = !on;
    } catch (e) {}
    ST.riding = on;
  }

  root.userData = {
    footprint: foot, center: { x: 8, z: -400 }, radius: 460,
    state: ST,
    trainPos: trainWorld,
    // called by city.js action system
    actHere: function (wx, wz) {
      if (ST.riding) return null;
      var tw = trainWorld();
      var d = Math.hypot(wx - tw.x, wz - tw.z);
      if (ST.mode === 'docked-station' && d < 9) return 'BOARD TRAIN → STARWELL';
      if (ST.mode === 'docked-arrival' && d < 9) return 'BOARD TRAIN → THE BORE';
      return null;
    },
    board: function () {
      if (ST.riding) return;
      if (ST.mode !== 'docked-station' && ST.mode !== 'docked-arrival') return;
      ST.dir = ST.mode === 'docked-station' ? 1 : -1;
      ST.mode = ST.dir === 1 ? 'ride-out' : 'ride-back';
      ST.t = 0; ST.s = 0;
      setRiding(true);
    },
    update: function (t, dt, api) {
      var i;
      // wormhole: golden-angle spin + shimmer
      for (i = 0; i < rings.length; i++) {
        rings[i].m.rotation.z += rings[i].sp * dt;
        rings[i].b.rotation.z -= rings[i].sp * dt * 0.7;
      }
      var sh = 1 + Math.sin(t * 2.4) * 0.035;
      worm.scale.set(sh, sh, 1);
      wormLight.intensity = 2.4 + Math.sin(t * 3.1) * 0.5;
      throatTex.offset.y = (t * 0.35) % 1;
      lampL.intensity = 1.2 + Math.sin(t * 2.0) * 0.15;
      crown.scale.setScalar(1 + Math.sin(t * 3) * 0.1);

      if (!ST.riding) return;
      var S = api.S;
      if (ST.mode === 'ride-out' || ST.mode === 'ride-back') {
        ST.t += dt;
        // physics: ease-in 3s, cruise, ease-out 3s
        var v;
        if (ST.t < 3) v = VMAX * ST.t / 3;
        else if (ST.t < RIDE_T - 3) v = VMAX;
        else v = Math.max(0, VMAX * (RIDE_T - ST.t) / 3);
        ST.s += v * dt;
        var z0 = ST.dir === 1 ? Z_STATION : Z_ARRIVAL;
        var z = z0 - ST.dir * ST.s;
        // clamp at the wormhole approach
        var zEnd = ST.dir === 1 ? Z_WORM + 5 : Z_WORM - 5;
        if ((ST.dir === 1 && z <= zEnd) || (ST.dir === -1 && z >= zEnd) || ST.t >= RIDE_T) {
          z = zEnd;
          ST.mode = ST.dir === 1 ? 'transit-out' : 'transit-back';
          ST.transitT = 0;
          overlay.style.opacity = '1';
        }
        train.position.z = z;
        // the rider travels with the train
        S.p.x = P.x + train.position.x; S.p.z = P.z + z; S.p.y = P.y + 3.4;
        S.p.face = ST.dir === 1 ? Math.PI : 0;
      } else if (ST.mode === 'transit-out' || ST.mode === 'transit-back') {
        ST.transitT += dt;
        // hold the rider at the wormhole's heart
        S.p.x = P.x; S.p.z = P.z + (Z_WORM - 2); S.p.y = P.y + 3.4;
        train.position.z = Z_WORM - 2;
        train.visible = ST.transitT < 1.2; // swallowed by the light
        if (ST.transitT > 0.9) overlay.style.opacity = '0';
        if (ST.transitT >= 2.6) {
          train.visible = true;
          if (ST.mode === 'transit-out') {
            train.position.z = Z_ARRIVAL; ST.mode = 'docked-arrival';
          } else {
            train.position.z = Z_STATION; ST.mode = 'docked-station';
          }
          setRiding(false);
          // step the rider onto the platform beside the train
          S.p.x = P.x + 6; S.p.z = P.z + train.position.z + 2; S.p.y = P.y + 1.2;
          try { var av2 = SC.api.avatar; if (av2) av2.visible = true; } catch (e) {}
          try { if (api.help) api.help(ST.mode === 'docked-arrival' ? 'The Starwell. You crossed the fold.' : 'The Bore mouth. The mountain remembers.'); } catch (e) {}
        }
      }
    }
  };
  return root;
}
export default createHyperTrain;


=====