<!-- SOLID CITY · part 60 -->
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 boot = $('sc-boot'); if ((boot && !boot.hidden) || S.mode !== 'walk') return setTimeout(wait, 500);
    S.p.x = READ.x + Math.sin(FACE) * 3; S.p.z = READ.z + Math.cos(FACE) * 3; S.p.y = A.groundAt(S.p.x, S.p.z); S.camYaw = FACE; open(0); })();
}

/* ---------------- the reader ---------------- */
var R = null;
function css() {
  if ($('bk-css')) return; var st = document.createElement('style'); st.id = 'bk-css';
  st.textContent = '#bk-reader{position:absolute;z-index:24;inset:0;display:flex;align-items:center;justify-content:center;background:rgba(0,0,0,.62);pointer-events:auto}#bk-reader[hidden]{display:none}' +
    '#bk-book{position:relative;width:min(760px,94vw);height:min(88vh,980px);display:flex;flex-direction:column;color:#f1dfae;font:18px/1.62 Georgia,"Times New Roman",serif;border:2px solid #d9ab46;border-radius:6px;' +
    'background:repeating-linear-gradient(0deg,rgba(201,154,58,.075) 0 1px,transparent 1px 3px),repeating-linear-gradient(90deg,rgba(201,154,58,.035) 0 1px,transparent 1px 4px),radial-gradient(ellipse at 50% 0%,#1a1209,#070506 70%);' +
    'box-shadow:inset 0 0 0 7px #070506,inset 0 0 0 8px #a87b26,inset 0 0 0 11px #070506,inset 0 0 0 12px #6b4e18,0 20px 60px #000;perspective:1400px}' +
    '#bk-book:before,#bk-book:after{content:"\\2756";position:absolute;color:#d9ab46;font-size:20px;line-height:1}#bk-book:before{left:16px;top:12px}#bk-book:after{right:16px;bottom:10px}' +
    '.bk-hd{display:flex;align-items:center;gap:8px;padding:18px 22px 8px}.bk-hd .bk-crest{flex:1;text-align:center;letter-spacing:.32em;font:700 13px Georgia,serif;color:#d9ab46}' +
    '.bk-btn{min-width:44px;min-height:44px;border-radius:8px;border:1px solid #a87b26;background:#0b0806;color:#ecc76e;font:700 15px Georgia,serif;cursor:pointer}.bk-btn:disabled{opacity:.35;cursor:default}' +
    '#bk-page{flex:1;overflow:auto;padding:6px 34px 18px;-webkit-overflow-scrolling:touch;transform-origin:50% 50%;backface-visibility:hidden}' +
    '#bk-page.turn-n{animation:bkTurnN .32s ease-out}#bk-page.turn-p{animation:bkTurnP .32s ease-out}@keyframes bkTurnN{from{transform:rotateY(-24deg) translateX(26px);opacity:0}to{transform:none;opacity:1}}@keyframes bkTurnP{from{transform:rotateY(24deg) translateX(-26px);opacity:0}to{transform:none;opacity:1}}' +
    '@media (prefers-reduced-motion:reduce){#bk-page.turn-n,#bk-page.turn-p{animation:none}}' +
    '.bk-label{text-align:center;letter-spacing:.34em;font:700 13px Georgia,serif;color:#c99a3a;margin:10px 0 2px}.bk-title{text-align:center;margin:0 0 6px;font:700 clamp(22px,5.4vw,32px)/1.2 Georgia,serif;letter-spacing:.06em;color:#ecc76e;' +
    'text-shadow:0 1px 0 #2a1c08,0 0 1px #ecc76e}.bk-rule{height:9px;margin:10px auto 16px;width:72%;background:linear-gradient(#d9ab46,#d9ab46) center/100% 1px no-repeat,radial-gradient(circle,#d9ab46 3px,transparent 4px) center/18px 9px no-repeat}' +
    '#bk-page p{margin:0 0 14px;text-align:left}#bk-page p.bk-first:first-letter{float:left;font-size:3.3em;line-height:.86;padding:4px 8px 0 0;color:#ecc76e;font-weight:700}' +
    '.bk-cover{text-align:center;padding-top:4vh}.bk-cover .bk-big{font:700 clamp(30px,8vw,52px)/1.08 Georgia,serif;letter-spacing:.05em;color:#ecc76e;text-shadow:0 2px 0 #2a1c08;margin:14px 0}' +
    '.bk-cover .bk-sub{font-style:italic;color:#e2cf9c;