const SLIDES = [
{
  EN: {
    eyebrow: 'SERVICE · MANAGED SERVICES',
    title: ['Infrastructure', 'that doesn\u2019t', 'get in the way.'],
    italicWord: 'doesn\u2019t',
    body: 'Streamline business processes through automation, optimized IT infrastructure, and proactive system management\u2014reducing downtime and improving productivity.',
    metric: { value: '42%', label: 'Infra spend reduced' },
    secondary: { value: '2.1\u00d7', label: 'Throughput' }
  },
  DE: {
    eyebrow: 'SERVICE · MANAGED SERVICES',
    title: ['Infrastruktur,', 'die nicht im', 'Weg steht.'],
    italicWord: 'nicht',
    body: 'Optimieren Sie Gesch\u00e4ftsprozesse durch Automatisierung, eine optimierte IT-Infrastruktur und proaktives Systemmanagement \u2014 weniger Ausfallzeiten, h\u00f6here Produktivit\u00e4t.',
    metric: { value: '42%', label: 'Infrastrukturkosten reduziert' },
    secondary: { value: '2.1\u00d7', label: 'Durchsatz' }
  },
  diagram: 'constellation',
  tag: 'GLOBAL · 5 REGIONS',
},
{
  EN: {
    eyebrow: 'SERVICE · MEDICAL DEVICE INTEGRATION',
    title: ['Lab instruments, X-ray', 'systems and EMR/EHR,', 'finally talking.'],
    italicWord: 'finally',
    body: 'HL7, FHIR and DICOM integrations that connect lab analyzers, X-ray systems and EMR/EHR \u2014 automated, bidirectional, audit-ready.',
    metric: { value: '0', label: 'Manual errors' },
    secondary: { value: '2\u00d7', label: 'Faster turnaround' }
  },
  DE: {
    eyebrow: 'SERVICE · INTEGRATION MEDIZINTECHNIK',
    title: ['Laborger\u00e4te, R\u00f6ntgen-', 'systeme und EMR/EHR,', 'endlich verbunden.'],
    italicWord: 'endlich',
    body: 'HL7-, FHIR- und DICOM-Integrationen, die Laboranalyseger\u00e4te, R\u00f6ntgensysteme und EMR/EHR verbinden \u2014 automatisiert, bidirektional, audit-sicher.',
    metric: { value: '0', label: 'Manuelle Fehler' },
    secondary: { value: '2\u00d7', label: 'Schnellere Bearbeitung' }
  },
  diagram: 'signal-bridge',
  tag: 'HL7 / FHIR · LIVE',
},
{
  EN: {
    eyebrow: 'SERVICE · AI SOLUTIONS & SIMULATION',
    title: ['From complex data', 'to smart', 'decisions\u2014powered by AI.'],
    italicWord: 'smart',
    body: 'Address industry-specific challenges with customized AI models and simulation environments.',
    metric: { value: '6.4\u00d7', label: 'Faster simulation' },
    secondary: { value: 'GPU', label: 'Accelerated compute' }
  },
  DE: {
    eyebrow: 'SERVICE · KI-L\u00d6SUNGEN & SIMULATION',
    title: ['Von komplexen Daten', 'zu klugen', 'Entscheidungen \u2014 mit KI.'],
    italicWord: 'klugen',
    body: 'L\u00f6sen Sie branchenspezifische Herausforderungen mit ma\u00dfgeschneiderten KI-Modellen und Simulationsumgebungen.',
    metric: { value: '6.4\u00d7', label: 'Schnellere Simulation' },
    secondary: { value: 'GPU', label: 'Beschleunigte Rechenleistung' }
  },
  diagram: 'neural-pipeline',
  tag: 'INFERENCE · ACTIVE',
}];

/* ============================================================
   SCENE 1 — NETWORK CONSTELLATION
   ============================================================ */
