/* Sybilhunt — Docs page. window-mounted. Uses kit-components.jsx primitives. */

// Scroll-reveal wrapper
function Reveal({ children, delay = 0, y = 24 }) {
  const ref = React.useRef(null);
  const [shown, setShown] = React.useState(false);
  React.useEffect(() => {
    const el = ref.current;
    if (!el) return;
    const io = new IntersectionObserver((entries) => {
      entries.forEach((e) => { if (e.isIntersecting) { setShown(true); io.unobserve(el); } });
    }, { threshold: 0.16 });
    io.observe(el);
    return () => io.disconnect();
  }, []);
  return (
    <div ref={ref} style={{ opacity: shown ? 1 : 0, transform: shown ? 'none' : `translateY(${y}px)`, transition: `opacity 620ms var(--ease-out) ${delay}ms, transform 620ms var(--ease-out) ${delay}ms` }}>
      {children}
    </div>
  );
}

// Count-up number
function CountUp({ to, prefix = '', suffix = '', dur = 1400 }) {
  const ref = React.useRef(null);
  const [val, setVal] = React.useState(0);
  React.useEffect(() => {
    const el = ref.current;
    if (!el) return;
    let raf, started = false;
    const io = new IntersectionObserver((entries) => {
      entries.forEach((e) => {
        if (e.isIntersecting && !started) {
          started = true;
          const t0 = performance.now();
          const tick = (t) => {
            const p = Math.min(1, (t - t0) / dur);
            const eased = 1 - Math.pow(1 - p, 3);
            setVal(to * eased);
            if (p < 1) raf = requestAnimationFrame(tick);
          };
          raf = requestAnimationFrame(tick);
        }
      });
    }, { threshold: 0.5 });
    io.observe(el);
    return () => { io.disconnect(); cancelAnimationFrame(raf); };
  }, [to, dur]);
  const fmt = (n) => Math.round(n).toLocaleString('en-US');
  return <span ref={ref} style={{ fontVariantNumeric: 'tabular-nums' }}>{prefix}{fmt(val)}{suffix}</span>;
}

const DOC_CONCEPTS = [
  { tag: 'What Sybils are', t: 'One person, a hundred faces', d: 'A Sybil spins up dozens or hundreds of accounts and poses as a crowd of real users — to grab rewards meant for many people.' },
  { tag: 'Why they\u2019re dangerous', t: 'They take what isn\u2019t theirs', d: 'Sybils drain airdrop pools, distort activity metrics and erode trust in the project. Real participants get less — or nothing.' },
  { tag: 'Why projects pay', t: 'Cheaper to catch than to lose', d: 'Handing $5M to bots is a direct loss. It\u2019s cheaper to give hunters a slice of the pool to filter Sybils out before distribution.' },
];

const DOC_STEPS = [
  { n: '01', t: 'Pick an active hunt', d: 'Open a partner campaign. Inside: the pool size, the rules, and the kind of Sybils we\u2019re after.' },
  { n: '02', t: 'Analyze wallets & links', d: 'Trace funding sources, transaction timing, shared contracts and behavioral patterns that tie accounts into one cluster.' },
  { n: '03', t: 'Build the evidence', d: 'Assemble the cluster: the set of accounts one actor controls, and the on-chain proof that links them.' },
  { n: '04', t: 'Submit & claim', d: 'Confirmed clusters split the pool by what they found. Earlier and sharper reports earn a bigger share.' },
];

const DOC_FAQ = [
  { q: 'How is the reward calculated?', a: 'Each confirmed cluster earns a share of the pool proportional to the number of Sybil accounts it proves and the confidence of the evidence. Earlier submissions break ties.' },
  { q: 'What counts as proof?', a: 'On-chain links — shared funding wallets, coordinated timing, identical contract interactions, recycled gas — packaged into a clear cluster a reviewer can verify independently.' },
  { q: 'Do I need KYC to hunt?', a: 'No KYC to investigate or submit. Payouts in USDC are sent to the wallet that filed the confirmed report.' },
  { q: 'Who reviews submissions?', a: 'The partner project plus Sybilhunt\u2019s forensics team review each cluster before rewards are released, so false positives don\u2019t cost real users.' },
];

function DocsHeader() {
  const go = (hash) => { window.location.href = 'index.html' + (hash ? '#' + hash : ''); };
  return (
    <header style={{ position: 'sticky', top: 0, zIndex: 100, height: 'var(--header-h)', display: 'flex', alignItems: 'center', justifyContent: 'space-between', padding: '0 clamp(20px, 4vw, 48px)', background: 'rgba(250,250,250,0.88)', backdropFilter: 'blur(14px)', WebkitBackdropFilter: 'blur(14px)', borderBottom: '1px solid var(--border-subtle)' }}>
      <div style={{ display: 'flex', alignItems: 'center', gap: 36 }}>
        <Logo size={28} onClick={() => go('')} />
        <nav style={{ display: 'flex', alignItems: 'center', gap: 28 }}>
          <DNav onClick={() => go('')}>Home</DNav>
          <DNav onClick={() => { window.location.href = 'who.html'; }}>Who are Sybils</DNav>
          <DNav onClick={() => { window.location.href = 'experience.html'; }}>Hunters</DNav>
          <DNav active>Docs</DNav>
          <DNav onClick={() => go('partners')}>Partners</DNav>
        </nav>
      </div>
    </header>
  );
}

