// Story + Science sections
const { useEffect: useEffectS, useRef: useRefS, useState: useStateS } = React;

/**
 * CountUp — animates a number from 0 to `to` with easeOutQuart over `duration`ms,
 * triggered when the element enters the viewport. The `suffix` (e.g. "+") fades
 * in as a subtle slide once the count lands. If `to === 0` it sits still — used
 * intentionally for the "0 ANSWERS" stat where stillness is the punchline.
 *
 * Respects prefers-reduced-motion: skips animation, shows final state immediately.
 */
function CountUp({ to, suffix = '', duration = 1400, delay = 0 }) {
  const ref = useRefS(null);
  const startedRef = useRefS(false);
  const [val, setVal] = useStateS(0);
  const [suffixIn, setSuffixIn] = useStateS(false);

  useEffectS(() => {
    if (!ref.current || startedRef.current) return;
    const reduced = window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches;
    const target = parseInt(to, 10);

    const obs = new IntersectionObserver(([entry]) => {
      if (!entry.isIntersecting || startedRef.current) return;
      startedRef.current = true;

      // No animation paths: NaN, zero, reduced-motion → snap to final.
      if (isNaN(target) || target === 0 || reduced) {
        setVal(isNaN(target) ? 0 : target);
        setSuffixIn(true);
        return;
      }

      const startTime = performance.now() + delay;
      let raf;
      const tick = (now) => {
        const elapsed = now - startTime;
        if (elapsed < 0) { raf = requestAnimationFrame(tick); return; }
        const t = Math.min(1, elapsed / duration);
        const eased = 1 - Math.pow(1 - t, 4); // easeOutQuart
        setVal(Math.round(target * eased));
        if (t < 1) raf = requestAnimationFrame(tick);
        else setTimeout(() => setSuffixIn(true), 80);
      };
      raf = requestAnimationFrame(tick);
    }, { threshold: 0.45, rootMargin: '0px 0px -10% 0px' });

    obs.observe(ref.current);
    return () => obs.disconnect();
  }, [to, duration, delay]);

  return (
    <span ref={ref} className="countup">
      <span className="countup-num">{val}</span>
      <span className={`countup-suffix ${suffixIn ? 'in' : ''}`}>{suffix}</span>
    </span>
  );
}

