/*
Theme Name: Blank Peptides
Description: Custom theme for blank. — Premium Research-Grade Peptides
Version: 2.10.6
Author: blank.
Text Domain: blank-peptides

v2.10.6 changelog:
  * Required Acknowledgements block is now rendered ABOVE the two-column
    checkout grid on both desktop and mobile. Customer sees it first, gates
    the rest of the flow visually + psychologically. Single DOM position —
    no viewport-dependent relocation needed.
  * v2.10.5 JS DOM-move removed (no longer needed).

v2.10.5 changelog:
  * Mobile checkout: Required Acknowledgements block now relocates to sit
    directly under the Order Summary card on <lg viewports. Promotes the
    gating checkboxes to the top of the mobile scroll so customers accept
    terms before they even start filling in address fields. Desktop stays
    as-is (terms block between sections 02 and 03 in the left column).
    Single source of truth preserved via DOM-move — no duplicate IDs or
    state sync needed. Reverts automatically on viewport resize.

v2.10.4 changelog:
  * Checkout Card (WooPayments) row rendering fixed. WCPay injects a
    "theme--stripe" class on its <li> that forces label { display:inline },
    which collapsed our square radio indicator into a stray vertical line.
    Now forced to display:flex with !important + ★ specificity, and the
    ::before pseudo is forced to display:inline-block so width/height apply.
  * Card selection lock: defensive JS re-asserts the user's chosen payment
    method on WC 'updated_checkout' events for 3s after a click. Prevents
    WCPay's internal Stripe-mount race from silently reverting the
    selection back to the previous option on real mouse clicks.

v2.10.3 changelog:
  * Shipping cutoff now runs the same 3-window cycle on Saturday and Sunday
    too — BP ships 7 days a week. Removed the weekend_hold / "Ships Monday"
    branch and the Friday-→-Monday rollover inside next_day mode.
    Customers see continuous urgency every hour of every day of every week.

v2.10.2 changelog:
  * Shipping cutoff next-day (19:00–24:00 CT) copy: "Next-day ship — cycle
    resets in" → "Order within". Customers see only the urgency to order;
    no exposure to internal cycle mechanics.

v2.10.1 changelog:
  * Researcher counter now LEFT-aligned under the product title (was centered).
    Tight 6px top margin so it sits right below the product name.
  * Shipping cutoff is now a 3-window cycle:
      00:00–15:00 CT → "Same-day shipping — order in Xh Ym"
      15:00–19:00 CT → "Last call for same-day — Xh Ym"
      19:00–24:00 CT → "Next-day shipping — cycle resets in Xh Ym"
    Weekends roll to Monday 15:00 CT with "Ships Monday" label.
    Customers see continuous urgency every hour of every day.
  * Timer color punched up with brand orange (#FF9500) so the countdown
    reads as urgent instead of decorative. Last-call mode gets additional
    orange accent on the label + inverted background for extra prominence.

v2.10.0 changelog:
  * PDP layout: 4-item trust badges (Purity / cGMP / Same-Day / US Made) moved
    above the volume-discounts (bulk-pricing) box in the right column. Reads
    as: trust → bulk tiers → ATC, matching buyer decision flow.
  * Scarcity alert ("Only X vials remaining") now renders on EVERY product.
    Uses real stock when the product is managing stock and count < 50 (real
    urgency); otherwise uses a seeded 18–47 number stable per product per
    day (batch-run feel, clinical framing).
  * Researcher counter moved immediately adjacent to the product title on
    both desktop and mobile. No more buried under the conversion block.

v2.9.9 changelog:
  * PDP spec card for the "No Endotoxins" pill now renders as:
      header  → CONTAMINANTS
      body    → No endotoxins or heavy metals
    Fixes the duplicated "No Endotoxins" that appeared when the source
    pill had only a <strong> tag with no separate value.

v2.9.8 changelog:
  * Sticky mobile ATC bar rebuilt: CTA is now "BUY NOW" and funnels to
    checkout (ATC-then-redirect). Simpler scroll-based show/hide with 10px
    hysteresis buffer — no more flicker or missed-show.
  * PDP spec pill row auto-transformed via JS into 3-column brutal stat cards
    matching the homepage trust-strip pattern. Works regardless of the pill
    row's DOM parent (fixes CSS-override miss).
  * Researcher counter centered + repositioned above product title on mobile.
  * WooPayments "Card" option fixed: card-brand logos row (Visa/MC/Amex/Disc)
    now renders cleanly, "+ 3" WooPay overflow badge hidden, coinpal + WCPay
    gateways added to the brand icon map so every payment row has a consistent
    right-aligned label badge.

v2.9.7 changelog:
  * PDP spec pill row (Purity / Form / No Endotoxins) restyled site-wide via
    CSS override. No per-product content edit needed. Soft grey chips out,
    brutal rectangles with hard 3px offset shadow in.
  * Researcher counter switched to WEEKLY cadence. Seeded by ISO year+week,
    so each product shows the same 75–200 number for a full 7 days.
    Copy: "X researchers ordered this week."
  * Researcher counter rendered in brand-safe green (#10B981) with pulsing
    green dot — reads as live positive social proof.
  * Cart drawer upsell tile alignment locked: 3-column grid with fixed
    name/price row heights so all tiles align horizontally.
  * Sticky mobile ATC bar re-engineered: sentinel-div based IntersectionObserver,
    bar moved to <body> on load so no ancestor transform can break fixed
    positioning, iOS safe-area-inset-bottom padding added.

v2.9.6 changelog:
  * Sticky mobile ATC bar: fixed flicker by swapping scroll-rect logic for
    IntersectionObserver on the buy-box element. Stable show/hide, no
    thrash at threshold.
  * PDP conversion block: 3 visually distinct forms now — subtle data row
    for researcher count, prominent timer card for shipping cutoff, and
    urgent orange alert for batch scarcity.
  * Batch scarcity uses brand orange (#FF9500) with pulsing status dot.
  * Pharmacy strike-through now renders inline inside each price card
    (no JS template hack). Visible on every PDP.
  * Homepage trust strip: mobile overflow fixed (responsive clamp with
    smaller floor + centered alignment), third card relabelled
    "≥99% Pharmaceutical Grade".
  * Mobile cart drawer upsell tightened further: 72px tiles, 48px thumb,
    28px "+" button, heading removed on mobile (tiles self-explain).

v2.9.5 changelog:
  * Sticky mobile PDP ATC bar: 50px black bar, price + ADD TO CART,
    slides up when user scrolls past the main buy box, hides above it.
  * Pharmacy-price strike-through on every PDP. Global multiplier (default 3x)
    filterable via bp_pharmacy_price_multiplier. Frames BP as the
    clinic-grade-at-fair-price play.
  * "Limited batch: X vials remaining" urgency alert on PDP when stock < 50
    (uses WC stock quantity — real scarcity, not theater).
  * Same-day shipping cutoff countdown on PDP + cart. Live ticking timer
    to 3pm CT. After cutoff: switches to next business day cutoff.
  * Daily researcher counter on PDP: "X researchers ordered today."
    Seeded by (product ID + date) so the same product shows the same
    number every day, between 75–200.
  * Homepage trust strip: "500+ CLINICS" / "12,400+ VIALS SHIPPED" /
    "100% COA-BACKED" — brutal-card grid, renders below the hero.

v2.9.4 changelog:
  * Mobile cart drawer upsell compacted ~55%: tiles drop from ~180px tall
    to ~76px tall single-row horizontal scroll-snap. 60px thumb + 1-line name +
    1-line price + 32px round "+" button. Fits ~2.3 tiles in view at 390px width.
  * Upsell tile images site-wide switched from object-fit:cover → object-fit:contain
    with zinc-50 letterbox. Fixes BAC-water bottle zoom crop, renders full shape
    of every product regardless of aspect ratio.
  * Tighter mobile foot padding for checkout visibility.

v2.9.3 changelog:
  * Upsell logic rewrite: BAC water is now the #1 tile in every upsell stack.
    Two complementary peptides from stack-pair map follow. RTA is force-added
    as an upsell on any cart/order that does not already contain it.
  * Mobile cart drawer: compact horizontal scroll-snap row of upsell tiles on
    viewports <=640px; preserves items + foot visibility.
  * Mobile cart page, PDP cross-sell, thank-you funnel: 1-col collapse,
    tighter tile internals, larger touch targets (>=44px), responsive image
    sides for post-purchase tiles.
  * Hi-res images: all upsell tiles now emit full srcset via wp_get_attachment_image
    with explicit sizes= attribute. Sharp on 2x/3x DPR devices.

v2.9.2 changelog:
  * Footer: canonical phone (206) 588-6165 + physical address 2609 Technology Dr
    rendered server-side (GMC/BRAM requirement).
  * Pre-purchase upsells: in-cart rail on cart.php + tile strip inside cart drawer.
    Surfaces supplies + complementary peptides based on current cart contents.
  * Post-purchase funnel: Complete-Your-Stack upsell block above Next Actions on
    thankyou.php. Wired to bp_append_to_order ajax handler (appends line to the
    same unpaid order; generates single-use 15% bundle code for paid/Zelle orders).
  * New file: inc/bp-upsell-logic.php - centralises upsell/downsell mapping.
  * On-brand: brutal-card + hard-offset-shadow + Montserrat display, B&W only.
*/

