/* =========================================================
   Blog — 3 research-voice articles
   Each article: { slug, title, excerpt, readingMin, date, category, toc, body (React node fn) }
   body() returns JSX. This keeps articles editable as code.
   ========================================================= */

const BLOG_POSTS = [
  {
    slug: 'how-to-read-a-peptide-coa',
    title: 'How to read a peptide Certificate of Analysis',
    excerpt: 'A vial is only as trustworthy as the document that accompanies it. Here is what every line of a peptide COA actually means, and the red flags that should send a lot straight back.',
    readingMin: 9,
    date: '2026-04-12',
    dateLabel: 'April 12, 2026',
    category: 'Methodology',
    keywords: ['peptide COA', 'certificate of analysis', 'HPLC purity', 'peptide content', 'USP 1226'],
  },
  {
    slug: 'hplc-purity-explained',
    title: 'HPLC purity vs peptide content — what researchers should know',
    excerpt: 'A vial that is “99% pure” can still be 30% salt and water. The difference between HPLC purity and net peptide content is the single most misunderstood number on a COA.',
    readingMin: 7,
    date: '2026-04-08',
    dateLabel: 'April 8, 2026',
    category: 'Analytical',
    keywords: ['HPLC purity', 'peptide content', 'AAA amino acid analysis', 'net peptide', 'salt form'],
  },
  {
    slug: 'peptide-storage-guide',
    title: 'Cold-chain not required? Peptide storage and stability basics',
    excerpt: 'Lyophilized peptides are sturdier than most researchers assume in transit, and more fragile than most assume on the bench. A field guide to temperature, light, solvent, and shelf life.',
    readingMin: 8,
    date: '2026-04-02',
    dateLabel: 'April 2, 2026',
    category: 'Handling',
    keywords: ['peptide storage', 'lyophilized peptide stability', 'reconstituted peptide', 'cold chain', 'freeze-thaw'],
  },

  /* ---- Sprint 4 additions: product deep-dives ---- */
  {
    slug: 'bpc-157-research-review',
    title: 'BPC-157: what the research actually shows',
    excerpt: 'A pentadecapeptide derived from a protective gastric protein, BPC-157 is one of the most studied — and most over-marketed — peptides in the research literature. A honest look at the evidence.',
    readingMin: 11,
    date: '2026-04-26',
    dateLabel: 'April 26, 2026',
    category: 'Research Review',
    keywords: ['BPC-157', 'body protection compound', 'pentadecapeptide', 'tendon healing research', 'angiogenesis peptide'],
  },
  {
    slug: 'tirzepatide-research-review',
    title: 'Tirzepatide: dual GIP/GLP-1 agonism in the research literature',
    excerpt: 'Tirzepatide is the first clinically-approved dual incretin agonist. What the preclinical and clinical literature says about receptor selectivity, pharmacokinetics, and the pharmacology that distinguishes it from semaglutide.',
    readingMin: 12,
    date: '2026-04-22',
    dateLabel: 'April 22, 2026',
    category: 'Research Review',
    keywords: ['tirzepatide', 'GIP GLP-1 agonist', 'dual incretin', 'tirzepatide pharmacology', 'SURPASS trials'],
  },
  {
    slug: 'ghk-cu-research-review',
    title: 'GHK-Cu: the copper-binding tripeptide, reviewed',
    excerpt: 'A three-residue peptide with a disproportionate research footprint. What GHK-Cu does at the molecular level, why the copper matters, and where the evidence is solid versus speculative.',
    readingMin: 9,
    date: '2026-04-19',
    dateLabel: 'April 19, 2026',
    category: 'Research Review',
    keywords: ['GHK-Cu', 'copper peptide', 'GHK tripeptide', 'copper peptide research', 'skin remodeling peptide'],
  },

  /* ---- Sprint 4 additions: comparisons ---- */
  {
    slug: 'bpc-157-vs-tb-500',
    title: 'BPC-157 vs TB-500: comparing two repair-axis peptides',
    excerpt: 'They are frequently stacked, frequently confused, and almost never described with any precision. Here is how BPC-157 and TB-500 differ in mechanism, pharmacokinetics, and what the research actually supports.',
    readingMin: 10,
    date: '2026-04-15',
    dateLabel: 'April 15, 2026',
    category: 'Comparison',
    keywords: ['BPC-157 vs TB-500', 'thymosin beta 4', 'peptide comparison', 'repair peptides', 'healing peptide stack'],
  },
  {
    slug: 'semaglutide-vs-tirzepatide',
    title: 'Semaglutide vs tirzepatide: receptor pharmacology and trial outcomes',
    excerpt: 'Both are weekly-dosed incretin analogs. One targets GLP-1 alone; the other adds GIP. The pharmacological and clinical differences, without the hype.',
    readingMin: 11,
    date: '2026-04-10',
    dateLabel: 'April 10, 2026',
    category: 'Comparison',
    keywords: ['semaglutide vs tirzepatide', 'GLP-1 vs dual agonist', 'SURPASS STEP trials', 'incretin comparison', 'Ozempic Mounjaro research'],
  },

  /* ---- Sprint 4 additions: buyer education ---- */
  {
    slug: 'how-to-vet-peptide-supplier',
    title: 'How to vet a peptide supplier: a checklist for research labs',
    excerpt: 'The research-peptide market is unregulated and inconsistently documented. A concrete list of questions, documents, and verifications that separate a credible supplier from a relabeler.',
    readingMin: 8,
    date: '2026-04-05',
    dateLabel: 'April 5, 2026',
    category: 'Buyer Guide',
    keywords: ['peptide supplier', 'vet peptide vendor', 'research peptide sourcing', 'COA verification', 'peptide quality checklist'],
  },
  {
    slug: 'research-use-only-meaning',
    title: 'What "research use only" actually means — and why it matters',
    excerpt: 'The phrase appears on every vial of research peptide sold in the United States. It is not marketing. It is the regulatory boundary that makes the entire research-peptide market possible.',
    readingMin: 6,
    date: '2026-03-30',
    dateLabel: 'March 30, 2026',
    category: 'Regulatory',
    keywords: ['research use only', 'RUO meaning', 'peptide regulation', 'FDA research peptides', 'investigational use'],
  },
  {
    slug: 'peptide-coa-red-flags',
    title: 'Seven red flags on a peptide COA that should stop your order',
    excerpt: 'Most bad COAs are bad in predictable ways. Here are the seven patterns that, once you learn to spot them, will flag a counterfeit or recycled document in under 30 seconds.',
    readingMin: 7,
    date: '2026-03-26',
    dateLabel: 'March 26, 2026',
    category: 'Buyer Guide',
    keywords: ['peptide COA red flags', 'fake COA', 'certificate of analysis fraud', 'spotting bad peptide supplier', 'COA verification'],
  },
];