function NetworkConstellation() {
  const W = 800, H = 600;
  const cx = 480, cy = 300;
  // Scattered constellation nodes
  const nodes = [
    {x: 220, y: 110, label: 'EU-WEST',  big: true},
    {x: 660, y: 120, label: 'US-EAST',  big: true},
    {x: 680, y: 410, label: 'APAC',     big: true},
    {x: 180, y: 300, label: 'CORE',     big: true},
    {x: 360, y: 80,  label: ''},
    {x: 540, y: 200, label: ''},
    {x: 720, y: 250, label: ''},
    {x: 280, y: 460, label: 'CDN'},
    {x: 500, y: 520, label: 'EDGE'},
    {x: 400, y: 410, label: ''},
    {x: 600, y: 480, label: ''},
    {x: 320, y: 210, label: ''},
  ];
  return (
    <svg viewBox={`0 0 ${W} ${H}`} preserveAspectRatio="xMidYMid slice" width="100%" height="100%" style={{display:'block'}}>
      <defs>
        <radialGradient id="ncBg" cx="60%" cy="50%" r="65%">
          <stop offset="0%" stopColor="#0F1A2E"/>
          <stop offset="100%" stopColor="#06080F"/>
        </radialGradient>
        <radialGradient id="ncCore" cx="50%" cy="50%" r="50%">
          <stop offset="0%" stopColor="#7CB4F0"/>
          <stop offset="100%" stopColor="#1E73D9"/>
        </radialGradient>
        <radialGradient id="ncGlow" cx="50%" cy="50%" r="50%">
          <stop offset="0%" stopColor="rgba(30,115,217,0.5)"/>
          <stop offset="100%" stopColor="rgba(30,115,217,0)"/>
        </radialGradient>
        <radialGradient id="ncGlowSoft" cx="50%" cy="50%" r="50%">
          <stop offset="0%" stopColor="rgba(30,115,217,0.18)"/>
          <stop offset="100%" stopColor="rgba(30,115,217,0)"/>
        </radialGradient>
        <pattern id="ncGrid" width="40" height="40" patternUnits="userSpaceOnUse">
          <path d="M 40 0 L 0 0 0 40" fill="none" stroke="rgba(255,255,255,0.05)" strokeWidth="0.6"/>
        </pattern>
      </defs>
      <rect width={W} height={H} fill="url(#ncBg)"/>
      <rect width={W} height={H} fill="url(#ncGrid)"/>

      {/* Drifting stars */}
      {Array.from({length: 60}).map((_, i) => {
        const sx = (i * 113) % W;
        const sy = (i * 197) % H;
        return (
          <circle key={`s-${i}`} cx={sx} cy={sy} r={0.6 + (i % 3) * 0.3} fill="rgba(255,255,255,0.4)">
            <animate attributeName="opacity" values="0.2;0.8;0.2"
              dur={`${2.5 + (i % 5)}s`} repeatCount="indefinite" begin={`${(i * 0.27) % 4}s`}/>
          </circle>
        );
      })}

      {/* Glow halo around core */}
      <circle cx={cx} cy={cy} r="200" fill="url(#ncGlowSoft)"/>

      {/* Connection lines core ↔ nodes */}
      {nodes.map((n, i) => (
        <line key={`l-${i}`} x1={cx} y1={cy} x2={n.x} y2={n.y}
          stroke={n.big ? "rgba(94,160,228,0.55)" : "rgba(255,255,255,0.14)"}
          strokeWidth={n.big ? 1 : 0.6}
          strokeDasharray={n.big ? "none" : "2 4"}>
          <animate attributeName="opacity" values={n.big ? "0.85;0.45;0.85" : "0.3;0.7;0.3"}
            dur={`${3.5 + (i % 4)}s`} repeatCount="indefinite" begin={`${(i * 0.25) % 3}s`}/>
        </line>
      ))}

      {/* Expanding pulse rings */}
      {[0, 1, 2].map(i => (
        <circle key={`r-${i}`} cx={cx} cy={cy} r="36" fill="none"
          stroke="rgba(30,115,217,0.4)" strokeWidth="1">
          <animate attributeName="r" values="36;160" dur="3.6s" repeatCount="indefinite" begin={`${i * 1.2}s`}/>
          <animate attributeName="opacity" values="0.7;0" dur="3.6s" repeatCount="indefinite" begin={`${i * 1.2}s`}/>
        </circle>
      ))}

      {/* Core */}
      <circle cx={cx} cy={cy} r="46" fill="url(#ncGlow)" opacity="0.7"/>
      <circle cx={cx} cy={cy} r="24" fill="url(#ncCore)" stroke="rgba(255,255,255,0.5)" strokeWidth="1"/>
      <circle cx={cx} cy={cy} r="7" fill="#fff" opacity="0.95"/>
      <text x={cx} y={cy + 60} textAnchor="middle" fontFamily="Geist Mono, monospace" fontSize="9" letterSpacing="0.18em" fill="#7CB4F0">CORE · LIVE</text>

      {/* Nodes */}
      {nodes.map((n, i) => (
        <g key={`n-${i}`}>
          {n.big && <circle cx={n.x} cy={n.y} r="18" fill="url(#ncGlow)" opacity="0.5"/>}
          <circle cx={n.x} cy={n.y} r={n.big ? 8 : 4}
            fill={n.big ? "#1E73D9" : "rgba(255,255,255,0.65)"}
            stroke={n.big ? "rgba(255,255,255,0.6)" : "none"} strokeWidth="1"/>
          {n.big && <circle cx={n.x} cy={n.y} r="3" fill="#fff"/>}
          {n.big && (
            <circle cx={n.x} cy={n.y} r="12" fill="none" stroke="rgba(30,115,217,0.6)" strokeWidth="1">
              <animate attributeName="r" values="12;22;12" dur="2.4s" repeatCount="indefinite" begin={`${i * 0.6}s`}/>
              <animate attributeName="opacity" values="0.8;0;0.8" dur="2.4s" repeatCount="indefinite" begin={`${i * 0.6}s`}/>
            </circle>
          )}
          {n.label && (
            <text x={n.x} y={n.y + 24} textAnchor="middle"
              fontFamily="Geist Mono, monospace" fontSize="8" fill="rgba(255,255,255,0.75)"
              letterSpacing="0.14em">{n.label}</text>
          )}
        </g>
      ))}

      {/* Data packets traveling along edges */}
      {[0, 1, 2, 3, 7, 8, 5, 6].map((nodeIdx, i) => {
        const n = nodes[nodeIdx];
        const reverse = i % 2 === 0;
        const dur = 2.4 + (i % 3) * 0.6;
        return (
          <circle key={`p-${i}`} r="2.8" fill="#7CB4F0">
            <animate attributeName="opacity" values="0;1;1;0"
              dur={`${dur}s`} repeatCount="indefinite" begin={`${i * 0.4}s`}/>
            <animateMotion dur={`${dur}s`} repeatCount="indefinite" begin={`${i * 0.4}s`}
              path={reverse
                ? `M ${n.x} ${n.y} L ${cx} ${cy}`
                : `M ${cx} ${cy} L ${n.x} ${n.y}`}/>
          </circle>
        );
      })}

      {/* Stat cards */}
      <g transform="translate(36, 36)">
        <rect width="138" height="74" rx="12" fill="rgba(255,255,255,0.04)" stroke="rgba(255,255,255,0.10)"/>
        <rect width="3" height="74" rx="0" fill="#1E73D9"/>
        <text x="16" y="26" fontFamily="Geist Mono, monospace" fontSize="9" letterSpacing="0.16em" fill="#929596">UPTIME</text>
        <text x="16" y="58" fontFamily="Geist, sans-serif" fontSize="26" fontWeight="500" fill="#fff">99.98%</text>
      </g>

      <g transform="translate(36, 126)">
        <rect width="138" height="56" rx="12" fill="rgba(255,255,255,0.04)" stroke="rgba(255,255,255,0.10)"/>
        <rect width="3" height="56" rx="0" fill="#3D7A66"/>
        <circle cx="120" cy="28" r="4" fill="#3D7A66"/>
        <circle cx="120" cy="28" r="4" fill="#3D7A66" opacity="0.5">
          <animate attributeName="r" values="4;10;4" dur="1.8s" repeatCount="indefinite"/>
          <animate attributeName="opacity" values="0.5;0;0.5" dur="1.8s" repeatCount="indefinite"/>
        </circle>
        <text x="16" y="22" fontFamily="Geist Mono, monospace" fontSize="9" letterSpacing="0.16em" fill="#929596">ALERTS</text>
        <text x="16" y="44" fontFamily="Geist, sans-serif" fontSize="18" fontWeight="500" fill="#fff">0</text>
      </g>

      <g transform="translate(626, 502)">
        <rect width="138" height="62" rx="12" fill="rgba(255,255,255,0.04)" stroke="rgba(255,255,255,0.10)"/>
        <rect width="3" height="62" rx="0" fill="#1E73D9"/>
        <text x="16" y="24" fontFamily="Geist Mono, monospace" fontSize="9" letterSpacing="0.16em" fill="#929596">REGIONS</text>
        <text x="16" y="50" fontFamily="Geist, sans-serif" fontSize="22" fontWeight="500" fill="#fff">5</text>
      </g>
    </svg>
  );
}