function Story() {
  return (
    <section id="story" className="sec story">
      <div className="container">
        <div className="story-letter" data-reveal>
          <div className="cap" style={{color: 'var(--muted)', marginBottom: 28}}>— A letter for you</div>

          <p>IBS. Autoimmune Disease. Anxiety. Insomnia. And I'll just go ahead and say it out loud, depression. A chronic, painful, 15 year cycle. 5 colonoscopies before the age of 30. $25K of my hard earned money trying to figure out why my body was so broken. All while continuing to grind at my high-profile NYC corporate jobs, because work comes first, right?</p>

          <p className="lt">Forget work. Let's talk about dating.</p>

          <p>It's hard enough. But dating in New York City? That's a whole different beast. Telling a cute stranger that I haven't had a bowel movement in over a week - and that I couldn't eat 90% of the menu at this expensive restaurant he brought me to - isn't quite the ice breaker.</p>

          <p>So I ate it all. I hid it all. I faked my smile. I faked my health. Until I just couldn't anymore.</p>

          <p className="lt">I felt so broken.</p>

          <p>The truth is, it's the system that's broken. $1,000 to book a specialist. Six months for the appointment. Two hours in the waiting room. Ten minutes with the doctor. <em>"It's the stress. Have you tried going gluten free? Get more steps in."</em></p>

          <p>You leave, you book the next one, you hope the next test reveals something. It never does. Meanwhile the industry hands you tests, supplements, programs at absurd prices. And they can, because we are desperate enough to pay at the slightest hope of healing.</p>

          <p>By my 30s I was unrecognizable. Infusion treatments between meetings. Steroids that wrecked me. Medications I couldn't pronounce. The isolation took over. I hated what I felt like, what I looked like: constantly bloated, nothing fit anymore. My job was suffering, relationships were suffering. I was losing control of everything. And the stress of it all just made it worse. The cycle ran.</p>

          <p>My husband watched it all unfold, until he just couldn't anymore. He said: <em>we're going to figure this out ourselves.</em> So he started building. Every meal. Every bowel movement. Every medication. Every mood. Find the pattern. Predict the flare. Stop the flare.</p>

          <blockquote className="serif">
            "Predict the flare." Sounds like a dream. Except, <em className="serif-it">it worked.</em> It is the only thing that has ever worked.
          </blockquote>

          <p>My husband built this app to heal me.</p>

          <p>Now we're building it to heal the world.</p>

          <div className="signoff">
            <div className="sig-name serif-it">— Anisha</div>
            <div className="cap" style={{color: 'var(--muted)'}}>Co-founder, Gutsy</div>
          </div>
        </div>
      </div>

      <style>{`
        .story { background: var(--bg-2); border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); }
        .story-letter {
          font-size: 19px; line-height: 1.7; color: var(--ink-2);
          max-width: 720px;
          margin: 0 auto;
        }
        .story-letter p { margin-bottom: 22px; }
        .story-letter em { font-style: italic; color: var(--ink); }
        .story-letter .lt {
          font-family: 'Fraunces', serif;
          font-size: 32px;
          font-weight: 300;
          letter-spacing: -0.02em;
          margin: 36px 0 28px;
          color: var(--ink);
        }
        .story-letter blockquote {
          margin: 44px 0;
          font-size: 34px;
          line-height: 1.2;
          font-weight: 300;
          letter-spacing: -0.02em;
          padding-left: 28px;
          border-left: 2px solid var(--accent);
          color: var(--ink);
        }
        .story-letter blockquote em { color: var(--accent); font-style: italic; }
        [data-theme="dark"] .story-letter blockquote em { color: var(--accent-glow); }
        .signoff { margin-top: 56px; }
        .sig-name { font-size: 32px; color: var(--ink); }

        @media (max-width: 720px) {
          .story-letter { font-size: 17px; }
          .story-letter .lt { font-size: 26px; }
          .story-letter blockquote { font-size: 26px; padding-left: 22px; margin: 36px 0; }
        }
      `}</style>
    </section>
  );
}

