<!-- SOLID CITY · part 2191 -->
('data-mode') === m); });
  $('hc-mode-indicator').textContent = m; modeLabel();
  $('hc-aidrive').classList.toggle('active', m === 'AI DRIVE' || m === 'NAVIGATE');
}
function modeLabel() {
  var el = $('hc-mode-indicator'); if (!el) return;
  var t = H.mode, rf = window.CityRadarFind && CityRadarFind.followState && CityRadarFind.followState();
  if (H.nav && H.nav.p) t = (H.tour ? 'TOUR \u00b7 ' : '') + 'WALKING TO ' + String(H.nav.p.short || H.nav.p.name).toUpperCase();
  else if (H.flyDrive && H.flyDrive.t) t = 'FLYING TO ' + String(H.flyDrive.t.short || H.flyDrive.t.name).toUpperCase();
  else if (H.tour) t = 'TOUR';
  else if (rf) t = 'FOLLOWING ' + String(rf.name).toUpperCase();
  if (el.textContent !== t) { el.textContent = t; el.title = t; }
}
setInterval(modeLabel, 400);
function baseMode() { return flying() ? 'FLIGHT' : 'WALK'; }

/* ---------------- info card ("glass") ---------------- */
function showCard(title, sub, html, buttons) {
  card.innerHTML = '<div class="hc-card-h"><b>' + esc(title) + '</b><button type="button" class="hc-x" aria-label="Close">✕</button></div>' +
    (sub ? '<div class="hc-card-sub">' + esc(sub) + '</div>' : '') + '<div class="hc-card-b">' + html + '</div><div class="hc-card-a"></div>';
  var bar = card.querySelector('.hc-card-a');
  (buttons || []).forEach(function (b) {
    var el = document.createElement(b.href ? 'a' : 'button'); el.className = 'sc-b' + (b.gold ? ' sc-gold' : ''); el.textContent = b.label;
    if (b.href) el.href = b.href; else { el.type = 'button'; el.addEventListener('click', b.fn); }
    bar.appendChild(el);
  });
  card.querySelector('.hc-x').addEventListener('click', hideCard);
  card.hidden = false;
}
function hideCard() { card.hidden = true; }
function poiCard(p) {
  var me = flying() ? S.ship : S.p, d = Math.hypot(p.x - me.x, p.z - me.z), btns = [];
  if (flying()) {
    btns.push({ label: p.home ? 'LAND AT SPACEPORT' : '🧭 FLY THERE', gold: true, fn: function () { hideCard(); driveTo(p, 'NAVIGATE'); } });
  } else {
    if (d > 10) btns.push({ label: '🧭 NAVIGATE', gold: true, fn: function () { hideCard(); driveTo(p, 'NAVIGATE'); } });
    if (p.act === 'soul') btns.push({ label: 'TALK TO SOUL PRINT', fn: function () { hideCard(); if (d < 14) A.openSoul(); else driveTo(p, 'AI DRIVE', function () { A.openSoul(); }); } });
    if (p.act === 'podium') btns.push({ label: 'READ', gold: true, fn: function () { hideCard(); if (d < 7 || !window.CityPodium) { if (window.CityPodium) CityPodium.open('features'); } else driveTo(p, 'AI DRIVE', function () { CityPodium.open('features'); }); } });
    if (p.act === 'book') btns.push({ label: 'READ THE BOOK', gold: true, fn: function () { hideCard(); if (d < 7 || !window.CityBook) { if (window.CityBook) CityBook.open(0); } else driveTo(p, 'AI DRIVE', function () { CityBook.open(0); }); } });
    if (p.act === 'talk') btns.push({ label: 'TALK TO SABLE', fn: function () { hideCard(); if (d < 8) A.openTalk(); else driveTo(p, 'AI DRIVE', function () { A.openTalk(); }); } });
    if (p.url) btns.push({ label: (p.go || 'OPEN') + ' \u2192', href: p.url });
  }
  var extra = '';
  if (p.volcano || p.alt) extra = '<p class="hc-meta">Ground ' + Math.round(Math.max(0, A.heightAt(p.x, p.z))).toLocaleString() + ' m \u00b7 ' + fmtDist(d) + ' away</p>';
  showCard(p.name, flying() ? 'LANDMARK' : (A.whereName(p.x, p.z) || '').toString(), '<p>' + esc(p.text || '') + '</p>' + (extra || '<p class="hc-meta">' + fmtDist(d) + ' away</p>'), btns);
}
function picker() {
  var list = flying() ? FLY.concat([P('studio')]) : POIS, html = '<div class="hc-chips"></div>';
  showCard(flying() ? 'AI DRIVE \u00b7 WHERE TO?' : 'AI DRIVE \u00b7 WHERE TO?', flying() ? 'Pick a landmark: autopilot flies you there' : 'Pick a place: I\u2019ll walk you there', html, []);
  var box = card.querySelector('.hc-chips');
  list.forEach(function (p) {
    var me = flying() ? S.ship : S.p, b = document.createElement('button'); b.type = 'button'; b.className = 'hc-chip';
    b.innerHTML = esc(p.name) + ' <small>' + fmtDist(Math.hypot(p.x - me.x, p.z - me.z)) + '</small>';
    b.addEventListener('click', function () { hideCard(); H.focus = p; driveTo(p, 'AI DRIVE'); });
    box.appendChild(b);
  });
  if (!flying()) {
    var fx = document.createElement('p'); fx.className = 'hc-meta'; fx.textContent = 'Volcanoes and islands are flight destinations: board a ship at the spaceport, LAUNCH, then tap 🤖 again.'; card.querySelector('.hc-card-b').appendChild(fx);
  }
}
function glossary() {
  showCard('Shared language', 'SOLID CITY', '<dl class="hc-gl">' + GLOSS.map(function (g) { return '<dt>' + esc(g[0]) + '</dt><dd>' + esc(g[1]) + '</dd>'; }).join('') + '</dl>', []);
}

/* ---------------- 3D markers (beacons, path line, scan ring, labels) ---------------- */
var beamGeo = new T.CylinderGeometry(1, 1, 1, 10, 1, true); beamGeo.translate(0, 0.5, 0);
var ringGeo = new T.RingGeometry(0.94, 1, 96);
var matGold = A.curve(new T.MeshBas