/* ============================================================
   SCENE 2 — SIGNAL BRIDGE (HL7 / FHIR)
   ============================================================ */
function SignalBridge() {
  const W = 800, H = 600;
  const LAB = ['Analyzer', 'Centrifuge', 'Sequencer', 'Imager'];
  const HOSP = ['EMR / EHR', 'LIS', 'PACS', 'HIS'];
  const cardW = 160, cardH = 64;
  const colYTop = 80, colGap = 90;
  const labX = 60;
  const hospX = W - 60 - cardW;
  const busX = W / 2 - 36, busW = 72;
  const busTop = 60, busBottom = H - 60;
  return (
    <svg viewBox={`0 0 ${W} ${H}`} preserveAspectRatio="xMidYMid slice" width="100%" height="100%" style={{display:'block'}}>
      <defs>
        <radialGradient id="sbBg" cx="50%" cy="50%" r="70%">
          <stop offset="0%" stopColor="#0E1828"/>
          <stop offset="100%" stopColor="#05070D"/>
        </radialGradient>
        <linearGradient id="sbBus" x1="0%" y1="0%" x2="0%" y2="100%">
          <stop offset="0%" stopColor="#1E73D9" stopOpacity="0.05"/>
          <stop offset="50%" stopColor="#1E73D9" stopOpacity="0.7"/>
          <stop offset="100%" stopColor="#1E73D9" stopOpacity="0.05"/>
        </linearGradient>
        <radialGradient id="sbBusGlow" cx="50%" cy="50%" r="50%">
          <stop offset="0%" stopColor="rgba(30,115,217,0.4)"/>
          <stop offset="100%" stopColor="rgba(30,115,217,0)"/>
        </radialGradient>
        <pattern id="sbGrid" width="36" height="36" patternUnits="userSpaceOnUse">
          <path d="M 36 0 L 0 0 0 36" fill="none" stroke="rgba(255,255,255,0.04)" strokeWidth="0.6"/>
        </pattern>
        <marker id="sbArrow" markerWidth="6" markerHeight="6" refX="5" refY="3" orient="auto">
          <path d="M0,0 L0,6 L6,3 z" fill="#7CB4F0"/>
        </marker>
      </defs>
      <rect width={W} height={H} fill="url(#sbBg)"/>
      <rect width={W} height={H} fill="url(#sbGrid)"/>

      {/* Bus glow */}
      <ellipse cx={W/2} cy={H/2} rx="200" ry={H/2} fill="url(#sbBusGlow)"/>

      {/* Bus pillar */}
      <rect x={busX} y={busTop} width={busW} height={busBottom - busTop} rx="14" fill="rgba(30,115,217,0.08)" stroke="rgba(30,115,217,0.35)" strokeWidth="1"/>
      <rect x={busX + busW/2 - 1.5} y={busTop} width="3" height={busBottom - busTop} fill="url(#sbBus)"/>

      {/* Bus header label */}
      <rect x={busX - 6} y={busTop - 20} width={busW + 12} height="36" rx="8" fill="#0A1326" stroke="rgba(30,115,217,0.5)" strokeWidth="1"/>
      <text x={W/2} y={busTop + 4} textAnchor="middle" fontFamily="Geist Mono, monospace" fontSize="10" letterSpacing="0.2em" fill="#7CB4F0">HL7 / FHIR</text>

      {/* Bus inner pulse */}
      {[0, 1, 2].map(i => (
        <circle key={`b-${i}`} cx={W/2} cy={busTop + (busBottom - busTop) * ((i + 1) / 4)}
          r="4" fill="#7CB4F0">
          <animate attributeName="opacity" values="0.3;1;0.3" dur="1.6s" repeatCount="indefinite" begin={`${i * 0.4}s`}/>
        </circle>
      ))}

      {/* Lab devices left column */}
      {LAB.map((name, i) => {
        const y = colYTop + i * colGap;
        const cy_ = y + cardH/2;
        return (
          <g key={name}>
            <rect x={labX} y={y} width={cardW} height={cardH} rx="10"
              fill="rgba(255,255,255,0.04)" stroke="rgba(255,255,255,0.10)"/>
            <rect x={labX} y={y} width="3" height={cardH} fill="#1E73D9"/>
            {/* LED */}
            <circle cx={labX + cardW - 18} cy={y + 16} r="4" fill="#3D7A66">
              <animate attributeName="opacity" values="0.4;1;0.4" dur="1.8s" repeatCount="indefinite" begin={`${i * 0.3}s`}/>
            </circle>
            <text x={labX + 16} y={y + 20} fontFamily="Geist Mono, monospace" fontSize="9"
              letterSpacing="0.14em" fill="#929596">LAB · 0{i+1}</text>
            <text x={labX + 16} y={y + 42} fontFamily="Geist, sans-serif" fontSize="14"
              fontWeight="500" fill="#fff">{name}</text>
            {/* Connection line to bus */}
            <line x1={labX + cardW} y1={cy_} x2={busX} y2={cy_}
              stroke="rgba(94,160,228,0.4)" strokeWidth="0.7" strokeDasharray="3 4">
              <animate attributeName="opacity" values="0.4;0.9;0.4" dur={`${3 + i * 0.3}s`} repeatCount="indefinite"/>
            </line>
            {/* Packet: lab → bus */}
            <g>
              <rect x="0" y="0" width="36" height="14" rx="3" fill="rgba(30,115,217,0.9)" stroke="#7CB4F0">
                <animateMotion dur="3.2s" repeatCount="indefinite" begin={`${i * 0.7}s`}
                  path={`M ${labX + cardW - 18} ${cy_ - 7} L ${busX - 24} ${cy_ - 7}`}/>
                <animate attributeName="opacity" values="0;1;1;0" dur="3.2s" repeatCount="indefinite" begin={`${i * 0.7}s`}/>
              </rect>
              <text fontFamily="Geist Mono, monospace" fontSize="7" fill="#fff" textAnchor="middle">
                <animateMotion dur="3.2s" repeatCount="indefinite" begin={`${i * 0.7}s`}
                  path={`M ${labX + cardW} ${cy_} L ${busX - 6} ${cy_}`}/>
                <animate attributeName="opacity" values="0;1;1;0" dur="3.2s" repeatCount="indefinite" begin={`${i * 0.7}s`}/>
                MSG
              </text>
            </g>
          </g>
        );
      })}

      {/* Hospital systems right column */}
      {HOSP.map((name, i) => {
        const y = colYTop + i * colGap;
        const cy_ = y + cardH/2;
        return (
          <g key={name}>
            <rect x={hospX} y={y} width={cardW} height={cardH} rx="10"
              fill="rgba(255,255,255,0.04)" stroke="rgba(255,255,255,0.10)"/>
            <rect x={hospX + cardW - 3} y={y} width="3" height={cardH} fill="#3D7A66"/>
            <circle cx={hospX + 18} cy={y + 16} r="4" fill="#3D7A66">
              <animate attributeName="opacity" values="0.4;1;0.4" dur="1.8s" repeatCount="indefinite" begin={`${0.4 + i * 0.3}s`}/>
            </circle>
            <text x={hospX + cardW - 16} y={y + 20} textAnchor="end" fontFamily="Geist Mono, monospace"
              fontSize="9" letterSpacing="0.14em" fill="#929596">HOSPITAL</text>
            <text x={hospX + cardW - 16} y={y + 42} textAnchor="end" fontFamily="Geist, sans-serif"
              fontSize="14" fontWeight="500" fill="#fff">{name}</text>
            {/* Connection */}
            <line x1={busX + busW} y1={cy_} x2={hospX} y2={cy_}
              stroke="rgba(94,160,228,0.4)" strokeWidth="0.7" strokeDasharray="3 4">
              <animate attributeName="opacity" values="0.4;0.9;0.4" dur={`${3 + i * 0.3}s`} repeatCount="indefinite" begin="1s"/>
            </line>
            {/* Packet: bus → hospital */}
            <g>
              <rect x="0" y="0" width="36" height="14" rx="3" fill="rgba(61,122,102,0.9)" stroke="rgba(124,180,164,0.8)">
                <animateMotion dur="3.2s" repeatCount="indefinite" begin={`${1.6 + i * 0.7}s`}
                  path={`M ${busX + busW + 6} ${cy_ - 7} L ${hospX - 24} ${cy_ - 7}`}/>
                <animate attributeName="opacity" values="0;1;1;0" dur="3.2s" repeatCount="indefinite" begin={`${1.6 + i * 0.7}s`}/>
              </rect>
            </g>
          </g>
        );
      })}

      {/* Throughput counter */}
      <g transform={`translate(${W/2 - 80}, ${H - 56})`}>
        <rect width="160" height="36" rx="10" fill="rgba(30,115,217,0.10)" stroke="rgba(30,115,217,0.4)"/>
        <text x="80" y="14" textAnchor="middle" fontFamily="Geist Mono, monospace" fontSize="8" letterSpacing="0.16em" fill="#7CB4F0">THROUGHPUT</text>
        <text x="80" y="30" textAnchor="middle" fontFamily="Geist, sans-serif" fontSize="13" fontWeight="500" fill="#fff">
          12,847 msg/min
        </text>
      </g>
    </svg>
  );
}

