// WorldMapGL — MapLibre GL (flat) + globe.gl (globe)
// mapMode="flat"  → Mercator, renderWorldCopies:false
// mapMode="globe" → globe.gl 3D sphere, drag-to-rotate, night-sky bg, projected chips

// Globe mode uses an earth-night texture for continents (light & cached by the
// browser after first paint) instead of 200 tessellated country polygons.
// This replaces ~800KB of GeoJSON + ~500ms of main-thread triangulation
// with a single ~150KB image the GPU handles.

// ── Global chip sets (used by imperative position loops) ──────────────────
// Three tiers of chip visibility:
//   alwaysSet (zoomed out, ~0-33%): G7 + BRICS + a handful of regional anchors — ~14 chips, uncluttered
//   midSet    (zoomed ~33-66%):     adds top-40 economies — ~30 chips, still readable
//   all       (zoomed 66%+):        every country with a chip ref
window.__chipAlwaysSet = new Set([
  "US","CA","BR","GB","DE","FR","RU","CN","JP","IN","AU","ZA","TR","SA"
]);
window.__chipMidSet = new Set([
  // alwaysSet
  "US","CA","BR","GB","DE","FR","RU","CN","JP","IN","AU","ZA","TR","SA",
  // + second-tier economies & regional anchors
  "MX","AR","CL","CO","PE","ES","IT","CH","SE","NO","PL","UA","RO","HU",
  "AE","IL","EG","NG","KE","MA","KR","ID","TH","VN","MY","SG","PH","HK","PK","NZ","BD"
]);

// ── O(1) country lookups — built once, used in hot loops ──────────────────
window.__countryByCode = {};
window.__countryByCcy  = {};
if (window.COUNTRIES) {
  window.COUNTRIES.forEach(function(c) {
    window.__countryByCode[c.code] = c;
    window.__countryByCcy[c.ccy]   = c;
  });
}

// Pre-compute arrays of country objects for each tier so hot loops can
// iterate without allocating (no Array.from / .map / .filter each frame).
window.__chipAlwaysArr = [];
window.__chipMidArr    = [];
if (window.COUNTRIES) {
  window.COUNTRIES.forEach(function(c) {
    if (window.__chipAlwaysSet.has(c.code)) window.__chipAlwaysArr.push(c);
    if (window.__chipMidSet.has(c.code))    window.__chipMidArr.push(c);
  });
}

