<!-- SOLID CITY · part 884 -->
flyT = 0; S.rflyV = 0; help('You rise. Climb and sink with the gold arrows (or R / F). Tap WALK to land.', 6); }
    else if (!on && S.rfly) { S.rflyLand = true; }
    return true;
  },
  flying: function () { return !!S.rfly; },
  setRise: function (v) { S.rflyRise = v; },
  onLand: null
};
/* FIRST DRIVES (2026-10-13) — the South Lot rides. The avatar is the real
   human of this world; the rides were built for him to roll in. CityDrive
   owns the drive state and updateWalk integrates it (driveStep), exactly
   the way royal flight is integrated: one sanctioned hook in the physics.
   Any visitor may roll a lot ride, as any visitor may ride the train. */
/* RUNG 2 — THE DOORS ARE SEARCHED (the Apply-Everything Commission, 2026-10-13).
 * VECTOR's exit contract, entered after the Rung 1 survey found the old
 * step-out blind: it placed the avatar 2.6 m to the car's left with no
 * clearance and no standing test. Now both doors are searched — left
 * first, as the city has always stepped out — and each candidate must
 * pass two tests in the city's own terms: no blocker (a solid whose body
 * occupies the landing, judged at the walker's own radius) and stand
 * permission (a surface the walker himself could stand on: terrain,
 * classified support, or the parking system's own surfaces, inside the
 * walker's 1.6 eligibility gate and with no drop greater than 1.2). If
 * neither door is lawful, the exit is REFUSED — NO_SAFE_EXIT — and the
 * driver stays seated. A refusal is a door that would have hurt him,
 * named instead of opened. */
function driveDoorClear(x, z, floorY) {
  for (var k = 0; k < solids.length; k++) {
    var s = solids[k];
    if (s.y1 <= floorY + 0.55) continue; // a floor at the feet, not a blocker
    if (s.y0 >= floorY + 1.7) continue; // above the head — the walker passes under
    if (x > s.x0 - 0.45 && x < s.x1 + 0.45 && z > s.z0 - 0.45 && z < s.z1 + 0.45) return false;
  }
  return true;
}
function driveDoorStand(x, z, floorY) {
  var gy = groundAt(x, z); if (gy < 0.5) gy = 0.5;
  var sty = solidsTopSupport(x, z, 0); if (sty > gy) gy = sty;
  if (window.CityFirstParking && CityFirstParking.standY) { var py = CityFirstParking.standY(x, z, floorY); if (py > gy) gy = py; }
  return gy >= floorY - 1.2 && gy <= floorY + 1.6;
}
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) {
    if (S.mode !== 'walk' || S.rfly || S.drive) return false;
    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) && 