// Broadsheet sections — part A: hero, sample, thesis, discoverability, access

function Topbar() {
  const sections = ['Findings', 'Sample', 'Discoverability', 'Access', 'Cadence', 'Topics', 'Signup', 'Explorer'];
  const [active, setActive] = React.useState('Findings');
  const [progress, setProgress] = React.useState(0);
  const [docked, setDocked] = React.useState(false);
  React.useEffect(() => {
    const onScroll = () => {
      const h = document.documentElement;
      setProgress(h.scrollTop / (h.scrollHeight - h.clientHeight) * 100);
      const strip = document.getElementById('sponsor');
      if (strip) {
        // Dock once the inline strip has scrolled past the topbar
        setDocked(strip.getBoundingClientRect().bottom < 72);
      }
    };
    window.addEventListener('scroll', onScroll, { passive: true });
    onScroll();
    return () => window.removeEventListener('scroll', onScroll);
  }, []);
  return (
    <header className="topbar">
      <div className="topbar-inner">
        <a href="#top" className="topbar-mast">
          <img src={window.__resources && window.__resources.csmLogo || "assets/csm-logo.png"} alt="" />
          <div>
            <div>Center for Sustainable Media</div>
            <small>Newsletter Audit · 2026</small>
          </div>
        </a>
        <nav>
          {sections.map((s) =>
          <a key={s} href={`#${s.toLowerCase()}`}
          className={active === s ? 'is-active' : ''}
          onClick={() => setActive(s)}>{s}</a>
          )}
        </nav>
        <div className={`topbar-right${docked ? ' is-docked' : ''}`}>
          <div className="topbar-issue">REPORT №01 · 2026</div>
          <a className="topbar-sponsor" href="https://fatchillimedia.com/2881/newsletter-course/?utm_source=report_page_peter_e&utm_medium=cta_button&utm_campaign=newsletter_course" target="_blank" rel="noopener" aria-label="FatChilli newsletter course">
            <span className="topbar-sponsor-label">Sponsor</span>
            <img src="assets/fatchilli-logo.png" alt="FatChilli for publishers" />
          </a>
        </div>
        <div className="scroll-progress" style={{ width: `${progress}%` }} />
      </div>
    </header>);

}

function SponsorStrip() {
  return (
    <section className="sponsor-strip" id="sponsor">
      <div className="shell">
        <div className="sponsor-strip-inner">
          <div className="sponsor-strip-copy">
            <div className="section-tag"><em>※</em> Sponsored by FatChilli</div>
            <p>
              This research is supported by <strong>FatChilli for Publishers</strong>, an audience monetization agency. FatChilli in partnership with the Slovak independent Denník N is developing REMP - Readers’ Engagement and Monetization Platform, a publisher technology platform built for audience revenue, subscriptions, and audience engagement.
            </p>
            <p>
              FatChilli is preparing a newsletter course: practical, step-by-step guidance covering strategy, editorial decisions, audience growth, and the technical foundations of newsletters that work. For publishers starting from scratch and for those looking to improve what they already have.
            </p>
            <a className="sponsor-strip-cta" href="https://fatchillimedia.com/2881/newsletter-course/?utm_source=report_page_peter_e&utm_medium=cta_button&utm_campaign=newsletter_course" target="_blank" rel="noopener">
              <span className="sponsor-strip-cta-text">
                <span className="sponsor-strip-cta-sub">INTERESTED? SAVE YOUR SPOT AND THEY'LL BE IN TOUCH WITH MORE DETAILS.</span>
                <span className="sponsor-strip-cta-title">Register for the newsletter course</span>
              </span>
              <span className="sponsor-strip-cta-arrow" aria-hidden="true">→</span>
            </a>
          </div>
          <a className="sponsor-strip-mark" href="https://fatchillimedia.com/2881/newsletter-course/?utm_source=report_page_peter_e&utm_medium=cta_button&utm_campaign=newsletter_course" target="_blank" rel="noopener" aria-label="FatChilli for publishers">
            <img src="assets/fatchilli-logo.png" alt="FatChilli for publishers" />
          </a>
        </div>
      </div>
    </section>);

}

