<!-- SOLID CITY · part 2127 -->
st center columns
      if (cx === -340) h = Math.min(400, h + 40);
      westTower(T, root, foot, M, x, z, h, types[ti % 4], R);
      ti++;
    });
  });

  // ---- 6 BUSINESSES: the working city ----
  // (fit functions defined below; uses buildStore)
  var biz = [
    {x:-230, z:-100, ry:Math.PI/2, name:'THE MERIDIAN BANK', fit:bankFit},
    {x:-230, z:-60, ry:Math.PI/2, name:'PACIFIC RIM SHIPPING', fit:shipFit},
    {x:-230, z:-20, ry:Math.PI/2, name:'HALE & ASSOCIATES', fit:lawFit},
    {x:-230, z:20, ry:Math.PI/2, name:'THE COPPER ANCHOR', fit:restFit},
    {x:-230, z:60, ry:Math.PI/2, name:'THE DAILY MERIDIAN', fit:newsFit},
    {x:-230, z:100, ry:Math.PI/2, name:'ATELIER KAI', fit:archFit}
  ];
  // business materials (reuse retail material factory via a light shim)
  // buildStore needs M with wall/floor/ceil/glass/awn/strip/shelf/counter/etc + sign()
  // We'll construct a minimal M here.
  var BM = makeBizMaterials(T, o);
  biz.forEach(function(b) { buildStore(T, root, foot, BM, b); });

  // ---- HARBOR ----
  buildHarbor(T, root, foot, o, BM);
}

function makeBizMaterials(T, o) {
  return {
    gold: o.gold,
    wall: new T.MeshLambertMaterial({color: 0x2e3238}),
    floor: new T.MeshLambertMaterial({color: 0x3d4149}),
    ceil: new T.MeshLambertMaterial({color: 0x22262c}),
    glass: new T.MeshLambertMaterial({color: 0x9fc4e8, transparent: true, opacity: 0.4}),
    awn: new T.MeshLambertMaterial({color: 0x2a4a6a}),
    strip: new T.MeshBasicMaterial({color: 0xffe8c0}),
    shelf: new T.MeshLambertMaterial({color: 0x5a4028}),
    counter: new T.MeshLambertMaterial({color: 0x3a3f47}),
    register: new T.MeshLambertMaterial({color: 0x1a1c20}),
    table: new T.MeshLambertMaterial({color: 0x8a6a48}),
    chair: new T.MeshLambertMaterial({color: 0x6a4a3a}),
    rackBar: new T.MeshLambertMaterial({color: 0xb0b6be}),
    caseGlass: new T.MeshLambertMaterial({color: 0xcfe4f8, transparent: true, opacity: 0.3}),
    glowA: new T.MeshBasicMaterial({color: 0x7ad8ff}),
    glowB: new T.MeshBasicMaterial({color: 0xffb86a}),
    marble: new T.MeshLambertMaterial({color: 0xd8d4c8}),
    paper: new T.MeshLambertMaterial({color: 0xf0ece0}),
    blueprint: new T.MeshLambertMaterial({color: 0x2a4a8a}),
    sign: function(name) {
      var c = document.createElement('canvas'); c.width = 512; c.height = 128;
      var x2 = c.getContext('2d');
      x2.fillStyle = '#14161a'; x2.fillRect(0, 0, 512, 128);
      x2.strokeStyle = '#d8aa48'; x2.lineWidth = 4; x2.strokeRect(6, 6, 500, 116);
      x2.fillStyle = '#e8c86a'; x2.textAlign = 'center'; x2.textBaseline = 'middle';
      var fs = name.length > 16 ? 30 : 40;
      x2.font = 'bold ' + fs + 'px Georgia,serif'; x2.fillText(name, 256, 66);
      var t = new T.CanvasTexture(c); t.encoding = T.sRGBEncoding; t.anisotropy = 4; return t;
    }
  };
}

