// site-v3.jsx — ReturnScribe marketing landing, "The Ledger" edition.
// Themed directly on the ReturnScribe iOS app and rendering REAL excerpts:
// the live prototype in the hero, real screens in the scroll sequence, real
// plan data (RSData.plans), real ledger rows (RSData.inbox) and figures
// (RSData.heroStates). No email signup.

const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "theme": "dark",
  "accent": "#C2451E",
  "motion": "Full"
}/*EDITMODE-END*/;

const SITE_ACCENTS = {
  Vermillion: '#C2451E',
  Ink:        '#3D6B9E',
  Sage:       '#3E8F7C',
  Plum:       '#7A5CA8',
};
const DARK_ACCENTS = { '#C2451E': '#F0653A', '#3D6B9E': '#6FA3DC', '#3E8F7C': '#5FC3A9', '#7A5CA8': '#A98BE0' };

const prefersReducedMotion = () =>
  window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches;

const WordmarkText = ({ accent }) => (
  <span className="wm-text">Return<em style={{ color: accent, fontStyle: 'italic' }}>Scribe</em></span>
);

// ── Intro overlay ────────────────────────────────────────────────
const Intro = ({ accent, enabled, onDone }) => {
  const [exit, setExit] = React.useState(false);
  const [gone, setGone] = React.useState(false);
  const doneRef = React.useRef(false);

  const finish = React.useCallback((instant) => {
    if (doneRef.current) return;
    doneRef.current = true;
    if (instant) document.body.classList.add('entered-instant');
    document.body.classList.remove('intro-active');
    document.body.classList.add('entered');
    onDone && onDone();
  }, [onDone]);

  React.useLayoutEffect(() => {
    if (!enabled || document.hidden) { finish(true); setGone(true); return; }
    document.body.classList.remove('entered-instant');
    document.body.classList.add('intro-active');
  }, []);

  React.useEffect(() => {
    if (!enabled) { setGone(true); return; }
    const onVis = () => { if (document.hidden) { finish(true); setGone(true); } };
    document.addEventListener('visibilitychange', onVis);
    const t1 = setTimeout(() => { setExit(true); finish(false); }, 1650);
    const t2 = setTimeout(() => setGone(true), 2450);
    return () => {
      document.removeEventListener('visibilitychange', onVis);
      clearTimeout(t1); clearTimeout(t2);
    };
  }, [enabled, finish]);

  if (gone || !enabled) return null;
  return (
    <div
      className={`intro ${exit ? 'exit' : ''}`}
      onClick={() => { setExit(true); finish(false); setTimeout(() => setGone(true), 760); }}
      aria-hidden="true"
    >
      <div className="intro-glyph"><BrandMark size={64} color={accent}/></div>
      <div className="intro-word-mask"><span className="intro-word">Return<em>Scribe</em></span></div>
      <div className="intro-mono">The ledger · Est. 2026</div>
    </div>
  );
};

// ── Scroll progress ──────────────────────────────────────────────
const ScrollProgress = () => {
  const ref = React.useRef(null);
  React.useEffect(() => {
    const onScroll = () => {
      const h = document.documentElement;
      const max = h.scrollHeight - h.clientHeight;
      if (ref.current) ref.current.style.width = `${max > 0 ? (h.scrollTop / max) * 100 : 0}%`;
    };
    onScroll();
    window.addEventListener('scroll', onScroll, { passive: true });
    return () => window.removeEventListener('scroll', onScroll);
  }, []);
  return <div className="progress" ref={ref}></div>;
};

