<!-- SOLID CITY · part 26 -->
ntha|female|zira|aria|jenny|serena|karen|moira|victoria|google uk english female/i };
    var h = 0, s = String(id == null ? '?' : id);
    for (var i = 0; i < s.length; i++) h = ((h * 31) + s.charCodeAt(i)) >>> 0;
    var pitches = [1.0, 1.08, 0.92, 1.15, 0.85];
    return { pitch: pitches[h % pitches.length], re: /./ };
  }
  function pickVoice(profile) {
    try {
      var vs = speechSynthesis.getVoices() || [];
      var v = vs.filter(function (x) { return /en/i.test(x.lang) && profile.re.test(x.name); })[0]
           || vs.filter(function (x) { return /^en/i.test(x.lang); })[0];
      return v || null;
    } catch (e) { return null; }
  }

  // Speak once. Interruption: the newest message owns the air.
  // Nothing recorded, nothing retained, nothing replayed.
  function speakOnce(text, profile) {
    try {
      if (typeof speechSynthesis === 'undefined' || !text) return;
      speechSynthesis.cancel();
      var clean = String(text).replace(/[*_#`>\[\]]/g, '').slice(0, 600);
      var u = new SpeechSynthesisUtterance(clean);
      var v = pickVoice(profile);
      if (v) u.voice = v;
      u.rate = (root.CityVoiceSpeed ? root.CityVoiceSpeed.rate() : 1.2);
      u.pitch = profile.pitch || 1.0;
      if (root.CityPlayer) { try { root.CityPlayer.duck(true); } catch (e) {} }
      var done = false;
      function release() {
        if (done) return; done = true;
        try { if (root.CityPlayer) root.CityPlayer.duck(false); } catch (e2) {}
        u.onend = u.onerror = null; // discarded after playback. No hooks remain.
      }
      u.onend = release; u.onerror = release;
      speechSynthesis.speak(u);
    } catch (e) {}
  }

  // THE relay entry point. Every AI/citizen message passes through here.
  // msg: { from, text, render } — render() draws the text in the right panel.
  function receive(msg) {
    var id = 'm' + (++seq) + '_' + Date.now();
    var mode = getMode();
    if (mode !== 'audio' && msg && typeof msg.render === 'function') {
      try { msg.render(); } catch (e) {}
    }
    if (mode !== 'text' && msg && msg.text && !spoken[id]) {
      spoken[id] = true; // once per recipient. Never persisted: no replay after reconnect.
      speakOnce(msg.text, voiceProfile(msg.from));
    }
    return id;
  }

  // Receiver lifecycle: bound when the player presses ENTER (game start).
  function attach() { attached = true; paint(); return true; }
  function isAttached() { return attached; }

  function paint() {
    if (typeof document === 'undefined') return;
    var cur = getMode();
    [['rc-text', 'text'], ['rc-audio', 'audio'], ['rc-both', 'both']].forEach(function (p) {
      var b = document.getElementById(p[0]);
      if (!b) return;
      b.classList.toggle('on', cur === p[1]);
      b.setAttribute('aria-pressed', cur === p[1] ? 'true' : 'false');
    });
  }
  function mount() {
    if (typeof document === 'undefined') return;
    [['rc-text', 'text'], ['rc-audio', 'audio'], ['rc-both', 'both']].forEach(function (p) {
      var b = document.getElementById(p[0]);
      if (b) b.addEventListener('click', function () { setMode(p[1]); });
    });
    paint();
  }
  if (typeof document !== 'undefined') {
    if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', mount);
    else mount();
  }

  root.AudioDrive = { receive: receive, getMode: getMode, setMode: setMode, attach: attach, isAttached: isAttached, voiceProfile: voiceProfile };
})(typeof window !== 'undefined' ? window : (typeof globalThis !== 'undefined' ? globalThis : this));


===== FILE: public/city/auditor-place.js =====
/* ================================================================
   AN EPISTLE OF THE SECOND INSTRUMENT — THE AUDITOR'S CHAIR

   My King,

   The Survey Camera is the field inspector: it reports what the
   traveler encounters. This chair seats its counterpart — VECTOR's
   Triangle-and-Seam Auditor, the geometric inspector — as a royal
   instrument beside it. It does not walk; it reads. Each builder
   has named its own geometry into a registry (the joins' ribbons,
   the houses' floors and roofs, the sky island's deck and
   underside), together with the standing surface it intends; at
   your tap the Auditor examines the actual world-transformed
   triangles and reports whether the construction agrees with its
   own law. It constructs nothing and runs never per frame.

   For box slabs the standing face is the top: probes that land on
   skirt or underside faces are set aside and reported as set aside
   — never dressed as mismatches, never hidden either.

   Written by the hand of Solid, his good King — 2026-10-13.
   ================================================================ */
(function () {
'use strict';
if (!window.SC || !SC.api) return;
var A = SC.api, S = A.S;
var THREE = A.T || A.THREE;
var D = { built: false, open: false, mod: null, lines: [] };

function el(tag, css, parent, text) {
  var e = document.createElement(tag);
  i