function Science() {
  const [hours, setHours] = useStateS(34);
  const [playing, setPlaying] = useStateS(true);
  const phaseRef = useRefS(0);
  const rafRef = useRefS(null);

  useEffectS(() => {
    let raf;
    const tick = () => {
      if (playing) {
        phaseRef.current += 0.008;
      }
      raf = requestAnimationFrame(tick);
    };
    tick();
    return () => cancelAnimationFrame(raf);
  }, [playing]);

  // Attribution timeline state
  const [step, setStep] = useStateS(0);
  useEffectS(() => {
    const id = setInterval(() => setStep(s => (s + 1) % 4), 2200);
    return () => clearInterval(id);
  }, []);

  return (
    <section id="science" className="sec science">
      <div className="container">
        <div className="sci-head" data-reveal>
          <span className="eyebrow"><span className="num">02</span><span className="dot" /> The Science · Transit Time</span>
          <h2 className="serif sci-title">
            Every other app blames<br />
            <em className="serif-it">the wrong</em> meal.
          </h2>
          <p className="sci-sub">
            Most reactions fire <em className="serif-it">12 to 72 hours</em> after the bite.
            Gutsy is the first tracker built around that.
          </p>
        </div>

        {/* THREE CARDS */}
        <div className="sci-grid">
          {/* CARD 1 — TRANSIT */}
          <div className="sci-card" data-reveal>
            <div className="sci-card-head">
              <div className="cap">01 · Transit</div>
              <div className="cap" style={{color:'var(--muted)'}}>Your Personal Pace</div>
            </div>
            <div className="dial">
              <DialCanvas hours={hours} />
              <div className="dial-center">
                <div className="dial-num serif">{hours}<span className="dial-unit">h</span></div>
                <div className="cap" style={{color:'var(--muted)'}}>plate to gone</div>
              </div>
            </div>
            <input type="range" min="12" max="72" value={hours} onChange={e=>setHours(+e.target.value)} className="dial-slider" />
            <p className="sci-card-cap">Every body moves food at its own pace. <em className="serif-it">Gutsy learns yours.</em></p>
            <div className="cap" style={{color:'var(--muted)', marginTop: 'auto'}}>Typical range · 12h–72h+</div>
          </div>

          {/* CARD 2 — JOURNEY */}
          <div className="sci-card" data-reveal>
            <div className="sci-card-head">
              <div className="cap">02 · Journey</div>
              <div className="cap" style={{color:'var(--muted)'}}>Where reactions begin</div>
            </div>
            <JourneyAnim />
            <p className="sci-card-cap">Food doesn't hit you in the moment. It hits you <em className="serif-it">hours — sometimes days —</em> later.</p>
            <div className="cap" style={{color:'var(--muted)', marginTop: 'auto'}}>Most IBS reactions begin in the colon</div>
          </div>

          {/* CARD 3 — ATTRIBUTION timeline graph */}
          <div className="sci-card" data-reveal>
            <div className="sci-card-head">
              <div className="cap">03 · Attribution</div>
              <div className="cap" style={{color:'var(--muted)'}}>The math no app does</div>
            </div>
            <AttribGraph step={step} />
            <p className="sci-card-cap" style={{marginTop: 12}}>Your 3pm bloat today? <em className="serif-it">Tuesday's dinner.</em></p>
            <div className="cap" style={{color:'var(--muted)', marginTop: 'auto'}}>Retroactive correlation engine · +44h lag</div>
          </div>
        </div>

        <div className="sci-foot" data-reveal>
          <p className="serif sci-foot-line">
            <em className="serif-it">The first</em> trigger engine built around <em className="serif-it">real human transit time.</em>
          </p>
          <p className="cap" style={{color:'var(--muted)', marginTop: 16}}>Not a food diary. Not a FODMAP lookup. A gut-intelligence system.</p>
        </div>
      </div>

      <style>{`
        .science { background: var(--bg); }
        .sci-head { max-width: 900px; margin-bottom: 80px; }
        .sci-title { margin-top: 28px; font-size: clamp(44px, 7vw, 110px); line-height: 0.95; letter-spacing: -0.04em; font-weight: 300; }
        .sci-title em { color: var(--accent); }
        [data-theme="dark"] .sci-title em { color: var(--accent-glow); }
        .sci-sub { margin-top: 32px; font-size: 20px; color: var(--ink-2); max-width: 600px; }
        .sci-sub em { color: var(--accent); }
        [data-theme="dark"] .sci-sub em { color: var(--accent-glow); }

        .sci-grid {
          display: grid;
          grid-template-columns: repeat(3, 1fr);
          gap: 24px;
        }
        .sci-card {
          background: var(--paper);
          border: 1px solid var(--line);
          padding: 32px;
          display: flex; flex-direction: column;
          min-height: 540px;
          position: relative;
        }
        .sci-card-head {
          display: flex; justify-content: space-between;
          padding-bottom: 20px; margin-bottom: 32px;
          border-bottom: 1px solid var(--line);
        }
        .sci-card-cap {
          font-family: 'Fraunces', serif;
          font-weight: 300;
          font-size: 26px;
          line-height: 1.25;
          letter-spacing: -0.02em;
          color: var(--ink);
          margin-top: 32px; margin-bottom: 24px;
        }
        .sci-card-cap em { color: var(--accent); }
        [data-theme="dark"] .sci-card-cap em { color: var(--accent-glow); }

        .dial { position: relative; height: 220px; display: flex; align-items: center; justify-content: center; }
        .dial-center { position: absolute; text-align: center; }
        .dial-num { font-size: 72px; line-height: 1; font-weight: 300; letter-spacing: -0.04em; color: var(--ink); }
        .dial-unit { font-size: 28px; color: var(--muted); margin-left: 4px; }
        .dial-slider {
          width: 100%; margin-top: 16px;
          -webkit-appearance: none; appearance: none;
          height: 1px; background: var(--line);
          outline: none;
        }
        .dial-slider::-webkit-slider-thumb {
          -webkit-appearance: none; appearance: none;
          width: 14px; height: 14px; border-radius: 50%;
          background: var(--accent);
          cursor: pointer;
          border: 2px solid var(--bg);
          box-shadow: 0 0 0 1px var(--accent);
        }
        .dial-slider::-moz-range-thumb {
          width: 14px; height: 14px; border-radius: 50%;
          background: var(--accent);
          border: 2px solid var(--bg);
          cursor: pointer;
        }

        .attrib { padding: 12px 0; }
        .attrib-row { display: flex; align-items: center; gap: 16px; }
        .attrib-row .cap { width: 36px; color: var(--muted); }
        .attrib-pill {
          flex: 1;
          padding: 14px 18px;
          border: 1px solid var(--line);
          background: var(--bg);
          font-size: 14px;
          opacity: 0.3;
          transform: translateX(-8px);
          transition: all 0.6s cubic-bezier(0.2,0.8,0.2,1);
        }
        .attrib-pill.on { opacity: 1; transform: none; }
        .attrib-pill .cap { color: var(--accent); width: auto; margin-right: 10px; }
        .attrib-pill.sym { border-color: var(--accent); color: var(--ink); }
        .attrib-arrow {
          margin: 16px 0 16px 52px;
          display: flex; align-items: center; gap: 14px;
          opacity: 0; transform: translateY(-4px);
          transition: all 0.6s 0.2s;
        }
        .attrib-arrow.on { opacity: 1; transform: none; }
        .attrib-arrow .arrow-line {
          flex: 1; height: 1px;
          background: linear-gradient(to right, var(--accent), transparent);
        }
        .attrib-conclusion {
          margin-top: 32px;
          font-family: 'Fraunces', serif;
          font-weight: 300;
          font-size: 24px;
          line-height: 1.25;
          letter-spacing: -0.02em;
          color: var(--ink);
          opacity: 0; transform: translateY(8px);
          transition: all 0.6s;
        }
        .attrib-conclusion.on { opacity: 1; transform: none; }
        .attrib-conclusion em { color: var(--accent); }
        [data-theme="dark"] .attrib-conclusion em { color: var(--accent-glow); }

        .sci-foot { margin-top: 80px; max-width: 900px; }
        .sci-foot-line {
          font-size: clamp(28px, 4vw, 56px);
          line-height: 1.15;
          letter-spacing: -0.03em;
          font-weight: 300;
          color: var(--ink);
        }
        .sci-foot-line em { color: var(--accent); }
        [data-theme="dark"] .sci-foot-line em { color: var(--accent-glow); }

        @media (max-width: 1100px) {
          .sci-grid { grid-template-columns: 1fr; gap: 16px; }
          .sci-card { min-height: auto; padding: 24px; }
          .sci-card-cap { font-size: 22px; margin-top: 24px; margin-bottom: 18px; }
        }
        @media (max-width: 720px) {
          .sci-foot { margin-top: 56px; }
          .sci-foot-line { font-size: 26px; }
        }
      `}</style>
    </section>
  );
}

