/* HomeMagazine, editorial homepage, 10 sections, critic voice first.
   Uses ALBUMS + ESSAYS_FULL data; wires click-throughs via onAlbum / onList. */

const { useState: useHMState, useEffect: useHMEffect, useMemo: useHMMemo } = React;

/* --- Deterministic composite score + 6-dim radar values per album -------- */
function scoreFor(rank) {
  // Smooth descent from 9.8 (rank 1) to 7.9 (rank 100) with tiny perturbation
  const base = 9.8 - (rank - 1) * 0.019;
  const jitter = ((rank * 2654435761) >>> 0) % 1000 / 10000; // 0..0.1
  return Math.max(7.4, Math.min(9.9, +(base - jitter + 0.05).toFixed(1)));
}
function radarFor(rank, genre) {
  // Six dims: songwriting, production, performance, innovation, influence, cohesion
  const seed = (rank * 97 + 31) >>> 0;
  const rand = (n) => (((seed * (n + 13)) >>> 0) % 100) / 100;
  const base = 0.7 + (0.28 * (1 - (rank - 1) / 120));
  const shape = {
    Jazz:    [0.9, 0.85, 1.0, 0.95, 0.9, 0.95],
    Rock:    [0.95, 0.9, 0.9, 0.85, 0.95, 0.85],
    Soul:    [0.95, 0.9, 0.95, 0.85, 0.95, 0.95],
    Folk:    [1.0, 0.8, 0.9, 0.8, 0.85, 0.95],
    "Hip-Hop": [0.95, 0.95, 0.85, 0.95, 0.9, 0.85],
    Pop:     [0.9, 0.95, 0.85, 0.85, 0.85, 0.9],
    Country: [0.95, 0.85, 0.9, 0.75, 0.85, 0.9],
    Electronic: [0.8, 1.0, 0.75, 1.0, 0.85, 0.9],
    Punk:    [0.85, 0.7, 0.9, 0.95, 0.95, 0.85],
    default: [0.9, 0.9, 0.9, 0.9, 0.9, 0.9],
  }[genre] || [0.9, 0.9, 0.9, 0.9, 0.9, 0.9];
  return shape.map((s, i) => Math.max(0.45, Math.min(1, base * s + (rand(i) - 0.5) * 0.12)));
}

/* ========================================================
   HomeMagazine, top-level
   ======================================================== */
function HomeMagazine({ albums, onAlbum, onList }) {
  const featuredSlug = "whats-going-on";
  const featured = albums.find(a => a.slug === featuredSlug) || albums[1];
  const featuredEssay = window.ESSAYS_FULL?.[featuredSlug];

  return (
    <main className="mag">
      <MagMasthead />
      <HeroCover
        album={featured}
        essay={featuredEssay}
        onOpen={() => onAlbum(featured)}
      />
      <LatestTeaser
        album={featured}
        essay={featuredEssay}
        onOpen={() => onAlbum(featured)}
      />
      <RankedGrid albums={albums} onAlbum={onAlbum} />
      <ReadingPaths onAlbum={onAlbum} onList={onList} albums={albums} />
      <FromArchive onAlbum={onAlbum} albums={albums} />
      <PodcastModule album={featured} essay={featuredEssay} />
      <CollectorsDesk />
      <Newsletter />
      <Manifesto />
      <FooterMag onList={onList} />
    </main>
  );
}

/* ---- Masthead --------------------------------------------------------- */
function MagMasthead() {
  const today = new Date("2026-04-20");
  const fmt = today.toLocaleDateString("en-US", { weekday: "long", month: "long", day: "numeric", year: "numeric" });
  return (
    <header className="mag-masthead">
      <div className="mm-date">{fmt} · Issue 47</div>
      <div className="mm-title">
        <span className="mm-stroke">The</span>
        <span className="mm-mark">Lead-In</span>
      </div>
      <div className="mm-tag">Long-form criticism &amp; pressing guides for the hundred greatest albums ever made. One deep dive per week.</div>
    </header>
  );
}

