/* global React */
const { useState, useEffect, useRef } = React;

// ============ Nav ============
function Nav({ active, onNav }) {
  const [scrolled, setScrolled] = useState(false);
  const [menuOpen, setMenuOpen] = useState(false);

  useEffect(() => {
    const onScroll = () => setScrolled(window.scrollY > 40);
    window.addEventListener("scroll", onScroll);
    return () => window.removeEventListener("scroll", onScroll);
  }, []);

  // Close overlay when navigating
  const handleNav = id => {
    setMenuOpen(false);
    document.body.style.overflow = "";
    onNav(id);
  };

  // Lock body scroll when overlay is open
  useEffect(() => {
    document.body.style.overflow = menuOpen ? "hidden" : "";
    return () => { document.body.style.overflow = ""; };
  }, [menuOpen]);

  const links = [
    { id: "book-one", label: "Book One" },
    { id: "series", label: "The Series" },
    { id: "world", label: "The World" },
    { id: "map", label: "Thresholds" },
    { id: "characters", label: "Characters" },
    { id: "author", label: "Author" },
  ];
  return (
    <>
      <nav className={"nav " + (scrolled ? "scrolled" : "")}>
        <a href="#top" className="nav-brand" onClick={e => { e.preventDefault(); handleNav("top"); }}>
          <img src="assets/brand/jackal-stamp.png" alt=""/>
          <span>The Jackal Court</span>
        </a>
        <div className="nav-links">
          {links.map(l => (
            <a key={l.id} href={"#" + l.id}
               className={active === l.id ? "active" : ""}
               onClick={e => { e.preventDefault(); handleNav(l.id); }}>{l.label}</a>
          ))}
        </div>
        <button className="nav-cta" onClick={() => handleNav("author")}>Notify Me</button>
        <button
          className={"nav-hamburger " + (menuOpen ? "open" : "")}
          onClick={() => setMenuOpen(o => !o)}
          aria-label={menuOpen ? "Close menu" : "Open menu"}
          aria-expanded={menuOpen}
        >
          <span className="hb-line"/>
          <span className="hb-line"/>
          <span className="hb-line"/>
        </button>
      </nav>
      {menuOpen && (
        <div className="nav-overlay" onClick={() => setMenuOpen(false)} role="dialog" aria-modal="true">
          <div className="nav-overlay-inner" onClick={e => e.stopPropagation()}>
            <div className="overlay-brand">
              <span className="overline">The Jackal Court</span>
            </div>
            {links.map(l => (
              <a key={l.id} href={"#" + l.id}
                 className={"overlay-link " + (active === l.id ? "active" : "")}
                 onClick={e => { e.preventDefault(); handleNav(l.id); }}>
                {l.label}
              </a>
            ))}
            <button className="btn-primary overlay-cta" onClick={() => handleNav("author")}>
              Notify Me at Launch
            </button>
          </div>
        </div>
      )}
    </>
  );
}

// ============ Hero ============
const BOOK_ORDINALS = ['','One','Two','Three','Four','Five','Six','Seven','Eight','Nine','Ten'];
function pillarSub(book) {
  if (book.tagline) return book.tagline;
  if (book.blurb) return book.blurb.split(/\n\n/)[0].replace(/\*\*/g,'');
  return '';
}

