<!-- SOLID CITY · part 431 -->
artAuto(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 the 1.6 gate — transcribed, not reinterpreted, so the
 * fleet's world adapter (and any future instrument) reads the fabric from one source.
 * py is the asker's current height (the walker's P.y); it defaults to the ground
 * itself. LAW OF THE TWO LISTS: a hook added to the walk chain below is added here
 * in the same breath, or the two laws drift and craft and walker disagree. */
function standingAt(x, z, py) {
  var gy = groundAt(x, z); if (gy < 0.5) { gy = 0.5; }
  if (py == null) py = gy;
  if (window.CityForge) { var fy = CityForge.standY(x, z, py); if (fy > gy) gy = fy; }
  if (window.CityAncestorRoads && CityAncestorRoads.topY) { var ap = CityAncestorRoads.pos; if (Math.hypot(x - ap.x, z - ap.z) < 560) { var ay = CityAncestorRoads.topY(); if (ay > gy) gy = ay; } }
  if (window.CityVillageMauna && CityVillageMauna.standY) { var vy = CityVillageMauna.standY(x, z); if (vy > gy) gy = vy; }
  if (window.CityMountainHomes && CityMountainHomes.standY) { var mhy = CityMountainHomes.standY(x, z, py); if (mhy > gy) gy = mhy; }
  if (window.CityTunnelBore && CityTunnelBore.standY) { var ty = CityTunnelBore.standY(x, z); if (ty > gy) gy = ty; }
  if (window.CityStarwell && CityStarwell.standY) { var wy = CityStarwell.standY(x, z); if (wy > gy) gy = wy; }
  if (window.CityHyperTrain && CityHyperTrain.standY) { var hy = CityHyperTrain.standY(x, z); if (hy > gy) gy = hy; }
  if (window.CityHyperCity && CityHyperCity.standY) { var hcy = CityHyperCity.standY(x, z); if (hcy > gy) gy = hcy; }
  if (window.CityAnnex && CityAnnex.standY) { var any = CityAnnex.standY(x, z); if (any > gy) gy = any; }
  if (window.CityQuadrantCrown && CityQuadrantCrown.standY) { var qcy = CityQuadrantCrown.standY(x, z); if (qcy > gy) gy = qcy; }
  if (window.CitySpaceport && CitySpaceport.standY) { var spy = CitySpaceport.standY(x, z); if (spy > gy) gy = spy; }
  if (window.CityLostWings && CityLostWings.standY) { var lwy = CityLostWings.standY(x, z, py); if (l