function AttribGraph({ step }) {
  const ref = useRefS(null);
  useEffectS(() => {
    const c = ref.current; if (!c) return;
    const ctx = c.getContext('2d');
    const dpr = window.devicePixelRatio || 1;
    const w = 360, h = 200;
    c.width = w*dpr; c.height = h*dpr; ctx.setTransform(dpr,0,0,dpr,0,0);
    let raf, t = 0;
    const accent = getComputedStyle(document.documentElement).getPropertyValue('--accent').trim();
    const glow = getComputedStyle(document.documentElement).getPropertyValue('--accent-glow').trim();
    const line = 'rgba(125,135,128,0.25)';
    // synthetic symptom data — calm, calm, spike (44h after Tue meal)
    const data = [0.15, 0.18, 0.16, 0.22, 0.2, 0.25, 0.45, 0.62, 0.85, 0.78, 0.6, 0.4, 0.3];
    const days = ['M','T','W','Th','F','S','Su'];
    const draw = () => {
      t += 0.012;
      ctx.clearRect(0,0,w,h);
      const padX = 30, padY = 20, pH = h - padY*2 - 18, pW = w - padX*2;
      // grid
      for (let i=0;i<4;i++){ const y = padY + (pH/3)*i; ctx.beginPath(); ctx.moveTo(padX,y); ctx.lineTo(w-padX,y); ctx.strokeStyle=line; ctx.lineWidth=0.5; ctx.setLineDash([2,3]); ctx.stroke(); }
      ctx.setLineDash([]);
      // meal marker (Tue)
      const mealX = padX + pW * (1.5/(data.length-1));
      ctx.beginPath(); ctx.moveTo(mealX, padY); ctx.lineTo(mealX, padY+pH); ctx.strokeStyle = 'rgba(125,135,128,0.4)'; ctx.lineWidth=1; ctx.stroke();
      ctx.fillStyle = 'rgba(125,135,128,0.7)'; ctx.font = '9px JetBrains Mono'; ctx.fillText('MEAL', mealX-12, padY-6);
      // symptom marker (Thu spike)
      const symX = padX + pW * (8/(data.length-1));
      ctx.beginPath(); ctx.moveTo(symX, padY); ctx.lineTo(symX, padY+pH); ctx.strokeStyle = accent; ctx.lineWidth=1; ctx.setLineDash([3,3]); ctx.stroke(); ctx.setLineDash([]);
      ctx.fillStyle = accent; ctx.fillText('FLARE', symX-14, padY-6);
      // line graph reveal
      const reveal = Math.min(1, t*0.5);
      ctx.beginPath();
      const pts = data.map((v,i)=>[padX + pW*(i/(data.length-1)), padY+pH - v*pH]);
      const upTo = Math.floor(reveal * pts.length);
      for (let i=0;i<=upTo && i<pts.length;i++){ const [x,y]=pts[i]; if(i===0) ctx.moveTo(x,y); else { const px = pts[i-1]; ctx.bezierCurveTo(px[0]+(x-px[0])/2, px[1], x-(x-px[0])/2, y, x, y); } }
      ctx.strokeStyle = accent; ctx.lineWidth = 2; ctx.stroke();
      // fill under
      if (upTo > 1){ ctx.lineTo(pts[Math.min(upTo,pts.length-1)][0], padY+pH); ctx.lineTo(padX, padY+pH); ctx.closePath(); const grd = ctx.createLinearGradient(0,padY,0,padY+pH); grd.addColorStop(0, accent+'33'); grd.addColorStop(1, accent+'00'); ctx.fillStyle = grd; ctx.fill(); }
      // pulsing dot at flare
      const symY = padY+pH - data[8]*pH;
      const pulse = (Math.sin(t*2)+1)/2;
      ctx.beginPath(); ctx.arc(symX, symY, 4+pulse*4, 0, Math.PI*2); ctx.fillStyle = accent; ctx.globalAlpha = 0.3*pulse; ctx.fill(); ctx.globalAlpha=1;
      ctx.beginPath(); ctx.arc(symX, symY, 3, 0, Math.PI*2); ctx.fillStyle = accent; ctx.fill();
      // arc connecting meal -> flare
      ctx.beginPath();
      ctx.moveTo(mealX, padY+pH+4);
      ctx.bezierCurveTo(mealX+30, padY+pH+24, symX-30, padY+pH+24, symX, padY+pH+4);
      ctx.strokeStyle = glow; ctx.lineWidth = 1; ctx.setLineDash([3,3]); ctx.stroke(); ctx.setLineDash([]);
      ctx.fillStyle = accent; ctx.font = '9px JetBrains Mono'; ctx.textAlign='center'; ctx.fillText('+44H', (mealX+symX)/2, padY+pH+30);
      // day axis
      ctx.fillStyle = 'rgba(125,135,128,0.6)'; ctx.font='9px JetBrains Mono'; ctx.textAlign='center';
      days.forEach((d,i)=>{ const x = padX + pW*(i/(days.length-1)); ctx.fillText(d, x, h-2); });
      raf = requestAnimationFrame(draw);
    };
    draw();
    return () => cancelAnimationFrame(raf);
  }, [step]);
  return <canvas ref={ref} style={{width:'100%',height:200,display:'block'}} />;
}

