// Articles page — QDI Intelligence Briefing
// To publish a new article: add an object to the ARTICLES array below.

const ARTICLES = [
  {
    id: 1,
    tag: 'Breaking Intelligence',
    title: "Q-Day Just Got Closer: What Google's 2029 Deadline Means for Canadian Critical Infrastructure",
    date: 'May 2026',
    readTime: '7 min read',
    excerpt: "On March 25, 2026, Google announced it is accelerating its internal quantum migration deadline to 2029 — six years ahead of federal mandates. New research has reduced the qubit estimates needed to break RSA encryption by a factor of twenty. The window for inaction has closed.",
    content: [
      {
        type: 'lead',
        text: "On March 25, 2026, Google published a post titled 'Quantum Frontiers May Be Closer Than They Appear.' The headline was understated. What it contained was the most concrete public signal yet that the cryptographic foundation of the internet has a hard expiration date — and that date is closer than any government timeline has acknowledged.",
      },
      {
        type: 'heading',
        text: "The 2029 Signal",
      },
      {
        type: 'body',
        text: "Google announced it is setting 2029 as its internal deadline to migrate its entire infrastructure — Chrome, Android, Google Cloud, Gmail, all APIs and certificates — to post-quantum cryptography. This is not a regulatory response. Google's own Quantum AI division is producing the research that defines the threat, and they are migrating six years ahead of the 2035 federal mandate. When the company that operates one of the world's largest quantum programs sets its own migration deadline to 2029, that signal carries different weight than any government guidance.",
      },
      {
        type: 'body',
        text: "Heather Adkins, VP of Security Engineering at Google, and Sophie Schmieg, Senior Staff Cryptology Engineer, wrote: 'This new timeline reflects migration needs for the PQC era in light of progress on quantum computing hardware development, quantum error correction, and quantum factoring resource estimates.' Google has already migrated its internal key exchange to ML-KEM, the primary post-quantum standard finalized by NIST in August 2024. Android 17 will include ML-DSA quantum-resistant signatures for the boot process and app signing.",
      },
      {
        type: 'heading',
        text: "The Research That Changed the Numbers",
      },
      {
        type: 'body',
        text: "Three papers published between May 2025 and March 2026 have fundamentally shifted the quantum threat assessment. First, Google Quantum AI published research showing that breaking the elliptic curve encryption protecting most digital signatures and cryptocurrency would require roughly 500,000 physical qubits — twenty times fewer than previously estimated. Second, a joint paper from Caltech, Oratomic, and UC Berkeley demonstrated that neutral-atom architectures could break classical encryption with as few as 10,000 qubits. Third, Google released a zero-knowledge proof showing RSA-2048 is more vulnerable than previously modelled — without publishing the actual attack circuits, for national security reasons.",
      },
      {
        type: 'stat',
        label: 'Previous qubit estimate to break RSA',
        value: '20 million+',
        note: 'pre-2025 consensus',
      },
      {
        type: 'stat',
        label: 'Current estimate after 2026 research',
        value: '< 500,000',
        note: 'Google Quantum AI, March 2026',
      },
      {
        type: 'body',
        text: "Qian Xu, a Caltech researcher and co-author of the neutral-atom paper, stated the findings are significant and indicate a cryptographically relevant quantum computer could be operational by the end of this decade. 'We have gone from planning for a threat two decades out to one that overlaps with systems actively being deployed and funded,' said Nathaniel Szerezla, Chief Growth Officer at Naoris Protocol.",
      },
      {
        type: 'heading',
        text: "What This Means for Canadian Critical Infrastructure",
      },
      {
        type: 'body',
        text: "Canada's ITSM.40.001 migration roadmap, published by the Canadian Centre for Cyber Security on June 23, 2025, sets end-of-2031 for high-priority systems and end-of-2035 for all remaining systems. The Treasury Board's October 2025 Security Policy Implementation Notice (SPIN) makes PQC readiness a mandatory contractual requirement for all Government of Canada procurement after April 1, 2026. These deadlines were set based on threat assessments that pre-date the March 2026 research. The actual threat timeline is compressing faster than the compliance timeline.",
      },
      {
        type: 'body',
        text: "For critical infrastructure operators in Canada — power grids, financial institutions, telecommunications providers, healthcare systems — the practical implication is this: if Google, with its vast engineering resources, considers 2029 the right internal target, an organisation beginning PQC procurement in late 2026 or 2027 may not complete migration before the threat window opens. The CSE's ITSP.40.111 cryptographic standards define which algorithms to use. QDI's Peregrine X platform is the procurement decision that activates them — without rip-and-replace, without operational downtime, and within a 24-hour deployment window.",
      },
      {
        type: 'source',
        text: "Sources: Google Security Blog (March 25, 2026); Google Quantum AI research paper on ECDLP-256; Caltech/Oratomic/UC Berkeley preprint on neutral-atom qubit estimates; CyberScoop (April 2026); CCCS ITSM.40.001 (June 2025); TBS SPIN (October 2025); CSE ITSP.40.111.",
      },
    ],
  },
  {
    id: 2,
    tag: 'Threat Intelligence',
    title: "Harvest Now, Decrypt Later: The Active Operation Against Canadian Data You Cannot See",
    date: 'April 2026',
    readTime: '8 min read',
    excerpt: "State actors are not waiting for quantum computers. They are collecting Canadian government communications, financial records, and infrastructure data right now — storing it for decryption once a cryptographically relevant quantum machine exists. A March 2026 academic paper models this as an economic operation, not a speculative threat.",
    content: [
      {
        type: 'lead',
        text: "The most dangerous aspect of the Harvest Now, Decrypt Later threat is that it produces no observable incident. There is no breach notification. There is no anomaly in your SIEM. Encrypted packets leave your network looking exactly as they should — because they are encrypted. The attack has already succeeded by the time anyone knows to look for it.",
      },
      {
        type: 'heading',
        text: "What HNDL Actually Is",
      },
      {
        type: 'body',
        text: "Harvest Now, Decrypt Later (HNDL) is an intelligence collection strategy in which adversaries intercept and archive encrypted data today with the explicit intention of decrypting it once a cryptographically relevant quantum computer (CRQC) becomes available. The strategy requires no quantum capability today — only storage, which is economically trivial. A March 2026 peer-reviewed paper published on arXiv by researchers at Universidad Carlos III de Madrid reframed HNDL as an economic problem: retaining intercepted TLS, QUIC, and SSH traffic is so inexpensive that the defensive question is no longer whether an adversary can archive it, but how much quantum computation decryption will eventually cost them. The answer, based on new qubit estimates, is less than previously thought.",
      },
      {
        type: 'body',
        text: "The Communications Security Establishment Canada (CSE) has assessed that a quantum computer capable of breaking current cryptographic standards could exist as early as the 2030s. The Global Risk Institute's 2026 Quantum Threat Timeline, produced with evolutionQ, estimates a cryptographically relevant quantum computer is 'quite possible' within ten years and 'likely' within fifteen. Google's own research, published March 2026, suggests the threat is closer to the lower end of that range.",
      },
      {
        type: 'heading',
        text: "Who Is Doing This and What Are They Targeting",
      },
      {
        type: 'body',
        text: "HNDL operations are attributed primarily to nation-state intelligence services with long-term strategic data collection mandates. The Google security team stated in February 2026 that the US, Russia, and China have been archiving encrypted internet traffic for years with the explicit plan to decrypt it when quantum computers are ready. The data categories most at risk are those with long confidentiality requirements: classified and protected government communications, national security intelligence, long-term infrastructure configuration data, financial transaction records, health records, intellectual property, and any information whose compromise would be damaging years from now.",
      },
      {
        type: 'stat',
        label: 'Estimated GDP at risk from single quantum attack on one top-5 bank',
        value: '$2–3.3T',
        note: 'Citi Institute / QuSecure, January 2026',
      },
      {
        type: 'body',
        text: "A January 2026 report from the Citi Institute, co-authored by QuSecure's Rebecca Krauthamer and Garrison Buss, modelled a single-day quantum attack on one top-five US bank's Fedwire access. The estimated economic impact: $2 to $3.3 trillion USD in GDP at risk — 10 to 17 percent of US GDP from one attack on one institution. Canadian financial infrastructure operates on interconnected systems. The exposure is not theoretical.",
      },
      {
        type: 'heading',
        text: "The Detection Problem — and QDI's Answer",
      },
      {
        type: 'body',
        text: "Standard security tooling — firewalls, intrusion detection systems, SIEM platforms — cannot detect HNDL operations because the traffic being collected is encrypted and legitimate. There is no signature to match, no payload to inspect, no threshold to trigger. The attack is invisible to every tool built on the assumption that threats must be decrypted to be dangerous.",
      },
      {
        type: 'body',
        text: "QDI's Live Watch module addresses this detection gap directly. Rather than inspecting payload content, Live Watch analyses network behaviour patterns: the volume, timing, destination, and protocol characteristics of encrypted traffic flows consistent with bulk state-sponsored collection campaigns. When HNDL-pattern signatures are identified, encryption protocols escalate automatically and the CISO is alerted in real time. This is the only commercially available tool designed specifically to detect active HNDL operations before the data leaves the network perimeter. Combined with Peregrine X's Dual-Spectrum cryptographic engine — running CSE ITSP.40.111-approved ML-KEM and ML-DSA alongside RSA-4096 simultaneously — organisations achieve both immediate detection and long-term cryptographic immunity.",
      },
      {
        type: 'body',
        text: "The CCCS ITSM.40.001 roadmap explicitly identifies systems susceptible to HNDL — specifically those protecting the confidentiality of information in transit over public network zones — as the highest priority for early PQC migration. The Treasury Board SPIN (October 2025) requires departments to identify and prioritise these systems by April 2028. For private sector operators, the equivalent urgency is immediate: every day of delay extends the window of harvestable data.",
      },
      {
        type: 'source',
        text: "Sources: arXiv preprint 2603.01091, Blanco-Romero et al. (March 2026); Google Security Blog (February 7, 2026); Global Risk Institute Quantum Threat Timeline (2026); Citi Institute / QuSecure report (January 2026); CSE assessment via Canada.ca; CCCS ITSM.40.001 (June 2025); TBS SPIN (October 2025).",
      },
    ],
  },
  {
    id: 3,
    tag: 'Regulatory Analysis',
    title: "ITSM.40.001 Decoded: Canada's Binding PQC Mandate and What It Demands of Your Organisation",
    date: 'March 2026',
    readTime: '9 min read',
    excerpt: "On June 23, 2025, Canada published its first binding Post-Quantum Cryptography migration roadmap. On October 9, 2025, the Treasury Board converted it into hard-dated procurement obligations. This is a complete breakdown of every deadline, every requirement, and what it means for government departments and critical infrastructure operators.",
    content: [
      {
        type: 'lead',
        text: "ITSM.40.001 is not guidance. It is not a recommendation. It is a binding migration schedule with specific deadlines, annual reporting obligations, and procurement implications that are already in effect. Published by the Canadian Centre for Cyber Security on June 23, 2025, and operationalised by the Treasury Board on October 9, 2025, this two-document framework is Canada's functional equivalent of the regulatory mandates that have galvanised quantum migration efforts in allied nations.",
      },
      {
        type: 'heading',
        text: "The Three Deadlines You Need to Know",
      },
      {
        type: 'body',
        text: "ITSM.40.001 establishes three hard milestones for all federal departments and agencies. By April 2026, every department must submit an initial PQC migration plan and begin annual progress reporting to the Treasury Board. By end of 2031, all high-priority systems — defined as those most susceptible to Harvest Now, Decrypt Later attacks and those handling sensitive data in transit over public network zones — must complete migration. By end of 2035, all remaining non-classified systems must achieve full PQC compliance.",
      },
      {
        type: 'body',
        text: "The scope is broader than many organisations have recognised. ITSM.40.001 applies to any Government of Canada information system that employs cryptography. This includes network services, operating systems, applications, code development pipelines, and all physical IT assets. It explicitly includes third-party services — if a department uses cloud infrastructure, the cryptographic components of that infrastructure fall within scope.",
      },
      {
        type: 'heading',
        text: "The TBS SPIN: From Roadmap to Obligation",
      },
      {
        type: 'body',
        text: "On October 9, 2025, the Treasury Board of Canada Secretariat issued a Security Policy Implementation Notice titled 'Migrating the Government of Canada to Post-Quantum Cryptography.' This SPIN is the instrument that converts ITSM.40.001 from a planned roadmap into auditable, monitored, procurement-enforced obligations. Its key commercial implication: PQC readiness is now a contractual requirement for new Government of Canada procurement after April 1, 2026. Vendors that cannot demonstrate quantum-safe cryptographic roadmaps aligned to CSE ITSP.40.111 will face procurement disadvantage.",
      },
      {
        type: 'stat',
        label: 'GC Procurement PQC requirement effective date',
        value: 'April 1, 2026',
        note: 'TBS SPIN, October 9, 2025',
      },
      {
        type: 'body',
        text: "The SPIN is explicit about monitoring and enforcement. The Treasury Board will engage senior officials — CIOs, CSOs, and Designated Officials for Cyber Security — when departments fail to meet direction deadlines. The instrument ties PQC migration progress to the annual Departmental Plans on Service and Digital, making it a visible governance metric at the deputy head level.",
      },
      {
        type: 'heading',
        text: "The Cryptographic Standard: CSE ITSP.40.111",
      },
      {
        type: 'body',
        text: "The SPIN ties all 'PQC compliant' definitions to the Cyber Centre's cryptographic algorithm baseline, CSE ITSP.40.111. This document defines the approved quantum-resistant algorithms for all Government of Canada systems at Unclassified, Protected A, and Protected B levels. The three post-quantum algorithms mandated are ML-KEM (FIPS 203) for key encapsulation, ML-DSA (FIPS 204) for digital signatures, and SLH-DSA (FIPS 205) for hash-based signatures — the same three standards finalized by NIST in August 2024. In March 2025, NIST also selected HQC as an additional key encapsulation mechanism, providing algorithmic diversity.",
      },
      {
        type: 'heading',
        text: "Bill C-8 and the Extension to Critical Infrastructure",
      },
      {
        type: 'body',
        text: "The obligations described above apply directly to federal departments. The extension to private sector critical infrastructure comes through Bill C-8 — the Critical Cyber Systems Protection Act (CCSPA) — re-tabled in the House of Commons on June 18, 2025, and currently progressing through the Standing Committee on Public Safety and National Security. If enacted, CCSPA will impose mandatory cybersecurity program obligations on designated operators in four federally regulated sectors: telecommunications, finance, energy, and transport. Penalties for non-compliance reach $15 million CAD per day for organisations.",
      },
      {
        type: 'body',
        text: "The CCSPA does not yet specify PQC requirements by name, but its requirement for cybersecurity programs that 'protect critical cyber systems' against 'a broad range of threats' will, once enacted, create the basis for PQC-specific regulatory direction. Organisations in regulated sectors that begin migration now will be demonstrably ahead of compliance requirements when CCSPA receives Royal Assent.",
      },
      {
        type: 'heading',
        text: "The National Quantum Strategy Context",
      },
      {
        type: 'body',
        text: "ITSM.40.001 and the TBS SPIN do not exist in isolation. They are the security implementation arm of Canada's National Quantum Strategy (NQS), launched in January 2023 with $360 million in federal funding. The NQS identifies three missions: quantum computing, quantum sensors, and quantum communications including post-quantum cryptography. The Department of National Defence's Quantum 2030 plan, released in 2023, commits DND and the Canadian Armed Forces to quantum-safe prototypes tested in the field by 2030. QDI's product roadmap aligns directly with these national commitments — Peregrine X for enterprise and government PQC migration, and Osprey X for sovereign-grade hardware deployment in classified and defence environments.",
      },
      {
        type: 'body',
        text: "QDI Peregrine X implements ML-KEM, ML-DSA, and SLH-DSA as defined in CSE ITSP.40.111, deploys via Docker or Kubernetes on existing infrastructure, and supports Government of Canada procurement eligibility under the TBS SPIN framework. For departments that must submit initial migration plans by April 2026, Peregrine X is the fastest path from compliance obligation to cryptographic protection.",
      },
      {
        type: 'source',
        text: "Sources: CCCS ITSM.40.001 (June 23, 2025); TBS SPIN 'Migrating the Government of Canada to Post-Quantum Cryptography' (October 9, 2025); CSE ITSP.40.111 (updated March 2025); Bill C-8 / CCSPA legislative record (June 2025 – present); Canada's National Quantum Strategy (January 2023); DND Quantum 2030 (2023); NIST FIPS 203, 204, 205 (August 2024); NIST HQC selection (March 2025).",
      },
    ],
  },
];