/* ============================================================
   SCENE 3 — NEURAL PIPELINE
   ============================================================ */
function NeuralPipeline() {
  const W = 800, H = 600;
  const layers = [
    { x: 120, n: 4, label: 'INPUT' },
    { x: 290, n: 6, label: 'HIDDEN' },
    { x: 460, n: 6, label: 'ATTN' },
    { x: 630, n: 3, label: 'OUTPUT' },
  ];
  const nodeR = 14;
  const getY = (count, idx) => H/2 - 110 + (idx - (count - 1) / 2) * 56;

  // Active path
  const active = [
    { layer: 0, node: 1 },
    { layer: 1, node: 2 },
    { layer: 2, node: 3 },
    { layer: 3, node: 1 },
  ];
  const isActiveNode = (li, ni) => active.some(p => p.layer === li && p.node === ni);
  const isActiveEdge = (li, ai, bi) => {
    const a = active.find(p => p.layer === li);
    const b = active.find(p => p.layer === li + 1);
    return a && b && a.node === ai && b.node === bi;
  };

  // Pre-compute random secondary edges with particles
  const particleEdges = [];
  for (let li = 0; li < layers.length - 1; li++) {
    const a = layers[li], b = layers[li + 1];
    for (let ai = 0; ai < a.n; ai++) {
      for (let bi = 0; bi < b.n; bi++) {
        if (((ai * 7 + bi * 11 + li * 13) % 6) === 0) { // sparse subset
          particleEdges.push({ li, ai, bi });
        }
      }
    }
  }

  return (
    <svg viewBox={`0 0 ${W} ${H}`} preserveAspectRatio="xMidYMid slice" width="100%" height="100%" style={{display:'block'}}>
      <defs>
        <radialGradient id="npBg" cx="50%" cy="40%" r="60%">
          <stop offset="0%" stopColor="#0F1A2E"/>
          <stop offset="100%" stopColor="#05070D"/>
        </radialGradient>
        <pattern id="npGrid" width="36" height="36" patternUnits="userSpaceOnUse">
          <path d="M 36 0 L 0 0 0 36" fill="none" stroke="rgba(255,255,255,0.04)" strokeWidth="0.6"/>
        </pattern>
        <radialGradient id="npNode" cx="35%" cy="35%" r="65%">
          <stop offset="0%" stopColor="#9BC4F4"/>
          <stop offset="100%" stopColor="#1E73D9"/>
        </radialGradient>
        <radialGradient id="npOutput" cx="35%" cy="35%" r="65%">
          <stop offset="0%" stopColor="#7CB4F0"/>
          <stop offset="100%" stopColor="#155EBA"/>
        </radialGradient>
        <linearGradient id="npFlow" x1="0%" y1="0%" x2="100%" y2="0%">
          <stop offset="0%" stopColor="#1E73D9" stopOpacity="0.9"/>
          <stop offset="100%" stopColor="#7CB4F0" stopOpacity="0.7"/>
        </linearGradient>
        <radialGradient id="npHalo" cx="50%" cy="50%" r="50%">
          <stop offset="0%" stopColor="rgba(30,115,217,0.18)"/>
          <stop offset="100%" stopColor="rgba(30,115,217,0)"/>
        </radialGradient>
        <filter id="npBlur" x="-30%" y="-30%" width="160%" height="160%">
          <feGaussianBlur stdDeviation="3"/>
        </filter>
      </defs>
      <rect width={W} height={H} fill="url(#npBg)"/>
      <rect width={W} height={H} fill="url(#npGrid)"/>

      {/* Soft halo behind network */}
      <ellipse cx={W/2} cy={H/2 - 60} rx="320" ry="200" fill="url(#npHalo)"/>

      {/* All edges (dim) */}
      {layers.slice(0, -1).map((la, li) => {
        const lb = layers[li + 1];
        return Array.from({length: la.n}).map((_, ai) =>
          Array.from({length: lb.n}).map((_, bi) => {
            const y1 = getY(la.n, ai);
            const y2 = getY(lb.n, bi);
            const active = isActiveEdge(li, ai, bi);
            if (active) return null;
            return (
              <line key={`e-${li}-${ai}-${bi}`}
                x1={la.x + nodeR} y1={y1}
                x2={lb.x - nodeR} y2={y2}
                stroke="rgba(255,255,255,0.10)" strokeWidth="0.5"/>
            );
          })
        );
      })}

      {/* Continuous particle flow on secondary edges */}
      {particleEdges.map(({ li, ai, bi }, i) => {
        const la = layers[li], lb = layers[li + 1];
        const y1 = getY(la.n, ai);
        const y2 = getY(lb.n, bi);
        const dur = 1.6 + (i % 5) * 0.4;
        return (
          <circle key={`pp-${i}`} r="1.8" fill="#7CB4F0">
            <animate attributeName="opacity" values="0;0.9;0.9;0"
              dur={`${dur}s`} repeatCount="indefinite" begin={`${(i * 0.13) % 2.5}s`}/>
            <animateMotion dur={`${dur}s`} repeatCount="indefinite" begin={`${(i * 0.13) % 2.5}s`}
              path={`M ${la.x + nodeR} ${y1} L ${lb.x - nodeR} ${y2}`}/>
          </circle>
        );
      })}

      {/* Active path edges */}
      {layers.slice(0, -1).map((la, li) => {
        const lb = layers[li + 1];
        const a = active.find(p => p.layer === li);
        const b = active.find(p => p.layer === li + 1);
        if (!a || !b) return null;
        const y1 = getY(la.n, a.node);
        const y2 = getY(lb.n, b.node);
        return (
          <g key={`ae-${li}`}>
            <line x1={la.x + nodeR} y1={y1} x2={lb.x - nodeR} y2={y2}
              stroke="#1E73D9" strokeWidth="3" opacity="0.25" filter="url(#npBlur)"/>
            <line x1={la.x + nodeR} y1={y1} x2={lb.x - nodeR} y2={y2}
              stroke="url(#npFlow)" strokeWidth="1.5"/>
            <circle r="4" fill="#fff">
              <animateMotion dur="1.8s" repeatCount="indefinite" begin={`${li * 0.45}s`}
                path={`M ${la.x + nodeR} ${y1} L ${lb.x - nodeR} ${y2}`}/>
              <animate attributeName="opacity" values="0;1;1;0" dur="1.8s" repeatCount="indefinite" begin={`${li * 0.45}s`}/>
            </circle>
          </g>
        );
      })}

      {/* Nodes */}
      {layers.map((la, li) => (
        Array.from({length: la.n}).map((_, ni) => {
          const y = getY(la.n, ni);
          const isOut = li === layers.length - 1;
          const act = isActiveNode(li, ni);
          return (
            <g key={`n-${li}-${ni}`}>
              {act && (
                <>
                  <circle cx={la.x} cy={y} r={nodeR + 14} fill="rgba(30,115,217,0.18)"/>
                  <circle cx={la.x} cy={y} r={nodeR + 6} fill="none" stroke="rgba(30,115,217,0.5)" strokeWidth="1">
                    <animate attributeName="r" values={`${nodeR + 6};${nodeR + 14};${nodeR + 6}`}
                      dur="2.2s" repeatCount="indefinite"/>
                    <animate attributeName="opacity" values="0.7;0.1;0.7" dur="2.2s" repeatCount="indefinite"/>
                  </circle>
                </>
              )}
              <circle cx={la.x} cy={y} r={nodeR}
                fill={act ? "url(#npNode)" : isOut ? "url(#npOutput)" : "rgba(20,30,50,0.9)"}
                stroke={act ? "#7CB4F0" : isOut ? "rgba(124,180,240,0.6)" : "rgba(255,255,255,0.20)"}
                strokeWidth={act || isOut ? 1.2 : 1}/>
              <circle cx={la.x - 3} cy={y - 3} r="3" fill={act || isOut ? "rgba(255,255,255,0.7)" : "rgba(255,255,255,0.15)"}/>
            </g>
          );
        })
      ))}

      {/* Layer labels */}
      {layers.map((la) => (
        <text key={la.label} x={la.x} y={70}
          textAnchor="middle" fontFamily="Geist Mono, monospace" fontSize="10"
          letterSpacing="0.18em" fill="#7CB4F0" fontWeight="500">{la.label}</text>
      ))}

      {/* Top-left status */}
      <g transform="translate(36, 100)">
        <text fontFamily="Geist Mono, monospace" fontSize="9" letterSpacing="0.14em" fill="#929596">INFERENCE</text>
        <g transform="translate(0, 14)">
          <circle cx="4" cy="4" r="4" fill="#3D7A66"/>
          <circle cx="4" cy="4" r="4" fill="#3D7A66" opacity="0.4">
            <animate attributeName="r" values="4;9;4" dur="1.6s" repeatCount="indefinite"/>
            <animate attributeName="opacity" values="0.5;0;0.5" dur="1.6s" repeatCount="indefinite"/>
          </circle>
          <text x="14" y="8" fontFamily="Geist, sans-serif" fontSize="12" fontWeight="500" fill="#fff">Active</text>
        </g>
      </g>

      {/* Speedup hero card */}
      <g transform={`translate(${W - 200}, 36)`}>
        <rect width="160" height="100" rx="14" fill="rgba(30,115,217,0.10)" stroke="rgba(30,115,217,0.45)"/>
        <text x="16" y="24" fontFamily="Geist Mono, monospace" fontSize="9" letterSpacing="0.16em" fill="#7CB4F0">SPEEDUP</text>
        <text x="16" y="68" fontFamily="Geist, sans-serif" fontSize="40" fontWeight="600" fill="#fff" letterSpacing="-0.02em">6.4×</text>
        <text x="16" y="86" fontFamily="Geist Mono, monospace" fontSize="8" letterSpacing="0.14em" fill="#929596">vs CPU baseline</text>
      </g>

      {/* Bottom oscilloscope waveform */}
      <g transform={`translate(36, ${H - 90})`}>
        <text fontFamily="Geist Mono, monospace" fontSize="9" letterSpacing="0.14em" fill="#929596">LATENCY · 24 ms</text>
        <g transform="translate(0, 14)">
          {Array.from({length: 60}).map((_, i) => {
            const h = 6 + Math.abs(Math.sin(i * 0.35) * 18) + (i % 4) * 1.5;
            const isAccent = i > 26 && i < 36;
            return (
              <rect key={i} x={i * 11} y={28 - h} width="4" height={h} rx="1.5"
                fill={isAccent ? "#7CB4F0" : "rgba(255,255,255,0.25)"}>
                <animate attributeName="height"
                  values={`${h};${h + 6};${h - 4};${h}`}
                  dur={`${1.4 + (i % 5) * 0.2}s`}
                  repeatCount="indefinite" begin={`${(i * 0.05) % 1.2}s`}/>
              </rect>
            );
          })}
        </g>
      </g>
    </svg>
  );
}

