/* global React, ReactDOM, useTweaks, TweaksPanel, TweakSection, TweakRadio, TweakColor, TweakSelect */
const { useState, useEffect } = React;

/* =========================================================================
   NAV  (Stories active)
   ========================================================================= */
function Nav() {
  const [open, setOpen] = useState(false);

  const links = [
    { label: "How it works", href: "index.html#how" },
    { label: "The craft",    href: "index.html#craft" },
    { label: "Stories",      href: "Stories.html", active: true },
  ];

  return (
    <header className="nav" id="nav">
      <a href="index.html" className="wordmark">
        Roast<span className="amp">&amp;</span>Toast
      </a>
      <nav className={"nav-links" + (open ? " open" : "")}>
        {links.map(({ label, href, active }) => (
          <a
            key={href}
            href={href}
            className={"nav-link" + (active ? " is-active" : "")}
            onClick={() => setOpen(false)}
          >
            {label}
          </a>
        ))}
        <a className="nav-cta" href="https://roastandtoast.softr.app" onClick={() => setOpen(false)}>
          Create My Hoodie
        </a>
      </nav>
      <button className="nav-burger" aria-label="Menu" onClick={() => setOpen(o => !o)}>
        <span style={{ transform: open ? "translateY(6.5px) rotate(45deg)" : "" }}></span>
        <span style={{ opacity: open ? 0 : 1 }}></span>
        <span style={{ transform: open ? "translateY(-6.5px) rotate(-45deg)" : "" }}></span>
      </button>
    </header>
  );
}

/* =========================================================================
   STORIES HERO
   ========================================================================= */
function StoriesHero() {
  return (
    <section className="section stories-hero" id="top">
      <div className="shell">
        <div className="sec-head reveal">
          <span className="idx">Stories</span>
          <hr className="rule" />
          <p className="eyebrow">Real results</p>
        </div>
        <div className="lead-grid">
          <div>
            <h1 className="display">
              <span className="line-mask" data-d="1"><span>Proof it</span></span>
              <br />
              <span className="line-mask" data-d="2"><span><em>gets the joke.</em></span></span>
            </h1>
          </div>
          <div className="lead-side reveal" data-d="2">
            <div className="counter">
              <b>06</b>
              <p className="eyebrow">of the ones that made us laugh</p>
            </div>
            <p className="body">
              Every hoodie starts with a person and a story. Here are a few we
              generated so you can picture what yours might become.
            </p>
          </div>
        </div>
      </div>
    </section>
  );
}

/* =========================================================================
   STORY CARDS
   ========================================================================= */
// Source order drives CSS-columns layout. To read left→right across visual rows:
// Row 1 (top): card1, card2, card3 → source positions 0, 2, 4
// Row 2 (bottom): card4, card5, card6 → source positions 1, 3, 5
const STORIES = [
  // ── Column 1 ──
  {
    id: 1, d: 1, type: "roast", style: "Anime",
    src: "images/story1-opt.png",
    title: "The Self-Proclaimed Pro",
    juice: "He talks like an esports legend. The scoreboard usually tells a different story.",
    ph: 'STORY 01 · ROAST · ANIME — hoodie mockup · Anime print of "The Self-Proclaimed Pro"',
  },
  {
    id: 4, d: 2, type: "roast", style: "Anime",
    src: "images/story4-opt.png",
    title: "Energy Conservation Expert",
    juice: "He doesn't waste energy on anything. Even his blinking feels optional.",
    ph: 'STORY 04 · ROAST · ANIME — hoodie mockup · Anime print of "Energy Conservation Expert"',
  },
  // ── Column 2 ──
  {
    id: 2, d: 3, type: "toast", style: "Anime",
    src: "images/story2-opt.png",
    title: "The Heart of This Family",
    juice: "The kids call her Mom. I call her the reason this whole thing works.",
    ph: 'STORY 02 · TOAST · ANIME — hoodie mockup · Anime print of "The Heart of This Family"',
  },
  {
    id: 5, d: 1, type: "toast", style: "Pixar",
    src: "images/story5-opt.png",
    title: "The Innocent Face",
    juice: "The house is a disaster. He has absolutely no idea how that happened.",
    ph: 'STORY 05 · TOAST · PIXAR — hoodie mockup · Pixar print of "The Innocent Face"',
  },
  // ── Column 3 ──
  {
    id: 3, d: 2, type: "roast", style: "Cartoon",
    src: "images/story3-opt.png",
    title: "Social Subtitles Required",
    juice: "He misses every hint. It’s like he needs subtitles for real life.",
    ph: 'STORY 03 · ROAST · CARTOON — hoodie mockup · Cartoon print of "Social Subtitles Required"',
  },
  {
    id: 6, d: 3, type: "roast", style: "Pixar",
    src: "images/story6-opt.png",
    title: "The Blanket Thief",
    juice: "Claims they're cold. Wakes up wrapped in 95% of the blanket.",
    ph: 'STORY 06 · ROAST · PIXAR — hoodie mockup · Pixar print of "The Blanket Thief"',
  },
];