// ── Nav ──────────────────────────────────────────────────────────
const Nav = ({ accent, dark, onToggleTheme }) => {
  const [scrolled, setScrolled] = React.useState(false);
  React.useEffect(() => {
    const onScroll = () => setScrolled(window.scrollY > 8);
    onScroll();
    window.addEventListener('scroll', onScroll, { passive: true });
    return () => window.removeEventListener('scroll', onScroll);
  }, []);
  return (
    <nav className={`nav ${scrolled ? 'scrolled' : ''}`} data-enter style={{ '--d': '0.55s' }}>
      <div className="nav-inner">
        <a href="/" className="wordmark">
          <span className="glyph"><BrandMark size={26} color={accent}/></span>
          <WordmarkText accent={accent}/>
        </a>
        <div className="nav-links">
          <a href="#ledger">The ledger</a>
          <a href="#pricing">Pricing</a>
          <a href="#privacy">Privacy</a>
          <a href="#faq">FAQ</a>
          <button className="theme-toggle" onClick={onToggleTheme} title="Toggle light / dark" aria-label="Toggle theme">
            {dark ? (
              <svg width="15" height="15" viewBox="0 0 15 15" fill="none">
                <circle cx="7.5" cy="7.5" r="3.2" stroke="currentColor" strokeWidth="1.3"></circle>
                <path d="M7.5 0.8v1.8M7.5 12.4v1.8M0.8 7.5h1.8M12.4 7.5h1.8M2.8 2.8l1.3 1.3M10.9 10.9l1.3 1.3M12.2 2.8l-1.3 1.3M4.1 10.9l-1.3 1.3" stroke="currentColor" strokeWidth="1.3" strokeLinecap="round"></path>
              </svg>
            ) : (
              <svg width="15" height="15" viewBox="0 0 15 15" fill="none">
                <path d="M12.5 9.3A5.7 5.7 0 0 1 5.7 2.5a5.7 5.7 0 1 0 6.8 6.8Z" stroke="currentColor" strokeWidth="1.3" strokeLinejoin="round"></path>
              </svg>
            )}
          </button>
          <span className="nav-chip"><span className="dot"></span> Summer 2026</span>
        </div>
      </div>
    </nav>
  );
};

// ── Hero: live prototype + shader backdrop + 3D tilt ─────────────
const Hero = ({ accent, glow, dark, motionOK }) => {
  const stageRef = React.useRef(null);
  const { outerRef, innerRef } = useMouseTilt(6);

  // Live masthead date — always today's actual date.
  const todayStr = new Date().toLocaleDateString('en-US', {
    weekday: 'long', month: 'long', day: 'numeric', year: 'numeric',
  });

  React.useEffect(() => {
    if (!motionOK) return;
    let raf = 0;
    const onScroll = () => {
      cancelAnimationFrame(raf);
      raf = requestAnimationFrame(() => {
        const y = Math.min(window.scrollY, 700);
        if (stageRef.current) stageRef.current.style.transform = `translateY(${y * 0.09}px)`;
      });
    };
    onScroll();
    window.addEventListener('scroll', onScroll, { passive: true });
    return () => { window.removeEventListener('scroll', onScroll); cancelAnimationFrame(raf); };
  }, [motionOK]);

  const saved = RSData.heroStates[0]; // real app data

  return (
    <header className="hero" data-screen-label="Hero">
      <div className="container hero-grid">
        <div>
          <div className="masthead-rule" data-enter style={{ '--d': '0.08s' }}>
            <span>{todayStr}</span>
            <span className="acc">No. 001 — The Ledger</span>
          </div>
          <h1 className="hero-title">
            <span className="tmask"><span className="tline" style={{ '--d': '0.12s' }}>Every return window.</span></span>
            <span className="tmask"><span className="tline" style={{ '--d': '0.22s' }}>Every renewal.</span></span>
            <span className="tmask"><span className="tline" style={{ '--d': '0.32s' }}><em>One ledger.</em></span></span>
          </h1>
          <p className="hero-sub" data-enter style={{ '--d': '0.42s' }}>
            ReturnScribe reads the receipts already sitting in your inbox and keeps a
            running ledger of what&rsquo;s still returnable, what renews next, and what
            you&rsquo;ve quietly saved. Built for iPhone — read-only, private by design.
          </p>
          <div className="hero-actions" data-enter style={{ '--d': '0.52s' }}>
            <a className="btn-primary" href="#glance">Open the ledger <span className="arrow" aria-hidden="true">↓</span></a>
            <span className="hero-meta"><span className="dot"></span> Coming to iPhone · Late summer 2026</span>
          </div>
        </div>

        <div data-enter style={{ '--d': '0.34s' }}>
          <div className="hero-stage">
            <div className="hero-stage-inner" ref={stageRef}>
              <div className="hero-halo"></div>
              <div className="tilt-outer" ref={outerRef}>
                <div className="tilt-inner" ref={innerRef}>
                  <RSAppEmbed width={318} dark={dark} accent={accent} playSplash={true}/>
                </div>
              </div>
              <div className="float-note" style={{ top: 330, left: -176, '--fd': '0s' }}>
                <span className="nd" style={{ background: 'var(--success)' }}></span>
                <span>
                  <span className="nt" style={{ display: 'block', color: 'var(--success)' }}>+$1,247.<span style={{ fontSize: '0.8em' }}>83</span></span>
                  <span className="ns" style={{ display: 'block' }}>{saved.caption}</span>
                </span>
              </div>
              <div className="float-note" style={{ bottom: 130, right: -178, '--fd': '1.7s' }}>
                <span className="nd" style={{ background: 'var(--warning)' }}></span>
                <span>
                  <span className="nt" style={{ display: 'block' }}>Patagonia — 2 days left</span>
                  <span className="ns" style={{ display: 'block' }}>Houdini Air Jacket · $159.00</span>
                </span>
              </div>
            </div>
            <div className="live-tag"><span className="dot"></span> Live prototype — tap around</div>
          </div>
        </div>
      </div>
    </header>
  );
};

