// All sections for the morally pink Eve Riche site

const { useState: useStateS, useEffect: useEffectS, useRef: useRefS, useMemo: useMemoS } = React;

/* ============================================================
   HEADER
   ============================================================ */
function Header({ onSignup, current = 'home' }) {
  const scrolled = useScrolled(40);
  const [menuOpen, setMenuOpen] = useStateS(false);

  // Lock body scroll when mobile menu open
  useEffectS(() => {
    if (menuOpen) {
      const prev = document.body.style.overflow;
      document.body.style.overflow = 'hidden';
      return () => { document.body.style.overflow = prev; };
    }
  }, [menuOpen]);

  // Each nav item: label, slug used both as href and for active state.
  // About and Bonuses each carry a sub-dropdown.
  const NAV = [
    { slug: 'home',     label: 'Home',     href: 'index.html'    },
    { slug: 'about',    label: 'About',    href: 'about.html',
      children: [
        { slug: 'about', label: 'About Eve Riche', href: 'about.html' },
        { slug: 'media', label: 'Media contact',   href: 'media.html' },
      ] },
    { slug: 'books',    label: 'Books',    href: 'books.html'    },
    { slug: 'bonuses',  label: 'Bonuses',  href: 'bonuses.html',
      children: [
        { slug: 'bonuses',       label: 'Bonus material',   href: 'bonuses.html' },
        { slug: 'reading-order', label: 'Reading order',    href: 'reading-order.html' },
        { slug: 'arc',           label: 'ARC applications', href: 'arc.html' },
      ] },
    { slug: 'warnings', label: 'Warnings', href: 'warnings.html' },
  ];

  function handleSignup(e) {
    e.preventDefault();
    setMenuOpen(false);
    if (current === 'home') {
      onSignup();
    } else {
      // navigate to home and hash to newsletter
      window.location.href = 'index.html#newsletter';
    }
  }

  return (
    <header
      className={`er-header ${scrolled ? 'is-scrolled' : ''} ${menuOpen ? 'is-menu-open' : ''}`}
      data-screen-label="Header"
    >
      <a className="er-header__brand" href="index.html" data-cursor="hover">
        <img src="assets/brand/er-logo-circle.png" alt="Eve Riche" />
        <div>
          <div className="er-header__name">Eve Riche</div>
          <div className="er-header__tag">
            Unapologetically dark <span style={{ whiteSpace: 'nowrap' }}>why choose</span> romance
          </div>
        </div>
      </a>

      <nav className="er-nav" aria-label="Primary">
        {NAV.map((n) => (
          n.children ? (
            <div key={n.slug} className={`er-nav__group ${current === n.slug || (n.children.some(c => c.slug === current)) ? 'is-active' : ''}`}>
              <a
                href={n.href}
                className={`er-nav__link ${current === n.slug ? 'is-active' : ''}`}
              >
                {n.label}
                <span aria-hidden="true" style={{ marginLeft: 4, fontSize: '0.6em', opacity: 0.7 }}>▾</span>
              </a>
              <div className="er-nav__dropdown" role="menu">
                {n.children.map((c) => (
                  <a
                    key={c.slug}
                    href={c.href}
                    className={`er-nav__dropdown-link ${current === c.slug ? 'is-active' : ''}`}
                    role="menuitem"
                  >
                    {c.label}
                  </a>
                ))}
              </div>
            </div>
          ) : (
            <a
              key={n.slug}
              href={n.href}
              className={`er-nav__link ${current === n.slug ? 'is-active' : ''}`}
            >
              {n.label}
            </a>
          )
        ))}
        <a className="er-cta er-cta--filled er-header__cta" href="#newsletter" onClick={handleSignup}>
          RSVP to the Club
        </a>
      </nav>

      <button
        className="er-header__hamburger"
        aria-label={menuOpen ? 'Close menu' : 'Open menu'}
        aria-expanded={menuOpen}
        onClick={() => setMenuOpen(!menuOpen)}
      >
        <span /><span /><span />
      </button>

      {menuOpen && (
        <div className="er-mobile-menu" role="dialog" aria-modal="true">
          {NAV.map((n) => (
            <a
              key={n.slug}
              href={n.href}
              className={`er-mobile-menu__link ${current === n.slug ? 'is-active' : ''}`}
            >
              {n.label}
            </a>
          ))}
          <a
            className="er-cta er-cta--filled"
            href="#newsletter"
            onClick={handleSignup}
            style={{ marginTop: 24, alignSelf: 'flex-start' }}
          >
            RSVP to the Club
          </a>
        </div>
      )}
    </header>);

}

