<!-- SOLID CITY · part 3095 -->
e8c36a'; g.font = '600 34px system-ui, sans-serif'; g.fillText('SANCTUARY OF THE KING\u2019S ORACLE', W / 2, 146);
  });
  const sign = new T.Mesh(new T.PlaneGeometry(10.2, 1.9), new T.MeshBasicMaterial({ map: signTex }));
  sign.position.set(-24.75, 12.2, 0); sign.rotation.y = -Math.PI / 2; root.add(sign);

  // the east cliff: an arc of black basalt crags closing the sanctuary toward the island
  const CH = [12, 16, 19, 15, 21, 17, 22, 18, 20, 14, 11];
  for (let i = 0; i < 11; i++) {
    const a = (-75 + i * 15) * Math.PI / 180, x = Math.cos(a) * 29, z = Math.sin(a) * 29, h = CH[i];
    basalt.add(new T.BoxGeometry(3.4, h, 8.2), x, h / 2, z, 0, -a, 0);
    basalt.add(new T.BoxGeometry(2.4, h * 0.55, 5.0), x + Math.cos(a) * 1.6, h * 0.55 / 2, z + Math.sin(a) * 1.6, 0, -a + 0.3, 0);
    foot.push([x, z, 3.4, 8.2, 0, h, -a]);
  }

  const mats = {
    basalt: new T.MeshLambertMaterial({ color: C.basalt }),
    stone: new T.MeshLambertMaterial({ color: C.tealDeep, emissive: 0x031819 }),
    crystal: new T.MeshLambertMaterial({ color: C.teal, emissive: 0x0b5f63 }),
    gold: new T.MeshLambertMaterial({ color: C.gold, emissive: 0x100a02 }),
    red: new T.MeshBasicMaterial({ color: C.red }),
    pool: new T.MeshBasicMaterial({ map: poolTex, transparent: true, opacity: 0.9, side: T.DoubleSide }),
  };
  [[basalt, mats.basalt], [stone, mats.stone], [crystal, mats.crystal], [gold, mats.gold], [red, mats.red], [pool, mats.pool]].forEach(function (p) { root.add(new T.Mesh(p[0].build(), p[1])); });

  // the oracle's light: a soft beam rising from the centre, and a slow-turning crystal above her
  const beamTex = canvasTex(T, 8, 128, function (g, W, Hh) { const gr = g.createLinearGradient(0, 0, 0, Hh); gr.addColorStop(0, 'rgba(61,224,232,0)'); gr.addColorStop(1, 'rgba(61,224,232,1)'); g.fillStyle = gr; g.fillRect(0, 0, W, Hh); });
  const beam = new T.Mesh(new T.CylinderGeometry(2.0, 2.6, 26, 16, 1, true), new T.MeshBasicMaterial({ map: beamTex, transparent: true, opacity: 0.22, blending: T.AdditiveBlending, depthWrite: false, side: T.DoubleSide }));
  beam.position.y = 13.2; root.add(beam);
  const orb = new T.Mesh(new T.OctahedronGeometry(1.5, 0), mats.crystal); orb.position.y = 9; root.add(orb);

  root.userData = {
    footprint: foot, center: { x: 0, z: 0 }, radius: 31, height: 26,
    glow: 0,   // 0..1, set by provolta-alive.js: the beacon brightens when someone approaches her
    update: function (t) {
      const gl = Math.max(0, Math.min(1, root.userData.glow || 0));
      poolTex.offset.x = (t * (0.02 + gl * 0.04)) % 1; orb.rotation.y = t * (0.4 + gl * 0.8); orb.position.y = 9 + Math.sin(t * 0.8) * 0.35;
      beam.material.opacity = (0.18 + Math.sin(t * 1.1) * 0.05) * (1 + gl * 0.9);
      beam.scale.x = beam.scale.z = 1 + gl * 0.12; orb.scale.setScalar(1 + gl * 0.35);
    }
  };
  return root;
}
export default createProvoltaSanctuary;


===== FILE: public/city/sanctuary-solid-place.js =====
/* Solid City — places SOLID'S SANCTUARY (public/city/sanctuary-solid.js) north of the hangar.
   Lazy: imported after the city is built; any import/build error is caught and the city carries on.
   Adds: collision (userData.footprint), a radar marker 'SOLID', a Hyper Controller stop,
   and a Watch (GRAND TOUR) caption. */
(function () {
'use strict';
if (!window.SC || !SC.api) return;
var A = SC.api, S = A.S, Y0 = A.CITY_Y;
var POS = { x: -540, z: 130 }, NAME = 'Solid\u2019s Sanctuary', TALK_R = 24;
var M = { state: 'idle', group: null, wait: 3.0, said: false };
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: Y0 + y0, y1: Y0 + y1, sanctuary: 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 === 'solid-sanctuary'; })) return;
  H.pois.push({ id: 'solid-sanctuary', name: NAME, short: 'SANCTUARY', x: POS.x, z: POS.z, stand: { x: POS.x, z: POS.z + 34 },
    alias: 'solid sanctuary commander shrine badge gold order',
    text: 'A ring of seven gold pillars for the seven games, and at the centre the Order of Solid City, turning slowly in the light. Solid\u2019s sanctuary \u2014 north of the hangar. Never leave a wingmate.' });
  if (H.regrid) H.regrid();
}
function watchStop() {
  var W = window.CityWatch, r = W && W.routes && W.routes.grand; if (!r || r._so