// ── Ledger stat strip — real numbers, blur count-up ──────────────
const StatLine = () => {
  const [saved, risk, flight] = RSData.heroStates; // real app data
  return (
    <section className="statline" data-screen-label="Ledger stats">
      <div className="container">
        <div className="statline-grid" data-reveal>
          <div className="stat">
            <div className="lbl">Saved this year</div>
            <div className="val" style={{ color: 'var(--success)' }}>
              <BlurNumber value={saved.amount} decimals={2} prefix="$"/>
            </div>
            <div className="cap">{saved.caption}</div>
          </div>
          <div className="stat">
            <div className="lbl">At risk</div>
            <div className="val" style={{ color: 'var(--warning)' }}>
              <BlurNumber value={risk.amount} decimals={2} prefix="$"/>
            </div>
            <div className="cap">{risk.caption}</div>
          </div>
          <div className="stat">
            <div className="lbl">Refunds in flight</div>
            <div className="val" style={{ color: 'var(--accent)' }}>
              <BlurNumber value={flight.amount} decimals={2} prefix="$"/>
            </div>
            <div className="cap">{flight.count} refunds being processed</div>
          </div>
          <div className="stat">
            <div className="lbl">Tracked</div>
            <div className="val"><BlurNumber value={12}/> <span style={{ fontSize: '0.5em', color: 'var(--ink-2)' }}>returns</span></div>
            <div className="cap">+ 9 subscriptions · $247/mo</div>
          </div>
        </div>
        <div className="stat-demo-note">Figures from the prototype&rsquo;s sample ledger</div>
      </div>
    </section>
  );
};

// ── Ticker ───────────────────────────────────────────────────────
const TICKER_ITEMS = [
  'Return windows', 'Renewal dates', 'Trial conversions', 'Refunds in flight',
  'Read-only mail access', 'Encrypted at rest', 'No ads · no tracking', 'Export anytime',
];
const Ticker = () => (
  <div className="ticker" aria-hidden="true" data-screen-label="Ticker">
    <div className="ticker-track">
      {[0, 1].map((dup) => (
        <span key={dup} style={{ display: 'inline-flex' }}>
          {TICKER_ITEMS.map((t) => <span className="ticker-item" key={t}>{t}</span>)}
        </span>
      ))}
    </div>
  </div>
);

