<!-- SOLID CITY · part 55 -->
op(1, 'rgba(255,214,130,0)'); g.fillStyle = gr; g.fillRect(0, 0, w, h); }), transparent: true, blending: T.AdditiveBlending, depthWrite: false, side: T.DoubleSide, fog: true }));
  cone.position.set(0, 4.75, 0.15); cone.renderOrder = 2;
  var glow = new T.Mesh(new T.CircleGeometry(3.4, 40), new T.MeshBasicMaterial({ map: gradTex(64, 64, function (g, w) { var gr = g.createRadialGradient(w / 2, w / 2, 0, w / 2, w / 2, w / 2); gr.addColorStop(0, 'rgba(255,205,110,0.55)'); gr.addColorStop(1, 'rgba(255,205,110,0)'); g.fillStyle = gr; g.fillRect(0, 0, w, w); }), transparent: true, blending: T.AdditiveBlending, depthWrite: false }));
  glow.rotation.x = -Math.PI / 2; glow.position.y = 0.23; glow.renderOrder = 2;
  // engraved plaque on the plinth front
  var pc = document.createElement('canvas'); pc.width = 512; pc.height = 128; var q = pc.getContext('2d');
  q.fillStyle = '#070506'; q.fillRect(0, 0, 512, 128); q.strokeStyle = '#d9ab46'; q.lineWidth = 4; q.strokeRect(6, 6, 500, 116); q.lineWidth = 1; q.strokeRect(14, 14, 484, 100);
  q.fillStyle = '#ecc76e'; q.textAlign = 'center'; q.textBaseline = 'middle'; q.font = '700 34px Georgia, serif'; q.fillText("THE KING'S BOOK OF LAW", 256, 52); q.font = '600 20px Georgia, serif'; q.fillStyle = '#c9a24c'; q.fillText('THIRTEEN PAGES \u00b7 READ THE BOOK', 256, 90);
  var pt = new T.CanvasTexture(pc); pt.encoding = T.sRGBEncoding;
  var plaque = new T.Mesh(new T.PlaneGeometry(1.9, 0.475), curve(new T.MeshBasicMaterial({ map: pt }))); plaque.position.set(0, 0.44, 1.035); plaque.rotation.x = -0.02;
  var col = new T.Mesh(new T.BoxGeometry(2.02, 0.52, 0.04), stone); col.position.set(0, 0.44, 1.01);   // plaque backing on the plinth face (correction 2026-10-14: the plaque first stood at z 0.51, INSIDE the octagonal column whose face stands at ~0.80 — only its wings showed, "THE B..." and "...LAW" flanking the column, as the King photographed. The comment always said plinth front; now the numbers agree.)
  var grp = new T.Group(); grp.name = 'kings-book-of-law'; grp.position.set(POS.x, Y, POS.z); grp.rotation.y = FACE;
  grp.add(st.mesh(stone)); grp.add(gd.mesh(gold)); grp.add(lec); grp.add(cone); grp.add(glow); grp.add(col); grp.add(plaque);
  A.world.add(grp); B.group = grp;
}
function solids() {
  var hw = 1.45, hd = 1.15, c = Math.cos(FACE), s = Math.sin(FACE), ex = Math.abs(c) * hw + Math.abs(s) * hd, ez = Math.abs(s) * hw + Math.abs(c) * hd;
  A.solids.push({ x0: POS.x - ex, x1: POS.x + ex, z0: POS.z - ez, z1: POS.z + ez, y0: Y, y1: Y + 3.4, book: true });
  var px = POS.x - s * 3.1, pz = POS.z - c * 3.1; A.solids.push({ x0: px - 0.25, x1: px + 0.25, z0: pz - 0.25, z1: pz + 0.25, y0: Y, y1: Y + 7.9, book: true });   // spotlight post
}
function stop() {
  var H = window.CityHyper; if (!H || !H.pois || H.pois.some(function (p) { return p.id === 'book'; })) return;
  H.pois.splice(1, 0, { id: 'book', name: 'The King\u2019s Book of Law', short: 'BOOK OF LAW', x: POS.x, z: POS.z, stand: { x: READ.x, z: READ.z }, act: 'book',
    alias: 'book law laws kings king covenant bookoflaw', text: 'The King\u2019s Book of Law, open on a black-and-gold pedestal in the Forum Plaza: thirteen pages, thirteen truths, engraved in gold. Walk up and tap READ THE BOOK.' });
  if (H.regrid) H.regrid();
}
function watchCap() {   // the CAMPUS TOUR opens with a low pass over the book
  var W = window.CityWatch; if (!W || !W.routes || !W.routes.campus || W.routes.campus._book) return;
  var orig = W.routes.campus.build; W.routes.campus._book = true;
  W.routes.campus.build = function () { var w = orig.apply(this, arguments); w.unshift({ x: POS.x + 30, z: POS.z + 40, y: Y + 55, v: 110, cap: { cap: 'THE KING\u2019S BOOK OF LAW', sub: 'Forum Plaza \u00b7 gold intaglio on a black-and-gold pedestal', say: 'The King\u2019s Book of Law, on display in the Forum Plaza. Thirteen pages. Thirteen truths.' } }); return w; };
}
function init() {
  B.state = 'loading';
  text().then(function (book) {
    try { solids(); build(book); stop(); watchCap(); B.state = 'ready'; arrive(); }
    catch (e) { B.state = 'failed'; try { console.warn('[city] book of law skipped:', e && e.message); } catch (x) {} }
  }).catch(function (e) { B.state = 'failed'; try { console.warn('[city] book of law text unavailable:', e && e.message); } catch (x) {} });
}
function update(dt) {
  if (B.state === 'idle') { if (A.isBuilt && !A.isBuilt()) return; B.wait -= dt; if (B.wait <= 0) init(); return; }
  if (B.state !== 'ready') return;
  if (S.mode === 'walk') { var d = Math.hypot(S.p.x - READ.x, S.p.z - READ.z); if (d > 14) B.auto = false; }
}
function actHere(x, z) { return B.state === 'ready' && (Math.hypot(x - READ.x, z - READ.z) < 4.2 || Math.hypot(x - POS.x, z - POS.z) < 4.6); }
function radar(g, blip, fl) { if (B.state === 'ready' && !fl) blip(POS.x, POS.z, '#ffd27a', 4, 'LAW'); }
function arrive() {
  if (new URLSearchParams(location.search).get('to') !== 'book') return;
  (function wait() { var b