/* ============================================================
   HERO
   ============================================================ */
function Hero({ featured, seriesMode, onSignup, onOpenBook }) {
  return (
    <section className="er-hero" id="hero" data-screen-label="01 Hero" aria-label="Hero">
      <div className="er-hero__bg" aria-hidden="true" />
      <div className="er-hero__inner">
        <div className="er-hero__copy">
          <Reveal delay={120}>
            <h1 className="display display--xl er-hero__title">
              {seriesMode === 'hangmen' ?
              <>Five men.<br />One woman.<br /><em>A body count.</em></> :
              seriesMode === 'gods' ?
              <>Couture &amp; <em>casualties.</em><br />The gods take<br />their <em>tithe.</em></> :
              seriesMode === 'cuc' ?
              <>The crew that <em>cleans</em><br />up after the gods.<br /><em>Soft</em> for her.</> :

              <>Are you <em>dying</em><br />for love?</>
              }
            </h1>
          </Reveal>

          <Reveal delay={220}>
            <p className="er-hero__sub">
              {seriesMode === 'hangmen' ?
              'The Hangmen Trilogy opens 8 August. Why-choose dark romance from two USA Today bestselling authors in a trench coat. Soft hands. Sharper teeth.' :
              'Dark, sensual, occasionally lethal romance from two USA Today bestselling authors writing under one pen name. Why-choose. Morally black. Earned happy endings, no apologies.'}
            </p>
          </Reveal>

          <Reveal delay={300}>
            <div className="er-hero__cta">
              <button className="er-cta er-cta--filled" onClick={onSignup}>RSVP to the Club</button>
              {featured.preorderUrl ? (
                <a className="er-cta" href={featured.preorderUrl} target="_blank" rel="noopener">
                  Pre-order Now
                </a>
              ) : (
                <button className="er-cta" onClick={onSignup}>
                  Pre-order Now
                </button>
              )}
            </div>
          </Reveal>

          <Reveal delay={400}>
            <div className="er-hero__credit">
              <b></b>
              <div>Two USA Today bestselling authors<br />writing under one pen name. Yes, on purpose.</div>
            </div>
          </Reveal>
        </div>

        <div className="er-hero__cover" onClick={() => onOpenBook(featured)} data-cursor="hover">
          <div className="er-hero__halo" aria-hidden="true" />
          <div className="er-hero__stamp">Pre-order now</div>
          <div className="er-hero__cover-inner">
            {featured.cover ?
            <img src={featured.cover} alt={`${featured.title} cover`} /> :

            <div className="er-book__placeholder">
                <strong>{featured.title}</strong>
                <span>cover · reveal · TBC</span>
              </div>
            }
          </div>
        </div>
      </div>

      <div className="er-hero__scroll">
        <span>scroll, sweet thing</span>
      </div>
    </section>);

}

/* ============================================================
   PITCH
   ============================================================ */
function Pitch({ seriesMode }) {
  return (
    <section className="er-pitch" id="pitch" data-screen-label="02 Pitch">
      <div className="er-pitch__ornament" aria-hidden="true">Eve</div>
      <div className="er-pitch__inner">
        <Reveal>
          <p className="er-pitch__attrib" style={{ marginBottom: 32 }}>II &nbsp;·&nbsp; The itch</p>
        </Reveal>
        <Reveal delay={120}>
          <h2 className="er-pitch__quote">
            For readers who want their romance <em>bloody,</em><br />
            their heroes <em>unrepentant,</em> and their<br />
            happy endings <em>earned</em> in the dark.
          </h2>
        </Reveal>
        <Reveal delay={240}>
          <p className="er-pitch__attrib">
            — the kind of book your best friend texts you about at 2am
          </p>
        </Reveal>
        <Reveal delay={320}>
          <div style={{ marginTop: 56, maxWidth: 720, margin: '56px auto 0' }}>
            <p className="serif-body" style={{ fontSize: 21, color: 'var(--er-ink-2)' }}>
              Why-choose that earns its structure. Explicit heat with consent baked in. Morally black heroes with real interiority. Honky-tonk banter, kill scene, vulnerability scene — all in the same chapter. And jokes. A lot of jokes. Dark romance is too funny to be relentlessly grim.
            </p>
          </div>
        </Reveal>
      </div>
    </section>);

}