function DNav({ onClick, active, children }) {
  return (
    <button onClick={onClick} style={{ background: 'none', border: 'none', cursor: active ? 'default' : 'pointer', fontFamily: 'var(--font-body)', fontWeight: active ? 700 : 500, fontSize: 15, color: active ? 'var(--text-strong)' : 'var(--text-muted)', padding: 0, transition: 'color var(--dur-fast)' }}
      onMouseEnter={(e) => { if (!active) e.currentTarget.style.color = 'var(--text-strong)'; }}
      onMouseLeave={(e) => { if (!active) e.currentTarget.style.color = 'var(--text-muted)'; }}>
      {children}
    </button>
  );
}

function FaqItem({ q, a }) {
  const [open, setOpen] = React.useState(false);
  return (
    <div style={{ borderBottom: '1px solid var(--border-subtle)' }}>
      <button onClick={() => setOpen((o) => !o)} style={{ width: '100%', display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 16, padding: '22px 4px', background: 'none', border: 'none', cursor: 'pointer', textAlign: 'left' }}>
        <span style={{ fontFamily: 'var(--font-display)', fontWeight: 600, fontSize: 'clamp(17px, 2vw, 20px)', color: 'var(--text-strong)' }}>{q}</span>
        <span style={{ flex: 'none', width: 28, height: 28, borderRadius: '50%', border: '1px solid var(--border-strong)', display: 'inline-flex', alignItems: 'center', justifyContent: 'center', color: 'var(--text-muted)', fontSize: 17, transition: 'transform var(--dur-base) var(--ease-out), background var(--dur-base)', transform: open ? 'rotate(45deg)' : 'none', background: open ? 'var(--surface-raised)' : 'transparent' }}>+</span>
      </button>
      <div style={{ maxHeight: open ? 220 : 0, overflow: 'hidden', transition: 'max-height var(--dur-slow) var(--ease-out)' }}>
        <p style={{ fontSize: 16, color: 'var(--text-muted)', lineHeight: 1.65, padding: '0 4px 24px', maxWidth: 760 }}>{a}</p>
      </div>
    </div>
  );
}