/* ---- 1. Hero cover ---------------------------------------------------- */
function HeroCover({ album, essay, onOpen }) {
  const summary = essay?.tagline ||
    "Motown's golden boy turned the hit factory inside out and made a record about Vietnam, ecology, and his own crumbling faith.";
  return (
    <section className="hero-cover">
      <div className="hc-left">
        <div className="hc-kicker">
          <span className="hc-pulse"><i/></span>
          This week&rsquo;s deep dive
        </div>
        <div className="hc-rank-row">
          <div className="hc-rank">
            <span className="hc-rank-label">Ranked</span>
            <span className="hc-rank-n">№&nbsp;{String(album.rank).padStart(2, "0")}</span>
          </div>
          <div className="hc-meta-stack">
            <span>{album.year}</span>
            <span>{album.genre}</span>
            <span>{album.country}</span>
          </div>
        </div>
        <h1 className="hc-title">{album.title}</h1>
        <div className="hc-artist">{album.artist}</div>
        <p className="hc-summary">
          <span className="hc-quote">“</span>
          {summary}
          <span className="hc-quote hc-quote-r">”</span>
        </p>
        <div className="hc-byline">
          <span>By the editors</span>
          <span className="hc-sep">·</span>
          <span>14-minute read</span>
          <span className="hc-sep">·</span>
          <span>Published April 16, 2026</span>
        </div>
        <button className="hc-cta" onClick={onOpen}>
          Read the full piece
          <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.2"><path d="M5 12h14M13 5l7 7-7 7"/></svg>
        </button>
      </div>

      <div className="hc-right">
        <div className="hc-cover-wrap">
          <div className="hc-vinyl" aria-hidden="true" />
          <div className="hc-cover">
            <Sleeve album={album} size={520} />
          </div>
          <div className="hc-stamp">
            <span className="s1">Issue</span>
            <span className="s2">47</span>
          </div>
        </div>
      </div>
    </section>
  );
}

/* ---- 2. Latest teaser ------------------------------------------------- */
function LatestTeaser({ album, essay, onOpen }) {
  const dek = essay?.essay?.dek ||
    "A concept album disguised as a pop record, smuggled past the industry that tried to kill it at the pressing plant.";
  const opening = essay?.essay?.paragraphs?.[0] ||
    "By the end of 1970, Marvin Gaye had stopped recording. His duet partner Tammi Terrell had died of a brain tumor in March at twenty-four.";
  // Take first 2-3 sentences of opening for teaser
  const teaser = opening.split(/(?<=[.!?])\s+/).slice(0, 3).join(" ");
  return (
    <section className="teaser">
      <div className="t-left">
        <div className="t-kicker">Latest deep dive · An excerpt</div>
        <h2 className="t-dek">{dek}</h2>
      </div>
      <div className="t-right">
        <p className="t-body">
          <span className="dropcap">{teaser.charAt(0)}</span>
          {teaser.slice(1)}
        </p>
        <div className="t-footer">
          <button className="t-more" onClick={onOpen}>
            Continue reading
            <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2"><path d="M5 12h14M13 5l7 7-7 7"/></svg>
          </button>
          <span className="t-read-time">14 min · 3,870 words</span>
        </div>
      </div>
    </section>
  );
}