/* ============================================================
   BOOKS — horizontal carousel + filters
   ============================================================ */
function Books({ seriesMode, onPickSeries, onOpenBook, homepage = false }) {
  const trackRef = useRefS(null);
  // On the homepage we show only the launch trilogy as a preview.
  // On the books page (homepage=false) we honor the filter.
  const list = useMemoS(() => {
    if (homepage) return BOOKS.filter((b) => b.seriesKey === 'hangmen');
    // Until other series are announced, the "all books" view is just Hangmen.
    if (seriesMode === 'all') return BOOKS.filter((b) => b.seriesKey === 'hangmen');
    return BOOKS.filter((b) => b.seriesKey === seriesMode);
  }, [seriesMode, homepage]);

  function scrollBy(dir) {
    const t = trackRef.current;
    if (!t) return;
    const card = t.querySelector('.er-card');
    const w = card ? card.getBoundingClientRect().width + 28 : 320;
    t.scrollBy({ left: dir * w, behavior: 'smooth' });
  }

  return (
    <section className="er-shelf" id="books" data-screen-label="Books">
      <div className="er-shelf__inner">
        {homepage && (
          <div style={{ marginTop: 18, textAlign: 'center' }}>
            <a className="er-cta" href="books.html">See all books</a>
          </div>
        )}

        <div className="er-shelf__viewport">
          <button
            className="er-shelf__arrow er-shelf__arrow--prev"
            onClick={() => scrollBy(-1)}
            aria-label="Previous book"
            type="button"
          >‹</button>
          <button
            className="er-shelf__arrow er-shelf__arrow--next"
            onClick={() => scrollBy(1)}
            aria-label="Next book"
            type="button"
          >›</button>
          <div className="er-shelf__track" ref={trackRef}>
          {list.map((book, i) =>
          <article className="er-card" key={book.id}>
              <div className="er-card__cover" onClick={() => onOpenBook(book)}>
                {book.cover ?
              <img src={book.cover} alt={`${book.title} cover`} /> :

              <div className="er-book__placeholder">
                    <strong>{book.title}</strong>
                    <span>cover · reveal · TBC</span>
                  </div>
              }
                <div className="er-card__overlay">
                  <span>read more →</span>
                </div>
              </div>
              <div className="er-card__series">{book.series}</div>
              <h3 className="er-card__title">{book.title}</h3>
              <div className="er-card__meta">
                <span><b>{book.date}</b></span>
                <span>{book.status}</span>
              </div>
              <p className="serif-body" style={{ fontSize: 16, marginTop: 8 }}>{book.blurb}</p>
              {book.readUrl ? (
                <a className="er-cta er-cta--filled er-card__cta" href={book.readUrl} target="_blank" rel="noopener">
                  Read now on Amazon
                </a>
              ) : book.preorderUrl ? (
                <a className="er-cta er-cta--filled er-card__cta" href={book.preorderUrl} target="_blank" rel="noopener">
                  Pre-order now on Amazon
                </a>
              ) : (
                <button className="er-cta er-card__cta" onClick={() => onOpenBook(book)}>
                  Pre-order coming
                </button>
              )}
            </article>
          )}
          </div>
        </div>

        <div className="label" style={{ textAlign: 'center', marginTop: 12 }}>
          ← drag, scroll, or click any cover to read more →
        </div>
      </div>
    </section>);

}

/* ============================================================
   SERIES — staggered rows
   ============================================================ */