/* ============================================================
   SCENE SWITCHER
   ============================================================ */
function SlideScene({ kind }) {
  if (kind === 'constellation') return <NetworkConstellation/>;
  if (kind === 'signal-bridge') return <SignalBridge/>;
  if (kind === 'neural-pipeline') return <NeuralPipeline/>;
  return null;
}

/* ============================================================
   SLIDE CONTENT — cinematic split card
   ============================================================ */
function SlideContent({ slide, lang }) {
  const t = slide[lang] || slide.EN;
  return (
    <div className="gs-slide-inner" style={{
      width: '100%', height: '100%',
      display: 'grid',
      gridTemplateColumns: '1fr 1fr',
      gridTemplateAreas: '"copy scene"',
      background: '#0A0E18',
    }}>
      {/* Animated Scene panel */}
      <div className="gs-slide-scene-panel" style={{
        gridArea: 'scene',
        position: 'relative',
        overflow: 'hidden',
        borderLeft: '1px solid rgba(255,255,255,0.06)',
      }}>
        <SlideScene kind={slide.diagram}/>
        {/* Top-right tag */}
        <div className="gs-slide-livetag" style={{
          position: 'absolute', top: 22, right: 22,
          fontFamily: 'var(--font-mono)', fontSize: 10,
          letterSpacing: '0.16em',
          padding: '6px 12px', borderRadius: 999,
          background: 'rgba(30,115,217,0.14)',
          border: '1px solid rgba(30,115,217,0.4)',
          color: '#7CB4F0',
          display: 'inline-flex', alignItems: 'center', gap: 8,
          backdropFilter: 'blur(6px)', zIndex: 2,
        }}>
          <span style={{
            width: 6, height: 6, borderRadius: '50%', background: '#7CB4F0',
            boxShadow: '0 0 10px #1E73D9',
            animation: 'pulse 1.6s ease-in-out infinite',
          }}/>
          {slide.tag}
        </div>
        {/* Edge-fade for blend with copy */}
        <div style={{
          position: 'absolute', inset: 0,
          background: 'linear-gradient(90deg, rgba(10,14,24,0.6) 0%, rgba(10,14,24,0) 14%)',
          pointerEvents: 'none',
        }}/>
      </div>

      {/* Copy panel */}
      <div className="gs-slide-copy" style={{
        gridArea: 'copy',
        position: 'relative',
        padding: '60px 56px 56px',
        display: 'flex',
        flexDirection: 'column',
        justifyContent: 'center',
        color: '#fff',
      }}>
        {/* Eyebrow */}
        <div className="gs-slide-eyebrow" style={{
          fontFamily: 'var(--font-mono)',
          fontSize: 12,
          letterSpacing: '0.2em',
          color: '#7CB4F0',
          display: 'inline-flex', alignItems: 'center', gap: 10,
          marginBottom: 28,
        }}>
          <span style={{
            width: 6, height: 6, borderRadius: '50%', background: '#7CB4F0',
            boxShadow: '0 0 10px #1E73D9',
            animation: 'pulse 1.6s ease-in-out infinite',
          }}/>
          {t.eyebrow}
        </div>

        {/* Title */}
        <h2 className="gs-slide-title" style={{
          margin: 0,
          fontSize: 48,
          lineHeight: 1.05,
          letterSpacing: '-0.03em',
          fontWeight: 500,
          color: '#fff',
          maxWidth: 580,
        }}>
          {t.title.map((line, i) => {
            const parts = line.split(t.italicWord);
            if (parts.length === 2) {
              return (
                <span key={i} style={{ display: 'block' }}>
                  {parts[0]}
                  <span style={{
                    fontFamily: 'var(--font-serif)',
                    fontStyle: 'italic',
                    fontWeight: 400,
                    background: 'linear-gradient(90deg, #7CB4F0, #1E73D9)',
                    WebkitBackgroundClip: 'text',
                    WebkitTextFillColor: 'transparent',
                    backgroundClip: 'text',
                  }}>{t.italicWord}</span>
                  {parts[1]}
                </span>
              );
            }
            return <span key={i} style={{ display: 'block' }}>{line}</span>;
          })}
        </h2>

        {/* Body */}
        <p className="gs-slide-body" style={{
          margin: '24px 0 0',
          fontSize: 16,
          lineHeight: 1.65,
          color: 'rgba(255,255,255,0.65)',
          maxWidth: 540,
        }}>{t.body}</p>

        {/* Metrics + CTA */}
        <div className="gs-slide-footer" style={{
          marginTop: 36,
          paddingTop: 28,
          borderTop: '1px solid rgba(255,255,255,0.10)',
          display: 'flex', alignItems: 'flex-end', justifyContent: 'space-between',
          gap: 24, flexWrap: 'wrap',
        }}>
          <div className="gs-slide-metrics" style={{ display: 'flex', gap: 40 }}>
            {[t.metric, t.secondary].map((m, i) => (
              <div key={i} className={i === 0 ? 'gs-metric-primary' : 'gs-metric-secondary'}>
                <div style={{
                  fontFamily: 'var(--font-mono)', fontSize: 9,
                  letterSpacing: '0.18em', color: 'rgba(255,255,255,0.5)',
                  textTransform: 'uppercase', marginBottom: 10,
                }}>{m.label}</div>
                <div className="gs-metric-val" style={{
                  fontSize: i === 0 ? 38 : 26,
                  fontWeight: 500, letterSpacing: '-0.02em',
                  color: i === 0 ? '#7CB4F0' : '#fff',
                  lineHeight: 1,
                }}>{m.value}</div>
              </div>
            ))}
          </div>

          <a href="case-studies.html" className="gs-slide-cta" style={{
            display: 'inline-flex', alignItems: 'center', gap: 8,
            height: 44, padding: '0 22px',
            borderRadius: 999,
            background: 'linear-gradient(135deg, #1E73D9 0%, #155EBA 100%)',
            color: '#fff', fontSize: 13.5, fontWeight: 500, whiteSpace: 'nowrap',
            boxShadow: '0 8px 24px -8px rgba(30,115,217,0.6)',
            transition: 'transform 200ms, box-shadow 200ms',
          }}
          onMouseEnter={(e) => { e.currentTarget.style.transform = 'translateY(-1px)'; e.currentTarget.style.boxShadow = '0 12px 28px -8px rgba(30,115,217,0.8)'; }}
          onMouseLeave={(e) => { e.currentTarget.style.transform = 'translateY(0)'; e.currentTarget.style.boxShadow = '0 8px 24px -8px rgba(30,115,217,0.6)'; }}>
            Read the brief
            <span style={{ fontSize: 13 }}>→</span>
          </a>
        </div>
      </div>
    </div>
  );
}

