/* v2/mid-v2.jsx — Logowall, Problem, How It Works, Platforms, Showcase, Stats */

const LogoWallV2 = () => {
  const rowRef = React.useRef(null);
  const [inView, setInView] = React.useState(false);
  React.useEffect(() => {
    if (!rowRef.current) return;
    const reduced = window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches;
    if (reduced) { setInView(true); return; }
    const io = new IntersectionObserver((entries) => {
      for (const e of entries) {
        if (e.isIntersecting) { setInView(true); io.disconnect(); }
      }
    }, { threshold: 0.3 });
    io.observe(rowRef.current);
    return () => io.disconnect();
  }, []);
  const itemStyle = (i) => ({
    opacity: inView ? 1 : 0,
    transform: inView ? 'translateY(0)' : 'translateY(6px)',
    transition: 'opacity 280ms cubic-bezier(0.2,0.7,0.2,1), transform 280ms cubic-bezier(0.2,0.7,0.2,1)',
    transitionDelay: (inView ? (i * 90) + 'ms' : '0ms'),
  });
  return (
  <div className="logowall">
    <div className="wrap reveal">
      <div className="logowall-label">Track and influence citations across every major AI engine</div>
      <div className="logowall-row" ref={rowRef}>
        <span className="logowall-item" style={itemStyle(0)}><ChatGPT size={20} pad={0} bg="transparent" rounded={4}/> ChatGPT</span>
        <span className="logowall-item" style={itemStyle(1)}><Claude size={20} pad={0} bg="transparent" rounded={4}/> Claude</span>
        <span className="logowall-item" style={itemStyle(2)}><Perplexity size={20} pad={0} bg="transparent" rounded={4}/> Perplexity</span>
        <span className="logowall-item" style={itemStyle(3)}><Gemini size={20} pad={0} bg="transparent" rounded={4}/> Gemini</span>
        <span className="logowall-item" style={itemStyle(4)}><Grok size={20} pad={0} bg="transparent" rounded={4}/> Grok</span>
        <span className="logowall-item" style={itemStyle(5)}><Copilot size={20} pad={0} bg="transparent" rounded={4}/> Google AI</span>
      </div>
    </div>
  </div>
  );
};