function Hero({ onNav, onOpen }) {
  const books = window.JACKAL_COURT_BOOKS;
  const available = books.filter(b => b.status === 'available').sort((a,b) => a.n - b.n);
  const startHere = available[0];
  const latest    = available[available.length - 1];
  const showTwin  = available.length >= 2 && startHere.n !== latest.n;

  if (showTwin) {
    return (
      <section className="hero hero-twin" id="top">
        <div className="hero-bg-abstract">
          <div className="hero-grain"/>
          <div className="hero-glyph"/>
          <div className="hero-mist"/>
        </div>
        <div className="hero-inner">
          <div className="hero-head">
            <span className="overline">S. J. Kemet presents</span>
            <h1>The Jackal<br/><span className="gold">Court</span></h1>
            <p className="hero-tagline twin-tagline">
              A hidden world ruled by ancient beast-kin.<br/>
              Ten books. One woman who sees the pattern.
            </p>
          </div>
          <div className="twin">
            {/* Left pillar: Start Here */}
            <div className="pillar">
              <div className="pillar-label">Start Here</div>
              <div className="cover-frame pillar-cover-wrap">
                <div className="pillar-cover" style={{ backgroundImage: `url(${startHere.cover})` }}/>
              </div>
              <div className="pillar-meta">
                <div className="pillar-numeral">Book {BOOK_ORDINALS[startHere.n]}</div>
                <h2 className="pillar-title">{startHere.title}</h2>
                <p className="pillar-sub">{pillarSub(startHere)}</p>
                <button className="btn-primary pillar-btn" onClick={() => onOpen(startHere)}>Begin the Series</button>
              </div>
            </div>
            <div className="twin-divider"/>
            {/* Right pillar: Latest Release */}
            <div className="pillar pillar-latest">
              <div className="latest-ribbon">Just Released</div>
              <div className="pillar-label">Latest Release</div>
              <div className="cover-frame pillar-cover-wrap">
                <div className="pillar-cover" style={{ backgroundImage: `url(${latest.cover})` }}/>
              </div>
              <div className="pillar-meta">
                <div className="pillar-numeral">Book {BOOK_ORDINALS[latest.n]}</div>
                <h2 className="pillar-title">{latest.title}</h2>
                <p className="pillar-sub">{pillarSub(latest)}</p>
                <button className="btn-ghost pillar-btn" onClick={() => onOpen(latest)}>Read Book {BOOK_ORDINALS[latest.n]}</button>
              </div>
            </div>
          </div>
          <div className="hero-meta twin-meta">
            <span><i className="dot"/>Monster Romance</span>
            <span><i className="dot"/>Egyptian Mythology</span>
            <span><i className="dot"/>Neurodivergent Leads</span>
          </div>
        </div>
        <div className="scroll-cue"><span>Scroll</span><div className="line"/></div>
      </section>
    );
  }

  // Single hero (only book 1 available)
  return (
    <section className="hero" id="top">
      <div className="hero-bg-abstract">
        <div className="hero-grain"/>
        <div className="hero-glyph"/>
        <div className="hero-mist"/>
      </div>
      <div className="hero-content">
        <div className="hero-copy">
          <span className="overline">S. J. Kemet presents</span>
          <h1>
            The Jackal<br/>
            <span className="gold">Court</span>
          </h1>
          <p className="hero-tagline">
            A hidden world ruled by ancient beast-kin.<br/>
            Ten books. One woman who sees the pattern.
          </p>
          <div className="hero-meta">
            <span><i className="dot"/>Monster Romance</span>
            <span><i className="dot"/>Egyptian Mythology</span>
            <span><i className="dot"/>Neurodivergent Leads</span>
          </div>
          <div className="hero-ctas">
            <a className="btn-primary" href="#book-one" onClick={e => { e.preventDefault(); onNav("book-one"); }}>
              Begin with Book One
            </a>
            <a className="btn-ghost" href="#series" onClick={e => { e.preventDefault(); onNav("series"); }}>
              The Full Series
            </a>
          </div>
        </div>
        <div className="hero-cover-frame cover-frame">
          <div className="hero-cover" style={{ backgroundImage: `url(${window.JACKAL_COURT_BOOKS[0].cover})` }}/>
        </div>
      </div>
      <div className="scroll-cue">
        <span>Scroll</span>
        <div className="line"/>
      </div>
    </section>
  );
}

