// grittt landing — center-focus screen carousel + story sections + footer.
// Uses primitives from grittt-ui.jsx (L, PhoneShot, Btn, Eyebrow, RoundArrow, Wordmark)
// and the live app screens from warm-coach/*.

// ── Center-focus carousel ─────────────────────────────
const CAROUSEL = [
  { label: 'Dashboard',    blurb: "Yesterday's score, your streak, and the 7-day trend in one honest glance.", el: () => <A_Dashboard showBecoming={false} /> },
  { label: 'Discipline',   blurb: 'Build the habits that lift you, control the ones that drag you down.',      el: () => <A_Discipline /> },
  { label: 'Control',      blurb: 'Quit smoking, sugar or scrolling — every clean day counted.',               el: () => <A_Control /> },
  { label: 'Habit detail', blurb: 'Tap any habit for its streak, 30-day history and impact.',                  el: () => <A_HabitDetail /> },
  { label: 'Fuel',         blurb: 'Quick three-tap check-in, or full macro tracking — your call.',             el: () => <A_Fuel /> },
  { label: 'Strength',     blurb: 'Rate the session out of ten, or log every set and rep.',                    el: () => <A_Strength /> },
  { label: 'Challenges',   blurb: 'Pacts and streaks across health and lifestyle that you actually feel.',     el: () => <A_Challenges /> },
  { label: 'Calendar',     blurb: 'Every day scored as a heat-map — strong, mixed or slipped at a glance.',   el: () => <HE_CalendarV2 /> },
  { label: 'Countdown',    blurb: "Days left until your big occasion, with the chain you're building.",        el: () => <HE_CountdownV2 /> },
  { label: 'AI Coach',     blurb: 'AI reads your pattern and finds exactly where you slip.',                   el: () => <A_Insights /> },
  { label: 'The crowd',    blurb: 'See how 48,210 others do — and the exact day most people lose the streak.', el: () => <A_InsightsGraph /> },
  { label: 'Screen time',  blurb: "Tap any app for a week's usage graph and the AI read on your detox.",      el: () => <A_ScreenTime /> },
  { label: 'App detail',   blurb: "Tap any app for a week's usage graph and the AI read on your detox.",      el: () => <A_ScreenTimeDetail /> },
];

function ScreenCarousel() {
  const isMobile = useIsMobile(760);
  const trackRef = React.useRef(null);
  const items = React.useRef([]);
  const [active, setActive] = React.useState(0);
  const raf = React.useRef(0);
  const period = React.useRef(0);
  const wheelLock = React.useRef(false);
  const wheelTimeout = React.useRef(0);
  const phoneScale = isMobile ? 0.44 : 0.506;

  const N = CAROUSEL.length;
  const K = 3; // edge clones each side so the rail stays full (no gaps) and ends can centre
  const loop = [];
  for (let j = N - K; j < N; j++) loop.push({ ...CAROUSEL[j], _base: j });   // leading clones
  for (let i = 0; i < N; i++)     loop.push({ ...CAROUSEL[i], _base: i });   // real screens
  for (let j = 0; j < K; j++)     loop.push({ ...CAROUSEL[j], _base: j });   // trailing clones

  const apply = () => {
    const track = trackRef.current;
    if (!track) return;
    const center = track.scrollLeft + track.clientWidth / 2;
    let best = Infinity, bestI = 0;
    items.current.forEach((el, i) => {
      if (!el) return;
      const elCenter = el.offsetLeft + el.offsetWidth / 2;
      const d = Math.abs(elCenter - center);
      const norm = Math.min(1, d / 240);       // ~one item pitch → neighbours clearly recede
      const centerScale = isMobile ? 1.5 : 1.35; // mobile center is 10% bigger
      const scale = centerScale - 0.65 * norm; // center pops, neighbours down to 0.7
      el.style.transform = `scale(${scale})`;
      el.style.opacity = String(1 - 0.5 * norm);
      el.style.zIndex = String(100 - Math.round(d / 10));
      el.firstChild.style.filter = `saturate(${1 - 0.5 * norm})`;
      if (d < best) { best = d; bestI = i; }
    });
    setActive(loop[bestI]._base);
  };

  const onScroll = () => {
    cancelAnimationFrame(raf.current);
    raf.current = requestAnimationFrame(apply);
  };

  const centerIndex = (idx, smooth) => {
    const track = trackRef.current;
    const el = items.current[idx];
    if (!track || !el) return;
    const left = el.offsetLeft + el.offsetWidth / 2 - track.clientWidth / 2;
    track.scrollTo({ left, behavior: smooth ? 'smooth' : 'auto' });
  };

  React.useEffect(() => {
    const t = trackRef.current;
    period.current = items.current[K + 1].offsetLeft - items.current[K].offsetLeft; // item pitch
    centerIndex(K, false);                 // start on the first real screen, clones fill its left
    requestAnimationFrame(apply);

    t.addEventListener('scroll', onScroll, { passive: true });
    const onResize = () => {
      if (items.current[K] && items.current[K + 1]) {
        period.current = items.current[K + 1].offsetLeft - items.current[K].offsetLeft;
      }
      apply();
    };
    window.addEventListener('resize', onResize);
    const onWheel = (e) => {
      if (Math.abs(e.deltaX) > Math.abs(e.deltaY)) {
        e.preventDefault();
        if (!wheelLock.current) {
          wheelLock.current = true;
          step(e.deltaX > 0 ? 1 : -1, true);
        }
        // keep the lock for as long as this gesture keeps sending wheel
        // events, and only release it once it pauses — so no matter how
        // hard or long the scroll, it advances exactly one screen.
        clearTimeout(wheelTimeout.current);
        wheelTimeout.current = setTimeout(() => { wheelLock.current = false; }, 150);
      }
    };
    t.addEventListener('wheel', onWheel, { passive: false });

    // drag to scroll
    let down = false, sx = 0, ss = 0;
    const dn = (e) => { down = true; sx = e.pageX; ss = t.scrollLeft; t.style.cursor = 'grabbing'; };
    const mv = (e) => { if (down) t.scrollLeft = ss - (e.pageX - sx); };
    const up = () => { down = false; t.style.cursor = 'grab'; };
    t.addEventListener('pointerdown', dn);
    window.addEventListener('pointermove', mv);
    window.addEventListener('pointerup', up);

    return () => {
      t.removeEventListener('scroll', onScroll);
      window.removeEventListener('resize', onResize);
      t.removeEventListener('wheel', onWheel);
      t.removeEventListener('pointerdown', dn);
      window.removeEventListener('pointermove', mv);
      window.removeEventListener('pointerup', up);
      cancelAnimationFrame(raf.current);
      clearTimeout(wheelTimeout.current);
    };
  }, []);

  // centre the nearest instance of a base screen
  const goToBase = (baseIdx) => {
    const track = trackRef.current;
    if (!track) return;
    const center = track.scrollLeft + track.clientWidth / 2;
    let best = Infinity, bestI = K;
    items.current.forEach((el, i) => {
      if (!el || loop[i]._base !== baseIdx) return;
      const d = Math.abs(el.offsetLeft + el.offsetWidth / 2 - center);
      if (d < best) { best = d; bestI = i; }
    });
    centerIndex(bestI, true);
  };

  const step = (dir, instant) => {
    const track = trackRef.current;
    if (!track) return;
    track.scrollBy({ left: dir * (period.current || 265), behavior: instant ? 'auto' : 'smooth' });
  };

  const cur = CAROUSEL[active];

  return (
    <section id="screens" style={{ padding: isMobile ? '32px 0 40px' : '40px 0 52px', overflow: 'hidden' }}>
      <div style={{ maxWidth: 1000, margin: '0 auto', padding: isMobile ? '0 16px' : '0 24px', textAlign: 'center', marginBottom: 0 }}>
        <Eyebrow style={{ marginBottom: 12 }}>Every screen</Eyebrow>
        <h2 style={{
          fontFamily: L.display, fontWeight: 800, fontSize: 'clamp(28px, 4vw, 44px)',
          lineHeight: 1, letterSpacing: '-0.03em', color: L.ink, margin: 0,
        }}>Built to keep you honest.</h2>
      </div>

      {/* the rail — full of screens both sides, centre one highlighted */}
      <div
        ref={trackRef}
        className="carousel"
        style={{
          display: 'flex', alignItems: 'center', gap: isMobile ? 12 : 18, position: 'relative',
          overflowX: 'auto', padding: isMobile ? '4px 0 0' : '6px 0 0', cursor: 'grab',
          minHeight: isMobile ? 700 : 760,
          WebkitOverflowScrolling: 'touch', scrollBehavior: 'smooth',
          scrollSnapType: isMobile ? 'x mandatory' : 'none',
        }}
      >
        {loop.map((s, i) => (
          <div
            key={i}
            ref={(el) => (items.current[i] = el)}
            onClick={() => goToBase(s._base)}
            style={{
              flex: '0 0 auto',
              transformOrigin: 'center center',
              transition: 'transform .25s cubic-bezier(.22,.61,.36,1), opacity .25s ease',
              cursor: 'pointer', willChange: 'transform',
              scrollSnapAlign: isMobile ? 'center' : 'none',
            }}
          >
            <div style={{ filter: 'drop-shadow(0 34px 46px rgba(20,17,13,0.20))', transition: 'filter .18s ease' }}>
              <PhoneShot scale={phoneScale}>{s.el()}</PhoneShot>
            </div>
          </div>
        ))}
      </div>

      {/* active caption + controls */}
      <div style={{ maxWidth: 560, margin: '-16px auto 0', padding: isMobile ? '0 16px' : '0 24px', textAlign: 'center' }}>
        <div style={{
          fontFamily: L.display, fontWeight: 700, fontSize: isMobile ? 17 : 21, letterSpacing: '-0.02em',
          color: L.ink, display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 10,
        }}>
          <span style={{ fontFamily: L.mono, fontSize: 13, color: L.ink3 }}>{String(active + 1).padStart(2, '0')}</span>
          {cur.label}
        </div>

        <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 16, marginTop: 18 }}>
          <RoundArrow dir={-1} onClick={() => step(-1)} />
          <div style={{ display: 'flex', gap: 6 }}>
            {CAROUSEL.map((_, i) => (
              <button
                key={i}
                onClick={() => goToBase(i)}
                aria-label={'screen ' + (i + 1)}
                style={{
                  width: i === active ? 20 : 7, height: 7, borderRadius: 999, border: 'none',
                  background: i === active ? L.ink : L.rule, cursor: 'pointer',
                  transition: 'width .2s ease, background .2s ease', padding: 0,
                }}
              />
            ))}
          </div>
          <RoundArrow dir={1} onClick={() => step(1)} />
        </div>
      </div>
    </section>
  );
}