function DocsApp() {
  return (
    <div>
      <DocsHeader />

      {/* Hero */}
      <section style={{ padding: 'clamp(56px, 11vh, 132px) clamp(20px, 4vw, 48px) clamp(20px, 4vh, 40px)', maxWidth: 'var(--container-max)', margin: '0 auto' }}>
        <Reveal>
          <div className="sh-overline" style={{ marginBottom: 16 }}>Documentation</div>
          <h1 style={{ fontSize: 'clamp(36px, 6vw, 68px)', maxWidth: 860, lineHeight: 1.03, letterSpacing: '-0.02em' }}>
            An open sybil hunt where the community wins
          </h1>
          <p style={{ fontFamily: 'var(--font-body)', fontSize: 'clamp(17px, 2vw, 20px)', color: 'var(--text-muted)', marginTop: 20, maxWidth: 700 }}>
            Sybilhunt connects projects that hand out rewards with hunters who know how to find fraud. The project puts up a pool — hunters bring the evidence — bots get nothing.
          </p>
        </Reveal>
      </section>

      {/* Concepts */}
      <section style={{ padding: 'clamp(20px, 4vh, 48px) clamp(20px, 4vw, 48px) clamp(48px, 8vh, 96px)', maxWidth: 'var(--container-max)', margin: '0 auto' }}>
        <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(280px, 1fr))', gap: 18 }}>
          {DOC_CONCEPTS.map((c, i) => (
            <Reveal key={c.tag} delay={i * 90}>
              <Card interactive padding={28} style={{ height: '100%' }}>
                <Badge tone="signal" size="sm">{c.tag}</Badge>
                <div style={{ fontFamily: 'var(--font-display)', fontWeight: 600, fontSize: 22, color: 'var(--text-strong)', margin: '16px 0 10px', letterSpacing: '-0.01em' }}>{c.t}</div>
                <p style={{ fontSize: 15, color: 'var(--text-muted)', lineHeight: 1.6 }}>{c.d}</p>
              </Card>
            </Reveal>
          ))}
        </div>
      </section>

      {/* How a hunt works */}
      <section style={{ padding: 'clamp(56px, 10vh, 120px) clamp(20px, 4vw, 48px)', maxWidth: 'var(--container-max)', margin: '0 auto' }}>
        <Reveal>
          <div className="sh-overline" style={{ marginBottom: 14 }}>How a hunt works</div>
          <h2 style={{ fontSize: 'clamp(28px, 4vw, 46px)', maxWidth: 640, lineHeight: 1.05 }}>From open campaign to paid reward</h2>
        </Reveal>
        <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(230px, 1fr))', gap: 18, marginTop: 44 }}>
          {DOC_STEPS.map((s, i) => (
            <Reveal key={s.n} delay={i * 90}>
              <div style={{ position: 'relative', background: 'var(--surface-card)', border: '1px solid var(--border-subtle)', borderRadius: 'var(--radius-lg)', padding: 26, height: '100%', boxShadow: 'var(--inset-hairline), var(--shadow-md)' }}>
                <div style={{ fontFamily: 'var(--font-mono)', fontWeight: 700, fontSize: 26, color: 'var(--signal-500)' }}>{s.n}</div>
                <div style={{ fontFamily: 'var(--font-display)', fontWeight: 600, fontSize: 19, color: 'var(--text-strong)', margin: '12px 0 8px' }}>{s.t}</div>
                <p style={{ fontSize: 14.5, color: 'var(--text-muted)', lineHeight: 1.55 }}>{s.d}</p>
              </div>
            </Reveal>
          ))}
        </div>
      </section>

      {/* FAQ */}
      <section style={{ padding: 'clamp(40px, 7vh, 88px) clamp(20px, 4vw, 48px) clamp(64px, 11vh, 132px)', maxWidth: 880, margin: '0 auto' }}>
        <Reveal>
          <div className="sh-overline" style={{ marginBottom: 14 }}>FAQ</div>
          <h2 style={{ fontSize: 'clamp(28px, 4vw, 46px)', lineHeight: 1.05, marginBottom: 28 }}>Questions hunters ask</h2>
        </Reveal>
        <Reveal delay={80}>
          <div>
            {DOC_FAQ.map((f) => <FaqItem key={f.q} q={f.q} a={f.a} />)}
          </div>
        </Reveal>
      </section>

      {/* CTA */}
      <section style={{ padding: '0 clamp(20px, 4vw, 48px) clamp(56px, 9vh, 110px)' }}>
        <Reveal>
          <div style={{ position: 'relative', overflow: 'hidden', maxWidth: 'var(--container-max)', margin: '0 auto', borderRadius: 'var(--radius-2xl)', padding: 'clamp(40px, 7vw, 80px) clamp(28px, 5vw, 72px)', textAlign: 'center', background: 'linear-gradient(135deg, #0F1A12 0%, #15301B 60%, #0E2A18 100%)', boxShadow: '0 30px 80px rgba(15,40,22,0.28)' }}>
            <div aria-hidden="true" style={{ position: 'absolute', inset: 0, background: 'radial-gradient(680px 340px at 50% -10%, rgba(125,200,32,0.30), transparent 60%)', pointerEvents: 'none' }} />
            <div style={{ position: 'relative' }}>
              <h2 style={{ fontSize: 'clamp(30px, 5vw, 56px)', lineHeight: 1.04, letterSpacing: '-0.02em', color: '#fff', maxWidth: 780, margin: '0 auto' }}>Ready to hunt?</h2>
              <p style={{ fontSize: 'clamp(16px, 2vw, 19px)', color: 'rgba(255,255,255,0.72)', marginTop: 16, maxWidth: 520, marginInline: 'auto' }}>Pick the active Polymarket campaign and start tracing clusters.</p>
              <div style={{ display: 'flex', justifyContent: 'center', marginTop: 32 }}>
                <Button variant="primary" size="lg" onClick={() => { window.location.href = 'index.html'; }} rightIcon={<span>→</span>} style={{ height: 60, fontSize: 18, padding: '0 38px' }}>Start hunting Sybils</Button>
              </div>
            </div>
          </div>
        </Reveal>
      </section>

      <footer style={{ borderTop: '1px solid var(--border-subtle)', padding: 'clamp(36px, 6vh, 64px) clamp(20px, 4vw, 48px)', background: '#F0F2F0' }}>
        <div style={{ maxWidth: 'var(--container-max)', margin: '0 auto', display: 'flex', flexWrap: 'wrap', gap: 20, justifyContent: 'space-between', alignItems: 'center' }}>
          <div>
            <Logo size={26} onClick={() => { window.location.href = 'index.html'; }} />
            <p style={{ fontSize: 13, color: 'var(--text-faint)', marginTop: 14, maxWidth: 360 }}>An open platform for hunting Sybils in crypto distributions. © 2026 Sybilhunt.</p>
          </div>
          <DNav onClick={() => { window.location.href = 'index.html'; }}>← Back to home</DNav>
        </div>
      </footer>
    </div>
  );
}

function DocStat({ value, label, tone = 'default' }) {
  const colors = { default: 'var(--text-strong)', signal: 'var(--signal-400)', coral: 'var(--coral-300)' };
  return (
    <div>
      <div style={{ fontFamily: 'var(--font-display)', fontWeight: 700, fontSize: 'clamp(34px, 5vw, 60px)', lineHeight: 1, letterSpacing: '-0.02em', color: colors[tone] }}>{value}</div>
      <div className="sh-overline" style={{ marginTop: 10 }}>{label}</div>
    </div>
  );
}

ReactDOM.createRoot(document.getElementById('root')).render(<DocsApp />);