function StoryCard({ s }) {
  const idx = String(s.id).padStart(2, "0");
  return (
    <article className="story reveal" data-d={s.d}>
      <div className="story-media">
        <image-slot
          id={"rt-story-" + s.id}
          fit="cover"
          src={s.src || ""}
          placeholder={s.ph}
        ></image-slot>
        <div className="story-tags">
          <span className={"badge badge-" + s.type}>
            <span className="dot"></span>
            {s.type}
          </span>
          <span className="chip">{s.style}</span>
        </div>
      </div>
      <div className="story-body">
        <span className="story-idx">{idx} / 06</span>
        <h3>{s.title}</h3>
        <p className="juice">{s.juice}</p>
        <div className="story-foot">
          <span className="style-line">{s.style.toUpperCase()}</span>
          <span>&middot;</span>
          <span>A {s.type.toUpperCase()}</span>
        </div>
      </div>
    </article>
  );
}

function StoryGallery() {
  return (
    <section className="section section--tight gallery">
      <div className="shell">
        <div className="masonry">
          {STORIES.map(s => <StoryCard key={s.id} s={s} />)}
        </div>
      </div>
    </section>
  );
}

/* =========================================================================
   CLOSING CTA (dark band)
   ========================================================================= */
function StoriesCta() {
  return (
    <section className="section stories-cta dark">
      <div className="shell">
        <div className="sec-head sec-head--center reveal">
          <span className="idx">Your turn</span>
          <p className="eyebrow accent">Early access &middot; Beta</p>
        </div>
        <h2 className="display reveal" data-d="1">
          Now make the one<br /><em>only you</em> would get.
        </h2>
        <p className="body-lg reveal" data-d="2">
          Answer a few prompts, let the AI design it, and preview it on the hoodie before you commit.
        </p>
        <div className="cta-row reveal" data-d="2">
          <a className="btn" href="https://roastandtoast.softr.app">
            Create My Hoodie <span className="arrow">&rarr;</span>
          </a>
          <a className="link-arrow" href="index.html#how">
            See how it works <span className="arrow">&rarr;</span>
          </a>
        </div>
        <p className="cta-note reveal" data-d="3">
          Free to design &middot; pay only when you love it &middot; generation takes up to ~90 seconds
        </p>
      </div>
    </section>
  );
}

/* =========================================================================
   FOOTER  (identical to landing page)
   ========================================================================= */
function Footer() {
  const [email, setEmail] = useState("");
  const [done, setDone] = useState(false);
  const submit = (e) => {
    e.preventDefault();
    if (/^[^@\s]+@[^@\s]+\.[^@\s]+$/.test(email)) setDone(true);
  };
  return (
    <footer className="footer">
      <div className="shell">
        <div className="footer-top">
          <div>
            <h3 className="reveal">Not ready yet? Get on the early list.</h3>
            <form className={"news reveal" + (done ? " ok" : "")} data-d="1" onSubmit={submit}>
              <input
                type="email"
                value={email}
                disabled={done}
                onChange={e => setEmail(e.target.value)}
                placeholder={done ? "You're on the list." : "Email address"}
              />
              <button type="submit" aria-label="Subscribe">&rarr;</button>
            </form>
            <p className="news-msg">
              {done ? "You're in — we'll send you the good stuff, never spam." : ""}
            </p>
          </div>
          <div className="footer-cols reveal" data-d="2">
            <div className="footer-col">
              <h5>Product</h5>
              <a href="index.html#how">How it works</a>
              <a href="index.html#craft">The craft</a>
              <a href="Stories.html">Stories</a>
            </div>
            <div className="footer-col">
              <h5>Connect</h5>
              <a href="#">Instagram</a>
              <a href="#">TikTok</a>
              <a href="#">Contact</a>
            </div>
          </div>
        </div>
        <div className="footer-bottom">
          <span className="wordmark" style={{ color: "var(--bone)" }}>
            Roast<span className="amp">&amp;</span>Toast
          </span>
          <span>&copy; 2026 &middot; Early access &middot; Made to order</span>
        </div>
      </div>
    </footer>
  );
}