// ── Real screens in a 3D container-scroll panel ──────────────────
const LedgerSheet = ({ accent, dark }) => (
  <section className="cscroll-section" id="glance" data-screen-label="At a glance">
    <div className="container">
      <ContainerScroll
        header={
          <div className="cscroll-title">
            <div className="eyebrow">Straight from the prototype</div>
            <h2 className="section-title">The ledger, <em>at a glance</em>.</h2>
          </div>
        }
      >
        <div className="screen-trio">
          <div className="trio-side hide-sm"><RSScreenFrame screen="settings" width={244} dark={dark} accent={accent}/></div>
          <div className="trio-main"><RSScreenFrame screen="home" width={292} dark={dark} accent={accent}/></div>
          <div className="trio-side hide-sm"><RSScreenFrame screen="detail" width={244} dark={dark} accent={accent}/></div>
        </div>
        <div className="trio-caption">Settings · Overview · Deadline detail — prototype</div>
      </ContainerScroll>
    </div>
  </section>
);

// ── The ledger, step by step (real screens, scroll-pinned) ───────
const CHAPTERS = [
  {
    num: '01 — Connect',
    title: <span>Plug in the mailboxes <em>you already have</em>.</span>,
    body: 'Gmail and Outlook, read-only — ReturnScribe never sends, deletes, or moves a thing. Connect one inbox or several; the ledger fills itself from receipts you already received.',
    tag: 'Read-only OAuth · Revoke anytime',
    screen: 'connect',
  },
  {
    num: '02 — Record',
    title: <span>Every purchase becomes <em>a line in the book</em>.</span>,
    body: 'ReturnScribe scans only purchase confirmations and subscription receipts. Email that isn\u2019t a receipt never leaves your device, and raw email bodies are never stored.',
    tag: 'Merchant · Amount · Return-by date',
    screen: 'inbox',
  },
  {
    num: '03 — Deadline',
    title: <span>Watch the window <em>before it closes</em>.</span>,
    body: 'Every item carries a countdown against the retailer\u2019s policy. Two days left on a $159 jacket gets a push notification — not a shrug three weeks later.',
    tag: 'Closing-soon alerts · Snooze · Done',
    screen: 'detail',
  },
  {
    num: '04 — Recurring',
    title: <span>Subscriptions, <em>on the record</em>.</span>,
    body: 'Recurring receipts surface as subscriptions with renewal dates and a real monthly total. Free trials get flagged before they quietly convert into charges.',
    tag: 'Renewal reminders · Trial-to-paid warnings',
    screen: 'subs',
  },
  {
    num: '05 — Recovered',
    title: <span>Refunds, <em>followed to the cent</em>.</span>,
    body: 'Mark an item returned and ReturnScribe watches for the refund confirmation, keeping a running total of what the ledger has actually put back in your pocket.',
    tag: '$1,247.83 saved in the sample ledger',
    screen: 'refunds',
  },
];

