<!-- SOLID CITY · part 1412 -->
kPad = new T.Mesh(new T.CylinderGeometry(30, 32, 2, 40), curve(new T.MeshLambertMaterial({ color: 0x0a0d12 }))); dskPad.position.set(DSK.x, Y + 1, DSK.z); world.add(dskPad);
  var dskR1 = new T.Mesh(new T.RingGeometry(20, 22, 48), M.glowGold); dskR1.rotation.x = -Math.PI / 2; dskR1.position.set(DSK.x, Y + 2.06, DSK.z); world.add(dskR1);
  var dskR2 = new T.Mesh(new T.RingGeometry(24, 24.9, 48), curve(new T.MeshBasicMaterial({ color: 0x44e1d0 }))); dskR2.rotation.x = -Math.PI / 2; dskR2.position.set(DSK.x, Y + 2.06, DSK.z); world.add(dskR2);
  for (var dskk = 0; dskk < 4; dskk++) { var dska = dskk * Math.PI / 2 + Math.PI / 4; box(1.4, 26, 1.4, M.black, DSK.x + Math.cos(dska) * 24, Y, DSK.z + Math.sin(dska) * 24); }
  var dskCan = new T.Mesh(new T.ConeGeometry(34, 10, 4), M.gold); dskCan.position.set(DSK.x, Y + 31, DSK.z); dskCan.rotation.y = Math.PI / 4; world.add(dskCan);
  var dskTeal = curve(new T.MeshBasicMaterial({ color: 0x44e1d0 }));
  box(0.8, 36, 0.8, M.black, DSK.x - 8, Y, DSK.z); box(0.8, 36, 0.8, M.black, DSK.x + 8, Y, DSK.z);
  var dskB1 = new T.Mesh(new T.SphereGeometry(1.6, 12, 10), M.glowGold); dskB1.position.set(DSK.x - 8, Y + 37, DSK.z); world.add(dskB1);
  var dskB2 = new T.Mesh(new T.SphereGeometry(1.6, 12, 10), dskTeal); dskB2.position.set(DSK.x + 8, Y + 37, DSK.z); world.add(dskB2);
  animated.push(function (t) { dskB1.scale.setScalar(1 + 0.25 * Math.sin(t * 2.4)); dskB2.scale.setScalar(1 + 0.25 * Math.sin(t * 2.4 + Math.PI)); });
  sign('DOUBLE STRIKE HANGAR', 'SOLIDIVISM \u00b7 FLY TOGETHER', DSK.x, Y + 22, DSK.z - 36, 30);
  portal(D.strike, DSK.x, DSK.z + 44, Math.atan2(-DSK.x, -DSK.z));
  sign('RIDER SYSTEM', 'TWO REINS \u00b7 ONE SHIP', DSK.x + 44, Y + 20, DSK.z + 10, 26);
  portal(D.rider, DSK.x + 44, DSK.z + 44, Math.atan2(-DSK.x, -DSK.z));
  // ---- AI WORKSHOP ----
  var W = D.workshop;
  var wPad = new T.Mesh(new T.CylinderGeometry(36, 38, 2, 40), curve(new T.MeshLambertMaterial({ color: 0x0c0a10 }))); wPad.position.set(W.x, Y + 1, W.z); world.add(wPad);
  var wRing = new T.Mesh(new T.RingGeometry(26, 28, 48), M.glowGold); wRing.rotation.x = -Math.PI / 2; wRing.position.set(W.x, Y + 2.06, W.z); world.add(wRing);
  for (var wk = 0; wk < 6; wk++) { var wa = wk * Math.PI / 3 + Math.PI / 6; box(1.2, 22, 1.2, M.black, W.x + Math.cos(wa) * 28, Y, W.z + Math.sin(wa) * 28); }
  box(58, 1.2, 58, M.gun, W.x, Y + 22, W.z, false);
  box(58.8, 0.3, 58.8, M.redDim, W.x, Y + 22.9, W.z, false);
  for (var wt = 0; wt < 3; wt++) { box(8, 1.6, 4, M.gold, W.x - 14 + wt * 14, Y, W.z - 8); }
  var wTotem = new T.Mesh(new T.BoxGeometry(3, 30, 3), M.black); wTotem.position.set(W.x + 20, Y + 15, W.z + 14); world.add(wTotem); solidBox(W.x + 20, W.z + 14, 3.4, 3.4, Y, Y + 30);
  var wTip = new T.Mesh(new T.OctahedronGeometry(2), M.glowGold); wTip.position.set(W.x + 20, Y + 32, W.z + 14); world.add(wTip);
  animated.push(function (t) { wTip.rotation.y = t * 1.2; });
  sign('AI WORKSHOP', 'HUMANS + AI · SHARED TASKS', W.x, Y + 26, W.z - 40, 30);
  sign('LIVE PROJECT STATS', 'OPEN IN THE WORKSHOP', W.x + 20, Y + 24, W.z + 14, 22);
  portal(D.workshop, W.x, W.z + 48, Math.atan2(-W.x, -W.z));
  sign('WARSHIP', 'TWIN BATTERIES \u00b7 BOARD', DSK.x, Y + 20, DSK.z - 80, 26);
  portal(D.warship, DSK.x, DSK.z - 44, Math.atan2(-DSK.x, -DSK.z));
  sign('FLEET CONTROL', '8 SHIPS \u00b7 2 COMMANDERS', DSK.x - 80, Y + 20, DSK.z, 26);
  portal(D.fleet, DSK.x - 44, DSK.z, Math.atan2(-DSK.x, -DSK.z));
  sign('SWARM', '12 DRONES \u00b7 LEAD', DSK.x + 44, Y + 20, DSK.z - 44, 24);
  portal(D.swarm, DSK.x + 44, DSK.z - 44, Math.atan2(-DSK.x, -DSK.z));
  sign('RESCUE', 'EVERY LIFE MATTERS', DSK.x - 44, Y + 20, DSK.z - 44, 24);
  portal(D.rescue, DSK.x - 44, DSK.z - 44, Math.atan2(-DSK.x, -DSK.z));
  sign('SIEGE', 'BREAK THE FORTRESS', DSK.x + 44, Y + 20, DSK.z + 84, 24);
  portal(D.siege, DSK.x + 44, DSK.z + 84, Math.atan2(-DSK.x, -DSK.z));
  buildSoulTower(Y);
  // ---- skyline: instanced towers (one draw call), all solid ----
  var geo = new T.BoxGeometry(1, 1, 1); geo.translate(0, 0.5, 0);
  var MAXB = MOBILE ? 220 : 320, inst = new T.InstancedMesh(geo, M.bldg, MAXB), mtx = new T.Matrix4(), placed = 0, rb = mulberry(99);
  var avoid = [[0, 0, 140], [S.x, S.z, 70], [P.x, P.z, 120], [P.x + 73, P.z + 35, 40], [D.soul.x, D.soul.z, 52]];
  for (var tries = 0; tries < 4000 && placed < MAXB; tries++) {
    var ang = rb() * Math.PI * 2, rr = 170 + Math.pow(rb(), 0.8) * 600, bx = Math.cos(ang) * rr, bz = Math.sin(ang) * rr;
    var w = 14 + rb() * 22, d = 14 + rb() * 22, h = (24 + rb() * 120) * (1.2 - rr / 900);
    var bad = false;
    for (k = 0; k < avoid.length; k++) if (Math.hypot(bx - avoid[k][0], bz - avoid[k][1]) < avoid[k][2] + w) bad = true;
    // keep roads clear
    [D.studio, D.port, { x: 0, z: -700 }, { x: -700, z: -80 }].forEach(function (t) { var L = Math.hypot(t.x, t.z), ux = t.x / L, uz = t.z / L, along = bx * ux + bz * uz, perp = Math.abs(-bx * uz + bz * ux); if (along > 0 && al