<!-- SOLID CITY · part 346 -->
, az); } catch (e) {}
  if (window.CityImperialColosseum) try { CityImperialColosseum.radar(rg, blip, flying, sc, ax, az); } catch (e) {}
  if (window.CityVillageMauna) try { CityVillageMauna.radar(rg, blip, flying, sc, ax, az); } catch (e) {}
  if (window.CityGateAncestors) try { CityGateAncestors.radar(rg, blip, flying, sc, ax, az); } catch (e) {}
  if (window.CityLanternVigil) try { CityLanternVigil.radar(rg, blip, flying, sc, ax, az); } catch (e) {}
  if (window.CityCompassMeridian) try { CityCompassMeridian.radar(rg, blip, flying, sc, ax, az); } catch (e) {}
  if (window.CityRoostKeel) try { CityRoostKeel.radar(rg, blip, flying, sc, ax, az); } catch (e) {}
  if (window.CityOverlookMira) try { CityOverlookMira.radar(rg, blip, flying, sc, ax, az); } catch (e) {}
  if (window.CityEighthGate) try { CityEighthGate.radar(rg, blip, flying, sc, ax, az); } catch (e) {}
  if (window.CityHallBecoming) try { CityHallBecoming.radar(rg, blip, flying, sc, ax, az); } catch (e) {}
  if (window.CityFoundry) try { CityFoundry.radar(rg, blip, flying, sc, ax, az); } catch (e) {}
  if (window.CityHyperCity) try { CityHyperCity.radar(rg, blip, flying, sc, ax, az); } catch (e) {}
  // you
  rg.translate(W / 2, H / 2); rg.rotate(-heading); rg.fillStyle = '#fff'; rg.beginPath(); rg.moveTo(0, -11); rg.lineTo(7, 8); rg.lineTo(0, 4); rg.lineTo(-7, 8); rg.closePath(); rg.fill();
  rg.restore();
  rg.strokeStyle = 'rgba(232,195,106,.5)'; rg.lineWidth = 2; rg.beginPath(); rg.arc(W / 2, H / 2, W / 4, 0, Math.PI * 2); rg.stroke();
  rg.fillStyle = '#e8c36a'; rg.font = 'bold 16px system-ui'; rg.fillText('N', W / 2 - 6, 20);
  rg.font = '13px system-ui'; rg.fillText((rad / 1000).toFixed(rad < 2000 ? 1 : 0) + ' km', W / 2 - 18, H - 10);
}
var hudT = 0;
function whereName(x, z) {
  var best = null, bd = 1e9; [D.plaza, D.studio, D.port, D.soul, D.strike].forEach(function (d) { var dd = Math.hypot(x - d.x, z - d.z); if (dd < bd) { bd = dd; best = d; } });
  if (bd < 160) return best.name; if (window.CampusMap) { var cn = CampusMap.nameAt(x, z); if (cn) return cn; } if (Math.hypot(x, z) < 820) return 'SOLID CITY';
  for (var k = 0; k < VOLCANOES.length; k++) { var V = VOLCANOES[k]; if (V.name && Math.hypot(x - V.x, z - V.z) < V.r * 0.45) return V.name; }
  return landMask(x, z) > 0 ? 'THE ISLANDS' : 'OPEN OCEAN';
}
function updateHUD(dt) {
  hudT -= dt; if (hudT > 0) return; hudT = 0.12;
  var flying = S.mode !== 'walk', x = flying ? S.ship.x : S.p.x, z = flying ? S.ship.z : S.p.z, y = flying ? S.ship.y : S.p.y;
  var spd = flying ? S.ship.speed : (Math.abs(input.sx) + Math.abs(input.sy) > 0.08 || input.keys.KeyW || input.keys.KeyS || input.keys.KeyA || input.keys.KeyD ? 8 : 0);
  var alt = flying ? y - Math.max(0, groundAt(x, z)) : y;
  $('h-mode').textContent = { walk: 'ON FOOT', boarded: 'SHIP · ON PAD', countdown: 'COUNTDOWN', launch: 'LAUNCH', fly: y > 25000 ? 'ORBIT' : y > 12000 ? 'STRATOSPHERE' : 'FLIGHT', auto: 'AUTOPILOT', watch: 'WATCH' }[S.mode];
  $('h-where').textContent = y > 25000 ? 'ABOVE THE ATMOSPHERE' : whereName(x, z);
  $('h-spd').textContent = Math.round(spd * 3.6).toLocaleString();
  $('h-alt').textContent = Math.round(flying ? y : y).toLocaleString();
  $('h-dist').textContent = (Math.hypot(x, z) / 1000).toFixed(1);
  $('sc-thr-fill').style.height = Math.round(S.ship.throttle * 100) + '%';
  var w = $('h-warn'); if (warnMsg && (S.mode === 'fly')) { w.hidden = false; w.textContent = warnMsg; } else w.hidden = true;
  var heading = flying ? Math.atan2(-new V3(0, 0, 1).applyQuaternion(S.ship.q).x, -new V3(0, 0, 1).applyQuaternion(S.ship.q).z) : Math.atan2(-Math.sin(S.camYaw), -Math.cos(S.camYaw));
  drawRadar(x, z, -heading + Math.PI);
  // action buttons
  var act = $('sc-act');
  if (S.mode === 'walk' && actTarget) { act.hidden = false; act.textContent = actTarget.label; }
  else if (S.mode === 'boarded') { act.hidden = false; act.textContent = 'EXIT SHIP'; actTarget = { kind: 'exit' }; }
  else act.hidden = true;
  $('sc-launch').hidden = S.mode !== 'boarded';
  $('sc-stick').style.display = (S.mode === 'walk' || S.mode === 'fly' || S.mode === 'auto' || S.mode === 'watch') && (IS_TOUCH || QS.has('touch')) ? '' : 'none';
  $('b-land').hidden = !((S.mode === 'fly') && Math.hypot(x - PAD.x, z - PAD.z) < 2500 && y < 3000);
  $('b-rtc').classList.toggle('is-on', S.mode === 'auto' && !(S.auto && S.auto.tx != null));
  if (window.CityPlayer) {
    CityPlayer.setCockpit(S.mode !== 'walk');
    var bd = 1e9; for (var mi = 0; mi < RADIO_MASTS.length; mi++) bd = Math.min(bd, Math.hypot(x - RADIO_MASTS[mi].x, z - RADIO_MASTS[mi].z, Math.max(0, y - CITY_Y - 90)));
    CityPlayer.setBoost(1 + 0.3 * smooth((260 - bd) / 200));
  }
  if (helpTimer > 0) { helpTimer -= 0.12; if (helpTimer <= 0) $('sc-help').style.opacity = 0; }
  if (PERF) { var ts = terrainStats(); $('sc-perf').hidden = false; $('sc-perf').textContent = fpsVal.toFixed(0) + ' fps  ' + renderer.info.render.calls + ' calls\n' + Math.round(r