// ============ Featured Book ============
function Featured({ onOpen }) {
  const book = window.JACKAL_COURT_BOOKS[0];
  return (
    <section className="featured" id="book-one">
      <div className="section-inner">
        <div className="section-header" style={{ marginBottom: 56 }}>
          <div className="ornament"><span className="diamond"/></div>
          <span className="overline">Begin Here</span>
          <h2>Book One</h2>
          <p>The first binding in four thousand years of guild record.</p>
        </div>
        <div className="featured-grid">
          <div className="featured-cover" style={{ backgroundImage: `url(${book.cover})` }}/>
          <div className="featured-copy">
            <span className="overline">Book One · The Jackal Court</span>
            <h2>
              <span className="small">Bound to the</span>
              Anubis Guardian
            </h2>
            <p className="featured-tagline">{book.tagline}</p>

            <div className="meta-grid">
              <div className="meta-item">
                <span className="ui-label">Setting</span>
                <span className="v">{book.setting}</span>
              </div>
              <div className="meta-item">
                <span className="ui-label">Heat</span>
                <span className="v">{book.heat}</span>
              </div>
              <div className="meta-item">
                <span className="ui-label">Neurotype</span>
                <span className="v">{book.nd}</span>
              </div>
              <div className="meta-item">
                <span className="ui-label">Length</span>
                <span className="v">{book.length}</span>
              </div>
            </div>

            <div className="blurb">
              {book.blurb.split(/\n\n+/).map((para, i) => <p key={i}>{para}</p>)}
            </div>

            <div className="tropes">
              {book.tropes.map(t => <span key={t} className="trope">{t}</span>)}
            </div>

            <details className="warnings">
              <summary>Content & Trigger Warnings</summary>
              <ul>
                {book.warnings.map((w, i) => <li key={i}>{w}</li>)}
              </ul>
            </details>

            <div className="hero-ctas" style={{ marginTop: 40 }}>
              <a className="btn-primary" href="#notify" onClick={e => { e.preventDefault(); document.getElementById("author").scrollIntoView({behavior:"smooth"}); }}>
                Notify me at launch
              </a>
              <button className="btn-ghost" onClick={() => onOpen(book)}>
                Read Excerpt
              </button>
            </div>
          </div>
        </div>
      </div>
    </section>
  );
}

// ============ Series grid ============
function Series({ onOpen }) {
  return (
    <section className="books" id="series">
      <div className="section-inner">
        <div className="section-header">
          <div className="ornament"><span className="diamond"/></div>
          <span className="overline">The Complete Ten</span>
          <h2>A Ladder of Emotional Intensity</h2>
          <p>Bound. Claimed. Marked. Tamed. Sworn. Lost. Forged. Hunted. Broken. Crowned.<br/>
            Each book stands alone. Together they carry a three-thousand-year reckoning.</p>
        </div>
        <div className="books-grid">
          {window.JACKAL_COURT_BOOKS.map(b => <BookCard key={b.n} book={b} onOpen={onOpen}/>)}
        </div>
      </div>
    </section>
  );
}

function BookCard({ book, onOpen }) {
  const isVeiled    = book.status === "veiled";
  const isAnnounced = book.status === "announced";
  const isAvailable = book.status === "available";
  const sealed = book.status === "coming" || isVeiled;
  const cls = "book-card " + (sealed ? "sealed " : "open ") + (isVeiled ? "veiled " : "") + (isAnnounced ? "announced" : "");
  return (
    <button className={cls} onClick={() => onOpen(book)}>
      <div className="book-cover-wrap">
        {sealed ? (
          <div className="sealed-file">
            <div className="sealed-grain"/>
            <div className="sealed-corner tl"/>
            <div className="sealed-corner tr"/>
            <div className="sealed-corner bl"/>
            <div className="sealed-corner br"/>
            <div className="sealed-body">
              <div className="sealed-roman">{book.numeral}</div>
              {!isVeiled && (
                <div className="sealed-verb">{book.verb || "Sealed"}</div>
              )}
              <div className="sealed-rule"/>
              <div className="sealed-status">{isVeiled ? "Finale · Veiled" : book.statusLabel}</div>
            </div>
            <div className="wax-seal">
              <div className="wax-ring">
                <div className="wax-glyph">JC</div>
              </div>
            </div>
          </div>
        ) : (
          <div className="book-cover-img" style={{ backgroundImage: `url(${book.cover})` }}/>
        )}
      </div>
      <div className="book-info">
        <div className="book-num">
          Book {book.numeral}
          {isAvailable  && <span className="book-num-badge">Available</span>}
          {isAnnounced  && <span className="book-num-badge announced-badge">Coming Soon</span>}
        </div>
        <div className="book-title">
          {isVeiled
            ? <span className="muted-it">— sealed —</span>
            : (sealed ? null : book.title)}
        </div>
        <div className="book-meta">
          {isVeiled ? "Revealed upon release" : (sealed ? null : `${book.setting} · ${book.nd}`)}
        </div>
      </div>
    </button>
  );
}