// ── AI section: techy 4-card grid ────────
function AISection() {
  const isMobile = useIsMobile(760);

  const cards = [
    {
      number: '01',
      title: 'Your habits today',
      status: 'LIVE DATA',
      dot: L.hype,
      visual: (
        <div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
          {[
            { label: 'Food',     done: true },
            { label: 'Physical', done: true },
            { label: 'Mental',   done: true },
            { label: 'Health',   done: true },
          ].map((habit, i) => (
            <div key={i} style={{
              display: 'flex', alignItems: 'center', gap: 9,
              padding: '4px 8px', borderRadius: 6,
              background: habit.done ? `${L.hype}12` : 'rgba(255,255,255,0.04)',
              border: `1px solid ${habit.done ? L.hype + '35' : 'rgba(255,255,255,0.07)'}`,
            }}>
              <div style={{
                width: 13, height: 13, borderRadius: 3, flexShrink: 0,
                background: habit.done ? L.hype : 'transparent',
                border: `1.5px solid ${habit.done ? L.hype : 'rgba(255,255,255,0.2)'}`,
                display: 'flex', alignItems: 'center', justifyContent: 'center',
              }}>
                {habit.done && <span style={{ fontSize: 8, color: L.ink, lineHeight: 1, fontWeight: 800 }}>✓</span>}
              </div>
              <span style={{
                fontFamily: L.mono, fontSize: 10, letterSpacing: '0.06em',
                color: habit.done ? 'rgba(255,255,255,0.75)' : 'rgba(255,255,255,0.28)',
              }}>{habit.label}</span>
            </div>
          ))}
        </div>
      ),
    },
    {
      number: '02',
      title: 'Patterns AI discovered',
      status: 'ANALYZING',
      dot: L.hype,
      visual: (
        <div style={{ display: 'flex', flexDirection: 'column', gap: 5 }}>
          {[
            { text: 'Weekend slumps — day 6 & 7', hi: false },
            { text: 'Morning peak 06:00 – 08:00',  hi: true  },
            { text: 'Day 7 drop-off risk: 68%',     hi: false },
          ].map((row, i) => (
            <div key={i} style={{
              padding: '5px 8px', borderRadius: 5,
              background: row.hi ? `${L.hype}20` : 'rgba(255,255,255,0.04)',
              border: `1px solid ${row.hi ? L.hype + '50' : 'rgba(255,255,255,0.07)'}`,
              fontFamily: L.mono, fontSize: 10,
              color: row.hi ? L.hype : 'rgba(255,255,255,0.32)',
              letterSpacing: '0.03em',
              display: 'flex', alignItems: 'center', gap: 6,
            }}>
              {row.hi && <span style={{ fontSize: 8, color: L.hype }}>▶</span>}
              {row.text}
            </div>
          ))}
        </div>
      ),
    },
    {
      number: '03',
      title: 'Future you in 6 months',
      status: 'PROJECTED',
      dot: '#4ADE80',
      visual: (
        <div style={{ display: 'flex', alignItems: 'flex-end', justifyContent: 'center', gap: 18 }}>
          <div style={{ textAlign: 'center', opacity: 0.25 }}>
            <div style={{ width: 16, height: 16, borderRadius: '50%', background: '#fff', margin: '0 auto 3px' }} />
            <div style={{ width: 24, height: 28, borderRadius: '7px 7px 0 0', background: '#fff', margin: '0 auto' }} />
            <div style={{ fontFamily: L.mono, fontSize: 8, color: '#fff', marginTop: 5, letterSpacing: '0.1em' }}>NOW</div>
          </div>
          <div style={{ fontFamily: L.mono, fontSize: 15, color: L.hype, marginBottom: 18, lineHeight: 1 }}>{'→'}</div>
          <div style={{ textAlign: 'center' }}>
            <div style={{ width: 22, height: 22, borderRadius: '50%', background: L.hype, margin: '0 auto 3px', boxShadow: `0 0 12px ${L.hype}` }} />
            <div style={{ width: 30, height: 38, borderRadius: '9px 9px 0 0', background: L.hype, margin: '0 auto', boxShadow: `0 0 18px ${L.hype}55` }} />
            <div style={{ fontFamily: L.mono, fontSize: 8, color: L.hype, marginTop: 5, letterSpacing: '0.1em' }}>+6M</div>
          </div>
        </div>
      ),
    },
    {
      number: '04',
      title: "Today's coaching plan",
      status: 'AI GENERATED',
      dot: L.hype,
      visual: (
        <div style={{ display: 'flex', flexDirection: 'column', gap: 7 }}>
          {[
            { text: '07:00 — Cold shower streak', done: true  },
            { text: 'No phone before 09:00',       done: false },
            { text: '10,000 steps before noon',    done: false },
          ].map((item, i) => (
            <div key={i} style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
              <div style={{
                width: 13, height: 13, borderRadius: 4, flexShrink: 0,
                border: `1.5px solid ${item.done ? L.hype : 'rgba(255,255,255,0.2)'}`,
                background: item.done ? L.hype : 'transparent',
                display: 'flex', alignItems: 'center', justifyContent: 'center',
              }}>
                {item.done && <span style={{ fontSize: 8, color: L.ink, lineHeight: 1 }}>✓</span>}
              </div>
              <span style={{
                fontFamily: L.mono, fontSize: 10, letterSpacing: '0.03em',
                color: item.done ? 'rgba(255,255,255,0.65)' : 'rgba(255,255,255,0.28)',
                textDecoration: item.done ? 'none' : 'none',
              }}>{item.text}</span>
            </div>
          ))}
        </div>
      ),
    },
  ];

  return (
    <section id="ai" style={{
      padding: isMobile ? '56px 16px 64px' : '72px 32px 88px',
      background: L.ink,
    }}>
      <div style={{ maxWidth: 1200, margin: '0 auto' }}>

        {/* Header */}
        <div style={{ textAlign: 'center', marginBottom: isMobile ? 48 : 64 }}>
          <h2 style={{
            fontFamily: L.display, fontWeight: 800, fontSize: 'clamp(32px, 5vw, 56px)',
            lineHeight: 1.05, letterSpacing: '-0.035em', color: '#fff',
            margin: '0 auto', maxWidth: 800, textWrap: 'balance',
          }}>
            Not just a tracker.<br />
            <span style={{
              backgroundImage: `linear-gradient(${L.hype}, ${L.hype})`,
              backgroundRepeat: 'no-repeat',
              backgroundSize: '100% 0.25em',
              backgroundPosition: '0 100%',
              boxDecorationBreak: 'clone',
              WebkitBoxDecorationBreak: 'clone',
            }}>
              An AI that shows you the future and coaches you forward.
            </span>
          </h2>
        </div>

        {/* 4 Techy Cards */}
        <div style={{
          display: 'grid',
          gridTemplateColumns: isMobile ? '1fr 1fr' : 'repeat(4, 1fr)',
          gap: isMobile ? 12 : 16,
        }}>
          {cards.map((card, i) => (
            <div
              key={i}
              style={{
                position: 'relative', overflow: 'hidden',
                background: 'rgba(255,255,255,0.04)',
                border: '1px solid rgba(255,255,255,0.08)',
                borderRadius: 16,
                padding: isMobile ? '18px 14px 16px' : '24px 20px 20px',
                cursor: 'default',
                transition: 'border-color 0.25s ease, background 0.25s ease',
                display: 'flex', flexDirection: 'column',
              }}
              onMouseEnter={(e) => {
                e.currentTarget.style.borderColor = `${L.hype}60`;
                e.currentTarget.style.background = 'rgba(184,242,58,0.05)';
              }}
              onMouseLeave={(e) => {
                e.currentTarget.style.borderColor = 'rgba(255,255,255,0.08)';
                e.currentTarget.style.background = 'rgba(255,255,255,0.04)';
              }}
            >
              {/* top accent */}
              <div style={{
                position: 'absolute', top: 0, left: 0, right: 0, height: 2,
                background: `linear-gradient(90deg, ${L.hype}, transparent)`,
                opacity: 0.55,
              }} />

              {/* number */}
              <div style={{
                fontFamily: L.mono, fontSize: 11, fontWeight: 700,
                color: L.hype, letterSpacing: '0.18em', marginBottom: 14,
              }}>{card.number}</div>

              {/* visual */}
              <div style={{ marginBottom: 18, minHeight: 52 }}>
                {card.visual}
              </div>

              {/* title */}
              <h3 style={{
                fontFamily: L.display, fontWeight: 800,
                fontSize: isMobile ? 15 : 'clamp(16px, 1.5vw, 20px)',
                color: '#fff', lineHeight: 1.2, letterSpacing: '-0.02em',
                margin: '0 0 auto',
              }}>{card.title}</h3>

              {/* status */}
              <div style={{ display: 'flex', alignItems: 'center', gap: 7, marginTop: 16 }}>
                <span style={{
                  width: 6, height: 6, borderRadius: '50%', flexShrink: 0,
                  background: card.dot, boxShadow: `0 0 6px ${card.dot}`,
                }} />
                <span style={{
                  fontFamily: L.mono, fontSize: 10, fontWeight: 600,
                  color: 'rgba(255,255,255,0.3)', letterSpacing: '0.14em',
                }}>{card.status}</span>
              </div>
            </div>
          ))}
        </div>

      </div>
    </section>
  );
}

