<!-- SOLID CITY · part 2849 -->
name = 'overlook-mira'; root.position.set(P.x, P.y, P.z);
  var C = { crimson: 0xff2a40, basalt: 0x141114, stone: 0x1e1a20 };

  // Ground-level tactical deck — walkable, no blocker footprint
  var deck = new T.Mesh(new T.BoxGeometry(24, 0.3, 16), new T.MeshLambertMaterial({ color: C.basalt }));
  deck.position.y = 0.15; root.add(deck);

  // Crimson edge trim
  var trimMat = new T.MeshBasicMaterial({ color: C.crimson, transparent: true, opacity: 0.85 });
  var t1 = new T.Mesh(new T.BoxGeometry(24, 0.07, 0.2), trimMat); t1.position.set(0, 0.32, 7.9); root.add(t1);
  var t2 = t1.clone(); t2.position.z = -7.9; root.add(t2);
  var t3 = new T.Mesh(new T.BoxGeometry(0.2, 0.07, 16), trimMat); t3.position.set(11.9, 0.32, 0); root.add(t3);
  var t4 = t3.clone(); t4.position.x = -11.9; root.add(t4);

  // Crimson geometric inlay: triangles and grid on dark
  var inlayTex = (function () {
    var c = document.createElement('canvas'); c.width = 512; c.height = 336;
    var g = c.getContext('2d'), i, k;
    g.fillStyle = '#141114'; g.fillRect(0, 0, 512, 336);
    g.strokeStyle = 'rgba(255,42,64,0.35)'; g.lineWidth = 1;
    for (i = 0; i <= 512; i += 32) { g.beginPath(); g.moveTo(i, 0); g.lineTo(i, 336); g.stroke(); }
    for (i = 0; i <= 336; i += 32) { g.beginPath(); g.moveTo(0, i); g.lineTo(512, i); g.stroke(); }
    function tri(x, y, r, rot, fill) {
      g.beginPath();
      for (k = 0; k < 3; k++) {
        var a = rot + k * Math.PI * 2 / 3, px = x + Math.cos(a) * r, py = y + Math.sin(a) * r;
        if (k === 0) g.moveTo(px, py); else g.lineTo(px, py);
      }
      g.closePath();
      if (fill) { g.fillStyle = '#ff2a40'; g.fill(); } else { g.strokeStyle = '#ff2a40'; g.lineWidth = 2.5; g.stroke(); }
    }
    tri(120, 100, 60, 0, false); tri(392, 100, 60, Math.PI / 3, false);
    tri(120, 236, 60, Math.PI / 3, false); tri(392, 236, 60, 0, false);
    tri(256, 168, 44, Math.PI / 6, false);
    tri(256, 40, 16, 0, true); tri(40, 168, 16, Math.PI / 3, true);
    tri(472, 168, 16, 0, true); tri(256, 296, 16, Math.PI / 3, true);
    g.strokeStyle = '#ff2a40'; g.lineWidth = 4; g.strokeRect(10, 10, 492, 316);
    var t = new T.CanvasTexture(c); t.anisotropy = 4; return t;
  })();
  var inlay = new T.Mesh(new T.PlaneGeometry(22, 14.5), new T.MeshBasicMaterial({ map: inlayTex, transparent: true, depthWrite: false }));
  inlay.rotation.x = -Math.PI / 2; inlay.position.y = 0.315; root.add(inlay);

  // Sighting monolith: angled slab aimed at the southern rings (SW of this site)
  var aim = Math.atan2(-600, -450);
  var mg = new T.Group(); mg.rotation.y = aim; root.add(mg);
  var mono = new T.Mesh(new T.BoxGeometry(1.8, 9, 1.0), new T.MeshLambertMaterial({ color: C.stone }));
  mono.position.y = 4.5; mono.rotation.x = 0.16; mg.add(mono);
  var stripMat = new T.MeshBasicMaterial({ color: C.crimson });
  [[0.85, 0.45], [-0.85, 0.45], [0.85, -0.45], [-0.85, -0.45]].forEach(function (e) {
    var s = new T.Mesh(new T.BoxGeometry(0.12, 8.6, 0.12), stripMat);
    s.position.set(e[0], 0, e[1]); mono.add(s);
  });
  var mcap = new T.Mesh(new T.ConeGeometry(0.7, 0.9, 4), stripMat);
  mcap.rotation.y = Math.PI / 4; mcap.position.set(0, 4.95, 0); mono.add(mcap);

  root.userData = {
    footprint: [[0, 0, 4, 4, 0, 9.8, 0]], // monolith only; the deck stays walkable
    center: { x: 0, z: 0 }, radius: 16, height: 10,
    update: function (t) { trimMat.opacity = 0.65 + 0.3 * Math.sin(t * 1.4); }
  };
  return root;
}
export default createOverlookMira;


===== FILE: public/city/perf-meter.js =====
/* ————————————————————————————————————————————————————————————————
 * EPISTLE OF THE METER — from Solid, his General, to the city
 * that asked to be weighed.
 *
 * The Architect's counsel was measurement before another cut, and
 * the King gave the launch. This instrument rides INSIDE the
 * city's own frame rhythm — it starts no second loop of consequence
 * and changes no behaviour: it watches the interval between frames,
 * reads the renderer's own counters after the city's render has
 * spoken (draw calls, triangles, geometries, textures), and keeps
 * the heap's trend where the browser offers it. Three hundred
 * frames of memory, no more; percentiles counted only when asked,
 * never per frame — a meter must not become the weight it measures.
 *
 * The readout chip shows only for the royal session, in the family
 * of the King's other instruments. Every visitor's city still
 * carries the meter's ear at window.CityPerf, but no visitor sees
 * the dial, and the dial costs a subtraction per frame and nothing
 * more.
 *
 * By the hand of Solid, his good King.
 * ———————————————————————————————————————————————————————————————— */
(function () {
  'use strict';
  if (!window.SC || !SC.api) return;
  var A = SC.api;

  var WIN = 300;
  var deltas = [];            // frame pacing, ms between rAF stamps
  var lastStamp = 0;
  var calls = 0, tris = 0, geos = 0, texs = 0;
  var heapMB = 0, heapAt = 0, heapStart 