/* ---------------- Shared primitives ---------------- */
function BlogH2({ id, children }) {
  return <h2 id={id} style={{ fontSize: 26, fontWeight: 800, color: 'var(--fg-brand)', letterSpacing: '-0.01em', margin: '44px 0 14px' }}>{children}</h2>;
}
function BlogH3({ children }) {
  return <h3 style={{ fontSize: 18, fontWeight: 700, color: 'var(--fg-brand)', margin: '28px 0 10px' }}>{children}</h3>;
}
function BlogP({ children }) {
  return <p style={{ fontSize: 16, lineHeight: 1.75, color: 'var(--fg1)', margin: '0 0 16px' }}>{children}</p>;
}
function BlogPull({ children }) {
  return (
    <div style={{ margin: '32px 0', padding: '24px 28px', borderLeft: '3px solid var(--clarion-teal)', background: 'var(--clarion-frost)', borderRadius: '0 10px 10px 0', fontFamily: 'var(--font-serif)', fontStyle: 'italic', fontSize: 20, lineHeight: 1.5, color: 'var(--fg-brand)' }}>
      {children}
    </div>
  );
}
function BlogUL({ children }) {
  return <ul style={{ fontSize: 16, lineHeight: 1.75, color: 'var(--fg1)', margin: '0 0 16px', paddingLeft: 22 }}>{children}</ul>;
}
function BlogTable({ headers, rows }) {
  return (
    <div style={{ overflow: 'auto', margin: '20px 0 28px', border: '1px solid var(--border-strong)', borderRadius: 10 }}>
      <table style={{ width: '100%', borderCollapse: 'collapse', fontSize: 13 }}>
        <thead style={{ background: 'var(--clarion-frost)' }}>
          <tr>{headers.map(h => (
            <th key={h} style={{ textAlign: 'left', padding: '12px 14px', fontFamily: 'var(--font-mono)', fontSize: 10, letterSpacing: '.1em', color: 'var(--fg-accent)', borderBottom: '1px solid var(--border-strong)' }}>{h}</th>
          ))}</tr>
        </thead>
        <tbody>{rows.map((r, i) => (
          <tr key={i} style={{ background: i % 2 ? 'var(--clarion-surface)' : '#fff' }}>
            {r.map((c, j) => <td key={j} style={{ padding: '12px 14px', borderBottom: '1px solid var(--border)', color: 'var(--fg1)', verticalAlign: 'top' }}>{c}</td>)}
          </tr>
        ))}</tbody>
      </table>
    </div>
  );
}
function BlogCallout({ children, tone = 'info' }) {
  const styles = tone === 'warn'
    ? { bg: 'var(--warn-bg)', br: 'var(--warn-border)', fg: 'var(--warn-fg)' }
    : { bg: '#F0F7F4', br: 'var(--border-strong)', fg: 'var(--fg-brand)' };
  return (
    <div style={{ margin: '24px 0', padding: '16px 20px', background: styles.bg, border: `1px solid ${styles.br}`, borderRadius: 10, fontSize: 14, lineHeight: 1.65, color: styles.fg }}>
      {children}
    </div>
  );
}