// ── generic story section: text column + media column ──
function Story({ id, eyebrow, title, points, media, flip, bg, columns }) {
  const isMobile = useIsMobile(900);
  return (
    <section id={id} style={{ background: bg || 'transparent', padding: '8px 0' }}>
      <div className="story" style={{
        maxWidth: 1200, margin: '0 auto', padding: '56px 32px',
        display: 'grid', gridTemplateColumns: columns || '1fr 1fr', gap: isMobile ? 24 : 56, alignItems: 'center',
        direction: flip ? 'rtl' : 'ltr',
      }}>
        <div style={{ direction: 'ltr', textAlign: isMobile ? 'center' : 'left' }}>
          <Eyebrow style={{ marginBottom: 14 }}>{eyebrow}</Eyebrow>
          <h2 style={{
            fontFamily: L.display, fontWeight: 800, fontSize: 'clamp(30px, 3.6vw, 44px)',
            lineHeight: 1.02, letterSpacing: '-0.03em', color: L.ink, margin: 0, textWrap: 'balance',
          }}>{title}</h2>
          {points && (
            <div style={{ display: 'flex', flexDirection: 'column', gap: 14, marginTop: 26 }}>
              {points.map((p, i) => (
                <div key={i} style={{ display: 'flex', gap: 14, alignItems: 'flex-start', justifyContent: isMobile ? 'center' : 'flex-start', textAlign: 'left' }}>
                  <div style={{
                    flex: '0 0 auto', marginTop: 2, width: 34, height: 34, borderRadius: 10,
                    background: p.accent || L.ink, color: p.accent === L.hype ? L.ink : '#fff',
                    display: 'flex', alignItems: 'center', justifyContent: 'center',
                    fontFamily: L.display, fontWeight: 800, fontSize: 13,
                  }}>{p.tag}</div>
                  <div>
                    <div style={{ fontFamily: L.display, fontWeight: 700, fontSize: 16, color: L.ink, letterSpacing: '-0.01em' }}>{p.title}</div>
                    <div style={{ fontFamily: L.body, fontSize: 14.5, lineHeight: 1.45, color: L.ink2, marginTop: 2 }}>{p.body}</div>
                  </div>
                </div>
              ))}
            </div>
          )}
        </div>
        <div style={{ direction: 'ltr', display: 'flex', justifyContent: 'center' }}>
          {media}
        </div>
      </div>
    </section>
  );
}