/* ============================================================
   SLIDER — autoplay + swipe + tape + controls
   ============================================================ */
function Slider({ lang = 'EN' }) {
  const [idx, setIdx] = React.useState(0);
  const [paused, setPaused] = React.useState(false);
  const total = SLIDES.length;
  const touch = React.useRef({ x: 0, y: 0, t: 0, active: false });
  const AUTOPLAY_MS = 7000;

  React.useEffect(() => {
    if (paused) return;
    const tid = setTimeout(() => setIdx((i) => (i + 1) % total), AUTOPLAY_MS);
    return () => clearTimeout(tid);
  }, [idx, paused, total]);

  const go = (n) => setIdx((n + total) % total);

  const onTouchStart = (e) => {
    const tc = e.touches[0];
    touch.current = { x: tc.clientX, y: tc.clientY, t: Date.now(), active: true };
    setPaused(true);
  };
  const onTouchEnd = (e) => {
    if (!touch.current.active) return;
    const tc = e.changedTouches[0];
    const dx = tc.clientX - touch.current.x;
    const dy = tc.clientY - touch.current.y;
    const dt = Date.now() - touch.current.t;
    touch.current.active = false;
    if (Math.abs(dx) > 40 && Math.abs(dx) > Math.abs(dy) * 1.2 && dt < 800) {
      if (dx < 0) go(idx + 1); else go(idx - 1);
    }
    setTimeout(() => setPaused(false), 4000);
  };

  return (
    <section
      className="gs-slider-section"
      onMouseEnter={() => setPaused(true)}
      onMouseLeave={() => setPaused(false)}
      onTouchStart={onTouchStart}
      onTouchEnd={onTouchEnd}
      style={{
        maxWidth: 1440, margin: '0 auto',
        padding: '16px var(--page-px,40px) 56px',
      }}>

      <style>{`
        @keyframes gs-progress-fill {
          from { transform: scaleX(0); }
          to   { transform: scaleX(1); }
        }
        .gs-slider-card { box-shadow: 0 30px 70px -30px rgba(0,0,0,0.5), 0 2px 6px -2px rgba(0,0,0,0.3); }

        /* Tablet & below — stack scene on top */
        @media (max-width: 1024px) {
          .gs-slider-card { height: auto !important; min-height: 0 !important; }
          .gs-slide-inner {
            grid-template-areas: "scene" "copy" !important;
            grid-template-columns: 1fr !important;
            grid-template-rows: 280px auto !important;
          }
          .gs-slide-scene-panel { border-left: none !important; border-bottom: 1px solid rgba(255,255,255,0.06); }
          .gs-slide-copy { padding: 44px 40px 40px !important; }
          .gs-slide-title { font-size: 38px !important; max-width: 100% !important; }
          .gs-slide-body { font-size: 15px !important; max-width: 100% !important; }
        }

        @media (max-width: 720px) {
          .gs-slide-inner { grid-template-rows: 220px auto !important; }
          .gs-slide-copy { padding: 32px 24px 28px !important; }
          .gs-slide-eyebrow { font-size: 10.5px !important; margin-bottom: 20px !important; }
          .gs-slide-title { font-size: 30px !important; }
          .gs-slide-body { font-size: 14px !important; margin-top: 18px !important; }
          .gs-slide-footer { flex-direction: column !important; align-items: stretch !important; gap: 18px !important; margin-top: 28px !important; padding-top: 22px !important; }
          .gs-slide-metrics { gap: 28px !important; }
          .gs-metric-primary .gs-metric-val { font-size: 30px !important; }
          .gs-metric-secondary .gs-metric-val { font-size: 22px !important; }
          .gs-slide-cta { width: 100%; justify-content: center; height: 46px !important; }
          .gs-slide-livetag { top: 14px !important; right: 14px !important; padding: 5px 10px !important; font-size: 9px !important; }
        }

        @media (max-width: 480px) {
          .gs-slider-card { border-radius: 16px !important; }
          .gs-slide-inner { grid-template-rows: 190px auto !important; }
          .gs-slide-copy { padding: 28px 20px 24px !important; }
          .gs-slide-title { font-size: 26px !important; line-height: 1.1 !important; }
          .gs-slide-body { font-size: 13.5px !important; }
          .gs-tape { padding: 12px 16px !important; }
          .gs-tape-brand { font-size: 10px !important; }
          .gs-tape-status { font-size: 9px !important; }
        }

        @media (prefers-reduced-motion: reduce) {
          .gs-slide-track, .gs-progress-active span { transition: none !important; animation: none !important; }
          .gs-progress-active span { transform: scaleX(1) !important; }
          [class*="anim"] { animation: none !important; }
        }
      `}</style>

      <div className="gs-slider-card" style={{
        position: 'relative',
        borderRadius: 20,
        overflow: 'hidden',
        border: '1px solid rgba(255,255,255,0.08)',
        background: '#0A0E18',
        height: 560,
        touchAction: 'pan-y',
      }}>
        {/* TOP TAPE */}
        <div className="gs-tape" style={{
          position: 'absolute',
          top: 0, left: 0, right: 0,
          zIndex: 4,
          display: 'flex',
          alignItems: 'center',
          gap: 14,
          padding: '14px 24px',
          background: 'linear-gradient(180deg, rgba(6,9,16,0.85) 0%, rgba(6,9,16,0))',
          backdropFilter: 'blur(8px)',
          pointerEvents: 'none',
        }}>
          <span className="gs-tape-brand" style={{
            fontFamily: 'var(--font-mono)',
            fontSize: 11, letterSpacing: '0.22em',
            color: '#7CB4F0', whiteSpace: 'nowrap', fontWeight: 600,
          }}>GREYSPACEOPS</span>
          <span style={{
            fontFamily: 'var(--font-mono)', fontSize: 11,
            letterSpacing: '0.16em', color: 'rgba(255,255,255,0.45)', whiteSpace: 'nowrap',
          }}>0{idx + 1} / 0{total}</span>

          {/* Progress segments */}
          <div style={{ flex: 1, display: 'flex', gap: 6, paddingLeft: 12, pointerEvents: 'auto' }}>
            {SLIDES.map((_, i) => {
              const isPast = i < idx;
              const isActive = i === idx;
              return (
                <button key={i} onClick={() => go(i)}
                  aria-label={`Go to slide ${i + 1}`}
                  className={isActive ? 'gs-progress-active' : ''}
                  style={{
                    flex: 1, height: 2, padding: 0, border: 'none',
                    background: 'rgba(255,255,255,0.10)', cursor: 'pointer',
                    position: 'relative', overflow: 'hidden', borderRadius: 999,
                  }}>
                  <span key={isActive ? `a-${idx}` : `p-${i}`} style={{
                    position: 'absolute', inset: 0,
                    background: 'linear-gradient(90deg, #1E73D9, #7CB4F0)',
                    transformOrigin: 'left',
                    transform: isPast ? 'scaleX(1)' : isActive ? undefined : 'scaleX(0)',
                    animation: isActive && !paused
                      ? `gs-progress-fill ${AUTOPLAY_MS}ms linear forwards` : 'none',
                  }}/>
                </button>
              );
            })}
          </div>

          <span className="gs-tape-status" style={{
            fontFamily: 'var(--font-mono)', fontSize: 10,
            letterSpacing: '0.16em', color: 'rgba(124,180,240,0.85)',
            display: 'inline-flex', alignItems: 'center', gap: 8, whiteSpace: 'nowrap',
          }}>
            <span style={{
              width: 6, height: 6, borderRadius: '50%', background: '#1E73D9',
              animation: 'pulse 1.6s ease-in-out infinite',
            }}/>
            LIVE OPS
          </span>
        </div>

        {/* SLIDING TRACK */}
        <div className="gs-slide-track" style={{
          display: 'flex',
          width: `${total * 100}%`,
          height: '100%',
          transform: `translateX(-${idx * (100 / total)}%)`,
          transition: 'transform 700ms var(--ease-standard)',
        }}>
          {SLIDES.map((s, i) => (
            <div key={i} style={{ width: `${100 / total}%`, height: '100%' }}>
              <SlideContent slide={s} lang={lang}/>
            </div>
          ))}
        </div>

        {/* BOTTOM CONTROLS */}
        <div className="gs-slide-controls" style={{
          position: 'absolute',
          right: 22, bottom: 20,
          zIndex: 4,
          display: 'flex', alignItems: 'center', gap: 10,
        }}>
          <div style={{
            display: 'inline-flex', alignItems: 'center', gap: 6,
            padding: '8px 12px', borderRadius: 999,
            background: 'rgba(255,255,255,0.06)',
            border: '1px solid rgba(255,255,255,0.10)',
            backdropFilter: 'blur(8px)',
          }}>
            {SLIDES.map((_, i) => (
              <button key={i} onClick={() => go(i)}
                aria-label={`Go to slide ${i + 1}`}
                style={{
                  width: i === idx ? 22 : 6, height: 6, padding: 0,
                  border: 'none', borderRadius: 999,
                  background: i === idx ? '#7CB4F0' : 'rgba(255,255,255,0.25)',
                  cursor: 'pointer',
                  transition: 'width 280ms var(--ease-standard), background 220ms',
                }}/>
            ))}
          </div>
          <button onClick={() => go(idx - 1)} aria-label="Previous" style={arrowBtn()}>←</button>
          <button onClick={() => go(idx + 1)} aria-label="Next" style={arrowBtn()}>→</button>
        </div>
      </div>
    </section>
  );
}

function arrowBtn() {
  return {
    width: 40, height: 40, borderRadius: 999,
    border: '1px solid rgba(255,255,255,0.14)',
    background: 'rgba(255,255,255,0.06)',
    color: '#fff', fontSize: 16,
    cursor: 'pointer', fontFamily: 'inherit',
    backdropFilter: 'blur(8px)',
    transition: 'background 160ms, transform 160ms, border-color 160ms',
  };
}

window.Slider = Slider;
