/* ---------------------------------------------------------------------------
 * Product page — the app-owned stylesheet.
 *
 * Not vendored, so `npm run fetch:live` cannot overwrite it, and it is linked
 * AFTER the vendored product stylesheet (verified on the served document:
 * live/product.css `data-precedence="live"` then app/pdp.css `="app"`), so an
 * equal-specificity rule here wins on source order.
 *
 * ═══ WHY THIS FILE GREW ═══════════════════════════════════════════════════
 *
 * It used to hold ONE declaration: the fix for the Description tab's spec list,
 * which inherited the site's LIGHT-theme body ink (#374151) onto a dark panel
 * and measured 1.76:1. Then the three-tab strip was removed and its contents
 * were rehomed — the lead sentence into the Molecular Profile card, the
 * compliance statements into a new RUO panel.
 *
 * ⚠️  THE DEFECT MOVED WITH THE CONTENT. Neither destination had a colour rule,
 *     so both landed back on that same #374151. Measured on the deployed page,
 *     2026-09-03, before this file was extended:
 *
 *       .vsc-compound-blurb          rgb(55,65,81) on the card   1.32:1
 *       .vsc-compound-applications   rgb(55,65,81) on the card   1.32:1
 *       .vsc-pdp-ruo-p               rgb(55,65,81) on #0F1620    1.76:1
 *       .vsc-pdp-ruo-head            rgb(55,65,81) on #0F1620    1.76:1
 *
 *     So the RUO panel — a compliance surface, and the ONLY place the FDA
 *     statement appears on 46 of 60 product pages — was rendering at a ratio
 *     where the text is present in the DOM and effectively unreadable on
 *     screen, full-bleed at 1376px with no panel and no spacing. That is worse
 *     than the tab strip it replaced, which at least had a colour rule.
 *
 * The classes `.vsc-compound-blurb`, `.vsc-compound-applications`,
 * `.vsc-pdp-ruo*` and `.vsc-pdp-pay*` do not exist in the vendored stylesheet
 * at all — grepped, zero hits. They are this build's own markup, so this file
 * is where they get their only styling. Nothing below overrides a live rule;
 * it dresses markup that had none.
 *
 * ═══ THE INK VALUES ARE THE SITE'S OWN, NOT NEW ONES ══════════════════════
 *
 *   rgba(255,255,255,0.70)  body ink on a panel      — what .vsc-tab-content p
 *                                                      and .vsc-pdp-trust-item
 *                                                      already use
 *   rgba(255,255,255,0.82)  RUO ink                  — what .vsc-ruo-banner p
 *                                                      uses site-wide
 *   #7DD3FC                 cyan TYPE on dark        — #0EA5E9 measures 4.41:1
 *                                                      at small sizes and fails
 *                                                      AA; this is the
 *                                                      documented pair
 *   #FFFFFF                 headings
 *
 * Panel chrome (background rgba(255,255,255,0.05), border rgba(255,255,255,
 * 0.10), radius 20px) is copied from `.vsc-pdp-trust` / `.vsc-compound-card`
 * so the new surfaces are the same object as the ones already on the page.
 * ------------------------------------------------------------------------- */


/* ── 1. FOSSIL: the original one-line fix ────────────────────────────────────
 * The three-tab strip no longer renders, so this matches nothing today. It is
 * kept, not deleted: `.vsc-tab-content` still exists in the vendored stylesheet
 * and a rollback of PdpDetail.tsx would put the defect straight back. It costs
 * one selector. See the block above for where the same defect went instead. */
html.vsc-dark body:not(.home) .vsc-pdp-tabs .vsc-tab-content {
  color: rgba(255, 255, 255, 0.70);
}


/* ── 2. The prose that moved into the Molecular Profile card ─────────────────
 * `leadHtml()` (the Description tab's own lead sentence) and `researchHtml()`
 * (the per-product half of the Research Context tab). Both arrive as markup,
 * so the inner <p> and <strong> are targeted too rather than relying on
 * inheritance alone — a captured run can nest either. */
.vsc-compound-blurb,
.vsc-compound-applications {
  font-size: 14px;
  line-height: 1.7;
  color: var(--text-muted);
  margin: 0 0 14px;
}
.vsc-compound-applications > p { margin: 0 0 10px; }
.vsc-compound-applications > p:last-child { margin-bottom: 0; }
.vsc-compound-applications strong { font-weight: 700; color: var(--midnight); }

html.vsc-dark body:not(.home) .vsc-compound-blurb,
html.vsc-dark body:not(.home) .vsc-compound-applications,
html.vsc-dark body:not(.home) .vsc-compound-applications p {
  color: rgba(255, 255, 255, 0.70) !important;
}
html.vsc-dark body:not(.home) .vsc-compound-applications strong,
html.vsc-dark body:not(.home) .vsc-compound-blurb strong {
  color: #FFFFFF !important;
}


/* ── 3. The research-use-only panel ──────────────────────────────────────────
 * Contained to the same 1280px column as `.vsc-compound-info` and
 * `.vsc-sources` above it, so it stops running full-bleed past the content it
 * belongs to. */
.vsc-pdp-ruo {
  max-width: 1280px;
  margin: 0 auto;
  /* 44px, not 64px — see "THE GAP ABOVE RELATED RESEARCH COMPOUNDS" at 7n.
     44 is the padding `.vsc-compound-info` and `.vsc-sources` already use on
     this page at this width, so the panel closes on the page's own rhythm. */
  padding: 0 0 44px;
}
/* A product whose record the runtime RUO gate withheld renders NO compound and
 * NO sources section, so the panel becomes the first thing after the buy box
 * and needs its own separation. This sibling selector fires only in that case;
 * with the sections present they already supply the rule and the 60px. */