// ---- business interiors ----
function bankFit(bx, sl, M) {
  [[-6,-3],[6,-3],[-6,3],[6,3]].forEach(function(p){
    bx(1.4,7,1.4,M.marble, p[0],3.5,p[1]); sl(p[0],p[1],1.4,1.4,0,7);
  });
  bx(10,1.2,1.8,M.marble, 0,0.6,-3);
  bx(10.3,0.15,2,M.gold, 0,1.28,-3);
  for (var i=-1;i<=1;i++) bx(0.15,1.0,1.8,M.shelf, i*3.3,1.8,-3);
  sl(0,-3,10,1.8,0,1.3);
  // vault door
  bx(4.5,4.5,0.8,M.register, 0,2.25,-6.6);
  bx(1.2,1.2,0.9,M.gold, 0,2.25,-6.5);
  bx(3.4,0.3,0.9,M.gold, 0,2.25,-6.5);
  bx(0.3,3.4,0.9,M.gold, 0,2.25,-6.5);
  sl(0,-6.6,4.5,0.8,0,4.5);
  // waiting chairs
  for (var c=0;c<4;c++){ bx(0.9,0.9,0.9,M.chair, -4.5+c*3,0.45,4.5); sl(-4.5+c*3,4.5,0.9,0.9,0,0.9); }
}
function shipFit(bx, sl, M) {
  // desks with manifests
  [[-4,-2],[4,-2],[-4,2],[4,2]].forEach(function(p){
    bx(3,0.9,1.6,M.table, p[0],0.45,p[1]);
    bx(1.2,0.35,0.9,M.paper, p[0],1.05,p[1]);
    bx(0.8,0.8,0.8,M.chair, p[0],0.4,p[1]+1.6);
    sl(p[0],p[1],3,1.6,0,1.2); sl(p[0],p[1]+1.6,0.8,0.8,0,0.8);
  });
  // big wall chart
  bx(10,4,0.25,M.blueprint, 0,3.5,-6.7);
  bx(10.4,4.4,0.15,M.gold, 0,3.5,-6.8);
  // model ship on table
  bx(4,0.9,2,M.table, 0,0.45,4.5);
  bx(2.4,0.8,0.8,M.register, 0,1.3,4.5);
  bx(0.8,1.2,0.8,M.paper, 0.6,2.2,4.5);
  sl(0,4.5,4,2,0,1.8);
  bx(6,1.2,1.6,M.counter, -5.5,0.6,5.5); sl(-5.5,5.5,6,1.6,0,1.2);
}
function lawFit(bx, sl, M) {
  bx(5,1.1,1.6,M.counter, -5,0.55,4.5); sl(-5,4.5,5,1.6,0,1.1); // reception
  // 3 offices
  for (var i=0;i<3;i++){
    var ox=-5+i*5;
    bx(0.3,2.8,6,M.shelf, ox,1.4,-2); sl(ox,-2,0.3,6,0,2.8);
    bx(2.6,0.9,1.4,M.table, ox+1.8,0.45,-2);
    bx(0.8,0.8,0.8,M.chair, ox+1.8,0.4,-0.2);
    sl(ox+1.8,-2,2.6,1.4,0,0.9);
  }
  // bookshelf wall
  for (var b=0;b<5;b++){
    bx(1.6,2.6,0.6,M.shelf, -6+b*2,1.3,-6.5);
    for (var sh=0;sh<3;sh++) bx(1.4,0.4,0.4,M.paper, -6+b*2,0.7+sh*0.7,-6.5);
  }
  sl(0,-6.5,10,0.6,0,2.6);
  // conference table
  bx(5,0.9,2,M.table, 3,0.45,3.5);
  for (var ch=0;ch<4;ch++){ bx(0.8,0.8,0.8,M.chair, 1.5+ch*1.2,0.4,5.2); sl(1.5+ch*1.2,5.2,0.8,0.8,0,0.8); }
  sl(3,3.5,5,2,0,0.9);
}
function restFit(bx, sl, M) {
  // bar (L-shape)