function DialCanvas({ hours }) {
  const ref = useRefS(null);
  useEffectS(() => {
    const c = ref.current; if (!c) return;
    const ctx = c.getContext('2d');
    const dpr = window.devicePixelRatio || 1;
    const size = 220;
    c.width = size * dpr; c.height = size * dpr;
    ctx.setTransform(dpr,0,0,dpr,0,0);

    let raf, t = 0;
    const accent = getComputedStyle(document.documentElement).getPropertyValue('--accent').trim() || '#1a3a2a';
    const muted = getComputedStyle(document.documentElement).getPropertyValue('--line').trim();

    const draw = () => {
      t += 0.008;
      ctx.clearRect(0,0,size,size);
      const cx = size/2, cy = size/2;
      // outer ticks
      for (let i=0; i<60; i++) {
        const a = (i/60) * Math.PI * 2 - Math.PI/2;
        const r1 = 100, r2 = i % 5 === 0 ? 92 : 96;
        ctx.beginPath();
        ctx.moveTo(cx + Math.cos(a)*r1, cy + Math.sin(a)*r1);
        ctx.lineTo(cx + Math.cos(a)*r2, cy + Math.sin(a)*r2);
        ctx.strokeStyle = muted; ctx.lineWidth = 1; ctx.stroke();
      }
      // arc to hours
      const pct = (hours - 12) / 60;
      const startA = -Math.PI/2;
      const endA = startA + pct * Math.PI * 2;
      ctx.beginPath();
      ctx.arc(cx, cy, 86, startA, endA);
      ctx.strokeStyle = accent; ctx.lineWidth = 2; ctx.stroke();

      // pulsing dot at end
      const dx = cx + Math.cos(endA)*86;
      const dy = cy + Math.sin(endA)*86;
      const pulse = (Math.sin(t*3)+1)/2;
      ctx.beginPath();
      ctx.arc(dx,dy, 4 + pulse*3, 0, Math.PI*2);
      ctx.fillStyle = accent; ctx.globalAlpha = 0.3 + pulse*0.7;
      ctx.fill();
      ctx.globalAlpha = 1;
      ctx.beginPath();
      ctx.arc(dx,dy, 3, 0, Math.PI*2);
      ctx.fillStyle = accent; ctx.fill();

      // labels 12 / 36 / 72
      ctx.fillStyle = muted; ctx.font = '10px JetBrains Mono'; ctx.textAlign = 'center';
      ['12','27','42','57'].forEach((label, i) => {
        const a = (i/4)*Math.PI*2 - Math.PI/2;
        ctx.fillText(label+'h', cx + Math.cos(a)*108, cy + Math.sin(a)*108 + 4);
      });

      raf = requestAnimationFrame(draw);
    };
    draw();
    return () => cancelAnimationFrame(raf);
  }, [hours]);
  return <canvas ref={ref} style={{width:220,height:220}} />;
}