function WorldMapGL({
  base, hovered, onHoverCountry, onLeaveCountry, onClickCountry,
  search, mapMode, mapApiRef,
}) {
  mapMode = mapMode || "flat";

  const containerRef = React.useRef(null);
  const mapRef       = React.useRef(null);
  const overlayRef   = React.useRef(null);
  const [ready, setReady] = React.useState(false);
  const [spaceOpacity, setSpaceOpacity] = React.useState(1);
  // mapModeRef — lets the flat render callback read current mapMode without stale closure
  const mapModeRef = React.useRef(mapMode);
  React.useEffect(function() {
    mapModeRef.current = mapMode;
    // On mode switch: clear ALL chip positions so ghosts from the other mode
    // don't linger. The active mode's loop will re-position its chips next tick.
    var refs = window.__chipRefs || {};
    var codes = Object.keys(refs);
    for (var i = 0; i < codes.length; i++) {
      refs[codes[i]].style.transform = 'translate3d(-9999px,-9999px,0)';
    }
    // Invalidate cached key so flat tick re-projects on next render
    if (window.__resetFlatKey) window.__resetFlatKey();
  }, [mapMode]);

  const mapStyle = React.useMemo(function() { return buildMapStyle(); }, []);

  // ── Init MapLibre once ─────────────────────────────────────────────────────
  React.useEffect(function() {
    if (!window.maplibregl) { console.error("maplibregl not loaded"); return; }
    var map = new window.maplibregl.Map({
      container:          containerRef.current,
      style:              mapStyle,
      center:             [10, 20],
      zoom:               1.4,
      minZoom:            0.8,
      maxZoom:            10,
      renderWorldCopies:  false,
      attributionControl: false,
      dragRotate:         false,
      pitchWithRotate:    false,
      touchPitch:         false,
      fadeDuration:       120,
      antialias:          false, // fix #2: kill MSAA overhead
    });
    mapRef.current = map;

    // Silence known-benign MapLibre style-race errors; log anything else
    map.on("error", function(ev) {
      var msg = ev && ev.error && ev.error.message || '';
      if (msg.indexOf("non-existing layer") !== -1) return;
      if (msg.indexOf("does not exist in the map's style") !== -1) return;
      console.warn("MapLibre:", msg);
    });

    if (window.deck && window.deck.MapboxOverlay) {
      var overlay = new window.deck.MapboxOverlay({ interleaved: true, layers: [] });
      map.addControl(overlay);
      overlayRef.current = overlay;
    }

    // Direct DOM chip updater — runs synchronously on MapLibre render event.
    // Bypasses React scheduler entirely: chip transforms update in the same JS
    // task as MapLibre's WebGL frame → zero lag, zero wiggle.
    var lastFlatKey = '';
    var flatPrevPositioned = {};
    function updateFlatDom() {
      // Tick runs for BOTH flat and globe now — MapLibre's setProjection handles the sphere,
      // map.project([lng,lat]) is projection-aware so chip positioning just works.
      var m = mapRef.current;
      if (!m) return;
      var rect = containerRef.current && containerRef.current.getBoundingClientRect();
      if (!rect || !rect.width) return;
      var zoom = m.getZoom();
      var g    = window.__chipGlobals || {};
      // Skip if nothing affecting chip positions has changed
      var ctr  = m.getCenter();
      var key  = (ctr.lng*100|0)+','+(ctr.lat*100|0)+','+(zoom*10|0)+'|'+(g.base||'')+'|'+(g.hovered||'')+'|'+(g.search||'')+'|'+(g.hasFilter?'F':'A');
      if (key === lastFlatKey) return;
      lastFlatKey = key;
      window.__chipZoom = zoom; // expose for React opacity logic in atlas_gl
      // Fire tier listener when zoom crosses a threshold — so chipShouldShow re-runs
      var newTier = zoom >= 10 ? 3 : zoom >= 3.56 ? 2 : 1;
      if (newTier !== window.__chipTier) {
        window.__chipTier = newTier;
        if (window.__atlasTierListener) window.__atlasTierListener();
      }
      var isMobileLayout = window.innerWidth < 640;
      // zoom range: 0.8 (min) → 10 (max). Two tiers:
      //   desktop: 0-29% majors → 30%+ all chips (threshold 3.56)
      //   mobile:  0-24% majors → 25%+ all chips (threshold 3.10)
      var showAll = zoom >= (isMobileLayout ? 3.10 : 3.56);
      var refs = window.__chipRefs || {};
      var s    = (g.search || '').toLowerCase();
      var countries = window.COUNTRIES;
      // Two-pass rendering with collision: priority chips first, others only if they don't overlap.
      // Chip footprint: desktop ~88×34, mobile ~100×44 (larger tap target).
      var CHIP_W = isMobileLayout ? 100 : 88;
      var CHIP_H = isMobileLayout ? 44  : 34;
      // Pad collision test slightly so chips don't kiss edges
      var PAD = 4;
      var placed = []; // {x1,y1,x2,y2}
      function overlaps(x, y) {
        var x1 = x - PAD, y1 = y - PAD, x2 = x + CHIP_W + PAD, y2 = y + CHIP_H + PAD;
        for (var k = 0; k < placed.length; k++) {
          var r2 = placed[k];
          if (x2 < r2.x1 || x1 > r2.x2 || y2 < r2.y1 || y1 > r2.y2) continue;
          return true;
        }
        return false;
      }
      function priorityOf(c, searchMatch) {
        if (g.base === c.ccy) return 4;
        if (g.hovered === c.code) return 3;
        if (searchMatch) return 2;
        if (window.__chipAlwaysSet.has(c.code)) return 1;
        return 0;
      }
      // Build a priority-ordered candidate list
      var candidates = [];
      for (var j = 0; j < countries.length; j++) {
        var c = countries[j];
        var el = refs[c.code];
        if (!el) continue;
        var p = m.project([c.lon, c.lat]);
        // Globe horizon culling: back-of-sphere points still project inside the disc.
        // Use angular distance from map center — if > 85° the point is on the hidden hemisphere.
        var isGlobe = mapModeRef.current === 'globe';
        var onscreen;
        if (isGlobe) {
          var mc = m.getCenter();
          var lat1 = mc.lat * Math.PI / 180, lat2 = c.lat * Math.PI / 180;
          var dLng = (c.lon - mc.lng) * Math.PI / 180;
          var cosAngle = Math.sin(lat1)*Math.sin(lat2) + Math.cos(lat1)*Math.cos(lat2)*Math.cos(dLng);
          // cos(72°) ≈ 0.309 — only show chips whose centroid is clearly on the near hemisphere.
          // Tighter than 85° to prevent limb flicker (e.g. JPY showing when viewing N America).
          onscreen = cosAngle > 0.309;
        } else {
          onscreen = p.x > -100 && p.x < rect.width+100 && p.y > -100 && p.y < rect.height+100;
        }
        if (!onscreen) continue;
        var searchMatch = s && (c.code.toLowerCase().indexOf(s) !== -1 || c.ccy.toLowerCase().indexOf(s) !== -1 || c.name.toLowerCase().indexOf(s) !== -1);
        var isBaseCcy = g.base === c.ccy;
        // Explicit filter bypasses zoom tiers — user picked these countries, always show them.
        var show = g.hasFilter || showAll || isBaseCcy || (g.hovered === c.code) || searchMatch ||
                   window.__chipAlwaysSet.has(c.code);
        if (!show) continue;
        candidates.push({ c: c, el: el, x: p.x + 10, y: p.y - 40, pri: priorityOf(c, searchMatch) });
      }
      candidates.sort(function(a, b){ return b.pri - a.pri; });
      var flatNowPositioned = {};
      for (var q = 0; q < candidates.length; q++) {
        var cand = candidates[q];
        // Priority ≥2 (base/hovered/search) always shown — no collision check
        // Also skip collision when showAll or hasFilter is active — user wants every visible country rendered
        if (showAll || g.hasFilter || cand.pri >= 2 || !overlaps(cand.x, cand.y)) {
          // Integer-floor: GPU compositor fast-path on pixel-aligned transforms
          var cx = cand.x|0, cy = cand.y|0;
          cand.el.style.transform = 'translate3d('+cx+'px,'+cy+'px,0)';
          placed.push({ x1: cand.x, y1: cand.y, x2: cand.x + CHIP_W, y2: cand.y + CHIP_H });
          flatNowPositioned[cand.c.code] = true;
        }
      }
      // Off-screen only chips that WERE positioned last frame but aren't now
      var fpKeys = Object.keys(flatPrevPositioned);
      for (var fpi = 0; fpi < fpKeys.length; fpi++) {
        if (!flatNowPositioned[fpKeys[fpi]]) {
          var felOff = refs[fpKeys[fpi]];
          if (felOff) felOff.style.transform = 'translate3d(-9999px,-9999px,0)';
        }
      }
      flatPrevPositioned = flatNowPositioned;
    }

    // Expose so atlas_gl can trigger initial positioning after React commits refs
    window.__updateFlatDom = updateFlatDom;
    window.__resetFlatKey  = function() { lastFlatKey = ''; flatPrevPositioned = {}; };

    map.on("load", function() {
      setReady(true);
      // Force a render after load so updateFlatDom fires once all tiles are ready
      map.triggerRepaint();
      if (mapApiRef) {
        mapApiRef.current = {
          flyTo:   function(opts) { map.flyTo(opts); },
          zoomIn:  function() { map.zoomIn(); },
          zoomOut: function() { map.zoomOut(); },
          reset:   function() { map.flyTo({ center: [10, 20], zoom: 1.4, duration: 900 }); },
          getZoom: function() { return map.getZoom(); },
        };
      }
    });
    map.on("render", updateFlatDom);

    // Fade space chrome (moon/stars/satellites) as user zooms in — at ground level there's no sky
    map.on("zoom", function() {
      var z = map.getZoom();
      var mob = window.innerWidth < 640;
      // Mobile: fade much earlier since viewport is tight — full at ≤1.4, gone by 2.2
      // Desktop: full at ≤1.8, gone by 3.2
      var zMin = mob ? 1.4 : 1.8;
      var zMax = mob ? 2.2 : 3.2;
      var o = z <= zMin ? 1 : z >= zMax ? 0 : 1 - (z - zMin) / (zMax - zMin);
      setSpaceOpacity(o);
    });

    return function() {
      map.off("render", updateFlatDom);
      map.remove();
      mapRef.current     = null;
      overlayRef.current = null;
      setReady(false);
    };
  }, []); // eslint-disable-line

  // ── Resize MapLibre when returning to flat ─────────────────────────────────
  React.useEffect(function() {
    if (mapMode !== "flat") return;
    var map = mapRef.current;
    if (!map) return;
    var t = setTimeout(function() {
      try {
        map.resize();
        if (window.__resetFlatKey) window.__resetFlatKey(); // reset AFTER resize so next render uses correct dimensions
        map.triggerRepaint();
      } catch(e) {}
    }, 60);
    return function() { clearTimeout(t); };
  }, [mapMode]);

  // ── Base highlight via MapLibre paint expressions (flat + globe) ─────────
  // Previously used deck.gl but it doesn't project onto the sphere. MapLibre's
  // native circle layer with feature-state + match expression handles both.
  React.useEffect(function() {
    var m = mapRef.current;
    if (!m || !ready) return;
    try {
      // Enlarge + recolor dot for base country
      m.setPaintProperty('country-dots', 'circle-radius', [
        "interpolate",["linear"],["zoom"],
        0.5, ["case", ["==", ["get","ccy"], base], 5,   1.8],
        3,   ["case", ["==", ["get","ccy"], base], 6.5, 2.6],
        6,   ["case", ["==", ["get","ccy"], base], 8.5, 3.4]
      ]);
      m.setPaintProperty('country-dots', 'circle-color', [
        "case",
        ["==", ["get","ccy"], base], "#e2a23f",
        "#fde68a"
      ]);
      m.setPaintProperty('country-dots', 'circle-stroke-color', [
        "case",
        ["==", ["get","ccy"], base], "rgba(226,162,63,0.5)",
        "rgba(251,191,36,0.7)"
      ]);
      m.setPaintProperty('country-dots', 'circle-stroke-width', [
        "case",
        ["==", ["get","ccy"], base], 4,
        1.2
      ]);
      // Enlarge the glow halo for the base country too
      m.setPaintProperty('country-dots-glow', 'circle-radius', [
        "interpolate",["linear"],["zoom"],
        0.5, ["case", ["==", ["get","ccy"], base], 16, 7],
        3,   ["case", ["==", ["get","ccy"], base], 22, 10],
        6,   ["case", ["==", ["get","ccy"], base], 30, 14]
      ]);
      m.setPaintProperty('country-dots-glow', 'circle-opacity', [
        "case",
        ["==", ["get","ccy"], base], 0.35,
        0.18
      ]);
    } catch(e) {}
    // Clear any leftover deck.gl layers (no longer used)
    if (overlayRef.current) { try { overlayRef.current.setProps({ layers: [] }); } catch(e) {} }
  }, [base, ready, mapMode]);

  // ── Pulsing halo on base-currency dot ────────────────────────────────────
  // Soft "breathing" glow at 2.5s cadence. Draws the eye to the anchor
  // currency without being distracting. Amber, matches existing glow palette.
  React.useEffect(function() {
    var m = mapRef.current;
    if (!m || !ready) return;
    try {
      m.setFilter('base-pulse', ["==", ["get","ccy"], base]);
    } catch(e) { return; }
    var raf; var t0 = performance.now();
    var tick = function() {
      var mm = mapRef.current;
      if (!mm) return;
      var t = (performance.now() - t0) / 1000;
      // Sine wave period ≈ 2.5s. Radius breathes 18→36, opacity 0.12→0.35.
      var phase = 0.5 + 0.5 * Math.sin((t * Math.PI * 2) / 2.5);
      var zoom = mm.getZoom() || 1.4;
      // Scale pulse with zoom so it's visible at low zoom but not huge at high zoom
      var zoomScale = 0.8 + 0.6 * Math.min(1, Math.max(0, (zoom - 0.8) / 4));
      var r = (18 + 18 * phase) * zoomScale;
      var o = 0.12 + 0.23 * phase;
      try {
        mm.setPaintProperty('base-pulse', 'circle-radius', r);
        mm.setPaintProperty('base-pulse', 'circle-opacity', o);
      } catch(e) {}
      raf = requestAnimationFrame(tick);
    };
    raf = requestAnimationFrame(tick);
    return function() { if (raf) cancelAnimationFrame(raf); };
  }, [base, ready]);

  // ── MapLibre projection toggle (flat mercator ⇄ globe) ────────────────────
  // MapLibre v5 has native globe projection — same map instance, same style,
  // same vector tiles, same chip-position logic. Switching modes is just a
  // projection change. Atmosphere + stars are built in.
  React.useEffect(function() {
    var m = mapRef.current;
    if (!m || !ready) return;
    try {
      m.setProjection(
        mapMode === 'globe'
          ? { type: 'globe' }
          : { type: 'mercator' }
      );
      // Re-center + reset pitch on mode switch
      if (mapMode === 'globe') {
        m.easeTo({ center: [10, 20], zoom: 1.4, pitch: 0, bearing: 0, duration: 600 });
      }
    } catch(e) { console.warn('projection toggle failed:', e); }
  }, [mapMode, ready]);


  var bgColor = mapMode === "globe" ? "#000008" : "#0e1420";
  var isGlobeMode = mapMode === "globe";

  return (
    <div style={{ position:"absolute", inset:0, background: bgColor, overflow:"hidden" }}>
      {/* Space backdrop — only in globe mode. Layered stars + moon/sun + meteors. */}
      {isGlobeMode && (
        <div style={{ position:"absolute", inset:0, opacity: spaceOpacity, transition: "opacity 300ms ease-out", pointerEvents:"none" }}>
          <React.Fragment>
          <div className="atlas-starfield-a" style={{
            position:"absolute", inset:0, pointerEvents:"none",
            backgroundImage: [
              "radial-gradient(4.0px 4.0px at 13.6% 76.5%, rgba(255,248,220,0.96), transparent 62%)",
              "radial-gradient(4.5px 4.5px at 69.3% 58.8%, rgba(255,255,255,0.91), transparent 62%)",
              "radial-gradient(3.7px 3.7px at 38.6% 79.4%, rgba(235,240,255,0.99), transparent 62%)",
              "radial-gradient(3.8px 3.8px at 11.0% 6.1%, rgba(255,255,255,0.88), transparent 62%)",
              "radial-gradient(3.3px 3.3px at 76.1% 27.1%, rgba(255,255,255,0.96), transparent 62%)",
              "radial-gradient(3.8px 3.8px at 59.0% 5.3%, rgba(235,240,255,0.98), transparent 62%)",
              "radial-gradient(4.1px 4.1px at 74.6% 92.1%, rgba(255,255,255,0.89), transparent 62%)",
              "radial-gradient(3.2px 3.2px at 14.6% 51.6%, rgba(255,255,255,0.96), transparent 62%)",
              "radial-gradient(4.5px 4.5px at 17.4% 4.1%, rgba(255,255,255,0.93), transparent 62%)",
              "radial-gradient(4.3px 4.3px at 77.0% 33.7%, rgba(235,240,255,0.91), transparent 62%)",
              "radial-gradient(3.6px 3.6px at 93.0% 14.4%, rgba(215,225,255,0.95), transparent 62%)",
              "radial-gradient(4.3px 4.3px at 43.6% 36.7%, rgba(215,225,255,0.89), transparent 62%)",
              "radial-gradient(3.8px 3.8px at 62.7% 57.4%, rgba(255,248,220,0.99), transparent 62%)",
              "radial-gradient(3.7px 3.7px at 22.0% 16.0%, rgba(255,240,200,0.96), transparent 62%)",
              "radial-gradient(4.3px 4.3px at 9.2% 10.9%, rgba(255,240,200,0.89), transparent 62%)",
              "radial-gradient(3.5px 3.5px at 65.8% 59.3%, rgba(255,240,200,0.95), transparent 62%)",
              "radial-gradient(3.5px 3.5px at 69.8% 83.3%, rgba(215,225,255,0.99), transparent 62%)",
              "radial-gradient(4.0px 4.0px at 63.0% 61.9%, rgba(255,248,220,0.90), transparent 62%)",
              "radial-gradient(4.0px 4.0px at 50.2% 16.8%, rgba(215,225,255,1.00), transparent 62%)",
              "radial-gradient(3.4px 3.4px at 54.9% 15.8%, rgba(215,225,255,0.96), transparent 62%)",
              "radial-gradient(4.1px 4.1px at 7.6% 38.4%, rgba(255,255,255,0.94), transparent 62%)",
              "radial-gradient(4.5px 4.5px at 85.8% 10.1%, rgba(215,225,255,0.95), transparent 62%)",
              "radial-gradient(3.9px 3.9px at 43.5% 39.1%, rgba(235,240,255,0.92), transparent 62%)",
              "radial-gradient(4.2px 4.2px at 8.3% 43.2%, rgba(235,240,255,0.94), transparent 62%)",
              "radial-gradient(3.6px 3.6px at 54.3% 49.8%, rgba(235,240,255,0.91), transparent 62%)",
              "radial-gradient(4.4px 4.4px at 5.2% 21.4%, rgba(215,225,255,0.99), transparent 62%)",
              "radial-gradient(3.6px 3.6px at 74.5% 23.7%, rgba(255,248,220,0.91), transparent 62%)",
              "radial-gradient(4.6px 4.6px at 30.5% 29.5%, rgba(255,240,200,1.00), transparent 62%)",
              "radial-gradient(4.1px 4.1px at 62.6% 79.0%, rgba(255,240,200,1.00), transparent 62%)",
              "radial-gradient(4.0px 4.0px at 65.4% 40.5%, rgba(215,225,255,0.96), transparent 62%)",
              "radial-gradient(3.6px 3.6px at 51.1% 37.1%, rgba(255,255,255,0.97), transparent 62%)",
              "radial-gradient(3.9px 3.9px at 8.7% 41.3%, rgba(215,225,255,0.89), transparent 62%)",
              "radial-gradient(3.7px 3.7px at 59.4% 28.8%, rgba(255,248,220,0.91), transparent 62%)",
              "radial-gradient(3.3px 3.3px at 67.3% 61.5%, rgba(255,248,220,0.91), transparent 62%)",
              "radial-gradient(4.1px 4.1px at 7.9% 40.7%, rgba(235,240,255,0.93), transparent 62%)",
              "radial-gradient(4.0px 4.0px at 15.9% 63.9%, rgba(255,248,220,0.98), transparent 62%)",
              "radial-gradient(4.4px 4.4px at 57.4% 92.5%, rgba(255,255,255,0.95), transparent 62%)",
              "radial-gradient(4.2px 4.2px at 97.3% 83.8%, rgba(235,240,255,0.99), transparent 62%)",
              "radial-gradient(4.0px 4.0px at 59.2% 15.5%, rgba(235,240,255,0.99), transparent 62%)",
              "radial-gradient(4.0px 4.0px at 10.9% 66.6%, rgba(235,240,255,0.89), transparent 62%)",
              "radial-gradient(4.5px 4.5px at 26.1% 40.4%, rgba(235,240,255,0.99), transparent 62%)",
              "radial-gradient(3.3px 3.3px at 56.2% 51.1%, rgba(215,225,255,0.95), transparent 62%)",
              "radial-gradient(4.0px 4.0px at 63.4% 34.1%, rgba(255,248,220,0.90), transparent 62%)",
              "radial-gradient(3.7px 3.7px at 36.4% 97.9%, rgba(235,240,255,0.90), transparent 62%)",
              "radial-gradient(3.6px 3.6px at 29.3% 53.0%, rgba(255,255,255,0.95), transparent 62%)",
              "radial-gradient(3.2px 3.2px at 65.0% 64.6%, rgba(235,240,255,0.91), transparent 62%)",
              "radial-gradient(4.5px 4.5px at 33.7% 35.1%, rgba(255,240,200,0.94), transparent 62%)",
              "radial-gradient(4.0px 4.0px at 12.2% 49.3%, rgba(255,240,200,0.93), transparent 62%)",
              "radial-gradient(4.3px 4.3px at 75.8% 79.4%, rgba(255,248,220,0.92), transparent 62%)",
              "radial-gradient(4.1px 4.1px at 20.7% 47.2%, rgba(255,248,220,0.93), transparent 62%)",
              "radial-gradient(3.5px 3.5px at 76.7% 30.2%, rgba(215,225,255,0.91), transparent 62%)",
              "radial-gradient(3.8px 3.8px at 18.6% 39.6%, rgba(255,248,220,0.89), transparent 62%)",
              "radial-gradient(3.9px 3.9px at 44.7% 64.6%, rgba(255,248,220,0.96), transparent 62%)",
              "radial-gradient(3.4px 3.4px at 60.4% 67.0%, rgba(255,255,255,0.98), transparent 62%)",
              "radial-gradient(4.1px 4.1px at 35.6% 83.5%, rgba(255,240,200,0.99), transparent 62%)",
              "radial-gradient(3.8px 3.8px at 73.1% 33.7%, rgba(235,240,255,0.94), transparent 62%)",
              "radial-gradient(3.4px 3.4px at 7.8% 89.2%, rgba(255,240,200,1.00), transparent 62%)",
              "radial-gradient(4.2px 4.2px at 83.7% 95.1%, rgba(215,225,255,0.99), transparent 62%)",
              "radial-gradient(3.9px 3.9px at 32.2% 8.4%, rgba(255,248,220,0.90), transparent 62%)",
              "radial-gradient(4.1px 4.1px at 39.6% 97.4%, rgba(235,240,255,0.92), transparent 62%)",
              "radial-gradient(3.4px 3.4px at 55.4% 94.3%, rgba(235,240,255,0.96), transparent 62%)",
              "radial-gradient(3.5px 3.5px at 58.3% 52.6%, rgba(255,255,255,0.93), transparent 62%)",
              "radial-gradient(4.5px 4.5px at 11.4% 78.5%, rgba(255,248,220,0.94), transparent 62%)",
              "radial-gradient(3.5px 3.5px at 47.9% 70.1%, rgba(255,248,220,0.90), transparent 62%)",
              "radial-gradient(3.9px 3.9px at 32.2% 70.5%, rgba(255,248,220,0.95), transparent 62%)",
              "radial-gradient(3.2px 3.2px at 3.3% 21.4%, rgba(255,248,220,0.89), transparent 62%)",
              "radial-gradient(4.2px 4.2px at 26.2% 74.3%, rgba(235,240,255,0.90), transparent 62%)",
              "radial-gradient(3.9px 3.9px at 78.5% 44.8%, rgba(255,240,200,0.97), transparent 62%)",
              "radial-gradient(4.0px 4.0px at 47.5% 98.4%, rgba(255,248,220,0.89), transparent 62%)",
              "radial-gradient(3.4px 3.4px at 27.2% 14.1%, rgba(255,240,200,0.95), transparent 62%)"
            ].join(","),
            animation: "atlas-twinkle-a 4s ease-in-out infinite",
          }}/>
          {/* Hero stars — brightest accents */}
          <div className="atlas-starfield-hero" style={{
            position:"absolute", inset:0, pointerEvents:"none",
            filter:"drop-shadow(0 0 2px rgba(255,255,255,0.6))",
            backgroundImage: [
              "radial-gradient(5.2px 5.2px at 35.3% 89.7%, rgba(235,240,255,0.96), transparent 62%)",
              "radial-gradient(5.5px 5.5px at 62.1% 72.4%, rgba(255,248,220,0.96), transparent 62%)",
              "radial-gradient(6.2px 6.2px at 96.1% 1.9%, rgba(235,240,255,0.96), transparent 62%)",
              "radial-gradient(5.8px 5.8px at 77.1% 73.5%, rgba(255,240,200,0.98), transparent 62%)",
              "radial-gradient(5.9px 5.9px at 37.6% 45.8%, rgba(255,248,220,0.97), transparent 62%)",
              "radial-gradient(6.1px 6.1px at 47.4% 89.9%, rgba(215,225,255,0.96), transparent 62%)",
              "radial-gradient(6.0px 6.0px at 25.2% 39.9%, rgba(255,240,200,0.96), transparent 62%)",
              "radial-gradient(6.5px 6.5px at 84.1% 33.3%, rgba(235,240,255,0.99), transparent 62%)",
              "radial-gradient(6.5px 6.5px at 39.8% 75.4%, rgba(255,240,200,0.99), transparent 62%)",
              "radial-gradient(6.3px 6.3px at 17.3% 46.2%, rgba(235,240,255,0.99), transparent 62%)",
              "radial-gradient(5.6px 5.6px at 58.5% 6.5%, rgba(215,225,255,0.97), transparent 62%)",
              "radial-gradient(5.6px 5.6px at 42.3% 28.9%, rgba(215,225,255,1.00), transparent 62%)"
            ].join(","),
            animation: "atlas-twinkle-a 4.8s ease-in-out infinite 0.3s",
          }}/>
          {/* Starfield layer B — medium stars */}
          <div className="atlas-starfield-b" style={{
            position:"absolute", inset:0, pointerEvents:"none",
            backgroundImage: [
              "radial-gradient(2.2px 2.2px at 12.9% 96.3%, rgba(255,248,220,0.89), transparent 62%)",
              "radial-gradient(2.3px 2.3px at 29.6% 48.7%, rgba(255,255,255,0.84), transparent 62%)",
              "radial-gradient(2.6px 2.6px at 19.9% 66.9%, rgba(255,248,220,0.93), transparent 62%)",
              "radial-gradient(2.8px 2.8px at 50.4% 11.7%, rgba(255,255,255,0.86), transparent 62%)",
              "radial-gradient(2.4px 2.4px at 77.1% 10.0%, rgba(255,240,200,0.88), transparent 62%)",
              "radial-gradient(2.7px 2.7px at 10.0% 88.5%, rgba(215,225,255,0.92), transparent 62%)",
              "radial-gradient(2.3px 2.3px at 15.9% 55.9%, rgba(255,255,255,0.99), transparent 62%)",
              "radial-gradient(2.9px 2.9px at 30.4% 36.6%, rgba(255,240,200,0.96), transparent 62%)",
              "radial-gradient(2.2px 2.2px at 78.9% 50.2%, rgba(255,240,200,0.79), transparent 62%)",
              "radial-gradient(2.8px 2.8px at 54.3% 94.0%, rgba(215,225,255,0.81), transparent 62%)",
              "radial-gradient(2.5px 2.5px at 3.6% 94.3%, rgba(235,240,255,0.86), transparent 62%)",
              "radial-gradient(2.7px 2.7px at 91.9% 98.2%, rgba(255,248,220,0.91), transparent 62%)",
              "radial-gradient(2.4px 2.4px at 39.7% 81.2%, rgba(235,240,255,0.97), transparent 62%)",
              "radial-gradient(2.7px 2.7px at 87.7% 62.5%, rgba(255,240,200,0.95), transparent 62%)",
              "radial-gradient(2.6px 2.6px at 87.0% 74.0%, rgba(235,240,255,0.80), transparent 62%)",
              "radial-gradient(2.4px 2.4px at 61.0% 90.4%, rgba(255,248,220,1.00), transparent 62%)",
              "radial-gradient(2.7px 2.7px at 73.1% 96.4%, rgba(255,240,200,0.84), transparent 62%)",
              "radial-gradient(2.2px 2.2px at 4.6% 23.4%, rgba(235,240,255,0.82), transparent 62%)",
              "radial-gradient(2.2px 2.2px at 65.8% 92.3%, rgba(255,248,220,0.92), transparent 62%)",
              "radial-gradient(2.2px 2.2px at 43.7% 2.8%, rgba(255,240,200,0.91), transparent 62%)",
              "radial-gradient(2.3px 2.3px at 36.5% 72.7%, rgba(255,248,220,0.89), transparent 62%)",
              "radial-gradient(2.4px 2.4px at 56.7% 30.4%, rgba(255,248,220,0.92), transparent 62%)",
              "radial-gradient(2.4px 2.4px at 3.3% 86.7%, rgba(235,240,255,0.93), transparent 62%)",
              "radial-gradient(2.5px 2.5px at 5.3% 8.2%, rgba(255,255,255,0.80), transparent 62%)",
              "radial-gradient(2.6px 2.6px at 28.5% 18.4%, rgba(235,240,255,0.87), transparent 62%)",
              "radial-gradient(2.5px 2.5px at 22.7% 95.8%, rgba(235,240,255,0.93), transparent 62%)",
              "radial-gradient(2.6px 2.6px at 86.5% 87.3%, rgba(255,255,255,0.91), transparent 62%)",
              "radial-gradient(2.6px 2.6px at 56.9% 62.1%, rgba(235,240,255,0.80), transparent 62%)",
              "radial-gradient(2.8px 2.8px at 99.4% 92.7%, rgba(255,240,200,0.86), transparent 62%)",
              "radial-gradient(2.3px 2.3px at 39.0% 10.2%, rgba(235,240,255,0.94), transparent 62%)",
              "radial-gradient(2.9px 2.9px at 87.8% 99.3%, rgba(215,225,255,0.99), transparent 62%)",
              "radial-gradient(2.0px 2.0px at 3.9% 73.7%, rgba(255,255,255,0.87), transparent 62%)",
              "radial-gradient(2.2px 2.2px at 67.6% 53.8%, rgba(255,248,220,0.94), transparent 62%)",
              "radial-gradient(2.6px 2.6px at 37.3% 92.6%, rgba(255,255,255,0.94), transparent 62%)",
              "radial-gradient(2.2px 2.2px at 99.4% 18.0%, rgba(255,240,200,0.96), transparent 62%)",
              "radial-gradient(2.3px 2.3px at 72.0% 51.5%, rgba(255,240,200,0.85), transparent 62%)",
              "radial-gradient(2.3px 2.3px at 43.6% 63.3%, rgba(255,255,255,0.88), transparent 62%)",
              "radial-gradient(2.7px 2.7px at 73.9% 3.7%, rgba(215,225,255,0.81), transparent 62%)",
              "radial-gradient(2.4px 2.4px at 82.9% 72.8%, rgba(255,255,255,0.85), transparent 62%)",
              "radial-gradient(2.2px 2.2px at 56.3% 65.9%, rgba(255,240,200,0.91), transparent 62%)",
              "radial-gradient(2.9px 2.9px at 84.6% 80.4%, rgba(215,225,255,0.97), transparent 62%)",
              "radial-gradient(2.9px 2.9px at 83.8% 24.3%, rgba(255,240,200,0.86), transparent 62%)",
              "radial-gradient(2.5px 2.5px at 40.8% 63.8%, rgba(235,240,255,0.97), transparent 62%)",
              "radial-gradient(2.7px 2.7px at 24.6% 31.0%, rgba(215,225,255,0.78), transparent 62%)",
              "radial-gradient(2.2px 2.2px at 69.7% 27.7%, rgba(255,240,200,0.84), transparent 62%)",
              "radial-gradient(2.2px 2.2px at 97.8% 98.2%, rgba(255,255,255,0.87), transparent 62%)",
              "radial-gradient(2.0px 2.0px at 18.5% 19.3%, rgba(255,240,200,0.98), transparent 62%)",
              "radial-gradient(2.1px 2.1px at 83.6% 73.2%, rgba(255,248,220,0.96), transparent 62%)",
              "radial-gradient(2.6px 2.6px at 65.2% 68.5%, rgba(235,240,255,0.85), transparent 62%)",
              "radial-gradient(2.4px 2.4px at 14.6% 74.8%, rgba(235,240,255,0.84), transparent 62%)",
              "radial-gradient(2.5px 2.5px at 48.1% 58.6%, rgba(255,240,200,0.80), transparent 62%)",
              "radial-gradient(2.6px 2.6px at 14.1% 9.7%, rgba(255,255,255,0.90), transparent 62%)",
              "radial-gradient(2.0px 2.0px at 12.5% 23.4%, rgba(255,248,220,0.82), transparent 62%)",
              "radial-gradient(2.6px 2.6px at 97.4% 14.0%, rgba(255,248,220,0.83), transparent 62%)",
              "radial-gradient(2.6px 2.6px at 85.6% 2.5%, rgba(255,255,255,0.89), transparent 62%)",
              "radial-gradient(2.7px 2.7px at 63.0% 13.0%, rgba(235,240,255,1.00), transparent 62%)",
              "radial-gradient(2.5px 2.5px at 94.7% 55.9%, rgba(235,240,255,0.85), transparent 62%)",
              "radial-gradient(2.6px 2.6px at 57.8% 48.5%, rgba(255,240,200,0.89), transparent 62%)",
              "radial-gradient(2.6px 2.6px at 64.1% 26.7%, rgba(235,240,255,0.95), transparent 62%)",
              "radial-gradient(2.1px 2.1px at 3.5% 45.8%, rgba(255,255,255,0.83), transparent 62%)",
              "radial-gradient(2.1px 2.1px at 85.0% 18.4%, rgba(215,225,255,0.95), transparent 62%)",
              "radial-gradient(2.2px 2.2px at 65.5% 28.2%, rgba(235,240,255,0.81), transparent 62%)",
              "radial-gradient(2.2px 2.2px at 51.1% 75.2%, rgba(255,255,255,0.82), transparent 62%)",
              "radial-gradient(2.3px 2.3px at 29.3% 59.4%, rgba(215,225,255,0.79), transparent 62%)",
              "radial-gradient(2.4px 2.4px at 2.6% 99.2%, rgba(255,240,200,0.99), transparent 62%)",
              "radial-gradient(2.5px 2.5px at 20.1% 60.9%, rgba(255,248,220,0.96), transparent 62%)",
              "radial-gradient(2.5px 2.5px at 20.5% 61.7%, rgba(255,240,200,0.98), transparent 62%)",
              "radial-gradient(2.1px 2.1px at 70.2% 32.0%, rgba(235,240,255,0.81), transparent 62%)",
              "radial-gradient(2.2px 2.2px at 29.8% 75.1%, rgba(215,225,255,0.86), transparent 62%)",
              "radial-gradient(2.1px 2.1px at 43.6% 92.4%, rgba(215,225,255,0.96), transparent 62%)",
              "radial-gradient(2.6px 2.6px at 95.1% 99.0%, rgba(255,240,200,0.79), transparent 62%)",
              "radial-gradient(2.0px 2.0px at 91.7% 7.7%, rgba(255,255,255,0.90), transparent 62%)",
              "radial-gradient(2.3px 2.3px at 26.6% 2.9%, rgba(255,255,255,0.96), transparent 62%)",
              "radial-gradient(2.8px 2.8px at 14.2% 34.9%, rgba(215,225,255,0.85), transparent 62%)",
              "radial-gradient(2.5px 2.5px at 89.4% 91.1%, rgba(255,240,200,0.84), transparent 62%)",
              "radial-gradient(2.0px 2.0px at 6.3% 63.9%, rgba(255,255,255,0.90), transparent 62%)",
              "radial-gradient(2.2px 2.2px at 87.1% 66.9%, rgba(215,225,255,0.78), transparent 62%)",
              "radial-gradient(2.9px 2.9px at 61.2% 67.5%, rgba(255,240,200,0.91), transparent 62%)",
              "radial-gradient(2.3px 2.3px at 15.8% 72.3%, rgba(255,248,220,0.98), transparent 62%)",
              "radial-gradient(2.2px 2.2px at 39.7% 97.8%, rgba(255,255,255,0.91), transparent 62%)",
              "radial-gradient(2.8px 2.8px at 80.0% 67.9%, rgba(235,240,255,0.83), transparent 62%)",
              "radial-gradient(2.5px 2.5px at 6.1% 60.9%, rgba(255,248,220,0.91), transparent 62%)",
              "radial-gradient(2.3px 2.3px at 81.5% 37.4%, rgba(215,225,255,0.98), transparent 62%)",
              "radial-gradient(2.0px 2.0px at 8.9% 71.5%, rgba(255,248,220,0.98), transparent 62%)",
              "radial-gradient(2.7px 2.7px at 3.0% 13.6%, rgba(255,240,200,0.90), transparent 62%)",
              "radial-gradient(2.1px 2.1px at 80.3% 20.2%, rgba(215,225,255,0.93), transparent 62%)",
              "radial-gradient(2.0px 2.0px at 24.3% 91.1%, rgba(215,225,255,0.92), transparent 62%)",
              "radial-gradient(2.2px 2.2px at 28.4% 4.6%, rgba(215,225,255,0.93), transparent 62%)",
              "radial-gradient(2.1px 2.1px at 96.3% 80.9%, rgba(255,248,220,0.81), transparent 62%)",
              "radial-gradient(2.2px 2.2px at 55.4% 41.8%, rgba(215,225,255,0.91), transparent 62%)",
              "radial-gradient(2.7px 2.7px at 62.9% 56.2%, rgba(255,255,255,0.89), transparent 62%)",
              "radial-gradient(2.5px 2.5px at 55.9% 53.8%, rgba(215,225,255,0.94), transparent 62%)",
              "radial-gradient(2.4px 2.4px at 70.0% 33.0%, rgba(255,240,200,0.82), transparent 62%)",
              "radial-gradient(2.2px 2.2px at 92.5% 14.0%, rgba(215,225,255,0.96), transparent 62%)",
              "radial-gradient(2.0px 2.0px at 40.1% 39.9%, rgba(255,240,200,0.84), transparent 62%)"
            ].join(","),
            animation: "atlas-twinkle-b 3.2s ease-in-out infinite 1.5s",
          }}/>
          {/* Starfield layer C — distant tiny stars */}
          <div className="atlas-starfield-c" style={{
            position:"absolute", inset:0, pointerEvents:"none", opacity:0.92,
            backgroundImage: [
              "radial-gradient(1.3px 1.3px at 93.2% 80.4%, rgba(255,255,255,0.85), transparent 62%)",
              "radial-gradient(1.4px 1.4px at 65.6% 31.9%, rgba(255,255,255,0.75), transparent 62%)",
              "radial-gradient(1.6px 1.6px at 58.2% 49.5%, rgba(255,255,255,0.85), transparent 62%)",
              "radial-gradient(1.5px 1.5px at 93.3% 1.6%, rgba(255,255,255,0.87), transparent 62%)",
              "radial-gradient(1.4px 1.4px at 39.3% 72.8%, rgba(255,255,255,0.99), transparent 62%)",
              "radial-gradient(1.4px 1.4px at 29.9% 74.9%, rgba(255,255,255,0.71), transparent 62%)",
              "radial-gradient(1.6px 1.6px at 53.2% 71.2%, rgba(245,248,255,1.00), transparent 62%)",
              "radial-gradient(1.4px 1.4px at 40.3% 24.4%, rgba(245,248,255,0.98), transparent 62%)",
              "radial-gradient(1.2px 1.2px at 14.2% 6.0%, rgba(245,248,255,0.96), transparent 62%)",
              "radial-gradient(1.7px 1.7px at 46.2% 93.2%, rgba(255,255,255,0.99), transparent 62%)",
              "radial-gradient(1.5px 1.5px at 52.1% 37.3%, rgba(245,248,255,0.92), transparent 62%)",
              "radial-gradient(1.5px 1.5px at 63.7% 91.0%, rgba(245,248,255,0.97), transparent 62%)",
              "radial-gradient(1.7px 1.7px at 15.1% 64.2%, rgba(255,255,255,0.87), transparent 62%)",
              "radial-gradient(1.6px 1.6px at 79.3% 35.0%, rgba(245,248,255,0.90), transparent 62%)",
              "radial-gradient(1.5px 1.5px at 5.9% 96.1%, rgba(255,255,255,0.73), transparent 62%)",
              "radial-gradient(1.1px 1.1px at 18.5% 60.0%, rgba(245,248,255,0.93), transparent 62%)",
              "radial-gradient(1.6px 1.6px at 38.6% 40.1%, rgba(245,248,255,0.78), transparent 62%)",
              "radial-gradient(1.4px 1.4px at 87.7% 97.7%, rgba(255,255,255,0.72), transparent 62%)",
              "radial-gradient(1.8px 1.8px at 98.6% 51.5%, rgba(255,255,255,0.85), transparent 62%)",
              "radial-gradient(1.2px 1.2px at 69.2% 23.1%, rgba(255,255,255,0.78), transparent 62%)",
              "radial-gradient(1.5px 1.5px at 56.5% 75.4%, rgba(255,255,255,0.80), transparent 62%)",
              "radial-gradient(1.3px 1.3px at 25.7% 36.0%, rgba(255,255,255,0.78), transparent 62%)",
              "radial-gradient(1.6px 1.6px at 48.6% 76.0%, rgba(255,255,255,0.86), transparent 62%)",
              "radial-gradient(1.7px 1.7px at 93.8% 5.0%, rgba(245,248,255,0.73), transparent 62%)",
              "radial-gradient(1.6px 1.6px at 87.5% 91.4%, rgba(245,248,255,0.86), transparent 62%)",
              "radial-gradient(1.4px 1.4px at 53.4% 43.5%, rgba(245,248,255,0.83), transparent 62%)",
              "radial-gradient(1.4px 1.4px at 76.8% 16.1%, rgba(245,248,255,0.93), transparent 62%)",
              "radial-gradient(1.2px 1.2px at 79.2% 77.9%, rgba(255,255,255,0.82), transparent 62%)",
              "radial-gradient(1.2px 1.2px at 5.9% 53.4%, rgba(245,248,255,0.89), transparent 62%)",
              "radial-gradient(1.5px 1.5px at 17.0% 88.1%, rgba(245,248,255,0.95), transparent 62%)",
              "radial-gradient(1.6px 1.6px at 0.9% 84.7%, rgba(245,248,255,0.78), transparent 62%)",
              "radial-gradient(1.4px 1.4px at 68.3% 58.4%, rgba(255,255,255,0.72), transparent 62%)",
              "radial-gradient(1.8px 1.8px at 89.3% 63.0%, rgba(245,248,255,0.98), transparent 62%)",
              "radial-gradient(1.6px 1.6px at 96.3% 36.2%, rgba(245,248,255,0.82), transparent 62%)",
              "radial-gradient(1.7px 1.7px at 62.6% 98.3%, rgba(245,248,255,0.81), transparent 62%)",
              "radial-gradient(1.6px 1.6px at 79.4% 18.7%, rgba(245,248,255,0.87), transparent 62%)",
              "radial-gradient(1.2px 1.2px at 99.0% 2.9%, rgba(245,248,255,0.76), transparent 62%)",
              "radial-gradient(1.7px 1.7px at 56.8% 93.4%, rgba(255,255,255,0.86), transparent 62%)",
              "radial-gradient(1.6px 1.6px at 26.2% 35.1%, rgba(255,255,255,0.87), transparent 62%)",
              "radial-gradient(1.6px 1.6px at 89.1% 43.9%, rgba(245,248,255,1.00), transparent 62%)",
              "radial-gradient(1.1px 1.1px at 91.2% 78.1%, rgba(255,255,255,0.97), transparent 62%)",
              "radial-gradient(1.3px 1.3px at 44.4% 23.8%, rgba(245,248,255,0.83), transparent 62%)",
              "radial-gradient(1.7px 1.7px at 0.1% 79.4%, rgba(245,248,255,0.72), transparent 62%)",
              "radial-gradient(1.5px 1.5px at 61.8% 4.2%, rgba(245,248,255,0.75), transparent 62%)",
              "radial-gradient(1.2px 1.2px at 90.7% 68.0%, rgba(255,255,255,0.73), transparent 62%)",
              "radial-gradient(1.6px 1.6px at 58.8% 51.4%, rgba(255,255,255,0.90), transparent 62%)",
              "radial-gradient(1.4px 1.4px at 54.1% 5.6%, rgba(255,255,255,0.86), transparent 62%)",
              "radial-gradient(1.6px 1.6px at 37.3% 50.4%, rgba(255,255,255,0.74), transparent 62%)",
              "radial-gradient(1.3px 1.3px at 98.6% 32.1%, rgba(255,255,255,1.00), transparent 62%)",
              "radial-gradient(1.2px 1.2px at 50.6% 59.2%, rgba(255,255,255,0.76), transparent 62%)",
              "radial-gradient(1.4px 1.4px at 69.5% 67.1%, rgba(245,248,255,0.85), transparent 62%)",
              "radial-gradient(1.5px 1.5px at 82.4% 53.6%, rgba(245,248,255,0.87), transparent 62%)",
              "radial-gradient(1.2px 1.2px at 82.8% 82.3%, rgba(245,248,255,0.83), transparent 62%)",
              "radial-gradient(1.2px 1.2px at 64.6% 63.7%, rgba(255,255,255,0.73), transparent 62%)",
              "radial-gradient(1.7px 1.7px at 92.4% 63.7%, rgba(255,255,255,0.92), transparent 62%)",
              "radial-gradient(1.4px 1.4px at 36.5% 24.0%, rgba(255,255,255,0.87), transparent 62%)",
              "radial-gradient(1.4px 1.4px at 18.4% 23.2%, rgba(245,248,255,0.75), transparent 62%)",
              "radial-gradient(1.7px 1.7px at 56.9% 96.1%, rgba(255,255,255,0.93), transparent 62%)",
              "radial-gradient(1.2px 1.2px at 17.5% 48.9%, rgba(255,255,255,0.74), transparent 62%)",
              "radial-gradient(1.5px 1.5px at 43.5% 32.4%, rgba(255,255,255,0.76), transparent 62%)",
              "radial-gradient(1.3px 1.3px at 42.2% 48.8%, rgba(255,255,255,0.99), transparent 62%)",
              "radial-gradient(1.6px 1.6px at 47.3% 13.1%, rgba(245,248,255,0.72), transparent 62%)",
              "radial-gradient(1.2px 1.2px at 7.4% 7.0%, rgba(255,255,255,0.96), transparent 62%)",
              "radial-gradient(1.8px 1.8px at 72.1% 82.1%, rgba(255,255,255,0.96), transparent 62%)",
              "radial-gradient(1.7px 1.7px at 32.8% 58.2%, rgba(255,255,255,0.70), transparent 62%)",
              "radial-gradient(1.2px 1.2px at 0.5% 23.5%, rgba(255,255,255,0.74), transparent 62%)",
              "radial-gradient(1.4px 1.4px at 5.2% 60.8%, rgba(255,255,255,0.81), transparent 62%)",
              "radial-gradient(1.5px 1.5px at 61.3% 30.8%, rgba(255,255,255,0.76), transparent 62%)",
              "radial-gradient(1.3px 1.3px at 43.1% 4.5%, rgba(255,255,255,0.91), transparent 62%)",
              "radial-gradient(1.8px 1.8px at 87.6% 91.2%, rgba(245,248,255,0.85), transparent 62%)",
              "radial-gradient(1.7px 1.7px at 66.1% 65.0%, rgba(245,248,255,0.93), transparent 62%)",
              "radial-gradient(1.3px 1.3px at 75.0% 92.2%, rgba(255,255,255,0.82), transparent 62%)",
              "radial-gradient(1.3px 1.3px at 7.9% 58.0%, rgba(245,248,255,0.95), transparent 62%)",
              "radial-gradient(1.2px 1.2px at 15.5% 85.3%, rgba(245,248,255,0.98), transparent 62%)",
              "radial-gradient(1.5px 1.5px at 68.9% 98.2%, rgba(255,255,255,0.77), transparent 62%)",
              "radial-gradient(1.3px 1.3px at 44.3% 88.0%, rgba(255,255,255,0.94), transparent 62%)",
              "radial-gradient(1.7px 1.7px at 19.1% 55.7%, rgba(245,248,255,0.75), transparent 62%)",
              "radial-gradient(1.1px 1.1px at 44.8% 99.7%, rgba(255,255,255,0.93), transparent 62%)",
              "radial-gradient(1.5px 1.5px at 16.2% 74.1%, rgba(245,248,255,0.77), transparent 62%)",
              "radial-gradient(1.7px 1.7px at 58.7% 99.6%, rgba(245,248,255,0.93), transparent 62%)",
              "radial-gradient(1.4px 1.4px at 43.9% 5.3%, rgba(255,255,255,0.81), transparent 62%)",
              "radial-gradient(1.7px 1.7px at 18.0% 40.0%, rgba(245,248,255,0.82), transparent 62%)",
              "radial-gradient(1.2px 1.2px at 48.9% 33.1%, rgba(255,255,255,0.88), transparent 62%)",
              "radial-gradient(1.8px 1.8px at 43.4% 64.1%, rgba(245,248,255,0.85), transparent 62%)",
              "radial-gradient(1.3px 1.3px at 57.5% 97.9%, rgba(245,248,255,0.99), transparent 62%)",
              "radial-gradient(1.3px 1.3px at 18.4% 40.2%, rgba(245,248,255,0.97), transparent 62%)",
              "radial-gradient(1.6px 1.6px at 41.0% 23.0%, rgba(245,248,255,0.96), transparent 62%)",
              "radial-gradient(1.4px 1.4px at 0.9% 63.3%, rgba(245,248,255,0.99), transparent 62%)",
              "radial-gradient(1.7px 1.7px at 93.5% 94.9%, rgba(245,248,255,0.97), transparent 62%)",
              "radial-gradient(1.2px 1.2px at 41.6% 79.3%, rgba(255,255,255,0.94), transparent 62%)",
              "radial-gradient(1.3px 1.3px at 97.4% 56.1%, rgba(245,248,255,0.71), transparent 62%)",
              "radial-gradient(1.2px 1.2px at 7.8% 91.1%, rgba(245,248,255,0.72), transparent 62%)",
              "radial-gradient(1.7px 1.7px at 7.9% 76.2%, rgba(245,248,255,0.77), transparent 62%)",
              "radial-gradient(1.1px 1.1px at 78.7% 90.7%, rgba(255,255,255,0.96), transparent 62%)",
              "radial-gradient(1.7px 1.7px at 89.7% 87.3%, rgba(255,255,255,0.81), transparent 62%)",
              "radial-gradient(1.3px 1.3px at 15.3% 49.4%, rgba(245,248,255,0.83), transparent 62%)",
              "radial-gradient(1.4px 1.4px at 55.5% 39.9%, rgba(245,248,255,0.80), transparent 62%)",
              "radial-gradient(1.5px 1.5px at 44.9% 64.6%, rgba(245,248,255,0.73), transparent 62%)",
              "radial-gradient(1.1px 1.1px at 99.5% 81.5%, rgba(255,255,255,0.99), transparent 62%)",
              "radial-gradient(1.2px 1.2px at 51.0% 32.5%, rgba(255,255,255,0.76), transparent 62%)",
              "radial-gradient(1.4px 1.4px at 32.3% 65.7%, rgba(255,255,255,0.76), transparent 62%)",
              "radial-gradient(1.3px 1.3px at 20.0% 14.4%, rgba(245,248,255,0.89), transparent 62%)",
              "radial-gradient(1.6px 1.6px at 78.9% 4.4%, rgba(245,248,255,0.95), transparent 62%)",
              "radial-gradient(1.5px 1.5px at 76.2% 35.7%, rgba(245,248,255,0.91), transparent 62%)",
              "radial-gradient(1.4px 1.4px at 85.4% 24.4%, rgba(255,255,255,0.89), transparent 62%)",
              "radial-gradient(1.4px 1.4px at 42.1% 32.1%, rgba(245,248,255,0.99), transparent 62%)",
              "radial-gradient(1.5px 1.5px at 91.1% 50.0%, rgba(255,255,255,0.93), transparent 62%)",
              "radial-gradient(1.4px 1.4px at 47.2% 54.9%, rgba(245,248,255,0.72), transparent 62%)",
              "radial-gradient(1.7px 1.7px at 92.3% 56.9%, rgba(255,255,255,0.98), transparent 62%)",
              "radial-gradient(1.4px 1.4px at 64.2% 70.0%, rgba(255,255,255,0.93), transparent 62%)",
              "radial-gradient(1.5px 1.5px at 32.8% 0.6%, rgba(245,248,255,0.86), transparent 62%)",
              "radial-gradient(1.3px 1.3px at 81.8% 76.3%, rgba(245,248,255,0.94), transparent 62%)",
              "radial-gradient(1.3px 1.3px at 29.5% 67.9%, rgba(255,255,255,0.77), transparent 62%)",
              "radial-gradient(1.2px 1.2px at 43.2% 7.9%, rgba(245,248,255,0.78), transparent 62%)",
              "radial-gradient(1.3px 1.3px at 37.9% 59.7%, rgba(255,255,255,0.85), transparent 62%)",
              "radial-gradient(1.1px 1.1px at 37.0% 57.3%, rgba(245,248,255,0.86), transparent 62%)",
              "radial-gradient(1.8px 1.8px at 19.6% 26.9%, rgba(255,255,255,0.92), transparent 62%)",
              "radial-gradient(1.4px 1.4px at 55.4% 90.7%, rgba(255,255,255,0.79), transparent 62%)",
              "radial-gradient(1.2px 1.2px at 47.4% 32.7%, rgba(255,255,255,0.96), transparent 62%)",
              "radial-gradient(1.5px 1.5px at 71.6% 1.5%, rgba(255,255,255,0.82), transparent 62%)",
              "radial-gradient(1.7px 1.7px at 96.2% 52.8%, rgba(255,255,255,0.86), transparent 62%)",
              "radial-gradient(1.1px 1.1px at 51.5% 57.2%, rgba(245,248,255,0.94), transparent 62%)",
              "radial-gradient(1.4px 1.4px at 18.3% 35.1%, rgba(245,248,255,0.73), transparent 62%)",
              "radial-gradient(1.6px 1.6px at 21.5% 97.9%, rgba(245,248,255,0.96), transparent 62%)",
              "radial-gradient(1.8px 1.8px at 0.9% 10.2%, rgba(245,248,255,0.77), transparent 62%)",
              "radial-gradient(1.7px 1.7px at 35.0% 27.3%, rgba(255,255,255,0.94), transparent 62%)",
              "radial-gradient(1.6px 1.6px at 10.0% 92.2%, rgba(245,248,255,0.93), transparent 62%)",
              "radial-gradient(1.8px 1.8px at 33.8% 14.3%, rgba(255,255,255,0.85), transparent 62%)",
              "radial-gradient(1.5px 1.5px at 23.6% 53.6%, rgba(245,248,255,0.99), transparent 62%)",
              "radial-gradient(1.2px 1.2px at 31.9% 5.9%, rgba(255,255,255,0.96), transparent 62%)"
            ].join(","),
            animation: "atlas-twinkle-c 5.4s ease-in-out infinite 0.7s",
          }}/>
          {/* Moon — top-right */}
          <div style={{
            position:"absolute", top:"5%", right:"5%", width:140, height:140,
            pointerEvents:"none", zIndex:1,
          }}>
            {/* Outer glow halo — multi-layer for real luminescence */}
            <div style={{
              position:"absolute", inset:-90,
              background: "radial-gradient(circle at 50% 50%, rgba(240,245,255,0.28) 0%, rgba(220,230,250,0.18) 22%, rgba(200,215,235,0.08) 48%, transparent 75%)",
              filter: "blur(6px)",
              pointerEvents:"none",
            }}/>
            <div style={{
              position:"absolute", inset:-40,
              background: "radial-gradient(circle at 50% 50%, rgba(255,255,255,0.35) 0%, rgba(240,245,255,0.18) 38%, transparent 70%)",
              filter: "blur(3px)",
              pointerEvents:"none",
            }}/>
            {/* Pulsing inner corona — gentle breathing */}
            <div className="atlas-moon-pulse" style={{
              position:"absolute", inset:-18,
              background: "radial-gradient(circle at 50% 50%, rgba(255,255,255,0.20), transparent 65%)",
              pointerEvents:"none",
              animation: "atlas-moon-pulse 5s ease-in-out infinite",
            }}/>
            <img src="assets/moon.jpg"
              alt="Moon"
              draggable={false}
              style={{
                position:"absolute", inset:0, width:"100%", height:"100%",
                objectFit:"contain",
                // mix-blend "lighten" kills the photo's pure-black padding so it fuses with the space backdrop
                mixBlendMode:"lighten",
                userSelect:"none", WebkitUserDrag:"none",
              }}/>
          </div>
          <style>{`
            @keyframes atlas-twinkle-a {
              0%, 100% { opacity: 1; }
              50%      { opacity: 0.78; }
            }
            @keyframes atlas-twinkle-c {
              0%, 100% { opacity: 0.92; }
              50%      { opacity: 0.55; }
            }
            @keyframes atlas-twinkle-b {
              0%, 100% { opacity: 0.72; }
              50%      { opacity: 1; }
            }
            @keyframes atlas-moon-pulse {
              0%, 100% { opacity: 0.7; transform: scale(1); }
              50%      { opacity: 1;   transform: scale(1.08); }
            }
            @keyframes atlas-sun-rays {
              from { transform: rotate(0deg); }
              to   { transform: rotate(360deg); }
            }
          `}</style>
          </React.Fragment>
        </div>
      )}
      <div ref={containerRef} style={{ position:"absolute", inset:0 }} />
    </div>
  );
}