// ============ World ============
function World() {
  const codex = window.JACKAL_COURT_CODEX || [];
  if (codex.length === 0) return null;
  return (
    <section className="world" id="world">
      <div className="section-inner">
        <div className="section-header">
          <div className="ornament"><span className="diamond"/></div>
          <span className="overline">The Hidden World</span>
          <h2>Codex of the Guild</h2>
          <p>The gods did not vanish. They stepped sideways, and stayed.</p>
        </div>
        <div className="codex-grid">
          {codex.map((c, i) => (
            <div className="codex-card" key={c.slug}>
              <div className="num">{String(i+1).padStart(2,"0")}</div>
              <h3>{c.title}</h3>
              <div className="short">{c.short}</div>
              <div className="body">{c.body}</div>
            </div>
          ))}
        </div>
      </div>
    </section>
  );
}

// ============ Characters ============
function Characters() {
  // Only show cast whose book is already available — avoid spoilers.
  const maxBook = Math.max(...window.JACKAL_COURT_BOOKS.filter(b => b.status === "available" || b.status === "announced").map(b => b.n));
  const cast = window.JACKAL_COURT_CAST.filter(c => c.book <= maxBook);
  return (
    <section className="characters" id="characters">
      <div className="section-inner">
        <div className="section-header">
          <div className="ornament"><span className="diamond"/></div>
          <span className="overline">The Court · Book One Roster</span>
          <h2>Those You Meet First</h2>
          <p>The cast seen, or glimpsed, in Book One. More names will be added to this page as the series releases.</p>
        </div>
        <div className="cast-grid">
          {cast.map(c => (
            <div className="cast-card" key={c.name}>
              <h3 className="cast-name">{c.name}</h3>
              <div className="cast-line">{c.line}</div>
              <div className="cast-meta">
                <span>{c.age}</span>
                <span>{c.role}</span>
              </div>
              <p className="cast-desc">{c.desc}</p>
            </div>
          ))}
        </div>
      </div>
    </section>
  );
}

// ============ Author / Signup ============
function Author() {
  const [email, setEmail] = useState("");
  const [sent, setSent] = useState(false);
  const submit = e => {
    e.preventDefault();
    if (!email.includes("@")) return;
    try {
      const list = JSON.parse(localStorage.getItem("jackal_notify_list") || "[]");
      list.push({ email, ts: Date.now() });
      localStorage.setItem("jackal_notify_list", JSON.stringify(list));
    } catch (_) {}
    setSent(true);
  };
  return (
    <section className="author" id="author">
      <div className="section-inner author-inner">
        <div className="author-wordmark">
          <span className="aw-initials">S. J.</span>
          <span className="aw-name">Kemet</span>
        </div>
        <p className="statement">
          "I write the women who notice what others cannot. The ancient beings who have spent too long alone. The love that arrives the way it was always going to."
        </p>
        <p className="note">
          S. J. Kemet is a pseudonym. The Jackal Court is her first series:
          ten standalone romances across the hidden world of the Egyptian beast-kin,
          each centred on a neurodivergent heroine whose mind is the reason she is indispensable.
        </p>
        {!sent ? (
          <form className="signup-form" onSubmit={submit}>
            <input type="email" placeholder="your@email.com" value={email} onChange={e => setEmail(e.target.value)} required/>
            <button type="submit">Notify Me</button>
          </form>
        ) : (
          <div className="signup-success">Noted. You will be the first to know when Book One arrives.</div>
        )}
      </div>
    </section>
  );
}

function Footer() {
  return (
    <footer>
      <div className="row"><strong>The Jackal Court</strong> · by S. J. Kemet</div>
      <div className="row">Ten books · Spicy monster romance · Egyptian mythology · Neurodivergent heroines</div>
      <div className="row" style={{ marginTop: 24 }}>© 2026 S. J. Kemet · All rights reserved</div>
    </footer>
  );
}