/* ---- 3. Ranked 100 grid ----------------------------------------------- */
function RankedGrid({ albums, onAlbum }) {
  const [decade, setDecade] = useHMState("all");
  const [genre, setGenre] = useHMState("all");
  const [sort, setSort] = useHMState("rank");

  const decades = ["all", "1950s", "1960s", "1970s", "1980s", "1990s", "2000s", "2010s", "2020s"];
  const genres = useHMMemo(() => ["all", ...Array.from(new Set(albums.map(a => a.genre))).sort()], [albums]);

  const enriched = useHMMemo(() => albums.map(a => ({
    ...a,
    score: scoreFor(a.rank),
    radar: radarFor(a.rank, a.genre),
    decadeStr: (Math.floor(a.year / 10) * 10) + "s",
    hasEssay: !!window.ESSAYS_FULL?.[a.slug],
    readTime: 8 + ((a.rank * 3) % 12),
    collectible: ((a.rank * 7 + a.year) % 97) / 97, // 0..1 proxy
  })), [albums]);

  const filtered = useHMMemo(() => {
    let list = enriched;
    if (decade !== "all") list = list.filter(a => a.decadeStr === decade);
    if (genre !== "all") list = list.filter(a => a.genre === genre);
    const sorts = {
      rank: (a, b) => a.rank - b.rank,
      score: (a, b) => b.score - a.score,
      collectible: (a, b) => b.collectible - a.collectible,
      readtime: (a, b) => a.readTime - b.readTime,
    };
    return [...list].sort(sorts[sort] || sorts.rank);
  }, [enriched, decade, genre, sort]);

  return (
    <section className="ranked">
      <div className="r-head">
        <div>
          <h2>The Ranked 100.</h2>
          <p className="r-sub">The canon as we hear it, with our composite score, the shape of our argument, and every deep dive we&rsquo;ve written so far.</p>
        </div>
        <div className="r-legend">
          <span className="r-dot r-dot-live" /> <span>Deep dive live</span>
          <span className="r-dot r-dot-soon" /> <span>Coming soon</span>
        </div>
      </div>

      <div className="r-filters">
        <div className="rf-group">
          <span className="rf-label">Decade</span>
          <div className="rf-pills">
            {decades.map(d => (
              <button key={d} className={"rf-pill" + (decade === d ? " active" : "")} onClick={() => setDecade(d)}>
                {d === "all" ? "All" : d}
              </button>
            ))}
          </div>
        </div>
        <div className="rf-group">
          <span className="rf-label">Genre</span>
          <select className="rf-select" value={genre} onChange={e => setGenre(e.target.value)}>
            {genres.map(g => <option key={g} value={g}>{g === "all" ? "All genres" : g}</option>)}
          </select>
        </div>
        <div className="rf-group">
          <span className="rf-label">Sort</span>
          <select className="rf-select" value={sort} onChange={e => setSort(e.target.value)}>
            <option value="rank">Our ranking</option>
            <option value="score">Composite score</option>
            <option value="collectible">Most collectible</option>
            <option value="readtime">Reading time</option>
          </select>
        </div>
        <div className="rf-count">
          <b>{filtered.length}</b> album{filtered.length === 1 ? "" : "s"}
        </div>
      </div>

      <div className="r-grid">
        {filtered.map(a => (
          <button key={a.rank} className={"r-tile" + (a.hasEssay ? " live" : " soon")} onClick={() => onAlbum(a)}>
            <div className="rt-rank">{String(a.rank).padStart(3, "0")}</div>
            <div className="rt-cover"><Sleeve album={a} size={220} /></div>
            <div className="rt-body">
              <div className="rt-title">{a.title}</div>
              <div className="rt-artist">{a.artist} · {a.year}</div>
              <div className="rt-score-row">
                <span className="rt-score">{a.score.toFixed(1)}</span>
                <Radar values={a.radar} size={44} />
                <span className={"rt-status " + (a.hasEssay ? "rts-live" : "rts-soon")}>
                  {a.hasEssay ? "Deep dive" : "Soon"}
                </span>
              </div>
            </div>
          </button>
        ))}
      </div>
    </section>
  );
}

/* Radar thumbnail, 6-point SVG hexagon shape */
function Radar({ values, size = 44 }) {
  const cx = size / 2, cy = size / 2, r = size / 2 - 3;
  const pts = values.map((v, i) => {
    const angle = (Math.PI * 2 * i) / 6 - Math.PI / 2;
    const rr = r * Math.max(0.25, v);
    return [cx + rr * Math.cos(angle), cy + rr * Math.sin(angle)];
  });
  const grid = [0.33, 0.66, 1].map(f => {
    const p = [];
    for (let i = 0; i < 6; i++) {
      const a = (Math.PI * 2 * i) / 6 - Math.PI / 2;
      p.push([cx + r * f * Math.cos(a), cy + r * f * Math.sin(a)]);
    }
    return p.map(([x, y]) => x.toFixed(1) + "," + y.toFixed(1)).join(" ");
  });
  const path = pts.map(([x, y]) => x.toFixed(1) + "," + y.toFixed(1)).join(" ");
  return (
    <svg className="rt-radar" width={size} height={size} viewBox={`0 0 ${size} ${size}`} aria-hidden="true">
      {grid.map((g, i) => <polygon key={i} points={g} fill="none" stroke="currentColor" opacity={0.12} />)}
      <polygon points={path} fill="currentColor" fillOpacity="0.82" stroke="currentColor" strokeWidth="1" />
    </svg>
  );
}

