diff --git a/webui/static/discover.js b/webui/static/discover.js
index 245d5c3c..dad9bad8 100644
--- a/webui/static/discover.js
+++ b/webui/static/discover.js
@@ -5059,6 +5059,26 @@ function _artMapGlossSprite() {
return c;
}
+// A cached soft radial "halo" sprite per genre hue — drawn behind the focused
+// island so it reads as a glowing place on the water. Cached per hue (≤ a few),
+// so it's just a drawImage per frame, never a per-frame gradient.
+function _artMapHaloSprite(hue) {
+ _artMap._halos = _artMap._halos || {};
+ if (_artMap._halos[hue]) return _artMap._halos[hue];
+ const S = 256;
+ const c = document.createElement('canvas');
+ c.width = S; c.height = S;
+ const cx = c.getContext('2d');
+ const g = cx.createRadialGradient(S / 2, S / 2, 0, S / 2, S / 2, S / 2);
+ g.addColorStop(0, `hsla(${hue},75%,55%,0.22)`);
+ g.addColorStop(0.45, `hsla(${hue},75%,50%,0.08)`);
+ g.addColorStop(1, `hsla(${hue},75%,50%,0)`);
+ cx.fillStyle = g;
+ cx.fillRect(0, 0, S, S);
+ _artMap._halos[hue] = c;
+ return c;
+}
+
// Deterministic hue (0–360) from a genre name, so each island has a stable tint.
function _artMapGenreHue(name) {
let h = 0;
@@ -5229,11 +5249,11 @@ function _artMapFocusIsland(idx, opts = {}) {
_artMap._focusIdx = idx;
const isl = islands[idx];
- // Show only this island's bubbles + its title; hide everything else so the
- // buffer/zoom frame just this island.
+ // Show only this island's bubbles; hide everything else (and the in-world
+ // titles — the nav bar already names the genre) so the frame is just this
+ // island's covers.
for (const n of _artMap.placed) {
- const mine = n._isLabel ? (n.name === isl.name) : (n._island === isl.name);
- n.opacity = mine ? 1 : 0;
+ n.opacity = (!n._isLabel && n._island === isl.name) ? 1 : 0;
}
// Frame the island in ~80% of the viewport.
@@ -5299,15 +5319,53 @@ function _artMapUpdateIslandNav() {
nav.style.cssText = `position:absolute;top:64px;left:${sbW + 16}px;display:flex;align-items:center;gap:12px;padding:7px 12px;background:rgba(16,12,28,0.82);backdrop-filter:blur(10px);border:1px solid rgba(168,85,247,0.25);border-radius:14px;z-index:30;box-shadow:0 6px 24px rgba(0,0,0,0.45);user-select:none;`;
const idx = _artMap._focusIdx || 0;
const isl = islands[idx];
- const btn = 'width:30px;height:30px;border-radius:50%;border:1px solid rgba(255,255,255,0.18);background:rgba(255,255,255,0.06);color:#fff;font-size:13px;cursor:pointer;display:flex;align-items:center;justify-content:center;';
+ const btn = 'width:30px;height:30px;border-radius:50%;border:1px solid rgba(255,255,255,0.18);background:rgba(255,255,255,0.06);color:#fff;font-size:13px;cursor:pointer;display:flex;align-items:center;justify-content:center;flex:none;';
nav.innerHTML = `
-