function Hero() {
  return (
    <section className="hero" id="top">
      <div className="shell">
        <div>
          <div className="eyebrow">A field audit by CSM</div>
          <h1>Europe's enterprise publishers are <em>underusing</em> the inbox.</h1>
          <p className="hero-deck">
            Newsletters give publishers their most controlled channel and connect with the
            readers most likely to pay. Across 32 enterprise publishers in 10 markets, we
            found newsletter products that are hard to find, harder to evaluate, and asked
            too much of readers before they ever saw a single edition.
          </p>
          <div className="hero-meta">
            <span>Published<b>May 2026</b></span>
            <span>Reading time<b>14 minutes</b></span>
            <span>Sample size<b>n = 859</b></span>
          </div>
        </div>
        <div className="hero-stats">
          <div className="hero-stat"><div className="num">859</div><div className="label">Newsletters reviewed</div></div>
          <div className="hero-stat"><div className="num">32</div><div className="label">Enterprise publishers</div></div>
          <div className="hero-stat"><div className="num">10</div><div className="label">European markets</div></div>
        </div>
      </div>
    </section>);

}

function Sample() {
  const { countries, publishers } = window.BS_DATA;
  const max = Math.max(...countries.map((c) => c[3]));
  return (
    <section className="section" id="sample">
      <div className="shell">
        <SectionHead num="01" tag="Sample" title="859 newsletters · 32 publishers · 10 markets."
        lede="Publishers were assessed across their full newsletter portfolio, not a flagship subset. The sample spans Western, Northern, Southern, and Central Europe." />
        <div className="sample-grid">
          <div>
            <div className="section-tag" style={{ marginBottom: 16 }}>By country</div>
            <div className="country-list">
              {countries.map(([c, name, region, count], i) =>
              <div key={c} className="country-row">
                  <span className="rank">{String(i + 1).padStart(2, '0')}</span>
                  <span className="name">{name}<small>{region} Europe</small></span>
                  <div className="bar"><span style={{ width: `${count / max * 100}%` }} /></div>
                  <span className="count">{count}</span>
                </div>
              )}
            </div>
          </div>
          <div>
            <div className="section-tag" style={{ marginBottom: 16 }}>By publisher (top 10)</div>
            <div className="sample-pubs">
              {publishers.map(([p, c, n, signup]) =>
              <div key={p} className="pub-row">
                  <div className="pub-name">{p}<small>{c}</small></div>
                  <div className="pub-count">{n}</div>
                </div>
              )}
            </div>
            <p style={{ marginTop: 16, fontSize: 13, color: 'var(--ink-soft)', lineHeight: 1.5 }}>
              Use the <a href="#explorer" style={{ color: 'var(--accent)', borderBottom: '1px solid currentColor' }}>data explorer</a> to inspect every publisher and newsletter product.
            </p>
          </div>
        </div>
      </div>
    </section>);

}

function Thesis() {
  const { thesis } = window.BS_DATA;
  return (
    <section className="section" id="findings">
      <div className="shell">
        <SectionHead num="02" tag="Why newsletters matter"
        title="The inbox is one of the last channels publishers actually control."
        lede="Six structural reasons newsletters are becoming a more important channel for distribution and monetization than the typical enterprise publisher treats them as." />
        <div className="thesis-grid">
          {thesis.map(([n, t, p]) =>
          <article key={n} className="thesis-card">
              <div className="num">№ {n}</div>
              <h3>{t}</h3>
              <p>{p}</p>
            </article>
          )}
        </div>
      </div>
    </section>);

}

function Discoverability() {
  const { placement } = window.BS_DATA;
  return (
    <section className="section" id="discoverability">
      <div className="shell">
        <SectionHead num="03" tag="Discoverability"
        title="Most newsletter portfolios aren't visible from the homepage."
        lede="Where 32 enterprise publishers place newsletter entry points. Multiple placements possible per publisher; categories are not mutually exclusive." />
        <div className="bars">
          {placement.map(([l, s, p, accent]) =>
          <div key={l} className={`bar-row${accent ? ' is-accent' : ''}`}>
              <div className="label">{l}<small>{s}</small></div>
              <div className="bar"><span style={{ width: `${p}%` }} /></div>
              <div className="pct">{p}%</div>
            </div>
          )}
        </div>
        <div className="chart-foot">
          <div />
          <p>Only 1 in 6 enterprise publishers in the sample features a newsletter on the homepage above the fold.
            For a product category meant to be habitual, the entry door is rarely the front door.</p>
        </div>
      </div>
    </section>);

}

