<!-- SOLID CITY · part 2482 -->
 M.tris[ti + 6]) / 3, tcz = (M.tris[ti + 2] + M.tris[ti + 5] + M.tris[ti + 8]) / 3;
        var tk = Math.floor(tcx / 16) + ':' + Math.floor(tcz / 16);
        (M.triIx[tk] = M.triIx[tk] || []).push(ti);
      }
    }
    collide(g.userData || {}); hyperStop(); watchStop();
  }).catch(function (e) { M.state = 'failed'; try { console.warn('[city] Ancestors homes skipped:', e && e.message); } catch (x) {} });
}
function update(dt) {
  if (M.state === 'idle') { if (A.isBuilt && !A.isBuilt()) return; M.wait -= dt; if (M.wait <= 0) load(); return; }
  if (M.state !== 'ready' || document.hidden) return;
  var c = A.camera.position, d = Math.hypot(c.x + A.origin.x - POS.x, c.z + A.origin.z - POS.z);
  M.group.visible = d < 11000;
  if (S.mode === 'walk') {
    var pd = Math.hypot(S.p.x - POS.x, S.p.z - POS.z);
    if (pd < 420 && !M.said) { M.said = true; if (window.CityHyper && CityHyper.narrate) CityHyper.narrate("<b>Nā Hale o nā Kūpuna</b> — the Ancestors' Homes. 'Ohana compounds on the green benches; every door opens.", 7); }
    else if (pd > 700) M.said = false;
  }
}
function radar(g, blip, fl) { if (M.state === 'ready') blip(POS.x, POS.z, '#4a8a3a', fl ? 3 : 6, fl ? '' : 'HOMES'); }
window.CityMountainHomes = { update: update, radar: radar, pos: POS, standY: standY, state: function () { return M.state; }, group: function () { return M.group; } };
})();


===== FILE: public/city/mountain-homes-place.js.bak-oldtrail-20261014 =====
/* Solid City — places NĀ HALE O NĀ KŪPUNA, THE ANCESTORS' HOMES (public/city/mountain-homes.js)
   on the green coastal benches around the Ancestral Roads, by order of the King:
   "We need to build homes for hawaiians."
   Lazy: imported after the city is built; any import/build error is caught and the city carries on.
   The module sites every home on the real terrain at runtime (placement law:
   gentle benches only, ledges and cliffs untouched, a driveway to every door).
   Adds: collision (userData.footprint, world-absolute), P.y-aware standY (floors,
   lanai, stairs), a radar marker 'HOMES', a Hyper Controller stop, and a Watch
   (GRAND TOUR) caption. One quiet line on first approach. */
(function () {
'use strict';
if (!window.SC || !SC.api) return;
var A = SC.api, S = A.S;
var POS = { x: 300, z: -1500 }, NAME = "Nā Hale o nā Kūpuna — The Ancestors' Homes";
var M = { state: 'idle', group: null, wait: 4.5, said: false, rects: null, tris: null, triIx: null };
function addBox(cx, cz, w, d, rot, y0, y1) {
  var nx = Math.max(1, Math.ceil(w / 2.5)), nz = Math.max(1, Math.ceil(d / 2.5)), cw = w / nx, cd = d / nz, c = Math.cos(rot), s = Math.sin(rot);
  var hx = cw / 2 * Math.abs(c) + cd / 2 * Math.abs(s), hz = cw / 2 * Math.abs(s) + cd / 2 * Math.abs(c);
  for (var i = 0; i < nx; i++) for (var j = 0; j < nz; j++) {
    var ox = -w / 2 + cw * (i + 0.5), oz = -d / 2 + cd * (j + 0.5), lx = cx + ox * c + oz * s, lz = cz - ox * s + oz * c;
    A.solids.push({ x0: lx - hx, x1: lx + hx, z0: lz - hz, z1: lz + hz, y0: y0, y1: y1, mountainHomes: true });
  }
}
function collide(ud) { (ud.footprint || []).forEach(function (b) { addBox(b[0], b[1], b[2], b[3], b[6] || 0, b[4], b[5]); }); }
function hyperStop() {
  var H = window.CityHyper; if (!H || !H.pois || H.pois.some(function (p) { return p.id === 'ancestors-homes'; })) return;
  H.pois.push({ id: 'ancestors-homes', name: NAME, short: 'HOMES', x: POS.x, z: POS.z, stand: { x: 438, z: -1055 },
    alias: 'ancestors homes hawaiian houses ohana hale plantation dickey village benches kupuna',
    text: "Nā Hale o nā Kūpuna — the Ancestors' Homes. On the green benches around the Ancestral Roads stand sixty-some dwellings for Hawaiian families: 'ohana compounds around shared yards, traditional hale, plantation homes, Dickey-roof residences, and two small apartment blocks at the base. Every home has a driveway, a lanai, gardens of taro and banana — and a door that opens. Walk in." });
  if (H.regrid) H.regrid();
}
function watchStop() {
  var W = window.CityWatch, r = W && W.routes && W.routes.grand; if (!r || r._ancestorsHomes) return;
  var orig = r.build; r._ancestorsHomes = true;
  r.build = function () {
    var w = orig.apply(this, arguments), at = Math.min(1, w.length);
    w.splice(at, 0, { x: 700, z: -880, y: 250, v: 230, cap: { cap: "NĀ HALE O NĀ KŪPUNA", sub: "The Ancestors' Homes · 'ohana compounds · green benches", say: "The Ancestors' Homes: Hawaiian families living on the green benches around the Ancestral Roads — hale, plantation homes, and Dickey roofs among the taro and the trees." }, agl: false });
    return w;
  };
}
function triYAt(t, o, x, z) {
  var ax = t[o], ay = t[o + 1], az = t[o + 2], bx = t[o + 3], by = t[o + 4], bz = t[o + 5], cx = t[o + 6], cy = t[o + 7], cz = t[o + 8];
  var den = (bz - cz) * (ax - cx) + (cx - bx) * (az - cz);
  if (Math.abs(den) < 1e-9) return null;
  var w0 = ((bz - cz) * (x - cx) + (cx - bx) * (z - cz)) / den;
  var w1 = ((cz - az) * (x - cx) + (ax - cx) * (z 