function buildCountryLabelsGeoJSON() {
  var alwaysSet = window.__chipAlwaysSet || new Set();
  var midSet    = window.__chipMidSet    || new Set();
  var feats = (window.COUNTRIES || []).map(function(c) {
    // tier 1: majors (always shown), tier 2: mid (shown at zoom ≤3.5),
    // tier 3: remaining chip countries like QA/IS/IE — shown at zoom ≥3.5
    var tier = alwaysSet.has(c.code) ? 1 : (midSet.has(c.code) ? 2 : 3);
    return {
      type: "Feature",
      geometry: { type: "Point", coordinates: [c.lon, c.lat] },
      properties: {
        name: c.name,
        nameUpper: c.name.toUpperCase(),
        nameSpaced: c.name.toUpperCase().split("").join("\u2009"),
        tier: tier,
        ccy: c.ccy,
        code: c.code,
        labelOnly: 0,
      },
    };
  });
  // Extra label-only countries (tier 4) — only show at 40%+ zoom
  (window.EXTRA_LABELS || []).forEach(function(e) {
    feats.push({
      type: "Feature",
      geometry: { type: "Point", coordinates: [e.lon, e.lat] },
      properties: {
        name: e.name,
        nameUpper: e.name.toUpperCase(),
        nameSpaced: e.name.toUpperCase().split("").join("\u2009"),
        tier: 4,
        labelOnly: 1,
      },
    });
  });
  return { type: "FeatureCollection", features: feats };
}

