// V3 — Constellation
// Diagrammatic hero: a flow graph showing evidence → assessment → controls.
// Nodes pulse, lines draw on, packets flow along edges. Visual-first.

(function () {
const { Icon, Logo, TopNav, Footer, CustomerWall, FRAMEWORK_GROUPS } = window.LP;
const { useState: useStateC, useEffect: useEffectC, useRef: useRefC } = React;

function Constellation() {
  const [tick, setTick] = useStateC(0);
  useEffectC(() => {
    let raf;
    const start = performance.now();
    const loop = (ts) => {
      setTick((ts - start) / 1000);
      raf = requestAnimationFrame(loop);
    };
    raf = requestAnimationFrame(loop);
    return () => cancelAnimationFrame(raf);
  }, []);

  // Layout (in svg coords)
  const W = 720, H = 520;
  const sources = [
    { id: "src-okta", x: 60, y: 70, label: "Okta", sub: "MFA & access" },
    { id: "src-aws", x: 60, y: 160, label: "AWS", sub: "IAM & S3" },
    { id: "src-pdf", x: 60, y: 250, label: "Policy.pdf", sub: "Document" },
    { id: "src-github", x: 60, y: 340, label: "GitHub", sub: "Code & PRs" },
    { id: "src-csv", x: 60, y: 430, label: "Roster.csv", sub: "Training" },
  ];
  const hub = { x: 360, y: 260 };
  const frameworks = [
    { id: "f-cis", x: 660, y: 90, label: "CIS v8", color: "#93D2CC" },
    { id: "f-soc2", x: 660, y: 180, label: "SOC 2", color: "#A8D8A8" },
    { id: "f-iso", x: 660, y: 270, label: "ISO 27001", color: "#F4C28A" },
    { id: "f-nist", x: 660, y: 360, label: "NIST CSF", color: "#D4A8D4" },
    { id: "f-pci", x: 660, y: 450, label: "PCI DSS", color: "#E8A87C" },
  ];

  // A "packet" travels src → hub → framework on a 4s loop, offset per source
  const packets = sources.map((s, i) => {
    const dur = 4;
    const phase = ((tick + i * 0.6) % dur + dur) % dur;
    const seg = phase / dur; // 0..1
    let x, y;
    const cycle = Math.max(0, Math.floor((tick + i * 0.6) / dur));
    const fwIdx = ((i + cycle) % frameworks.length + frameworks.length) % frameworks.length;
    const fw = frameworks[fwIdx] || frameworks[0];
    if (seg < 0.5) {
      const t = seg / 0.5;
      x = s.x + (hub.x - s.x) * t;
      y = s.y + (hub.y - s.y) * t;
    } else {
      const t = (seg - 0.5) / 0.5;
      x = hub.x + (fw.x - hub.x) * t;
      y = hub.y + (fw.y - hub.y) * t;
    }
    return { id: s.id, x, y, fwId: fw.id, color: fw.color, opacity: seg < 0.05 || seg > 0.95 ? seg < 0.05 ? seg * 20 : (1 - seg) * 20 : 1 };
  });

  // Hub pulse
  const pulse = 1 + Math.sin(tick * 2.4) * 0.06;
  const ringR = 36 + ((tick * 30) % 36);
  const ringOp = Math.max(0, 1 - ((tick * 30) % 36) / 36);

  return (
    <div className="relative">
      <div className="absolute -inset-12 rounded-[40px] bg-gradient-to-br from-[#93D2CC]/15 via-transparent to-[#93D2CC]/5 blur-3xl" />
      <svg viewBox={`0 0 ${W} ${H}`} className="relative w-full h-auto" style={{ maxHeight: 540 }}>
        <defs>
          <linearGradient id="edge" x1="0" x2="1">
            <stop offset="0%" stopColor="rgba(147,210,204,0.0)" />
            <stop offset="50%" stopColor="rgba(147,210,204,0.7)" />
            <stop offset="100%" stopColor="rgba(147,210,204,0.0)" />
          </linearGradient>
          <radialGradient id="hubFill" cx="50%" cy="50%" r="50%">
            <stop offset="0%" stopColor="#93D2CC" stopOpacity="1" />
            <stop offset="60%" stopColor="#93D2CC" stopOpacity="0.4" />
            <stop offset="100%" stopColor="#93D2CC" stopOpacity="0" />
          </radialGradient>
          <filter id="glow"><feGaussianBlur stdDeviation="2.5" /></filter>
        </defs>

        {/* Edges from sources to hub */}
        {sources.map((s) => (
          <line key={`e1-${s.id}`} x1={s.x + 16} y1={s.y} x2={hub.x - 30} y2={hub.y} stroke="rgba(255,255,255,0.18)" strokeWidth="1" strokeDasharray="3 4" />
        ))}
        {/* Edges from hub to frameworks */}
        {frameworks.map((f) => (
          <line key={`e2-${f.id}`} x1={hub.x + 30} y1={hub.y} x2={f.x - 16} y2={f.y} stroke="rgba(255,255,255,0.18)" strokeWidth="1" strokeDasharray="3 4" />
        ))}

        {/* Animated edge highlights — a glowing path overlay that travels */}
        {packets.map((p, i) => {
          const s = sources[i];
          const fw = frameworks.find(f => f.id === p.fwId) || frameworks[0];
          if (!s || !fw) return null;
          // Two-segment polyline through hub
          return (
            <g key={`hl-${p.id}`} opacity={p.opacity}>
              <polyline points={`${s.x+16},${s.y} ${hub.x},${hub.y} ${fw.x-16},${fw.y}`} fill="none" stroke={fw.color} strokeWidth="1.5" strokeLinecap="round" strokeDasharray="120" strokeDashoffset={120 - ((tick * 80 + i * 25) % 240)} opacity="0.35" />
            </g>
          );
        })}

        {/* Hub pulse rings */}
        <circle cx={hub.x} cy={hub.y} r={ringR} fill="none" stroke="#93D2CC" strokeWidth="1" opacity={ringOp * 0.5} />

        {/* Hub */}
        <g transform={`translate(${hub.x}, ${hub.y})`}>
          <circle r="60" fill="url(#hubFill)" filter="url(#glow)" />
          <circle r={28 * pulse} fill="#93D2CC" opacity="0.95" />
          <circle r="28" fill="none" stroke="rgba(255,255,255,0.5)" strokeWidth="1" />
          <text textAnchor="middle" y="-50" fontSize="9.5" fontWeight="700" fill="#93D2CC" letterSpacing="2" style={{ textTransform: "uppercase", fontFamily: "Geist, sans-serif" }}>
            Control+S engine
          </text>
          <text textAnchor="middle" y="4" fontSize="11" fontWeight="700" fill="#404C5C" style={{ fontFamily: "Geist, sans-serif" }}>
            Map &amp; score
          </text>
          <text textAnchor="middle" y="18" fontSize="9" fill="#404C5C" opacity="0.65" style={{ fontFamily: "Geist, sans-serif" }}>
            with reasoning
          </text>
        </g>

        {/* Sources */}
        {sources.map((s, i) => {
          const isActive = (Math.floor(tick * 1.5) + i) % sources.length === i;
          return (
            <g key={s.id} transform={`translate(${s.x}, ${s.y})`}>
              <rect x="-46" y="-18" width="92" height="36" rx="8" fill={isActive ? "rgba(147,210,204,0.18)" : "rgba(255,255,255,0.04)"} stroke={isActive ? "#93D2CC" : "rgba(255,255,255,0.18)"} strokeWidth="1" />
              <text textAnchor="middle" y="-2" fontSize="11" fontWeight="600" fill="white" style={{ fontFamily: "Geist, sans-serif" }}>{s.label}</text>
              <text textAnchor="middle" y="11" fontSize="8.5" fill="rgba(255,255,255,0.5)" style={{ fontFamily: "Geist, sans-serif" }}>{s.sub}</text>
            </g>
          );
        })}

        {/* Frameworks */}
        {frameworks.map((f, i) => {
          const ping = packets.some(p => p.fwId === f.id && p.opacity > 0.7);
          return (
            <g key={f.id} transform={`translate(${f.x}, ${f.y})`}>
              <rect x="-46" y="-18" width="92" height="36" rx="8" fill={ping ? `${f.color}33` : "rgba(255,255,255,0.04)"} stroke={ping ? f.color : "rgba(255,255,255,0.18)"} strokeWidth={ping ? "1.5" : "1"} />
              <circle cx="-32" cy="0" r="3.5" fill={f.color} />
              <text x="-22" y="3" fontSize="11" fontWeight="600" fill="white" style={{ fontFamily: "Geist, sans-serif" }}>{f.label}</text>
            </g>
          );
        })}

        {/* Traveling packets */}
        {packets.map((p) => (
          <g key={`pkt-${p.id}`} opacity={p.opacity}>
            <circle cx={p.x} cy={p.y} r="6" fill={p.color} opacity="0.3" />
            <circle cx={p.x} cy={p.y} r="3" fill={p.color} />
            <circle cx={p.x} cy={p.y} r="3" fill="white" opacity="0.7" />
          </g>
        ))}

        {/* Column labels */}
        <text x={60} y={26} textAnchor="middle" fontSize="10" fontWeight="700" fill="rgba(255,255,255,0.4)" letterSpacing="2.5" style={{ textTransform: "uppercase", fontFamily: "Geist, sans-serif" }}>Evidence</text>
        <text x={hub.x} y={26} textAnchor="middle" fontSize="10" fontWeight="700" fill="rgba(255,255,255,0.4)" letterSpacing="2.5" style={{ textTransform: "uppercase", fontFamily: "Geist, sans-serif" }}>Assess</text>
        <text x={660} y={26} textAnchor="middle" fontSize="10" fontWeight="700" fill="rgba(255,255,255,0.4)" letterSpacing="2.5" style={{ textTransform: "uppercase", fontFamily: "Geist, sans-serif" }}>Frameworks</text>
      </svg>
    </div>
  );
}

function HeroConstellation({ headline, kicker }) {
  return (
    <section className="relative bg-[#404C5C] text-white overflow-hidden">
      {/* Star field background */}
      <div className="absolute inset-0 opacity-30 pointer-events-none">
        {Array.from({ length: 50 }).map((_, i) => {
          const x = (i * 37) % 100;
          const y = (i * 53) % 100;
          const size = (i % 3) + 1;
          return <span key={i} className="absolute rounded-full bg-white" style={{ left: `${x}%`, top: `${y}%`, width: size, height: size, opacity: 0.4 + (i % 3) * 0.2 }} />;
        })}
      </div>

      <div className="relative mx-auto max-w-6xl px-6 pt-12 md:pt-16 pb-20 md:pb-24">
        {/* Top text band */}
        <div className="text-center max-w-3xl mx-auto mb-10 md:mb-14">
          <span className="inline-flex items-center gap-2 px-3 py-1 rounded-full border border-[#93D2CC]/30 bg-[#93D2CC]/10 text-[11px] font-semibold uppercase tracking-[0.16em] text-[#93D2CC]">
            {kicker}
          </span>
          <h1 className="mt-5 text-[44px] md:text-[60px] lg:text-[68px] leading-[0.98] tracking-[-0.02em] font-semibold" style={{ fontFamily: "Geist, system-ui, sans-serif" }}>
            {headline.split("|").map((part, i) => (
              <span key={i} className={i === 1 ? "text-[#93D2CC]" : ""}>{part}</span>
            ))}
          </h1>
          <p className="mt-5 text-[16px] md:text-[18px] leading-relaxed text-white/70 max-w-2xl mx-auto">
            One platform turns scattered evidence into mapped, scored, audit-ready assessments — across every framework you need.
          </p>
        </div>

        {/* The constellation */}
        <Constellation />

        {/* CTAs */}
        <div className="mt-14 flex flex-wrap items-center justify-center gap-4">
          <button className="inline-flex items-center gap-2 px-7 py-3 rounded-full bg-[#93D2CC] text-[#404C5C] text-[14px] font-bold shadow-[0_14px_40px_-12px_rgba(147,210,204,0.7)] hover:bg-white transition-all">
            Access platform
            <Icon name="arrowRight" className="h-4 w-4" strokeWidth={2.4} />
          </button>
          <a href="#how" className="text-[14px] font-medium text-white/70 hover:text-white inline-flex items-center gap-1.5">
            See how it works <Icon name="arrowRight" className="h-3.5 w-3.5" strokeWidth={2.4} />
          </a>
        </div>
      </div>
    </section>
  );
}

function HowItWorksConstellation() {
  const steps = [
    { n: 1, title: "Evidence in", body: "From any source, in any format. Connect tools or drop files manually.", icon: "upload" },
    { n: 2, title: "Mapped to controls", body: "We match every artifact against every framework you've enabled, simultaneously.", icon: "layers" },
    { n: 3, title: "Scored with reasoning", body: "Maturity 1–5 per control, with the rationale. Override anytime; the trail stays intact.", icon: "shieldCheck" },
  ];
  return (
    <section id="how" className="bg-[#FAF7F4]">
      <div className="mx-auto max-w-6xl px-6 py-20 md:py-24">
        <div className="text-center max-w-2xl mx-auto mb-14">
          <p className="text-[11px] uppercase tracking-[0.22em] text-[#3a8a82] font-bold mb-3">The flow</p>
          <h2 className="text-[36px] md:text-[48px] tracking-tight font-semibold text-[#404C5C]" style={{ fontFamily: "Geist, system-ui, sans-serif" }}>
            One pipeline. Every framework.
          </h2>
        </div>

        <div className="relative">
          {/* Horizontal rule with markers */}
          <div className="absolute top-7 left-12 right-12 h-px bg-gradient-to-r from-transparent via-[#404C5C]/25 to-transparent hidden md:block" />
          <div className="grid gap-8 md:grid-cols-3 relative">
            {steps.map((s) => (
              <div key={s.n} className="relative flex flex-col items-center text-center">
                <div className="relative z-10 h-14 w-14 rounded-full bg-[#404C5C] text-[#93D2CC] flex items-center justify-center shadow-[0_8px_28px_-8px_rgba(64,76,91,0.5)]">
                  <Icon name={s.icon} className="h-5.5 w-5.5" strokeWidth={2} />
                  <span className="absolute -top-1.5 -right-1.5 h-5.5 w-5.5 rounded-full bg-[#93D2CC] text-[#404C5C] text-[10.5px] font-bold flex items-center justify-center" style={{ width: 22, height: 22 }}>{s.n}</span>
                </div>
                <h3 className="mt-5 text-[20px] font-semibold tracking-tight text-[#404C5C]">{s.title}</h3>
                <p className="mt-2 text-[14px] leading-relaxed text-[#404C5C]/70 max-w-xs">{s.body}</p>
              </div>
            ))}
          </div>
        </div>
      </div>
    </section>
  );
}

function FrameworksConstellation() {
  return (
    <section id="frameworks" className="bg-[#404C5C] text-white relative overflow-hidden">
      <div className="absolute inset-0 pointer-events-none" style={{
        background: "radial-gradient(800px circle at 50% 0%, rgba(147,210,204,0.1), transparent 50%)",
      }} />
      <div className="relative mx-auto max-w-6xl px-6 py-20 md:py-24">
        <div className="text-center max-w-2xl mx-auto mb-12">
          <p className="text-[11px] uppercase tracking-[0.22em] text-[#93D2CC] font-bold mb-3">Coverage</p>
          <h2 className="text-[36px] md:text-[48px] tracking-tight font-semibold" style={{ fontFamily: "Geist, system-ui, sans-serif" }}>
            16 frameworks. One graph.
          </h2>
        </div>
        <div className="space-y-10">
          {FRAMEWORK_GROUPS.map((g) => (
            <div key={g.category}>
              <p className="text-[11px] uppercase tracking-[0.18em] text-[#93D2CC] font-semibold mb-4">{g.category}</p>
              <div className="grid gap-3 sm:grid-cols-2 lg:grid-cols-3">
                {g.frameworks.map((f) => (
                  <div key={f.name} className="flex items-center gap-3 rounded-xl border border-white/10 bg-white/[0.04] px-4 py-3 hover:border-[#93D2CC]/40 hover:bg-white/[0.07] transition-all">
                    <span className="h-2.5 w-2.5 rounded-full bg-[#93D2CC] flex-none" />
                    <div className="min-w-0 flex-1">
                      <p className="text-[13.5px] font-semibold truncate">{f.name}</p>
                      <p className="text-[11px] text-white/45">{f.publisher}</p>
                    </div>
                    <Icon name="arrowUpRight" className="h-3.5 w-3.5 text-white/30" strokeWidth={2} />
                  </div>
                ))}
              </div>
            </div>
          ))}
        </div>
      </div>
    </section>
  );
}

function ClosingConstellation() {
  return (
    <section className="bg-[#FAF7F4]">
      <div className="mx-auto max-w-4xl px-6 py-24 text-center">
        <h2 className="text-[40px] md:text-[56px] leading-[1.02] tracking-tight font-semibold text-[#404C5C]" style={{ fontFamily: "Geist, system-ui, sans-serif" }}>
          Wire it up. <span className="text-[#3a8a82]">Or don't.</span>
        </h2>
        <p className="mt-4 text-[16px] text-[#404C5C]/70 max-w-xl mx-auto">
          Drag a file in to start. Connect sources later, when you're ready.
        </p>
        <button className="mt-8 inline-flex items-center gap-2 px-7 py-3.5 rounded-full bg-[#404C5C] text-white text-[14px] font-bold hover:bg-[#2e3744] transition-all">
          Access platform
          <Icon name="arrowRight" className="h-4 w-4" strokeWidth={2.4} />
        </button>
      </div>
    </section>
  );
}

window.LP_Constellation = function ({ headline, kicker, sectionOrder }) {
  const sections = {
    proof: <CustomerWall key="proof" tone="light" />,
    how: <HowItWorksConstellation key="how" />,
    frameworks: <FrameworksConstellation key="frameworks" />,
  };
  return (
    <div className="bg-[#404C5C]">
      <TopNav variant="dark" />
      <HeroConstellation headline={headline} kicker={kicker} />
      {sectionOrder.map((k) => sections[k])}
      <ClosingConstellation />
      <Footer tone="dark" />
    </div>
  );
};
})();