const LedgerChapters = ({ accent, dark }) => {
  const [active, setActive] = React.useState(0);
  const stepRefs = React.useRef([]);

  // Closest-to-viewport-center wins — keeps the phone exactly in sync
  // with the step you're reading.
  React.useEffect(() => {
    let raf = 0;
    const update = () => {
      const vh = window.innerHeight;
      let best = 0, bestD = Infinity;
      stepRefs.current.forEach((el, i) => {
        if (!el) return;
        const r = el.getBoundingClientRect();
        const d = Math.abs(r.top + r.height / 2 - vh / 2);
        if (d < bestD) { bestD = d; best = i; }
      });
      setActive(best);
    };
    const onScroll = () => { cancelAnimationFrame(raf); raf = requestAnimationFrame(update); };
    update();
    window.addEventListener('scroll', onScroll, { passive: true });
    window.addEventListener('resize', onScroll);
    return () => {
      window.removeEventListener('scroll', onScroll);
      window.removeEventListener('resize', onScroll);
      cancelAnimationFrame(raf);
    };
  }, []);

  return (
    <section className="section" id="ledger" data-screen-label="How it works">
      <div className="container">
        <div className="section-head" data-reveal>
          <div className="eyebrow">How it works</div>
          <div>
            <h2 className="section-title">From inbox to ledger, <em>automatically</em>.</h2>
            <p className="section-lead">
              Connect a mailbox once, then let the books keep themselves — scroll
              through each step the app handles on its own.
            </p>
          </div>
        </div>
        <div className="scrolly">
          <div className="scrolly-steps">
            {CHAPTERS.map((s, i) => (
              <div
                key={s.num}
                className={`step-block ${active === i ? 'active' : ''}`}
                ref={(el) => { stepRefs.current[i] = el; }}
              >
                <div className="step-num">{s.num}</div>
                <h3 className="step-title">{s.title}</h3>
                <p className="step-body">{s.body}</p>
                <div className="step-tag">{s.tag}</div>
              </div>
            ))}
          </div>
          <div className="scrolly-phone">
            <div style={{ position: 'relative' }}>
              {CHAPTERS.map((s, i) => (
                <div key={s.screen} style={{
                  position: i === 0 ? 'relative' : 'absolute',
                  inset: i === 0 ? 'auto' : 0,
                  opacity: active === i ? 1 : 0,
                  transform: active === i ? 'scale(1)' : 'scale(0.985)',
                  transition: 'opacity 0.45s ease, transform 0.45s ease',
                }}>
                  <RSScreenFrame screen={s.screen} width={300} dark={dark} accent={accent}/>
                </div>
              ))}
            </div>
          </div>
        </div>
      </div>
    </section>
  );
};

// ── "When it matters" — stacked display cards with real moments ──
const MOMENT_CARDS = [
  {
    tone: 'success', kind: 'Refund posted', when: 'Today',
    icon: <svg width="13" height="13" viewBox="0 0 13 13" fill="none"><path d="M2 7l3 3 6-7" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round"></path></svg>,
    title: '+$249.00 from Apple',
    sub: 'AirPods Pro (2nd gen) · refund landed',
  },
  {
    tone: 'accent', kind: 'Trial ending', when: 'Jul 4',
    icon: <svg width="13" height="13" viewBox="0 0 13 13" fill="none"><path d="M6.5 1v3M6.5 1l5 8.5h-10L6.5 1z" stroke="currentColor" strokeWidth="1.4" strokeLinecap="round" strokeLinejoin="round"></path></svg>,
    title: 'Adobe Creative converts in 6 days',
    sub: 'Becomes $59.99/mo unless you cancel',
  },
  {
    tone: 'warning', kind: 'Closing soon', when: 'Jun 9',
    icon: <svg width="13" height="13" viewBox="0 0 13 13" fill="none"><circle cx="6.5" cy="6.5" r="5.2" stroke="currentColor" strokeWidth="1.4"></circle><path d="M6.5 3.6v3.2l2.1 1.4" stroke="currentColor" strokeWidth="1.4" strokeLinecap="round"></path></svg>,
    title: 'Patagonia — 2 days left',
    sub: 'Houdini Air Jacket · $159.00 still returnable',
  },
];

const Moments = () => (
  <section className="section" id="moments" data-screen-label="Notifications">
    <div className="container moments-grid">
      <div data-reveal>
        <div className="eyebrow">When it matters</div>
        <h2 className="section-title" style={{ marginTop: 14 }}>Three pushes <em>worth getting</em>.</h2>
        <p className="section-lead">
          ReturnScribe stays quiet until money is on the line — a window about to
          close, a trial about to convert, a refund finally landing. Hover the stack.
        </p>
      </div>
      <div data-reveal style={{ '--d': '0.1s' }}>
        <DisplayCards cards={MOMENT_CARDS}/>
      </div>
    </div>
  </section>
);