/* ---- 4. Reading paths ------------------------------------------------- */
function ReadingPaths({ onAlbum, onList, albums }) {
  const paths = [
    {
      n: "01",
      label: "Start with the one that's live",
      kicker: "The flagship",
      blurb: "What's Going On is our first complete deep dive, twelve sections, the cover read closely, the Hitsville sessions reconstructed, eight pressings rated. Read it before any of the other four hundred pieces we're going to publish this year.",
      count: 1,
      time: "18 min",
      slugs: ["whats-going-on"]
    },
    {
      n: "02",
      label: "On deck for 2026",
      kicker: "Coming soon",
      blurb: "The next four deep dives in production: Kind of Blue, Velvet Underground &amp; Nico, Pet Sounds, and Songs in the Key of Life. Each will get the same treatment as What's Going On.",
      count: 4,
      time: "≈ 60 min when live",
      slugs: ["kind-of-blue", "velvet-underground-nico", "pet-sounds", "songs-in-the-key-of-life"]
    },
    {
      n: "03",
      label: "Rankings we&rsquo;re most likely to lose friends over",
      kicker: "The controversial placements",
      blurb: "Sgt. Pepper at 31. Thriller at 24. Pet Sounds outside the top five. We have the argument ready for each, these will be the third batch of deep dives, after the flagship and its four follow-ups.",
      count: 7,
      time: "Coming late 2026",
      slugs: ["thriller", "sgt-peppers", "ok-computer"]
    }
  ];
  return (
    <section className="paths">
      <div className="r-head">
        <div>
          <h2>Three routes through the list.</h2>
          <p className="r-sub">If you don&rsquo;t have time to read all hundred, read one of these.</p>
        </div>
      </div>
      <div className="p-grid">
        {paths.map(p => (
          <article key={p.n} className="p-card">
            <div className="p-n">{p.n}</div>
            <div className="p-kick">{p.kicker}</div>
            <h3 className="p-label" dangerouslySetInnerHTML={{ __html: p.label }} />
            <p className="p-blurb" dangerouslySetInnerHTML={{ __html: p.blurb }} />
            <div className="p-meta">
              <span><b>{p.count}</b> deep dives</span>
              <span className="p-sep">·</span>
              <span>{p.time}</span>
            </div>
            <button className="p-cta" onClick={onList}>
              Follow this path
              <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2"><path d="M5 12h14M13 5l7 7-7 7"/></svg>
            </button>
          </article>
        ))}
      </div>
    </section>
  );
}