/* =========================================================================
   FLOATING CTA
   ========================================================================= */
function FloatingCta() {
  const [visible, setVisible] = useState(false);

  useEffect(() => {
    const onScroll = () => setVisible(window.scrollY > 300);
    window.addEventListener("scroll", onScroll, { passive: true });
    onScroll();
    return () => window.removeEventListener("scroll", onScroll);
  }, []);

  return (
    <a
      className={"floating-cta btn" + (visible ? " floating-cta--visible" : "")}
      href="https://roastandtoast.softr.app"
      aria-label="Create My Hoodie"
    >
      Create My Hoodie <span className="arrow">&rarr;</span>
    </a>
  );
}

/* =========================================================================
   APP
   ========================================================================= */
const TWEAK_DEFAULTS = { headline: "didone", accent: "#c4622d", density: "airy" };
const DENSITY = {
  compact: "clamp(4.5rem,9vh,8rem)",
  regular: "clamp(6rem,12vh,11rem)",
  airy:    "clamp(7rem,14vh,13rem)",
};

function StoriesApp() {
  const [t, setTweak] = useTweaks(TWEAK_DEFAULTS);

  useEffect(() => {
    const r = document.documentElement;
    r.dataset.headline = t.headline;
    r.style.setProperty("--ember", t.accent);
    r.style.setProperty("--section-y", DENSITY[t.density] || DENSITY.airy);
  }, [t.headline, t.accent, t.density]);

  useEffect(() => {
    const items = Array.from(document.querySelectorAll(".reveal, .line-mask"));
    const reveal = el => el.classList.add("in");
    const checkInView = () => {
      const vh = window.innerHeight || document.documentElement.clientHeight;
      for (const el of items) {
        if (el.classList.contains("in")) continue;
        const r = el.getBoundingClientRect();
        if (r.top < vh * 0.92 && r.bottom > 0) reveal(el);
      }
    };

    checkInView();

    let io = null;
    if ("IntersectionObserver" in window) {
      io = new IntersectionObserver(entries => {
        entries.forEach(e => { if (e.isIntersecting) { reveal(e.target); io.unobserve(e.target); } });
      }, { threshold: 0.12, rootMargin: "0px 0px -8% 0px" });
      items.forEach(el => { if (!el.classList.contains("in")) io.observe(el); });
    }

    const onScroll = () => {
      checkInView();
      const nav = document.getElementById("nav");
      if (nav) nav.classList.toggle("scrolled", window.scrollY > 40);
    };
    onScroll();
    window.addEventListener("scroll", onScroll, { passive: true });
    window.addEventListener("resize", onScroll);

    const failsafe = setTimeout(() => items.forEach(reveal), 1400);

    return () => {
      if (io) io.disconnect();
      window.removeEventListener("scroll", onScroll);
      window.removeEventListener("resize", onScroll);
      clearTimeout(failsafe);
    };
  }, []);

  return (
    <React.Fragment>
      <Nav />
      <main>
        <StoriesHero />
        <StoryGallery />
        <StoriesCta />
      </main>
      <Footer />
      <FloatingCta />
      <TweaksPanel title="Tweaks">
        <TweakSection label="Typography" />
        <TweakSelect label="Headline" value={t.headline}
          options={[
            { value: "didone",       label: "Editorial Didone" },
            { value: "transitional", label: "Literary serif" },
            { value: "grotesque",    label: "Grotesque caps" },
          ]}
          onChange={v => setTweak("headline", v)} />
        <TweakSection label="Color" />
        <TweakColor label="Accent" value={t.accent}
          options={["#c4622d", "#a84b2a", "#c0892f", "#5a4632"]}
          onChange={v => setTweak("accent", v)} />
        <TweakSection label="Rhythm" />
        <TweakRadio label="Spacing" value={t.density}
          options={["compact", "regular", "airy"]}
          onChange={v => setTweak("density", v)} />
      </TweaksPanel>
    </React.Fragment>
  );
}

ReactDOM.createRoot(document.getElementById("root")).render(<StoriesApp />);
