// Landing page

const Hero = ({ onNav }) => {
  return (
  <section className="hero hero-v2">
    <div className="hero-main" style={{ position: "relative", zIndex: 1 }}>
      <span className="pill green">● Now tracking 47 peptides</span>
      <h1>
        Understand the peptide<br />
        before you <em>open the vial.</em>
      </h1>
      <p className="lede">
        PeptidePal is a friendly home for the peptide-curious. Plain-English briefings on what each molecule actually does, your own dashboard for stacks and labs, and Splat — a little green blob of peer-reviewed enthusiasm — whenever you have a question.
      </p>
      <div className="hero-cta">
        <button className="btn primary" onClick={() => onNav("dashboard")}>Open my dashboard →</button>
        <button className="btn" onClick={() => onNav("index")}>Browse peptides</button>
        <span className="mono" style={{ color: "var(--muted)", marginLeft: 8 }}>no account needed to read</span>
      </div>
      <div className="hero-stats">
        <div><div className="hero-stat-n">47</div><div className="hero-stat-l">peptide files</div></div>
        <div><div className="hero-stat-n">2,114</div><div className="hero-stat-l">papers in splat's brain</div></div>
        <div><div className="hero-stat-n">180+</div><div className="hero-stat-l">biomarkers tracked</div></div>
      </div>
    </div>

    <aside className="hero-scene" style={{ zIndex: 1 }}>
      {/* Soft green circular halo behind everything */}
      <div className="hero-halo" />

      {/* Main dashboard peek card */}
      <div className="hero-dash-card">
        <div className="hdc-header">
          <div className="hdc-window-dots">
            <span /><span /><span />
          </div>
          <div className="hdc-title">peptidepal.app / dashboard</div>
          <div className="hdc-live">● live</div>
        </div>

        <div className="hdc-greeting">
          <div className="hdc-caps">Wed · Apr 17 · week 6</div>
          <div className="hdc-hi">Welcome Back.</div>
        </div>

        <div className="hdc-stack-row">
          <div className="hdc-chip" style={{background:"var(--splat)"}}>R</div>
          <div className="hdc-stack-body">
            <div className="hdc-stack-nm">Retatrutide</div>
            <div className="hdc-stack-sub">4mg · Sun 8am</div>
          </div>
          <div className="hdc-tick">✓</div>
        </div>
        <div className="hdc-stack-row">
          <div className="hdc-chip" style={{background:"var(--sky)"}}>B</div>
          <div className="hdc-stack-body">
            <div className="hdc-stack-nm">BPC-157</div>
            <div className="hdc-stack-sub">250µg · daily</div>
          </div>
          <div className="hdc-tick empty" />
        </div>

        <div className="hdc-metrics">
          <div className="hdc-metric">
            <div className="hdc-m-lbl">HRV</div>
            <div className="hdc-m-val">62<span>ms</span></div>
            <svg viewBox="0 0 80 18" preserveAspectRatio="none">
              <polyline fill="none" stroke="var(--sky)" strokeWidth="1.6" strokeLinejoin="round"
                points="0,13 12,11 24,14 36,8 48,10 60,6 72,8 80,3" />
            </svg>
          </div>
          <div className="hdc-metric">
            <div className="hdc-m-lbl">Weight</div>
            <div className="hdc-m-val">184<span>lb</span></div>
            <svg viewBox="0 0 80 18" preserveAspectRatio="none">
              <polyline fill="none" stroke="var(--splat-deep)" strokeWidth="1.6" strokeLinejoin="round"
                points="0,3 14,5 28,4 42,8 56,10 70,13 80,15" />
            </svg>
          </div>
        </div>
      </div>

      {/* Tiny waving Splat, peeking from corner */}
      <div className="hero-splat-peek">
        <div className="splat-floating"><Splat size={72} expression="wink" /></div>
        <div className="hero-splat-caption">hi! — splat</div>
      </div>
    </aside>
  </section>
  );
};

const Marquee = () => {
  const items = [
    "RETATRUTIDE", "GHK-CU", "MELANOTAN-2", "MOTS-C", "TESAMORELIN",
    "BPC-157", "IPAMORELIN", "SEMAX", "SELANK", "CJC-1295", "TB-500", "THYMOSIN-β4",
  ];
  const set = items.map((x, i) => (
    <span key={i}>{x}<span className="dot" /></span>
  ));
  return (
    <div className="marquee">
      <div className="marquee-track">{set}{set}</div>
    </div>
  );
};