// ─── Article List View ────────────────────────────────────────────────────────
function ArticlesPage() {
  const [selected, setSelected] = React.useState(null);

  // Scroll to top whenever view changes
  React.useEffect(() => {
    window.scrollTo({ top: 0, behavior: 'instant' });
  }, [selected]);

  // Handle browser back button — popstate fires when user presses ←
  React.useEffect(() => {
    const onPop = () => setSelected(null);
    window.addEventListener('popstate', onPop);
    return () => window.removeEventListener('popstate', onPop);
  }, []);

  const selectArticle = (article) => {
    // Push a history entry so browser ← goes back to article list
    window.history.pushState({ articleId: article.id }, '');
    setSelected(article);
  };

  const goBack = () => {
    setSelected(null);
  };

  if (selected) return <ArticleDetail article={selected} onBack={goBack} />;
  return <ArticleList articles={ARTICLES} onSelect={selectArticle} />;
}

function ArticleList({ articles, onSelect }) {
  return (
    <div style={{ position: 'relative', zIndex: 2, padding: '140px 40px 120px' }}>
      <div style={{ maxWidth: 1100, margin: '0 auto' }}>

        {/* Header */}
        <div style={{ marginBottom: 80 }}>
          <div style={{ marginBottom: 20 }}>
            <Eyebrow>QDI Intelligence Briefing</Eyebrow>
          </div>
          <h1 style={{
            fontSize: 'clamp(52px, 7vw, 88px)', fontWeight: 600, margin: 0,
            lineHeight: 1.0, letterSpacing: '-0.035em', color: 'var(--text)',
          }}>
            Articles &{' '}
            <em style={{ fontWeight: 400, fontStyle: 'italic', color: 'var(--text-soft)' }}>Insights</em>.
          </h1>
        </div>

        <Rule style={{ marginBottom: 0 }} />

        {/* Articles */}
        {articles.map((a, i) => (
          <ArticleRow key={a.id} article={a} index={i} onClick={() => onSelect(a)} isLast={i === articles.length - 1} />
        ))}
      </div>
    </div>
  );
}