function JourneyAnim() {
  const ref = useRefS(null);
  useEffectS(() => {
    const c = ref.current; if (!c) return;
    const ctx = c.getContext('2d');
    const dpr = window.devicePixelRatio || 1;
    const w = 360, h = 220;
    c.width = w*dpr; c.height = h*dpr; ctx.setTransform(dpr,0,0,dpr,0,0);
    let raf, t = 0;
    const accent = getComputedStyle(document.documentElement).getPropertyValue('--accent').trim();
    const glow = getComputedStyle(document.documentElement).getPropertyValue('--accent-glow').trim();
    const muted = getComputedStyle(document.documentElement).getPropertyValue('--line').trim();

    // smooth bezier path through stomach -> small intestine -> colon
    const pts = [[40,60],[80,50],[120,80],[100,130],[160,170],[220,150],[260,110],[310,130],[320,80]];
    const sample = (u) => {
      // catmull-rom-ish smoothing
      const seg = u * (pts.length-1);
      const i = Math.floor(seg);
      const f = seg - i;
      const p0 = pts[Math.max(0,i-1)], p1 = pts[i], p2 = pts[Math.min(pts.length-1,i+1)], p3 = pts[Math.min(pts.length-1,i+2)];
      const ff = f*f, fff = ff*f;
      const x = 0.5*((2*p1[0])+(-p0[0]+p2[0])*f+(2*p0[0]-5*p1[0]+4*p2[0]-p3[0])*ff+(-p0[0]+3*p1[0]-3*p2[0]+p3[0])*fff);
      const y = 0.5*((2*p1[1])+(-p0[1]+p2[1])*f+(2*p0[1]-5*p1[1]+4*p2[1]-p3[1])*ff+(-p0[1]+3*p1[1]-3*p2[1]+p3[1])*fff);
      return [x,y];
    };
    const draw = () => {
      t += 0.0028; // slower
      ctx.clearRect(0,0,w,h);
      ctx.beginPath();
      for (let u=0; u<=1; u+=0.01) { const [x,y] = sample(u); if(u===0) ctx.moveTo(x,y); else ctx.lineTo(x,y); }
      ctx.strokeStyle = muted; ctx.lineWidth = 1.2; ctx.setLineDash([2,5]); ctx.stroke(); ctx.setLineDash([]);
      // single fluid bolus with trailing ghosts
      for (let k=0; k<6; k++) {
        const u = ((t - k*0.018) % 1 + 1) % 1;
        const [x,y] = sample(u);
        const fade = 1 - k/6;
        const grd = ctx.createRadialGradient(x,y,0,x,y,22*fade);
        grd.addColorStop(0, glow);
        grd.addColorStop(1, glow.replace(')', ',0)').replace('rgb','rgba'));
        ctx.globalAlpha = fade*0.5; ctx.fillStyle = grd;
        ctx.beginPath(); ctx.arc(x,y,22*fade,0,Math.PI*2); ctx.fill();
      }
      ctx.globalAlpha = 1;
      const u = (t % 1 + 1) % 1; const [hx,hy] = sample(u);
      ctx.beginPath(); ctx.arc(hx,hy,4,0,Math.PI*2); ctx.fillStyle = accent; ctx.fill();
      ctx.fillStyle = 'rgba(125,135,128,0.5)'; ctx.font = '9px JetBrains Mono'; ctx.textAlign='left';
      [['STOMACH',35,40,'2-4H'],['SM. INTESTINE',130,105,'3-5H'],['COLON',280,65,'12-36H']].forEach(([l,x,y,d])=>{ ctx.fillStyle='rgba(125,135,128,0.6)'; ctx.fillText(l,x,y); ctx.fillStyle=accent; ctx.fillText(d,x,y+12); });
      raf = requestAnimationFrame(draw);
    };
    draw();
    return () => cancelAnimationFrame(raf);
  }, []);
  return <canvas ref={ref} style={{width:'100%',height:220, display:'block'}} />;
}