const PeptideIndex = ({ onSelect, onNav }) => (
  <section className="section">
    <div className="section-head">
      <div>
        <span className="caps" style={{ color: "var(--muted)" }}>The Index — 05 of 47</span>
        <h2>A reading list of the molecules you keep seeing online.</h2>
      </div>
      <button className="btn">View all peptides</button>
    </div>

    <div className="peptide-grid">
      {PEPTIDES.map((p, i) => (
        <div key={p.id} className="peptide-card" onClick={() => onSelect(p)}>
          <div className="thumb" style={{ position: "relative" }}>
            <PeptideArt id={p.id} />
            <span className="molecule-chip">{p.molecule}</span>
          </div>
          <div className="body">
            <span className="caps" style={{ color: "var(--muted)" }}>{p.tag}</span>
            <h3>{p.name}</h3>
            <p className="sub">{p.tagline}</p>
            <div className="meta-row">
              <span>t½ {p.halfLife}</span>
              <span>{p.timing}</span>
              <span>{p.route.split(" ")[0]}</span>
            </div>
          </div>
        </div>
      ))}

      {/* Splat "need help" card in 6th slot */}
      <div
        className="peptide-card"
        style={{ background: "var(--splat-soft)", borderColor: "var(--splat-deep)", cursor: "pointer" }}
        onClick={() => onNav && onNav("dashboard")}
        role="button"
        tabIndex={0}
        onKeyDown={(e) => { if ((e.key === "Enter" || e.key === " ") && onNav) { e.preventDefault(); onNav("dashboard"); } }}
      >
        <div style={{ aspectRatio: "16/11", borderBottom: "1.5px solid var(--ink)", display: "grid", placeItems: "center", background: "var(--splat-glow)", position: "relative" }}>
          <Splat size={150} expression="thinking" />
        </div>
        <div className="body">
          <span className="caps" style={{ color: "var(--splat-deep)" }}>Ask Splat</span>
          <h3>Not sure where to start?</h3>
          <p className="sub">Tell me your goal in one sentence and I'll point to 3 molecules worth reading about.</p>
          <div className="meta-row" style={{ borderColor: "var(--splat-deep)" }}>
            <span style={{ color: "var(--splat-deep)" }}>open dashboard →</span>
            <span style={{ color: "var(--splat-deep)" }}>→</span>
          </div>
        </div>
      </div>
    </div>
  </section>
);

const LANDING_ARTICLE_ART = {
  titration: (typeof Chart_Titration !== "undefined") ? Chart_Titration : null,
  amino: (typeof Chart_AminoChain !== "undefined") ? Chart_AminoChain : null,
  routine: (typeof Chart_Routine !== "undefined") ? Chart_Routine : null,
  mitoflex: (typeof Chart_MitoFlex !== "undefined") ? Chart_MitoFlex : null,
  thermometer: (typeof Chart_Thermometer !== "undefined") ? Chart_Thermometer : null,
  faq: (typeof Chart_FAQ !== "undefined") ? Chart_FAQ : null,
  receptor: (typeof Chart_Receptor !== "undefined") ? Chart_Receptor : null,
  halflife: (typeof Chart_HalfLife !== "undefined") ? Chart_HalfLife : null,
  stacks: (typeof Chart_Stacks !== "undefined") ? Chart_Stacks : null,
  bruise: (typeof Chart_Bruise !== "undefined") ? Chart_Bruise : null,
  subq: (typeof Chart_SubQ !== "undefined") ? Chart_SubQ : null,
  skinproto: (typeof Chart_SkinProto !== "undefined") ? Chart_SkinProto : null,
  qa: (typeof Chart_QA !== "undefined") ? Chart_QA : null,
  sites: (typeof Chart_Sites !== "undefined") ? Chart_Sites : null,
};

const Articles = ({ onNav }) => (
  <section className="section" style={{ paddingTop: 24 }}>
    <div className="section-head">
      <div>
        <span className="caps" style={{ color: "var(--muted)" }}>Learn — Splat's Weekly Reader</span>
        <h2>Long enough to be useful. Short enough to actually finish.</h2>
      </div>
      <button className="btn" onClick={() => onNav && onNav("learn")}>All articles →</button>
    </div>

    <div className="articles-grid">
      {ARTICLES.slice(0, 6).map((a, i) => {
        const Art = LANDING_ARTICLE_ART[a.art];
        return (
        <article key={a.id} className={`article ${a.size}`} onClick={() => onNav && onNav("learn")} style={{ cursor: "pointer" }}>
          <div className="thumb" style={{ position: "relative" }}>
            {Art ? <Art /> : <div className={`stripe-placeholder ${a.tint}`} style={{height:"100%"}}><span>fig. {String(i + 1).padStart(2, "0")}</span></div>}
          </div>
          <div className="body">
            <span className="caps" style={{ color: "var(--muted)" }}>{a.tag} · {a.readTime}</span>
            <h3>{a.title}</h3>
            <p>{a.excerpt}</p>
          </div>
        </article>
        );
      })}
    </div>
  </section>
);

