/* Shop product page — Vercel-style hero + tabs layout. * Reads window.PRODUCT_SLUG → merges window.PEPTIDE_DB[slug] + window.SHOP_DB[slug]. * Per-peptide accent color from window.PEPTIDE_ACCENTS. * Pulls window.PROTOCOL_DB to derive "Pairs well with" recommendations. */ const slug = window.PRODUCT_SLUG; const peptideData = window.PEPTIDE_DB[slug]; const shopData = (window.SHOP_DB || {})[slug] || {}; const data = { ...peptideData, ...shopData }; if (!peptideData) { document.getElementById("root").innerHTML = '

Product not found

Slug: ' + slug + '

Back to shop
'; } const PRICING_TIERS = [ { qty: 1, label: "1 month", multiplier: 1.0, savings: 0, badge: null }, { qty: 3, label: "3 months", multiplier: 2.7, savings: 10, badge: "SAVE 10%" }, { qty: 6, label: "6 months", multiplier: 5.1, savings: 15, badge: "BEST VALUE" }, ]; const SLUG_TO_NAME = { "sermorelin": "Sermorelin", "nad-plus": "NAD+", "bpc-157": "BPC-157", "ipamorelin": "Ipamorelin", "ghk-cu": "GHK-Cu", "glutathione": "Glutathione", "selank": "Selank", "dsip": "DSIP", "b12-mic": "B12 / MIC", "cjc-1295": "CJC-1295", }; const NAME_TO_SLUG = Object.fromEntries(Object.entries(SLUG_TO_NAME).map(([k, v]) => [v, k])); // Derive "pairs well with" from PROTOCOL_DB: // any peptide that appears alongside this one in any protocol, ranked by frequency. function getPairings(currentSlug) { const protocols = window.PROTOCOL_DB || {}; const counts = {}; const protocolNames = {}; Object.values(protocols).forEach(p => { const slugs = (p.stack || []).map(name => NAME_TO_SLUG[name]).filter(Boolean); if (!slugs.includes(currentSlug)) return; slugs.forEach(s => { if (s === currentSlug) return; counts[s] = (counts[s] || 0) + 1; protocolNames[s] = [...(protocolNames[s] || []), p.name]; }); }); return Object.entries(counts) .sort((a, b) => b[1] - a[1]) .slice(0, 3) .map(([s, n]) => ({ slug: s, name: SLUG_TO_NAME[s], count: n, protocols: protocolNames[s] })); } /* ============ STAR ICON ============ */ const StarIcon = ({ size = 14, color = "currentColor" }) => ( ); /* ============ HERO ============ */ const Hero = ({ d, accent }) => { const [tier, setTier] = React.useState(0); const [subscribe, setSubscribe] = React.useState(true); const [view, setView] = React.useState(0); const opt = PRICING_TIERS[tier]; const baseTotal = Math.round(d.price * opt.multiplier); const total = subscribe ? Math.round(baseTotal * 0.85) : baseTotal; const perMonth = Math.round(total / opt.qty); // Per-product palette (real product photo on colored backdrop) — pulled from brand.jsx PRODUCT_PALETTES const pal = (window.PRODUCT_PALETTES || {})[d.name] || {}; // 3 thumbnail variants — same vial photo, slightly different backdrops const stageVariants = [ { bg: pal.bg, label: "★ BATCH 26-A15" }, { bg: pal.cap || pal.bg, label: "WITH CARTON" }, { bg: "#1a1a1a", label: "LYO · STERILE", dark: true }, ]; const v = stageVariants[view]; return (
{/* Breadcrumb */}
SHOP / {d.name}
{/* LEFT: real product shot */}
{v.label}
{`${d.name} {/* Color-tinted overlay matching cap so each peptide reads visually distinct */}
{d.name}
Purity
99.6%
{/* Thumbs */}
{stageVariants.map((vv, i) => ( ))}
{/* RIGHT: buy box */}
★ MOST POPULAR RX {(d.class_label || "").split("(")[0].trim().toUpperCase()}

{d.name}

{d.class_label}

{d.hero_subtitle || d.tagline}

{[1,2,3,4,5].map(i => )}
4.9 {(1200 + (d.price * 7)).toLocaleString()} verified reviews

{d.one_liner}

{/* Pricing tier picker */}
How long you'll order
{PRICING_TIERS.map((o, i) => { const t = subscribe ? Math.round(d.price * o.multiplier * 0.85) : Math.round(d.price * o.multiplier); const pm = Math.round(t / o.qty); return ( ); })}
{/* Subscribe banner */} {/* Price + CTA */}
${perMonth}/mo {subscribe && ${Math.round(d.price * opt.multiplier / opt.qty)}}
{(d.dose_ladder?.[0]?.range || "").replace(/^Start:\s*/, "")} · per shipment
Start consultation → First, explain it to me
A real U.S. clinician reviews your medical history before anything ships. 15-min online consult. From a 503A licensed pharmacy in 48 hours after approval.
); }; /* ============ TABS ============ */ const Tabs = ({ d, accent }) => { const [tab, setTab] = React.useState("what"); const tabs = [ { id: "what", label: "What it does" }, { id: "how", label: "How you use it" }, { id: "pairs", label: "Pairs well with" }, { id: "science", label: "The science" }, { id: "faq", label: "Questions" }, ]; return (
{tabs.map(t => ( ))}
{tab === "what" && } {tab === "how" && } {tab === "pairs" && } {tab === "science" && } {tab === "faq" && }
); }; /* ───────────────────────── WHAT IT DOES ───────────────────────── */ const WhatTab = ({ d, accent }) => { // Split each indication on em-dash into title + desc; benefits cap at 4 const benefits = (d.indications || []).slice(0, 4).map(it => { const parts = it.split(/—|–|-\s/); return parts.length > 1 ? { title: parts[0].trim(), desc: parts.slice(1).join(" — ").trim() } : { title: it, desc: "" }; }); const ICONS = ["✿", "❋", "★", "▲"]; return (
★ WHAT IT DOES

It's not a drug — it's a signal your body forgot how to send.

{d.mechanism}

{d.the_promise && (
★ WHAT TO EXPECT

{d.the_promise}

)}
{benefits.map((b, i) => (
{ICONS[i % ICONS.length]}
{b.title}
{b.desc &&
{b.desc}
}
))}
); }; const PathwayDiagram = ({ d, accent }) => { const Glyph = window.PEPTIDE_GLYPH; const outcomes = (d.indications || []).slice(0, 3).map(it => { const t = it.split(/—|–|-\s/)[0].trim(); return t.length > 28 ? t.slice(0, 26) + "…" : t; }); return (
★ WHAT {d.name.toUpperCase()} DOES IN YOUR BODY
{Glyph && }
{d.name}
{(d.class_label || "").split("(")[0].trim()}
{outcomes.map((o, i) => (
{String(i + 1).padStart(2, "0")}
{o}
))}
Average outcomes from {d.evidence?.length ? `${d.evidence.length}+ peer-reviewed studies` : "decades of clinical research"}.
); }; /* ───────────────────────── HOW YOU USE IT ───────────────────────── */ const HowTab = ({ d, accent }) => { const steps = d.how_you_use_it || (d.dose_ladder || []).map(dose => ({ step: dose.range, note: dose.note })); return (
★ HOW YOU USE IT

Simple, daily, no guesswork.

Your prescriber sets the exact dose for you. The numbers below are typical starting points.

{steps.map((s, i) => (
{String(i + 1).padStart(2, "0")}
{s.step || s.range}
{s.note}
))}
{d.whats_in_the_box && (
★ WHAT SHIPS IN THE BOX
{d.whats_in_the_box.map((b, i) => (
{b.item}
{b.note}
))}
)}
); }; const ShopTimeline = ({ d, accent }) => (
★ WHAT TO EXPECT

Week by week.

{d.timeline.map((r, i) => (
{r.wk}
{i < d.timeline.length - 1 &&
}
{r.what}
))}
); /* ───────────────────────── PAIRS WELL WITH ───────────────────────── */ const PairsTab = ({ d, accent }) => { const pairs = getPairings(d.slug); const PALETTES = window.PRODUCT_PALETTES || {}; const ACCENTS = window.PEPTIDE_ACCENTS || {}; return (
★ PAIRS WELL WITH

Want to go further? These work alongside {d.name}.

You don't need them — {d.name} does plenty on its own. These are the most common stack-mates we prescribe and what they add.

{pairs.length === 0 ? (

{d.name} stands alone — your prescriber will add things based on your goals from the BioReveal.

Start the BioReveal →
) : (
{pairs.map(p => { const pAccent = ACCENTS[p.slug] || "#6b6b6b"; const pData = window.PEPTIDE_DB[p.slug]; const pPal = PALETTES[p.name] || {}; const inProtocols = p.protocols.length; const matchPct = Math.min(96, 70 + p.count * 8); return (
{`${p.name}
{matchPct}% match
{(pData?.class_label || "").split("(")[0].trim()}

{p.name}

{pData?.tagline || pData?.one_liner?.split(".")[0] + "."}

Stacked in {inProtocols} protocol{inProtocols === 1 ? "" : "s"}
${pData?.price}/mo View →
); })}
)}
); }; /* ───────────────────────── THE SCIENCE ───────────────────────── */ const ScienceTab = ({ d, accent }) => { const stats = [ { v: `${d.evidence?.length || 0}+`, l: "Cited studies" }, { v: (d.fda_status || "").match(/\d{4}/)?.[0] || "—", l: "Year established" }, { v: d.half_life ? d.half_life.split(/[\s—]/)[0] : "—", l: "Half-life" }, { v: "99.6%", l: "Avg lot purity" }, ]; return (
★ THE SCIENCE

For when you want the receipts.

{d.fda_status}

{stats.map(s => (
{s.v}
{s.l}
))}
{(d.evidence || []).map((e, i) => (
{String(i + 1).padStart(2, "0")}
{e.cite}
{e.note}
))}
); }; /* ───────────────────────── FAQ ───────────────────────── */ const FAQItem = ({ q, a, accent, initialOpen }) => { const [open, setOpen] = React.useState(initialOpen); return (
{open &&
{a}
}
); }; const FAQTab = ({ d, accent }) => { const faqs = d.faq || peptideData?.faq || []; return (
★ QUESTIONS

The ones we get most.

{faqs.map((f, i) => ( ))}
); }; /* ───────────────────────── REVIEW (if present) ───────────────────────── */ const ReviewSection = ({ d, accent }) => { if (!d.review) return null; return (
{[1,2,3,4,5].map(i => )}

"{d.review.quote}"

— {d.review.name}, {d.review.age} · {d.review.location}
); }; /* ───────────────────────── FINAL CTA ───────────────────────── */ const FinalCTA = ({ d, accent }) => (
★ NOT SURE YET?

Is {d.name}
right for you?

Take the 4-minute BioReveal. Tell us what you want to fix. We'll tell you whether {d.name} is the right starting point — or point you to a different peptide that fits better.

); /* ───────────────────────── PAGE ───────────────────────── */ function ProductPage() { const d = data; const accent = (window.PEPTIDE_ACCENTS || {})[d.slug] || "#6b6b6b"; return (
); } ReactDOM.createRoot(document.getElementById("root")).render();