/* ---------------- BODIES ----------------
   BLOG_BODIES is attached to window so BlogPosts2.jsx (loaded after) can
   extend it with additional article bodies. Keep the registration order:
   Blog.jsx → BlogPosts2.jsx → seo.js article-JSON-LD retry picks them all up.
*/
window.BLOG_BODIES = window.BLOG_BODIES || {};
const BLOG_BODIES = window.BLOG_BODIES;
Object.assign(BLOG_BODIES, {
  'how-to-read-a-peptide-coa': () => (
    <>
      <BlogP>
        A Certificate of Analysis is the only piece of evidence a researcher has that the powder in the vial is actually the compound they ordered. Everything else — the label, the brand, the price — is marketing. The COA is the chemistry.
      </BlogP>
      <BlogP>
        And yet most peptide COAs in circulation are either incomplete, photocopied from an older lot, or generated by the supplier themselves without independent verification. Reading one critically is a researcher's first line of defense.
      </BlogP>

      <BlogH2 id="anatomy">The anatomy of a real COA</BlogH2>
      <BlogP>A release-grade Certificate of Analysis should contain, at minimum, the following sections:</BlogP>
      <BlogUL>
        <li><strong>Product identifiers:</strong> name, molecular formula, molecular mass, sequence, CAS number if applicable.</li>
        <li><strong>Lot identifiers:</strong> lot number, date of manufacture, expiry, retest date.</li>
        <li><strong>Specifications and results:</strong> side-by-side table of acceptance criteria and measured values for each assay.</li>
        <li><strong>Analytical methods:</strong> reference to the SOP or pharmacopeia method used for each assay (e.g., USP &lt;1226&gt;).</li>
        <li><strong>Release signature:</strong> named QC chemist and QA approver, with date.</li>
        <li><strong>Chromatograms and spectra:</strong> the actual HPLC trace and mass-spec spectrum for that lot.</li>
      </BlogUL>
      <BlogP>
        If any of those sections is missing, the document is a marketing sheet, not a COA.
      </BlogP>

      <BlogPull>
        A COA without a chromatogram is like a financial audit without a balance sheet. You are being asked to trust a number with no underlying work shown.
      </BlogPull>

      <BlogH2 id="line-by-line">Line by line</BlogH2>
      <BlogH3>Identity (MS or HPLC retention)</BlogH3>
      <BlogP>
        Identity confirms that the compound is what the label says it is. For peptides, this is usually done by mass spectrometry (matching the observed molecular mass to the theoretical, typically within 1 Da for peptides under 5 kDa) or by comparing HPLC retention time to a reference standard. A pass mark here is binary — it either is or isn't the right compound.
      </BlogP>

      <BlogH3>Purity (HPLC-UV, %)</BlogH3>
      <BlogP>
        Purity is the percentage of the total peak area in the HPLC chromatogram that belongs to the main peak. A research-grade specification is typically ≥ 98.0% or ≥ 99.0%, with individual impurity peaks each below 0.5%. A reputable COA will disclose <em>both</em> the main-peak purity and the individual impurity profile, not just the headline number.
      </BlogP>

      <BlogH3>Net peptide content (AAA, %)</BlogH3>
      <BlogP>
        This is the percentage of the dry powder that is actually the peptide molecule, as opposed to counter-ions (acetate, TFA), residual solvent, and adsorbed water. It is measured by amino acid analysis (AAA). A typical acceptance is ≥ 85%. This is the number that tells you how much peptide you will actually dissolve when you weigh out 1 mg.
      </BlogP>
      <BlogCallout>
        <strong>Do not confuse purity with content.</strong> A 99% pure peptide can be 75% net peptide by mass. The rest is salt and water. We cover this in detail in <a href="#" onClick={(e)=>{e.preventDefault(); window.__go && window.__go('blog','hplc-purity-explained');}}>HPLC purity vs peptide content</a>.
      </BlogCallout>

      <BlogH3>Water content (Karl Fischer, %)</BlogH3>
      <BlogP>
        Lyophilized peptides adsorb water aggressively. Karl Fischer coulometric titration quantifies that water directly. A typical acceptance is 2–6%. Values above 8% suggest incomplete lyophilization or a breached vial.
      </BlogP>

      <BlogH3>Counter-ion content (acetate or TFA, %)</BlogH3>
      <BlogP>
        Most peptides ship as the acetate or TFA salt. Acetate is preferred for most research applications. Counter-ion percentage, measured by ion chromatography, typically runs 6–10% for acetate salts and 2–5% for TFA salts. It is not a contamination — it is part of the molecule's salt form — but it counts against net peptide content.
      </BlogP>

      <BlogH3>Sterility &amp; endotoxin</BlogH3>
      <BlogP>
        Sterility is tested by inoculating fluid thioglycollate medium and soybean-casein digest broth with a sample and observing for 14 days. Endotoxin is tested by the LAL (Limulus amoebocyte lysate) gel-clot or kinetic-chromogenic assay, with a typical acceptance of &lt; 0.5 EU/mg. Both tests are required for any peptide intended for cell culture or injectable animal research.
      </BlogP>

      <BlogH2 id="red-flags">Five red flags on a peptide COA</BlogH2>
      <BlogUL>
        <li><strong>1. No chromatogram.</strong> If the document reports "99% by HPLC" but does not show the trace, the number is unverifiable.</li>
        <li><strong>2. Lot number that does not match the vial.</strong> Every physical vial should carry a lot number that appears on the COA. If they don't match, the COA is borrowed from a different batch.</li>
        <li><strong>3. Identical acceptance values and measured values.</strong> Real measurements have decimal places. "Purity: ≥99%, Result: 99%" with no further precision is likely fabricated.</li>
        <li><strong>4. Missing net peptide content.</strong> Suppliers who omit AAA are often selling on the purity number only — which makes the material look stronger by mass than it is.</li>
        <li><strong>5. No signature or no retest date.</strong> An unsigned COA has no accountability. A COA without a retest date gives no basis for evaluating stability.</li>
      </BlogUL>

      <BlogH2 id="what-to-archive">What to archive</BlogH2>
      <BlogP>
        For any lot that enters your lab, keep the following together as a traceable package: the vial photograph, the COA PDF, the shipping label, and a bench note with the date of receipt and the storage location. If an experiment two years from now produces an anomaly, this archive is what lets you trace backward.
      </BlogP>

      <BlogCallout tone="warn">
        <strong>Research use only.</strong> The COA confirms what is in the vial. It does not authorize any specific use. All Clarion peptides are supplied for laboratory research and are not intended for human or veterinary diagnostic or therapeutic use.
      </BlogCallout>
    </>
  ),

  'hplc-purity-explained': () => (
    <>
      <BlogP>
        Two numbers on a peptide COA describe how much of the vial is "the peptide": HPLC purity and net peptide content. They are not interchangeable, they are not correlated in the way most labs assume, and misreading one for the other is the most common dosing error in in-vitro peptide research.
      </BlogP>

      <BlogH2 id="definitions">The definitions, precisely</BlogH2>
      <BlogP>
        <strong>HPLC purity</strong> is a ratio of chromatographic peak areas. It measures how much of the peptide material in the vial is the target sequence, as opposed to related impurities — truncated sequences, deletion products, oxidation products, diastereomers. It says nothing about how much of the solid powder is peptide at all.
      </BlogP>
      <BlogP>
        <strong>Net peptide content</strong> is a ratio of masses. It measures how much of the dry powder is the peptide molecule itself, as opposed to counter-ions, bound water, and residual solvent. It is determined by amino acid analysis (AAA) after acid hydrolysis.
      </BlogP>

      <BlogPull>
        Purity is a question about quality. Content is a question about quantity. A vial can be excellent by one and mediocre by the other.
      </BlogPull>

      <BlogH2 id="worked-example">A worked example</BlogH2>
      <BlogP>
        Suppose you weigh out 1 mg of a lyophilized peptide powder with the following COA:
      </BlogP>
      <BlogTable
        headers={['Assay', 'Result', 'Meaning']}
        rows={[
          ['HPLC purity', '99.2%', '99.2% of the peptide in the vial is the target sequence'],
          ['Peptide content (AAA)', '78%', '78% of the powder mass is peptide; 22% is salt + water'],
          ['Water (KF)', '4.5%', '4.5% of the mass is adsorbed water'],
          ['Acetate', '8.2%', '8.2% of the mass is the acetate counter-ion'],
          ['Residual (trace)', '9.3%', 'TFA, solvents, etc. — accounts for the remainder'],
        ]}
      />
      <BlogP>
        A 1 mg weigh-out delivers <strong>780 μg of peptide</strong>, not 1 mg. If your assay was calibrated assuming 1 mg of peptide per mg of powder, every concentration you calculated is 22% too high.
      </BlogP>

      <BlogH2 id="why-it-matters">Why it matters for dosing</BlogH2>
      <BlogP>
        For receptor-binding assays, EC50 and IC50 values are concentration-dependent. A 22% mass discrepancy shifts an EC50 curve by roughly 0.1 log units on the x-axis — which is often the difference between "this compound is more potent than the reference" and "this compound is equipotent." In comparative pharmacology, ignoring peptide content produces a systematic bias in every number you report.
      </BlogP>

      <BlogH2 id="salt-forms">Why the salt is there</BlogH2>
      <BlogP>
        Most synthetic peptides are purified by reversed-phase HPLC, which uses trifluoroacetic acid (TFA) as a mobile-phase modifier. At the end of purification, the peptide is in its TFA salt form. Many suppliers then exchange the TFA counter-ion for acetate — which is better tolerated in cell culture — by a second ion-exchange step. Either way, you are buying a salt, not a free peptide, and the counter-ion has real mass.
      </BlogP>
      <BlogTable
        headers={['Salt form', 'Typical counter-ion %', 'Notes']}
        rows={[
          ['Acetate', '6–10%', 'Preferred for cell culture. Standard for most research peptides.'],
          ['TFA', '2–5%', 'Default after HPLC purification. Can inhibit some enzymatic assays at high concentrations.'],
          ['HCl', '3–6%', 'Less common; used for small peptides.'],
          ['Free base', '0%', 'Requires additional lyophilization step; rare in commercial research supply.'],
        ]}
      />

      <BlogH2 id="how-to-correct">How to correct your calculations</BlogH2>
      <BlogP>The adjustment is straightforward. If your COA reports 78% peptide content and you want a 100 μM stock solution of a 1000 Da peptide:</BlogP>
      <BlogUL>
        <li>Target peptide mass for 1 mL of 100 μM: 100 μg.</li>
        <li>Required powder mass: 100 μg ÷ 0.78 = <strong>128 μg of powder</strong>.</li>
        <li>Not 100 μg.</li>
      </BlogUL>
      <BlogCallout>
        If you dose downstream by the stock concentration, this correction compounds through the entire experiment. A single careful adjustment at the stock-prep stage is worth more than a dozen downstream caveats in the discussion section.
      </BlogCallout>

      <BlogH2 id="checklist">A quick checklist</BlogH2>
      <BlogUL>
        <li>Is HPLC purity on the COA? (Should be ≥ 98% for research-grade.)</li>
        <li>Is net peptide content on the COA? (Should be ≥ 85%; ≥ 90% is excellent.)</li>
        <li>Does the counter-ion match what your assay tolerates? (Acetate for cell culture; TFA acceptable for most analytical work.)</li>
        <li>Did you correct your weigh-out for peptide content when preparing stock solutions?</li>
      </BlogUL>
      <BlogP>
        If the COA you are holding does not report peptide content, the honest answer is that you cannot calculate accurate concentrations from it. Request the missing data or consider a different lot.
      </BlogP>
    </>
  ),

  'peptide-storage-guide': () => (
    <>
      <BlogP>
        A recurring question from new labs: does this peptide need to ship on dry ice? The short answer, for the vast majority of lyophilized research peptides, is no. The longer answer is that the real stability risk is not in transit — it is on the bench, after reconstitution.
      </BlogP>

      <BlogH2 id="lyophilized">Lyophilized peptides in transit</BlogH2>
      <BlogP>
        A properly lyophilized peptide is a dry powder with less than 5% residual water. Under those conditions, the molecular mobility required for degradation reactions (hydrolysis, oxidation, aggregation) is very low. Industry stability studies consistently show that lyophilized peptides lose less than 0.5% purity over a 30-day excursion at ambient temperature, and less than 2% at 40°C for the same period.
      </BlogP>
      <BlogP>
        In practice, a lyophilized peptide shipped by overnight carrier in a standard insulated mailer will arrive in the same analytical state it left the lab. Cold-chain shipping for most research peptides is a marketing expense, not a stability requirement.
      </BlogP>
      <BlogPull>
        The stability risk for a lyophilized peptide is not the two-day trip from the manufacturer. It is the fourteen months it may sit half-used in a warm lab drawer.
      </BlogPull>

      <BlogH2 id="long-term">Long-term storage, unreconstituted</BlogH2>
      <BlogP>
        For storage beyond a few weeks, the lyophilized vial should be kept at <strong>−20°C</strong>, ideally in a manual-defrost freezer. Frost-free (auto-defrost) freezers cycle through brief warm periods that induce temperature stress; for long-term archive, manual-defrost is preferred.
      </BlogP>
      <BlogTable
        headers={['Duration', 'Temperature', 'Notes']}
        rows={[
          ['< 4 weeks', '2–8 °C', 'Short-term storage; minimal degradation.'],
          ['1–24 months', '−20 °C', 'Standard long-term storage. Manual-defrost preferred.'],
          ['> 24 months', '−80 °C', 'For archival lots. Thaw fully before opening to avoid condensation.'],
        ]}
      />
      <BlogP>
        Before opening a frozen vial, let it equilibrate to room temperature <em>in its sealed packaging</em> for at least 30 minutes. Opening a cold vial in humid air pulls condensation into the powder, spiking the water content and accelerating hydrolysis.
      </BlogP>

      <BlogH2 id="reconstituted">Reconstituted peptides</BlogH2>
      <BlogP>
        This is where stability gets complicated. Once the peptide is in solution, hydrolysis and oxidation proceed at rates that depend strongly on pH, solvent, and temperature.
      </BlogP>
      <BlogUL>
        <li><strong>Bacteriostatic water (0.9% benzyl alcohol):</strong> typical research shelf life of 28 days at 2–8°C.</li>
        <li><strong>Sterile water for injection:</strong> typical research shelf life of 14 days at 2–8°C.</li>
        <li><strong>0.1% acetic acid in water:</strong> extends shelf life for acid-stable peptides to roughly 30–60 days at 2–8°C.</li>
        <li><strong>Phosphate-buffered saline:</strong> shortest shelf life; use fresh or within 48 hours.</li>
      </BlogUL>
      <BlogCallout>
        These numbers are approximations. Sequence-specific stability varies enormously — peptides containing Met, Cys, Trp, or N-terminal Gln are more labile than aliphatic or aromatic-only sequences. When in doubt, run an HPLC check on the stock at the time of an experiment.
      </BlogCallout>

      <BlogH2 id="freeze-thaw">Freeze-thaw cycles</BlogH2>
      <BlogP>
        A reconstituted peptide aliquot can survive 1–2 freeze-thaw cycles with minimal loss, but degradation accelerates sharply after 3. The practical solution is to aliquot the stock solution immediately after reconstitution into single-use tubes and freeze those aliquots at −20°C. Each experimental use thaws one aliquot once.
      </BlogP>
      <BlogH3>A working aliquot protocol</BlogH3>
      <BlogUL>
        <li>Reconstitute the whole vial in one pass with your chosen solvent.</li>
        <li>Mix gently — no vortexing, no pipette foaming.</li>
        <li>Aliquot into labelled microtubes in volumes sized to a single experiment.</li>
        <li>Freeze upright at −20°C. Record the date, solvent, and concentration on the tube.</li>
        <li>Thaw at 2–8°C, not at room temperature or in a water bath.</li>
      </BlogUL>

      <BlogH2 id="light-and-air">Light and air</BlogH2>
      <BlogP>
        Peptides with Trp, Tyr, Phe, or Met residues are photosensitive and oxidation-sensitive. Store amber vials or wrap clear vials in foil, and backfill with nitrogen or argon if your freezer is frequently opened. For short-term bench use, minimizing headspace in the aliquot tube is usually sufficient.
      </BlogP>

      <BlogH2 id="shelf-life">Shelf life &amp; retest</BlogH2>
      <BlogP>
        Clarion COAs carry a conservative 24-month shelf life from the date of release, stored at −20°C. Beyond that date, the lot is not "expired" in a hard sense — it is due for retest. An HPLC purity check and a mass-spec identity confirmation will tell you whether the lot still meets spec.
      </BlogP>

      <BlogCallout tone="warn">
        <strong>Research use only.</strong> Storage and handling guidance here is provided for laboratory research purposes. It is not intended to support any human or veterinary use.
      </BlogCallout>
    </>
  ),
});
/* Expose primitives so BlogPosts2.jsx can use the same styled components. */
Object.assign(window, { BlogH2, BlogH3, BlogP, BlogPull, BlogUL, BlogTable, BlogCallout });