function ArticleRow({ article, index, onClick, isLast }) {
  const [hovered, setHovered] = React.useState(false);
  return (
    <div
      onClick={onClick}
      onMouseEnter={() => setHovered(true)}
      onMouseLeave={() => setHovered(false)}
      style={{
        display: 'grid',
        gridTemplateColumns: '48px 1fr 160px',
        gap: 48,
        alignItems: 'start',
        padding: '52px 0',
        borderBottom: isLast ? 'none' : '1px solid var(--border-soft)',
        cursor: 'pointer',
        transition: 'background 0.2s, padding-left 0.25s',
        paddingLeft: hovered ? 8 : 0,
      }}
    >
      {/* Number */}
      <div style={{
        fontSize: 13, fontWeight: 400, color: 'var(--accent-bright)',
        letterSpacing: '0.1em', opacity: 0.6, paddingTop: 6,
        fontVariantNumeric: 'tabular-nums',
      }}>
        {String(index + 1).padStart(2, '0')}
      </div>

      {/* Main content */}
      <div>
        <div style={{ display: 'flex', alignItems: 'center', gap: 12, marginBottom: 18 }}>
          <span style={{
            fontSize: 10, fontWeight: 600, color: 'var(--accent-bright)',
            letterSpacing: '0.2em', textTransform: 'uppercase',
            padding: '4px 10px',
            border: '1px solid rgba(18,196,168,0.35)',
            borderRadius: 3,
          }}>{article.tag}</span>
          <span style={{ fontSize: 12, color: 'var(--text-muted)', letterSpacing: '0.06em' }}>{article.readTime}</span>
        </div>
        <h2 style={{
          fontSize: 'clamp(22px, 2.4vw, 30px)', fontWeight: 600,
          margin: '0 0 16px', lineHeight: 1.2, letterSpacing: '-0.02em',
          color: hovered ? 'var(--accent-bright)' : 'var(--text)',
          transition: 'color 0.2s', maxWidth: 700,
        }}>
          {article.title}
        </h2>
        <p style={{
          fontSize: 16, color: 'var(--text-soft)', lineHeight: 1.7,
          margin: 0, maxWidth: 680,
        }}>
          {article.excerpt}
        </p>
      </div>

      {/* Date + arrow */}
      <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'flex-end', justifyContent: 'flex-start', gap: 16, paddingTop: 6 }}>
        <span style={{ fontSize: 12, color: 'var(--text-muted)', letterSpacing: '0.08em', whiteSpace: 'nowrap' }}>
          {article.date}
        </span>
        <div style={{
          width: 40, height: 40, borderRadius: '50%',
          border: `1px solid ${hovered ? 'var(--accent-bright)' : 'var(--border-soft)'}`,
          display: 'flex', alignItems: 'center', justifyContent: 'center',
          transition: 'border-color 0.2s, background 0.2s',
          background: hovered ? 'rgba(18,196,168,0.1)' : 'transparent',
        }}>
          <svg width="16" height="16" viewBox="0 0 24 24" fill="none"
            stroke={hovered ? 'var(--accent-bright)' : 'var(--text-muted)'}
            strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"
            style={{ transition: 'transform 0.2s, stroke 0.2s', transform: hovered ? 'translateX(2px)' : 'none' }}>
            <path d="M5 12h14M13 6l6 6-6 6" />
          </svg>
        </div>
      </div>
    </div>
  );
}