const FeatureRow = ({ onNav }) => (
  <section className="feature-row">
    <div className="section" style={{ paddingTop: 0, paddingBottom: 0, maxWidth: 1280 }}>
      <div style={{ display: "flex", justifyContent: "space-between", alignItems: "flex-end", gap: 24 }}>
        <div>
          <span className="caps" style={{ color: "var(--splat-glow)" }}>The Dashboard</span>
          <h2 style={{ fontFamily: "var(--serif)", fontWeight: 400, fontSize: 56, lineHeight: 1, margin: "8px 0 0", color: "white", maxWidth: 720, letterSpacing: "-0.02em" }}>
            One home for your stack, your <em style={{ color: "var(--splat-glow)" }}>numbers</em>, and your little green friend.
          </h2>
        </div>
        <button className="btn primary" onClick={() => onNav("dashboard")}>See the dashboard →</button>
      </div>

      <div className="feature-grid">
        <div className="feature-card">
          <div className="splat-corner"><Splat size={100} expression="reading" /></div>
          <span className="caps" style={{ color: "var(--splat-glow)" }}>01 · Biomarkers</span>
          <h3>Your labs, turned into a Sunday newspaper.</h3>
          <p>Upload a PDF and Splat rewrites every acronym into plain English. Then he draws the trend line.</p>
          <button className="btn primary">Try with a sample lab</button>
        </div>
        <div className="feature-card">
          <div className="splat-corner"><Splat size={100} expression="thinking" /></div>
          <span className="caps" style={{ color: "var(--splat-glow)" }}>02 · Cycle Timeline</span>
          <h3>See your whole protocol on a single horizon.</h3>
          <p>Stack, taper, pause, wash. Your calendar knows you're on Retatrutide; Splat tells you why week 6 matters.</p>
          <button className="btn primary">Plan a cycle</button>
        </div>
        <div className="feature-card">
          <div className="splat-corner"><Splat size={100} expression="wink" /></div>
          <span className="caps" style={{ color: "var(--splat-glow)" }}>03 · Splat Tips</span>
          <h3>A floating friend, nudging at the right moment.</h3>
          <p>"Nice HRV bump. Want to peek at last cycle?" He reads the room before he speaks.</p>
          <button className="btn primary">Say hi to Splat</button>
        </div>
      </div>
    </div>
  </section>
);

const Footer = () => (
  <footer className="footer">
    <div className="footer-inner">
      <div>
        <div className="big-logo">PeptidePal.</div>
        <p style={{ color: "var(--muted)", maxWidth: 320, margin: 0 }}>
          A friendly corner of the internet for people who want to understand what's in the vial before they open it.
        </p>
      </div>
      <div>
        <h4>Explore</h4>
        <ul><li>Peptide Index</li><li>The Weekly Reader</li><li>Splat's Notebook</li><li>Glossary</li></ul>
      </div>
      <div>
        <h4>Your pal</h4>
        <ul><li>Dashboard</li><li>Stack builder</li><li>Lab uploads</li><li>Supply tracker</li></ul>
      </div>
      <div>
        <h4>Splat</h4>
        <ul><li>Meet Splat</li><li>What he reads</li><li>How he thinks</li><li>Send fan mail</li></ul>
      </div>
    </div>
    <p className="disclaimer">
      ※ PeptidePal is for educational and informational purposes only and is not medical advice. Many peptides mentioned are investigational and not FDA-approved. Consult a licensed healthcare provider before making decisions about your health. © 2026 PeptidePal Co. &nbsp;·&nbsp; Splat is a cartoon character. He is not a doctor. He is a blob.
    </p>
  </footer>
);

const Landing = ({ onNav, onSelectPeptide }) => (
  <div>
    <Hero onNav={onNav} />
    <Marquee />
    <PeptideIndex onSelect={onSelectPeptide} onNav={onNav} />
    <Articles onNav={onNav} />
    <FeatureRow onNav={onNav} />
    <Footer />
  </div>
);

// ===== Peptide Index page =====

const FAMILIES = [
  { k: "all",             label: "All peptides" },
  { k: "Metabolic",       label: "Metabolic" },
  { k: "GH axis",         label: "GH axis" },
  { k: "Mitochondrial",   label: "Mitochondrial" },
  { k: "Cognitive",       label: "Cognitive" },
  { k: "Healing",         label: "Healing" },
  { k: "Skin · Recovery", label: "Skin & Recovery" },
  { k: "Longevity",       label: "Longevity" },
  { k: "Sleep",           label: "Sleep" },
  { k: "Wellness",        label: "Wellness" },
  { k: "Immune",          label: "Immune" },
  { k: "Antimicrobial",   label: "Antimicrobial" },
  { k: "Pigment · Novel", label: "Pigment & Novel" },
];

const GOAL_CHIPS = ["better sleep", "fat loss", "skin & hair", "recovery", "cognition", "longevity"];

// Popularity rank (hand-tuned — most-searched/written-about peptides first)
const POPULARITY_RANK = [
  "sema", "tirz", "reta", "bpc157", "tb500", "ipamorelin", "cjc1295",
  "ghkcu", "motsc", "tesa", "pt141", "mt2", "epithalon", "selank",
  "semax", "dsip", "aod9604", "dihexa", "ss31", "humanin", "kisspeptin",
  "tymalpha", "ll37",
];