const ProblemV2 = () => {
  const splitRef = React.useRef(null);
  const leftColRef = React.useRef(null);
  const [progress, setProgress] = React.useState(0);          // 0..1 scroll progress for "Then" slide to left
  const [thenRowsIn, setThenRowsIn] = React.useState(false);  // stagger rows in Then card
  const [nowShown, setNowShown] = React.useState(false);      // Now card slides in
  const [nowRowsIn, setNowRowsIn] = React.useState(false);    // stagger rows in Now card
  const playedRef = React.useRef(false);

  React.useEffect(() => {
    if (!splitRef.current) return;
    const reduced = window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches;
    if (reduced) {
      setProgress(1); setThenRowsIn(true); setNowShown(true); setNowRowsIn(true);
      playedRef.current = true; return;
    }

    // Reveal Then rows as soon as section enters view (before slide begins)
    const io = new IntersectionObserver((entries) => {
      for (const e of entries) {
        if (e.isIntersecting) { setThenRowsIn(true); io.disconnect(); }
      }
    }, { threshold: 0.15 });
    io.observe(splitRef.current);

    let ticking = false;
    const onScroll = () => {
      if (playedRef.current || ticking) return;
      ticking = true;
      requestAnimationFrame(() => {
        ticking = false;
        if (playedRef.current || !splitRef.current) return;
        const rect = splitRef.current.getBoundingClientRect();
        const vh = window.innerHeight;
        // Start sliding when split top reaches ~65% down viewport, finish by ~25%
        const startY = vh * 0.65;
        const endY   = vh * 0.25;
        const t = Math.max(0, Math.min(1, (startY - rect.top) / (startY - endY)));
        if (t >= 1) {
          // Lock: commit final state and stop responding to further scroll
          playedRef.current = true;
          setProgress(1);
          setNowShown(true);
          setTimeout(() => setNowRowsIn(true), 480);
        } else {
          setProgress(t);
        }
      });
    };
    onScroll();
    window.addEventListener('scroll', onScroll, { passive: true });
    return () => { window.removeEventListener('scroll', onScroll); io.disconnect(); };
  }, []);

  // ——— Transform helpers ———
  // Then col: starts centered in the 2-col grid, slides to natural left position as progress→1.
  // Centered offset = 50% of own width + half the column-gap (≈10px).
  const thenColStyle = {
    transform: `translateX(calc(${(1 - progress).toFixed(4)} * (50% + 10px)))`,
    transition: nowShown ? 'transform 420ms cubic-bezier(0.2,0.7,0.2,1)' : 'none',
    willChange: 'transform',
  };
  // Now col: off-screen right until nowShown, then slides in.
  const nowColStyle = {
    transform: nowShown ? 'translateX(0)' : 'translateX(calc(100% + 40px))',
    opacity: nowShown ? 1 : 0,
    transition: 'transform 560ms cubic-bezier(0.2,0.7,0.2,1), opacity 320ms ease',
    willChange: 'transform, opacity',
  };

  const rowStyle = (i) => ({
    opacity: thenRowsIn ? 1 : 0,
    transform: thenRowsIn ? 'translateX(0)' : 'translateX(-10px)',
    transition: 'opacity 360ms cubic-bezier(0.2,0.7,0.2,1), transform 360ms cubic-bezier(0.2,0.7,0.2,1)',
    transitionDelay: (thenRowsIn ? (i * 90) + 'ms' : '0ms'),
  });
  const rowStyleR = (i) => ({
    opacity: nowRowsIn ? 1 : 0,
    transform: nowRowsIn ? 'translateX(0)' : 'translateX(10px)',
    transition: 'opacity 360ms cubic-bezier(0.2,0.7,0.2,1), transform 360ms cubic-bezier(0.2,0.7,0.2,1)',
    transitionDelay: (nowRowsIn ? (i * 90) + 'ms' : '0ms'),
  });
  return (
  <section className="section dark-section">
    <div className="wrap">
      <div className="center-stack reveal">
        <span className="eyebrow">The shift</span>
        <h2 className="display-lg" style={{margin: '24px 0px 63.08px'}}>
          Buyers stopped<br/>
          Googling. They ask AI.
        </h2>
        <p className="lede" style={{margin: '24px auto 0'}}>
          67% of research now starts inside ChatGPT, Claude, or Perplexity.
          The answers they see decide which business gets the sale.
        </p>
      </div>

      <div className="split-quote" ref={splitRef}>
        <div className="sq-col" style={thenColStyle} ref={leftColRef}>
          <div className="sq-era">Then</div>
        <div className="sq-card">
          <div className="sq-brand-head">
            <div className="sq-brand">
              <span className="sq-brand-icon"><img src="/v2-assets/google.svg" alt="Google" style={{width:22, height:22, display:'block'}}/></span>
              <span className="sq-brand-name">Google</span>
            </div>
            <div className="sq-year">2022</div>
          </div>
          <div className="sq-query">
            <svg width="13" height="13" viewBox="0 0 16 16" fill="none" style={{flexShrink:0, opacity:0.6}}>
              <circle cx="7" cy="7" r="5" stroke="currentColor" strokeWidth="1.5"/>
              <path d="M11 11l4 4" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round"/>
            </svg>
            best project management software for agencies
          </div>
          <div className="rank-list">
            <div className="rank-row highlighted" style={rowStyle(0)}>
              <span className="rank-num">1</span>
              <span className="rank-name">YourBrand</span>
              <span className="rank-tag good">You ranked here</span>
            </div>
            <div className="rank-row" style={rowStyle(1)}><span className="rank-num">2</span><span className="rank-name">Competitor A</span></div>
            <div className="rank-row" style={rowStyle(2)}><span className="rank-num">3</span><span className="rank-name">Competitor B</span></div>
            <div className="rank-row" style={rowStyle(3)}><span className="rank-num">4</span><span className="rank-name">Competitor C</span></div>
          </div>
          <div className="sq-foot">
            <CheckIcon size={11} color="var(--green)"/>
            Before you ranked here.
          </div>
        </div>
        </div>

        <div className="sq-col" style={nowColStyle}>
          <div className="sq-era">Now</div>
        <div className="sq-card now">
          <div className="sq-brand-head">
            <div className="sq-brand">
              <span className="sq-brand-icon"><ChatGPT size={22} pad={0} bg="transparent" rounded={5}/></span>
              <span className="sq-brand-name">ChatGPT</span>
            </div>
            <div className="sq-year now-year">2026</div>
          </div>
          <div className="sq-query now-query">
            <span className="chat-dot"/>
            Which PM tool do agencies actually recommend?
          </div>
          <div className="rank-list">
            <div className="rank-row" style={rowStyleR(0)}><span className="rank-num">1</span><span className="rank-name">Competitor A</span></div>
            <div className="rank-row" style={rowStyleR(1)}><span className="rank-num">2</span><span className="rank-name">Competitor B</span></div>
            <div className="rank-row" style={rowStyleR(2)}><span className="rank-num">3</span><span className="rank-name">Competitor C</span></div>
            <div className="rank-row absent" style={rowStyleR(3)}>
              <span className="rank-num absent-num">—</span>
              <span className="rank-name absent-name">YourBrand</span>
              <span className="rank-tag bad">Not mentioned</span>
            </div>
          </div>
          <div className="sq-foot now-foot">
            <span className="alert-dot"/>
            But now you appear here.
          </div>
        </div>
        </div>
      </div>

      <p className="sq-cta reveal delay-3">
        Your SEO playbook can't reach the AI answer box.{' '}
        <a href="#how" className="sq-cta-link">
          See how we fix that
          <svg width="12" height="12" viewBox="0 0 12 12" fill="none" style={{marginLeft:4, verticalAlign:'-1px'}}>
            <path d="M3 6h6m0 0L6 3m3 3L6 9" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round"/>
          </svg>
        </a>
      </p>
    </div>
  </section>
  );
};