function SeriesRows({ onPickSeries }) {
  const ornaments = {
    hangmen: <SerpentHeart size={300} color="currentColor" />,
    gods: <AppleBite size={300} color="currentColor" />,
    cuc: <DaggerRose size={300} color="currentColor" />
  };
  return (
    <section className="er-section" id="series" data-screen-label="04 Series" style={{ padding: 0 }}>
      <div style={{ maxWidth: 1500, margin: '0 auto', padding: 'clamp(80px,12vw,180px) clamp(20px,4vw,80px) 64px' }}>
        <div className="er-section__head">
          <div>
            <div className="er-section__chapter">
              <span>The universe</span>
            </div>
            <h2 className="display display--lg" style={{ marginTop: 20 }}>
              One <em>world.</em> Three <em>doors</em> in.
            </h2>
          </div>
          <p className="serif-body" style={{ maxWidth: '38ch', fontSize: 18 }}>
            Read in any order. They braid in the middle. They all end the same way — with someone happy and someone in the ground.
          </p>
        </div>
      </div>

      <div className="er-series">
        {SERIES.map((s, i) =>
        <Reveal key={s.key}>
            <div className="er-series__row" onClick={() => {onPickSeries(s.key);scrollToId('books');}}>
              <div className="er-series__num">{`0${i + 1}`}</div>
              <div>
                <div className="label label--accent" style={{ marginBottom: 12 }}>{s.label}</div>
                <h3 className="er-series__title">{s.title}</h3>
                <p className="er-series__tagline">{s.tagline}</p>
                <p style={{ fontFamily: 'var(--er-display)', color: 'var(--er-ink-dim)', fontSize: 15 }}>
                  {s.note}
                </p>
                <span className="er-series__hover-cta">Enter</span>
              </div>
              <ul className="er-series__entries">
                {s.books.map((b, j) =>
              <li key={j}>
                    <span>0{j + 1} · {b}</span>
                    <span>{i === 0 && j === 0 ? '8 Aug' : i === 0 && j === 1 ? '8 Sep' : i === 0 && j === 2 ? '8 Oct' : 'TBC'}</span>
                  </li>
              )}
                <li style={{ borderBottom: 'none', marginTop: 6 }}>
                  <span style={{ color: 'var(--er-ink-dim)' }}>Begins</span>
                  <span>{s.starts}</span>
                </li>
              </ul>
              <div className="er-series__glyph" style={{ color: 'var(--er-oxblood)' }}>
                {ornaments[s.key]}
              </div>
            </div>
          </Reveal>
        )}
      </div>
    </section>);

}

/* ============================================================
   AUTHORS
   ============================================================ */
function Authors() {
  return (
    <section className="er-section" id="about" data-screen-label="05 About" style={{ padding: 0 }}>
      <div className="er-authors">
        <Reveal className="er-authors__visual">
          <div className="er-authors__silhouette">
            <img src="assets/brand/author-portrait.png" alt="Eve Riche" className="er-authors__photo" />
          </div>
          <div className="er-authors__caption">
            No headshot · not now · maybe not <b>ever</b>
          </div>
        </Reveal>

        <Reveal className="er-authors__body" delay={120}>
          <h2 className="display display--md">
            Two voices. <em>One</em> heartbeat.
          </h2>
          <p>
            Eve Riche is two USA Today bestselling authors writing under one pen name. They write dark why-choose romance about people who kill together, love fiercely, and refuse to apologize for either.
          </p>
          <p>
            Their books are explicit, darkly humorous, and emotionally unflinching. If you want morally grey characters and chaotic murder puppies — they’re your girls.
          </p>
          <p style={{ color: 'var(--er-ink-dim)', fontSize: 17, marginTop: 12 }}>They won't confess their names. Snitches get stitches...

          </p>
          <div className="er-authors__signature">
            <b>~ Eve Riche ~</b>
            <span></span>
          </div>
        </Reveal>
      </div>
    </section>);

}

/* ============================================================
   QUIZ — "Read me first"
   ============================================================ */