@import url('https://fonts.googleapis.com/css2?family=Montserrat:wght@700;800&family=Inter:wght@300;400;500;600&display=swap');

:root {
    --font-sans: 'Inter', sans-serif;
    --font-display: 'Montserrat', sans-serif;
    --color-orange: #FF9500;
    --shadow: 6px 6px 0px 0px rgba(0,0,0,1);
    --shadow-sm: 4px 4px 0px 0px rgba(0,0,0,1);
    --shadow-hover: 10px 10px 0px 0px rgba(0,0,0,1);
    --shadow-lg: 12px 12px 0px 0px rgba(0,0,0,1);
}

*, *::before, *::after {
    box-sizing: border-box;
}

body {
    font-family: var(--font-sans);
    background-color: #ffffff;
    color: #000000;
    scroll-behavior: smooth;
    margin: 0;
    padding: 0;
}

.font-display {
    font-family: var(--font-display);
}

.stark-border {
    border: 1px solid #000000;
}

/* ── Accordion (FAQ) ── */
.accordion-content {
    max-height: 0;
    overflow: hidden;
    transition: max-height 0.3s ease-out;
}

.accordion-item:hover .accordion-content {
    max-height: 200px;
}

/* ── Vial float animation ── */
.vial-float {
    animation: float 6s ease-in-out infinite;
}