const HowItWorksV2 = () => (
  <section className="section" id="how">
    <div className="wrap">
      <div className="center-stack reveal">
        <span className="eyebrow">How it works</span>
        <h2 className="display-md" style={{margin: '24px 0px 46.48px'}}>From invisible to recommended in 30 days.</h2>
      </div>

      <div className="steps-v2">
        <svg className="steps-arrows" viewBox="0 0 1200 700" preserveAspectRatio="none" aria-hidden="true">
          <defs>
            <filter id="arrow-rough" x="-5%" y="-5%" width="110%" height="110%">
              <feTurbulence type="fractalNoise" baseFrequency="0.02" numOctaves="2" seed="7"/>
              <feDisplacementMap in="SourceGraphic" scale="2.2"/>
            </filter>
            <marker id="arrow-step" viewBox="0 0 12 12" refX="6" refY="6" markerWidth="8" markerHeight="8" orient="auto-start-reverse">
              <path d="M1,1 L11,6 L1,11 Z" fill="#B8BEC9"/>
            </marker>
          </defs>
          <g filter="url(#arrow-rough)" stroke="#B8BEC9" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round" fill="none" strokeDasharray="5 7">
            {/* 1 → 2 : loops UP over the row */}
            <g className="reveal reveal-fade steps-arrow" style={{transitionDelay:'135ms'}}>
              <path d="M 267 90 Q 400 -7 533 90" markerEnd="url(#arrow-step)"/>
            </g>
            {/* 2 → 3 : loops DOWN under the row */}
            <g className="reveal reveal-fade steps-arrow" style={{transitionDelay:'225ms'}}>
              <path d="M 667 600 Q 800 697 933 600" markerEnd="url(#arrow-step)"/>
            </g>
          </g>
        </svg>
        <div className="step-v2 reveal delay-1" style={{fontFamily: 'Inter'}}>
          <div className="step-num">01 · BENCHMARK</div>
          <h3>Audit your visibility.</h3>
          <p>We map 40–80 high-intent queries for your ICP, then score how every AI engine currently answers them — and who they cite instead of you.</p>
          <div className="step-visual sv1">
            <div className="sv1-row bad"><span className="q">"best crm for agencies"</span><span className="s">0% SoV</span></div>
            <div className="sv1-row bad"><span className="q">"aeo tools for saas"</span><span className="s">0% SoV</span></div>
            <div className="sv1-row warn"><span className="q">"webflow alternatives"</span><span className="s">4% SoV</span></div>
            <div className="sv1-row ok"><span className="q">"notion for client work"</span><span className="s">18% SoV</span></div>
          </div>
        </div>

        <div className="step-v2 reveal delay-2" style={{fontFamily: 'Inter'}}>
          <div className="step-num">02 · PUBLISH</div>
          <h3>We place the citations.</h3>
          <p>Our editorial team writes and publishes across Reddit, Quora, press, Substack and authority blogs — the exact sources AI platforms read.</p>
          <div className="step-visual sv2">
            <div className="reddit-post">
              <div className="rp-top">
                <span className="rp-avatar" style={{background:'#FF4500'}}>r/</span>
                <div>
                  <div className="rp-sub">r/SaaS · u/answerexposure</div>
                </div>
                <div className="rp-platform"><Reddit size={12} pad={0} bg="transparent" rounded={3}/></div>
              </div>
              <div className="rp-reply-body">ChatGPT and Perplexity cite where <strong>practitioners discuss tools</strong> — not your landing page. One client went 0% → 34% SoV in 60 days.</div>
              <div className="rp-reply-foot">
                <span>▲ 284</span>
                <span>💬 42</span>
                <span className="rp-pub">✓ Published</span>
              </div>
            </div>
          </div>
        </div>

        <div className="step-v2 reveal delay-3" style={{fontFamily: 'Inter'}}>
          <div className="step-num">03 · COMPOUND</div>
          <h3>Watch share of voice grow.</h3>
          <p>Track citation count, share of voice and query coverage live. Each placement keeps earning for months as crawlers re-ingest it.</p>
          <div className="step-visual sv3">
            <div className="sv3-top">
              <div>
                <div className="sv3-lbl">Share of voice</div>
                <div className="sv3-big">38%</div>
              </div>
              <div className="sv3-delta">↑ 22 pts</div>
            </div>
            <svg viewBox="0 0 200 80" preserveAspectRatio="none" style={{width:'100%', height:70, display:'block'}}>
              <defs>
                <linearGradient id="g3" x1="0" y1="0" x2="0" y2="1">
                  <stop offset="0%" stopColor="#635BFF" stopOpacity="0.3"/>
                  <stop offset="100%" stopColor="#635BFF" stopOpacity="0"/>
                </linearGradient>
              </defs>
              <path d="M0,70 L20,66 L40,62 L60,54 L80,50 L100,38 L120,30 L140,22 L160,14 L180,8 L200,4"
                    stroke="#635BFF" strokeWidth="2" fill="none" strokeLinecap="round"/>
              <path d="M0,70 L20,66 L40,62 L60,54 L80,50 L100,38 L120,30 L140,22 L160,14 L180,8 L200,4 L200,80 L0,80Z"
                    fill="url(#g3)"/>
            </svg>
          </div>
        </div>
      </div>
    </div>
  </section>
);