// a labelled phone for persona pairs (quick vs detailed)
function PersonaPhone({ tag, persona, scale = 0.5, accent, children }) {
  const isMobile = useIsMobile(760);
  // on mobile, fill most of the viewport so one screen shows at a time
  // (the row scrolls horizontally to reach the rest)
  const effScale = isMobile ? 0.675 : scale;
  return (
    <figure style={{ margin: 0, display: 'flex', flexDirection: 'column', alignItems: 'center', flex: '0 0 auto' }}>
      <div style={{
        display: 'inline-flex', alignItems: 'center', gap: 7, marginBottom: 14,
        padding: '6px 12px', borderRadius: 999, background: accent || L.ink,
        color: accent === L.hype ? L.ink : '#fff',
        fontFamily: L.display, fontWeight: 700, fontSize: 12, letterSpacing: '0.12em', textTransform: 'uppercase',
      }}>{tag}</div>
      <div>
        <PhoneShot scale={effScale}>{children}</PhoneShot>
      </div>
      <figcaption style={{ marginTop: 14, fontFamily: L.body, fontSize: 13.5, color: L.ink2, textAlign: 'center', maxWidth: isMobile ? 280 : 200, lineHeight: 1.4 }}>
        {persona}
      </figcaption>
    </figure>
  );
}

function SinglePhone({ scale = 0.66, children }) {
  return (
    <div style={{ filter: 'drop-shadow(0 44px 60px rgba(20,17,13,0.20))' }}>
      <PhoneShot scale={scale}>{children}</PhoneShot>
    </div>
  );
}

// a LIVE, tappable phone (pointer events on) for interactive demos
function InteractivePhone({ scale = 0.72, children }) {
  const W = 402, H = 874;
  return (
    <div style={{ filter: 'drop-shadow(0 44px 60px rgba(20,17,13,0.20))' }}>
      <div style={{ width: W * scale, height: H * scale, position: 'relative', flex: '0 0 auto' }}>
        <div style={{ width: W, height: H, transform: `scale(${scale})`, transformOrigin: 'top left' }}>
          <IOSDevice width={W} height={H}>{children}</IOSDevice>
        </div>
      </div>
    </div>
  );
}

// a labelled, LIVE tappable phone — InteractivePhone with PersonaPhone's tag/caption
function InteractivePersonaPhone({ tag, persona, scale = 0.56, accent, children }) {
  const isMobile = useIsMobile(760);
  const effScale = isMobile ? 0.675 : scale;
  return (
    <figure style={{ margin: 0, display: 'flex', flexDirection: 'column', alignItems: 'center', flex: '0 0 auto' }}>
      <div style={{
        display: 'inline-flex', alignItems: 'center', gap: 7, marginBottom: 14,
        padding: '6px 12px', borderRadius: 999, background: accent || L.ink,
        color: accent === L.hype ? L.ink : '#fff',
        fontFamily: L.display, fontWeight: 700, fontSize: 12, letterSpacing: '0.12em', textTransform: 'uppercase',
      }}>{tag}</div>
      <InteractivePhone scale={effScale}>{children}</InteractivePhone>
      <figcaption style={{ marginTop: 14, fontFamily: L.body, fontSize: 13.5, color: L.ink2, textAlign: 'center', maxWidth: isMobile ? 280 : 200, lineHeight: 1.4 }}>
        {persona}
      </figcaption>
    </figure>
  );
}

// ── Stakes section: the fear / FOMO hit, right after the hero ──
// Asks for a birth year, then makes the whole block — copy, stats and the
// life grid — react to the visitor's actual age.
const STAKES_TOTAL_YEARS = 70;
const STAKES_WEEKS_PER_YEAR = 52;
const STAKES_GRID_COLS = 85; // more columns → wider grid
const STAKES_GRID_ROWS = 42; // fewer rows → shorter grid
const STAKES_TOTAL_WEEKS = STAKES_GRID_COLS * STAKES_GRID_ROWS; // 3,570
const STAKES_GRID_BASE_WIDTH_PCT = 85; // -15% width (vs square cells)
const STAKES_GRID_ASPECT = (STAKES_GRID_BASE_WIDTH_PCT / 100) / (1.2 * STAKES_GRID_ROWS / STAKES_GRID_COLS); // wider, shorter
const STAKES_GRID_SIZE_SCALE = 0.85; // -15% overall size
const STAKES_GRID_WIDTH_PCT = STAKES_GRID_BASE_WIDTH_PCT * STAKES_GRID_SIZE_SCALE;