/* ---- 5. From the archive --------------------------------------------- */
function FromArchive({ onAlbum, albums }) {
  const archive = [
    {
      hook: "This week in 1977, Fleetwood Mac finished mixing Rumours in Sausalito.",
      album: albums.find(a => a.slug === "rumours") || albums.find(a => a.title === "Rumours") || albums[10],
      teaser: "Five people in three relationships, all ending, all in the same room, all still singing the harmonies. Our 2024 deep dive on how the worst year of five people&rsquo;s lives produced the best-selling rock record of the decade.",
      date: "Originally published Feb 2024 · 11-min read"
    },
    {
      hook: "Fifty years since punk&rsquo;s first real manifesto landed in a bookstore on Eighth Street.",
      album: albums.find(a => a.title?.toLowerCase() === "horses") || albums[7],
      teaser: "Patti Smith walked into Electric Lady with John Cale producing and a bookful of Rimbaud. We wrote 3,200 words on what she did there in March 1975, and why Television, Blondie, and the Talking Heads followed her through the door.",
      date: "Originally published Mar 2025 · 13-min read"
    },
    {
      hook: "Marvin Gaye's What's Going On just got its full Lead-In dossier.",
      album: albums.find(a => a.slug === "whats-going-on") || albums[1],
      teaser: "Twelve sections, eight pressings rated, the Hitsville room reconstructed scene by scene, and a working pressing guide for anyone who's about to spend $400 on the original 1971 Tamla. Our first deep dive of 2026, and the one we've been working up to for years.",
      date: "Published April 2026 · 18-min read"
    }
  ];
  return (
    <section className="archive">
      <div className="r-head">
        <div>
          <h2>From the archive.</h2>
          <p className="r-sub">Older pieces, back in circulation for a specific reason.</p>
        </div>
      </div>
      <div className="a-grid">
        {archive.map((x, i) => (
          <article key={i} className="a-card" onClick={() => x.album && onAlbum(x.album)}>
            <div className="a-hook">{x.hook}</div>
            <div className="a-meta">
              <div className="a-cover"><Sleeve album={x.album} size={90} /></div>
              <div>
                <div className="a-title">{x.album?.title}</div>
                <div className="a-artist">{x.album?.artist} · №&nbsp;{String(x.album?.rank).padStart(3, "0")}</div>
              </div>
            </div>
            <p className="a-teaser">{x.teaser}</p>
            <div className="a-date">{x.date}</div>
          </article>
        ))}
      </div>
    </section>
  );
}

/* ---- 6. Podcast module ------------------------------------------------ */
function PodcastModule({ album, essay }) {
  const [playing, setPlaying] = useHMState(false);
  const [pos, setPos] = useHMState(0.18);
  const title = "The Marvin Gaye strike";
  const runtime = "47:32";

  useHMEffect(() => {
    if (!playing) return;
    const id = setInterval(() => {
      setPos(p => p + 0.0008 > 1 ? 0 : p + 0.0008);
    }, 100);
    return () => clearInterval(id);
  }, [playing]);

  return (
    <section className="pod">
      <div className="pod-left">
        <div className="pod-eyebrow">
          <span className="pod-live"><i/></span>
          The companion podcast · New every Wednesday
        </div>
        <h2 className="pod-title">{title}.</h2>
        <p className="pod-sub">
          Episode 41 · On <em>{album.title}</em> by {album.artist}. Maya and Dev unpack how a major-label soul star went on strike against his own label, why the bass line on the title track is the most imitated moment in American pop music, and whether the record&rsquo;s politics still land in 2026.
        </p>
        <div className="pod-hosts">
          <Host name="Maya" subtitle="Music historian, ex-NPR" color="#d97757" />
          <Host name="Dev" subtitle="Producer &amp; engineer" color="#2d5d3a" />
        </div>
        <div className="pod-subs">
          <a className="pod-sub-btn pod-sub-apple" href="#">
            <svg width="18" height="18" viewBox="0 0 24 24" fill="currentColor"><path d="M12 3a9 9 0 00-9 9c0 4.8 3.7 8.8 8.5 9v-3.4a5.5 5.5 0 115.5-5.6 6 6 0 01-1.3 3.8l2.4 2.4A9 9 0 0012 3z"/></svg>
            Apple Podcasts
          </a>
          <a className="pod-sub-btn pod-sub-spotify" href="#">
            <svg width="18" height="18" viewBox="0 0 24 24" fill="currentColor"><circle cx="12" cy="12" r="9" fill="currentColor"/><path d="M7 10c3-1 8-1 11 1M7.5 13c2.5-.7 6.5-.7 9 1M8 16c2-.5 5-.5 7 .7" stroke="#fff" strokeWidth="1.6" fill="none" strokeLinecap="round"/></svg>
            Spotify
          </a>
          <a className="pod-sub-btn pod-sub-rss" href="#">
            <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2"><path d="M4 11a9 9 0 019 9M4 4a16 16 0 0116 16"/><circle cx="5" cy="19" r="1.5" fill="currentColor"/></svg>
            RSS
          </a>
        </div>
      </div>

      <div className="pod-right">
        <div className="pod-art">
          <div className="pod-cover"><Sleeve album={album} size={180} /></div>
          <div className="pod-waves">
            {Array.from({ length: 48 }).map((_, i) => {
              const h = 10 + ((Math.sin(i * 0.7) + 1) * 22) + ((i * 173) % 15);
              return <span key={i} style={{ height: h + "px", opacity: i / 48 < pos ? 1 : 0.3 }} />;
            })}
          </div>
        </div>
        <button className="pod-play" onClick={() => setPlaying(!playing)} aria-label={playing ? "Pause" : "Play"}>
          {playing ? (
            <svg width="26" height="26" viewBox="0 0 24 24" fill="currentColor"><rect x="6" y="5" width="4" height="14"/><rect x="14" y="5" width="4" height="14"/></svg>
          ) : (
            <svg width="26" height="26" viewBox="0 0 24 24" fill="currentColor"><path d="M7 5l12 7-12 7z"/></svg>
          )}
        </button>
        <div className="pod-time">
          <span>{formatMS(pos * 47.5)}</span>
          <span className="pod-slash">/</span>
          <span>{runtime}</span>
        </div>
      </div>
    </section>
  );
}
function formatMS(min) {
  const m = Math.floor(min);
  const s = Math.floor((min - m) * 60);
  return m + ":" + String(s).padStart(2, "0");
}
function Host({ name, subtitle, color }) {
  return (
    <div className="pod-host">
      <div className="pod-host-av" style={{ background: color }}>{name[0]}</div>
      <div>
        <div className="pod-host-name">{name}</div>
        <div className="pod-host-sub" dangerouslySetInnerHTML={{ __html: subtitle }} />
      </div>
    </div>
  );
}