.vsc-product-layout + .vsc-pdp-ruo {
  padding-top: 56px;
  border-top: 1px solid var(--border);
}
.vsc-pdp-ruo-inner {
  /* An ink on the CONTAINER, not only on the paragraphs. Everything inside
     sets its own colour today, so this changes nothing on screen — it exists
     so that a sentence added straight into this panel tomorrow inherits a
     readable colour instead of falling back to the light-theme body ink,
     which is exactly how this surface shipped at 1.76:1. */
  color: var(--text-muted);
  background: var(--ivory);
  border: 1px solid var(--border);
  border-radius: 20px;
  padding: 26px 30px;
}
.vsc-pdp-ruo-head {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 1.5px;
  text-transform: uppercase;
  color: var(--vsc-cyan);
  margin-bottom: 14px;
}
.vsc-pdp-ruo-head svg { flex: 0 0 auto; }
.vsc-pdp-ruo-p {
  margin: 0 0 10px;
  font-size: 13px;
  line-height: 1.7;
  color: var(--text-muted);
  max-width: 104ch;
}
.vsc-pdp-ruo-p:last-child { margin-bottom: 0; }

html.vsc-dark body:not(.home) .vsc-pdp-ruo-inner {
  color: rgba(255, 255, 255, 0.82) !important;
  background: rgba(255, 255, 255, 0.05) !important;
  border-color: rgba(255, 255, 255, 0.10) !important;
}
html.vsc-dark body:not(.home) .vsc-pdp-ruo-head { color: #7DD3FC !important; }
html.vsc-dark body:not(.home) .vsc-pdp-ruo-p { color: rgba(255, 255, 255, 0.82) !important; }
html.vsc-dark body:not(.home) .vsc-product-layout + .vsc-pdp-ruo {
  border-top-color: rgba(255, 255, 255, 0.10) !important;
}


/* ── 4. Payment reassurance, under the trust panel ───────────────────────────
 * Same panel chrome as `.vsc-pdp-trust` directly above it, so the two read as
 * one assurance block — which is the shape the owner's reference uses (an
 * assurance list with the accepted marks closing it out).
 *
 * The marks are the four brands the FAQ already publishes, served from the
 * vendored WooCommerce icon set, same-origin. Each sits on a white chip so a
 * navy mark (Visa) and a light one (Mastercard) read evenly on the dark panel.
 * They are decorative-with-a-name: each <img> carries its brand as alt text. */
.vsc-pdp-pay {
  /* Same defensive ink as the RUO panel above — see the note there. */
  color: var(--text-muted);
  display: flex;
  flex-direction: column;
  gap: 10px;
  background: var(--ivory);
  border: 1px solid var(--border);
  border-radius: 16px;
  padding: 14px 18px;
  margin-top: 10px;
}
.vsc-pdp-pay-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
}
.vsc-pdp-pay-label {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.6px;
  text-transform: uppercase;
  color: var(--midnight);
}
.vsc-pdp-pay-label svg { color: var(--vsc-cyan); flex: 0 0 auto; }
.vsc-pdp-pay-marks {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-shrink: 0;
}
/* ⚠️  (0,2,1), NOT (0,1,1), AND THAT IS LOAD-BEARING.
 *
 * The vendored sheet carries `.woocommerce img, .woocommerce-page img
 * { height:auto; max-width:100% }` — same specificity as a bare
 * `.vsc-pdp-pay-marks img`, so which one wins is decided by SOURCE ORDER.
 *
 * AND THE SOURCE ORDER OF THESE TWO FILES IS NOT STABLE. React orders
 * stylesheet links by precedence group, and the group order depends on which
 * component emits its link first during the render. Measured on the same code:
 *
 *   deployed page   live/product.css  then  app/pdp.css
 *   fresh build     app/pdp.css       then  live/product.css   ← reversed
 *
 * In the second order the WooCommerce reset won and every mark rendered at its
 * intrinsic 750x471, which laid a 3,071px-wide row inside a 326px panel. The
 * extra class takes the decision away from source order entirely.
 *
 * The width/height ATTRIBUTES on the <img> do not save this either: they are
 * presentational hints at specificity zero, so any author rule beats them. */
.vsc-pdp-pay .vsc-pdp-pay-marks img {
  display: block;
  height: 15px;
  width: auto;
  background: #FFFFFF;
  border-radius: 4px;
  padding: 2px 3px;
  box-sizing: content-box;
}
.vsc-pdp-pay-note {
  margin: 0;
  font-size: 12px;
  line-height: 1.55;
  color: var(--text-muted);
}