function StakesSection() {
  const isMobile = useIsMobile(900);
  const CURRENT_YEAR = new Date().getFullYear();
  const DEFAULT_BIRTH_YEAR = 1997;

  const [birthYearInput, setBirthYearInput] = React.useState(String(DEFAULT_BIRTH_YEAR));
  const [focused, setFocused] = React.useState(false);

  const parsedBirthYear = birthYearInput.trim() === '' ? null : Number(birthYearInput);
  const validBirthYear = Number.isFinite(parsedBirthYear) ? parsedBirthYear : DEFAULT_BIRTH_YEAR;
  const rawAge = CURRENT_YEAR - validBirthYear;
  const age = Math.max(0, rawAge);
  const weeksLived = Math.min(STAKES_TOTAL_WEEKS - 1, Math.round(age * STAKES_WEEKS_PER_YEAR));

  // on mobile the grid sits on its own (no surrounding stats for contrast),
  // so bump the "gone"/"still yours" cells up from the desktop's subtle tints
  const goneColor = isMobile ? 'rgba(232,74,74,0.45)' : 'rgba(232,74,74,0.16)';
  const yoursColor = isMobile ? 'rgba(255,255,255,0.42)' : 'rgba(255,255,255,0.20)';

  return (
    <section id="stakes" style={{ padding: '8px 16px 56px' }}>
      <div className="hero-grid" style={{
        maxWidth: 1400, margin: '0 auto', background: L.ink, borderRadius: 32,
        padding: isMobile ? '40px 20px' : 'clamp(40px, 6vw, 80px) clamp(16px, 2vw, 32px) clamp(40px, 6vw, 80px) clamp(40px, 6vw, 80px)',
        position: 'relative', overflow: 'hidden',
        display: 'grid', gridTemplateColumns: '0.85fr 1.15fr', gap: isMobile ? 40 : 56, alignItems: 'center',
      }}>
        <div style={{ textAlign: 'center' }}>
          <Eyebrow color={L.bad} style={{ marginBottom: 18 }}>The stakes</Eyebrow>

          <h2 style={{
            fontFamily: L.display, fontWeight: 800, fontSize: 'clamp(22px, 3.2vw, 39px)',
            lineHeight: 1.15, letterSpacing: '-0.03em', color: '#fff', margin: '0 auto', maxWidth: 480, textWrap: 'pretty',
            textAlign: 'center',
          }}>
            <span style={{ display: 'block' }}>
              Every blank cell in this grid is a week you haven't lived yet.
            </span>
            <span style={{ display: 'block' }}>
              What you do with{' '}
              <span style={{
                backgroundImage: `linear-gradient(${L.hype}, ${L.hype})`,
                backgroundRepeat: 'no-repeat', backgroundSize: '100% 0.14em', backgroundPosition: '0 95%',
                boxDecorationBreak: 'clone', WebkitBoxDecorationBreak: 'clone',
              }}>
                the next one is still up to you.
              </span>
            </span>
          </h2>

          <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 10, flexWrap: 'wrap', marginTop: 28 }}>
            <label htmlFor="stakes-birth-year" style={{
              fontFamily: L.mono, fontSize: 12, color: 'rgba(255,255,255,0.45)',
              letterSpacing: '0.1em', textTransform: 'uppercase',
            }}>Born in</label>
            <div style={{ position: 'relative', display: 'inline-flex' }}>
              <input
                id="stakes-birth-year"
                type="number"
                inputMode="numeric"
                value={birthYearInput}
                onChange={(e) => setBirthYearInput(e.target.value)}
                onFocus={(e) => { setFocused(true); e.currentTarget.style.borderColor = L.hype; e.currentTarget.style.background = 'rgba(255,255,255,0.1)'; }}
                onBlur={(e) => { setFocused(false); e.currentTarget.style.borderColor = 'rgba(255,255,255,0.2)'; e.currentTarget.style.background = 'rgba(255,255,255,0.07)'; }}
                onMouseEnter={(e) => { if (!focused) { e.currentTarget.style.borderColor = 'rgba(255,255,255,0.45)'; e.currentTarget.style.background = 'rgba(255,255,255,0.1)'; } }}
                onMouseLeave={(e) => { if (!focused) { e.currentTarget.style.borderColor = 'rgba(255,255,255,0.2)'; e.currentTarget.style.background = 'rgba(255,255,255,0.07)'; } }}
                min={CURRENT_YEAR - 100}
                max={CURRENT_YEAR}
                placeholder={String(DEFAULT_BIRTH_YEAR)}
                style={{
                  width: 104, fontFamily: L.display, fontWeight: 800, fontSize: 18,
                  letterSpacing: '-0.01em', color: '#fff', background: 'rgba(255,255,255,0.07)',
                  border: `1px solid ${focused ? L.hype : 'rgba(255,255,255,0.2)'}`,
                  borderRadius: 10, padding: '8px 30px 8px 12px', outline: 'none', cursor: 'pointer',
                  transition: 'border-color .15s ease, background .15s ease',
                }}
              />
              <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="rgba(255,255,255,0.45)" strokeWidth="2.4" strokeLinecap="round" strokeLinejoin="round" style={{ position: 'absolute', right: 10, top: '50%', transform: 'translateY(-50%)', pointerEvents: 'none' }}>
                <path d="M12 20h9" />
                <path d="M16.5 3.5a2.121 2.121 0 0 1 3 3L7 19l-4 1 1-4Z" />
              </svg>
            </div>
            <span style={{ fontFamily: L.mono, fontSize: 12, color: 'rgba(255,255,255,0.45)' }}>
              → that makes you {age}
            </span>
          </div>

        </div>

        {/* life grid — one cell per week of an average 70-year life */}
        <div>
          <div style={{
            width: isMobile ? '100%' : `${STAKES_GRID_WIDTH_PCT}%`, aspectRatio: STAKES_GRID_ASPECT,
            marginLeft: isMobile ? 0 : 'auto', marginRight: 0,
            display: 'grid',
            gridTemplateColumns: `repeat(${STAKES_GRID_COLS}, 1fr)`,
            gridTemplateRows: `repeat(${STAKES_GRID_ROWS}, 1fr)`,
            gap: 2,
          }}>
            {Array.from({ length: STAKES_TOTAL_WEEKS }).map((_, i) => {
              const lived = i < weeksLived;
              const isToday = i === weeksLived;
              return (
                <div key={i} style={{
                  borderRadius: 1,
                  background: isToday ? L.hype : lived ? goneColor : yoursColor,
                  boxShadow: isToday ? '0 0 0 2px rgba(184,242,58,0.45)' : 'none',
                }} />
              );
            })}
          </div>
          <div style={{ width: isMobile ? '100%' : `${STAKES_GRID_WIDTH_PCT}%`, marginLeft: isMobile ? 0 : 'auto', marginRight: 0, display: 'flex', alignItems: 'center', gap: 16, flexWrap: 'wrap', marginTop: 18 }}>
            <span style={{ display: 'inline-flex', alignItems: 'center', gap: 6, fontFamily: L.mono, fontSize: 12, color: 'rgba(255,255,255,0.45)' }}>
              <span style={{ width: 10, height: 10, borderRadius: 2, background: goneColor, display: 'inline-block' }} /> gone
            </span>
            <span style={{ display: 'inline-flex', alignItems: 'center', gap: 6, fontFamily: L.mono, fontSize: 12, color: 'rgba(255,255,255,0.45)' }}>
              <span style={{ width: 10, height: 10, borderRadius: 2, background: L.hype, display: 'inline-block' }} /> today
            </span>
            <span style={{ display: 'inline-flex', alignItems: 'center', gap: 6, fontFamily: L.mono, fontSize: 12, color: 'rgba(255,255,255,0.45)' }}>
              <span style={{ width: 10, height: 10, borderRadius: 2, background: yoursColor, display: 'inline-block' }} /> still yours
            </span>
          </div>
          <p style={{ width: isMobile ? '100%' : `${STAKES_GRID_WIDTH_PCT}%`, fontFamily: L.body, fontSize: 13.5, lineHeight: 1.5, color: 'rgba(255,255,255,0.4)', margin: isMobile ? '14px 0 0' : '14px 0 0 auto', textWrap: 'pretty' }}>
            Every cell is one week of a {STAKES_TOTAL_YEARS}-year life — about {STAKES_TOTAL_WEEKS.toLocaleString()} in total.
          </p>
        </div>
      </div>
    </section>
  );
}

// ── Problem section: the promise problem ──────────────
// Fades + lifts a child into place the first time it enters the
// viewport — used for the scroll-reveal feel across this section.
function Reveal({ children, delay = 0 }) {
  const ref = React.useRef(null);
  const [visible, setVisible] = React.useState(false);

  React.useEffect(() => {
    const el = ref.current;
    if (!el) return;
    const obs = new IntersectionObserver(([entry]) => {
      if (entry.isIntersecting) {
        setVisible(true);
        obs.disconnect();
      }
    }, { threshold: 0.2 });
    obs.observe(el);
    return () => obs.disconnect();
  }, []);

  return (
    <div ref={ref} style={{
      opacity: visible ? 1 : 0,
      transform: visible ? 'translateY(0)' : 'translateY(28px)',
      transition: `opacity 0.7s ease ${delay}s, transform 0.7s ease ${delay}s`,
    }}>
      {children}
    </div>
  );
}

// local palette for the Problem section's premium-dark panel look
const PP = {
  panel: '#1B1813',
  panel2: '#211D17',
  line: '#2B261E',
  cream: '#F3EEE2',
  muted: '#9A9081',
  muted2: '#6E6557',
};

