<!-- SOLID CITY · part 316 -->
0; if (window.CityRoyal && CityRoyal.onLand) CityRoyal.onLand(); }
    S.drive = { mesh: mesh, yaw: yaw || 0, speed: 0, _thr: 0, _str: 0, ox: ox || 0, oz: oz || 0, carId: carId || null };
    if (avatar) avatar.visible = false;
    help('You roll. Push the stick up to drive, sideways to steer. The action button steps you out.', 7);
    return true;
  },
  end: function () {
    var D = S.drive; if (!D) return false;
    var P = S.p;
    var rx = Math.cos(D.yaw), rz = -Math.sin(D.yaw);
    var lx = P.x - rx * 2.6, lz = P.z - rz * 2.6, gx = P.x + rx * 2.6, gz = P.z + rz * 2.6;
    var door = null;
    if (driveDoorOpen(lx, lz, P.x, P.z, P.y)) door = [lx, lz];
    else if (driveDoorOpen(gx, gz, P.x, P.z, P.y)) door = [gx, gz];
    if (!door) { help('No safe exit here — roll somewhere clearer and step out.', 5); return 'NO_SAFE_EXIT'; }
    if (D.mesh) { D.mesh.position.set(P.x - D.ox, P.y, P.z - D.oz); D.mesh.rotation.y = D.yaw; }
    P.x = door[0]; P.z = door[1];
    P.face = D.yaw;
    S.drive = null;
    if (avatar) avatar.visible = true;
    help('You step out. The ride stays where you left it.', 5);
    return true;
  }
};
/* RUNG 3 — ONE DART UNDER THE BICYCLE LAW (the Apply-Everything Commission, 2026-10-13).
 * VECTOR's steering law, piloted on a single car so the King can feel both
 * laws in the same lot: THE DART, first stall of the north row, first name
 * on the factory's list — id 'car0' by the factory's own parking order in
 * first-city-parking.js. His constants (the DART table of his teaching):
 * wheelbase 2.65, accel 7, brake 12, maxSteer 0.48, lateral cap 7.0.
 * yaw = (v/L) * tan(delta), with delta itself capped where the lateral
 * limit binds — so the car turns hard in the stalls and honestly wide at
 * road speed. The steering SIGN keeps the shipped convention on purpose:
 * the pilot differs in the law's shape only. Every other ride drives the
 * shipped law below, untouched. */
var BICYCLE_PILOT_ID = 'car0'; // THE DART
function driveStep(dt) {
  var D = S.drive, P = S.p; if (!D) return;
  var thr = D._thr || 0, str = D._str || 0;
  if (D.carId === BICYCLE_PILOT_ID) {
    var targetB = thr * (thr >= 0 ? 26 : 9);
    var dv = targetB - D.speed;
    var pushing = D.speed === 0 || (Math.sign(dv) === Math.sign(D.speed) && Math.abs(targetB) > Math.abs(D.speed));
    var stepF = (pushing ? 7 : 12) * dt;
    D.speed += Math.abs(dv) < stepF ? dv : Math.sign(dv) * stepF;
    if (thr === 0 && Math.abs(D.speed) < 0.03) D.speed = 0;
    var delta = str * 0.48;
    var cap = Math.atan(7.0 * 2.65 / Math.max(4, D.speed * D.speed));
    if (delta > cap) delta = cap; else if (delta < -cap) delta = -cap;
    D.yaw -= (D.speed / 2.65) * Math.tan(delta) * dt;
  } else {
    var target = thr * (thr >= 0 ? 26 : 9);
    var rate = Math.abs(target) > Math.abs(D.speed) ? 1.9 : 3.4;
    D.speed += (target - D.speed) * Math.min(1, dt * rate);
    if (thr === 0 && Math.abs(D.speed) < 0.03) D.speed = 0;
    var sf = Math.min(1, Math.abs(D.speed) / 7);
    D.yaw -= str * sf * dt * 1.75 * (D.speed < 0 ? -1 : 1);
  }
  P.x += Math.sin(D.yaw) * D.speed * dt;
  P.z += Math.cos(D.yaw) * D.speed * dt;
  P.face = D.yaw;
  if (D.mesh) { D.mesh.position.set(P.x - D.ox, P.y, P.z - D.oz); D.mesh.rotation.y = D.yaw; }
}

function returnToCity() { if (S.mode === 'fly' || S.mode === 'auto') startAuto(false); }
function startAuto(landNow) { S.mode = 'auto'; S.auto = { phase: 'cruise', land: true }; help('Autopilot: returning to the Orbital Spaceport. Move the stick to take back control.'); }
var helpTimer = 0;
function help(t, sec) { var h = $('sc-help'); h.textContent = t; h.style.opacity = 1; helpTimer = sec || 6; }

/* ---------------- walking ---------------- */

/* THE SUPPORT CLASSES (VECTOR's taxonomy, entered on the King's fix commission, 2026-10-13).
 * The morning's law made every solid's top standing ground. The review's correction: not every
 * solid is a floor. A solid now carries a MEANING, read from its maker's mark:
 *   BLOCK_ONLY      stops movement, never stands (walls, shells, columns, furniture, figures)
 *   SUPPORT         a floor by design (building roofs, monument pedestals, plinths, podia)
 *   LANDING         arrival from the air is welcome (gate lintels, dwelling roofs, the train)
 *   MOVING_SUPPORT  supports while its registry entry moves with it (the cars)
 *   DECORATIVE      no collision claim at all (none registered today; the class stands ready)
 * Unmarked solids are BLOCK_ONLY: promotion is chosen, never accidental. A post-thin solid
 * (either footprint side under 0.8 m) never supports, whatever its mark — no one stands on a
 * post cap. solidsTop() itself is unchanged: collision measurement still sees every solid;
 * only STANDING is classified, through solidsTopSupport(). */
var SUPPORT_TAGS = {
  hyperCity: 'SUPPORT', annex: 'SUPPORT', campus: 'SUPPORT', colosseum: 'SUPPORT',
  monument: 'SUPPORT', podium: 'SUPPORT', quadrantcrown: 'SUPPORT', spaceport: 'S