function Access() {
  const accessSegs = [
  { label: 'Free', value: 83, color: 'var(--ink)', sub: '713 newsletters' },
  { label: 'Paid', value: 17, color: 'var(--accent)', sub: '146 newsletters' }];

  const paidTopics = [
  ['Business & Finance', 38, 26],
  ['Politics & Geopolitics', 32, 22],
  ['General News', 18, 12],
  ['Tech & Science', 14, 10],
  ['Culture & Arts', 12, 8],
  ['Sports', 10, 7],
  ['Local & Regional', 8, 5],
  ['Lifestyle & Leisure', 6, 4],
  ['Health & Wellness', 4, 3],
  ['Other', 4, 3]];

  const paidMax = Math.max(...paidTopics.map((t) => t[1]));
  const nonfreeSegs = [
  { label: 'Subscriber-only', value: 58, color: 'var(--accent)', sub: '85 newsletters' },
  { label: 'Vertical sub.', value: 27, color: 'var(--accent-soft)', sub: '39 newsletters' },
  { label: 'Freemium', value: 15, color: 'var(--paper-3)', sub: '22 newsletters' }];

  return (
    <section className="section" id="access">
      <div className="shell">
        <SectionHead num="04" tag="Access model"
        title="Mostly free, selectively paid."
        lede="Most newsletters in the sample are free, suggesting use as a distribution or engagement tool rather than a premium product. Paid sits in a small, concentrated tail." />
        <div className="access-grid">
          <div className="donut-card">
            <h3>All newsletters · share by access model</h3>
            <div className="donut-row">
              <Donut segments={accessSegs} centerValue="83%" centerLabel="Free" />
              <div className="donut-legend">
                {accessSegs.map((s) =>
                <div key={s.label} className="legend-item">
                    <span className="swatch" style={{ background: s.color }} />
                    <span className="name">{s.label}<small>{s.sub}</small></span>
                    <span className="v">{s.value}%</span>
                  </div>
                )}
              </div>
            </div>
          </div>
          <div className="donut-card">
            <h3>Of paid newsletters · share by paid model</h3>
            <div className="donut-row">
              <Donut segments={nonfreeSegs} centerValue="146" centerLabel="Paid total" />
              <div className="donut-legend">
                {nonfreeSegs.map((s) =>
                <div key={s.label} className="legend-item">
                    <span className="swatch" style={{ background: s.color }} />
                    <span className="name">{s.label}<small>{s.sub}</small></span>
                    <span className="v">{s.value}%</span>
                  </div>
                )}
              </div>
            </div>
          </div>
        </div>
        <div className="paid-topics-card">
          <div className="paid-topics-head">
            <h3>Of paid newsletters · breakdown by topic</h3>
            <p className="paid-topics-sub">Among the 146 paid newsletters in the sample. Business and politics together account for nearly half.</p>
          </div>
          <ul className="paid-topic-bars">
            {paidTopics.map(([label, count, pct]) =>
            <li key={label} className="paid-topic-row">
                <span className="paid-topic-label">{label}</span>
                <span className="paid-topic-track">
                  <span className="paid-topic-fill" style={{ width: `${count / paidMax * 100}%` }} />
                </span>
                <span className="paid-topic-count">{count}</span>
                <span className="paid-topic-pct">{pct}%</span>
              </li>
            )}
          </ul>
        </div>
        <div className="chart-foot">
          <div />
          <p>Of the 17% of newsletters that are Paid, the majority are subscriber-only.
            Standalone newsletter products remain rare across the sample. Within paid, the mix concentrates in business and politics, the two topics readers most often pay for elsewhere on the site.</p>
        </div>
      </div>
    </section>);

}

Object.assign(window, { Topbar, Hero, SponsorStrip, Sample, Thesis, Discoverability, Access });