// card 1 — "the workout skipped": a streak with one broken day, fading bar below
function StreakVisual() {
  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 12, width: '100%', maxWidth: 200 }}>
      <div style={{ display: 'flex', gap: 7, justifyContent: 'center' }}>
        {[0, 1, 2].map((i) => (
          <i key={i} style={{ width: 16, height: 16, borderRadius: 5, background: L.hype, opacity: 0.9 }} />
        ))}
        <i style={{ width: 16, height: 16, borderRadius: 5, border: `1.5px solid ${L.bad}`, position: 'relative' }}>
          <span style={{ position: 'absolute', top: '50%', left: '50%', width: 10, height: 1.5, background: L.bad, transform: 'translate(-50%,-50%) rotate(45deg)' }} />
          <span style={{ position: 'absolute', top: '50%', left: '50%', width: 10, height: 1.5, background: L.bad, transform: 'translate(-50%,-50%) rotate(-45deg)' }} />
        </i>
        {[0, 1, 2].map((i) => (
          <i key={`f${i}`} style={{ width: 16, height: 16, borderRadius: 5, background: '#2A2620' }} />
        ))}
      </div>
      <div style={{ height: 7, borderRadius: 999, background: '#100E0B', overflow: 'hidden' }}>
        <span className="grittt-fadebar" style={{ display: 'block', height: '100%', borderRadius: 999, background: `linear-gradient(90deg, ${L.bad}, #B83A30)` }} />
      </div>
    </div>
  );
}

// card 2 — "the extra hour scrolling": an endless spinning loop
function LoopVisual() {
  return (
    <div style={{ width: 90, height: 90, position: 'relative' }}>
      <svg className="grittt-spin" viewBox="0 0 100 100" style={{ width: '100%', height: '100%', display: 'block' }}>
        <circle cx="50" cy="50" r="38" fill="none" stroke="#2A2620" strokeWidth="4" />
        <path d="M50 12 a38 38 0 1 1 -26 10" fill="none" stroke={PP.muted} strokeWidth="4" strokeLinecap="round" strokeDasharray="150 100" />
        <path d="M18 16 l10 6 l-9 7 z" fill={PP.cream} />
      </svg>
      <div style={{ position: 'absolute', inset: 0, display: 'flex', alignItems: 'center', justifyContent: 'center', fontFamily: L.mono, fontSize: 10, letterSpacing: '0.18em', color: PP.muted }}>
        SCROLL
      </div>
    </div>
  );
}

// a checklist trailing off, unfinished
function GoalsVisual() {
  const rows = [
    { width: 138 },
    { width: 108 },
    { width: 130 },
    { width: 96 },
  ];
  return (
    <div style={{ display: 'flex', flexDirection: 'column', justifyContent: 'center', gap: 9, width: '100%', maxWidth: 180 }}>
      {rows.map((r, i) => (
        <div key={i} className="grittt-bullet-row" style={{ display: 'flex', alignItems: 'center', gap: 10, animationDelay: `${i * 0.6}s` }}>
          <span style={{ width: 6, height: 6, borderRadius: '50%', background: PP.muted2, flex: '0 0 auto' }} />
          <span style={{ height: 8, borderRadius: 999, background: '#2A2620', width: r.width }} />
        </div>
      ))}
    </div>
  );
}

// card 4 — "the promise pushed to tomorrow": a calendar reel that never lands
function CalendarReelVisual() {
  const nums = ['12', '13', '14', '15', '16', '12', '13', '14', '15', '16'];
  return (
    <div style={{ width: 84, height: 92, borderRadius: 12, background: '#100E0B', border: `1px solid ${PP.line}`, overflow: 'hidden', position: 'relative', boxShadow: '0 10px 26px rgba(0,0,0,0.4)' }}>
      <div style={{ height: 22, background: '#17140F', borderBottom: `1px solid ${PP.line}`, display: 'flex', alignItems: 'center', justifyContent: 'center', fontFamily: L.mono, fontSize: 9, letterSpacing: '0.2em', color: PP.muted }}>
        TOMORROW
      </div>
      <div className="grittt-reel" style={{ position: 'absolute', top: 22, left: 0, right: 0, display: 'flex', flexDirection: 'column', alignItems: 'center' }}>
        {nums.map((n, i) => (
          <span key={i} style={{ height: 70, display: 'flex', alignItems: 'center', justifyContent: 'center', fontFamily: L.display, fontWeight: 800, fontSize: 34, color: PP.cream }}>{n}</span>
        ))}
      </div>
    </div>
  );
}

const PROBLEM_CARDS = [
  { id: 'workout', visual: <StreakVisual />, excuse: 'The workout skipped.' },
  { id: 'scroll', visual: <LoopVisual />, excuse: 'The extra hour scrolling.' },
  { id: 'tomorrow', visual: <CalendarReelVisual />, excuse: 'The promise pushed to tomorrow.' },
  { id: 'career', visual: <GoalsVisual />, excuse: 'Spend another evening avoiding what would change your career.' },
];

// desktop swaps the career card into the 3rd slot; mobile keeps it last
const PROBLEM_CARDS_ORDER = {
  desktop: ['workout', 'scroll', 'career', 'tomorrow'],
  mobile: ['workout', 'scroll', 'tomorrow', 'career'],
};

function ProblemCard({ num, visual, excuse, delay, compact }) {
  return (
    <Reveal delay={delay}>
      <article className="problem-card" style={{
        background: `linear-gradient(180deg, ${PP.panel2}, ${PP.panel})`,
        border: `1px solid ${PP.line}`, borderRadius: compact ? 16 : 20,
        padding: compact ? '16px 16px 18px' : '22px 22px 24px',
        minHeight: compact ? 160 : 216, height: '100%', display: 'flex', flexDirection: 'column',
        transition: 'transform 0.25s ease, box-shadow 0.25s ease, border-color 0.25s ease',
      }}>
        <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
          <div style={{ fontFamily: L.mono, fontSize: 11, fontWeight: 500, letterSpacing: '0.18em', color: PP.muted2 }}>
            {num}
          </div>
          <div style={{ width: 6, height: 6, borderRadius: '50%', background: L.hype, opacity: 0.85 }} />
        </div>
        <div style={{ flex: 1, display: 'flex', alignItems: 'center', justifyContent: 'center', margin: compact ? '4px 0 10px' : '8px 0 18px', minHeight: compact ? 64 : 86 }}>
          {visual}
        </div>
        <div style={{ fontFamily: L.display, fontWeight: 700, fontSize: compact ? 'clamp(14px, 2.4vw, 21px)' : 'clamp(18px, 2.4vw, 21px)', lineHeight: 1.2, letterSpacing: '-0.02em', color: PP.cream }}>
          <span style={{ color: PP.muted2 }}>"</span>{excuse}<span style={{ color: PP.muted2 }}>"</span>
        </div>
      </article>
    </Reveal>
  );
}