html.vsc-dark body:not(.home) .vsc-pdp-pay {
  color: rgba(255, 255, 255, 0.70) !important;
  background: rgba(255, 255, 255, 0.05) !important;
  border-color: rgba(255, 255, 255, 0.10) !important;
}
html.vsc-dark body:not(.home) .vsc-pdp-pay-label { color: #FFFFFF !important; }
html.vsc-dark body:not(.home) .vsc-pdp-pay-note { color: rgba(255, 255, 255, 0.70) !important; }


/* ── 5. Narrow widths ───────────────────────────────────────────────────────
 * 640px is the breakpoint the vendored sheet already drops the compound
 * sections to 40px of padding at; the RUO panel follows it rather than
 * inventing a second one. The pay row wraps to two rows so four marks never
 * squeeze the label — measured at 390, where the buy column is 358px. */
@media (max-width: 640px) {
  .vsc-pdp-ruo { padding-bottom: 40px; }
  .vsc-product-layout + .vsc-pdp-ruo { padding-top: 36px; }
  .vsc-pdp-ruo-inner { padding: 20px 18px; border-radius: 16px; }
  .vsc-pdp-ruo-p { font-size: 12.5px; }
  .vsc-pdp-pay-top { flex-wrap: wrap; gap: 10px; }
  .vsc-pdp-pay-marks { gap: 5px; }
}


/* ── 6. THE BUY BOX READS TOP-DOWN AGAIN ────────────────────────────────────
 *
 * Owner review, 2026-09-03: "ADD TO CART · $70 renders as a dim grey ghost
 * that reads DISABLED while the three white bundle cards are the brightest
 * objects on the page."
 *
 * MEASURED before touching anything, on the deployed page at 1440:
 *
 *   .vsc-pdp-cart   (no dose picked)  bg rgba(255,255,255,.12)  ink rgba(255,255,255,.40)
 *   .vsc-pdp-cart   (dose picked)     bg rgb(14,165,233)        ink #FFFFFF
 *   .vsc-bundle-card                  bg rgb(246,250,255)       — the only light object on the page
 *   .vsc-bundle-note                  ink rgb(0,0,0) at 16px    — the LARGEST, DARKEST text on the card
 *
 * ⚠️  THE BUTTON IS NOT BROKEN. Once a dosage is selected it is already the
 *     site cyan with white ink, and it is already the brightest thing in the
 *     column. An earlier pass of this review read it as grey in BOTH states;
 *     that was a stale same-tick `getComputedStyle`, not the page. Repainting
 *     an enabled primary action would have been fixing nothing.
 *
 * So the inversion is real but it is three narrower things, and each is
 * corrected at its own cause rather than by making one control louder:
 *
 *   a. the LOCKED state is unreadable and does not say why it is locked
 *   b. the card's own hierarchy is upside down — its least important line is
 *      its biggest and blackest
 *   c. the enabled button lost the cyan glow the light theme gives it, so at
 *      the moment it becomes the primary action it gains no prominence
 *
 * The white card fill is left ALONE deliberately. `product.css` forces it back
 * to rgb(246,250,255) with !important inside the dark block, directly after a
 * rule that would otherwise have made it rgba(255,255,255,.06) — i.e. somebody
 * decided on purpose that these cards are light islands, matching the owner's
 * Amino Club reference. Overturning that is a design decision, not a defect
 * fix. Note in owner_actions. */

/* (a) The locked state. `:disabled` alone decides which sentence shows, so no
 *     script can leave it saying the wrong thing. 4.6:1 composited on the
 *     rgba(255,255,255,.12) pill — readable, still obviously inactive. */
.vsc-pdp-cart .vsc-pdp-cart-lock { display: none; }
.vsc-pdp-cart:disabled .vsc-pdp-cart-lock,
.vsc-pdp-cart[disabled] .vsc-pdp-cart-lock { display: inline; }
.vsc-pdp-cart:disabled .vsc-pdp-cart-label,
.vsc-pdp-cart[disabled] .vsc-pdp-cart-label { display: none; }
html.vsc-dark body:not(.home) .vsc-pdp-cart:disabled,
html.vsc-dark body:not(.home) .vsc-pdp-cart[disabled] {
  color: rgba(255, 255, 255, 0.78) !important;
}

/* (c) The glow the light theme gives this button, restored on the dark one —
 *     and ONLY when the button can actually be pressed, so "bright" and
 *     "usable" are the same signal. */
html.vsc-dark body:not(.home) .vsc-pdp-cart:not(:disabled) {
  box-shadow: 0 8px 28px rgba(14, 165, 233, 0.38) !important;
}

/* (b) The tier card, top-down: what you buy, what you save, then the money.
 *     `.vsc-bundle-note` had NO rule anywhere — not in the vendored sheet, not
 *     here — so it inherited 16px and the UA's black, which made the smallest
 *     fact on the card its loudest element and is most of why the strip
 *     shouted. Two classes only; the fill, the border and the ribbons are
 *     untouched. */
.vsc-pdp-bundle .vsc-bundle-qty {
  font-size: 15px;
  font-weight: 800;
  letter-spacing: -0.1px;
}
.vsc-pdp-bundle .vsc-bundle-note {
  font-size: 11.5px;
  font-weight: 600;
  line-height: 1.2;
  color: #5B6B80;
  letter-spacing: 0.1px;
}


/* ═══════════════════════════════════════════════════════════════════════════
 * 7. OWNER REVIEW, 2026-09-03 — THE BUY BOX IS TOO TALL, AND TWO NEAR-WHITE
 *    RULES ARE DRAWN ACROSS A DARK PAGE.
 *
 * "Pricing block, dosage selector and the quantity stepper are ALL TOO BIG and
 * make the page too long." Measured on the deployed page, the product page at
 * 390 is 6,614 CSS px tall.
 *
 * Everything below is spacing and type scale on elements that already exist.
 * No element is removed, no colour is invented, and every selector is written
 * at `body.single-product` (0,2,x) or higher, NOT because it needs to beat the
 * vendored sheet on specificity in every case, but because THE SOURCE ORDER OF
 * THESE TWO FILES IS NOT STABLE — this file already records measuring
 * `live/product.css` before and after `app/pdp.css` on the same code. A rule
 * that wins only on order is a rule that loses on the next build.
 * ═══════════════════════════════════════════════════════════════════════════ */

/* ── 7a. THE SECTION LABELS BECOME EYEBROWS ─────────────────────────────────
 * "Dosage", "Quantity" and "Bundle & save" render at 15px/700 in the midnight
 * ink — the same weight and nearly the same size as the product's own
 * sub-headings, so three utility labels compete with the copy around them and
 * each one costs a full line of height.
 *
 * They become the eyebrow this site already uses everywhere else: 11px, 800,
 * uppercase, 0.12em, muted. `.vsc-pdp-category` above them in the same column,
 * `.vsc-pdp-ruo-head` below, `.vsc-compound-card-label`, `.vsc-acard-sizes-head`
 * — all four are already that object. This is the "one copy style site-wide"
 * pass reaching the last three labels that were not. */
body.single-product .vsc-pdp-option-label {
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--text-muted);
  line-height: 1;
}
html.vsc-dark body.single-product .vsc-pdp-option-label {
  color: rgba(255, 255, 255, 0.55) !important;
}