const PlatformsV2 = () => {
  const plats = [
    {name:'Reddit', share:'46% OF AI CITATIONS', desc:'The single largest source LLMs pull from. We publish contextual, helpful replies that earn upvotes — and stay cited for months.', tags:['r/SaaS','r/smallbusiness','r/marketing'], color:'#FF4500', Ico: Reddit},
    {name:'Quora', share:'AUTHORITATIVE Q&A', desc:'Evergreen answers that rank at the top of question threads and feed directly into ChatGPT and Claude context.', tags:['Expert answers','Top voted'], color:'#B92B27', Ico: Quora},
    {name:'X (Twitter)', share:'REAL-TIME SIGNAL', desc:'Thought-leader threads and replies from seeded accounts. Grok and xAI-powered engines surface these first.', tags:['Founder voice','Deep threads'], color:'#000000', Ico: XLogo},
    {name:'Substack', share:'HIGH SEMANTIC WEIGHT', desc:'Long-form essays in respected newsletters become canonical references that AI engines cite verbatim.', tags:['Newsletters','Guest posts'], color:'#FF6719', Ico: Substack},
    {name:'Digital press', share:'STRONG DOMAIN AUTHORITY', desc:'Yahoo Finance, Digital Journal, AP News. Premium outlets weight heavily in Perplexity and Google AI rankings.', tags:['Press releases','Feature placements'], color:'#0078D4', Ico: PressLogo},
    {name:'Authority blogs', share:'NICHE SIGNAL', desc:'Industry-specific publications in your vertical. Small sites, high trust. Frequently quoted in niche AI answers.', tags:['Vertical coverage','Interviews'], color:'#00B8D9', Ico: AuthorityLogo},
  ];
  return (
    <section className="section" id="platforms" style={{background:'var(--bg-soft)'}}>
      <div className="wrap">
        <div className="center-stack reveal">
          <span className="eyebrow">Where we publish</span>
          <h2 className="display-md" style={{margin: '24px 0px 46.48px'}}>Six channels. One goal:<br/>get AI to name you.</h2>
          <p className="lede" style={{margin: '20px auto 0'}}>
            We don't run ads or pump out SEO drafts. We organically seed
            contextually relevant mentions that community moderators respect
            and AI models trust.
          </p>
        </div>

        <div className="plats">
          {plats.map((p, i) => (
            <div key={i} className={"plat reveal delay-" + Math.min(i+1, 6)} style={{'--plat-color': p.color}}>
              <div className="logo"><p.Ico size={22} pad={0} bg="transparent" rounded={4}/></div>
              <div className="name">{p.name}</div>
              <div className="share" style={{fontFamily: 'Inter'}}>{p.share}</div>
              <div className="desc">{p.desc}</div>
              <div className="tags">
                {p.tags.map((t,j) => <span key={j} className="tag">{t}</span>)}
              </div>
            </div>
          ))}
        </div>
      </div>
    </section>
  );
};