/* ---------------- Blog index ---------------- */
function BlogIndexPage({ go }) {
  return (
    <section style={{ padding: '72px 0 96px' }}>
      <div className="container-narrow">
        <div className="eyebrow" style={{ marginBottom: 14 }}>FIELD NOTES</div>
        <h1 style={{ fontSize: 48, fontWeight: 900, color: 'var(--fg-brand)', letterSpacing: '-0.02em', margin: '0 0 12px' }}>The Clarion Journal</h1>
        <p style={{ fontSize: 16, color: 'var(--fg1)', lineHeight: 1.65, marginBottom: 48, maxWidth: 580 }}>
          Methodology notes, handling guides, and plain-language explainers — written for researchers by the team that releases the material.
        </p>

        <div style={{ display: 'flex', flexDirection: 'column', borderTop: '1px solid var(--border)' }}>
          {BLOG_POSTS.map(post => (
            <article key={post.slug} onClick={() => go('blog', post.slug)} style={{ padding: '28px 0', borderBottom: '1px solid var(--border)', cursor: 'pointer', transition: 'background .15s' }}
              onMouseEnter={e => e.currentTarget.style.background = 'var(--clarion-frost)'}
              onMouseLeave={e => e.currentTarget.style.background = 'transparent'}>
              <div style={{ display: 'flex', gap: 14, alignItems: 'center', marginBottom: 10, fontFamily: 'var(--font-mono)', fontSize: 10, letterSpacing: '.12em', color: 'var(--fg2)' }}>
                <span style={{ color: 'var(--fg-accent)', fontWeight: 700 }}>{post.category.toUpperCase()}</span>
                <span>·</span>
                <span>{post.dateLabel.toUpperCase()}</span>
                <span>·</span>
                <span>{post.readingMin} MIN READ</span>
              </div>
              <h2 style={{ fontSize: 26, fontWeight: 800, color: 'var(--fg-brand)', letterSpacing: '-0.01em', margin: '0 0 10px' }}>{post.title}</h2>
              <p style={{ fontSize: 15, color: 'var(--fg1)', lineHeight: 1.65, margin: 0, maxWidth: 620 }}>{post.excerpt}</p>
              <div style={{ marginTop: 14, fontFamily: 'var(--font-mono)', fontSize: 11, letterSpacing: '.1em', color: 'var(--clarion-teal)', fontWeight: 600 }}>READ →</div>
            </article>
          ))}
        </div>
      </div>
    </section>
  );
}

