<!-- SOLID CITY · part 3612 -->
ot.add(light);

  // Three stone benches, facing the centre — rest for the weary
  var benchGeo = new T.BoxGeometry(2.6, 0.7, 1.0);
  [90, 210, 330].forEach(function (deg) {
    var a = deg * Math.PI / 180;
    var bx = Math.cos(a) * 4.6, bz = Math.sin(a) * 4.6;
    var bench = new T.Mesh(benchGeo, stoneMat);
    bench.position.set(bx, 0.65, bz); bench.rotation.y = -a + Math.PI / 2; root.add(bench);
    var trim = new T.Mesh(new T.BoxGeometry(2.6, 0.1, 1.06), glowGoldMat);
    trim.position.set(bx, 1.02, bz); trim.rotation.y = bench.rotation.y; root.add(trim);
    foot.push([bx, bz, 2.6, 1.0, 0, 1.1, -a + Math.PI / 2]);
  });

  // Small open shelter: 4 posts + flat roof
  var postGeo = new T.BoxGeometry(0.3, 3.2, 0.3);
  var posts = [[2.2, -3.3], [-2.2, -3.3], [2.2, -7.7], [-2.2, -7.7]];
  posts.forEach(function (pt) {
    var post = new T.Mesh(postGeo, darkMat); post.position.set(pt[0], 1.9, pt[1]); root.add(post);
    foot.push([pt[0], pt[1], 0.5, 0.5, 0, 3.5, 0]);
  });
  var roof = new T.Mesh(new T.BoxGeometry(6.4, 0.35, 6.4), stoneMat);
  roof.position.set(0, 3.72, -5.5); root.add(roof);
  var rim = new T.Mesh(new T.BoxGeometry(6.6, 0.12, 6.6), glowGoldMat);
  rim.position.set(0, 3.94, -5.5); root.add(rim);
  // A low stone windbreak on the shelter's north face — shelter from the weather
  var wall = new T.Mesh(new T.BoxGeometry(6.4, 1.4, 0.4), darkMat);
  wall.position.set(0, 1.0, -7.9); root.add(wall);
  foot.push([0, -7.9, 6.4, 0.5, 0, 1.7, 0]);

  root.userData = {
    footprint: foot, center: { x: 0, z: 0 }, radius: 14, height: 6,
    update: function (t) {
      for (var i = 0; i < flames.length; i++) {
        var f = flames[i], ph = f.userData.phase;
        f.scale.set(1 + Math.sin(t * 7 + ph) * 0.13, 1 + Math.sin(t * 9 + ph) * 0.2, 1 + Math.cos(t * 8 + ph) * 0.13);
      }
      light.intensity = 1.1 + Math.sin(t * 10) * 0.2;
    }
  };
  return root;
}
export default createLanternVigil;


===== FILE: public/city/village-mauna-place.js =====
/* Solid City — places KAUHALE MAUNA, THE MOUNTAIN VILLAGE (public/city/village-mauna.js)
   on a mountainside ~2.8 km southeast of the capital.
   Lazy: imported after the city is built; any import/build error is caught and the city carries on.
   The village height adapts to the terrain at runtime: samples groundAt over the
   district, takes the max, and sets the terraces above it. Permanent at load.
   Adds: collision (userData.footprint), a radar marker 'VILLAGE', 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: 2000, z: 2000 }, NAME = 'Kauhale Mauna';
var M = { state: 'idle', group: null, wait: 4.0, said: false, gy: 22, tops: null };
function sampleGround() {
  var g = (typeof groundAt === 'function') ? groundAt : null;
  if (!g) return 22;
  var max = -1000, x, z, h;
  for (var i = -2; i <= 2; i++) for (var j = -2; j <= 2; j++) {
    x = POS.x + i * 130; z = POS.z + j * 130;
    try { h = g(x, z); } catch (e) { h = 22; }
    if (h > max) max = h;
  }
  return max;
}
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: POS.x + lx - hx, x1: POS.x + lx + hx, z0: POS.z + lz - hz, z1: POS.z + lz + hz, y0: M.gy + y0, y1: M.gy + y1, villageMauna: 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 === 'village-mauna'; })) return;
  H.pois.push({ id: 'village-mauna', name: 'Kauhale Mauna — Mountain Village', short: 'VILLAGE', x: POS.x, z: POS.z, stand: { x: POS.x, z: POS.z + 200 },
    alias: 'mountain village kauhale trees huts',
    text: 'Kauhale Mauna, the mountain village: three terraces climbing the slope, ten hale with warm windows, a gathering hale with its fire, and a forest of giant trees — ancients 25 to 40 meters tall. The lookout faces the city lights, far below.' });
  if (H.regrid) H.regrid();
}
function watchStop() {
  var W = window.CityWatch, r = W && W.routes && W.routes.grand; if (!r || r._villageMauna) return;
  var orig = r.build; r._villageMauna = true;
  r.build = function () {
    var w = orig.apply(this, arguments);
    w.push({ x: POS.x - 500, z: POS.z + 300, y: M.gy + 260, v: 240, cap: { cap: 'KAUHALE MAUNA', sub: 'Mountain village \u00b7 giant trees \u00b7 terraces', say: 'Kauhale Mauna, the mountain v