<!-- SOLID CITY · part 1800 -->
glass city, carrying a mountain of crystal, three rivers that pour off its rim and fall as rain on the rooftops below, and great trees wherever the land is kind. Raised by the King\'s word on October 14, 2026.' });
  if (H.regrid) H.regrid();
}
async function build() {
  if (M.state !== 'idle') return;
  M.state = 'building';
  try {
    var mod = await import('/city/crystal-crown.js?v=20261014a');
    var topY = window.CityAncestorRoads.topY();
    var g = mod.createCrystalCrown({ THREE: A.T, center: POS, baseY: topY + SKY_LIFT + CROWN_LIFT, floorY: topY + SKY_LIFT });
    A.world.add(g); M.group = g;
    (g.userData.solids || []).forEach(function (b) {
      A.solids.push({ x0: b.x - b.w / 2, x1: b.x + b.w / 2, z0: b.z - b.d / 2, z1: b.z + b.d / 2, y0: b.y0, y1: b.y1, crystalCrown: true });
    });
    M.state = 'ready';
    hyperStop();
  } catch (e) { M.state = 'idle'; }
}
function standY(x, z, py) {
  if (!M.group || M.state !== 'ready') return -1000;
  var h = M.group.userData.heightAt(x, z);
  if (h == null) return -1000;
  var gate = (S && S.drive) ? 1.6 : 0.45;
  if (py == null || h <= py + gate) return h;
  return -1000;
}
function update(dt) {
  if (M.state === 'idle') {
    M.wait -= dt;
    var tReady = !!(window.CityAncestorRoads && CityAncestorRoads.state && CityAncestorRoads.state() === 'ready');
    if (M.wait <= 0 && A.isBuilt() && tReady) build();
    return;
  }
  if (M.state !== 'ready' || !M.group) return;
  if (M.group.userData.update) try { M.group.userData.update(dt, S.t); } catch (e) {}
}
window.CityCrystalCrown = { update: update, standY: standY, state: function () { return M.state; }, group: function () { return M.group; } };
})();


===== FILE: public/city/crystal-crown.js =====
/* THE CRYSTAL CROWN — a letter in the code.
 *
 * The King's word (2026-10-14 ~06:41): "Make another one on
 * top with a crystal mountain and have valleys with rivers
 * that fall to rain on the houses below. And make trees all
 * over big ones" — "the top of the glass one, floating even
 * higher."
 *
 * So above the glass city floats a wild crown: an island of
 * meadow and valley carrying a mountain of crystal. Three
 * rivers rise at the spring lake in its high bowl, run down
 * the carved valleys, and pour off the rim — falling a
 * hundred metres and more, breaking into rain over the
 * rooftops of the glass city below. Big trees stand all over
 * it, wherever the land is kind. Nothing here is a road and
 * nothing is a house: this is the city's wilderness, kept in
 * the sky.
 *
 * By the hand of Solid, his good King. */

function mulberry(seed) {
  return function () {
    seed |= 0; seed = seed + 0x6D2B79F5 | 0;
    var t = Math.imul(seed ^ seed >>> 15, 1 | seed);
    t = t + Math.imul(t ^ t >>> 7, 61 | t) ^ t;
    return ((t ^ t >>> 14) >>> 0) / 4294967296;
  };
}

export var CROWN_RIVERS = [0.6, 2.7, 4.8];
export var CROWN_PEAKS = [
  { r: 95, a: 3.9, h: 44, s: 54, crystal: 26 },
  { r: 150, a: 1.9, h: 30, s: 46, crystal: 17 },
  { r: 170, a: 5.3, h: 22, s: 40, crystal: 15 }
];
export var CROWN_RADIUS = 330;

export function crownHeight(r, th) {
  var h = 16 * (1 - Math.pow(Math.min(r, 330) / 330, 1.6));
  h += 2.0 * Math.sin(th * 3 + r * 0.021) + 1.4 * Math.sin(th * 5 - r * 0.013);
  var x = Math.cos(th) * r, z = Math.sin(th) * r;
  for (var i = 0; i < CROWN_PEAKS.length; i++) {
    var p = CROWN_PEAKS[i], px = Math.cos(p.a) * p.r, pz = Math.sin(p.a) * p.r;
    var d2 = (x - px) * (x - px) + (z - pz) * (z - pz);
    h += p.h * Math.exp(-d2 / (2 * p.s * p.s));
  }
  for (var k = 0; k < CROWN_RIVERS.length; k++) {
    var dth = Math.abs(th - CROWN_RIVERS[k]) % (Math.PI * 2); if (dth > Math.PI) dth = Math.PI * 2 - dth;
    var lateral = dth * Math.max(r, 20);
    var gate = Math.min(1, Math.max(0, (r - 25) / 65));
    h -= 6.5 * Math.exp(-(lateral / 13) * (lateral / 13)) * gate;
  }
  if (r > 295) { var kk = (r - 295) / 35; h = h * (1 - kk) + 2.2 * kk; }
  if (r < 30) { var pk = r < 12 ? 0 : (r - 12) / 18; h = 30 * (1 - pk) + h * pk; }
  return h;
}

export function createCrystalCrown(opts) {
  var T = opts.THREE;
  var CX = opts.center.x, CZ = opts.center.z, BASE = opts.baseY, FLOOR = opts.floorY;
  var R = mulberry(20261014);
  var group = new T.Group(); group.name = 'the-crystal-crown';
  var C = {
    stone: 0x55504c, stoneDark: 0x35302c, gold: 0xd8a833, lawn: 0x4d7d33, lawnDeep: 0x3a6126,
    leaf: 0x2a5c2e, leafLight: 0x3f7a38, trunk: 0x5a4630, rock: 0x6a7076,
    crystal: 0xbfe4f5, pool: 0x2e7db0, water: 0x7fb8dd
  };
  function Batch() { this.pos = []; this.nor = []; this.col = []; }
  Batch.prototype.add = function (geo, matrix, color) {
    var g = geo.index ? geo.toNonIndexed() : geo;
    var p = g.getAttribute('position'), n = g.getAttribute('normal');
    var nm = new T.Matrix3().getNormalMatrix(matrix);
    var c = new T.Color(color), v = new T.Vector3(), nv = new T.Vector3();
    for (var i = 0; i < p.count; i++) {
      v.fromBufferAttribute(p, 