function ProblemSection() {
  const isMobile = useIsMobile(760);
  const order = isMobile ? PROBLEM_CARDS_ORDER.mobile : PROBLEM_CARDS_ORDER.desktop;
  const cards = order.map((id) => PROBLEM_CARDS.find((c) => c.id === id));
  return (
    <section style={{
      position: 'relative', overflow: 'hidden',
      background: `radial-gradient(120% 80% at 50% -10%, #1A1610 0%, rgba(26,22,16,0) 60%), ${L.ink}`,
      padding: 'clamp(24px, 4.5vw, 48px) 22px clamp(40px, 7vw, 80px)',
    }}>
      {/* vignette */}
      <div style={{ position: 'absolute', inset: 0, pointerEvents: 'none', background: 'radial-gradient(130% 100% at 50% 120%, rgba(0,0,0,0.55), rgba(0,0,0,0) 55%)' }} />

      <div style={{ position: 'relative', zIndex: 1, maxWidth: 1080, margin: '0 auto' }}>
        {/* the small decisions */}
        <div style={{
          display: 'grid', gridTemplateColumns: `repeat(auto-fit, minmax(${isMobile ? 160 : 240}px, 1fr))`, gap: isMobile ? 12 : 18,
          marginTop: 'clamp(20px, 3.5vw, 32px)',
        }}>
          {cards.map((c, i) => (
            <ProblemCard key={c.id} num={String(i + 1).padStart(2, '0')} visual={c.visual} excuse={c.excuse} delay={i * 0.08} compact={isMobile} />
          ))}
        </div>

        {/* evidence */}
        {/* <Reveal delay={0.1}>
          <p style={{
            maxWidth: 760, margin: 'clamp(72px, 13vw, 130px) auto 0', textAlign: 'center',
            fontFamily: L.display, fontWeight: 700, fontSize: 'clamp(30px, 6.6vw, 60px)',
            lineHeight: 1.04, letterSpacing: '-0.035em', color: PP.cream, textWrap: 'balance',
          }}>
            <span style={{ display: 'block', color: PP.muted }}>Each one feels insignificant.</span>
            Until it becomes a pattern.
            <span style={{ display: 'block', color: L.hype }}>And patterns become your future.</span>
          </p>
        </Reveal> */}

        {/* transition into the product */}
        <Reveal delay={0.1}>
          <div style={{ textAlign: 'center', maxWidth: 740, margin: 'clamp(20px, 3.5vw, 32px) auto 0' }}>
            <p style={{
              fontFamily: L.display, fontWeight: 800, letterSpacing: '-0.04em',
              fontSize: 'clamp(32px, 7vw, 64px)', lineHeight: 1.06, color: PP.cream, margin: 0, textWrap: 'balance',
            }}>
              Most people never see the pattern.{' '}
              <span style={{
                color: L.ink, background: L.hype, padding: '0 0.12em', borderRadius: 4,
                boxDecorationBreak: 'clone', WebkitBoxDecorationBreak: 'clone',
              }}>
                grittt does.
              </span>
            </p>
            <p style={{
              fontFamily: L.body, fontWeight: 400, fontSize: 'clamp(15px, 2.3vw, 18px)',
              lineHeight: 1.6, color: PP.muted, margin: '18px auto 0', maxWidth: 560,
            }}>
              It turns your daily decisions into something visible — so you can stop guessing where your habits are taking you, and start steering them.
            </p>
            <a href="#screens" className="grittt-cta" style={{
              display: 'inline-flex', alignItems: 'center', gap: 10, marginTop: 'clamp(30px, 5vw, 46px)',
              background: L.hype, color: L.ink, fontFamily: L.display, fontWeight: 800,
              fontSize: 'clamp(16px, 2.2vw, 19px)', letterSpacing: '-0.01em',
              padding: '16px 28px', borderRadius: 999, textDecoration: 'none',
              boxShadow: '0 14px 36px rgba(184,242,58,0.22)',
            }}>
              See Your Pattern <span className="grittt-cta-arrow" aria-hidden="true">→</span>
            </a>
          </div>
        </Reveal>
      </div>
    </section>
  );
}