// ── Pricing — the app's real plans (RSData.plans) ────────────────
const Pricing = () => {
  const [cadence, setCadence] = React.useState('annual');
  const plans = RSData.plans; // real paywall data
  const suffix = cadence === 'annual' ? '/yr' : '/mo';
  const priceFor = (pl) => (cadence === 'annual' ? pl.annual : pl.monthly);
  return (
    <section className="section pricing-section" id="pricing" data-screen-label="Pricing">
      <div className="container" style={{ position: 'relative' }}>
        <div className="section-head" data-reveal>
          <div className="eyebrow">Pricing</div>
          <div>
            <h2 className="section-title">Two tiers. <em>Straight from the paywall.</em></h2>
            <p className="section-lead">
              Billed through your Apple ID, cancel anytime. The same plans you&rsquo;ll see
              in the app on day one.
            </p>
          </div>
        </div>
        <div className="pricing-wrap" data-reveal style={{ '--d': '0.08s' }}>
          <div className="cadence" role="tablist" aria-label="Billing cadence">
            <button className={cadence === 'monthly' ? 'on' : ''} onClick={() => setCadence('monthly')}>Monthly</button>
            <button className={cadence === 'annual' ? 'on' : ''} onClick={() => setCadence('annual')}>
              Annual <span className="save">Save 17%</span>
            </button>
          </div>

          <div className="tier featured">
            <span className="trial-badge">7-day free trial</span>
            <span>
              <span className="tname">{plans.max.name} <span style={{ color: 'var(--accent)', fontSize: 20 }}>✦</span></span>
              <span className="tline2" style={{ display: 'block' }}>{plans.max.line}</span>
            </span>
            <span className="tprice">
              <span className="amt"><BlurNumber value={priceFor(plans.max)} decimals={2} prefix="$" duration={650}/></span>
              <span className="per">{suffix}</span>
            </span>
          </div>

          <div className="tier">
            <span>
              <span className="tname">{plans.pro.name}</span>
              <span className="tline2" style={{ display: 'block' }}>{plans.pro.line}</span>
            </span>
            <span className="tprice">
              <span className="amt"><BlurNumber value={priceFor(plans.pro)} decimals={2} prefix="$" duration={650}/></span>
              <span className="per">{suffix}</span>
            </span>
          </div>

          <div className="pricing-foot">Managed through your Apple ID · Restore purchases supported</div>
        </div>
      </div>
    </section>
  );
};

// ── Privacy — mirrors the app's "Before you start" consent ───────
const PRIVACY_ITEMS = [
  { t: 'Reads receipt emails — read-only', b: <span>OAuth scopes are limited to read-only Gmail / Microsoft Graph. We never send email on your behalf, and we can&rsquo;t delete or modify anything in your inbox.</span> },
  { t: 'AI parsing, disclosed before you start', b: <span>ReturnScribe uses AI to read your receipt emails and pull out purchase details — merchant, amount, dates, return windows. Some receipt content is processed by a third-party AI service to do this, and the app tells you exactly that on its sign-up disclosure before anything is connected.</span> },
  { t: 'Your address is redacted before AI parsing', b: <span>Before any receipt content reaches the AI parser, your own email address is redacted from it. Only structured fields come back.</span> },
  { t: 'Raw email bodies are never kept', b: <span>A 256 KB body cap is applied before parsing, structured purchase fields are extracted, and the raw text is dropped. Nothing is kept.</span> },
  { t: 'Encrypted in transit & at rest', b: <span>Your ledger lives in encrypted storage on your iPhone, and your sign-in stays locked to your device — ReturnScribe never sees or stores your email password.</span> },
  { t: 'No ads, no third-party tracking', b: <span>No analytics SDKs, no ad networks, no behavioural profiling. Required-Reason API usage is declared in the App Store privacy manifest.</span> },
  { t: 'Export or delete your data anytime', b: <span>One tap in Settings. Full details in the <a href="/privacy">privacy policy</a> — and if anything there is unclear, write to <a href="mailto:privacy@returnscribe.com">privacy@returnscribe.com</a>.</span> },
];