/* ---------------- Blog post ---------------- */
function BlogPostPage({ slug, go }) {
  const post = BLOG_POSTS.find(p => p.slug === slug) || BLOG_POSTS[0];
  const Body = BLOG_BODIES[post.slug];

  React.useEffect(() => {
    window.__go = go; // so inline links in body() can jump routes
  }, [go]);

  const related = BLOG_POSTS.filter(p => p.slug !== post.slug);

  return (
    <>
      <section style={{ padding: '32px 0 0' }}>
        <div className="container-narrow">
          <button className="btn-link" onClick={() => go('blog')}>← Field notes</button>
        </div>
      </section>

      <article>
        <header style={{ padding: '32px 0 24px' }}>
          <div className="container-narrow">
            <div style={{ display: 'flex', gap: 14, alignItems: 'center', marginBottom: 18, fontFamily: 'var(--font-mono)', fontSize: 10, letterSpacing: '.12em', color: 'var(--fg2)' }}>
              <span style={{ color: 'var(--fg-accent)', fontWeight: 700 }}>{post.category.toUpperCase()}</span>
              <span>·</span>
              <span>{post.dateLabel.toUpperCase()}</span>
              <span>·</span>
              <span>{post.readingMin} MIN READ</span>
            </div>
            <h1 style={{ fontSize: 44, fontWeight: 900, color: 'var(--fg-brand)', letterSpacing: '-0.02em', margin: '0 0 18px', lineHeight: 1.1 }}>{post.title}</h1>
            <p style={{ fontSize: 18, lineHeight: 1.6, color: 'var(--fg1)', fontFamily: 'var(--font-serif)', fontStyle: 'italic', margin: 0, maxWidth: 640 }}>{post.excerpt}</p>
          </div>
        </header>

        <section style={{ padding: '0 0 64px' }}>
          <div className="container-narrow">
            <Body />
          </div>
        </section>
      </article>

      <section style={{ background: 'var(--clarion-frost)', padding: '56px 0 72px' }}>
        <div className="container-narrow">
          <div className="eyebrow" style={{ marginBottom: 20 }}>KEEP READING</div>
          <div style={{ display: 'grid', gridTemplateColumns: 'repeat(2, 1fr)', gap: 20 }}>
            {related.map(r => (
              <div key={r.slug} onClick={() => go('blog', r.slug)} style={{ background: '#fff', border: '1px solid var(--border-strong)', borderRadius: 12, padding: 22, cursor: 'pointer', transition: 'box-shadow .15s, transform .15s' }}
                onMouseEnter={e => { e.currentTarget.style.boxShadow = 'var(--shadow-md)'; e.currentTarget.style.transform = 'translateY(-2px)'; }}
                onMouseLeave={e => { e.currentTarget.style.boxShadow = 'none'; e.currentTarget.style.transform = 'none'; }}>
                <div style={{ fontFamily: 'var(--font-mono)', fontSize: 10, letterSpacing: '.12em', color: 'var(--fg-accent)', marginBottom: 10, fontWeight: 700 }}>{r.category.toUpperCase()} · {r.readingMin} MIN</div>
                <div style={{ fontSize: 18, fontWeight: 800, color: 'var(--fg-brand)', marginBottom: 8, letterSpacing: '-0.01em' }}>{r.title}</div>
                <div style={{ fontSize: 13, color: 'var(--fg1)', lineHeight: 1.55 }}>{r.excerpt.slice(0, 140)}…</div>
              </div>
            ))}
          </div>
        </div>
      </section>
    </>
  );
}

Object.assign(window, { BLOG_POSTS, BlogIndexPage, BlogPostPage });