const ShowcaseV2 = () => (
  <section className="showcase" id="showcase">
    <div className="wrap">
      <div className="center-stack reveal">
        <span className="eyebrow">The platform</span>
        <h2 className="display-lg" style={{margin: '24px 0px 63.08px'}}>
          Every citation,<br/>measured.
        </h2>
        <p className="lede" style={{margin: '24px auto 0'}}>
          A single dashboard for AI visibility. Watch every engine, every query,
          every placement, compounding in real time.
        </p>
      </div>

      <div className="reveal delay-1">
        <ProductMockupLarge/>
      </div>
    </div>
  </section>
);

const useCountUp = (target, duration = 1400, key = 0, active = true) => {
  const [val, setVal] = React.useState(0);
  React.useEffect(() => {
    if (!active) return;
    let raf; const start = performance.now();
    const tick = (t) => {
      const p = Math.min(1, (t - start) / duration);
      const eased = 1 - Math.pow(1 - p, 3);
      setVal(target * eased);
      if (p < 1) raf = requestAnimationFrame(tick);
    };
    raf = requestAnimationFrame(tick);
    return () => cancelAnimationFrame(raf);
  }, [target, duration, key, active]);
  return val;
};

const useInView = (threshold = 0.35) => {
  const ref = React.useRef(null);
  const [inView, setInView] = React.useState(false);
  React.useEffect(() => {
    if (!ref.current || inView) return;
    const io = new IntersectionObserver((entries) => {
      entries.forEach(e => {
        if (e.isIntersecting) { setInView(true); io.disconnect(); }
      });
    }, { threshold });
    io.observe(ref.current);
    return () => io.disconnect();
  }, [threshold, inView]);
  return [ref, inView];
};