/* ── 7b. THE DOSE CHIPS ─────────────────────────────────────────────────────
 * 11px/22px padding at 14px is a 45px-tall pill for a two-word label. The
 * reference's are noticeably smaller. 44px is the touch-target floor and these
 * are still 40px + the row's own gap, which clears it in practice; on a phone
 * 7f puts the padding back up. */
body.single-product .vsc-pdp-options .vsc-pdp-size {
  padding: 9px 18px;
  font-size: 13.5px;
}

/* ── 7c. THE STEPPER ────────────────────────────────────────────────────────
 * 38px round buttons inside a 4px-padded pill = 46px of height for a control
 * whose value is almost always 1 — and the bundle strip directly beneath it is
 * the thing that actually sets quantity. */
body.single-product .vsc-pdp-qty { padding: 3px; }
body.single-product .vsc-pdp-qty button { width: 32px; height: 32px; font-size: 16px; }
body.single-product .vsc-pdp-qty input { width: 34px; font-size: 14px; }

/* ── 7d. THE PRICE ──────────────────────────────────────────────────────────
 * 30px Inter 700. The reference's is large too, so this is a trim rather than
 * a demotion: it stays the biggest number in the column. */
body.single-product .vsc-pdp-qtyrow .vsc-pdp-price { font-size: 26px; }

/* ── 7e. THE VERTICAL RHYTHM ────────────────────────────────────────────────
 * Four stacked blocks each carrying 18-22px of its own bottom margin. Pulled
 * to a single 14px step so the box reads as one object. */
body.single-product .vsc-pdp-options  { margin-bottom: 14px; gap: 12px; }
body.single-product .vsc-pdp-qtyrow   { margin-bottom: 14px; gap: 12px; }
body.single-product .vsc-pdp-bundle   { margin-bottom: 16px; }
body.single-product .vsc-pdp-actions  { margin-bottom: 14px; }
body.single-product .vsc-pdp-desc     { margin-bottom: 18px; }
body.single-product .vsc-bundle-row   { margin-top: 14px; }

/* ── 7f. THE TIER CARD LOST ITS THIRD LINE ──────────────────────────────────
 * `.vsc-bundle-note` is gone from the markup (PdpPurchase.tsx). The card is now
 * thumbs + "Buy N" + "Save N%", which is the reference's own anatomy, so the
 * padding comes down with it. The `.vsc-bundle-note` rule in section 6 below
 * is left in place deliberately: it costs two selectors and it is what stops
 * the element inheriting 16px black if it is ever restored. */
body.single-product .vsc-bundle-card { padding: 14px 8px 12px; gap: 5px; }
body.single-product .vsc-bundle-thumbs { height: 52px; }

/* ── 7g. 🔴 THE TWO NEAR-WHITE RULES ACROSS A DARK PAGE ─────────────────────
 * THIS IS THE "it has lines and stuff on it" DEFECT, and it is a real one.
 *
 *   .vsc-compound-info { border-top: 1px solid var(--border) }
 *   .vsc-sources       { border-top: 1px solid var(--border) }
 *
 * `--border` is #E5EAF0. Both rules live in the LIGHT half of the vendored
 * stylesheet and NEITHER has a dark-theme override — grepped: zero hits for
 * `.vsc-compound-info` or `.vsc-sources` in the `html.vsc-dark` block. So the
 * product page draws two full-width near-white hairlines on #0F1620, one of
 * them landing directly under the Secure Checkout panel, which is exactly where
 * the owner pointed.
 *
 * The RUO panel immediately below already solved this for its own border
 * (section 3, `rgba(255,255,255,0.10)`), so this is that same value reaching
 * the two surfaces that were missed rather than a new decision. */
html.vsc-dark body:not(.home) .vsc-compound-info,
html.vsc-dark body:not(.home) .vsc-sources {
  border-top-color: rgba(255, 255, 255, 0.10) !important;
}

/* ── 7h. THE SECURE-CHECKOUT PANEL ──────────────────────────────────────────
 * The panel itself was sound; what read as "weird" was the hairline above and
 * the marks row wrapping under its own label at 390. The label and the marks
 * now share one row that never wraps — four 15px marks and a 12px label fit in
 * 358px with room — and the note keeps its own line. */
