<!-- SOLID CITY · part 53 -->
 book && book.pages && book.pages[0];
  engravedText(g, p1 ? p1.label : 'PAGE ONE', R, m + 92 * s, 40 * s, s);
  engravedText(g, p1 ? p1.title : 'THE FIRST TRUTH', R, m + 150 * s, 50 * s, s);
  g.strokeStyle = GOLD; g.lineWidth = 1.2 * s; g.beginPath(); g.moveTo(R - 260 * s, m + 195 * s); g.lineTo(R + 260 * s, m + 195 * s); g.stroke();
  if (p1) {
    var fs = 27 * s, lh = fs * 1.42, x0 = P + m + 70 * s, maxW = pw - 140 * s, yy = m + 240 * s, yMax = H - m - 110 * s, first = true;
    g.textAlign = 'left'; g.textBaseline = 'top';
    for (var pi = 0; pi < p1.paras.length && yy < yMax; pi++) {
      var text = p1.paras[pi];
      if (first) {   // drop cap
        var cap = text.charAt(0); text = text.slice(1).replace(/^\s+/, ''); g.font = '700 ' + (lh * 2.6) + 'px Georgia, serif';
        var cw = g.measureText(cap).width + 14 * s; engraveShape(g, x0 - 4 * s, yy - 6 * s, cw + 8 * s, lh * 2.9, s, function (cc, ox, oy) { cc.font = '700 ' + (lh * 2.6) + 'px Georgia, serif'; cc.textBaseline = 'top'; cc.fillText(cap, x0 + ox, yy + oy - 4 * s); }, 2);
        g.strokeStyle = GOLD; g.lineWidth = 1 * s; g.strokeText(cap, x0, yy - 4 * s);
        g.font = (fs) + 'px Georgia, "Times New Roman", serif'; g.fillStyle = GOLD;
        var lsv = wrapVar(g, text, function (i) { return i < 2 ? maxW - cw : maxW; });
        for (var k = 0; k < lsv.length && yy < yMax; k++) { g.fillText(lsv[k], x0 + (k < 2 ? cw : 0), yy); yy += lh; }
        first = false; yy += lh * 0.4; continue;
      }
      g.font = fs + 'px Georgia, "Times New Roman", serif'; g.fillStyle = GOLD;
      var ln = wrap(g, text, maxW); for (var q = 0; q < ln.length && yy < yMax; q++) { g.fillText(ln[q], x0, yy); yy += lh; } yy += lh * 0.4;
    }
  }
  rosette(g, R, H - m - 62 * s, 30 * s, s, 18, 7); rosette(g, L, H - m - 62 * s, 30 * s, s, 18, 7);
  return c;
}
var api = { parse: parse, engrave: engrave };
if (typeof module !== 'undefined' && module.exports) module.exports = api; else root.BookLawArt = api;
})(typeof window !== 'undefined' ? window : this);


===== FILE: public/city/book-law-page.js =====
/* /book-of-law: draw the procedural gold intaglio spread (book-law-art.js) into the page header; the text is already in the HTML. */
(function () {
  var cv = document.getElementById('bk-spread'); if (!cv || !window.BookLawArt) return;
  var small = Math.min(screen.width, screen.height) < 700, W = small ? 1024 : 2048;
  fetch('/city/book-of-law.md?v=20261010a', { cache: 'force-cache' }).then(function (r) { return r.text(); }).then(function (md) {
    var art = BookLawArt.engrave(W, W / 2, BookLawArt.parse(md)); cv.width = W; cv.height = W / 2; cv.getContext('2d').drawImage(art, 0, 0);
  }).catch(function () {});
})();


===== FILE: public/city/book-law.js =====
/* SOLID CITY — THE KING'S BOOK OF LAW on display (2026-10-10, the King: "The first book will be on display with gold
   ultra-dense intaglio linework").
   WHERE: the Forum Plaza, 18 m in front of the Crest Obelisk on the arrival axis, the first thing every visitor sees from the
   spawn point (the University arch is 1.2 km out); placed clear of every citizen walking line (>= 5 m) and the pavilions.
   WHAT: an open book on a black-and-gold pedestal under a soft (faked, additive) spotlight; its spread is ONE procedural canvas
   (book-law-art.js engrave(): guilloche, hatched engraved serif, crown, ornamental border; 2048x1024 desktop / 1024x512 iPhone,
   mipmapped, built once). Collision, no-build zone (forge-core.js), radar "LAW", Hyper stop "the King's Book of Law", Watch
   CAMPUS TOUR caption, "READ THE BOOK" -> an engraved gold-on-black reader (13 pages + title page, page turning, swipe, keys).
   The King's words come verbatim from /city/book-of-law.md and are only ever put on screen with textContent. */
(function () {
'use strict';
if (!window.SC || !SC.api || !window.BookLawArt) return;
var A = SC.api, T = A.T, S = A.S, Y = A.CITY_Y, curve = A.curve || function (m) { return m; };
var POS = { x: -4, z: 46 }, FACE = Math.atan2(6 - POS.x, 62 - POS.z);   // the book faces the arrival point (6, 62)
var READ = { x: POS.x + Math.sin(FACE) * 4.6, z: POS.z + Math.cos(FACE) * 4.6 };
var MD_URL = '/city/book-of-law.md?v=20261010a';
var B = { state: 'idle', book: null, page: 0, built: false, wait: 1.0, auto: false };
function $(id) { return document.getElementById(id); }
function text() { if (B.book) return Promise.resolve(B.book); return fetch(MD_URL, { cache: 'force-cache' }).then(function (r) { if (!r.ok) throw new Error('book ' + r.status); return r.text(); }).then(function (md) { B.book = BookLawArt.parse(md); return B.book; }); }

/* ---------------- the sculpture ---------------- */
function Merge() { this.g = []; }
Merge.prototype.add = function (geo, x, y, z, rx, ry, rz) { var g = geo.index ? geo.toNonIndexed() : geo.clone(); g.applyMatrix4(new T.Matrix4().compose(new T.Vector3(x, y, z), new T.Quaternion().setFromEuler(new T.Euler(rx || 0, ry || 0, rz || 0)), ne