<!-- SOLID CITY · part 2177 -->
; k++) if (al[k] && (al[k] === q || q.split(/\s+/).indexOf(al[k]) >= 0)) return p; }
  return null;
}
function handleCommand(cmd) {
  var c = fold(cmd).trim().replace(/[.!?]+$/, ''); if (!c) return;
  if (/^(stop|stop driving|halt|cancel)$/.test(c)) return stopAI();
  if (/^(tour|guided tour|show me around)$/.test(c)) return startTour();
  if (/^(show me (the )?(city|solid city|my website)|guide|hello|hi)$/.test(c)) return guide();
  if (/^(talk|talk to sable|sable|meet sable)$/.test(c)) return guide();
  if (/^(what is this|what does this do|explain this|what's this)$/.test(c)) { var f = H.focus || focusNearest(); if (f) { narrate('<b>' + esc(f.name) + '</b>: ' + esc(f.text || ''), 9); poiCard(f); } else narrate('Focus a place first (🎯), then ask me what it does.'); return; }
  if (/^(return|go back|back|take me back)$/.test(c)) { if (!goReturn()) narrate('No previous location to return to.'); else narrate('Returning to your previous location.', 3); return; }
  if (/^scan$/.test(c)) return scan();
  if (/^focus$/.test(c)) return focusNearest();
  if (/^look( around)?$/.test(c)) return pick('LOOK');
  if (/^walk$/.test(c)) return pick('WALK');
  if (/^(glossary|help)$/.test(c)) return c === 'help' ? narrate('I understand: "drive me to studio", "fly me to Mauna Kea", "tour", "scan", "focus", "return", "talk to sable", "stop".', 9) : glossary();
  if (/^(home|go home|take me home|fly home|land|return to city)$/.test(c)) { return driveTo(flying() ? FLY[0] : P('plaza'), 'AI DRIVE'); }
  var m = c.match(/(?:drive me to|take me to|walk me to|walk to|fly me to|fly to|go to|navigate to|show me|find|head to)\s+(.+)/);
  if (m) {
    var p = matchTarget(m[1]);
    if (p) { driveTo(p, 'AI DRIVE'); return; }
    narrate('I couldn\u2019t find anything matching \u201c' + esc(m[1]) + '\u201d. Try "studio", "spaceport", "warp", "SABLE", or in flight "Mauna Kea".', 7); return;
  }
  var p2 = matchTarget(c); if (p2) { driveTo(p2, 'AI DRIVE'); return; }
  narrate('I understand: "drive me to studio", "fly me to Mauna Kea", "tour", "scan", "return", "stop".', 7);
}

/* ---------------- wiring ---------------- */
function pick(m) { stopAI(true); clearNarration(); setMode(m); if (m === 'LOOK') { S.camDist = 14; S.camPitch = 0.5; H.lastDrag = 0; narrate('LOOK: drag to orbit the camera; it slowly circles when you let go. Tap 🚶 to walk again.', 5); } }
hc.querySelectorAll('.hc-mode-btn').forEach(function (b) { b.addEventListener('click', function () { pick(b.getAttribute('data-mode')); }); });

/* ================= ROYAL RIGHTS (2026-10-12) =================
   One gate: the server decides from the King's account; his typed password
   unlocks; then FLY pops up and BUILD arms. Nobody else ever sees the key. */
(function () {
  var me = null, flyBtn = null, riseEl = null, sending = false;
  var buildBtn = $('hc-build'); if (buildBtn) buildBtn.style.display = 'none'; // fail closed until royal is proven
  function post(path, body) {
    return fetch(path, { method: 'POST', credentials: 'same-origin', cache: 'no-store', headers: { 'Content-Type': 'application/json', 'X-CSRF-Token': (me && me.csrf) || '' }, body: JSON.stringify(body || {}) })
      .then(function (r) { return r.json().catch(function () { return {}; }).then(function (j) { return { status: r.status, j: j }; }); });
  }
  function showRise(on) {
    if (!riseEl) {
      riseEl = document.createElement('div'); riseEl.id = 'hc-rise';
      riseEl.innerHTML = '<button type="button" id="hc-rise-up" aria-label="Climb">⬆</button><button type="button" id="hc-rise-dn" aria-label="Sink">⬇</button>';
      document.body.appendChild(riseEl);
      bindHold(riseEl.querySelector('#hc-rise-up'), 1); bindHold(riseEl.querySelector('#hc-rise-dn'), -1);
    }
    riseEl.style.display = on ? 'flex' : 'none';
    if (!on && window.CityRoyal) CityRoyal.setRise(0);
  }
  function bindHold(el, v) {
    el.addEventListener('pointerdown', function (e) { e.preventDefault(); if (window.CityRoyal) CityRoyal.setRise(v); });
    ['pointerup', 'pointerleave', 'pointercancel'].forEach(function (t) { el.addEventListener(t, function () { if (window.CityRoyal) CityRoyal.setRise(0); }); });
    el.addEventListener('contextmenu', function (e) { e.preventDefault(); });
  }
  function applyRoyal() {
    if (buildBtn) buildBtn.style.display = '';
    var key = $('hc-royal-key'); if (key) key.style.display = 'none';
    if (!flyBtn) {
      flyBtn = document.createElement('button');
      flyBtn.type = 'button'; flyBtn.id = 'hc-royal-fly'; flyBtn.className = 'hc-mode-btn'; flyBtn.setAttribute('data-mode', 'FLY');
      flyBtn.title = 'Fly — the King\'s own power'; flyBtn.setAttribute('aria-label', 'Fly'); flyBtn.textContent = '🪽';
      var look = hc.querySelector('.hc-mode-btn[data-mode="LOOK"]');
      if (look && look.nextSibling) look.parentNode.insertBefore(flyBtn, look.nextSibling); else $('hc-buttons').appendChild(flyBtn);
      flyBtn.addEventListener('click', function 