<!-- SOLID CITY · part 2885 -->
;
        var tw = TOWERS.filter(function (x) { return x.id === el.tower; })[0];
        var dx = wx - (P.x + tw.ox + el.x), dz = wz - (P.z + tw.oz + el.z);
        if (Math.abs(dx) < 4 && Math.abs(dz) < 4) {
          var nf = (el.idx + 1) % el.floors.length;
          var names = ['LOBBY', 'FLOOR 2', 'ROOF'];
          return 'ELEVATOR \u2192 ' + (names[nf] || ('FLOOR ' + (nf + 1)));
        }
      }
      return null;
    },
    boardElevator: function (wx, wz) {
      for (var e = 0; e < elevators.length; e++) {
        var el = elevators[e]; if (el.moving) continue;
        var tw = TOWERS.filter(function (x) { return x.id === el.tower; })[0];
        var dx = wx - (P.x + tw.ox + el.x), dz = wz - (P.z + tw.oz + el.z);
        if (Math.abs(dx) < 4 && Math.abs(dz) < 4) {
          el.toIdx = (el.idx + 1) % el.floors.length;
          el.from = el.floors[el.idx]; el.to = el.floors[el.toIdx];
          el.t = 0; el.moving = true;
          return true;
        }
      }
      return false;
    }
  };
  return root;
}


===== FILE: public/city/quadrant-crown.js.bak-visual-20261011 =====
/* QUADRANT CROWN — four enterable towers (Command, Intelligence, Living, Frontier).
   The King's lightweight directive: maximum sophistication, minimum weight.
   One shared tower factory, selective interiors (lobby + floor 2), demo storefronts,
   walkable stairs, rideable elevators, two walkable bridges. No Medusa, no new DB.
   Exports createQuadrantCrown({THREE, position, shops}). */
export function createQuadrantCrown(o) {
  var T = o.THREE, P = o.position || { x: 0, y: 0, z: 0 };
  var SHOPS = o.shops || { stores: [] };
  var root = new T.Group(); root.name = 'quadrant-crown';
  root.position.set(P.x, P.y || 0, P.z);

  var FH = 8, W = 36, D = 36, FLOORS = 12, TH = FLOORS * FH; // 96m
  var foot = [], elevators = [], standFloors = [], portholes = [];

  /* ---- shared lightweight materials ---- */
  function lam(c, e) { return new T.MeshLambertMaterial({ color: c, emissive: e || 0x000000 }); }
  var M = {
    dark: lam(0x1a2537), steel: lam(0x3a4556),
    glass: new T.MeshLambertMaterial({ color: 0x92c9e8, transparent: true, opacity: 0.36 }),
    gold: lam(0xd8a833, 0x352400),
    white: lam(0xe8e4da), wood: lam(0x6b4a2f)
  };
  function box(parent, w, h, d, x, y, z, mt) {
    var m = new T.Mesh(new T.BoxGeometry(w, h, d), mt); m.position.set(x, y, z); parent.add(m); return m;
  }
  function FP(x, z, w, d, y0, y1) { foot.push([x, z, w, d, y0, y1, 0]); } // [x,z,w,d,y0,y1,rot]
  function SF(x0, x1, z0, z1, y) { standFloors.push({ x0: x0, x1: x1, z0: z0, z1: z1, y: y }); }

  var TOWERS = [
    { id: 'command', name: 'COMMAND SPIRE', accent: 0xffc65c, tint: 0x9caec6, ox: -55, oz: -55 },
    { id: 'intelligence', name: 'INTELLIGENCE TOWER', accent: 0x4be5ff, tint: 0x83b8cc, ox: 55, oz: -55 },
    { id: 'living', name: 'LIVING TOWER', accent: 0xffda72, tint: 0xc7b7a0, ox: -55, oz: 55 },
    { id: 'frontier', name: 'FRONTIER TOWER', accent: 0xff5b6b, tint: 0x9c9cb3, ox: 55, oz: 55 }
  ];

  function towerShops(id) { return SHOPS.stores.filter(function (s) { return s.tower === id; }).slice(0, 2); }

  function buildTower(cfg) {
    var g = new T.Group(); g.name = 'tower:' + cfg.id; g.position.set(cfg.ox, 0, cfg.oz); root.add(g);
    var shell = lam(cfg.tint), trim = lam(cfg.accent, cfg.accent);
    var hw = W / 2, hd = D / 2;

    /* corner columns */
    for (var sx = -1; sx <= 1; sx += 2) for (var sz = -1; sz <= 1; sz += 2) {
      box(g, 1.6, TH, 1.6, sx * hw, TH / 2, sz * hd, shell);
      FP(cfg.ox + sx * hw, cfg.oz + sz * hd, 2.2, 2.2, 0, TH);
    }
    /* floor plates + accent trim */
    for (var f = 0; f <= FLOORS; f++) {
      var y = f * FH;
      box(g, W + 2, 0.55, D + 2, 0, y, 0, M.dark);
      box(g, W + 2, 0.4, 0.5, 0, y, hd, trim); box(g, W + 2, 0.4, 0.5, 0, y, -hd, trim);
      box(g, 0.5, 0.4, D + 2, hw, y, 0, trim); box(g, 0.5, 0.4, D + 2, -hw, y, 0, trim);
    }
    /* glass facades floors 1-11 (skip lobby) */
    for (var fl = 1; fl < FLOORS; fl++) {
      var gy = fl * FH + FH / 2;
      box(g, W - 3, FH - 1, 0.22, 0, gy, hd, M.glass); box(g, W - 3, FH - 1, 0.22, 0, gy, -hd, M.glass);
      box(g, 0.22, FH - 1, D - 3, hw, gy, 0, M.glass); box(g, 0.22, FH - 1, D - 3, -hw, gy, 0, M.glass);
    }
    /* lobby exterior walls with SOUTH door gap (8m wide) */
    var lh = FH;
    box(g, W, lh, 0.6, 0, lh / 2, -hd, shell); FP(cfg.ox, cfg.oz - hd, W, 1, 0, lh); // north wall
    box(g, 0.6, lh, D, hw, lh / 2, 0, shell); FP(cfg.ox + hw, cfg.oz, 1, D, 0, lh);   // east
    box(g, 0.6, lh, D, -hw, lh / 2, 0, shell); FP(cfg.ox - hw, cfg.oz, 1, D, 0, lh);  // west
    box(g, (W - 8) / 2, lh, 0.6, -(8 + (W - 8) / 2) / 2, lh / 2, hd, shell);           // south-left
    box(g, (W - 8) / 2, lh, 0.6, (8 + (W - 8) / 2) / 2, lh / 2, hd, shell);           // south-right
    FP(cfg.ox - (8 + (W - 8) / 2) / 2, cfg.oz + hd, (W - 8) / 2, 1, 0, lh);
    FP(cfg.ox + (8 + (W - 8) / 2) / 2, cfg.