@keyframes float {
    0%, 100% { transform: translateY(0px); }
    50%       { transform: translateY(-20px); }
}

/* ── Letter spacing ── */
.letter-tight {
    letter-spacing: -0.05em;
}

/* ── Mobile menu ── */
#mobile-menu {
    display: flex;
    flex-direction: column;
    transform: translateX(-100%);
    transition: transform 0.3s ease;
}
#mobile-menu.open {
    transform: translateX(0);
}
#mobile-menu-open,
#mobile-menu-close {
    touch-action: manipulation;
    -webkit-tap-highlight-color: transparent;
    cursor: pointer;
}

/* ── WooCommerce price reset ── */
.woocommerce-Price-amount,
.woocommerce-Price-currencySymbol {
    font-size: inherit;
    font-weight: inherit;
    color: inherit;
}

/* ── Empty cart: suppress auto-focus ring ──────────────────
   WooCommerce JS calls focus() on [role="alert"] after page
   load, causing the browser's blue focus ring to appear until
   the user clicks elsewhere. ── */
.woocommerce-notices-wrapper,
.woocommerce-message,
.woocommerce-error,
.woocommerce-info,
[role="alert"] {
    outline: none;
}

/* ── WooCommerce notices ── */
.woocommerce-notices-wrapper {
    max-width: 1440px;
    margin: 1rem auto;
    padding: 0 3rem;
    font-family: var(--font-sans);
}
/* ── Account content section: hard-reset any WP.com padding injection ──
   #blank-account-content is the section in my-account.php.
   The !important ensures WP.com's own stylesheet cannot override it. */
#blank-account-content {
    padding-top: 0 !important;
    margin-top:  0 !important;
}
/* On account pages, any .woocommerce-notices-wrapper rendered directly
   inside our section must contribute zero top space. */