// Newest-first (most recently added to the library)
const NEWEST_ORDER = [
  "reta", "tirz", "sema", "ss31", "humanin", "dihexa", "kisspeptin",
  "ll37", "tymalpha", "pt141", "aod9604", "epithalon", "dsip", "semax",
  "selank", "cjc1295", "ipamorelin", "tb500", "bpc157", "tesa", "motsc",
  "mt2", "ghkcu",
];

const rankIndex = (arr, id) => {
  const i = arr.indexOf(id);
  return i === -1 ? 9999 : i;
};

const IndexPage = ({ onSelect, onNav }) => {
  const [family, setFamily] = React.useState("all");
  const [q, setQ] = React.useState("");
  const [sort, setSort] = React.useState(null); // null | az | popular | newest
  const toggleSort = (k) => setSort(s => s === k ? null : k);
  const filtered = PEPTIDES.filter(p => {
    if (family !== "all" && p.tag !== family) return false;
    if (q && !p.name.toLowerCase().includes(q.toLowerCase())) return false;
    return true;
  });
  const shown = !sort ? filtered : filtered.slice().sort((a, b) => {
    if (sort === "az") return a.name.localeCompare(b.name);
    if (sort === "popular") return rankIndex(POPULARITY_RANK, a.id) - rankIndex(POPULARITY_RANK, b.id);
    if (sort === "newest") return rankIndex(NEWEST_ORDER, a.id) - rankIndex(NEWEST_ORDER, b.id);
    return 0;
  });

  // Compute live counts per family from PEPTIDES
  const familyCounts = React.useMemo(() => {
    const c = { all: PEPTIDES.length };
    PEPTIDES.forEach(p => { c[p.tag] = (c[p.tag] || 0) + 1; });
    return c;
  }, []);
  const familiesToShow = FAMILIES.filter(f => f.k === "all" || familyCounts[f.k] > 0);

  return (
    <div>
      <section className="index-hero">
        <div className="index-hero-inner">
          <span className="caps" style={{ color: "var(--muted)" }}>The Index</span>
          <h1 className="index-title">The <em>peptide index.</em></h1>
          <p className="index-sub">Every molecule we've written up — plain-English briefings, mechanism, reported benefits, and what the research actually says (and doesn't).</p>

          <div className="index-searchbar">
            <input
              placeholder="Search: retatrutide, GHK, GLP-1…"
              value={q}
              onChange={(e) => setQ(e.target.value)}
            />
            <button className="btn ink">Search</button>
          </div>

          <div className="index-goals">
            <span className="caps" style={{ color: "var(--muted)", marginRight: 6 }}>or start from a goal →</span>
            {GOAL_CHIPS.map(g => (
              <button key={g} className="goal-chip" onClick={() => setQ(g)}>{g}</button>
            ))}
          </div>
        </div>
      </section>

      <section className="section" style={{ paddingTop: 32 }}>
        <div className="index-layout">
          <aside className="index-side">
            <div className="caps" style={{ color: "var(--muted)", marginBottom: 10 }}>Family</div>
            {familiesToShow.map(f => (
              <div
                key={f.k}
                className={`family-row ${family === f.k ? "active" : ""}`}
                onClick={() => setFamily(f.k)}
              >
                <span>{f.label}</span>
                <span className="family-count">{familyCounts[f.k] || 0}</span>
              </div>
            ))}
          </aside>

          <div>
            <div className="index-toolbar">
              <div className="mono" style={{ color: "var(--muted)" }}>
                Showing {shown.length} of {PEPTIDES.length}
                {family !== "all" && ` · ${family}`}
                {q && ` · "${q}"`}
              </div>
              <div className="index-sort">
                <span className="caps" style={{ color: "var(--muted)" }}>sort</span>
                <button className={`sort-btn ${sort === "az" ? "active" : ""}`} onClick={() => toggleSort("az")}>A → Z</button>
                <button className={`sort-btn ${sort === "popular" ? "active" : ""}`} onClick={() => toggleSort("popular")}>Popularity</button>
                <button className={`sort-btn ${sort === "newest" ? "active" : ""}`} onClick={() => toggleSort("newest")}>Newest</button>
              </div>
            </div>

            <div className="peptide-grid">
              {shown.map((p, i) => (
                <div key={p.id} className="peptide-card" onClick={() => onSelect(p)}>
                  <div className="thumb" style={{ position: "relative" }}>
                    <PeptideArt id={p.id} />
                    <span className="molecule-chip">{p.molecule}</span>
                  </div>
                  <div className="body">
                    <span className="caps" style={{ color: "var(--muted)" }}>{p.tag}</span>
                    <h3>{p.name}</h3>
                    <p className="sub">{p.tagline}</p>
                    <div className="meta-row">
                      <span>t½ {p.halfLife}</span>
                      <span>{p.timing}</span>
                      <span>{p.route.split(" ")[0]}</span>
                    </div>
                  </div>
                </div>
              ))}

              {shown.length === 0 && (
                <div className="empty-state">
                  <Splat size={120} expression="thinking" />
                  <h3>Hmm, nothing matches that yet.</h3>
                  <p>Try a different keyword, or poke Splat — he'll improvise.</p>
                </div>
              )}

              <div className="peptide-card splat-help" onClick={() => onNav("dashboard")}>
                <div style={{ aspectRatio: "16/11", borderBottom: "1.5px solid var(--ink)", display: "grid", placeItems: "center", background: "var(--splat-glow)" }}>
                  <Splat size={140} expression="thinking" />
                </div>
                <div className="body">
                  <span className="caps" style={{ color: "var(--splat-deep)" }}>Ask Splat</span>
                  <h3>Tell me your goal.</h3>
                  <p className="sub">One sentence. I'll point to 3 molecules worth reading about and why.</p>
                  <div className="meta-row" style={{ borderColor: "var(--splat-deep)" }}>
                    <span style={{ color: "var(--splat-deep)" }}>try: "better sleep"</span>
                    <span style={{ color: "var(--splat-deep)" }}>→</span>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </section>

      <Footer />
    </div>
  );
};