body.single-product .vsc-pdp-pay { padding: 13px 16px; gap: 8px; }
/* ⚠️  THE LABEL NEVER BREAKS, THE ROW STILL MAY.
   An earlier pass set the row to `flex-wrap: nowrap` to stop the marks
   dropping under their own label. Rendered, that traded one defect for a worse
   one: with nowrap the label is the flex item that gives, so "SECURE CHECKOUT"
   broke across two lines while the marks stayed put. The row keeps the
   vendored sheet's `wrap` — dropping the marks to a second line is a fine
   outcome — and the LABEL is what is protected. */
body.single-product .vsc-pdp-pay-label { letter-spacing: 0.08em; white-space: nowrap; }
body.single-product .vsc-pdp-pay-marks { flex-wrap: nowrap; }

/* ── 7i. THE TRUST PANEL ────────────────────────────────────────────────────
 * Same chrome as the pay panel directly under it, so the pair reads as one
 * assurance block rather than two widgets of different heights. */
body.single-product .vsc-pdp-trust { padding: 14px 16px; gap: 9px 18px; }

/* ── 7j. COMPOUND INFORMATION / SOURCES ─────────────────────────────────────
 * 60px of padding above and below each, a 56px icon tile beside a 36px
 * heading, and a 32px gap under the header. On a phone the heading wraps to two
 * lines beside a tile that is taller than one of them. The reference keeps the
 * icon INLINE with a small eyebrow rather than as a block beside the title. */
body.single-product .vsc-compound-info,
body.single-product .vsc-sources { padding: 44px 0; }
body.single-product .vsc-compound-header { margin-bottom: 24px; gap: 14px; }
body.single-product .vsc-compound-header-icon { width: 44px; height: 44px; border-radius: 13px; }
body.single-product .vsc-compound-card { padding: 24px; }

/* ── 7k. RELATED COMPOUNDS ──────────────────────────────────────────────────
 * The heading carried an inline style — 36px fixed, and a colour that was only
 * ever correct because the light token happens to be white on the dark theme.
 * It is a class now, with the clamp the rest of the site's section headings
 * use, so it actually shrinks at 390.
 *
 * ⚠️  MEASURED, NOT ASSUMED: the clamp decides on DESKTOP only. The vendored
 * mobile block carries `body.single-product .vsc-related .vsc-section-container
 * > h2 { font-size: 22px !important }` (product.css:16575), written for the
 * inline style this markup no longer has. It still matches, it still wins, and
 * 22px is the right size there — so the phone value comes from that rule and
 * the clamp's 24px floor is never reached. Confirmed on the deployed page:
 * 36px at 1440, 22px at 390. The clamp is kept because it is what governs
 * every width between them, and because it removes the hardcoded 36px.
 *
 * THE GAP ABOVE IT WAS THE OWNER'S MOBILE COMPLAINT. `.vsc-pdp-ruo` closes
 * with 64px, `.vsc-related` opens with 56px on a phone and the section before
 * it has already ended — 120px of nothing between the compliance panel and the
 * next heading. Halved on both sides; see 7l. */
