<!-- SOLID CITY · part 592 -->
ry'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: 'SUPPORT',
  starwell: 'SUPPORT', foundry: 'SUPPORT', hallBecoming: 'SUPPORT', hiddenShip: 'SUPPORT',
  overlookMira: 'SUPPORT', sanctuary: 'SUPPORT', book: 'SUPPORT', firstWard: 'SUPPORT',
  gateAncestors: 'LANDING', eighthGate: 'LANDING', mountainHomes: 'LANDING',
  villageMauna: 'LANDING', hyperTrain: 'LANDING', tunnelBore: 'LANDING',
  betweenStones: 'LANDING', lostWings: 'LANDING', ancestorRoads: 'LANDING'
};
function supportClass(q) {
  if (!q) return 'BLOCK_ONLY';
  if (q.sup) return q.sup;
  for (var k in q) { if (typeof q[k] === 'string' && q[k].indexOf('car:') === 0) return 'MOVING_SUPPORT'; }
  if ((q.x1 - q.x0) < 0.8 || (q.z1 - q.z0) < 0.8) return 'BLOCK_ONLY';
  for (var t in SUPPORT_TAGS) if (q[t]) return SUPPORT_TAGS[t];
  return 'BLOCK_ONLY';
}
function solidsTopSupport(x, z, pad) {
  var t = -1e9;
  for (var k = 0; k < solids.length; k++) {
    var q = solids[k], c = supportClass(q);
    if (c !== 'SUPPORT' && c !== 'LANDING' && c !== 'MOVING_SUPPORT') continue;
    if (x > q.x0 - pad && x < q.x1 + pad && z > q.z0 - pad && z < q.z1 + pad && q.y1 > t) t = q.y1;
  }
  return t;
}
/* THE STANDING LAW, READABLE — standingAt(x, z, py) answers the question updateWalk
 * answers for the walker every frame: what holds a body up at this point? It is the
 * same chain in the same order — the clamped earth, every named standY hook, then the
 * support-classed solids under t