// ===== Learn page =====

const LEARN_TOPICS = [
  { k: "basics", label: "The Basics", count: 12 },
  { k: "mechanism", label: "Mechanism Deep-Dives", count: 14 },
  { k: "safety", label: "Safety & Storage", count: 9 },
  { k: "stacks", label: "Stacking Guides", count: 7 },
  { k: "protocols", label: "Sample Protocols", count: 11 },
  { k: "faq", label: "Splat's FAQ", count: 22 },
];

const GLOSSARY = [
  { term: "Half-life", def: "The time it takes for half the peptide in your system to be eliminated. Short = more frequent dosing." },
  { term: "GLP-1", def: "Glucagon-like peptide-1. A gut hormone that modulates insulin release and appetite." },
  { term: "Titration", def: "The act of slowly ramping up a dose to find a therapeutic window while minimizing side effects." },
  { term: "Lyophilized", def: "Freeze-dried. How most research peptides ship. Needs reconstitution before use." },
  { term: "Bioavailability", def: "The fraction of a dose that actually reaches systemic circulation." },
  { term: "Agonist", def: "A molecule that binds to a receptor and activates it. Opposite of an antagonist." },
  { term: "Peptide", def: "A short chain of amino acids — generally under ~50 residues — linked by peptide bonds." },
  { term: "Protein", def: "A long amino acid chain that folds into a functional 3D structure. Bigger and more complex than a peptide." },
  { term: "Receptor", def: "A protein on or inside a cell that recognizes a specific ligand and triggers a signal when engaged." },
  { term: "Antagonist", def: "A molecule that occupies a receptor without activating it, blocking the natural ligand from binding." },
  { term: "Reconstitution", def: "The act of adding bacteriostatic water to a lyophilized peptide so it becomes an injectable solution." },
  { term: "Subcutaneous (SubQ)", def: "An injection delivered just under the skin into the fat layer — shallow, slow absorption." },
  { term: "Intramuscular (IM)", def: "An injection delivered deeper, into muscle tissue — faster absorption, sharper peak." },
  { term: "IGF-1", def: "Insulin-like Growth Factor 1. The downstream hormone GH prompts the liver to release; a real-world readout of GH activity." },
  { term: "GHRH", def: "Growth Hormone-Releasing Hormone. The hypothalamic signal that tells the pituitary to pulse GH." },
  { term: "Ghrelin", def: "A hunger hormone from the stomach. Also a secretagogue for GH — ghrelin mimetics trigger GH pulses." },
  { term: "Incretin", def: "A gut hormone that boosts insulin secretion in response to a meal. GLP-1 and GIP are the major incretins." },
  { term: "Pharmacokinetics", def: "The study of what the body does to a drug: absorption, distribution, metabolism, and excretion (ADME)." },
  { term: "Steady state", def: "The predictable plateau concentration reached after roughly 5 half-lives of consistent dosing." },
  { term: "Loading dose", def: "A higher initial dose used to reach therapeutic levels faster than regular dosing would allow." },
  { term: "Peptide bond", def: "The covalent amide bond between the carboxyl of one amino acid and the amino of the next." },
  { term: "Cyclic peptide", def: "A peptide whose ends are joined into a ring. Often more stable against enzymatic degradation." },
  { term: "Pegylation", def: "Attaching polyethylene glycol (PEG) chains to a peptide to extend half-life and reduce immune clearance." },
  { term: "Analog", def: "A molecule structurally similar to a natural peptide, engineered for improved stability, selectivity, or potency." },
  { term: "IU", def: "International Unit — a unit of biological activity, not mass. Used for peptides like HGH where activity is standardized." },
  { term: "mcg / mg", def: "Micrograms (µg) and milligrams. 1,000 mcg = 1 mg. 1,000 mg = 1 g. Peptide doses live across all three scales." },
];