function Quiz({ onOpenBook }) {
  const [step, setStep] = useStateS(0);
  const [scores, setScores] = useStateS({ hangmen: 0, gods: 0, cuc: 0 });

  function choose(a) {
    const ns = { ...scores };
    Object.keys(a.w || {}).forEach((k) => {ns[k] = (ns[k] || 0) + a.w[k];});
    setScores(ns);
    setStep(step + 1);
  }

  function reset() {
    setStep(0);
    setScores({ hangmen: 0, gods: 0, cuc: 0 });
  }

  const done = step >= QUIZ.length;
  const winner = done ?
  Object.keys(scores).reduce((a, b) => scores[a] >= scores[b] ? a : b, 'hangmen') :
  null;
  const result = winner ? QUIZ_RESULTS[winner] : null;
  const resultBook = result ? BOOKS.find((b) => b.id === result.bookId) : null;

  return (
    <section className="er-quiz" id="quiz" data-screen-label="06 Quiz">
      <div className="er-quiz__inner">
        <Reveal>
          <div className="er-section__chapter" style={{ justifyContent: 'center' }}>
            <span>Read me first</span>
          </div>
        </Reveal>
        <Reveal delay={80}>
          <h2 className="display display--lg" style={{ margin: '24px 0 16px' }}>
            <em>Three questions.</em> One ruined night.
          </h2>
        </Reveal>
        <Reveal delay={160}>
          <p className="serif-body" style={{ fontSize: 19, maxWidth: '52ch', margin: '0 auto' }}>
            We don’t care where you start — they all braid — but if you want a recommendation, indulge us.
          </p>
        </Reveal>

        <div className="er-quiz__progress" style={{ marginTop: 40 }}>
          {QUIZ.map((_, i) =>
          <span key={i} className={i <= (done ? QUIZ.length : step) - 1 ? 'is-on' : ''} />
          )}
        </div>

        {!done &&
        <div className="er-quiz__step">
            <h3 className="er-quiz__question">{QUIZ[step].q}</h3>
            <div className="er-quiz__opts">
              {QUIZ[step].a.map((a, i) =>
            <button key={i} data-letter={a.letter} onClick={() => choose(a)}>
                  <span>{a.text}</span>
                </button>
            )}
            </div>
            <div className="label" style={{ marginTop: 24 }}>
              question {step + 1} of {QUIZ.length}
            </div>
          </div>
        }

        {done && resultBook &&
        <div className="er-quiz__result">
            <div className="er-quiz__result-cover">
              {resultBook.cover ?
            <img src={resultBook.cover} alt={resultBook.title} /> :

            <div className="er-book__placeholder"><strong>{resultBook.title}</strong></div>
            }
            </div>
            <div>
              <div className="label label--accent" style={{ marginBottom: 8 }}>Your prescription</div>
              <h4>{result.title.split('.').map((p, i) => i === 0 ? <em key={i}>{p}.</em> : p).filter(Boolean)}</h4>
              <p>{result.sub}</p>
              <p style={{ fontFamily: 'var(--er-display)', fontSize: 22, color: 'var(--er-ink)', marginBottom: 18 }}>
                Begin with <em style={{ color: 'var(--er-oxblood)' }}>{resultBook.title}</em>.
              </p>
              <div className="er-quiz__result-actions">
                <button className="er-cta er-cta--filled" onClick={() => onOpenBook(resultBook)}>See the book</button>
                <button className="er-cta" onClick={() => scrollToId('newsletter')}>Tell me when it drops</button>
                <button className="er-quiz__reset" onClick={reset}>retake</button>
              </div>
            </div>
          </div>
        }
      </div>
    </section>);

}

/* ============================================================
   NEWSLETTER
   ============================================================ */
function Newsletter() {
  const [email, setEmail] = useStateS('');
  const [submitted, setSubmitted] = useStateS(false);
  const [error, setError] = useStateS('');

  function submit(e) {
    e.preventDefault();
    if (!/^[^@\s]+@[^@\s]+\.[^@\s]+$/.test(email)) {
      setError('That doesn’t look like an email, sweet thing. Try again.');
      return;
    }
    setError('');
    setSubmitted(true);
  }

  return (
    <section className="er-newsletter" id="newsletter" data-screen-label="07 Newsletter">
      <div className="er-newsletter__inner">
        <Reveal>
          <div className="er-section__chapter" style={{ justifyContent: 'center' }}>
            <span>Members only</span>
          </div>
        </Reveal>
        <Reveal delay={80}>
          <h2 className="er-newsletter__title">
            Step inside <em>the Club.</em>
          </h2>
        </Reveal>
        <Reveal delay={160}>
          <p className="er-newsletter__sub">
            A velvet rope, a low-lit room, a list with your name on it. First chapters, cover reveals, bonus scenes and ARC drops — straight to your inbox before anyone else hears the door open.
          </p>
        </Reveal>

        <Reveal delay={200}>
          <Countdown target={new Date('2026-08-08T00:00:00Z')} label="Doors open in" />
        </Reveal>

        <div className="er-menu-heading">
          <h3>The Menu</h3>
          <p>Hangmen Trilogy starts 8 August 2026</p>
        </div>

        <ul className="er-newsletter__perks">
          <li>First chapter of What We Bury</li>
          <li>Cover reveals before they go public</li>
          <li>Bonus POVs &amp; deleted scenes</li>
          <li>Priority ARC consideration &amp; members-only giveaways</li>
        </ul>

        {submitted ?
        <div className="er-form--success">
            <strong>You’re on the list, sweetheart.</strong>
            <span>The doorman saw you. The first chapter is on its way to {email}. If it’s in spam, you’re holding it wrong — drag us into the inbox.</span>
          </div> :

        <form className="er-form" onSubmit={submit}>
            <input
            type="email"
            placeholder="your@email"
            value={email}
            onChange={(e) => setEmail(e.target.value)}
            aria-label="Email address" />
          
            <button type="submit"><span>RSVP</span></button>
          </form>
        }
        {error && <div className="er-fineprint" style={{ color: 'var(--er-oxblood)', marginTop: 16 }}>{error}</div>}
        <p className="er-fineprint">
          Members only · unsubscribe with one click · the velvet rope swings both ways
        </p>
      </div>
    </section>);

}