// ─── Article Detail View ──────────────────────────────────────────────────────
function ArticleDetail({ article, onBack }) {
  return (
    <div style={{ position: 'relative', zIndex: 2, padding: '120px 40px 120px' }}>
      <div style={{ maxWidth: 800, margin: '0 auto' }}>

        {/* Back button */}
        <button
          onClick={onBack}
          style={{
            background: 'none', border: 'none', cursor: 'pointer', padding: 0,
            display: 'inline-flex', alignItems: 'center', gap: 8,
            fontSize: 11, fontWeight: 500, color: 'var(--text-muted)',
            letterSpacing: '0.16em', textTransform: 'uppercase', marginBottom: 64,
            transition: 'color 0.2s', fontFamily: 'inherit',
          }}
          onMouseEnter={(e) => e.currentTarget.style.color = 'var(--accent-bright)'}
          onMouseLeave={(e) => e.currentTarget.style.color = 'var(--text-muted)'}
        >
          <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
            <path d="M19 12H5M11 6l-6 6 6 6" />
          </svg>
          All Articles
        </button>

        {/* Meta */}
        <div style={{ display: 'flex', alignItems: 'center', gap: 14, marginBottom: 28, flexWrap: 'wrap' }}>
          <span style={{
            fontSize: 10, fontWeight: 600, color: 'var(--accent-bright)',
            letterSpacing: '0.2em', textTransform: 'uppercase',
            padding: '5px 12px', border: '1px solid rgba(18,196,168,0.35)', borderRadius: 3,
          }}>{article.tag}</span>
          <span style={{ fontSize: 13, color: 'var(--text-muted)', letterSpacing: '0.06em' }}>{article.date}</span>
          <span style={{ fontSize: 13, color: 'var(--text-muted)', letterSpacing: '0.06em' }}>· {article.readTime}</span>
        </div>

        {/* Title */}
        <h1 style={{
          fontSize: 'clamp(34px, 4.5vw, 52px)', fontWeight: 600,
          margin: '0 0 56px', lineHeight: 1.1, letterSpacing: '-0.025em', color: 'var(--text)',
        }}>
          {article.title}
        </h1>

        <Rule style={{ marginBottom: 56 }} />

        {/* Body blocks */}
        <div style={{ display: 'flex', flexDirection: 'column', gap: 0 }}>
          {article.content.map((block, i) => {
            if (block.type === 'lead') return (
              <p key={i} style={{
                fontSize: 22, fontWeight: 400, color: 'var(--text)',
                lineHeight: 1.7, margin: '0 0 40px',
                borderLeft: '3px solid var(--accent-bright)',
                paddingLeft: 24,
              }}>{block.text}</p>
            );
            if (block.type === 'heading') return (
              <h2 key={i} style={{
                fontSize: 24, fontWeight: 600, color: 'var(--accent-bright)',
                margin: '48px 0 20px', letterSpacing: '-0.01em', lineHeight: 1.25,
              }}>{block.text}</h2>
            );
            if (block.type === 'body') return (
              <p key={i} style={{
                fontSize: 18, fontWeight: 400, color: 'var(--text-soft)',
                lineHeight: 1.85, margin: '0 0 28px',
              }}>{block.text}</p>
            );
            if (block.type === 'stat') return (
              <div key={i} style={{
                margin: '12px 0 40px',
                background: 'var(--bg-card)',
                border: '1px solid var(--border)',
                borderLeft: '3px solid var(--accent-bright)',
                borderRadius: 8, padding: '24px 28px',
                display: 'flex', alignItems: 'baseline', gap: 24, flexWrap: 'wrap',
              }}>
                <div style={{ fontSize: 13, color: 'var(--text-muted)', letterSpacing: '0.04em', flex: 1 }}>{block.label}</div>
                <div style={{ fontSize: 36, fontWeight: 600, color: 'var(--accent-bright)', letterSpacing: '-0.03em', lineHeight: 1 }}>{block.value}</div>
                <div style={{ fontSize: 11, color: 'var(--text-muted)', letterSpacing: '0.08em', width: '100%', marginTop: 6 }}>{block.note}</div>
              </div>
            );
            if (block.type === 'source') return (
              <div key={i} style={{
                margin: '48px 0 0',
                padding: '20px 24px',
                background: 'rgba(235, 230, 220, 0.8)',
                border: '1px solid rgba(0,0,0,0.08)',
                borderRadius: 6,
                fontSize: 12, color: 'var(--text-soft)', lineHeight: 1.8,
                letterSpacing: '0.02em',
              }}>
                <span style={{ color: 'var(--accent-bright)', fontWeight: 600, letterSpacing: '0.1em', textTransform: 'uppercase', fontSize: 10 }}>Sources · </span>
                {block.text}
              </div>
            );
            return null;
          })}
        </div>

        <Rule style={{ margin: '64px 0 48px' }} />

        {/* CTA */}
        <div style={{
          background: 'var(--bg-card)', border: '1px solid var(--border)',
          borderRadius: 10, padding: '36px 40px',
          display: 'flex', alignItems: 'center', justifyContent: 'space-between', flexWrap: 'wrap', gap: 24,
        }}>
          <div>
            <div style={{ fontSize: 11, color: 'var(--accent-bright)', letterSpacing: '0.2em', textTransform: 'uppercase', marginBottom: 8 }}>
              QDI Intelligence Briefing
            </div>
            <div style={{ fontSize: 17, fontWeight: 500, color: 'var(--text)', letterSpacing: '-0.01em' }}>
              Get articles like this delivered to your inbox.
            </div>
          </div>
          <button onClick={onBack} style={{
            height: 44, padding: '0 22px', borderRadius: 6,
            background: 'var(--accent-bright)', color: '#fff', border: 'none',
            fontFamily: 'inherit', fontSize: 13, fontWeight: 500,
            cursor: 'pointer', flexShrink: 0,
            boxShadow: '0 4px 16px rgba(14,158,136,0.25)',
          }}>
            Subscribe on Home Page
          </button>
        </div>
      </div>
    </div>
  );
}

Object.assign(window, { ArticlesPage, ARTICLES });