// Art map for article illustrations
const ARTICLE_ART = {
  titration: Chart_Titration,
  amino: Chart_AminoChain,
  routine: Chart_Routine,
  mitoflex: Chart_MitoFlex,
  thermometer: Chart_Thermometer,
  faq: Chart_FAQ,
  receptor: Chart_Receptor,
  halflife: Chart_HalfLife,
  stacks: Chart_Stacks,
  bruise: Chart_Bruise,
  subq: Chart_SubQ,
  skinproto: Chart_SkinProto,
  qa: Chart_QA,
  sites: Chart_Sites,
};

const topicLabel = (k) => {
  const t = LEARN_TOPICS.find(x => x.k === k);
  return t ? t.label : k;
};

// Full-page article view
const ArticlePage = ({ article, onNav, onBack }) => {
  if (!article) return null;
  const Art = ARTICLE_ART[article.art] || Chart_AminoChain;
  const [copied, setCopied] = React.useState(false);
  const [saved, setSaved] = React.useState(false);

  React.useEffect(() => {
    window.scrollTo({ top: 0, behavior: "instant" });
  }, [article.id]);

  const handleCopy = () => {
    try {
      const url = `${location.origin}${location.pathname}#learn/${article.id}`;
      navigator.clipboard && navigator.clipboard.writeText(url);
    } catch (e) { /* no-op */ }
    setCopied(true);
    setTimeout(() => setCopied(false), 1500);
  };

  const handleShare = () => {
    try {
      if (navigator.share) {
        navigator.share({ title: article.title, text: article.excerpt });
      } else {
        handleCopy();
      }
    } catch (e) { /* no-op */ }
  };

  const related = ARTICLES
    .filter(a => a.id !== article.id && a.topic === article.topic)
    .slice(0, 3);

  return (
    <div style={{ background: "var(--cream)", minHeight: "100vh" }}>
      <div style={{ maxWidth: 820, margin: "0 auto", padding: "28px 28px 80px" }}>
        <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: 24 }}>
          <button className="btn" onClick={onBack}>← Back to Learn</button>
          <span className="caps" style={{ color: "var(--muted)" }}>Article</span>
        </div>

        <div style={{
          position: "relative",
          aspectRatio: "4 / 3",
          maxHeight: "60vh",
          width: "100%",
          background: "var(--cream-2)",
          border: "1.5px solid var(--ink)",
          borderRadius: 16,
          overflow: "hidden",
          marginBottom: 24,
        }}>
          <div style={{ position: "absolute", inset: 0 }}>
            <Art />
          </div>
          <span style={{ position: "absolute", top: 14, right: 14, zIndex: 2 }}>
            <Splat size={72} expression="reading" />
          </span>
        </div>

        <div style={{ display: "flex", gap: 8, alignItems: "center", flexWrap: "wrap", marginBottom: 10 }}>
          <span className="pill green">{article.tag}</span>
          <span className="caps" style={{ color: "var(--muted)" }}>{article.readTime}</span>
          <span className="caps" style={{ color: "var(--muted)" }}>· updated {article.updated}</span>
        </div>

        <h1 style={{
          fontFamily: "var(--serif)",
          fontWeight: 400,
          fontSize: 56,
          lineHeight: 1.04,
          letterSpacing: "-0.02em",
          margin: "6px 0 12px",
        }}>
          {article.title}
        </h1>
        <p style={{ fontSize: 20, lineHeight: 1.45, color: "var(--ink-2)", marginBottom: 24 }}>
          {article.excerpt}
        </p>

        <div style={{
          display: "flex", gap: 12, alignItems: "center",
          padding: "12px 14px", marginBottom: 28,
          border: "1px solid var(--line)", borderRadius: 12, background: "var(--paper)",
        }}>
          <SplatBadge size={44} expression="wink" />
          <div style={{ display: "flex", flexDirection: "column" }}>
            <div className="mono" style={{ fontSize: 11, color: "var(--splat-deep)", textTransform: "uppercase", letterSpacing: "0.1em" }}>
              By Splat
            </div>
            <div style={{ fontSize: 13, color: "var(--muted)" }}>
              Filed under {topicLabel(article.topic)}
            </div>
          </div>
        </div>

        <div style={{ fontSize: 17, lineHeight: 1.72, color: "var(--ink-2)" }}>
          {(article.body || []).map((para, i) => (
            <p key={i} style={{ margin: "0 0 18px" }}>{para}</p>
          ))}
        </div>

        <div style={{ display: "flex", gap: 8, marginTop: 28, flexWrap: "wrap" }}>
          <button className="btn" onClick={() => setSaved(s => !s)}>
            {saved ? "Saved ✓" : "Save to reader"}
          </button>
          <button className="btn" onClick={handleShare}>Share</button>
          <button className="btn" onClick={handleCopy}>
            {copied ? "Copied ✓" : "Copy link"}
          </button>
        </div>

        <h4 style={{ fontFamily: "var(--serif)", fontWeight: 400, fontSize: 26, marginTop: 36 }}>Citations</h4>
        <ol style={{ paddingLeft: 20, color: "var(--ink-2)", fontSize: 14, lineHeight: 1.6 }}>
          {(article.references || []).map((r, i) => (
            <li key={i} style={{ marginBottom: 10 }}>
              {r.author} <em style={{ fontFamily: "var(--serif)", fontStyle: "italic" }}>{r.title}.</em>{" "}
              <span style={{ color: "var(--muted)" }}>{r.journal}. {r.year}.</span>{" "}
              {r.url && (
                <a href={r.url} target="_blank" rel="noopener noreferrer" style={{ color: "var(--splat-deep)", textDecoration: "underline" }}>
                  link →
                </a>
              )}
            </li>
          ))}
        </ol>

        {related.length > 0 && (
          <div style={{ marginTop: 48 }}>
            <h4 style={{ fontFamily: "var(--serif)", fontWeight: 400, fontSize: 26, marginBottom: 16 }}>
              Keep reading
            </h4>
            <div style={{ display: "grid", gridTemplateColumns: "repeat(3, 1fr)", gap: 16 }}>
              {related.map((r) => {
                const RArt = ARTICLE_ART[r.art] || Chart_AminoChain;
                return (
                  <button
                    key={r.id}
                    onClick={() => onNav && onNav("article", r.id)}
                    style={{
                      textAlign: "left",
                      background: "var(--paper)",
                      border: "1.5px solid var(--ink)",
                      borderRadius: 16,
                      padding: 0,
                      cursor: "pointer",
                      overflow: "hidden",
                      boxShadow: "var(--shadow-sticker)",
                    }}
                  >
                    <div style={{ aspectRatio: "4/3", background: "var(--cream-2)", position: "relative" }}>
                      <div style={{ position: "absolute", inset: 0 }}><RArt /></div>
                    </div>
                    <div style={{ padding: 14 }}>
                      <div className="caps" style={{ color: "var(--muted)", fontSize: 10, marginBottom: 6 }}>
                        {r.tag} · {r.readTime}
                      </div>
                      <div style={{ fontFamily: "var(--serif)", fontSize: 18, lineHeight: 1.2, letterSpacing: "-0.01em" }}>
                        {r.title}
                      </div>
                    </div>
                  </button>
                );
              })}
            </div>
          </div>
        )}

        <p style={{ marginTop: 40, fontSize: 11, fontFamily: "var(--mono)", color: "var(--muted)" }}>
          ※ Educational only — not medical advice. Many peptides mentioned are investigational and not FDA-approved. Consult your healthcare provider.
        </p>
      </div>
    </div>
  );
};