body.single-product .vsc-related .vsc-related-h2 {
  font-family: 'Onest', -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
  font-size: clamp(24px, 3.4vw, 36px);
  font-weight: 500;
  letter-spacing: -0.02em;
  line-height: 1.1;
  color: var(--midnight);
  margin: 0 0 28px;
}
html.vsc-dark body:not(.home) .vsc-related .vsc-related-h2 { color: #FFFFFF !important; }

/* The related grid renders `.vsc-acard` now, the same component the shop grid
   does. The vendored `.vsc-related-grid` rule already lays out four columns
   with a 28px gap, which is the shop grid's own geometry, so nothing about the
   track sizing changes — only the thing inside it. */

/* ── 7l. PHONES ─────────────────────────────────────────────────────────────
 * 640px is the breakpoint the vendored sheet already uses for this template. */
@media (max-width: 640px) {
  /* The dose chips get their tap target back: 12px x 2 + a 13.5px line is 44px. */
  body.single-product .vsc-pdp-options .vsc-pdp-size { padding: 12px 18px !important; }

  /* ⚠️  !important HERE AND NOWHERE ELSE IN 7a. The vendored mobile block
     carries `.vsc-pdp-option-label { font-size: 14px !important }`
     (product.css:5688), which beat the desktop rule above on phones only —
     measured on the deployed page: 11px at 1440 and 14px at 390, so the three
     labels became eyebrows on one width and stayed sub-headings on the other.
     One label, one size, both widths. */
  body.single-product .vsc-pdp-option-label { font-size: 11px !important; }

  body.single-product .vsc-pdp-qtyrow .vsc-pdp-price { font-size: 24px !important; }
  body.single-product .vsc-compound-info,
  body.single-product .vsc-sources { padding: 32px 0; }
  /* 🔴 "Compound Information" WRAPPED TO TWO LINES beside its icon.
     Measured at 390: the tile is 38px + a 14px gap = 52px out of a 326px
     column, leaving 274px for a 28px Onest heading that needs about 300.
     The reference (Ascend) prints this header as heading + sub with NO tile at
     all; keeping the tile but paying for it in width is what broke the line.
     Tile to 32px, gap to 10px, heading to 24px -> one line with room, and the
     header block drops from 62px to 30px. "Sources & References" is shorter
     and was already fitting; it follows the same values so the two headers
     stay identical objects. */
  body.single-product .vsc-compound-header { gap: 10px; margin-bottom: 18px; }
  body.single-product .vsc-compound-header-icon { width: 32px; height: 32px; border-radius: 10px; }
  body.single-product .vsc-compound-header-icon svg { width: 17px; height: 17px; }
  body.single-product .vsc-compound-header h2 { font-size: 24px !important; }
  body.single-product .vsc-compound-header p { font-size: 13px; }
  body.single-product .vsc-compound-card { padding: 20px 18px; }

  /* 🔴 THE OWNER'S GAP. 64 + 56 = 120px of empty page between the RUO panel
     and "Related research compounds". */
  body.single-product .vsc-pdp-ruo { padding-bottom: 28px !important; }
  body.single-product .vsc-related { padding: 32px 32px 48px !important; }
  body.single-product .vsc-related .vsc-related-h2 { margin-bottom: 18px; }
}


/* ── 7m. THE LAST TWO 16px PANELS ON THE BUY COLUMN ─────────────────────────
 * `.vsc-pdp-trust` and `.vsc-pdp-pay` are 16px while `.vsc-compound-card` and
 * `.vsc-pdp-ruo-inner` on the same page are 20px — see the measured inventory
 * in components/live/shop-card.css, which moves the shop funnel's stragglers
 * onto the same three values. These are the product page's two. */
body.single-product .vsc-pdp-trust,
body.single-product .vsc-pdp-pay { border-radius: 20px; }


/* ── 8. THE GALLERY IS ONE IMAGE, AND IT FILLS ITS FRAME ────────────────────
 * Owner, 2026-09-04: "get rid of that little box under it and just make that
 * image fill out that whole section so it's really clean ... just the one big
 * image, scaled properly on there, so it just looks really beautiful."
 *
 * The little box was the one-item thumbnail strip; it is gone from the markup
 * (see the note in app/(product)/product/[slug]/page.tsx for what was checked
 * before deleting it). This rule is the "scaled properly" half, and it fixes a
 * defect that is measured, not a matter of taste.
 *
 * ⚠️  THE PRODUCT PHOTO WAS BEING CROPPED. Not letterboxed — cropped. Measured
 *     in a real browser on the deployed page, 2026-09-04, /product/glp3-rt:
 *
 *                        frame (overflow:hidden)   image box       clipped
 *       1440             628.6 x 628.6            628.6 x 786.8   79.1px top
 *                                                                 79.1px bottom
 *       390              326.0 x 326.0            326.0 x 408.1   41.0px top
 *                                                                 41.0px bottom
 *
 *     Identical on tesamorelin, bpc-157-5mg and amino-h20, so it was every
 *     product page at every width, not one bad asset.
 *
 *     THE MECHANISM. The frame is `aspect-ratio: 1/1` in the vendored sheet and
 *     every hero in the catalogue is 4:5 — measured across `imgLarge` plus every
 *     `imgBySku` entry, 117 resolved files: 0.799 (63), 0.800 (53), 0.806 (1).
 *     No square hero exists. `.vsc-gallery-img` declares `height:100%`, but a
 *     percentage height does not resolve against a height the parent only gets
 *     from `aspect-ratio`, so the computed height is the image's own intrinsic
 *     786.844px — taller than the 628.562px frame that clips it. `object-fit:
 *     contain` never got to letterbox anything, because the box it was fitting
 *     into was already the full 4:5. The vial lost its cap and its base, and the
 *     frame's gradient was never visible at all.
 *
 * THE FIX IS `auto`, NOT A NEW RATIO. Dropping the forced square lets the frame
 * take its height from the image, so frame and image become the same rectangle
 * for ANY artwork — nothing clipped, nothing letterboxed. A hard `4/5` was
 * measured first and left 0.6px of clipping at 1440, because the real aspect is
 * 0.79883 rather than 0.800; `auto` measures exactly 0/0 on every product and
 * needs no assumption about what shape the next photograph will be.
 *
 *   after, measured:   1440  frame 628.6 x 786.8 = image box, clipped 0/0
 *                      390   frame 326.0 x 408.1 = image box, clipped 0/0
 *
 * ⚠️  `auto` means the frame has no height of its own, so a hero that failed to
 *     load would collapse it. That cannot ship: `scripts/check-pdp-art.mjs` is a
 *     build gate that fails if ANY product's hero or per-size image does not
 *     resolve to a file on disk — it exists because six bundle pages once shipped
 *     a 400 from the optimizer. If that gate is ever weakened, put a ratio back.
 *
 * THE COLUMN DOES NOT GET TALLER ON DESKTOP. At 1440 the gallery was 793.2px
 * (628.6 frame + 18 margin + 146.6 thumb) and is now 786.8 — six pixels shorter,
 * because removing the strip pays for growing the frame. On the phone, where the
 * strip was already hidden, it goes 326 -> 408.1. That 82px is the price of not
 * slicing the ends off the product, and it buys the big clean image asked for.
 *
 * `background: transparent` on the image: the vendored `background: var(--white)`
 * has no dark-mode override anywhere — grepped, zero hits — so any letterbox
 * would paint white slabs inside a navy frame on a dark page. Measured
 * `rgb(255,255,255)` before, `rgba(0,0,0,0)` after. At 0/0 there is no letterbox
 * to paint, which is exactly why this is worth setting now rather than after
 * some future product ships at a different aspect.
 *
 * (0,2,1) beats the vendored (0,1,0) declarations on specificity and source
 * order; the dark-mode `!important` on this element sets `background` only, and
 * the <=640px `!important` sets `border-radius` only, so neither fights this. */
body.single-product .vsc-gallery-main { aspect-ratio: auto; }
body.single-product .vsc-gallery-img { background: transparent; }


/* ── 7n. THE GAP ABOVE "RELATED RESEARCH COMPOUNDS" ─────────────────────────
 * Owner, 2026-09-04: "there's too big of a gap between the related research
 * compounds, so I want to tighten that up on mobile and on desktop."
 *
 * SAID TWICE. Pass 1 took the boundary from 244/140 to 88/60 and it was still
 * too big, because pass 1 only removed the spacer nobody had FOUND — it never
 * asked what the boundary should be worth.
 *
 * ═══ PASS 1 — THREE SPACERS STACKED ON ONE BOUNDARY ════════════════════════
 *
 * It was never one padding that was too large. Panel bottom to heading top:
 *
 *                        .vsc-pdp-ruo  .vsc-product-detail  .vsc-related
 *                          padding-bot   padding-bottom      padding-top   total
 *     1440 before               64    +        80         +     100      =  244
 *      390 before               28    +        80         +      32      =  140
 *
 * The 80 was the hidden one: `.vsc-product-detail` closes its own section and
 * `.vsc-related` is its NEXT SIBLING, not its child, so the two sections'
 * paddings add on top of the panel's. Unconditional in product.css, therefore
 * paid at every width — which is why the phone still read as too airy after
 * the mobile-only pass at 7l.
 *
 * ═══ PASS 2 — WHAT IS LEFT IS EXACTLY DOUBLE THE BOUNDARY ABOVE IT ═════════
 *
 * Measured on this build, /product/amino-h20/ and /product/glp-3-r/ (identical
 * on both), content edge to content edge:
 *
 *                                                          1440    390
 *     A  buy layout      -> "Compound Information" header     45     33
 *     B  compound cards  -> "Sources & References" header     89     65
 *     C  sources         -> RUO panel                         44     32
 *     D  RUO panel       -> "Related research compounds"      88     60   <- owner
 *
 * The page has ONE section token: 44px desktop, 32px mobile, applied as
 * `padding: 44px 0` on `.vsc-compound-info` and `.vsc-sources`. A boundary is
 * 44 when one side owns the air (A, C) and 88 when both sides do (B).
 *
 * THE RUO PANEL OWNS NO AIR ABOVE ITSELF — `.vsc-pdp-ruo` is `padding: 0 0 44px`
 * at section 3, deliberately, so the panel hugs the sources block it belongs
 * to. All 44px above it comes from `.vsc-sources`. But it was still paying its
 * own 44 BELOW, on top of `.vsc-related`'s 44, so the last card in the
 * compliance stack sat with half the air above it that it had below it and
 * read as orphaned from the stack.
 *
 * Fix: the panel owns no air on either side, and `.vsc-related` is the single
 * owner of the boundary — the same shape as A and C.
 *
 *                        .vsc-pdp-ruo  .vsc-product-detail  .vsc-related
 *     1440 after                 0    +         0         +      44      =   44
 *      390 after                 0    +         0         +      32      =   32
 *
 * Now D == C at both widths, and the panel is symmetric: 44 above, 44 below on
 * desktop; 32 and 32 on the phone. B stays at 88 on purpose — it is the only
 * boundary on the page where both sides are full sections that own their own
 * padding, and nothing about it was complained about.
 *
 * NOT CHANGED, DELIBERATELY: `.vsc-related`'s own padding-top stays 44/32 and
 * keeps the air. Zeroing it instead would have looked identical on this site
 * (dark mode paints `.vsc-related` transparent) and broken in light mode,
 * where the vendored rule gives that section `background: var(--white)` and the
 * heading would sit flush against the top edge of a white band.
 *
 * ⚠️  BOTH RULES ARE GATED ON `.vsc-related` ACTUALLY FOLLOWING. The section is
 *     conditional — `related.length > 0` in the page component — and a product
 *     with no related compounds would otherwise have its compliance panel
 *     sitting flush against the footer. `:has(+ .vsc-related)` is the whole
 *     reason this is two rules instead of a JS class; verified supported and
 *     matching on the rendered page before it was written, and an engine
 *     without `:has()` simply keeps the old spacing rather than breaking.
 *
 * ⚠️  THE `!important` IS LOAD-BEARING AND ONLY HERE. 7l carries
 *     `body.single-product .vsc-pdp-ruo { padding-bottom: 28px !important }`
 *     for the no-related case on a phone; an important declaration can only be
 *     beaten by another important one. This selector is (0,4,1) against that
 *     rule's (0,2,1), so it wins on specificity and the 28px still applies
 *     everywhere this `:has()` does not match. Removing the 28px instead would
 *     put the panel against the footer on those products. */
body.single-product .vsc-product-detail:has(+ .vsc-related) { padding-bottom: 0; }
body.single-product .vsc-product-detail:has(+ .vsc-related) .vsc-pdp-ruo {
  padding-bottom: 0 !important;
}
body.single-product .vsc-related { padding-top: 44px; }


/* ── 8. THE PINNED BUY SHEET — STOP IT SMEARING OVER THE BUY BOX ────────────
 * Owner, mobile: "when you click on the vial it's overlapping with the add
 * button ... clean up how the buttons look, how they overlap on that product
 * page." (tmp/refs/pdp-overlap.png)
 *
 * The pinned bar (`components/live/PdpPurchase.tsx` -> `.vsc-stickybar`,
 * re-parented to <body> by vsc-product.js and shown on load) was painting at
 * `rgba(15,22,32,0.95)` — 95% opaque, so the in-flow eyebrow, H1 and RESEARCH
 * USE ONLY line rendering right under the hero GHOSTED THROUGH it. Two copies
 * of the same title, one faint behind the other, is the "overlap/cramped" the
 * owner saw. Measured on the deployed page: `.vsc-stickybar` background
 * `rgba(15,22,32,0.95)`, and the in-flow `.vsc-pdp-info` top (y=671) sitting
 * one pixel above the bar top (y=704) with the bar covering everything below.
 *
 * TWO THINGS WERE WRONG.
 *
 *   1. TRANSLUCENCY. The bar is a control surface pinned over content, not a
 *      scrim — it must be OPAQUE so nothing reads through it. Set to a solid
 *      #0F1620 (the page's own dark panel value), given a rounded top, a top
 *      hairline and an upward shadow so it reads as a distinct sheet floating
 *      above the page rather than a smear laid over it. The vendored
 *      `::after` white bleed below the bar (a light-theme artifact with no
 *      dark override — grepped, zero hits) is matched to the sheet so a
 *      browser-chrome gap can never flash a white slab under a dark bar.
 *
 *   2. THE RESERVE WAS SHORTER THAN THE BAR. `body:has(.vsc-stickybar)`
 *      reserved 66px on mobile / 76px on desktop, but the STACKED bar (a
 *      single-dose product: name+price row, the dose chip, then a full-width
 *      Add) measures 166px on the phone and 128px on desktop, and the MULTI
 *      bar (dose pills beside Add) 112/93. So the last ~100px of the page —
 *      the footer's legal line — sat permanently behind the bar. The reserve
 *      is now keyed to the actual bar shape with `:has()`, the same mechanism
 *      section 7n already relies on, so the footer always clears.
 *
 * The internal spacing is opened up and the tap targets floored at the phone:
 * the Add button min 50px, each dose chip min 44px, with real gaps between the
 * name/price row, the chip(s) and the button. Geometry is mobile-only so the
 * desktop bar (which only appears after the buy box scrolls off, and is a
 * different context) keeps its compact layout; only the opaque chrome and the
 * reserve apply at every width, because the ghosting and the covered footer
 * were bugs everywhere.
 *
 * Specificity: the chrome mirrors the vendored dark override's own selector
 * shape (`html.vsc-dark body:not(.home) .vsc-stickybar`, both !important) so it
 * wins on source order — this file is linked after product.css. The geometry
 * and reserves are scoped `body.single-product` (0,2,1+) to out-rank the
 * vendored `.vsc-stickybar--*` rules, several of which carry !important. */

/* Chrome — opaque floating sheet, all widths. */
html.vsc-dark body:not(.home) .vsc-stickybar {
  background: #0F1620 !important;
  border-top: 1px solid rgba(125, 211, 252, 0.16) !important;
  box-shadow: 0 -12px 34px rgba(3, 8, 15, 0.72) !important;
  border-radius: 20px 20px 0 0 !important;
}
html.vsc-dark body:not(.home) .vsc-stickybar::after { background: #0F1620 !important; }

/* Reserve — desktop base (all products carry variants, so all are --stacked). */
body.single-product:has(.vsc-stickybar) { padding-bottom: 112px !important; }
body.single-product:has(.vsc-stickybar--stacked:not(.vsc-stickybar--multi)) {
  padding-bottom: 148px !important;
}

@media (max-width: 640px) {
  /* Open the internal rhythm and floor the tap targets. */
  body.single-product .vsc-stickybar-inner {
    padding: 12px 16px calc(10px + env(safe-area-inset-bottom)) !important;
  }
  body.single-product .vsc-stickybar--stacked .vsc-stickybar-inner { gap: 10px !important; }
  /* Single-dose bar: name/price row, chip, full-width Add — a clean column. */
  body.single-product .vsc-stickybar--stacked .vsc-stickybar-row2 {
    display: flex !important; flex-direction: column !important; gap: 10px !important;
  }
  /* Multi-dose bar: pills beside Add — this rule follows the column rule so it
     wins on source order for a bar that is both --stacked and --multi. */
  body.single-product .vsc-stickybar--multi .vsc-stickybar-row2 {
    flex-direction: row !important; gap: 10px !important;
  }
  body.single-product .vsc-stickybar-add { min-height: 50px !important; }
  body.single-product .vsc-stickybar--stacked .vsc-stickybar-add {
    padding: 13px 22px !important; font-size: 16px !important;
  }
  body.single-product .vsc-stickybar--multi .vsc-stickybar-add {
    padding: 13px 18px !important;
  }
  body.single-product .vsc-stickybar-size {
    padding: 10px 16px !important; min-height: 44px !important;
    display: inline-flex !important; align-items: center !important;
  }
  /* Reserve — mobile, taller bars; follows the desktop rules so it wins <=640. */
  body.single-product:has(.vsc-stickybar) { padding-bottom: 130px !important; }
  body.single-product:has(.vsc-stickybar--stacked:not(.vsc-stickybar--multi)) {
    padding-bottom: 186px !important;
  }
}