/* ---- 7. Collector's desk --------------------------------------------- */
function CollectorsDesk() {
  return (
    <section className="desk">
      <div className="r-head">
        <div>
          <h2>The collector&rsquo;s desk.</h2>
          <p className="r-sub">One pressing a week, identified properly, priced honestly.</p>
        </div>
        <div className="desk-head-right">Week of April 16 · 2026</div>
      </div>
      <div className="desk-grid">
        <div className="desk-cover-col">
          <div className="desk-label-top">Featured pressing</div>
          <div className="desk-cover"><div className="desk-rumours-art" /></div>
        </div>
        <div className="desk-body">
          <div className="desk-eyebrow">First press · Warner Bros. · 1977</div>
          <h3 className="desk-title">
            <em>Rumours</em>, Fleetwood Mac
          </h3>
          <p className="desk-intro">The single best-known rock record of the late 1970s, and one of the most frequently misidentified on Discogs. Three hundred thousand copies got pressed in the first week; a few thousand of them are the ones you want.</p>

          <div className="desk-ident">
            <div className="desk-ident-label">How to identify it</div>
            <dl className="desk-dl">
              <div><dt>Catalog</dt><dd>Warner Bros. BSK 3010 (US)</dd></div>
              <div><dt>Runout etching</dt><dd><code>BSK-3010-A-LW1 · BSK-3010-B-LW1</code>, hand-scribed, not machine-stamped</dd></div>
              <div><dt>Label</dt><dd>Tan / palm-tree Warner label; label text set in Helvetica, not Futura (a later repress tell)</dd></div>
              <div><dt>Jacket</dt><dd>Gatefold sleeve with the Herbert Worthington photo; inner sleeve with lyrics and a credits column in serif</dd></div>
              <div><dt>Mastering</dt><dd>Ken Perry at Amigo Studios, Burbank. 'LW' in the runout = his cut.</dd></div>
            </dl>
          </div>

          <div className="desk-values">
            <div className="desk-val">
              <div className="dv-grade">Mint (M)</div>
              <div className="dv-price">$140–$220</div>
              <div className="dv-note">Sealed with the original sticker adds $80–140.</div>
            </div>
            <div className="desk-val featured">
              <div className="dv-grade">Near Mint (NM)</div>
              <div className="dv-price">$75–$120</div>
              <div className="dv-note">The sweet spot. Plays quiet, sleeve intact, asking price reasonable.</div>
            </div>
            <div className="desk-val">
              <div className="dv-grade">VG+</div>
              <div className="dv-price">$30–$55</div>
              <div className="dv-note">Do your pressing-matrix homework first. Many &ldquo;VG+ originals&rdquo; are 1978 repress.</div>
            </div>
          </div>

          <div className="desk-footer">
            <span className="desk-source">Source, Discogs sale velocity (90 days) + auction highs. Updated weekly.</span>
            <button className="desk-cta">
              Read the full pressing guide
              <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2"><path d="M5 12h14M13 5l7 7-7 7"/></svg>
            </button>
          </div>
        </div>
      </div>
    </section>
  );
}