const PrivacySection = () => (
  <section className="section" id="privacy" data-screen-label="Privacy">
    <div className="container">
      <div className="section-head" data-reveal>
        <div className="eyebrow">Before you start</div>
        <div>
          <h2 className="section-title">The same honesty screen <em>the app opens with</em>.</h2>
          <p className="section-lead">
            ReturnScribe asks for consent before it reads a single receipt. Here&rsquo;s
            what that consent actually covers.
          </p>
        </div>
      </div>
      <div className="privacy-grid">
        {PRIVACY_ITEMS.map((p, i) => (
          <div className="privacy-item" key={p.t} data-reveal style={{ '--d': `${(i % 2) * 0.08}s` }}>
            <div className="privacy-idx">{String(i + 1).padStart(2, '0')}</div>
            <h3 className="privacy-title">{p.t}</h3>
            <p className="privacy-body">{p.b}</p>
          </div>
        ))}
      </div>
    </div>
  </section>
);

// ── FAQ ──────────────────────────────────────────────────────────
const FAQ_ITEMS = [
  { q: 'Is my email data safe?', a: 'Yes — and we\u2019re specific about how. ReturnScribe uses read-only OAuth: we cannot send, delete, or modify anything in your inbox. Your messages are fetched directly on your iPhone, and email that isn\u2019t a receipt never leaves your device. Receipt emails are parsed by AI: the message — with your own email address redacted — is processed by a cloud AI service to extract structured purchase details (merchant, amount, dates), and only those structured fields are stored, in encrypted on-device storage. Raw email bodies are never kept.' },
  { q: 'What email providers are supported?', a: 'Gmail and Outlook (Microsoft Graph) at launch. iCloud Mail and Yahoo Mail are planned for a future release. Multiple accounts on the same provider are supported on the Max plan.' },
  { q: 'How much does it cost?', a: 'ReturnScribe has two plans, billed through your Apple ID. Pro is $4.99/month or $49.99/year, with one connected mailbox and a 90-day scan window. Max is $9.99/month or $99.99/year, with unlimited mailboxes, a 120-day scan window, and a 7-day free trial.' },
  { q: 'When does it launch?', a: 'Late summer 2026, on the App Store. The prototype embedded on this page is the actual design the app will ship with.' },
  { q: 'How is this different from other apps?', a: 'ReturnScribe is a native iOS app built privacy-first — not a web shell, not a budgeting suite. It keeps a single ledger of the two purchase events with real deadlines: returns closing and subscriptions renewing, plus the refunds that follow.' },
];

const FAQ = () => {
  const [open, setOpen] = React.useState(0);
  return (
    <section className="section" id="faq" data-screen-label="FAQ">
      <div className="container">
        <div className="section-head" data-reveal>
          <div className="eyebrow">Questions</div>
          <div>
            <h2 className="section-title">Things people <em>ask first</em>.</h2>
          </div>
        </div>
        <div className="faq" data-reveal style={{ '--d': '0.08s' }}>
          {FAQ_ITEMS.map((it, i) => (
            <div className={`faq-item ${open === i ? 'open' : ''}`} key={it.q}>
              <button className="faq-q" onClick={() => setOpen(open === i ? -1 : i)} aria-expanded={open === i}>
                <span>{it.q}</span>
                <span className="faq-mark" aria-hidden="true">+</span>
              </button>
              <div className="faq-a-wrap">
                <div className="faq-a-inner"><div className="faq-a">{it.a}</div></div>
              </div>
            </div>
          ))}
        </div>
      </div>
    </section>
  );
};