/* ============================================================
   EVENTS
   ============================================================ */
function Events() {
  return (
    <section className="er-section" id="events" data-screen-label="08 Events">
      <div className="er-section__head">
        <div>
          <div className="er-section__chapter">
            <span>The diary</span>
          </div>
          <h2 className="display display--lg" style={{ marginTop: 20 }}>
            Where you can <em>find</em> us.
          </h2>
        </div>
        <p className="serif-body" style={{ maxWidth: '32ch' }}>
          Online unless noted. Always introvert-friendly. Sometimes lipstick required.
        </p>
      </div>
      <div className="er-events">
        {EVENTS.map((e, i) =>
        <Reveal key={i} delay={i * 50}>
            <div className="er-event" onClick={() => scrollToId('newsletter')}>
              <div className="er-event__date">
                {e.date}
                <small>{e.year}</small>
              </div>
              <div className="er-event__title">{e.title}</div>
              <div className="er-event__where">{e.where}</div>
              <div className="er-event__tag">{e.tag}</div>
            </div>
          </Reveal>
        )}
      </div>
    </section>);

}

/* ============================================================
   BONUS
   ============================================================ */
function Bonus({ showHeader = true } = {}) {
  return (
    <section className="er-section" id="bonus" data-screen-label="08b Bonus">
      {showHeader && (
        <div className="er-section__head">
          <div>
            <div className="er-section__chapter">
              <span>Bonus material</span>
            </div>
            <h2 className="display display--lg" style={{ marginTop: 20 }}>
              Extras for the <em>devoted.</em>
            </h2>
          </div>
          <p className="serif-body" style={{ maxWidth: '32ch' }}>
            Patreon, newsletter, preorder rewards — the gift bag at the back of the confessional.
          </p>
        </div>
      )}
      <div className="er-bonus">
        {BONUS.map((b, i) =>
        <Reveal key={i} delay={i * 60}>
            <div className="er-bonus__card">
              <div className="label label--accent">{b.label}</div>
              <h4>{b.title}</h4>
              <p>{b.body}</p>
              <div className="er-bonus__lock">❦ {b.lock}</div>
              {b.cta && (
                <a className="er-cta er-cta--filled er-bonus__cta" href={b.cta.href}>
                  {b.cta.label}
                </a>
              )}
            </div>
          </Reveal>
        )}
      </div>
    </section>);

}

/* ============================================================
   PRESS / CONTACT
   ============================================================ */
function Press({ onCw }) {
  return (
    <section className="er-section" id="press" data-screen-label="09 Press">
      <div className="er-section__head">
        <div>
          <div className="er-section__chapter">
            <span>The rest</span>
          </div>
          <h2 className="display display--lg" style={{ marginTop: 20 }}>
            For agents, podcasters, <em>conspirators.</em>
          </h2>
        </div>
        <p className="serif-body" style={{ maxWidth: '32ch' }}>
          No DMs · email only · we read it all · sometimes we even reply
        </p>
      </div>
      <div className="er-press">
        <Reveal><div className="er-press__block">
          <div className="label label--accent" style={{ }}>For readers</div>
          <h4>The list</h4>
          <p>Reply to any newsletter — a human (one of the two trench coats) will answer.</p>
          <button className="er-cta er-cta--filled" onClick={() => scrollToId('newsletter')}>RSVP to the Club</button>
        </div></Reveal>
        <Reveal delay={80}><div className="er-press__block">
          <div className="label label--accent" style={{ }}>Press &amp; rights</div>
          <h4>Hi. We bite.</h4>
          <p>Foreign rights, podcast interviews, panel invites, content trades. Pitch us in a paragraph; we’ll write back in two.</p>
          <a className="er-cta" href="mailto:press@everiche.com">press@everiche.com</a>
        </div></Reveal>
        <Reveal delay={160}><div className="er-press__block">
          <div className="label label--accent" style={{ }}>For sensitive readers</div>
          <h4>Content warnings</h4>
          <p>We list everything. We mean it. We’d rather you don’t read us than read us underprepared.</p>
          <button className="er-cta" onClick={onCw}>Read warnings</button>
        </div></Reveal>
        <Reveal delay={240}><div className="er-press__block">
          <div className="label label--accent" style={{ }}>Reader community</div>
          <h4>The Confessional</h4>
          <p>Our Discord. Spoiler-tagged channels per book. Daily chaos. Murder-puppy memes. Annotations only people who finished should read.</p>
          <a className="er-cta" href="#">Open Discord</a>
        </div></Reveal>
      </div>
    </section>);

}