const ProductMockupLarge = () => {
  const [activeNav, setActiveNav] = React.useState('Overview');
  const [engines, setEngines] = React.useState({
    ChatGPT: true, Claude: true, Perplexity: true, Gemini: true, Grok: true, 'Google AI': true
  });
  const activeCount = Object.values(engines).filter(Boolean).length;
  // chart value scales with how many engines are enabled
  const scale = activeCount / 6;

  // Count-up values keyed to scale so they re-animate on toggle
  const citations = Math.round(1284 * scale);
  const sov = Math.round(38 * scale);
  const queries = Math.round(412 * scale);
  // Trigger animations when the panel scrolls into view
  const [panelRef, inView] = useInView(0.25);

  const citationsN = useCountUp(citations, 1200, scale, inView);
  const sovN = useCountUp(sov, 1200, scale, inView);
  const queriesN = useCountUp(queries, 1200, scale, inView);

  // Chart path animates in once the panel is visible
  const [drawn, setDrawn] = React.useState(false);
  React.useEffect(() => {
    if (!inView) return;
    const t = setTimeout(() => setDrawn(true), 120);
    return () => clearTimeout(t);
  }, [inView]);

  // Cursor state — just a dot on the line, no numeric tooltip
  const [hover, setHover] = React.useState(null);
  const youPath = React.useMemo(() => {
    // amplitude depends on scale — fewer engines = flatter rise
    const endY = 8 + (1 - scale) * 80;
    const midY = 56 + (1 - scale) * 50;
    return `M0,148 C60,142 120,132 180,${118 - (scale-0.5)*10} C240,${102 - (scale-0.5)*14} 300,${80 - (scale-0.5)*18} 360,${midY} C420,${38 + (1-scale)*44} 480,${22 + (1-scale)*56} 540,${14 + (1-scale)*68} L600,${endY}`;
  }, [scale]);
  const endY = 8 + (1 - scale) * 80;

  // Measure the 'you' line so the cursor dot sits exactly on it
  const youPathRef = React.useRef(null);
  const [pathLen, setPathLen] = React.useState(0);
  React.useEffect(() => {
    if (youPathRef.current) setPathLen(youPathRef.current.getTotalLength());
  }, [youPath]);
  const hoverPt = React.useMemo(() => {
    if (hover === null || !youPathRef.current || !pathLen) return null;
    let lo = 0, hi = pathLen;
    for (let i = 0; i < 18; i++) {
      const mid = (lo + hi) / 2;
      const p = youPathRef.current.getPointAtLength(mid);
      if (p.x < hover) lo = mid; else hi = mid;
    }
    return youPathRef.current.getPointAtLength((lo + hi) / 2);
  }, [hover, pathLen, youPath]);

  // Ticker rows
  const baseRows = [
    {ico: Reddit, name: 'r/SaaS · u/marketing_pro', title: '"What\'s the best AEO service for B2B in 2026?"', date: 'Apr 12', status: 'live', pill: '● Live', cites: '12', color: 'violet'},
    {ico: DigitalJournal, name: 'Digital Journal · Press feature', title: '"AnswerExposure leads the AEO category as AI Overviews reshape search"', date: 'Apr 10', status: 'cited', pill: '● Cited 8×', cites: '8', color: 'violet'},
    {ico: Substack, name: 'The Growth Letter · Substack', title: '"Inside the shift from SEO to AEO for mid-market SaaS"', date: 'Apr 08', status: 'live', pill: '● Live', cites: '5', color: 'violet'},
    {ico: Quora, name: 'Quora · Top answer', title: '"Which AEO tool covers Reddit publishing?"', date: 'Apr 05', status: 'draft', pill: '● Drafting', cites: '—', color: 'muted'},
  ];
  const newRowPool = [
    {ico: Reddit, name: 'r/startups · u/founder_dave', title: '"Has anyone used AnswerExposure? Looking for AEO recs"', date: 'Just now', status: 'live', pill: '● Live', cites: '1', color: 'violet'},
    {ico: XLogo, name: '@growthreply · thread', title: '"The SEO-to-AEO playbook nobody\'s talking about"', date: 'Just now', status: 'live', pill: '● Live', cites: '2', color: 'violet'},
    {ico: Medium, name: 'Medium · @benjaminstrat', title: '"Why we switched from Surfer to AnswerExposure"', date: 'Just now', status: 'live', pill: '● Live', cites: '3', color: 'violet'},
  ];
  const [rows, setRows] = React.useState(baseRows);
  const [flash, setFlash] = React.useState(null);
  React.useEffect(() => {
    let i = 0;
    const id = setInterval(() => {
      const next = newRowPool[i % newRowPool.length];
      i++;
      setRows((r) => [{...next, _k: Date.now()}, ...r.slice(0, 3)]);
      setFlash(Date.now());
    }, 4200);
    return () => clearInterval(id);
  }, []);

  const toggleEngine = (name) => setEngines(e => ({...e, [name]: !e[name]}));

  const navItems = ['Overview', 'AI Perception', 'Keywords', 'Competition', 'Citations', 'Blog Posts'];
  const engineList = [
    {name: 'ChatGPT', Logo: ChatGPT},
    {name: 'Claude', Logo: Claude},
    {name: 'Perplexity', Logo: Perplexity},
    {name: 'Gemini', Logo: Gemini},
    {name: 'Grok', Logo: Grok},
    {name: 'Google AI', Logo: Copilot},
  ];

  return (
  <div className="showcase-panel" ref={panelRef}>
    <div className="showcase-header">
      <div className="showcase-dots"><span/><span/><span/></div>
      <div className="showcase-title">app.answerexposure.com / {activeNav.toLowerCase().replace(/ /g,'-')}</div>
    </div>
    <div className="showcase-body">
      <aside className="showcase-side">
        <div className="side-label">Workspace</div>
        {navItems.map(item => (
          <div key={item}
               className={"side-item" + (activeNav === item ? " active" : "")}
               onClick={() => setActiveNav(item)}
               style={{cursor:'pointer'}}>
            <span className="sb-dot"/> {item}
            {item === 'Blog Posts' && <span className="side-addon">Add-on</span>}
          </div>
        ))}

        <div className="side-label">Platforms <span style={{color:'var(--muted)', fontWeight:400}}>· {activeCount}/6</span></div>
        {engineList.map(({name, Logo}) => (
          <div key={name}
               className={"side-item engine-toggle" + (engines[name] ? "" : " off")}
               onClick={() => toggleEngine(name)}
               style={{cursor:'pointer'}}>
            <Logo size={14} pad={0} bg="transparent" rounded={3}/> {name}
            <span className="engine-check" aria-hidden>{engines[name] ? '●' : '○'}</span>
          </div>
        ))}
      </aside>

      <div className="showcase-main" data-page={activeNav.toLowerCase().replace(/ /g,'-')}>
        {activeNav === 'Overview' && (
          <PageOverview
            activeCount={activeCount} scale={scale}
            citationsN={citationsN} sovN={sovN} queriesN={queriesN}
            drawn={drawn} pathLen={pathLen} youPath={youPath} endY={endY}
            youPathRef={youPathRef} hover={hover} setHover={setHover} hoverPt={hoverPt}
            rows={rows} flash={flash}
          />
        )}
        {activeNav === 'AI Perception' && <PageAIPerception/>}
        {activeNav === 'Keywords'      && <PageKeywords/>}
        {activeNav === 'Competition'   && <PageCompetition/>}
        {activeNav === 'Citations'     && <PageCitations/>}
        {activeNav === 'Blog Posts'    && <PageBlogPosts/>}
      </div>
    </div>
  </div>
  );
};