// ============ Modal ============
function BookModal({ book, onClose }) {
  useEffect(() => {
    const onEsc = e => { if (e.key === "Escape") onClose(); };
    document.addEventListener("keydown", onEsc);
    document.body.style.overflow = "hidden";
    return () => {
      document.removeEventListener("keydown", onEsc);
      document.body.style.overflow = "";
    };
  }, [onClose]);
  if (!book) return null;

  const isVeiled    = book.status === "veiled";
  const isAnnounced = book.status === "announced";
  const isAvailable = book.status === "available";
  const sealed = book.status === "coming" || isVeiled;

  // Sealed view: minimal spoiler-free display
  if (sealed) {
    return (
      <div className="modal-backdrop" onClick={onClose}>
        <div className="modal" onClick={e => e.stopPropagation()}>
          <button className="modal-close" onClick={onClose}>×</button>
          <div className="modal-grid">
            <div>
              <div className="modal-cover" style={{ background: "radial-gradient(circle at center, #1a120a, #0a0604)", display:"flex", alignItems:"center", justifyContent:"center" }}>
                <div style={{ textAlign:"center", color:"var(--gold)", fontFamily:"Cinzel", letterSpacing:"0.25em" }}>
                  <div style={{ fontSize: 36, marginBottom: 12 }}>{book.numeral}</div>
                  {isVeiled && <div style={{ fontSize: 11, opacity: 0.6 }}>VEILED</div>}
                </div>
              </div>
            </div>
            <div>
              <div className="modal-num">Book {book.numeral} · The Jackal Court</div>
              <h2 style={{ fontFamily:"Cinzel", color:"var(--gold)" }}>{book.numeral}</h2>
              {!isVeiled && book.mmcRole && book.setting && (
                <div className="fmc-line" style={{ marginTop: 8, opacity: 0.75 }}>{book.mmcRole} · {book.setting}</div>
              )}
              <div className="meta-grid" style={{ marginTop: 16 }}>
                <div className="meta-item">
                  <span className="ui-label">Status</span>
                  <span className="v" style={{ color: "var(--paper)" }}>{book.statusLabel}</span>
                </div>
              </div>
              <p style={{ marginTop: 28, fontStyle: "italic", opacity: 0.65, lineHeight: 1.7 }}>
                Details revealed closer to release.
              </p>
            </div>
          </div>
        </div>
      </div>
    );
  }

  // Full view: available books
  return (
    <div className="modal-backdrop" onClick={onClose}>
      <div className="modal" onClick={e => e.stopPropagation()}>
        <button className="modal-close" onClick={onClose}>×</button>
        <div className="modal-grid">
          <div>
            <div className="modal-cover" style={{ backgroundImage: `url(${book.cover})` }}/>
          </div>
          <div>
            <div className="modal-num">Book {book.numeral} · The Jackal Court</div>
            <h2>{book.title}</h2>
            <div className="fmc-line">{book.mmc} × {book.fmc}</div>
            <div className="meta-grid" style={{ marginTop: 8 }}>
              <div className="meta-item"><span className="ui-label">Status</span><span className="v" style={{ color: isAvailable ? "var(--amber)" : "var(--gold)" }}>{book.statusLabel}</span></div>
              <div className="meta-item"><span className="ui-label">Setting</span><span className="v">{book.setting}</span></div>
              <div className="meta-item"><span className="ui-label">Neurotype</span><span className="v">{book.nd}</span></div>
              <div className="meta-item"><span className="ui-label">Heat</span><span className="v">{book.heat}</span></div>
            </div>
            <p className="featured-tagline" style={{ fontSize: 20, marginTop: 24 }}>{book.tagline}</p>
            {book.blurb ? (
              <div className="blurb">
                {book.blurb.split(/\n\n+/).map((para, i) => <p key={i}>{para}</p>)}
              </div>
            ) : (
              <div className="blurb" style={{ color: "var(--paper-mute)" }}>{book.logline}</div>
            )}
            {book.tropes && (
              <div className="tropes">
                {book.tropes.map(t => <span key={t} className="trope">{t}</span>)}
              </div>
            )}
            {book.excerpt && (
              <div className="excerpt-block">
                <div className="excerpt-divider"><span>· First Pages ·</span></div>
                <div className="excerpt-body">
                  {book.excerpt.split(/\n\n+/).map((para, i) => {
                    const isHeading = para.startsWith("**") && para.endsWith("**");
                    const isAside = para.startsWith("*[") && para.endsWith("]*");
                    if (isHeading) {
                      return <h4 key={i} className="excerpt-heading">{para.replace(/\*\*/g, "")}</h4>;
                    }
                    if (isAside) {
                      return <p key={i} className="excerpt-aside">{para.replace(/^\*\[|\]\*$/g, "")}</p>;
                    }
                    // Inline italic *x*
                    const parts = para.split(/(\*[^*]+\*)/g);
                    return (
                      <p key={i}>
                        {parts.map((p, j) =>
                          p.startsWith("*") && p.endsWith("*")
                            ? <em key={j}>{p.slice(1, -1)}</em>
                            : p
                        )}
                      </p>
                    );
                  })}
                </div>
              </div>
            )}
            {book.warnings && (
              <details className="warnings">
                <summary>Content & Trigger Warnings</summary>
                <ul>{book.warnings.map((w,i) => <li key={i}>{w}</li>)}</ul>
              </details>
            )}
          </div>
        </div>
      </div>
    </div>
  );
}

