<!-- SOLID CITY · part 759 -->
w.CityFirstParking && CityFirstParking.standY) { var py = CityFirstParking.standY(x, z, floorY); if (py > gy) gy = py; }
  return gy >= floorY - 1.2 && gy <= floorY + STEP_UP;
}
function driveDoorOpen(x, z, cx, cz, floorY) {
  if (!driveDoorClear(x, z, floorY)) return false;
  if (!driveDoorClear((x + cx) / 2, (z + cz) / 2, floorY)) return false; // the swept step between
  return driveDoorStand(x, z, floorY);
}
window.CityDrive = {
  active: function () { return !!S.drive; },
  state: function () { return S.drive || null; },
  begin: function (mesh, yaw, ox, oz, carId) {
    /* A DOOR THAT SPEAKS (the King's report, 2026-10-13 ~23:20):
     * he flew to the South Lot, came down on the Tug's own roof,
     * and the ROLL button "won't let me in" — the old law refused
     * in silence whenever the flight flag still stood, and a
     * silent refusal reads as a broken button. Now: a flight ends
     * by the choosing (no one boards from the air; stepping in IS
     * the landing), and every other refusal names itself aloud. */
    if (S.drive) { help('Already rolling — step out first.', 4); return false; }
    if (S.mode !== 'walk') { help('Roll from on foot — not while ' + S.mode + '.', 4); return false; }
    if (S.rfly) { S.rfly = false; S.rflyLand = false; S.rflyV = 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; }

/* ---------