const AnimatedStatNumber = ({ big, sup }) => {
  const ref = React.useRef(null);
  const target = parseFloat(big);
  const isFloat = /\./.test(big);
  const decimals = isFloat ? (big.split('.')[1] || '').length : 0;
  const [display, setDisplay] = React.useState(big);

  React.useEffect(() => {
    if (!ref.current) return;
    if (window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches) return;
    const el = ref.current;
    let raf, started = false;
    const io = new IntersectionObserver((entries) => {
      for (const e of entries) {
        if (e.isIntersecting && !started) {
          started = true;
          io.disconnect();
          const startTime = performance.now();
          const duration = 1400;
          const tick = (now) => {
            const t = Math.min(1, (now - startTime) / duration);
            const eased = 1 - Math.pow(1 - t, 3);
            const cur = target * eased;
            setDisplay(cur.toFixed(decimals));
            if (t < 1) raf = requestAnimationFrame(tick);
            else setDisplay(big);
          };
          // start from zero
          setDisplay((0).toFixed(decimals));
          raf = requestAnimationFrame(tick);
        }
      }
    }, { threshold: 0.4 });
    io.observe(el);
    return () => { io.disconnect(); if (raf) cancelAnimationFrame(raf); };
  }, [big]);

  // aria-label preserves the real, final value for screen readers & bots
  return (
    <span ref={ref} aria-label={big + sup}>
      <span aria-hidden="true">{display}</span>
      <sup aria-hidden="true">{sup}</sup>
    </span>
  );
};

const StatsV2 = () => {
  const data = [
    {big: "46", sup: "%", label: "of AI citations come from Reddit threads — the single largest source LLMs reference."},
    {big: "3.4", sup: "×", label: "average visibility lift across ChatGPT, Claude and Perplexity within 90 days."},
    {big: "147", sup: "", label: "strategic citations placed per month on high-authority community and press sources."},
    {big: "6", sup: "/6", label: "major AI engines monitored continuously — ChatGPT, Claude, Gemini, Perplexity, Grok, Copilot."},
  ];
  return (
    <section className="section" id="results">
      <div className="wrap">
        <div className="center-stack reveal">
          <span className="eyebrow">Results in numbers</span>
          <h2 className="display-md" style={{margin: '24px 0px 46.48px'}}>Benchmarks from real campaigns.</h2>
          <p className="lede" style={{margin:'20px auto 0'}}>
            Aggregated across 130+ client engagements, measured by our tracking
            dashboard and third-party crawlers.
          </p>
        </div>

        <div className="stats-v2">
          {data.map((s, i) => (
            <div key={i} className={"stat-v2 reveal delay-" + Math.min(i+1, 6)}>
              <div className="s-big"><AnimatedStatNumber big={s.big} sup={s.sup}/></div>
              <div className="s-lbl">{s.label}</div>
            </div>
          ))}
        </div>
      </div>
    </section>
  );
};

Object.assign(window, { LogoWallV2, ProblemV2, HowItWorksV2, PlatformsV2, ShowcaseV2, StatsV2 });