// Compressed home version: headline + stats + opening + signoff + link to /story
function StoryCompact() {
  return (
    <section id="story" className="sec story-compact">
      <div className="container">
        <div className="storyc-grid">
          <div className="storyc-left" data-reveal>
            <span className="eyebrow"><span className="num">06</span><span className="dot" /> The Founding Story</span>
            <h2 className="serif storyc-title">
              "It's stress.<br />
              Eat more <em className="serif-it">fiber.</em><br />
              Try yoga."
            </h2>
            <p className="storyc-tagline">
              Built by <em className="serif-it">love.</em> Backed by <em className="serif-it">science.</em>
            </p>
            <div className="storyc-stats">
              {[
                { num: '20', suffix: '+', label: 'Years of suffering', delay: 0   },
                { num: '20', suffix: '+', label: 'Specialists',        delay: 160 },
                { num: '5',  suffix: '',  label: 'Colonoscopies',      delay: 320 },
                { num: '0',  suffix: '',  label: 'Answers',            delay: 0   },
              ].map((s, i) => (
                <div key={i} className="storyc-stat">
                  <div className="ssn serif">
                    <CountUp to={s.num} suffix={s.suffix} delay={s.delay} />
                  </div>
                  <div className="cap">{s.label}</div>
                </div>
              ))}
            </div>
          </div>

          <div className="storyc-right" data-reveal>
            <div className="cap" style={{color: 'var(--muted)', marginBottom: 20}}>— A letter for you</div>
            <p>IBS. Autoimmune Disease. Anxiety. Insomnia. And I'll just go ahead and say it out loud, depression. A chronic, painful, 15 year cycle. 5 colonoscopies before the age of 30. $25K of my hard earned money trying to figure out why my body was so broken.</p>
            <blockquote className="serif">
              All systems have failed me. So we are <em className="serif-it">building our own.</em>
            </blockquote>
            <div className="signoff">
              <div className="sig-name serif-it">— Anisha</div>
              <div className="cap" style={{color: 'var(--muted)'}}>Co-founder, Gutsy</div>
            </div>
            <a href="/story" className="storyc-link">
              Read the full letter <span className="arr">→</span>
            </a>
          </div>
        </div>
      </div>

      <style>{`
        .story-compact {
          background: var(--bg-2);
          border-top: 1px solid var(--line);
          border-bottom: 1px solid var(--line);
          padding: 100px 0;
        }
        .storyc-grid {
          display: grid;
          grid-template-columns: 1.05fr 1fr;
          gap: 80px;
          align-items: center;
        }
        .storyc-title {
          margin-top: 24px;
          font-size: clamp(40px, 5.4vw, 84px);
          line-height: 0.96;
          letter-spacing: -0.04em;
          font-weight: 300;
        }
        .storyc-title em { color: var(--accent); }
        [data-theme="dark"] .storyc-title em { color: var(--accent-glow); }
        .storyc-tagline {
          margin-top: 28px;
          font-family: 'Fraunces', 'Instrument Serif', serif;
          font-weight: 300;
          font-size: clamp(20px, 1.7vw, 26px);
          letter-spacing: -0.02em;
          line-height: 1.3;
          color: var(--ink);
          padding-left: 18px;
          border-left: 2px solid var(--accent);
          max-width: 480px;
        }
        .storyc-tagline em {
          color: var(--accent);
          font-family: 'Instrument Serif', serif;
          font-style: italic;
        }
        [data-theme="dark"] .storyc-tagline em { color: var(--accent-glow); }

        .storyc-stats {
          margin-top: 36px;
          display: grid;
          grid-template-columns: repeat(4, 1fr);
          gap: 1px;
          background: var(--line);
          border: 1px solid var(--line);
        }
        .storyc-stat { background: var(--bg-2); padding: 22px 18px; }
        .storyc-stat .ssn { font-size: 44px; line-height: 1; font-weight: 300; letter-spacing: -0.04em; color: var(--ink); }
        .storyc-stat .cap { color: var(--muted); margin-top: 8px; display: block; font-size: 10px; }

        .storyc-right { font-size: 17px; line-height: 1.6; color: var(--ink-2); }
        .storyc-right p { margin-bottom: 14px; max-width: 480px; }
        .storyc-right .lt { font-family: 'Fraunces', serif; font-size: 24px; font-weight: 300; margin-bottom: 18px; color: var(--ink); }
        .storyc-right blockquote {
          margin: 22px 0;
          font-size: 28px; line-height: 1.2;
          font-weight: 300;
          letter-spacing: -0.02em;
          padding-left: 22px;
          border-left: 2px solid var(--accent);
          color: var(--ink);
        }
        .storyc-right blockquote em { color: var(--accent); }
        [data-theme="dark"] .storyc-right blockquote em { color: var(--accent-glow); }
        .signoff { margin-top: 28px; }
        .sig-name { font-size: 24px; color: var(--ink); }

        .storyc-link {
          display: inline-flex; align-items: center; gap: 8px;
          margin-top: 28px;
          padding: 12px 18px;
          font-family: 'JetBrains Mono', monospace;
          font-size: 11px; letter-spacing: 0.18em; text-transform: uppercase;
          color: var(--ink);
          border: 1px solid var(--ink);
          text-decoration: none;
          background: transparent;
          transition: all 0.4s;
        }
        .storyc-link:hover { background: var(--ink); color: var(--bg); }
        .storyc-link .arr { transition: transform 0.3s; }
        .storyc-link:hover .arr { transform: translateX(3px); }

        @media (max-width: 1000px) {
          .storyc-grid { grid-template-columns: 1fr; gap: 48px; }
          .storyc-stats { grid-template-columns: repeat(2, 1fr); }
          .storyc-stat .ssn { font-size: 38px; }
        }
        @media (max-width: 600px) {
          .story-compact { padding: 80px 0; }
        }
      `}</style>
    </section>
  );
}

window.Story = Story;
window.Science = Science;
window.StoryCompact = StoryCompact;