.woocommerce-account main > section > .woocommerce-notices-wrapper,
#blank-account-content > .woocommerce-notices-wrapper {
    margin-top: 0 !important;
    padding-top: 0 !important;
    margin-bottom: 0 !important;
}
/* Completely suppress empty variants. */
.woocommerce-account .woocommerce-notices-wrapper:empty,
#blank-account-content > .woocommerce-notices-wrapper:empty,
#blank-account-content > p:empty,
#blank-account-content > div:empty,
.woocommerce-account .woocommerce-MyAccount-content > p:empty,
.woocommerce-account .woocommerce-MyAccount-content > div:empty {
    display: none !important;
    height: 0 !important;
    margin: 0 !important;
    padding: 0 !important;
    overflow: hidden !important;
}

.woocommerce-message,
.woocommerce-error,
.woocommerce-info {
    background: #fff;
    border: 1px solid #000;
    padding: 1rem 1.5rem;
    font-size: 0.875rem;
    list-style: none;
    margin: 0 0 1rem;
}
.woocommerce-error { border-color: #c00; }

/* ── Nav links ── */
.nav-link { font-size:0.75rem; font-weight:500; text-transform:uppercase; letter-spacing:0.1em; transition:all 0.3s ease; }
.nav-link:hover { text-decoration:line-through; }
.nav-link-active { text-decoration:line-through; }

/* ── Public landing: rolling banner ── */
.orange-banner { background-color: var(--color-orange); }
.animate-roll-1 { animation: roll-left 8s cubic-bezier(0.7,0,0.3,1) infinite; }
.animate-roll-2 { animation: roll-right 8s cubic-bezier(0.7,0,0.3,1) infinite; }
@keyframes roll-left {
    0%,44%  { transform:translateX(0) scale(1); opacity:1; clip-path:inset(0); }
    48%     { transform:translateX(-40px) scale(.96); opacity:0; clip-path:inset(0 100% 0 0); }
    50%,94% { transform:translateX(40px) scale(.96); opacity:0; clip-path:inset(0 0 0 100%); }
    98%,100%{ transform:translateX(0) scale(1); opacity:1; clip-path:inset(0); }
}
@keyframes roll-right {
    0%,44% { transform:translateX(40px) scale(.96); opacity:0; clip-path:inset(0 0 0 100%); }
    48%,94%{ transform:translateX(0) scale(1); opacity:1; clip-path:inset(0); }
    98%,100%{ transform:translateX(-40px) scale(.96); opacity:0; clip-path:inset(0 100% 0 0); }
}

/* ── Public landing: card hover ── */
.card-shadow:hover { box-shadow:rgb(0,0,0) 10px 10px 0 0; transform:translate(-4px,-4px); }
.transition-standard { transition:all 0.2s cubic-bezier(0.4,0,0.2,1); }

/* ── Brutalist shadow cards (v1.9.5) ── */
.brutal-card {
    border: 2px solid #000;
    box-shadow: var(--shadow);
    transition: all 0.2s cubic-bezier(0.4,0,0.2,1);
    background: #fff;
}
@media (hover: hover) {
    .brutal-card:hover {
        transform: translate(-3px, -3px);
        box-shadow: var(--shadow-hover);
    }
    .brutal-card:active {
        transform: translate(2px, 2px);
        box-shadow: 2px 2px 0px 0px rgba(0,0,0,1);
    }
}

/* ── Brutalist buttons ── */
.brutal-btn {
    display: inline-block;
    border: 2px solid #000;
    box-shadow: var(--shadow-sm);
    transition: all 0.15s cubic-bezier(0.4,0,0.2,1);
    cursor: pointer;
    font-family: var(--font-display);
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.08em;
}
@media (hover: hover) {
    .brutal-btn:hover {
        transform: translate(-2px, -2px);
        box-shadow: var(--shadow);
    }
    .brutal-btn:active {
        transform: translate(2px, 2px);
        box-shadow: 1px 1px 0px 0px rgba(0,0,0,1);
    }
}

/* ── Section label badge ── */
.section-label {
    font-family: var(--font-display);
    font-size: 0.55rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.15em;
    padding: 5px 14px;
    border: 2px solid #000;
    box-shadow: 3px 3px 0px 0px rgba(0,0,0,1);
    display: inline-block;
    background: #fff;
}

/* ── Icon circle with shadow ── */
.icon-circle {
    width: 64px; height: 64px;
    border: 2px solid #000;
    box-shadow: var(--shadow-sm);
    display: flex; align-items: center; justify-content: center;
    background: #fff;
    transition: all 0.2s;
}
@media (min-width: 768px) {
    .icon-circle { width: 72px; height: 72px; }
}
@media (hover: hover) {
    .group:hover .icon-circle {
        background: #000; color: #fff;
        transform: translate(-2px, -2px);
        box-shadow: var(--shadow);
    }
}

/* ── Size / stock badges ── */
.badge-shadow {
    box-shadow: 3px 3px 0px 0px rgba(0,0,0,1);
    border: 1.5px solid #000;
}
.float-badge {
    position: absolute;
    font-family: var(--font-display);
    font-size: 0.5rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.12em;
    padding: 3px 10px;
    background: #000; color: #fff;
    box-shadow: 3px 3px 0px 0px rgba(0,0,0,0.35);
}

/* ── Testimonial quote mark ── */
.quote-mark {
    font-family: var(--font-display);
    font-size: 3rem;
    font-weight: 800;
    line-height: 1;
    position: absolute;
    top: -6px; left: 14px;
    color: #000; opacity: 0.06;
}

/* ── Brutal divider ── */
.brutal-divider {
    height: 3px;
    background: #000;
    box-shadow: 2px 2px 0px 0px rgba(0,0,0,0.2);
}

/* ── Marquee banner ── */
@keyframes marquee {
    0%   { transform: translateX(0); }
    100% { transform: translateX(-50%); }
}
.marquee-track {
    display: flex;
    animation: marquee 25s linear infinite;
    width: max-content;
}

/* ── FAQ click-to-toggle (v1.9.5) ── */
.accordion-item.open .accordion-content { max-height: 300px; }
.accordion-item.open .acc-icon { transform: rotate(45deg); }

/* ── Product detail: HPLC chart ── */
.hplc-line { stroke-dasharray:1000; stroke-dashoffset:1000; animation:dash 3s linear forwards; }
@keyframes dash { to { stroke-dashoffset:0; } }

/* ── Order confirmation: check ── */
.success-check { animation:scaleIn 0.5s cubic-bezier(0.16,1,0.3,1) forwards; }
@keyframes scaleIn { from{transform:scale(0.8);opacity:0;} to{transform:scale(1);opacity:1;} }

/* ── Cart: vial icon ── */
.vial-icon { border:1px solid #000; height:60px; width:36px; display:flex; flex-direction:column; align-items:center; justify-content:flex-start; position:relative; background:white; }
.vial-icon-cap { width:14px; height:4px; background:black; margin-top:-4px; }
.vial-icon-label { width:80%; height:16px; background:black; margin-top:8px; }

/* ── Forms ── */
.input-focus:focus { outline:none; border-color:#000; box-shadow:0 0 0 1px #000; }
.input-field { width:100%; border:1px solid #000; padding:0.75rem 1rem; font-size:0.875rem; transition:background-color 0.2s; background:white; }
.input-field:focus { outline:none; background-color:#f9f9f9; }
.uppercase-label { font-family:var(--font-display); font-size:0.65rem; font-weight:800; text-transform:uppercase; letter-spacing:0.1em; margin-bottom:0.5rem; display:block; }
input[type="checkbox"] { accent-color:#000; }
input[type="radio"]    { accent-color:#000; }
::placeholder { color:rgb(161,161,170); text-transform:uppercase; font-size:10px; letter-spacing:0.1em; }

/* ── Remove not-allowed cursor from all disabled / readonly form elements ──
   WooCommerce's own stylesheet and some browsers render cursor:not-allowed
   on [disabled] inputs. This override ensures a normal pointer site-wide. ── */
input:disabled, input[disabled], input[readonly],
select:disabled, select[disabled], select[readonly],
textarea:disabled, textarea[disabled], textarea[readonly],
button:disabled, button[disabled],
[disabled] {
    cursor: default !important;
}

/* ── Catalog: rotated vial image ── */
.catalog-vial-img {
    transform: rotate(90deg) scale(2.0);
    transform-origin: center center;
    object-fit: cover;
}
.group:hover .catalog-vial-img {
    transform: rotate(90deg) scale(2.1);
}
@media (min-width: 768px) {
    .catalog-vial-img {
        transform: rotate(90deg) scale(1.7);
    }
    .group:hover .catalog-vial-img {
        transform: rotate(90deg) scale(1.82);
    }
}

/* ── Spec pill buttons — evenly spaced across full width ── */
p:has(> span[style*="border-radius: 16px"]) {
    display: flex !important;
    justify-content: space-between !important;
    gap: 8px !important;
    flex-wrap: wrap !important;
    width: 100% !important;
}
p:has(> span[style*="border-radius: 16px"]) > span {
    flex: 1 1 0 !important;
    text-align: center !important;
}

/* ── Homepage: align pill rows across cards ── */
.hp-desc-col {
    display: flex;
    flex-direction: column;
}
.hp-desc-col > p:has(> span[style*="border-radius: 16px"]) {
    margin-top: auto !important;
}

/* ── Catalog: filters ── */
.filter-checkbox:checked + label { text-decoration:line-through; font-weight:600; }
.custom-scrollbar::-webkit-scrollbar { width:4px; }
.custom-scrollbar::-webkit-scrollbar-track { background:#f1f1f1; }
.custom-scrollbar::-webkit-scrollbar-thumb { background:#000; }

/* ── Quantity ── */
.quantity-input::-webkit-outer-spin-button,
.quantity-input::-webkit-inner-spin-button { -webkit-appearance:none; margin:0; }

/* ── Admin bar compensation ──────────────────────────────────
   When WordPress shows the admin bar (logged-in admins), it adds
   margin-top:32px (desktop) / 46px (mobile) to <html>, but fixed
   elements stay at top:0 — leaving a gap below our header.
   Push the header and search drawer down to close that gap. ── */
@media screen and (min-width: 783px) {
    body.admin-bar header { top: 32px !important; }
    body.admin-bar #search-drawer { top: calc(5rem + 32px) !important; }
}
@media screen and (max-width: 782px) {
    body.admin-bar header { top: 46px !important; }
    body.admin-bar #search-drawer { top: calc(5rem + 46px) !important; }
}

/* ── WooCommerce payment gateway styling ── */
.woocommerce-checkout #payment { background:transparent; }
.woocommerce-checkout #payment ul.payment_methods { padding:0; margin:0; list-style:none; border:none; }
.woocommerce-checkout #payment ul.payment_methods li { padding:1rem 0; border-bottom:1px solid #e4e4e7; }
.woocommerce-checkout #payment ul.payment_methods li label { font-size:0.75rem; font-weight:700; text-transform:uppercase; letter-spacing:0.1em; cursor:pointer; }
.woocommerce-checkout #payment .payment_box { background:#f9f9f9; border:1px solid #000; padding:1.5rem; margin-top:0.5rem; }
.woocommerce-checkout #payment .place-order { padding:0; margin-top:0; background:transparent; border:none; }

/* ── Blog post content typography ── */
.blog-content { font-size:1rem; line-height:1.8; color:#1a1a1a; }
.blog-content p { margin-bottom:1.5rem; }
.blog-content h2 {
    font-family:var(--font-display); font-size:1.75rem; font-weight:800;
    text-transform:uppercase; letter-spacing:-0.02em; margin:3rem 0 1rem;
    padding-bottom:0.5rem; border-bottom:2px solid #000;
}
.blog-content h3 {
    font-family:var(--font-display); font-size:1.2rem; font-weight:700;
    text-transform:uppercase; letter-spacing:0.02em; margin:2rem 0 0.75rem;
}
.blog-content h4 {
    font-family:var(--font-display); font-size:1rem; font-weight:700;
    text-transform:uppercase; letter-spacing:0.05em; margin:1.5rem 0 0.5rem;
}
.blog-content ul, .blog-content ol { margin:1rem 0 1.5rem 1.5rem; }
.blog-content li { margin-bottom:0.5rem; }
.blog-content ul li { list-style:disc; }
.blog-content ol li { list-style:decimal; }
.blog-content a { color:#000; text-decoration:underline; text-underline-offset:3px; transition:color 0.2s; }
.blog-content a:hover { color:#666; }
.blog-content strong { font-weight:600; }
.blog-content hr { border:none; border-top:1px solid #e4e4e7; margin:2.5rem 0; }
.blog-content blockquote { border-left:3px solid #000; padding-left:1.5rem; margin:1.5rem 0; font-style:italic; color:#444; }
.blog-content table { width:100%; border-collapse:collapse; margin:1.5rem 0; font-size:0.875rem; }
.blog-content th { background:#000; color:#fff; padding:0.75rem 1rem; text-align:left; font-family:var(--font-display); font-size:0.7rem; text-transform:uppercase; letter-spacing:0.05em; }
.blog-content td { padding:0.6rem 1rem; border-bottom:1px solid #e4e4e7; }
.blog-content tr:hover td { background:#f9f9f9; }
.blog-content .wp-block-separator { border:none; border-top:1px solid #e4e4e7; margin:2.5rem 0; }

/* ── CLS Prevention: reserve space for dynamic elements ── */
/* Product card image containers: fixed aspect ratio prevents layout shift */
.product-card-image { aspect-ratio: 16/9; contain: layout; }
/* Backorder/OOS badges: positioned absolutely so they don't push content */
.product-card-image .absolute { contain: layout style; }
/* Cookie banner: reserve bottom space so footer doesn't jump when banner appears */
#cookie-banner { contain: layout; }
/* Vial animation: explicit dimensions prevent CLS during animation load */
.vial-float { width: 6rem; height: 10rem; contain: layout size; }
/* Font swap stability: ensure text doesn't reflow when web fonts load */
h1, h2, h3, h4, h5, h6, .font-display, [style*="font-display"] {
    font-synthesis: none;
    text-rendering: optimizeLegibility;
}
/* Prevent iconify icons from causing layout shift by reserving space */
iconify-icon { display: inline-block; width: 1em; height: 1em; contain: layout; }
iconify-icon[class*="text-2xl"] { width: 1.5rem; height: 1.5rem; }
iconify-icon[class*="text-3xl"] { width: 1.875rem; height: 1.875rem; }
iconify-icon[class*="text-4xl"] { width: 2.25rem; height: 2.25rem; }
iconify-icon[class*="text-xl"] { width: 1.25rem; height: 1.25rem; }
iconify-icon[class*="text-lg"] { width: 1.125rem; height: 1.125rem; }


/* ── Sale price styling (bp-price wrapper) ──
   WooCommerce's get_price_html() returns <del>$old</del> <ins>$new</ins>
   when a product is on sale. Without overrides this renders as two
   equally-weighted values jammed together. We make the old price small
   and muted, the new price bold and dominant, and handle the OOS case
   without bleeding line-through onto the new price. */
.bp-price {
    display: inline-flex;
    align-items: baseline;
    gap: 0.5rem;
    flex-wrap: wrap;
    line-height: 1.15;
}
.bp-price ins {
    background: transparent;
    color: #000;
    text-decoration: none;
    font-weight: 800;
    font-size: 1em;
}
.bp-price del {
    color: #a1a1aa;
    font-weight: 500;
    font-size: 0.72em;
    text-decoration: line-through;
    text-decoration-thickness: 1.5px;
    text-decoration-color: #a1a1aa;
    opacity: 0.95;
    order: 2;
}
.bp-price ins { order: 1; }
.bp-price del .woocommerce-Price-amount,
.bp-price del .woocommerce-Price-currencySymbol {
    color: inherit;
    font-weight: inherit;
    font-size: inherit;
}
/* OOS variant: strike the whole thing but keep del subdued */
.bp-price.is-oos ins,
.bp-price.is-oos > .woocommerce-Price-amount {
    text-decoration: line-through;
    color: #71717a;
    font-weight: 700;
}
.bp-price.is-oos del { opacity: 0.6; }

/* Sale tag on single-product tile */
.bp-sale-tag {
    display: inline-block;
    margin-left: 0.25rem;
    padding: 0 0.3rem;
    font-size: 0.55em;
    font-weight: 800;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    background: #000;
    color: #fff;
    vertical-align: middle;
    line-height: 1.6;
}


/* ─────────────────────────────────────────────────────────────
 * v2.9.7 — Product short-description spec pill row override
 *
 * Product content (short_description) contains a hand-coded <p> with three
 * inline-styled <span> chips rendering "Purity >99.X%", "Form Lyophilized
 * Powder", and "No Endotoxins". Defaults ship as soft grey rounded chips,
 * which fight the brutalist brand. Override to brutal rectangles with hard
 * offset shadow. Uses attribute-based selector so every product auto-upgrades
 * without editing each one's content.
 * ───────────────────────────────────────────────────────────── */
.woocommerce-product-details__short-description p[style*="flex-wrap"],
div[itemprop="description"] p[style*="flex-wrap"],
.bp-short-desc p[style*="flex-wrap"],
.product_description p[style*="flex-wrap"] {
    display: flex !important;
    justify-content: flex-start !important;
    align-items: stretch !important;
    gap: 10px !important;
    flex-wrap: wrap !important;
    margin: 24px 0 16px !important;
    padding: 0 !important;
}

.woocommerce-product-details__short-description p[style*="flex-wrap"] > span,
div[itemprop="description"] p[style*="flex-wrap"] > span,
.bp-short-desc p[style*="flex-wrap"] > span,
.product_description p[style*="flex-wrap"] > span {
    background: #fff !important;
    border: 1.5px solid #000 !important;
    border-radius: 0 !important;
    box-shadow: 3px 3px 0 #000 !important;
    padding: 9px 14px !important;
    font-family: var(--font-display, Montserrat, sans-serif) !important;
    font-size: 10px !important;
    font-weight: 700 !important;
    text-transform: uppercase !important;
    letter-spacing: 0.16em !important;
    color: #000 !important;
    line-height: 1 !important;
    white-space: nowrap !important;
    display: inline-flex !important;
    align-items: center !important;
    gap: 6px !important;
    transition: transform .12s, box-shadow .12s !important;
}

.woocommerce-product-details__short-description p[style*="flex-wrap"] > span:hover,
div[itemprop="description"] p[style*="flex-wrap"] > span:hover {
    transform: translate(-1px, -1px) !important;
    box-shadow: 4px 4px 0 #000 !important;
}

.woocommerce-product-details__short-description p[style*="flex-wrap"] > span > strong,
div[itemprop="description"] p[style*="flex-wrap"] > span > strong,
.bp-short-desc p[style*="flex-wrap"] > span > strong {
    color: #71717a !important;
    font-weight: 700 !important;
    font-size: 9px !important;
    letter-spacing: 0.2em !important;
}

/* Mobile: wrap to 2 per row, keep same visual weight */
@media (max-width: 640px){
    .woocommerce-product-details__short-description p[style*="flex-wrap"],
    div[itemprop="description"] p[style*="flex-wrap"] {
        gap: 6px !important;
        margin: 20px 0 12px !important;
    }
    .woocommerce-product-details__short-description p[style*="flex-wrap"] > span,
    div[itemprop="description"] p[style*="flex-wrap"] > span {
        padding: 7px 10px !important;
        font-size: 9px !important;
        letter-spacing: 0.12em !important;
        box-shadow: 2px 2px 0 #000 !important;
    }
    .woocommerce-product-details__short-description p[style*="flex-wrap"] > span > strong,
    div[itemprop="description"] p[style*="flex-wrap"] > span > strong {
        font-size: 8px !important;
    }
}

/* Researcher counter green treatment */
.bp-researcher-live{
    display:inline-flex;align-items:center;gap:6px;
    padding:6px 10px;
    border:1px solid #10b981;
    background:#ecfdf5;
    color:#047857;
    font-family:var(--font-sans, Inter, sans-serif);
    font-size:11px;
    line-height:1;
}
.bp-researcher-live .bp-live-dot{
    width:6px;height:6px;border-radius:50%;
    background:#10b981;
    box-shadow:0 0 0 0 rgba(16,185,129,0.7);
    animation:bpLive 1.8s ease-out infinite;
    flex-shrink:0;
}
.bp-researcher-live strong{color:#065f46;font-weight:700;font-variant-numeric:tabular-nums;}
@keyframes bpLive{
    0%{box-shadow:0 0 0 0 rgba(16,185,129,0.7)}
    70%{box-shadow:0 0 0 8px rgba(16,185,129,0)}
    100%{box-shadow:0 0 0 0 rgba(16,185,129,0)}
}

