The file /home/ubuntu/ils-claude/app.js has been updated successfully.

/* ===================================================
   International Love Story — App
   D3 SVG world map + episode interactivity
   Works on all devices, no WebGL needed
   =================================================== */

// ——— Country centres [lon, lat] for D3 geoProjection ———
const COUNTRY_COORDS = {
  'Germany':        [-10.5,  51.2],   // swapped to [lon,lat] for D3
  'Mexico':         [-102.6, 23.6],
  'France':         [  2.2,  46.2],
  'India':          [ 79.0,  20.6],
  'Russia':         [ 60.0,  61.5],
  'Morocco':        [ -7.1,  31.8],
  'United Kingdom': [ -3.4,  54.4],
  'UK':             [ -3.4,  54.4],
  'USA':            [-95.7,  37.1],
  'Philippines':    [121.8,  12.9],
  'Taiwan':         [121.0,  23.7],
  'Argentina':      [-63.6, -38.4],
  'Netherlands':    [  5.3,  52.3],
  'Spain':          [ -3.7,  40.4],
  'Brazil':         [-51.9, -14.2],
  'Japan':          [138.3,  36.2],
  'Australia':      [133.8, -25.3],
  'Canada':         [-106.3, 56.1],
  'Italy':          [ 12.6,  41.9],
  'Colombia':       [-74.1,   4.6],
};

// Fix key: Germany was stored with negative lon in error — correct:
COUNTRY_COORDS['Germany'] = [10.5, 51.2];

// ——— State ———
let episodes       = [];
let currentFilter  = 'all';
let selectedEp     = null;
let projection     = null;
let svgEl          = null;

// ——— Helpers ———
function epHasCoords(ep) {
  if (!ep.storyCountries || ep.storyCountries.length < 2) return false;
  return !!(COUNTRY_COORDS[ep.storyCountries[0]] && COUNTRY_COORDS[ep.storyCountries[1]]);
}

function getFiltered(eps, filter) {
  if (filter === 'all') return eps;
  return eps.filter(ep =>
    ep.tags && ep.tags.some(t => t.toLowerCase().includes(filter.toLowerCase()))
  );
}

// ——— Build D3 SVG world map ———
async function initMap(episodes) {
  const container = document.getElementById('map-container');
  if (!container) return;

  // Responsive viewBox dimensions
  const VW = 960, VH = 500;

  // Create SVG
  const svg = d3.select('#map-container')
    .append('svg')
    .attr('viewBox', `0 0 ${VW} ${VH}`)
    .attr('preserveAspectRatio', 'xMidYMid meet')
    .attr('role', 'img')
    .attr('aria-label', 'World map showing episode connections');

  svgEl = svg;

  // Natural Earth projection — beautiful and distortion-free
  projection = d3.geoNaturalEarth1()
    .scale(153)
    .translate([VW / 2, VH / 2]);

  const pathGen = d3.geoPath().projection(projection);

  // Gradient defs
  const defs = svg.append('defs');

  const seaGrad = defs.append('linearGradient')
    .attr('id', 'seaGrad').attr('x1','0%').attr('y1','0%').attr('x2','100%').attr('y2','100%');
  seaGrad.append('stop').attr('offset','0%').attr('stop-color','#f5e8da');
  seaGrad.append('stop').attr('offset','100%').attr('stop-color','#edddd0');

  const arcGrad = defs.append('linearGradient')
    .attr('id', 'arcGrad').attr('x1','0%').attr('y1','0%').attr('x2','100%').attr('y2','0%');
  arcGrad.append('stop').attr('offset','0%').attr('stop-color','#e8896e');
  arcGrad.append('stop').attr('offset','100%').attr('stop-color','#c85a3a');

  // Glow filter for selected arc
  const glow = defs.append('filter').attr('id','glow');
  glow.append('feGaussianBlur').attr('stdDeviation','3').attr('result','coloredBlur');
  const feMerge = glow.append('feMerge');
  feMerge.append('feMergeNode').attr('in','coloredBlur');
  feMerge.append('feMergeNode').attr('in','SourceGraphic');

  // Sea background
  svg.append('rect')
    .attr('width', VW).attr('height', VH)
    .attr('fill', 'url(#seaGrad)')
    .attr('rx', 16);

  // Graticule (grid lines)
  svg.append('path')
    .datum(d3.geoGraticule()())
    .attr('d', pathGen)
    .attr('fill', 'none')
    .attr('stroke', 'rgba(160,100,80,0.12)')
    .attr('stroke-width', 0.5);

  // ——— Load world topology ———
  let world;
  try {
    world = await fetch('https://cdn.jsdelivr.net/npm/world-atlas@2/countries-110m.json')
      .then(r => r.json());
  } catch (e) {
    container.innerHTML = '
Map data unavailable. Check connection.
';
    return;
  }

  const countries = topojson.feature(world, world.objects.countries);
  const borders   = topojson.mesh(world, world.objects.countries, (a, b) => a !== b);

  // Country fills
  svg.append('g')
    .selectAll('path')
    .data(countries.features)
    .join('path')
    .attr('d', pathGen)
    .attr('fill', '#f0ddd0')
    .attr('stroke', 'none');

  // Country borders
  svg.append('path')
    .datum(borders)
    .attr('d', pathGen)
    .attr('fill', 'none')
    .attr('stroke', '#c4a090')
    .attr('stroke-width', 0.6)
    .attr('stroke-linejoin', 'round');

  // Outer border
  svg.append('path')
    .datum({ type: 'Sphere' })
    .attr('d', pathGen)
    .attr('fill', 'none')
    .attr('stroke', '#b89070')
    .attr('stroke-width', 0.8);

  // ——— Arc + pin layers (drawn on top of countries) ———
  const arcLayer = svg.append('g').attr('class', 'arc-layer');
  const pinLayer = svg.append('g').attr('class', 'pin-layer');

  drawConnections(episodes, 'all', arcLayer, pinLayer);

  // Hide loader
  const loader = document.getElementById('globe-loading');
  if (loader) loader.classList.add('hidden');
}

// ——— Draw arcs and pins ———
function drawConnections(eps, filter, arcLayer, pinLayer) {
  arcLayer.selectAll('*').remove();
  pinLayer.selectAll('*').remove();

  if (!projection) return;

  const filtered = getFiltered(eps, filter).filter(epHasCoords);

  filtered.forEach(ep => {
    const c1 = COUNTRY_COORDS[ep.storyCountries[0]];
    const c2 = COUNTRY_COORDS[ep.storyCountries[1]];
    const p1 = projection(c1);
    const p2 = projection(c2);
    if (!p1 || !p2) return;

    const isSelected = selectedEp && selectedEp.id === ep.id;

    // Quadratic bezier control point — arcs UP above the straight line
    const mx = (p1[0] + p2[0]) / 2;
    const my = (p1[1] + p2[1]) / 2;
    const dist = Math.hypot(p2[0] - p1[0], p2[1] - p1[1]);
    // Control point lifted above midpoint
    const cpx = mx;
    const cpy = my - dist * 0.35;

    const d = `M${p1[0]},${p1[1]} Q${cpx},${cpy} ${p2[0]},${p2[1]}`;

    // Shadow arc for click target (fat, transparent)
    arcLayer.append('path')
      .attr('d', d)
      .attr('fill', 'none')
      .attr('stroke', 'transparent')
      .attr('stroke-width', 16)
      .style('cursor', 'pointer')
      .on('click', () => selectEpisode(ep))
      .on('touchend', (e) => { e.preventDefault(); selectEpisode(ep); });

    // Visible arc
    arcLayer.append('path')
      .attr('d', d)
      .attr('fill', 'none')
      .attr('stroke', isSelected ? '#e03010' : '#c85a3a')
      .attr('stroke-width', isSelected ? 2.5 : 1.8)
      .attr('stroke-linecap', 'round')
      .attr('opacity', isSelected ? 1.0 : 0.8)
      .attr('filter', isSelected ? 'url(#glow)' : null)
      .style('pointer-events', 'none');

    // Animated dash for selected
    if (isSelected) {
      arcLayer.append('path')
        .attr('d', d)
        .attr('fill', 'none')
        .attr('stroke', '#ff7755')
        .attr('stroke-width', 1.5)
        .attr('stroke-linecap', 'round')
        .attr('stroke-dasharray', '4 8')
        .attr('opacity', 0.7)
        .style('pointer-events', 'none')
        .append('animateTransform')
          .attr('attributeName', 'stroke-dashoffset')
          .attr('type', 'translate')
          .attr('from', '0')
          .attr('to', '-24')
          .attr('dur', '1s')
          .attr('repeatCount', 'indefinite');
    }

    // Pins
    [[p1, ep.storyCountries[0]], [p2, ep.storyCountries[1]]].forEach(([pos, name]) => {
      // Outer ring
      pinLayer.append('circle')
        .attr('cx', pos[0]).attr('cy', pos[1])
        .attr('r', isSelected ? 8 : 6)
        .attr('fill', 'rgba(200,90,58,0.20)')
        .style('pointer-events', 'none');

      // Inner dot
      pinLayer.append('circle')
        .attr('cx', pos[0]).attr('cy', pos[1])
        .attr('r', isSelected ? 5 : 4)
        .attr('fill', isSelected ? '#e03010' : '#c85a3a')
        .attr('stroke', '#fdf8f3')
        .attr('stroke-width', 1.5)
        .style('cursor', 'pointer')
        .on('click', () => selectEpisode(ep))
        .on('touchend', (e) => { e.preventDefault(); selectEpisode(ep); });

      // Country label
      pinLayer.append('text')
        .attr('x', pos[0])
        .attr('y', pos[1] - (isSelected ? 10 : 9))
        .attr('text-anchor', 'middle')
        .attr('font-size', isSelected ? '9' : '8')
        .attr('font-family', 'Lato, sans-serif')
        .attr('font-weight', '700')
        .attr('fill', isSelected ? '#a03010' : '#8b5040')
        .attr('opacity', isSelected ? 1 : 0.85)
        .style('pointer-events', 'none')
        .text(name);
    });
  });
}

// Re-draw connections after filter/selection change
function redrawConnections() {
  if (!svgEl) return;
  const arcLayer = svgEl.select('.arc-layer');
  const pinLayer = svgEl.select('.pin-layer');
  drawConnections(episodes, currentFilter, arcLayer, pinLayer);
}

// ——— Episode selection ———
function selectEpisode(ep) {
  selectedEp = ep;
  redrawConnections();
  renderEpisodePreview(ep);
}

function renderEpisodePreview(ep) {
  const preview = document.getElementById('episode-preview');
  if (!preview) return;
  const countries = (ep.storyCountries || []).join(' ↔ ') || 'International';
  preview.innerHTML = `

Episode ${ep.episode || ''}

${ep.title}

${countries}

${ep.summary || ''}

      Listen now →

`;
}

// ——— Modal ———
function openModal(ep) {
  const overlay = document.getElementById('modal-overlay');
  const body    = document.getElementById('modal-body');
  if (!overlay || !body) return;

  const countries = (ep.storyCountries || []).join(' ↔ ') || 'International';
  const tags = (ep.tags || []).map(t => `<span class="ep-tag">${t}</span>`).join('');

  body.innerHTML = `

Episode ${ep.episode || ''} · Season ${ep.season || 3}

${ep.title}

📍 ${countries}

${ep.summary || ep.storySummary || ''}

${tags}

      Listen to episode →
      Follow the show

`;

  overlay.classList.add('open');
  overlay.setAttribute('aria-hidden', 'false');
  document.body.style.overflow = 'hidden';
}