// ── Sections ──────────────────────────────────────────
// ── Unified stories section — one step at a time, prev/next navigation ──
function StoriesSection() {
  const isMobile = useIsMobile(900);
  const [idx, setIdx] = React.useState(0);
  const [vis, setVis] = React.useState(true);

  const stories = [
    {
      id: 'build',
      eyebrow: 'Step 02 · Build',
      title: "Meet the version of yourself you've been trying to become.",
      body: "Stack tiny daily habits that compound into momentum — cold showers, deep work, morning runs. Check them off and feel the streak grow, and tap any habit for its full streak and history.",
      screens: [
        { tag: 'Build',  accent: L.hype, persona: 'Habits that lift you, checked off daily.',                       el: () => <A_Discipline /> },
        { tag: 'Detail', accent: L.ink,  persona: 'Tap any habit for its streak, 30-day history and impact.', el: () => <A_HabitDetail /> },
      ],
    },
    {
      id: 'control',
      eyebrow: 'Step 03 · Control',
      title: 'Stop being controlled by impulses.',
      body: "Name the habits quietly dragging you down — smoking, sugar, doomscrolling — and watch the clean days add up. Every day you don't give in counts toward starving the habit for good.",
      screens: [
        { tag: 'Control', accent: L.bad, persona: 'Quit smoking & co — clean days counted.', el: () => <A_Control /> },
      ],
    },
    {
      id: 'challenges',
      eyebrow: 'Step 04 · Challenges',
      title: 'The limits you believe in start disappearing.',
      body: '7, 21 and 30-day challenges across health and lifestyle. Cold showers, protein goals, digital detox, the 5AM club. See how you stack up — and exactly where most people quit.',
      screens: [
        { tag: 'Challenges', accent: L.hype, persona: 'Every active pact, with progress and days left.',                           el: () => <A_Challenges /> },
        { tag: 'AI Analysis', accent: L.ink, persona: "Tap a challenge to see the crowd's drop-off curve and ask the coach why.", el: () => <A_ChallengeDetail /> },
      ],
    },
    {
      id: 'fuel',
      eyebrow: 'Step 05 · Fuel',
      title: 'In a few weeks, your body starts thanking you.',
      body: 'Your energy changes before your body does.',
      screens: [
        { tag: 'Quick',    accent: L.hype, persona: 'Three taps — diet, junk, quality. Done in seconds.',           el: () => <A_Fuel /> },
        { tag: 'Detailed', accent: L.ink,  persona: 'Macros, photos, every gram — for the detail-obsessed.',        el: () => <A_Fuel_Detailed /> },
        { tag: 'Recap',    accent: L.bad,  persona: 'Your month on a plate, plus an AI breakdown of your patterns.', el: () => <A_FuelRecap /> },
      ],
    },
    {
      id: 'strength',
      eyebrow: 'Step 06 · Strength',
      title: "The mirror becomes proof that you're showing up.",
      body: 'Build confidence with your muscles and strength.',
      screens: [
        { tag: 'Quick',    accent: L.hype, persona: 'One honest rating, 1–10. Bank the effort and move on.', el: () => <A_Strength /> },
        { tag: 'Detailed', accent: L.ink,  persona: 'Full gym log — body part, sets, reps and weight.',      el: () => <A_Strength_BodyParts /> },
      ],
    },
    {
      id: 'coach',
      eyebrow: 'Step 07 · AI Coach',
      title: "It studies your streak — and everyone else's.",
      body: "The coach reads your pattern and says it straight, then zooms out to the crowd: how many share the habit and the exact day most of them quit.",
      points: [
        { tag: '!', accent: L.bad,  title: 'WHERE YOU SLIP',    body: 'Your misses cluster on weekends — the coach names the pattern, not just the number.' },
        { tag: '✓', accent: L.hype, title: 'WHERE OTHERS QUIT', body: "39% drop off at days 6–10. See the danger zone, and that you're already past it." },
      ],
      screens: [
        { tag: 'Your pattern', accent: L.bad, persona: 'AI finds exactly where you slip — weekends.',         el: () => <A_Insights /> },
        { tag: 'The crowd',    accent: L.ink, persona: 'The drop-off graph — where 48,210 lose the streak.', el: () => <A_InsightsGraph /> },
      ],
    },
    {
      id: 'detox',
      eyebrow: 'Step 08 · Digital Detox',
      title: "One day you'll realize you no longer reach for your phone every few minutes.",
      body: "grittt reads your screen time and turns it into the same honest scoreboard as everything else.",
      points: [
        { tag: '✓', accent: L.good, title: "PROOF IT'S WORKING",  body: 'Down 41% on the scroll this week — hours back, sleep onset 18 min faster.' },
        { tag: '!',  accent: L.bad,  title: 'WHERE IT CREEPS BACK', body: 'Late-night rabbit holes get flagged before they undo your streak.' },
      ],
      screens: [
        { tag: 'Screen time', accent: L.hype, persona: 'Live — tap an app to open its analysis.',                        el: () => <A_ScreenTime /> },
        { tag: 'AI Analysis', accent: L.ink,  persona: "A week of usage, what you got back, and the coach's detox read.", el: () => <A_ScreenTimeDetail /> },
      ],
    },
  ];

  const go = (dir) => {
    setVis(false);
    setTimeout(() => {
      setIdx((i) => (i + dir + stories.length) % stories.length);
      setVis(true);
    }, 200);
  };

  const jumpTo = (i) => {
    setVis(false);
    setTimeout(() => { setIdx(i); setVis(true); }, 200);
  };

  const cur = stories[idx];

  if (isMobile) return null;

  return (
    <section id="stories" style={{ padding: '72px 0 88px' }}>
      <div style={{ maxWidth: 1200, margin: '0 auto', padding: isMobile ? '0 20px' : '0 48px' }}>

        {/* Content: text + phones */}
        <div style={{
          display: 'grid',
          gridTemplateColumns: isMobile ? '1fr' : '0.35fr 0.65fr',
          gap: isMobile ? 36 : 64,
          alignItems: 'center',
          opacity: vis ? 1 : 0,
          transition: 'opacity 0.2s ease',
          minHeight: isMobile ? 'auto' : 580,
        }}>

          {/* Text column */}
          <div style={{ textAlign: isMobile ? 'center' : 'left' }}>
            <Eyebrow style={{ marginBottom: 14 }}>{cur.eyebrow}</Eyebrow>
            <h2 style={{
              fontFamily: L.display, fontWeight: 800, fontSize: 'clamp(28px, 3.2vw, 42px)',
              lineHeight: 1.08, letterSpacing: '-0.03em', color: L.ink, margin: 0, textWrap: 'balance',
            }}>{cur.title}</h2>
            {!isMobile && (
              <>
                <p style={{ fontFamily: L.body, fontSize: 16, lineHeight: 1.65, color: L.ink2, margin: '18px 0 0' }}>{cur.body}</p>
                {cur.points && (
                  <div style={{ display: 'flex', flexDirection: 'column', gap: 14, marginTop: 24 }}>
                    {cur.points.map((p, i) => (
                      <div key={i} style={{ display: 'flex', gap: 14, alignItems: 'flex-start' }}>
                        <div style={{
                          flex: '0 0 auto', marginTop: 2, width: 34, height: 34, borderRadius: 10,
                          background: p.accent || L.ink, color: p.accent === L.hype ? L.ink : '#fff',
                          display: 'flex', alignItems: 'center', justifyContent: 'center',
                          fontFamily: L.display, fontWeight: 800, fontSize: 13,
                        }}>{p.tag}</div>
                        <div>
                          <div style={{ fontFamily: L.display, fontWeight: 700, fontSize: 13, color: L.ink, letterSpacing: '0.08em' }}>{p.title}</div>
                          <div style={{ fontFamily: L.body, fontSize: 14, lineHeight: 1.5, color: L.ink2, marginTop: 3 }}>{p.body}</div>
                        </div>
                      </div>
                    ))}
                  </div>
                )}
              </>
            )}
          </div>

          {/* Phones column */}
          <div style={{
            display: 'flex', gap: isMobile ? 16 : 22, alignItems: 'flex-start',
            overflowX: 'auto', padding: '8px 0 12px',
            scrollSnapType: 'x mandatory', WebkitOverflowScrolling: 'touch',
            msOverflowStyle: 'none', scrollbarWidth: 'none',
            justifyContent: 'center',
          }}>
            {cur.screens.map((s, i) => (
              <div key={i} style={{ flex: '0 0 auto', scrollSnapAlign: 'center' }}>
                <PersonaPhone tag={s.tag} accent={s.accent} persona={s.persona} scale={isMobile ? 0.56 : 0.5}>
                  {s.el()}
                </PersonaPhone>
              </div>
            ))}
          </div>
        </div>

        {/* Navigation */}
        <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 16, marginTop: isMobile ? 36 : 48 }}>
          <RoundArrow dir={-1} onClick={() => go(-1)} />
          <div style={{ display: 'flex', gap: 6 }}>
            {stories.map((_, i) => (
              <button
                key={i}
                onClick={() => jumpTo(i)}
                style={{
                  width: i === idx ? 20 : 7, height: 7, borderRadius: 999, border: 'none',
                  background: i === idx ? L.ink : L.rule, cursor: 'pointer',
                  transition: 'width .2s ease, background .2s ease', padding: 0,
                }}
              />
            ))}
          </div>
          <RoundArrow dir={1} onClick={() => go(1)} />
        </div>

      </div>
    </section>
  );
}

// keep individual exports for backwards compat
function BuildSection()      { return <StoriesSection />; }
function ControlSection()    { return null; }
function ChallengesSection() { return null; }
function FuelSection()       { return null; }
function StrengthSection()   { return null; }
function CoachSection()      { return null; }
function DetoxSection()      { return null; }

// ── Footer CTA ────────────────────────────────────────
function FooterCTA() {
  const isMobile = useIsMobile(760);
  return (
    <section style={{ padding: isMobile ? '24px 20px 48px' : '40px 32px 64px' }}>
      <div style={{
        maxWidth: 1200, margin: '0 auto', background: L.ink, borderRadius: 32,
        padding: 'clamp(48px, 7vw, 88px) clamp(32px, 6vw, 80px)', position: 'relative', overflow: 'hidden',
      }}>
        <Eyebrow color={L.hype} style={{ marginBottom: 22 }}>No more excuses</Eyebrow>
        <h2 style={{
          fontFamily: L.display, fontWeight: 800, fontSize: 'clamp(34px, 5vw, 58px)',
          lineHeight: 1, letterSpacing: '-0.03em', color: '#fff', margin: 0, maxWidth: 760, textWrap: 'balance',
        }}>
          Stop negotiating with yourself.
        </h2>
        <p style={{ fontFamily: L.body, fontSize: 18, lineHeight: 1.5, color: 'rgba(255,255,255,0.7)', margin: '22px 0 36px', maxWidth: 520 }}>
          Download grittt, tell it who you're becoming, and let the score do the arguing.
          Your first streak starts today.
        </p>
        <div style={{ display: 'flex', gap: 12, flexWrap: 'wrap' }}>
          <Btn kind="lime" big>Get grittt — free</Btn>
          <Btn kind="ghost" big><span style={{ color: '#fff' }}>See the demo</span></Btn>
        </div>
        <div style={{
          marginTop: 56, paddingTop: 26, borderTop: '1px solid rgba(255,255,255,0.12)',
          display: 'flex', alignItems: 'center', justifyContent: 'space-between', flexWrap: 'wrap', gap: 16,
        }}>
          <Wordmark size={20} color="#fff" />
          <div style={{ fontFamily: L.mono, fontSize: 12, color: 'rgba(255,255,255,0.45)', letterSpacing: '0.04em' }}>
            © 2026 grittt — show up, every day.
          </div>
        </div>
      </div>
    </section>
  );
}

Object.assign(window, {
  ScreenCarousel, Story, PersonaPhone, SinglePhone, StakesSection, ProblemSection,
  AISection, BuildSection, ControlSection, ChallengesSection, FuelSection, StrengthSection, CoachSection, DetoxSection, FooterCTA,
});