const ArticleCard = ({ article, index, onOpen }) => {
  const Art = ARTICLE_ART[article.art];
  return (
    <article
      className={`article ${article.size || "med"}`}
      onClick={() => onOpen(article.id)}
      role="button"
      tabIndex={0}
      onKeyDown={(e) => { if (e.key === "Enter" || e.key === " ") { e.preventDefault(); onOpen(article.id); } }}
    >
      <div className="thumb" style={{ position: "relative" }}>
        {Art ? <Art /> : <div className={`stripe-placeholder ${article.tint || "tinted-green"}`} style={{ height: "100%" }}><span>fig. {String(index + 1).padStart(2, "0")}</span></div>}
      </div>
      <div className="body">
        <span className="caps" style={{ color: "var(--muted)" }}>
          {article.tag} · {article.readTime}{article.updated ? ` · ${article.updated}` : ""}
        </span>
        <h3>{article.title}</h3>
        <p>{article.excerpt}</p>
      </div>
    </article>
  );
};

const LearnPage = ({ onNav, onOpenArticle }) => {
  const [topic, setTopic] = React.useState("basics");
  const [query, setQuery] = React.useState("");
  const [sort, setSort] = React.useState("newest"); // newest | popular | quick
  const [allGlossary, setAllGlossary] = React.useState(false);
  const topicsRef = React.useRef(null);

  // Dynamic counts from ARTICLES
  const topicsWithCount = LEARN_TOPICS.map(t => ({
    ...t,
    count: ARTICLES.filter(a => a.topic === t.k).length,
  }));

  // Filter + sort
  const filtered = React.useMemo(() => {
    const q = query.trim().toLowerCase();
    let list = ARTICLES.filter(a => a.topic === topic);
    if (q) {
      list = list.filter(a =>
        (a.title + " " + a.excerpt + " " + (a.tag || "")).toLowerCase().includes(q)
      );
    }
    if (sort === "quick") {
      list = list.filter(a => {
        const n = parseInt(a.readTime, 10);
        return !isNaN(n) && n < 5;
      });
    }
    // Sorting
    const monthIdx = (s) => {
      const months = ["JAN","FEB","MAR","APR","MAY","JUN","JUL","AUG","SEP","OCT","NOV","DEC"];
      const m = (s || "").match(/([A-Z]{3})\s+(\d+),\s+(\d{4})/);
      if (!m) return 0;
      return parseInt(m[3], 10) * 12 * 31 + months.indexOf(m[1]) * 31 + parseInt(m[2], 10);
    };
    if (sort === "newest") {
      list = [...list].sort((a, b) => monthIdx(b.updated) - monthIdx(a.updated));
    } else if (sort === "popular") {
      // Deterministic pseudo-"popularity" — sort by readTime desc as a proxy
      list = [...list].sort((a, b) => parseInt(b.readTime, 10) - parseInt(a.readTime, 10));
    }
    return list;
  }, [topic, query, sort]);

  const scrollToTopics = () => {
    if (topicsRef.current) {
      topicsRef.current.scrollIntoView({ behavior: "smooth", block: "start" });
    }
  };

  const startBasics = () => {
    setTopic("basics");
    setTimeout(scrollToTopics, 40);
  };

  const glossaryShown = allGlossary ? GLOSSARY : GLOSSARY.slice(0, 6);

  return (
    <div>
      <section className="learn-hero">
        <div className="learn-hero-inner">
          <div className="learn-hero-text">
            <span className="caps" style={{ color: "var(--splat-deep)" }}>Learn — Splat's Weekly Reader</span>
            <h1 className="learn-title">A short, kind, <em>citation-heavy</em> education in peptides.</h1>
            <p className="learn-sub">New pieces every Friday. Long enough to be useful, short enough to finish before your coffee goes cold. No paywall. No scary acronyms without translation.</p>
            <div style={{ display: "flex", gap: 10, flexWrap: "wrap" }}>
              <button className="btn primary" onClick={startBasics}>Start with the basics →</button>
              <button className="btn ghost-on-dark" onClick={() => onNav("index")}>Browse the Index</button>
            </div>
          </div>
          <div className="learn-hero-splat">
            <Splat size={120} expression="reading" />
          </div>
        </div>
      </section>

      <section className="section" style={{ paddingTop: 40 }} ref={topicsRef}>
        {/* Search + sort toolbar */}
        <div style={{
          display: "flex", gap: 12, alignItems: "center", flexWrap: "wrap",
          marginBottom: 18,
        }}>
          <div style={{ position: "relative", flex: "1 1 320px", minWidth: 220 }}>
            <input
              value={query}
              onChange={(e) => setQuery(e.target.value)}
              placeholder="Search articles: bruising, half-life, GLP-1…"
              style={{
                width: "100%",
                padding: "12px 16px",
                border: "1.5px solid var(--ink)",
                borderRadius: 999,
                background: "var(--paper)",
                fontFamily: "var(--mono)",
                fontSize: 13,
                outline: "none",
              }}
            />
          </div>
          <div style={{ display: "flex", gap: 6, alignItems: "center" }}>
            <span className="caps" style={{ color: "var(--muted)" }}>Sort</span>
            <button className={`sort-btn ${sort === "newest" ? "active" : ""}`} onClick={() => setSort("newest")}>Newest</button>
            <button className={`sort-btn ${sort === "popular" ? "active" : ""}`} onClick={() => setSort("popular")}>Most read</button>
            <button className={`sort-btn ${sort === "quick" ? "active" : ""}`} onClick={() => setSort("quick")}>Quick reads</button>
          </div>
        </div>

        <div className="learn-topics">
          {topicsWithCount.map(t => (
            <button
              key={t.k}
              className={`topic-tab ${topic === t.k ? "active" : ""}`}
              onClick={() => setTopic(t.k)}
            >
              {t.label}<span className="topic-count">{t.count}</span>
            </button>
          ))}
        </div>

        <div className="articles-grid" style={{ marginTop: 32 }}>
          {filtered.map((a, i) => (
            <ArticleCard key={a.id} article={a} index={i} onOpen={(id) => onOpenArticle && onOpenArticle(id)} />
          ))}

          {filtered.length === 0 && (
            <div className="empty-state" style={{ gridColumn: "span 12", padding: "40px 20px", textAlign: "center" }}>
              <Splat size={120} expression="thinking" />
              <h3 style={{ fontFamily: "var(--serif)", fontWeight: 400, fontSize: 28, margin: "12px 0 6px" }}>
                Nothing here yet — try another topic
              </h3>
              <p style={{ color: "var(--muted)", margin: 0 }}>
                Splat is still drafting pieces for this section. In the meantime, poke around The Basics.
              </p>
            </div>
          )}
        </div>
      </section>

      <section className="glossary-section">
        <div className="section" style={{ padding: "0 28px" }}>
          <div className="section-head">
            <div>
              <span className="caps" style={{ color: "var(--muted)" }}>Glossary · {GLOSSARY.length} terms worth knowing</span>
              <h2>Words Splat insisted we define before anything else.</h2>
            </div>
            <button className="btn" onClick={() => setAllGlossary(v => !v)}>
              {allGlossary ? "Show featured 6 ←" : "Full glossary →"}
            </button>
          </div>

          <div className="glossary-grid">
            {glossaryShown.map((g, i) => (
              <div key={i} className="glossary-card">
                <div className="glossary-k">{g.term}</div>
                <div className="glossary-v">{g.def}</div>
              </div>
            ))}
          </div>
        </div>
      </section>

      <Footer />

    </div>
  );
};

Object.assign(window, { Landing, IndexPage, LearnPage, ArticlePage });
