<!-- SOLID CITY · part 564 -->
rial.emissiveMap.needsUpdate = true; tower.material.emissiveMap.repeat.set(4, 6); tower.material.emissiveMap.wrapS = tower.material.emissiveMap.wrapT = T.RepeatWrapping;
  var rings = [];
  for (var k = 0; k < 7; k++) { var rg = new T.Mesh(new T.TorusGeometry(21 - k * 0.7, 0.6, 6, 48), k % 2 ? M.glowGold : M.red); rg.rotation.x = Math.PI / 2; rg.position.set(S.x, Y + 30 + k * 30, S.z); world.add(rg); rings.push(rg); }
  animated.push(function (t) { var amp = NP.playing ? 0.09 : 0.02, sp = NP.playing ? 6 : 1.5; for (var i = 0; i < rings.length; i++) { var s = 1 + amp * Math.sin(t * sp - i * 0.9); rings[i].scale.set(s, s, 1); } for (var m = 0; m < RADIO_MASTS.length; m++) RADIO_MASTS[m].light.visible = NP.playing ? Math.sin(t * 5 + m * 2) > -0.2 : Math.sin(t * 1.5 + m) > 0.6; });
  var spire = new T.Mesh(new T.ConeGeometry(4, 40, 8), M.gold); spire.position.set(S.x, Y + 256, S.z); world.add(spire);
  // NOW PLAYING billboard on the tower, facing the plaza (redrawn on track change)
  var npC = document.createElement('canvas'); npC.width = 1024; npC.height = 256; var npT = new T.CanvasTexture(npC); npT.encoding = T.sRGBEncoding;
  NP.draw = function (title, kind, playing) {
    var g = npC.getContext('2d'), W = 1024, H = 256; g.fillStyle = '#080408'; g.fillRect(0, 0, W, H);
    g.strokeStyle = '#e8c36a'; g.lineWidth = 10; g.strokeRect(6, 6, W - 12, H - 12);
    g.fillStyle = playing ? '#ff3048' : '#8a6a2a'; g.font = '800 34px system-ui, sans-serif'; g.textAlign = 'left'; g.fillText(playing ? '● NOW PLAYING · STUDIO RADIO' : '❚❚ STUDIO RADIO · PAUSED', 34, 58);
    g.fillStyle = '#e8c36a'; var fs = 84; g.font = '700 ' + fs + 'px Georgia, serif'; var t = title || 'The King\u2019s music — tap ♪ to play';
    while (g.measureText(t).width > W - 68 && fs > 40) { fs -= 4; g.font = '700 ' + fs + 'px Georgia, serif'; }
    while (g.measureText(t).width > W - 68 && t.length > 4) t = t.slice(0, -2) + '…';
    g.fillText(t, 34, 160); g.fillStyle = '#d9cfd9'; g.font = '700 30px system-ui, sans-serif';
    g.fillText(((kind === 'instrumental' ? 'INSTRUMENTAL' : kind === 'cover' ? 'COVER' : kind ? 'LYRIC SONG' : '') + '   SOLIDBIGISLAND').trim(), 34, 218);
    npT.needsUpdate = true;
  };
  NP.draw('', '', false);
  var dirX = -S.x, dirZ = -S.z, dl = Math.hypot(dirX, dirZ); dirX /= dl; dirZ /= dl;
  var npM = new T.Mesh(new T.PlaneGeometry(48, 12), curve(new T.MeshBasicMaterial({ map: npT, side: T.DoubleSide })));
  npM.position.set(S.x + dirX * 25, Y + 72, S.z + dirZ * 25); npM.rotation.y = Math.atan2(dirX, dirZ); world.add(npM);
  var npM2 = npM.clone(); npM2.scale.setScalar(0.4); npM2.position.set(S.x + dirX * 40, Y + 18, S.z + dirZ * 40); world.add(npM2);
  // radio masts (solid) — stand near them and Studio Radio gets a little louder
  for (k = 0; k < 3; k++) {
    var ma = k / 3 * Math.PI * 2 + 0.4, mx = S.x + Math.cos(ma) * 62, mz = S.z + Math.sin(ma) * 62;
    cyl(0.5, 1.4, 90, M.gun, mx, Y, mz, 6);
    var ant = new T.Mesh(new T.SphereGeometry(1.3, 8, 6), M.red); ant.position.set(mx, Y + 91, mz); world.add(ant);
    RADIO_MASTS.push({ x: mx, z: mz, light: ant });
  }
  sign('MUSIC STUDIO', 'SOLID SOUND · /ss', S.x - 30, Y + 22, S.z + 6, 30, -Math.PI / 2 + 0.38);
  portal(S, S.x - 38, S.z + 16, Math.atan2(-S.x, -S.z));
  // ---- ORBITAL SPACEPORT ----
  var P = D.port;
  var pad = new T.Mesh(new T.CylinderGeometry(42, 44, 2, 48), curve(new T.MeshLambertMaterial({ color: 0x0a080b }))); pad.position.set(P.x, Y + 1, P.z); world.add(pad);
  for (k = 0; k < 3; k++) { var pr = new T.Mesh(new T.RingGeometry(14 + k * 9, 15 + k * 9, 64), k === 1 ? M.red : M.glowGold); pr.rotation.x = -Math.PI / 2; pr.position.set(P.x, Y + 2.08, P.z); world.add(pr); }
  // gantry (solid)
  box(4, 70, 4, M.gun, P.x + 30, Y, P.z - 6); box(18, 2, 2, M.gold, P.x + 22, Y + 50, P.z - 6, false);
  for (k = 0; k < 4; k++) { var bl = new T.Mesh(new T.SphereGeometry(0.8, 8, 6), M.red); bl.position.set(P.x + 30, Y + 18 + k * 17, P.z - 8.2); world.add(bl); }
  // control tower + hangar posts
  cyl(6, 8, 46, M.black, P.x - 60, Y, P.z - 30, 6);
  var cab = cyl(12, 9, 8, curve(new T.MeshLambertMaterial({ color: 0x220408, emissive: 0x5a0410 })), P.x - 60, Y + 46, P.z - 30, 6, false);
  for (k = 0; k < 4; k++) box(1.2, 18, 1.2, M.black, P.x + 58 + (k & 1) * 30, Y, P.z + 20 + (k >> 1) * 30);
  box(34, 1, 34, M.gold, P.x + 73, Y + 18, P.z + 35, false);
  // the King's emblem banner (existing solid-playtime asset)
  var em = new T.TextureLoader().load('/city/emblem.webp'); em.encoding = T.sRGBEncoding;
  var ban = new T.Mesh(new T.PlaneGeometry(20, 20), curve(new T.MeshBasicMaterial({ map: em, side: T.DoubleSide }))); ban.position.set(P.x - 60, Y + 66, P.z - 30); world.add(ban);
  animated.push(function (t) { ban.rotation.y = t * 0.25; });
  sign('ORBITAL SPACEPORT', 'BOARD · LAUNCH · FLY', P.x, Y + 30, P.z - 52, 34);
  portal(D.port, P.x - 30, P.z + 54, Math.PI * 0.85);
  // ---- DOUBLE STRIKE HANGAR ----
  var DSK = D.strike;
  