// ── Footer ───────────────────────────────────────────────────────
const Footer = ({ accent }) => (
  <footer className="footer" data-screen-label="Footer">
    <div className="container">
      <div className="footer-grid">
        <div>
          <a href="/" className="wordmark">
            <span className="glyph"><BrandMark size={26} color={accent}/></span>
            <WordmarkText accent={accent}/>
          </a>
          <p className="footer-blurb">
            A privacy-first iPhone app that keeps the ledger of what you&rsquo;ve bought —
            what&rsquo;s still returnable, what&rsquo;s recurring, and what came back. Built by
            an indie developer in Virginia.
          </p>
        </div>
        <div>
          <h4>Product</h4>
          <ul>
            <li><a href="#ledger">The ledger</a></li>
            <li><a href="#pricing">Pricing</a></li>
            <li><a href="#privacy">Privacy</a></li>
            <li><a href="#faq">FAQ</a></li>
          </ul>
        </div>
        <div>
          <h4>Legal &amp; contact</h4>
          <ul>
            <li><a href="/privacy">Privacy policy</a></li>
            <li><a href="/terms">Terms of use</a></li>
            <li><a href="mailto:info@returnscribe.com">info@returnscribe.com</a></li>
            <li><a href="mailto:privacy@returnscribe.com">privacy@returnscribe.com</a></li>
          </ul>
        </div>
      </div>
      <div className="footer-bottom">
        <span>© 2026 ReturnScribe. All rights reserved.</span>
        <span>No. 001 · returnscribe.com</span>
      </div>
    </div>
  </footer>
);

// ── App ──────────────────────────────────────────────────────────
const App = () => {
  const [t, setTweak] = useTweaks(TWEAK_DEFAULTS);
  const [introKey, setIntroKey] = React.useState(0);
  const reduced = prefersReducedMotion();
  const motionOK = !reduced && t.motion !== 'Calm';
  const dark = t.theme !== 'light';
  const accent = t.accent;
  const displayAccent = dark ? (DARK_ACCENTS[accent] || accent) : accent;

  React.useEffect(() => {
    document.body.classList.toggle('paper', !dark);
    const root = document.documentElement;
    root.style.setProperty('--accent', displayAccent);
    root.style.setProperty('--accent-soft', rsHexA(displayAccent, dark ? 0.14 : 0.11));
  }, [dark, displayAccent]);

  React.useEffect(() => {
    document.body.classList.toggle('motion-calm', t.motion === 'Calm');
  }, [t.motion]);

  React.useEffect(() => {
    const els = Array.from(document.querySelectorAll('[data-reveal]'));
    const io = new IntersectionObserver(
      (entries) => entries.forEach((e) => {
        if (e.isIntersecting) { e.target.classList.add('is-in'); io.unobserve(e.target); }
      }),
      { rootMargin: '0px 0px -10% 0px', threshold: 0.05 }
    );
    els.forEach((el) => io.observe(el));
    return () => io.disconnect();
  }, []);

  return (
    <>
      <Intro key={introKey} accent={displayAccent} enabled={motionOK} onDone={() => {}}/>
      <FlowPaths global count={36}/>
      <ScrollProgress/>
      <Nav accent={displayAccent} dark={dark} onToggleTheme={() => setTweak('theme', dark ? 'light' : 'dark')}/>
      <main>
        <Hero accent={accent} glow={displayAccent} dark={dark} motionOK={motionOK}/>
        <StatLine/>
        <Ticker/>
        <LedgerSheet accent={accent} dark={dark}/>
        <LedgerChapters accent={accent} dark={dark}/>
        <Moments/>
        <Pricing/>
        <PrivacySection/>
        <FAQ/>
      </main>
      <Footer accent={displayAccent}/>

      <TweaksPanel title="Tweaks">
        <TweakSection label="Appearance">
          <TweakRadio label="Theme" value={t.theme} options={['dark', 'light']} onChange={(v) => setTweak('theme', v)}/>
          <TweakColor label="Ink accent" value={t.accent} options={Object.values(SITE_ACCENTS)} onChange={(v) => setTweak('accent', v)}/>
        </TweakSection>
        <TweakSection label="Motion">
          <TweakRadio label="Animation" value={t.motion} options={['Full', 'Calm']} onChange={(v) => setTweak('motion', v)}/>
          <TweakButton label="Replay intro" secondary onClick={() => {
            window.scrollTo({ top: 0, behavior: 'auto' });
            setIntroKey((k) => k + 1);
          }}/>
        </TweakSection>
      </TweaksPanel>
    </>
  );
};

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