function buildMapStyle() {
  var ocean = "#0e1420";
  var land  = "#1d2636";
  var line  = "#3d4f6a";
  var grat  = "#1a2230";
  return {
    version: 8, name: "atlas",
    glyphs: "https://demotiles.maplibre.org/font/{fontstack}/{range}.pbf",
    sources: {
      demo: { type:"vector", url:"https://demotiles.maplibre.org/tiles/tiles.json" },
      grat: { type:"geojson", data: buildGraticule() },
      lbls: { type:"geojson", data: buildCountryLabelsGeoJSON() },
    },
    layers: [
      { id:"ocean",          type:"background", paint:{ "background-color": ocean } },
      { id:"graticule",      type:"line",   source:"grat",
        paint:{ "line-color":grat, "line-width":0.5, "line-opacity":0.6 } },
      { id:"countries-fill", type:"fill",   source:"demo", "source-layer":"countries",
        paint:{ "fill-color":land, "fill-opacity":1 } },
      { id:"countries-line", type:"line",   source:"demo", "source-layer":"countries",
        paint:{ "line-color":line, "line-width":1.5, "line-opacity":1 } },
      { id:"base-pulse", type:"circle", source:"lbls",
        filter: ["==", ["get","ccy"], "__NONE__"],
        paint:{
          "circle-radius": 20,
          "circle-color": "#fbbf24",
          "circle-opacity": 0.3,
          "circle-blur": 0.9,
        },
      },
      { id:"country-dots-glow", type:"circle", source:"lbls",
        filter: ["!=", ["get","labelOnly"], 1],
        paint:{
          "circle-radius": ["interpolate",["linear"],["zoom"],
            0.5, 7, 3, 10, 6, 14
          ],
          "circle-color": "#fbbf24",
          "circle-opacity": 0.18,
          "circle-blur": 0.7,
        },
      },
      { id:"country-dots", type:"circle", source:"lbls",
        filter: ["!=", ["get","labelOnly"], 1],
        paint:{
          "circle-radius": ["interpolate",["linear"],["zoom"],
            0.5, 1.8, 3, 2.6, 6, 3.4
          ],
          "circle-color": "#fde68a",
          "circle-opacity": 0.95,
          "circle-stroke-color": "rgba(251,191,36,0.7)",
          "circle-stroke-width": 1.2,
        },
      },
      { id:"country-labels", type:"symbol", source:"lbls",
        minzoom: 1.2,
        filter: ["case",
          ["<=", ["zoom"], 2.5], ["==", ["get","tier"], 1],
          ["<=", ["zoom"], 3.5], ["<=", ["get","tier"], 2],
          ["<",  ["zoom"], 4.48], ["<=", ["get","tier"], 3],
          true
        ],
        layout:{
          "text-field": ["case",
            ["==", ["get","tier"], 1], ["get","nameSpaced"],
            ["get","nameUpper"]
          ],
          "text-font": ["Noto Sans Regular"],
          "text-size": ["interpolate",["linear"],["zoom"],
            1.2, ["case", ["==", ["get","tier"], 1], 10, 0],
            3,   ["case", ["==", ["get","tier"], 1], 13, ["==", ["get","tier"], 2], 11, 9],
            5,   ["case", ["==", ["get","tier"], 1], 16, ["==", ["get","tier"], 2], 13, 11],
            7,   ["case", ["==", ["get","tier"], 1], 19, ["==", ["get","tier"], 2], 16, 14]
          ],
          "text-letter-spacing": 0.08,
          "text-max-width": 8,
          "text-anchor": "top",
          "text-offset": [0, 0.6],
          "text-padding": 4,
          "text-allow-overlap": false,
          "text-transform": "uppercase",
        },
        paint:{
          "text-color": ["case",
            ["==", ["get","tier"], 1], "#e8d4a0",
            ["==", ["get","tier"], 2], "#c8b890",
            "#98907a"
          ],
          "text-halo-color": "rgba(8,12,22,0.7)",
          "text-halo-width": 1.3,
          "text-opacity": ["interpolate",["linear"],["zoom"],
            1.2, ["case", ["==", ["get","tier"], 4], 0, 0.4],
            2,   ["case", ["==", ["get","tier"], 4], 0, 0.85],
            3.5, ["case", ["==", ["get","tier"], 4], 0, 1],
            4.3, ["case", ["==", ["get","tier"], 4], 0, 1],
            4.8, 1
          ],
        },
      },
    ],
  };
}