/* ============================================================
   CW BANNER + MODAL
   ============================================================ */
function CwBanner({ onOpen }) {
  return (
    <div className="er-cw-banner" data-screen-label="CW Banner">
      <div className="er-cw-banner__label">Content advisory</div>
      <div className="er-cw-banner__msg">
        These books are dark on purpose. We list every reason out loud.
      </div>
      <button className="er-cta" onClick={onOpen}>Read full warnings</button>
    </div>);

}

function CwModal({ open, onClose }) {
  useEffectS(() => {
    if (!open) return;
    function key(e) {if (e.key === 'Escape') onClose();}
    window.addEventListener('keydown', key);
    document.body.style.overflow = 'hidden';
    return () => {
      window.removeEventListener('keydown', key);
      document.body.style.overflow = '';
    };
  }, [open, onClose]);

  if (!open) return null;
  return (
    <div className="er-modal-overlay" onClick={onClose} role="dialog" aria-modal="true">
      <div className="er-modal" onClick={(e) => e.stopPropagation()}>
        <button className="er-modal__close" onClick={onClose}>Close ✕</button>
        <div className="label label--accent" style={{ }}>Read this before you read us</div>
        <h3>Content <em>warnings.</em></h3>
        <p className="er-modal__lede">
          We write dark romance that is actually dark. Not aestheticized darkness where everyone’s hot and brooding and nobody does anything morally reprehensible. Our men kill people. Sometimes the women do too. The on-page intimacy is enthusiastic; the on-page violence is not.
        </p>
        <ul className="er-cw__list">
          {CONTENT_WARNINGS.map((w, i) => <li key={i}>{w}</li>)}
        </ul>
        <div className="er-modal__final">
          Every book ships with its own content-warning sheet. Reply to any newsletter and we’ll send yours.
        </div>
      </div>
    </div>);

}

/* ============================================================
   FOOTER
   ============================================================ */
function Footer() {
  return (
    <footer className="er-footer" data-screen-label="Footer">
      <div className="er-footer__top">
        <div className="er-footer__brand">
          <img src="assets/brand/er-logo-circle.png" alt="Eve Riche" />
          <p>Eve Riche writes unapologetically dark why-choose romance.</p>
        </div>
        <div className="er-footer__col">
          <h5>Read</h5>
          <ul>
            <li><a href="books.html">All books</a></li>
            <li><a href="index.html#newsletter">Newsletter</a></li>
            <li><a href="warnings.html">Content warnings</a></li>
            <li><a href="about.html">About</a></li>
            <li><a href="bonuses.html">Bonuses</a></li>
          </ul>
        </div>
        <div className="er-footer__col">
          <h5>Find us</h5>
          <ul>
            <li><a href="https://instagram.com/EveRicheWrites" target="_blank" rel="noopener">Instagram</a></li>
            <li><a href="https://tiktok.com/@EveRicheWrites" target="_blank" rel="noopener">TikTok</a></li>
          </ul>
        </div>
        <div className="er-footer__col">
          <h5>Legal</h5>
          <ul>
            <li><a href="privacy.html">Privacy policy</a></li>
            <li><a href="terms.html">Terms of service</a></li>
            <li><a href="accessibility.html">Accessibility</a></li>
          </ul>
        </div>
      </div>
      <div className="er-footer__bottom">
        <span>© 2026 Velvet and Vice Press Pty Ltd · Eve Riche is an imprint pen name</span>
      </div>
    </footer>);

}

Object.assign(window, {
  Header, Hero, Pitch, Books, SeriesRows, Authors, Quiz,
  Newsletter, Events, Bonus, Press, CwBanner, CwModal, Footer
});