/* ---- 8. Newsletter --------------------------------------------------- */
function Newsletter() {
  const [email, setEmail] = useHMState("");
  const [subbed, setSubbed] = useHMState(false);
  return (
    <section className="news">
      <div className="news-inner">
        <div className="news-kicker">The newsletter</div>
        <h2>One legendary album in your inbox every week.</h2>
        <p className="news-body">Wednesday morning. The new deep dive, the pressing guide, and a short note from the editor on what we got wrong last week. No pitches, no partner content, no roundup of &ldquo;the week in music.&rdquo; One record, all the way through.</p>
        {subbed ? (
          <div className="news-thanks">
            ✓ <span>Thanks, you&rsquo;re in. First issue arrives Wednesday.</span>
          </div>
        ) : (
          <form className="news-form" onSubmit={(e) => { e.preventDefault(); if (email.includes("@")) setSubbed(true); }}>
            <input
              type="email"
              placeholder="you@domain.com"
              value={email}
              onChange={e => setEmail(e.target.value)}
              required
            />
            <button type="submit">Subscribe</button>
          </form>
        )}
        <div className="news-fine">4,820 readers · published since 2023 · unsubscribe is one click and we respect it</div>
      </div>
    </section>
  );
}

/* ---- 9. Manifesto ---------------------------------------------------- */
function Manifesto() {
  return (
    <section className="manifesto">
      <div className="m-inner">
        <div className="m-kicker">About this project</div>
        <p className="m-body">
          The Lead-In is one person&rsquo;s long-form argument, updated weekly, for what the hundred greatest albums ever recorded actually are and why. The pieces are five to eight thousand words. They cite mastering engineers by name. They include pressing guides because the format matters. They will tell you the 1977 reissue of <em>What&rsquo;s Going On</em> is worse than the original and explain exactly which suffix in the runout to look for. This is not a playlist. It is not a ranking service. It is not &ldquo;curated for music lovers.&rdquo; It is a publication, one that assumes you already know what a good record is, and wants to argue about the last ten percent.
        </p>
        <div className="m-sig">, The editor, Brooklyn, NY</div>
      </div>
    </section>
  );
}

/* ---- 10. Footer ------------------------------------------------------ */
function FooterMag({ onList }) {
  return (
    <footer className="foot">
      <div className="foot-grid">
        <div>
          <div className="foot-brand">The Lead-In</div>
          <div className="foot-tag">The hundred greatest albums ever made, one long-form piece at a time.</div>
        </div>
        <div>
          <div className="foot-h">Navigate</div>
          <a onClick={onList}>The list 100 → 1</a>
          <a>Latest deep dive</a>
          <a>The archive</a>
          <a>Podcast</a>
        </div>
        <div>
          <div className="foot-h">Follow</div>
          <a>RSS</a>
          <a>Substack</a>
          <a href="https://www.instagram.com/the.leadin" target="_blank" rel="noopener noreferrer">Instagram</a>
          <a>Letterboxd (yes, we have one)</a>
        </div>
        <div>
          <div className="foot-h">Legal</div>
          <a>Ethics &amp; sources</a>
          <a>Affiliate disclosure</a>
          <a>Privacy</a>
          <a>Contact</a>
        </div>
      </div>
      <div className="foot-bottom">
        <span>© 2026 The Lead-In · Independent &amp; reader-supported</span>
        <span>Set in Canela Deck, Inter, and JetBrains Mono</span>
      </div>
    </footer>
  );
}

window.HomeMagazine = HomeMagazine;