function buildHubsGeoJSON() {
  // Major FX/financial centers — where currencies actually trade.
  // Shown as glowing dots on flat + globe, independent of country chips.
  var hubs = [
    { name:"New York",   lon:-74.006,  lat:40.7128 },
    { name:"London",     lon:-0.1278,  lat:51.5074 },
    { name:"Tokyo",      lon:139.6917, lat:35.6895 },
    { name:"Hong Kong",  lon:114.1694, lat:22.3193 },
    { name:"Singapore",  lon:103.8198, lat:1.3521  },
    { name:"Frankfurt",  lon:8.6821,   lat:50.1109 },
    { name:"Zurich",     lon:8.5417,   lat:47.3769 },
    { name:"Shanghai",   lon:121.4737, lat:31.2304 },
    { name:"Sydney",     lon:151.2093, lat:-33.8688 },
    { name:"Toronto",    lon:-79.3832, lat:43.6532 },
    { name:"Dubai",      lon:55.2708,  lat:25.2048 },
    { name:"Mumbai",     lon:72.8777,  lat:19.0760 },
    { name:"São Paulo",  lon:-46.6333, lat:-23.5505 },
    { name:"Seoul",      lon:126.9780, lat:37.5665 },
    { name:"Mexico City",lon:-99.1332, lat:19.4326 },
    { name:"Johannesburg",lon:28.0473, lat:-26.2041 },
  ];
  return {
    type:"FeatureCollection",
    features: hubs.map(function(h){
      return {
        type:"Feature",
        geometry:{ type:"Point", coordinates:[h.lon, h.lat] },
        properties:{ name:h.name }
      };
    })
  };
}

function buildGraticule() {
  var features = [];
  for (var lon = -180; lon <= 180; lon += 20) {
    var c = []; for (var lt = -85; lt <= 85; lt += 5) c.push([lon, lt]);
    features.push({ type:"Feature", geometry:{ type:"LineString", coordinates:c }, properties:{} });
  }
  for (var lat = -80; lat <= 80; lat += 20) {
    var c2 = []; for (var ln = -180; ln <= 180; ln += 5) c2.push([ln, lat]);
    features.push({ type:"Feature", geometry:{ type:"LineString", coordinates:c2 }, properties:{} });
  }
  return { type:"FeatureCollection", features:features };
}

window.WorldMapGL = WorldMapGL;