// ============ If You Loved ============
function IfYouLoved() {
  return (
    <section className="loved" id="loved">
      <div className="section-inner">
        <div className="loved-statement">
          <div className="ornament"><span className="diamond"/></div>
          <p className="loved-lede">
            For readers of <em>Sarah&nbsp;J.&nbsp;Maas</em>, <em>Jennifer&nbsp;L.&nbsp;Armentrout</em>, and <em>Ruby&nbsp;Dixon</em>.
          </p>
          <p className="loved-tail">
            Monster romance written with reverence. Fated binding. Touch-starved guardians four thousand years old. Heroines the world already gave up on.
          </p>
        </div>
      </div>
    </section>
  );
}

// ============ Threshold Map ============
function ThresholdMap() {
  const thresholds = window.JACKAL_COURT_THRESHOLDS || [];
  const [active, setActive] = useState(null);
  const activeT = thresholds.find(t => t.n === active) || null;

  return (
    <section className="thresholds" id="map">
      <div className="section-inner">
        <div className="section-header">
          <div className="ornament"><span className="diamond"/></div>
          <span className="overline">Guild Cartography</span>
          <h2>Eight Thresholds. Six Known.</h2>
          <p>Specific places in the world where the boundary between the hidden world and the human one grows thin. They look like ordinary places. They are not.</p>
        </div>
        <div className="threshold-layout">
          <div className="map-frame">
            <div className="map-inner">
              <img src="assets/brand/map-mediterranean.png" alt="" className="map-bg" draggable="false"/>
              {thresholds.map(t => (
                <button
                  key={t.n}
                  className={`threshold-pin ${t.status} ${active === t.n ? "active" : ""}`}
                  style={{ left: `${t.x}%`, top: `${t.y}%` }}
                  onClick={() => setActive(active === t.n ? null : t.n)}
                  aria-label={`Threshold ${t.n}, ${t.city}`}
                >
                  <span className="pin-core"/>
                  <span className="pin-ring"/>
                  <span className="pin-label">{String(t.n).padStart(2,"0")}</span>
                </button>
              ))}
            </div>
          </div>
          <div className="threshold-panel">
            <div className="panel-head">
              <span className="overline">Current Status</span>
              <div className="legend">
                <span className="l-item"><i className="l-dot intact"/>Intact</span>
                <span className="l-item"><i className="l-dot unrecorded"/>Unrecorded</span>
              </div>
              <p className="legend-note">More statuses — <em>contested</em>, <em>lost</em> — will appear on this map as the series releases.</p>
            </div>
            {activeT ? (
              <div className="panel-active">
                <div className="panel-n">Threshold {String(activeT.n).padStart(2,"0")}</div>
                <h3 className="panel-city">{activeT.city}</h3>
                <div className={`panel-status ${activeT.status}`}>
                  {activeT.status === "unrecorded" ? "Unrecorded in any Guild archive" : activeT.status.charAt(0).toUpperCase() + activeT.status.slice(1)}
                </div>
                <p className="panel-disg">{activeT.disguise}</p>
                <button className="panel-back" onClick={() => setActive(null)}>← All thresholds</button>
              </div>
            ) : (
              <ul className="panel-list">
                {thresholds.map(t => (
                  <li key={t.n}>
                    <button onClick={() => setActive(t.n)}>
                      <span className={`l-dot ${t.status}`}/>
                      <span className="p-n">{String(t.n).padStart(2,"0")}</span>
                      <span className="p-city">{t.city}</span>
                      <span className={`p-status ${t.status}`}>
                        {t.status === "unrecorded" ? "unrecorded" : t.status}
                      </span>
                    </button>
                  </li>
                ))}
              </ul>
            )}
          </div>
        </div>
      </div>
    </section>
  );
}

Object.assign(window, { Nav, Hero, Featured, IfYouLoved, Series, World, ThresholdMap, Characters, Author, Footer, BookModal });
