<!-- SOLID CITY · part 359 -->
 = 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, 0.3, 48), curve(new T.MeshLambertMaterial({ color: 0x0a080b }))); pad.position.set(P.x, Y + 0.15, 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);
  // Runway 08/28 — the King's designation: 08 east-to-west, 28 west-to-east
  function runwayNum(txt, x, z) {
    var c = document.createElement('canvas'); c.width = 256; c.height = 256;
    var g = c.getContext('2d');
    g.fillStyle = '#f0d080'; g.textAlign = 'center'; g.textBaseline = 'middle';
    g.font = 'bold 170px Arial, sans-serif'; g.fillText(txt, 128, 140);
    var t = new T.CanvasTexture(c); t.encoding = T.sRGBEncoding; t.anisotropy = 4;
    var m = new T.Mesh(new T.PlaneGeometry(18, 18), new T.MeshBasicMaterial({ map: t, transparent: true, depthWrite: false }));
    m.rotation.x = -Math.PI / 2; m.position.set(x, Y + 0.36, z); world.add(m);
  }
  runwayNum('08', P.x + 28, P.z);
  runwayNum('28', P.x - 28, P.z);
  sign('RUNWAY 08 \