function closeModal() {
  const overlay = document.getElementById('modal-overlay');
  if (!overlay) return;
  overlay.classList.remove('open');
  overlay.setAttribute('aria-hidden', 'true');
  document.body.style.overflow = '';
}

// ——— Episode cards ———
function renderEpisodeCards(eps, filter) {
  const grid = document.getElementById('episodes-grid');
  if (!grid) return;

  const filtered = getFiltered(eps, filter);

  if (filtered.length === 0) {
    grid.innerHTML = '
No episodes match that filter.
';
    return;
  }

  grid.innerHTML = filtered.map(ep => {
    const countries = (ep.storyCountries || [])
      .map(c => `<span class="ep-card-flag">${c}</span>`).join(' ↔ ');
    const tags = (ep.tags || []).slice(0, 4)
      .map(t => `<span class="ep-tag">${t}</span>`).join('');
    return `

Ep. ${ep.episode || ''}

${ep.title}

        ${countries ? `<div class="ep-card-countries">${countries}</div>` : ''}

${ep.summary || ep.storySummary || ''}

${tags}

Read & listen →

`;
  }).join('');

  grid.querySelectorAll('.ep-card').forEach(card => {
    const ep = eps.find(e => e.id === card.dataset.epId);
    if (!ep) return;
    card.addEventListener('click', () => openModal(ep));
    card.addEventListener('keydown', e => {
      if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); openModal(ep); }
    });
  });
}

// ——— Filters ———
function bindFilters() {
  document.getElementById('globe-filters')?.querySelectorAll('.pill').forEach(btn => {
    btn.addEventListener('click', () => {
      document.getElementById('globe-filters').querySelectorAll('.pill')
        .forEach(b => b.classList.remove('pill-active'));
      btn.classList.add('pill-active');
      currentFilter = btn.dataset.filter;
      selectedEp = null;
      resetPreview();
      redrawConnections();
    });
  });

  document.getElementById('episodes-filters')?.querySelectorAll('.pill').forEach(btn => {
    btn.addEventListener('click', () => {
      document.getElementById('episodes-filters').querySelectorAll('.pill')
        .forEach(b => b.classList.remove('pill-active'));
      btn.classList.add('pill-active');
      renderEpisodeCards(episodes, btn.dataset.filter);
    });
  });
}

function resetPreview() {
  const preview = document.getElementById('episode-preview');
  if (!preview) return;
  preview.innerHTML = `

⚪

Click any red thread on the map to preview an episode here

`;
}

// ——— Nav toggle ———
function initNav() {
  const toggle = document.getElementById('nav-toggle');
  const nav    = document.getElementById('site-nav');
  if (!toggle || !nav) return;
  toggle.addEventListener('click', () => {
    const open = nav.classList.toggle('open');
    toggle.setAttribute('aria-expanded', open);
  });
  nav.querySelectorAll('a').forEach(a => {
    a.addEventListener('click', () => {
      nav.classList.remove('open');
      toggle.setAttribute('aria-expanded', 'false');
    });
  });
}

// ——— Bootstrap ———
async function main() {
  initNav();

  document.getElementById('modal-close')?.addEventListener('click', closeModal);
  document.getElementById('modal-overlay')?.addEventListener('click', e => {
    if (e.target === e.currentTarget) closeModal();
  });
  document.addEventListener('keydown', e => {
    if (e.key === 'Escape') closeModal();
  });

  // Load episodes
  try {
    const data = await fetch('./data/episodes.json').then(r => r.json());
    episodes = Array.isArray(data) ? data : (data.episodes || []);
  } catch (e) {
    console.error('Failed to load episodes:', e);
    return;
  }

  renderEpisodeCards(episodes, 'all');
  bindFilters();
  await initMap(episodes);
}

document.addEventListener('DOMContentLoaded', main);

-   Three.js 3D globe + episode interactivity

+   D3 SVG world map + episode interactivity

+   Works on all devices, no WebGL needed

-// ——— Country coordinate centres (lat, lon) ———

+// ——— Country centres [lon, lat] for D3 geoProjection ———

-  'United Kingdom': { lat: 54.4,  lon: -3.4   },

-  'Netherlands':    { lat: 52.3,  lon: 5.3    },

+  'Germany':        [-10.5,  51.2],   // swapped to [lon,lat] for D3

+// Fix key: Germany was stored with negative lon in error — correct:

+COUNTRY_COORDS['Germany'] = [10.5, 51.2];

-let globeScene, globeRenderer, globeCamera, globeGroup;

-function latLonToVec3(lat, lon, r = GLOBE_R) {

-  const phi   = (90 - lat)  * (Math.PI / 180);

-  const theta = (lon + 180) * (Math.PI / 180);

-    -r * Math.sin(phi) * Math.cos(theta),

-     r * Math.sin(phi) * Math.sin(theta)

+  if (!ep.storyCountries || ep.storyCountries.length < 2) return false;

+  return !!(COUNTRY_COORDS[ep.storyCountries[0]] && COUNTRY_COORDS[ep.storyCountries[1]]);

-  if (!ep.storyCountries || ep.storyCountries.length < 2) return false;

-  return !!(COUNTRY_COORDS[c1] && COUNTRY_COORDS[c2]);

+    ep.tags && ep.tags.some(t => t.toLowerCase().includes(filter.toLowerCase()))

-  const container = document.getElementById('globe-container');

-  if (!container || typeof THREE === 'undefined') return;

+  const container = document.getElementById('map-container');

+  const svg = d3.select('#map-container')

+    .attr('preserveAspectRatio', 'xMidYMid meet')

+    .attr('aria-label', 'World map showing episode connections');

-  const camera = new THREE.PerspectiveCamera(42, W / H, 0.1, 100);

-  const renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });

-  renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));

+  // Natural Earth projection — beautiful and distortion-free

-  scene.add(new THREE.AmbientLight(0xfff3e0, 1.0));

-  const sun = new THREE.DirectionalLight(0xfff0d0, 0.9);

-  const fill = new THREE.DirectionalLight(0xd0e8f0, 0.35);

+  const pathGen = d3.geoPath().projection(projection);

-  // Globe group (everything rotates together)

-  const sphereGeo = new THREE.SphereGeometry(GLOBE_R, 72, 72);

-  const sphereMat = new THREE.MeshPhongMaterial({

-    specular:  new THREE.Color(0x8b6558).multiplyScalar(0.15),

-  const sphere = new THREE.Mesh(sphereGeo, sphereMat);

+  const seaGrad = defs.append('linearGradient')

-  const atmoGeo = new THREE.SphereGeometry(GLOBE_R * 1.04, 32, 32);

-  const atmoMat = new THREE.MeshBasicMaterial({

-  group.add(new THREE.Mesh(atmoGeo, atmoMat));

+  const arcGrad = defs.append('linearGradient')

-  // ——— Country outlines from TopoJSON ———

-      'https://cdn.jsdelivr.net/npm/world-atlas@2/countries-110m.json'

+  const glow = defs.append('filter').attr('id','glow');

+  const feMerge = glow.append('feMerge');

-    const countries = topojson.feature(world, world.objects.countries);

-    const bordersMesh = topojson.mesh(world, world.objects.countries,

+    .attr('width', VW).attr('height', VH)

-    const lineMat = new THREE.LineBasicMaterial({

-    countries.features.forEach(feat => {

-      const ringArrays = geom.type === 'Polygon'

-        const pts = ring.map(([lon, lat]) => latLonToVec3(lat, lon, 1.002));

-        const geo = new THREE.BufferGeometry().setFromPoints(pts);

-        group.add(new THREE.Line(geo, lineMat));

+    world = await fetch('https://cdn.jsdelivr.net/npm/world-atlas@2/countries-110m.json')

-    console.warn('Could not load world-atlas topology:', e);

+    container.innerHTML = '
Map data unavailable. Check connection.
';

-  buildGlobeConnections(episodes, 'all');

+  const countries = topojson.feature(world, world.objects.countries);

+  const borders   = topojson.mesh(world, world.objects.countries, (a, b) => a !== b);

-  canvas.addEventListener('pointerdown', e => {

-    prevMouse = { x: e.clientX, y: e.clientY };

-  window.addEventListener('pointermove', e => {

-    const dx = e.clientX - prevMouse.x;

-    const dy = e.clientY - prevMouse.y;

-    group.rotation.x  = Math.max(-0.6, Math.min(0.6, group.rotation.x + dy * 0.005));

-  window.addEventListener('pointerup', () => {

+  // ——— Arc + pin layers (drawn on top of countries) ———

+  const arcLayer = svg.append('g').attr('class', 'arc-layer');

+  const pinLayer = svg.append('g').attr('class', 'pin-layer');

+  drawConnections(episodes, 'all', arcLayer, pinLayer);

-  canvas.addEventListener('click', e => {

-    if (Math.abs(e.clientX - prevMouse.x) > 4) return; // was a drag

-    const raycaster = new THREE.Raycaster();

-    raycaster.params.Line = { threshold: 0.025 };

-    const rect = canvas.getBoundingClientRect();

-      ((e.clientX - rect.left) / rect.width)  *  2 - 1,

-      ((e.clientY - rect.top)  / rect.height) * -2 + 1

-    raycaster.setFromCamera(mouse, camera);

-    const hits = raycaster.intersectObjects([...arcObjects, ...pinObjects], false);

-      const ep = hits[0].object.userData.episode;

-  canvas.addEventListener('mousemove', e => {

-    canvas.style.cursor = hits.length > 0 ? 'pointer' : (isGlobeDragging ? 'grabbing' : 'grab');

-  window.addEventListener('resize', () => {

-    if (autoRotate && !isGlobeDragging) {

const loader = document.getElementById('globe-loading');

-function buildGlobeConnections(episodes, filter) {

-  arcObjects.forEach(o => globeGroup && globeGroup.remove(o));

-  pinObjects.forEach(o => globeGroup && globeGroup.remove(o));

+function drawConnections(eps, filter, arcLayer, pinLayer) {

-    : episodes.filter(ep => ep.tags && ep.tags.some(t => t.toLowerCase().includes(filter.toLowerCase())));

-  const globeEps = filtered.filter(episodeHasGlobeData);

+  const filtered = getFiltered(eps, filter).filter(epHasCoords);

const c1 = COUNTRY_COORDS[ep.storyCountries[0]];

const c2 = COUNTRY_COORDS[ep.storyCountries[1]];

-    const isSelected = selectedEpisode && selectedEpisode.id === ep.id;

-    const arcColor   = isSelected ? 0xff3a1a : 0xc85a3a;

-    const pinColor   = isSelected ? 0xff3a1a : 0xc85a3a;

-    const arcOpacity = isSelected ? 1.0 : 0.75;

+    const isSelected = selectedEp && selectedEp.id === ep.id;

-    const start = latLonToVec3(c1.lat, c1.lon, 1.002);

-    const end   = latLonToVec3(c2.lat, c2.lon, 1.002);

-      .multiplyScalar(GLOBE_R + ARC_H);

+    // Quadratic bezier control point — arcs UP above the straight line

+    // Control point lifted above midpoint

-    const curve  = new THREE.QuadraticBezierCurve3(start, mid, end);

-    const points = curve.getPoints(60);

-    const arcGeo = new THREE.BufferGeometry().setFromPoints(points);

-    const arcMat = new THREE.LineBasicMaterial({

-    const arc = new THREE.Line(arcGeo, arcMat);

+    // Shadow arc for click target (fat, transparent)

+      .on('click', () => selectEpisode(ep))

+      .on('touchend', (e) => { e.preventDefault(); selectEpisode(ep); });

+      .attr('stroke', isSelected ? '#e03010' : '#c85a3a')

+      .attr('stroke-width', isSelected ? 2.5 : 1.8)

+      .attr('opacity', isSelected ? 1.0 : 0.8)

+      .attr('filter', isSelected ? 'url(#glow)' : null)

+      .style('pointer-events', 'none');

+        .attr('stroke-linecap', 'round')

+        .attr('stroke-dasharray', '4 8')

+        .style('pointer-events', 'none')

+          .attr('attributeName', 'stroke-dashoffset')

+          .attr('repeatCount', 'indefinite');

-      const pinGeo = new THREE.SphereGeometry(isSelected ? 0.025 : 0.018, 10, 10);

-      const pinMat = new THREE.MeshBasicMaterial({ color: pinColor });

-      const pin    = new THREE.Mesh(pinGeo, pinMat);

+    [[p1, ep.storyCountries[0]], [p2, ep.storyCountries[1]]].forEach(([pos, name]) => {

+        .style('pointer-events', 'none');

+        .on('click', () => selectEpisode(ep))

+        .attr('y', pos[1] - (isSelected ? 10 : 9))

+        .attr('font-size', isSelected ? '9' : '8')

+        .attr('font-family', 'Lato, sans-serif')

+        .attr('opacity', isSelected ? 1 : 0.85)

+// Re-draw connections after filter/selection change

+  const arcLayer = svgEl.select('.arc-layer');

+  const pinLayer = svgEl.select('.pin-layer');

+  drawConnections(episodes, currentFilter, arcLayer, pinLayer);

-  autoRotateTimer = setTimeout(() => { autoRotate = true; }, 4000);

-  buildGlobeConnections(episodes, currentFilter);

-  const tags = (ep.tags || []).map(t =>

+  const tags = (ep.tags || []).map(t => `<span class="ep-tag">${t}</span>`).join('');

Episode ${ep.episode || ''} · Season ${ep.season || 3}

const grid = document.getElementById('episodes-grid');

-    : eps.filter(ep => ep.tags && ep.tags.some(t => t.toLowerCase().includes(filter.toLowerCase())));

+  const filtered = getFiltered(eps, filter);

grid.innerHTML = '
No episodes match that filter.
';

const countries = (ep.storyCountries || [])

-      .map(c => `<span class="ep-card-flag">${c}</span>`)

+      .map(c => `<span class="ep-card-flag">${c}</span>`).join(' ↔ ');

const tags = (ep.tags || []).slice(0, 4)

.map(t => `<span class="ep-tag">${t}</span>`).join('');

const ep = eps.find(e => e.id === card.dataset.epId);

-      buildGlobeConnections(episodes, currentFilter);

-
Click any red thread on the globe to preview an episode here

+
Click any red thread on the map to preview an episode here

const open = nav.classList.toggle('open');

if (e.target === e.currentTarget) closeModal();

-  // Init globe (requires Three.js + topojson)

-  if (typeof THREE !== 'undefined' && typeof topojson !== 'undefined') {

-    const loader = document.getElementById('globe-loading');

-    if (loader) loader.innerHTML = '
3D globe requires a modern browser with WebGL.
';

/* ===================================================
   International Love Story — App
   Three.js 3D globe + episode interactivity
   =================================================== */

// ——— Country coordinate centres (lat, lon) ———
const COUNTRY_COORDS = {
  'Germany':        { lat: 51.2,  lon: 10.5   },
  'Mexico':         { lat: 23.6,  lon: -102.6 },
  'France':         { lat: 46.2,  lon: 2.2    },
  'India':          { lat: 20.6,  lon: 79.0   },
  'Russia':         { lat: 61.5,  lon: 60.0   },
  'Morocco':        { lat: 31.8,  lon: -7.1   },
  'United Kingdom': { lat: 54.4,  lon: -3.4   },
  'UK':             { lat: 54.4,  lon: -3.4   },
  'USA':            { lat: 37.1,  lon: -95.7  },
  'Philippines':    { lat: 12.9,  lon: 121.8  },
  'Taiwan':         { lat: 23.7,  lon: 121.0  },
  'Argentina':      { lat: -38.4, lon: -63.6  },
  'Netherlands':    { lat: 52.3,  lon: 5.3    },
  'Spain':          { lat: 40.4,  lon: -3.7   },
  'Brazil':         { lat: -14.2, lon: -51.9  },
  'Japan':          { lat: 36.2,  lon: 138.3  },
  'Australia':      { lat: -25.3, lon: 133.8  },
  'Canada':         { lat: 56.1,  lon: -106.3 },
  'Italy':          { lat: 41.9,  lon: 12.6   },
  'Colombia':       { lat: 4.6,   lon: -74.1  },
};

// ——— State ———
let episodes = [];
let currentFilter = 'all';
let globeScene, globeRenderer, globeCamera, globeGroup;
let arcObjects = [];
let pinObjects = [];
let selectedEpisode = null;
let isGlobeDragging = false;
let prevMouse = { x: 0, y: 0 };
let autoRotate = true;
let autoRotateTimer = null;
const GLOBE_R = 1.0;
const ARC_H   = 0.38;

// ——— Helpers ———
function latLonToVec3(lat, lon, r = GLOBE_R) {
  const phi   = (90 - lat)  * (Math.PI / 180);
  const theta = (lon + 180) * (Math.PI / 180);
  return new THREE.Vector3(
    -r * Math.sin(phi) * Math.cos(theta),
     r * Math.cos(phi),
     r * Math.sin(phi) * Math.sin(theta)
  );
}

function episodeHasGlobeData(ep) {
  if (!ep.storyCountries || ep.storyCountries.length < 2) return false;
  const c1 = ep.storyCountries[0];
  const c2 = ep.storyCountries[1];
  return !!(COUNTRY_COORDS[c1] && COUNTRY_COORDS[c2]);
}

// ——— Globe init ———
async function initGlobe(episodes) {
  const container = document.getElementById('globe-container');
  if (!container || typeof THREE === 'undefined') return;

  const W = container.clientWidth;
  const H = container.clientHeight;

  // Scene
  const scene = new THREE.Scene();
  globeScene = scene;

  // Camera
  const camera = new THREE.PerspectiveCamera(42, W / H, 0.1, 100);
  camera.position.set(0, 0, 2.8);
  globeCamera = camera;

  // Renderer
  const renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });
  renderer.setSize(W, H);
  renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
  renderer.setClearColor(0x000000, 0);
  container.appendChild(renderer.domElement);
  globeRenderer = renderer;

  // Lights
  scene.add(new THREE.AmbientLight(0xfff3e0, 1.0));
  const sun = new THREE.DirectionalLight(0xfff0d0, 0.9);
  sun.position.set(3, 2, 2);
  scene.add(sun);
  const fill = new THREE.DirectionalLight(0xd0e8f0, 0.35);
  fill.position.set(-2, -1, -1);
  scene.add(fill);

  // Globe group (everything rotates together)
  const group = new THREE.Group();
  scene.add(group);
  globeGroup = group;

  // ——— Sphere ———
  const sphereGeo = new THREE.SphereGeometry(GLOBE_R, 72, 72);
  const sphereMat = new THREE.MeshPhongMaterial({
    color:     0xfdf0e4,
    shininess: 8,
    specular:  new THREE.Color(0x8b6558).multiplyScalar(0.15),
  });
  const sphere = new THREE.Mesh(sphereGeo, sphereMat);
  group.add(sphere);

  // ——— Atmosphere glow ———
  const atmoGeo = new THREE.SphereGeometry(GLOBE_R * 1.04, 32, 32);
  const atmoMat = new THREE.MeshBasicMaterial({
    color:       0xf4c9a8,
    side:        THREE.BackSide,
    transparent: true,
    opacity:     0.18,
  });
  group.add(new THREE.Mesh(atmoGeo, atmoMat));

  // ——— Country outlines from TopoJSON ———
  try {
    const world = await fetch(
      'https://cdn.jsdelivr.net/npm/world-atlas@2/countries-110m.json'
    ).then(r => r.json());

    const countries = topojson.feature(world, world.objects.countries);
    const bordersMesh = topojson.mesh(world, world.objects.countries,
      (a, b) => a !== b
    );

    const lineMat = new THREE.LineBasicMaterial({
      color:       0xb89880,
      transparent: true,
      opacity:     0.55,
    });

    // Draw each country polygon
    countries.features.forEach(feat => {
      const geom = feat.geometry;
      const ringArrays = geom.type === 'Polygon'
        ? geom.coordinates
        : geom.coordinates.flat(1);

      ringArrays.forEach(ring => {
        const pts = ring.map(([lon, lat]) => latLonToVec3(lat, lon, 1.002));
        if (pts.length < 2) return;
        const geo = new THREE.BufferGeometry().setFromPoints(pts);
        group.add(new THREE.Line(geo, lineMat));
      });
    });
  } catch (e) {
    console.warn('Could not load world-atlas topology:', e);
  }

  // ——— Episode arcs & pins ———
  buildGlobeConnections(episodes, 'all');

  // ——— Interaction: drag ———
  const canvas = renderer.domElement;

  canvas.addEventListener('pointerdown', e => {
    isGlobeDragging = true;
    prevMouse = { x: e.clientX, y: e.clientY };
    canvas.style.cursor = 'grabbing';
    clearAutoRotateTimer();
  });

  window.addEventListener('pointermove', e => {
    if (!isGlobeDragging) return;
    const dx = e.clientX - prevMouse.x;
    const dy = e.clientY - prevMouse.y;
    group.rotation.y += dx * 0.008;
    group.rotation.x  = Math.max(-0.6, Math.min(0.6, group.rotation.x + dy * 0.005));
    prevMouse = { x: e.clientX, y: e.clientY };
  });

  window.addEventListener('pointerup', () => {
    if (!isGlobeDragging) return;
    isGlobeDragging = false;
    canvas.style.cursor = 'grab';
    resetAutoRotateTimer();
  });

  canvas.style.cursor = 'grab';

  // ——— Interaction: click ———
  canvas.addEventListener('click', e => {
    if (Math.abs(e.clientX - prevMouse.x) > 4) return; // was a drag
    const raycaster = new THREE.Raycaster();
    raycaster.params.Line = { threshold: 0.025 };
    const rect = canvas.getBoundingClientRect();
    const mouse = new THREE.Vector2(
      ((e.clientX - rect.left) / rect.width)  *  2 - 1,
      ((e.clientY - rect.top)  / rect.height) * -2 + 1
    );
    raycaster.setFromCamera(mouse, camera);
    const hits = raycaster.intersectObjects([...arcObjects, ...pinObjects], false);
    if (hits.length > 0) {
      const ep = hits[0].object.userData.episode;
      if (ep) {
        selectEpisode(ep);
        clearAutoRotateTimer();
        resetAutoRotateTimer();
      }
    }
  });

  canvas.addEventListener('mousemove', e => {
    const rect = canvas.getBoundingClientRect();
    const raycaster = new THREE.Raycaster();
    raycaster.params.Line = { threshold: 0.025 };
    const mouse = new THREE.Vector2(
      ((e.clientX - rect.left) / rect.width)  *  2 - 1,
      ((e.clientY - rect.top)  / rect.height) * -2 + 1
    );
    raycaster.setFromCamera(mouse, camera);
    const hits = raycaster.intersectObjects([...arcObjects, ...pinObjects], false);
    canvas.style.cursor = hits.length > 0 ? 'pointer' : (isGlobeDragging ? 'grabbing' : 'grab');
  });

  // ——— Resize ———
  window.addEventListener('resize', () => {
    const w = container.clientWidth;
    const h = container.clientHeight;
    camera.aspect = w / h;
    camera.updateProjectionMatrix();
    renderer.setSize(w, h);
  });

  // ——— Animate ———
  function animate() {
    requestAnimationFrame(animate);
    if (autoRotate && !isGlobeDragging) {
      group.rotation.y += 0.0025;
    }
    renderer.render(scene, camera);
  }
  animate();

  // Hide loader
  const loader = document.getElementById('globe-loading');
  if (loader) loader.classList.add('hidden');
}

function buildGlobeConnections(episodes, filter) {
  // Remove old arcs/pins
  arcObjects.forEach(o => globeGroup && globeGroup.remove(o));
  pinObjects.forEach(o => globeGroup && globeGroup.remove(o));
  arcObjects = [];
  pinObjects = [];

  const filtered = filter === 'all'
    ? episodes
    : episodes.filter(ep => ep.tags && ep.tags.some(t => t.toLowerCase().includes(filter.toLowerCase())));

  const globeEps = filtered.filter(episodeHasGlobeData);

  globeEps.forEach(ep => {
    const c1 = COUNTRY_COORDS[ep.storyCountries[0]];
    const c2 = COUNTRY_COORDS[ep.storyCountries[1]];

    const isSelected = selectedEpisode && selectedEpisode.id === ep.id;
    const arcColor   = isSelected ? 0xff3a1a : 0xc85a3a;
    const pinColor   = isSelected ? 0xff3a1a : 0xc85a3a;
    const arcOpacity = isSelected ? 1.0 : 0.75;

    // Arc
    const start = latLonToVec3(c1.lat, c1.lon, 1.002);
    const end   = latLonToVec3(c2.lat, c2.lon, 1.002);
    const mid   = new THREE.Vector3()
      .addVectors(start, end)
      .normalize()
      .multiplyScalar(GLOBE_R + ARC_H);

    const curve  = new THREE.QuadraticBezierCurve3(start, mid, end);
    const points = curve.getPoints(60);
    const arcGeo = new THREE.BufferGeometry().setFromPoints(points);
    const arcMat = new THREE.LineBasicMaterial({
      color:       arcColor,
      transparent: true,
      opacity:     arcOpacity,
    });
    const arc = new THREE.Line(arcGeo, arcMat);
    arc.userData = { episode: ep };
    globeGroup.add(arc);
    arcObjects.push(arc);

    // Pins
    [start, end].forEach(pos => {
      const pinGeo = new THREE.SphereGeometry(isSelected ? 0.025 : 0.018, 10, 10);
      const pinMat = new THREE.MeshBasicMaterial({ color: pinColor });
      const pin    = new THREE.Mesh(pinGeo, pinMat);
      pin.position.copy(pos);
      pin.userData = { episode: ep };
      globeGroup.add(pin);
      pinObjects.push(pin);
    });
  });
}

function clearAutoRotateTimer() {
  clearTimeout(autoRotateTimer);
  autoRotate = false;
}

function resetAutoRotateTimer() {
  autoRotateTimer = setTimeout(() => { autoRotate = true; }, 4000);
}

// ——— Episode selection ———
function selectEpisode(ep) {
  selectedEpisode = ep;
  buildGlobeConnections(episodes, currentFilter);
  renderEpisodePreview(ep);
}

function renderEpisodePreview(ep) {
  const preview = document.getElementById('episode-preview');
  if (!preview) return;
  const countries = (ep.storyCountries || []).join(' ↔ ') || 'International';
  preview.innerHTML = `

Episode ${ep.episode || ''}

${ep.title}

${countries}

${ep.summary || ''}

      Listen now →

`;
}

// ——— Modal ———
function openModal(ep) {
  const overlay = document.getElementById('modal-overlay');
  const body    = document.getElementById('modal-body');
  if (!overlay || !body) return;

  const countries = (ep.storyCountries || []).join(' ↔ ') || 'International';
  const tags = (ep.tags || []).map(t =>
    `<span class="ep-tag">${t}</span>`
  ).join('');

  body.innerHTML = `

Episode ${ep.episode || ''} · Season ${ep.season || 3}

${ep.title}

📍 ${countries}

${ep.summary || ep.storySummary || ''}

${tags}

      Listen to episode →
      Follow the show

`;

  overlay.classList.add('open');
  overlay.setAttribute('aria-hidden', 'false');
  document.body.style.overflow = 'hidden';
}

function closeModal() {
  const overlay = document.getElementById('modal-overlay');
  if (!overlay) return;
  overlay.classList.remove('open');
  overlay.setAttribute('aria-hidden', 'true');
  document.body.style.overflow = '';
}

// ——— Episode cards ———
function renderEpisodeCards(eps, filter) {
  const grid = document.getElementById('episodes-grid');
  if (!grid) return;

  const filtered = filter === 'all'
    ? eps
    : eps.filter(ep => ep.tags && ep.tags.some(t => t.toLowerCase().includes(filter.toLowerCase())));

  if (filtered.length === 0) {
    grid.innerHTML = '
No episodes match that filter.
';
    return;
  }

  grid.innerHTML = filtered.map(ep => {
    const countries = (ep.storyCountries || [])
      .map(c => `<span class="ep-card-flag">${c}</span>`)
      .join(' ↔ ');
    const tags = (ep.tags || []).slice(0, 4)
      .map(t => `<span class="ep-tag">${t}</span>`).join('');
    return `

Ep. ${ep.episode || ''}

${ep.title}

        ${countries ? `<div class="ep-card-countries">${countries}</div>` : ''}

${ep.summary || ep.storySummary || ''}

${tags}

Read & listen →

`;
  }).join('');

  // Bind clicks
  grid.querySelectorAll('.ep-card').forEach(card => {
    const ep = eps.find(e => e.id === card.dataset.epId);
    if (!ep) return;
    card.addEventListener('click', () => openModal(ep));
    card.addEventListener('keydown', e => {
      if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); openModal(ep); }
    });
  });
}

// ——— Filters ———
function bindFilters(episodes) {
  // Globe filters
  document.getElementById('globe-filters')?.querySelectorAll('.pill').forEach(btn => {
    btn.addEventListener('click', () => {
      document.getElementById('globe-filters').querySelectorAll('.pill')
        .forEach(b => b.classList.remove('pill-active'));
      btn.classList.add('pill-active');
      currentFilter = btn.dataset.filter;
      selectedEpisode = null;
      buildGlobeConnections(episodes, currentFilter);
      resetPreview();
    });
  });

  // Episode filters
  document.getElementById('episodes-filters')?.querySelectorAll('.pill').forEach(btn => {
    btn.addEventListener('click', () => {
      document.getElementById('episodes-filters').querySelectorAll('.pill')
        .forEach(b => b.classList.remove('pill-active'));
      btn.classList.add('pill-active');
      renderEpisodeCards(episodes, btn.dataset.filter);
    });
  });
}

function resetPreview() {
  const preview = document.getElementById('episode-preview');
  if (!preview) return;
  preview.innerHTML = `

⚪

Click any red thread on the globe to preview an episode here

`;
}

// ——— Nav toggle ———
function initNav() {
  const toggle = document.getElementById('nav-toggle');
  const nav    = document.getElementById('site-nav');
  if (!toggle || !nav) return;
  toggle.addEventListener('click', () => {
    const open = nav.classList.toggle('open');
    toggle.setAttribute('aria-expanded', open);
  });
  // Close on link click
  nav.querySelectorAll('a').forEach(a => {
    a.addEventListener('click', () => {
      nav.classList.remove('open');
      toggle.setAttribute('aria-expanded', 'false');
    });
  });
}

// ——— Bootstrap ———
async function main() {
  initNav();

  // Modal close
  document.getElementById('modal-close')?.addEventListener('click', closeModal);
  document.getElementById('modal-overlay')?.addEventListener('click', e => {
    if (e.target === e.currentTarget) closeModal();
  });
  document.addEventListener('keydown', e => {
    if (e.key === 'Escape') closeModal();
  });

  // Load episodes
  try {
    const data = await fetch('./data/episodes.json').then(r => r.json());
    episodes = Array.isArray(data) ? data : (data.episodes || []);
  } catch (e) {
    console.error('Failed to load episodes:', e);
    return;
  }

  // Render cards & filters
  renderEpisodeCards(episodes, 'all');
  bindFilters(episodes);

  // Init globe (requires Three.js + topojson)
  if (typeof THREE !== 'undefined' && typeof topojson !== 'undefined') {
    await initGlobe(episodes);
  } else {
    const loader = document.getElementById('globe-loading');
    if (loader) loader.innerHTML = '
3D globe requires a modern browser with WebGL.
';
  }
}

document.addEventListener('DOMContentLoaded', main);


Now fix the CSS for the map container — SVG needs different treatment than a canvas div:


Edit

.globe-wrap {
  position: relative;
  border-radius: var(--radius-lg);
  overflow: hidden;
  background: linear-gradient(145deg, #f0ddd0, #fdf0e8);
  box-shadow: var(--shadow-lg);
}
#globe-container {
  width: 100%;
  height: 520px;
  display: block;
}
#globe-container canvas { display: block; }

.globe-wrap {
  position: relative;
  border-radius: var(--radius-lg);
  overflow: hidden;
  background: linear-gradient(145deg, #f0ddd0, #fdf0e8);
  box-shadow: var(--shadow-lg);
}
#map-container {
  position: relative;
  width: 100%;
  min-height: 260px;
  border-radius: var(--radius-lg);
  overflow: hidden;
  background: linear-gradient(145deg, #f0ddd0, #fdf0e8);
  box-shadow: var(--shadow-lg);
}
#map-container svg {
  display: block;
  width: 100%;
  height: auto;
}


The file /home/ubuntu/ils-claude/styles.css has been updated successfully.

.globe-wrap {
  position: relative;
  border-radius: var(--radius-lg);
  overflow: hidden;
  background: linear-gradient(145deg, #f0ddd0, #fdf0e8);
  box-shadow: var(--shadow-lg);
}
#map-container {
  position: relative;
  width: 100%;
  min-height: 260px;
  border-radius: var(--radius-lg);
  overflow: hidden;
  background: linear-gradient(145deg, #f0ddd0, #fdf0e8);
  box-shadow: var(--shadow-lg);
}
#map-container svg {
  display: block;
  width: 100%;
  height: auto;
}

/* ===================================================
   International Love Story — Styles
   Design: warm, editorial, feminine
   =================================================== */

:root {
  --cream:       #fdf8f3;
  --cream-warm:  #f7ede3;
  --cream-deep:  #f0ddd0;
  --terra:       #c85a3a;
  --terra-dark:  #a0432a;
  --terra-light: #e8896e;
  --brown:       #2c1810;
  --brown-mid:   #5c3d2e;
  --brown-light: #8b6558;
  --olive:       #6b7c5e;
  --sage:        #c8d5be;
  --gold:        #c49a5a;
  --white:       #ffffff;

  --font-serif: 'Cormorant Garamond', Georgia, serif;
  --font-sans:  'Lato', system-ui, sans-serif;

  --radius-sm:  6px;
  --radius-md:  14px;
  --radius-lg:  28px;
  --radius-xl:  48px;

  --shadow-sm:  0 1px 4px rgba(44,24,16,.07);
  --shadow-md:  0 4px 20px rgba(44,24,16,.10);
  --shadow-lg:  0 12px 40px rgba(44,24,16,.14);

  --container:  1140px;
  --gap:        2rem;
}

/* ——— Reset & Base ——— */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
html { scroll-behavior: smooth; font-size: 16px; }
body {
  font-family: var(--font-sans);
  background: var(--cream);
  color: var(--brown);
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
}
img, svg { display: block; max-width: 100%; }
a { color: inherit; text-decoration: none; }
button { cursor: pointer; border: none; background: none; font: inherit; color: inherit; }
ul { list-style: none; }

/* ——— Typography ——— */
h1, h2, h3, h4 {
  font-family: var(--font-serif);
  line-height: 1.15;
  font-weight: 600;
  color: var(--brown);
}
h1 { font-size: clamp(2.4rem, 5vw, 3.8rem); }
h2 { font-size: clamp(1.9rem, 3.5vw, 2.8rem); }
h3 { font-size: 1.35rem; }
h4 { font-size: 1rem; }
h1 em, h2 em { font-style: italic; color: var(--terra); }
p { max-width: 68ch; }

/* ——— Layout ——— */
.container {
  width: min(var(--container), calc(100% - 2.5rem));
  margin-inline: auto;
}
section { padding-block: 5rem; }
.section-warm { background: var(--cream-warm); }

/* ——— Section headers ——— */
.section-header { margin-bottom: 2.5rem; }
.section-header.centered { text-align: center; }
.section-header.centered p { margin-inline: auto; }
.section-eyebrow {
  font-family: var(--font-sans);
  font-size: .78rem;
  font-weight: 700;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--terra);
  margin-bottom: .6rem;
}
.section-intro {
  font-size: 1.05rem;
  color: var(--brown-mid);
  margin-top: .8rem;
}

/* ——— Buttons ——— */
.btn {
  display: inline-flex;
  align-items: center;
  gap: .5rem;
  font-family: var(--font-sans);
  font-weight: 700;
  font-size: .9rem;
  letter-spacing: .03em;
  padding: .65rem 1.4rem;
  border-radius: var(--radius-lg);
  transition: all .2s ease;
  white-space: nowrap;
}
.btn svg { width: 1em; height: 1em; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.btn-lg  { padding: .85rem 1.8rem; font-size: 1rem; }
.btn-sm  { padding: .45rem 1rem;   font-size: .82rem; }

.btn-primary {
  background: var(--terra);
  color: var(--white);
  box-shadow: 0 2px 12px rgba(200,90,58,.30);
}
.btn-primary:hover { background: var(--terra-dark); box-shadow: 0 4px 20px rgba(200,90,58,.40); transform: translateY(-1px); }

.btn-secondary {
  background: var(--cream-deep);
  color: var(--brown);
  border: 1.5px solid var(--cream-deep);
}
.btn-secondary:hover { background: var(--cream-warm); border-color: var(--terra-light); }

.btn-ghost {
  background: transparent;
  color: var(--brown-mid);
  border: 1.5px solid rgba(44,24,16,.20);
}
.btn-ghost:hover { border-color: var(--terra); color: var(--terra); }

/* ——— HEADER ——— */
.site-header {
  position: sticky;
  top: 0;
  z-index: 100;
  background: rgba(253,248,243,.92);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid rgba(200,90,58,.12);
}
.header-inner {
  display: flex;
  align-items: center;
  gap: 2rem;
  height: 64px;
}
.logo {
  display: flex;
  align-items: center;
  gap: .7rem;
  flex-shrink: 0;
}
.logo-icon {
  font-size: 1.4rem;
  color: var(--terra);
  line-height: 1;
}
.logo-text {
  display: flex;
  flex-direction: column;
  line-height: 1.1;
}
.logo-title {
  font-family: var(--font-serif);
  font-weight: 600;
  font-size: 1.05rem;
  color: var(--brown);
}
.logo-sub {
  font-family: var(--font-serif);
  font-style: italic;
  font-size: .88rem;
  color: var(--terra);
}
.site-nav {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: 1.6rem;
}
.site-nav ul {
  display: flex;
  gap: 1.4rem;
}
.site-nav a {
  font-size: .9rem;
  font-weight: 600;
  color: var(--brown-mid);
  transition: color .15s;
}
.site-nav a:hover { color: var(--terra); }
.nav-toggle { display: none; flex-direction: column; gap: 5px; padding: .4rem; }
.nav-toggle span { display: block; width: 22px; height: 2px; background: var(--brown); border-radius: 2px; transition: .2s; }

/* ——— HERO ——— */
.hero {
  position: relative;
  overflow: hidden;
  padding-block: 7rem 5rem;
  background: linear-gradient(145deg, #fdf8f3 0%, #f7ede3 50%, #f0ddd0 100%);
}
.hero-bg-orbs { position: absolute; inset: 0; pointer-events: none; }
.orb {
  position: absolute;
  border-radius: 50%;
  filter: blur(60px);
  opacity: .45;
}
.orb-1 { width: 400px; height: 400px; background: radial-gradient(circle, #e8896e 0%, transparent 70%); top: -100px; right: -100px; }
.orb-2 { width: 300px; height: 300px; background: radial-gradient(circle, #c49a5a 0%, transparent 70%); bottom: -80px; left: 10%; }
.orb-3 { width: 200px; height: 200px; background: radial-gradient(circle, #c8d5be 0%, transparent 70%); top: 30%; left: -60px; }

.hero-content {
  position: relative;
  z-index: 1;
  max-width: 720px;
}
.hero-eyebrow {
  font-size: .82rem;
  font-weight: 700;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--terra);
  margin-bottom: 1rem;
  padding: .35rem .9rem;
  background: rgba(200,90,58,.1);
  border-radius: var(--radius-lg);
  display: inline-block;
}
.hero-headline {
  margin-bottom: 1.2rem;
  color: var(--brown);
}
.hero-subheadline {
  font-size: clamp(1.05rem, 2vw, 1.25rem);
  color: var(--brown-mid);
  margin-bottom: 2rem;
  max-width: 52ch;
}
.hero-ctas {
  display: flex;
  flex-wrap: wrap;
  gap: .8rem;
  margin-bottom: 2.5rem;
}
.spotify-icon { width: 1.1em; height: 1.1em; fill: currentColor; stroke: none; }
.hero-scroll-hint {
  display: flex;
  align-items: center;
  gap: .5rem;
  font-size: .82rem;
  color: var(--brown-light);
}
.hero-scroll-hint svg { width: 16px; height: 16px; stroke: currentColor; fill: none; stroke-width: 2; stroke-linecap: round; }

/* ——— TRUST STRIP ——— */
.trust-strip {
  background: var(--brown);
  padding: 1.4rem 0;
}
.trust-inner {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  gap: 1rem 2rem;
}
.trust-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: .2rem;
  text-align: center;
}
.trust-number {
  font-family: var(--font-serif);
  font-size: 1.6rem;
  font-weight: 600;
  color: var(--terra-light);
}
.trust-label {
  font-size: .75rem;
  font-weight: 600;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: rgba(253,248,243,.65);
}
.trust-divider {
  width: 1px;
  height: 36px;
  background: rgba(253,248,243,.2);
}

/* ——— DISCOVER / GLOBE ——— */
.discover-section { padding-block: 5rem; }
.discover-layout {
  display: grid;
  grid-template-columns: 1fr 320px;
  gap: 2.5rem;
  align-items: start;
  margin-top: 2rem;
}
.globe-wrap {
  position: relative;
  border-radius: var(--radius-lg);
  overflow: hidden;
  background: linear-gradient(145deg, #f0ddd0, #fdf0e8);
  box-shadow: var(--shadow-lg);
}
#globe-container {
  width: 100%;
  height: 520px;
  display: block;
}
#globe-container canvas { display: block; }
.globe-loading {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 1rem;
  background: linear-gradient(145deg, #f0ddd0, #fdf0e8);
  font-size: .9rem;
  color: var(--brown-mid);
  transition: opacity .4s;
}
.globe-loading.hidden { opacity: 0; pointer-events: none; }
.globe-loading-spinner {
  width: 36px;
  height: 36px;
  border: 3px solid rgba(200,90,58,.2);
  border-top-color: var(--terra);
  border-radius: 50%;
  animation: spin .8s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* ——— Globe Sidebar ——— */
.globe-sidebar {
  display: flex;
  flex-direction: column;
  gap: 1.5rem;
}
.sidebar-section {
  background: var(--white);
  border-radius: var(--radius-md);
  padding: 1.4rem;
  box-shadow: var(--shadow-sm);
}
.sidebar-heading {
  font-family: var(--font-sans);
  font-size: .78rem;
  font-weight: 700;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--brown-light);
  margin-bottom: 1rem;
}
.filter-pills {
  display: flex;
  flex-wrap: wrap;
  gap: .5rem;
}
.pill {
  display: inline-flex;
  align-items: center;
  padding: .35rem .9rem;
  border-radius: var(--radius-lg);
  font-size: .8rem;
  font-weight: 600;
  background: var(--cream-warm);
  color: var(--brown-mid);
  border: 1.5px solid transparent;
  transition: all .15s;
}
.pill:hover { border-color: var(--terra-light); color: var(--terra); }
.pill-active {
  background: var(--terra);
  color: var(--white);
  border-color: var(--terra);
}
.pill-active:hover { background: var(--terra-dark); border-color: var(--terra-dark); color: var(--white); }

.sidebar-hint {
  display: flex;
  align-items: center;
  gap: .6rem;
  padding: .9rem 1rem;
  background: var(--cream-warm);
  border-radius: var(--radius-md);
  font-size: .82rem;
  color: var(--brown-mid);
}
.sidebar-hint svg { width: 18px; height: 18px; fill: var(--terra-light); flex-shrink: 0; }

.episode-preview {
  background: var(--white);
  border-radius: var(--radius-md);
  padding: 1.4rem;
  box-shadow: var(--shadow-sm);
  min-height: 160px;
  display: flex;
  flex-direction: column;
  justify-content: center;
}
.episode-preview-placeholder {
  text-align: center;
  color: var(--brown-light);
  font-size: .88rem;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: .7rem;
}
.preview-globe-icon { font-size: 2rem; opacity: .4; }
.episode-preview-card { display: flex; flex-direction: column; gap: .6rem; }
.preview-ep-num {
  font-size: .75rem;
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--terra);
}
.preview-ep-title {
  font-family: var(--font-serif);
  font-size: 1.1rem;
  font-weight: 600;
  color: var(--brown);
  line-height: 1.2;
}
.preview-ep-countries {
  font-size: .82rem;
  color: var(--brown-mid);
  display: flex;
  align-items: center;
  gap: .4rem;
}
.preview-ep-countries::before { content: '📍'; }
.preview-ep-summary {
  font-size: .85rem;
  color: var(--brown-mid);
  line-height: 1.5;
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.preview-ep-cta {
  margin-top: .4rem;
}

/* ——— EPISODES SECTION ——— */
.episodes-section { background: var(--cream); }
.episodes-filter-row {
  display: flex;
  flex-wrap: wrap;
  gap: .5rem;
  margin-bottom: 2rem;
}
.episodes-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
  gap: 1.5rem;
}
.episodes-loading { color: var(--brown-mid); font-size: .9rem; }

.ep-card {
  background: var(--white);
  border-radius: var(--radius-md);
  padding: 1.5rem;
  box-shadow: var(--shadow-sm);
  border: 1.5px solid transparent;
  cursor: pointer;
  transition: all .2s ease;
  display: flex;
  flex-direction: column;
  gap: .7rem;
}
.ep-card:hover {
  box-shadow: var(--shadow-md);
  border-color: var(--terra-light);
  transform: translateY(-2px);
}
.ep-card-num {
  font-size: .75rem;
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--terra);
}
.ep-card-title {
  font-family: var(--font-serif);
  font-size: 1.15rem;
  font-weight: 600;
  color: var(--brown);
  line-height: 1.25;
}
.ep-card-countries {
  font-size: .82rem;
  color: var(--brown-mid);
  display: flex;
  align-items: center;
  gap: .4rem;
  flex-wrap: wrap;
}
.ep-card-flag {
  display: inline-block;
  background: var(--cream-warm);
  border-radius: var(--radius-sm);
  padding: .15rem .5rem;
  font-size: .78rem;
  font-weight: 600;
  color: var(--brown-mid);
}
.ep-card-tags {
  display: flex;
  flex-wrap: wrap;
  gap: .35rem;
}
.ep-tag {
  font-size: .72rem;
  font-weight: 600;
  padding: .15rem .6rem;
  background: var(--cream-warm);
  border-radius: var(--radius-lg);
  color: var(--brown-light);
  text-transform: capitalize;
}
.ep-card-summary {
  font-size: .85rem;
  color: var(--brown-mid);
  line-height: 1.55;
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
  flex: 1;
}
.ep-card-link {
  font-size: .82rem;
  font-weight: 700;
  color: var(--terra);
  margin-top: auto;
}
.ep-card.hidden { display: none; }

/* ——— OFFERS ——— */
.offers-section { padding-block: 5rem; }
.offers-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
  gap: 1.5rem;
  margin-top: 2rem;
}
.offer-card {
  display: flex;
  flex-direction: column;
  gap: .9rem;
  background: var(--white);
  border-radius: var(--radius-md);
  padding: 2rem 1.6rem;
  box-shadow: var(--shadow-sm);
  border: 1.5px solid transparent;
  transition: all .2s;
}
.offer-card:hover {
  box-shadow: var(--shadow-md);
  border-color: var(--terra-light);
  transform: translateY(-2px);
}
.offer-card--primary {
  background: linear-gradient(145deg, #c85a3a, #a0432a);
  color: var(--white);
}
.offer-card--primary h3,
.offer-card--primary p,
.offer-card--primary .offer-cta { color: var(--white); }
.offer-card--primary:hover { border-color: transparent; }
.offer-icon {
  width: 44px;
  height: 44px;
  background: var(--cream-warm);
  border-radius: var(--radius-md);
  display: flex;
  align-items: center;
  justify-content: center;
}
.offer-card--primary .offer-icon { background: rgba(255,255,255,.2); }
.offer-icon svg {
  width: 22px;
  height: 22px;
  stroke: var(--terra);
  fill: none;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.offer-card--primary .offer-icon svg { stroke: var(--white); }
.offer-card h3 { font-family: var(--font-serif); font-size: 1.2rem; }
.offer-card p { font-size: .88rem; color: var(--brown-mid); line-height: 1.55; }
.offer-cta {
  font-size: .85rem;
  font-weight: 700;
  color: var(--terra);
  margin-top: auto;
}

/* ——— ABOUT ——— */
.about-section { background: var(--white); }
.about-layout {
  display: grid;
  grid-template-columns: 220px 1fr;
  gap: 4rem;
  align-items: center;
}
.about-portrait-wrap {
  position: relative;
  width: 180px;
  margin: 0 auto;
}
.about-portrait-placeholder {
  width: 180px;
  height: 180px;
  border-radius: 50%;
  background: linear-gradient(145deg, var(--cream-deep), var(--cream-warm));
  display: flex;
  align-items: center;
  justify-content: center;
  border: 3px solid var(--cream-deep);
}
.portrait-initials {
  font-family: var(--font-serif);
  font-size: 3rem;
  font-weight: 600;
  color: var(--terra);
}
.about-portrait-ring {
  position: absolute;
  inset: -12px;
  border-radius: 50%;
  border: 1.5px solid rgba(200,90,58,.2);
  pointer-events: none;
}
.about-portrait-ring--2 {
  inset: -24px;
  border-color: rgba(200,90,58,.1);
}
.about-content { display: flex; flex-direction: column; gap: 1rem; }
.about-lead { font-size: 1.1rem; font-weight: 400; color: var(--brown-mid); }
.about-links { display: flex; gap: .8rem; flex-wrap: wrap; margin-top: .5rem; }

/* ——— FINAL CTA ——— */
.final-cta {
  padding-block: 6rem;
  text-align: center;
}
.final-cta-inner {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1.2rem;
}
.final-cta-ornament {
  font-size: 2rem;
  color: var(--terra-light);
}
.final-cta h2 { max-width: 18ch; }
.final-cta p {
  font-size: 1.05rem;
  color: var(--brown-mid);
  max-width: 52ch;
  margin-inline: auto;
}
.final-cta-buttons {
  display: flex;
  gap: .8rem;
  flex-wrap: wrap;
  justify-content: center;
  margin-top: .6rem;
}

/* ——— FOOTER ——— */
.site-footer {
  background: var(--brown);
  color: rgba(253,248,243,.8);
  padding-top: 4rem;
}
.footer-inner {
  display: grid;
  grid-template-columns: 220px 1fr;
  gap: 4rem;
  padding-bottom: 3rem;
  border-bottom: 1px solid rgba(253,248,243,.12);
}
.footer-brand { display: flex; flex-direction: column; gap: 1rem; }
.footer-brand .logo-title { color: rgba(253,248,243,.9); }
.footer-brand .logo-sub { color: var(--terra-light); }
.footer-tagline { font-size: .9rem; color: rgba(253,248,243,.6); }
.footer-links { display: grid; grid-template-columns: repeat(3, 1fr); gap: 2rem; }
.footer-col h4 {
  font-family: var(--font-sans);
  font-size: .78rem;
  font-weight: 700;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: rgba(253,248,243,.5);
  margin-bottom: 1rem;
}
.footer-col li + li { margin-top: .6rem; }
.footer-col a {
  font-size: .88rem;
  color: rgba(253,248,243,.75);
  transition: color .15s;
}
.footer-col a:hover { color: var(--terra-light); }
.footer-bottom {
  padding: 1.2rem 0;
}
.footer-bottom p {
  font-size: .8rem;
  color: rgba(253,248,243,.4);
  text-align: center;
}

/* ——— MODAL ——— */
.modal-overlay {
  position: fixed;
  inset: 0;
  background: rgba(44,24,16,.55);
  backdrop-filter: blur(6px);
  z-index: 200;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1.5rem;
  opacity: 0;
  pointer-events: none;
  transition: opacity .25s;
}
.modal-overlay.open {
  opacity: 1;
  pointer-events: all;
}
.modal-box {
  background: var(--cream);
  border-radius: var(--radius-lg);
  width: min(560px, 100%);
  max-height: 90vh;
  overflow-y: auto;
  padding: 2.5rem;
  position: relative;
  box-shadow: var(--shadow-lg);
  transform: translateY(20px) scale(.97);
  transition: transform .25s;
}
.modal-overlay.open .modal-box { transform: none; }
.modal-close {
  position: absolute;
  top: 1rem;
  right: 1rem;
  width: 36px;
  height: 36px;
  border-radius: 50%;
  background: var(--cream-warm);
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background .15s;
}
.modal-close:hover { background: var(--cream-deep); }
.modal-close svg {
  width: 16px;
  height: 16px;
  stroke: var(--brown-mid);
  fill: none;
  stroke-width: 2.5;
  stroke-linecap: round;
}
.modal-ep-num {
  font-size: .78rem;
  font-weight: 700;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--terra);
  margin-bottom: .5rem;
}
.modal-title {
  font-family: var(--font-serif);
  font-size: 1.6rem;
  color: var(--brown);
  line-height: 1.2;
  margin-bottom: .8rem;
}
.modal-countries {
  font-size: .9rem;
  color: var(--brown-mid);
  display: flex;
  align-items: center;
  gap: .6rem;
  flex-wrap: wrap;
  margin-bottom: .8rem;
}
.modal-divider {
  height: 1px;
  background: var(--cream-deep);
  margin: 1.2rem 0;
}
.modal-summary {
  font-size: .95rem;
  color: var(--brown-mid);
  line-height: 1.65;
  margin-bottom: 1.5rem;
}
.modal-tags {
  display: flex;
  flex-wrap: wrap;
  gap: .4rem;
  margin-bottom: 1.5rem;
}
.modal-actions { display: flex; gap: .8rem; flex-wrap: wrap; }

/* ——— RESPONSIVE ——— */
@media (max-width: 900px) {
  .discover-layout { grid-template-columns: 1fr; }
  #globe-container { height: 380px; }
  .about-layout { grid-template-columns: 1fr; gap: 2rem; text-align: center; }
  .about-portrait-wrap { margin: 0 auto; }
  .about-links { justify-content: center; }
  .footer-inner { grid-template-columns: 1fr; gap: 2.5rem; }
  .footer-links { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 620px) {
  section { padding-block: 3.5rem; }
  h1 { font-size: 2.2rem; }
  h2 { font-size: 1.7rem; }
  .hero { padding-block: 4.5rem 3.5rem; }
  .hero-ctas { flex-direction: column; }
  .hero-ctas .btn { justify-content: center; }
  .trust-inner { gap: .8rem 1.2rem; }
  .trust-divider { display: none; }
  .site-nav ul { display: none; }
  .nav-toggle { display: flex; }
  .site-nav.open ul {
    display: flex;
    flex-direction: column;
    position: fixed;
    inset: 64px 0 0;
    background: var(--cream);
    padding: 2rem;
    gap: 1.2rem;
    z-index: 99;
  }
  .site-nav.open ul a { font-size: 1.2rem; }
  .footer-links { grid-template-columns: 1fr 1fr; }
}

+  background: linear-gradient(145deg, #f0ddd0, #fdf0e8);

-#globe-container canvas { display: block; }


Also fix the loader positioning since it's now inside the map container, not a sibling:


.globe-loading {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 1rem;
  background: linear-gradient(145deg, #f0ddd0, #fdf0e8);
  font-size: .9rem;
  color: var(--brown-mid);
  transition: opacity .4s;
}
.globe-loading.hidden { opacity: 0; pointer-events: none; }

.globe-loading {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 1rem;
  padding: 4rem 2rem;
  font-size: .9rem;
  color: var(--brown-mid);
  transition: opacity .3s;
}
.globe-loading.hidden { display: none; }


.globe-loading {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 1rem;
  padding: 4rem 2rem;
  font-size: .9rem;
  color: var(--brown-mid);
  transition: opacity .3s;
}
.globe-loading.hidden { display: none; }

/* ===================================================
   International Love Story — Styles
   Design: warm, editorial, feminine
   =================================================== */

:root {
  --cream:       #fdf8f3;
  --cream-warm:  #f7ede3;
  --cream-deep:  #f0ddd0;
  --terra:       #c85a3a;
  --terra-dark:  #a0432a;
  --terra-light: #e8896e;
  --brown:       #2c1810;
  --brown-mid:   #5c3d2e;
  --brown-light: #8b6558;
  --olive:       #6b7c5e;
  --sage:        #c8d5be;
  --gold:        #c49a5a;
  --white:       #ffffff;

  --font-serif: 'Cormorant Garamond', Georgia, serif;
  --font-sans:  'Lato', system-ui, sans-serif;

  --radius-sm:  6px;
  --radius-md:  14px;
  --radius-lg:  28px;
  --radius-xl:  48px;

  --shadow-sm:  0 1px 4px rgba(44,24,16,.07);
  --shadow-md:  0 4px 20px rgba(44,24,16,.10);
  --shadow-lg:  0 12px 40px rgba(44,24,16,.14);

  --container:  1140px;
  --gap:        2rem;
}

/* ——— Reset & Base ——— */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
html { scroll-behavior: smooth; font-size: 16px; }
body {
  font-family: var(--font-sans);
  background: var(--cream);
  color: var(--brown);
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
}
img, svg { display: block; max-width: 100%; }
a { color: inherit; text-decoration: none; }
button { cursor: pointer; border: none; background: none; font: inherit; color: inherit; }
ul { list-style: none; }

/* ——— Typography ——— */
h1, h2, h3, h4 {
  font-family: var(--font-serif);
  line-height: 1.15;
  font-weight: 600;
  color: var(--brown);
}
h1 { font-size: clamp(2.4rem, 5vw, 3.8rem); }
h2 { font-size: clamp(1.9rem, 3.5vw, 2.8rem); }
h3 { font-size: 1.35rem; }
h4 { font-size: 1rem; }
h1 em, h2 em { font-style: italic; color: var(--terra); }
p { max-width: 68ch; }

/* ——— Layout ——— */
.container {
  width: min(var(--container), calc(100% - 2.5rem));
  margin-inline: auto;
}
section { padding-block: 5rem; }
.section-warm { background: var(--cream-warm); }

/* ——— Section headers ——— */
.section-header { margin-bottom: 2.5rem; }
.section-header.centered { text-align: center; }
.section-header.centered p { margin-inline: auto; }
.section-eyebrow {
  font-family: var(--font-sans);
  font-size: .78rem;
  font-weight: 700;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--terra);
  margin-bottom: .6rem;
}
.section-intro {
  font-size: 1.05rem;
  color: var(--brown-mid);
  margin-top: .8rem;
}

/* ——— Buttons ——— */
.btn {
  display: inline-flex;
  align-items: center;
  gap: .5rem;
  font-family: var(--font-sans);
  font-weight: 700;
  font-size: .9rem;
  letter-spacing: .03em;
  padding: .65rem 1.4rem;
  border-radius: var(--radius-lg);
  transition: all .2s ease;
  white-space: nowrap;
}
.btn svg { width: 1em; height: 1em; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.btn-lg  { padding: .85rem 1.8rem; font-size: 1rem; }
.btn-sm  { padding: .45rem 1rem;   font-size: .82rem; }

.btn-primary {
  background: var(--terra);
  color: var(--white);
  box-shadow: 0 2px 12px rgba(200,90,58,.30);
}
.btn-primary:hover { background: var(--terra-dark); box-shadow: 0 4px 20px rgba(200,90,58,.40); transform: translateY(-1px); }

.btn-secondary {
  background: var(--cream-deep);
  color: var(--brown);
  border: 1.5px solid var(--cream-deep);
}
.btn-secondary:hover { background: var(--cream-warm); border-color: var(--terra-light); }

.btn-ghost {
  background: transparent;
  color: var(--brown-mid);
  border: 1.5px solid rgba(44,24,16,.20);
}
.btn-ghost:hover { border-color: var(--terra); color: var(--terra); }

/* ——— HEADER ——— */
.site-header {
  position: sticky;
  top: 0;
  z-index: 100;
  background: rgba(253,248,243,.92);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid rgba(200,90,58,.12);
}
.header-inner {
  display: flex;
  align-items: center;
  gap: 2rem;
  height: 64px;
}
.logo {
  display: flex;
  align-items: center;
  gap: .7rem;
  flex-shrink: 0;
}
.logo-icon {
  font-size: 1.4rem;
  color: var(--terra);
  line-height: 1;
}
.logo-text {
  display: flex;
  flex-direction: column;
  line-height: 1.1;
}
.logo-title {
  font-family: var(--font-serif);
  font-weight: 600;
  font-size: 1.05rem;
  color: var(--brown);
}
.logo-sub {
  font-family: var(--font-serif);
  font-style: italic;
  font-size: .88rem;
  color: var(--terra);
}
.site-nav {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: 1.6rem;
}
.site-nav ul {
  display: flex;
  gap: 1.4rem;
}
.site-nav a {
  font-size: .9rem;
  font-weight: 600;
  color: var(--brown-mid);
  transition: color .15s;
}
.site-nav a:hover { color: var(--terra); }
.nav-toggle { display: none; flex-direction: column; gap: 5px; padding: .4rem; }
.nav-toggle span { display: block; width: 22px; height: 2px; background: var(--brown); border-radius: 2px; transition: .2s; }

/* ——— HERO ——— */
.hero {
  position: relative;
  overflow: hidden;
  padding-block: 7rem 5rem;
  background: linear-gradient(145deg, #fdf8f3 0%, #f7ede3 50%, #f0ddd0 100%);
}
.hero-bg-orbs { position: absolute; inset: 0; pointer-events: none; }
.orb {
  position: absolute;
  border-radius: 50%;
  filter: blur(60px);
  opacity: .45;
}
.orb-1 { width: 400px; height: 400px; background: radial-gradient(circle, #e8896e 0%, transparent 70%); top: -100px; right: -100px; }
.orb-2 { width: 300px; height: 300px; background: radial-gradient(circle, #c49a5a 0%, transparent 70%); bottom: -80px; left: 10%; }
.orb-3 { width: 200px; height: 200px; background: radial-gradient(circle, #c8d5be 0%, transparent 70%); top: 30%; left: -60px; }

.hero-content {
  position: relative;
  z-index: 1;
  max-width: 720px;
}
.hero-eyebrow {
  font-size: .82rem;
  font-weight: 700;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--terra);
  margin-bottom: 1rem;
  padding: .35rem .9rem;
  background: rgba(200,90,58,.1);
  border-radius: var(--radius-lg);
  display: inline-block;
}
.hero-headline {
  margin-bottom: 1.2rem;
  color: var(--brown);
}
.hero-subheadline {
  font-size: clamp(1.05rem, 2vw, 1.25rem);
  color: var(--brown-mid);
  margin-bottom: 2rem;
  max-width: 52ch;
}
.hero-ctas {
  display: flex;
  flex-wrap: wrap;
  gap: .8rem;
  margin-bottom: 2.5rem;
}
.spotify-icon { width: 1.1em; height: 1.1em; fill: currentColor; stroke: none; }
.hero-scroll-hint {
  display: flex;
  align-items: center;
  gap: .5rem;
  font-size: .82rem;
  color: var(--brown-light);
}
.hero-scroll-hint svg { width: 16px; height: 16px; stroke: currentColor; fill: none; stroke-width: 2; stroke-linecap: round; }

/* ——— TRUST STRIP ——— */
.trust-strip {
  background: var(--brown);
  padding: 1.4rem 0;
}
.trust-inner {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  gap: 1rem 2rem;
}
.trust-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: .2rem;
  text-align: center;
}
.trust-number {
  font-family: var(--font-serif);
  font-size: 1.6rem;
  font-weight: 600;
  color: var(--terra-light);
}
.trust-label {
  font-size: .75rem;
  font-weight: 600;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: rgba(253,248,243,.65);
}
.trust-divider {
  width: 1px;
  height: 36px;
  background: rgba(253,248,243,.2);
}

/* ——— DISCOVER / GLOBE ——— */
.discover-section { padding-block: 5rem; }
.discover-layout {
  display: grid;
  grid-template-columns: 1fr 320px;
  gap: 2.5rem;
  align-items: start;
  margin-top: 2rem;
}
.globe-wrap {
  position: relative;
  border-radius: var(--radius-lg);
  overflow: hidden;
  background: linear-gradient(145deg, #f0ddd0, #fdf0e8);
  box-shadow: var(--shadow-lg);
}
#map-container {
  position: relative;
  width: 100%;
  min-height: 260px;
  border-radius: var(--radius-lg);
  overflow: hidden;
  background: linear-gradient(145deg, #f0ddd0, #fdf0e8);
  box-shadow: var(--shadow-lg);
}
#map-container svg {
  display: block;
  width: 100%;
  height: auto;
}
.globe-loading {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 1rem;
  background: linear-gradient(145deg, #f0ddd0, #fdf0e8);
  font-size: .9rem;
  color: var(--brown-mid);
  transition: opacity .4s;
}
.globe-loading.hidden { opacity: 0; pointer-events: none; }
.globe-loading-spinner {
  width: 36px;
  height: 36px;
  border: 3px solid rgba(200,90,58,.2);
  border-top-color: var(--terra);
  border-radius: 50%;
  animation: spin .8s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* ——— Globe Sidebar ——— */
.globe-sidebar {
  display: flex;
  flex-direction: column;
  gap: 1.5rem;
}
.sidebar-section {
  background: var(--white);
  border-radius: var(--radius-md);
  padding: 1.4rem;
  box-shadow: var(--shadow-sm);
}
.sidebar-heading {
  font-family: var(--font-sans);
  font-size: .78rem;
  font-weight: 700;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--brown-light);
  margin-bottom: 1rem;
}
.filter-pills {
  display: flex;
  flex-wrap: wrap;
  gap: .5rem;
}
.pill {
  display: inline-flex;
  align-items: center;
  padding: .35rem .9rem;
  border-radius: var(--radius-lg);
  font-size: .8rem;
  font-weight: 600;
  background: var(--cream-warm);
  color: var(--brown-mid);
  border: 1.5px solid transparent;
  transition: all .15s;
}
.pill:hover { border-color: var(--terra-light); color: var(--terra); }
.pill-active {
  background: var(--terra);
  color: var(--white);
  border-color: var(--terra);
}
.pill-active:hover { background: var(--terra-dark); border-color: var(--terra-dark); color: var(--white); }

.sidebar-hint {
  display: flex;
  align-items: center;
  gap: .6rem;
  padding: .9rem 1rem;
  background: var(--cream-warm);
  border-radius: var(--radius-md);
  font-size: .82rem;
  color: var(--brown-mid);
}
.sidebar-hint svg { width: 18px; height: 18px; fill: var(--terra-light); flex-shrink: 0; }

.episode-preview {
  background: var(--white);
  border-radius: var(--radius-md);
  padding: 1.4rem;
  box-shadow: var(--shadow-sm);
  min-height: 160px;
  display: flex;
  flex-direction: column;
  justify-content: center;
}
.episode-preview-placeholder {
  text-align: center;
  color: var(--brown-light);
  font-size: .88rem;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: .7rem;
}
.preview-globe-icon { font-size: 2rem; opacity: .4; }
.episode-preview-card { display: flex; flex-direction: column; gap: .6rem; }
.preview-ep-num {
  font-size: .75rem;
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--terra);
}
.preview-ep-title {
  font-family: var(--font-serif);
  font-size: 1.1rem;
  font-weight: 600;
  color: var(--brown);
  line-height: 1.2;
}
.preview-ep-countries {
  font-size: .82rem;
  color: var(--brown-mid);
  display: flex;
  align-items: center;
  gap: .4rem;
}
.preview-ep-countries::before { content: '📍'; }
.preview-ep-summary {
  font-size: .85rem;
  color: var(--brown-mid);
  line-height: 1.5;
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.preview-ep-cta {
  margin-top: .4rem;
}

/* ——— EPISODES SECTION ——— */
.episodes-section { background: var(--cream); }
.episodes-filter-row {
  display: flex;
  flex-wrap: wrap;
  gap: .5rem;
  margin-bottom: 2rem;
}
.episodes-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
  gap: 1.5rem;
}
.episodes-loading { color: var(--brown-mid); font-size: .9rem; }

.ep-card {
  background: var(--white);
  border-radius: var(--radius-md);
  padding: 1.5rem;
  box-shadow: var(--shadow-sm);
  border: 1.5px solid transparent;
  cursor: pointer;
  transition: all .2s ease;
  display: flex;
  flex-direction: column;
  gap: .7rem;
}
.ep-card:hover {
  box-shadow: var(--shadow-md);
  border-color: var(--terra-light);
  transform: translateY(-2px);
}
.ep-card-num {
  font-size: .75rem;
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--terra);
}
.ep-card-title {
  font-family: var(--font-serif);
  font-size: 1.15rem;
  font-weight: 600;
  color: var(--brown);
  line-height: 1.25;
}
.ep-card-countries {
  font-size: .82rem;
  color: var(--brown-mid);
  display: flex;
  align-items: center;
  gap: .4rem;
  flex-wrap: wrap;
}
.ep-card-flag {
  display: inline-block;
  background: var(--cream-warm);
  border-radius: var(--radius-sm);
  padding: .15rem .5rem;
  font-size: .78rem;
  font-weight: 600;
  color: var(--brown-mid);
}
.ep-card-tags {
  display: flex;
  flex-wrap: wrap;
  gap: .35rem;
}
.ep-tag {
  font-size: .72rem;
  font-weight: 600;
  padding: .15rem .6rem;
  background: var(--cream-warm);
  border-radius: var(--radius-lg);
  color: var(--brown-light);
  text-transform: capitalize;
}
.ep-card-summary {
  font-size: .85rem;
  color: var(--brown-mid);
  line-height: 1.55;
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
  flex: 1;
}
.ep-card-link {
  font-size: .82rem;
  font-weight: 700;
  color: var(--terra);
  margin-top: auto;
}
.ep-card.hidden { display: none; }

/* ——— OFFERS ——— */
.offers-section { padding-block: 5rem; }
.offers-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
  gap: 1.5rem;
  margin-top: 2rem;
}
.offer-card {
  display: flex;
  flex-direction: column;
  gap: .9rem;
  background: var(--white);
  border-radius: var(--radius-md);
  padding: 2rem 1.6rem;
  box-shadow: var(--shadow-sm);
  border: 1.5px solid transparent;
  transition: all .2s;
}
.offer-card:hover {
  box-shadow: var(--shadow-md);
  border-color: var(--terra-light);
  transform: translateY(-2px);
}
.offer-card--primary {
  background: linear-gradient(145deg, #c85a3a, #a0432a);
  color: var(--white);
}
.offer-card--primary h3,
.offer-card--primary p,
.offer-card--primary .offer-cta { color: var(--white); }
.offer-card--primary:hover { border-color: transparent; }
.offer-icon {
  width: 44px;
  height: 44px;
  background: var(--cream-warm);
  border-radius: var(--radius-md);
  display: flex;
  align-items: center;
  justify-content: center;
}
.offer-card--primary .offer-icon { background: rgba(255,255,255,.2); }
.offer-icon svg {
  width: 22px;
  height: 22px;
  stroke: var(--terra);
  fill: none;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.offer-card--primary .offer-icon svg { stroke: var(--white); }
.offer-card h3 { font-family: var(--font-serif); font-size: 1.2rem; }
.offer-card p { font-size: .88rem; color: var(--brown-mid); line-height: 1.55; }
.offer-cta {
  font-size: .85rem;
  font-weight: 700;
  color: var(--terra);
  margin-top: auto;
}

/* ——— ABOUT ——— */
.about-section { background: var(--white); }
.about-layout {
  display: grid;
  grid-template-columns: 220px 1fr;
  gap: 4rem;
  align-items: center;
}
.about-portrait-wrap {
  position: relative;
  width: 180px;
  margin: 0 auto;
}
.about-portrait-placeholder {
  width: 180px;
  height: 180px;
  border-radius: 50%;
  background: linear-gradient(145deg, var(--cream-deep), var(--cream-warm));
  display: flex;
  align-items: center;
  justify-content: center;
  border: 3px solid var(--cream-deep);
}
.portrait-initials {
  font-family: var(--font-serif);
  font-size: 3rem;
  font-weight: 600;
  color: var(--terra);
}
.about-portrait-ring {
  position: absolute;
  inset: -12px;
  border-radius: 50%;
  border: 1.5px solid rgba(200,90,58,.2);
  pointer-events: none;
}
.about-portrait-ring--2 {
  inset: -24px;
  border-color: rgba(200,90,58,.1);
}
.about-content { display: flex; flex-direction: column; gap: 1rem; }
.about-lead { font-size: 1.1rem; font-weight: 400; color: var(--brown-mid); }
.about-links { display: flex; gap: .8rem; flex-wrap: wrap; margin-top: .5rem; }

/* ——— FINAL CTA ——— */
.final-cta {
  padding-block: 6rem;
  text-align: center;
}
.final-cta-inner {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1.2rem;
}
.final-cta-ornament {
  font-size: 2rem;
  color: var(--terra-light);
}
.final-cta h2 { max-width: 18ch; }
.final-cta p {
  font-size: 1.05rem;
  color: var(--brown-mid);
  max-width: 52ch;
  margin-inline: auto;
}
.final-cta-buttons {
  display: flex;
  gap: .8rem;
  flex-wrap: wrap;
  justify-content: center;
  margin-top: .6rem;
}

/* ——— FOOTER ——— */
.site-footer {
  background: var(--brown);
  color: rgba(253,248,243,.8);
  padding-top: 4rem;
}
.footer-inner {
  display: grid;
  grid-template-columns: 220px 1fr;
  gap: 4rem;
  padding-bottom: 3rem;
  border-bottom: 1px solid rgba(253,248,243,.12);
}
.footer-brand { display: flex; flex-direction: column; gap: 1rem; }
.footer-brand .logo-title { color: rgba(253,248,243,.9); }
.footer-brand .logo-sub { color: var(--terra-light); }
.footer-tagline { font-size: .9rem; color: rgba(253,248,243,.6); }
.footer-links { display: grid; grid-template-columns: repeat(3, 1fr); gap: 2rem; }
.footer-col h4 {
  font-family: var(--font-sans);
  font-size: .78rem;
  font-weight: 700;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: rgba(253,248,243,.5);
  margin-bottom: 1rem;
}
.footer-col li + li { margin-top: .6rem; }
.footer-col a {
  font-size: .88rem;
  color: rgba(253,248,243,.75);
  transition: color .15s;
}
.footer-col a:hover { color: var(--terra-light); }
.footer-bottom {
  padding: 1.2rem 0;
}
.footer-bottom p {
  font-size: .8rem;
  color: rgba(253,248,243,.4);
  text-align: center;
}

/* ——— MODAL ——— */
.modal-overlay {
  position: fixed;
  inset: 0;
  background: rgba(44,24,16,.55);
  backdrop-filter: blur(6px);
  z-index: 200;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1.5rem;
  opacity: 0;
  pointer-events: none;
  transition: opacity .25s;
}
.modal-overlay.open {
  opacity: 1;
  pointer-events: all;
}
.modal-box {
  background: var(--cream);
  border-radius: var(--radius-lg);
  width: min(560px, 100%);
  max-height: 90vh;
  overflow-y: auto;
  padding: 2.5rem;
  position: relative;
  box-shadow: var(--shadow-lg);
  transform: translateY(20px) scale(.97);
  transition: transform .25s;
}
.modal-overlay.open .modal-box { transform: none; }
.modal-close {
  position: absolute;
  top: 1rem;
  right: 1rem;
  width: 36px;
  height: 36px;
  border-radius: 50%;
  background: var(--cream-warm);
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background .15s;
}
.modal-close:hover { background: var(--cream-deep); }
.modal-close svg {
  width: 16px;
  height: 16px;
  stroke: var(--brown-mid);
  fill: none;
  stroke-width: 2.5;
  stroke-linecap: round;
}
.modal-ep-num {
  font-size: .78rem;
  font-weight: 700;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--terra);
  margin-bottom: .5rem;
}
.modal-title {
  font-family: var(--font-serif);
  font-size: 1.6rem;
  color: var(--brown);
  line-height: 1.2;
  margin-bottom: .8rem;
}
.modal-countries {
  font-size: .9rem;
  color: var(--brown-mid);
  display: flex;
  align-items: center;
  gap: .6rem;
  flex-wrap: wrap;
  margin-bottom: .8rem;
}
.modal-divider {
  height: 1px;
  background: var(--cream-deep);
  margin: 1.2rem 0;
}
.modal-summary {
  font-size: .95rem;
  color: var(--brown-mid);
  line-height: 1.65;
  margin-bottom: 1.5rem;
}
.modal-tags {
  display: flex;
  flex-wrap: wrap;
  gap: .4rem;
  margin-bottom: 1.5rem;
}
.modal-actions { display: flex; gap: .8rem; flex-wrap: wrap; }

/* ——— RESPONSIVE ——— */
@media (max-width: 900px) {
  .discover-layout { grid-template-columns: 1fr; }
  #globe-container { height: 380px; }
  .about-layout { grid-template-columns: 1fr; gap: 2rem; text-align: center; }
  .about-portrait-wrap { margin: 0 auto; }
  .about-links { justify-content: center; }
  .footer-inner { grid-template-columns: 1fr; gap: 2.5rem; }
  .footer-links { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 620px) {
  section { padding-block: 3.5rem; }
  h1 { font-size: 2.2rem; }
  h2 { font-size: 1.7rem; }
  .hero { padding-block: 4.5rem 3.5rem; }
  .hero-ctas { flex-direction: column; }
  .hero-ctas .btn { justify-content: center; }
  .trust-inner { gap: .8rem 1.2rem; }
  .trust-divider { display: none; }
  .site-nav ul { display: none; }
  .nav-toggle { display: flex; }
  .site-nav.open ul {
    display: flex;
    flex-direction: column;
    position: fixed;
    inset: 64px 0 0;
    background: var(--cream);
    padding: 2rem;
    gap: 1.2rem;
    z-index: 99;
  }
  .site-nav.open ul a { font-size: 1.2rem; }
  .footer-links { grid-template-columns: 1fr 1fr; }
}

-  background: linear-gradient(145deg, #f0ddd0, #fdf0e8);

-.globe-loading.hidden { opacity: 0; pointer-events: none; }

+.globe-loading.hidden { display: none; }


Also update the mobile breakpoint — remove the old globe height override:


  .discover-layout { grid-template-columns: 1fr; }
  #globe-container { height: 380px; }

.discover-layout { grid-template-columns: 1fr; }