/* ==========================================================================
   sinopep-brand.css — SinoPep's own design layer.

   Loaded AFTER public/css/sinopep.css. That file is REGENERATED by
   site-factory/generate-identity.js, so nothing hand-authored may live in it
   (runbook §2). Everything specific to this brand belongs here.

   The idea: the SinoPep mark is two interlocking blocks sheared 13° to the
   right. Nothing else in the fleet leans, so the shear is the whole identity —
   it appears as a rule under every section heading, as the notch on badges and
   buttons, and as the corner cut on the cards that carry the most weight. Type
   is Chakra Petch (chamfered, technical), which is where the mark's flat
   diagonal cuts come from in the first place.

   Restraint rule: the shear is a PUNCTUATION mark, never a layout. Body copy,
   inputs, tables and anything a customer has to read or click accurately stay
   perfectly upright.
   ========================================================================== */

:root {
    --sp-shear: -13deg;
    --sp-violet: #703b97;
    --sp-violet-soft: #b48ad0;
    --sp-violet-wash: #f2ecf7;
    --sp-ramp: linear-gradient(100deg, var(--primary) 0%, #4b397b 52%, var(--sp-violet) 100%);
    --sp-ramp-soft: linear-gradient(100deg, rgba(44, 55, 100, 0.08), rgba(112, 59, 151, 0.12));

    /* The identity layer does not emit these, but the cloned views reference them
       as var() fallbacks. Undefined token = the TEMPLATE's fallback hex renders,
       which is how the template's mint green survived a full re-theme (runbook §9.3). */
    --primary-lightest: #f3f4f7;
    --primary-600: #2c3764;
    --primary-700: #202748;
}

/* ---------- The seal -------------------------------------------------------
   The template's 中文 seal is vermillion, a colour SinoPep does not own. It is
   inline-styled in the footer, so that one is fixed at source. */
.cn-seal {
    border-color: var(--sp-violet-soft);
    color: var(--sp-violet);
    transform: skewX(var(--sp-shear));
    border-radius: 2px;
}
.footer-brand .cn-seal,
.footer-logo .cn-seal { color: var(--sp-violet-soft); border-color: var(--sp-violet-soft); }

/* ---------- Section headings ----------------------------------------------
   The template centres a short rule under every heading. Replace it with the
   sheared bar from the mark: two strokes, unequal, leaning. */
.section-heading { position: relative; }
/* One element, two strokes: a long ramped bar and a short violet tick, drawn as
   two backgrounds on the same box so they can never drift out of alignment the
   way a ::before/::after pair does. */
.section-heading::after {
    content: '';
    display: block;
    width: 74px;
    height: 6px;
    margin: 0.9rem auto 0;
    background:
        linear-gradient(100deg, var(--primary), var(--sp-violet)) 0 0 / 54px 100% no-repeat,
        linear-gradient(var(--sp-violet), var(--sp-violet)) 62px 0 / 12px 100% no-repeat;
    transform: skewX(var(--sp-shear));
    border-radius: 1px;
}
/* Left-aligned headings keep the motif on the left rather than floating centre. */
.about-section .section-heading,
.contact-section .section-heading { text-align: inherit; }

/* ---------- Buttons --------------------------------------------------------
   Primary actions carry the indigo→violet ramp. The notch is cut from the
   top-right corner only — the same corner the "7" turns in the mark. */
.btn-primary,
.hero-cta-primary,
.deal-card-cta,
button.btn-primary {
    background: var(--sp-ramp);
    border: none;
    clip-path: polygon(0 0, calc(100% - 11px) 0, 100% 11px, 100% 100%, 0 100%);
}
.btn-primary:hover,
.hero-cta-primary:hover { filter: brightness(1.08); }

/* Secondary buttons echo the notch as an outline, no fill. */
.btn-secondary,
.btn-outline,
.hero-cta-secondary {
    clip-path: polygon(0 0, calc(100% - 9px) 0, 100% 9px, 100% 100%, 0 100%);
}

/* ---------- Badges and chips ----------------------------------------------
   Small, high-frequency elements: shear the whole chip and counter-shear the
   text so the label stays readable. */
.trending-badge,
.badge-new,
.badge-popular,
.badge-value,
.hero-badge,
.deal-card-badge {
    transform: skewX(var(--sp-shear));
    border-radius: 2px;
}
.trending-badge > *,
.badge-new > *,
.badge-popular > *,
.badge-value > *,
.hero-badge > *,
.deal-card-badge > * { display: inline-block; transform: skewX(calc(-1 * var(--sp-shear))); }
/* Chips with no element wrapper get the counter-shear via a pseudo-safe rule. */
.hero-badge { padding-inline: 1.05rem; }

/* ---------- Cards ----------------------------------------------------------
   Only the cards that carry real weight get the corner cut: the trending
   products, the trust panels and the lab cards. Everything else stays square so
   the motif keeps meaning something. */
.trending-card,
.trust-card,
.lab-card,
.report-card {
    clip-path: polygon(0 0, calc(100% - 16px) 0, 100% 16px, 100% 100%, 0 100%);
    transition: transform 0.18s ease, box-shadow 0.18s ease;
}
.trending-card:hover,
.trust-card:hover { transform: translateY(-3px); }

/* A hairline of the ramp along the top of each trending card ties the grid to
   the hero without repainting the card itself. */
.trending-card { position: relative; }
.trending-card::before {
    content: '';
    position: absolute;
    inset: 0 0 auto 0;
    height: 3px;
    background: var(--sp-ramp);
    opacity: 0.85;
}

/* ---------- Hero -----------------------------------------------------------
   NOT animated: the hero heading is the LCP element (runbook §5). The only
   addition is a static sheared field behind it, echoing the mark's two blocks. */
.hero-section { position: relative; overflow: hidden; }
.hero-section::after {
    content: '';
    position: absolute;
    top: -12%;
    right: -6%;
    width: 340px;
    height: 130%;
    background: var(--sp-ramp-soft);
    transform: skewX(var(--sp-shear));
    pointer-events: none;
    z-index: 0;
}
.hero-section > * { position: relative; z-index: 1; }
@media (max-width: 900px) { .hero-section::after { display: none; } }

/* The italic run in the hero headline is the template's; SinoPep says it with
   the ramp instead, which reads as brand rather than as emphasis. */
.hero-title > span:not(.cn-seal) {
    font-style: normal;
    background: var(--sp-ramp);
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
}

/* ---------- Header ---------------------------------------------------------
   A single sheared rule under the sticky header, in place of the template's
   flat hairline. */
.header {
    border-bottom: 1px solid var(--border-subtle);
    box-shadow: 0 1px 0 rgba(112, 59, 151, 0.16);
}
.logo-img { border-radius: 3px; }
.nav-link.active::after,
.nav-links a.active::after {
    background: var(--sp-ramp);
    transform: skewX(var(--sp-shear));
}

/* ---------- Footer ---------------------------------------------------------
   The footer is always the ink ground. Give it the ramp as a top edge so the
   page closes on the brand. */
.footer { border-top: 3px solid transparent; border-image: var(--sp-ramp) 1; }

/* ---------- Trust bar ------------------------------------------------------ */
.trust-bar,
.about-trust-strip,
.trust-strip { background: var(--sp-ramp); }

/* ---------- Reduced motion -------------------------------------------------
   Nothing here animates on load, but the hover lifts should still stop for
   anyone who asks. */
@media (prefers-reduced-motion: reduce) {
    .trending-card,
    .trust-card { transition: none; }
    .trending-card:hover,
    .trust-card:hover { transform: none; }
}

/* ---------- "From resin to vial" ------------------------------------------
   SinoPep's own section, so it gets its own layout rather than inheriting the
   template's icon-and-chevron row: a numbered ladder where the rule between
   steps carries the shear. On a phone it collapses to a single column and the
   rule moves to the left edge, so the sequence still reads top to bottom. */
.sp-route {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    gap: 0;
    border-top: 2px solid var(--border-subtle);
}
.sp-route-step {
    position: relative;
    padding: 1.6rem 1.4rem 1.5rem;
    border-right: 1px solid var(--border-subtle);
}
.sp-route-step:last-child { border-right: 0; }
.sp-route-step::before {
    content: '';
    position: absolute;
    top: -2px;
    left: 0;
    width: 46px;
    height: 4px;
    background: var(--sp-ramp);
    transform: skewX(var(--sp-shear));
}
.sp-route-num {
    display: block;
    font-family: var(--font-mono, monospace);
    font-size: 0.78rem;
    font-weight: 700;
    letter-spacing: 0.14em;
    color: var(--sp-violet);
    margin-bottom: 0.55rem;
}
.sp-route-step h4 {
    font-family: var(--font-display, inherit);
    font-size: 1.02rem;
    margin: 0 0 0.45rem;
    color: var(--gray-900);
}
.sp-route-step p {
    margin: 0;
    font-size: 0.88rem;
    line-height: 1.6;
    color: var(--gray-600);
}
.sp-route-foot {
    margin: 1.6rem 0 0;
    padding-top: 1.1rem;
    border-top: 1px solid var(--border-subtle);
    font-size: 0.9rem;
    color: var(--gray-600);
    text-align: center;
}
.sp-route-foot i { color: var(--sp-violet); margin-right: 0.4rem; }
.sp-route-foot a { color: var(--primary); font-weight: 600; }
@media (max-width: 720px) {
    .sp-route { grid-template-columns: 1fr; border-top: 0; }
    .sp-route-step { border-right: 0; border-top: 2px solid var(--border-subtle); padding-inline: 0; }
}

/* ---------- Contrast floor on this shop's own ground ------------------------
   generate-identity derives --secondary-green from the brand hue; on this shop's
   pale surface it lands at 4.47:1, just under AA for the small "In Stock" and
   "Best Value" labels. Darken those two labels only — the token itself is used on
   other grounds where it already passes (runbook §9.4). */
.product-badge.badge-best-value,
.pl-stock-badge,
.pd-badge-best-value,
.trending-badge-value { color: #2f6040; }

/* The about-page trust strip sits on the gray-800 ground, where --gray-400 label
   text lands at 4.28:1. Known dark ground (runbook §9.4) — lift the label only. */
.about-trust-label { color: var(--gray-300); }

/* Header fit on narrow phones. Flex children default to min-width:auto, so a long
   legal name in .logo-text small refuses to shrink and pushes .header-actions —
   the CART BUTTON — off the right edge. Every element is still "present" and the
   page reports no overflow of its own, which is why this survives a casual look.
   The legal name is decorative at 390px; the cart is not. */
@media (max-width: 767px) {
    .header-content { min-width: 0; }
    .logo { min-width: 0; flex: 1 1 auto; overflow: hidden; }
    .logo-text { min-width: 0; }
    .logo-text small { display: none; }
    .header-actions { flex: 0 0 auto; }
}

/* The hero trust row's PeptideMeter link is a bare inline <a> inside a <span>, so it
   inherits no padding and lands at 143x21 on a phone — under the 44px tap floor. */
@media (max-width: 767px) {
    .hero-trust-item a {
        display: inline-flex;
        align-items: center;
        min-height: 44px;
        padding-block: 0.35rem;
    }
}

/* ==========================================================================
   HERO — rebuilt 2026-08-21

   What was wrong with the inherited one, in the order it hurt:

   1. THREE equal-weight CTAs. On desktop the third wrapped onto its own row and
      read as a mistake; on a 390px phone they stacked into ~200px of solid
      button before the fold. Now two: one filled, one outline. The third
      destination, the price list, is still in the nav and in the deal card.
   2. NO PRODUCT. A peptide shop whose hero shows only a discount table is
      selling the discount. The right column now leads with a real vial — this
      shop's own render, carrying its own label — with the lot number and the
      laboratory that verified it, because that IS the proposition here.
   3. The discount wall. Four stacked rows plus a timer plus two more CTAs ran
      the deal card past 600px on a phone, straight under the floating buttons
      and the bottom nav (runbook 9.5: an audit cannot see occlusion). It is now
      a 2x2 grid with the timer folded into its header: same four thresholds,
      roughly half the height.
   4. A weak trust row of three grey words carrying all the proof. Replaced as
      the primary signal by a four-up stat block; the row survives beneath it,
      because the PeptideMeter link inside it is a real outbound citation.
   5. fadeInUp on the h1. The hero heading is the LCP element and the inherited
      rule delayed its paint by 200ms with a `both` fill. Removed here.

   Mobile-first throughout: the base rules ARE the phone layout, and the
   two-column arrangement only appears at 900px.
   ========================================================================== */

/* The hero heading is the LCP element — it must paint immediately. */
.sp-hero .hero-eyebrow,
.sp-hero .hero-title,
.sp-hero .hero-subtitle,
.sp-hero .hero-cta,
.sp-hero .hero-trust-row,
.sp-hero .deal-card { animation: none !important; }

.sp-hero {
    padding: 2rem 0 2.25rem;
    scroll-margin-top: 5rem;
}
@media (min-width: 900px) { .sp-hero { padding: 3.5rem 0 3.25rem; } }

.sp-hero-grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: 1.75rem;
    align-items: start;
}
@media (min-width: 900px) {
    .sp-hero-grid {
        grid-template-columns: minmax(0, 1.05fr) minmax(0, 0.95fr);
        gap: 3rem;
        align-items: center;
    }
}

/* ---------- Copy column ---------------------------------------------------- */
.sp-hero-copy { min-width: 0; }

.sp-hero .hero-eyebrow {
    margin-bottom: 0.9rem;
    font-size: 0.62rem;
    padding: 0.35rem 0.7rem;
    max-width: 100%;
}

.sp-hero .hero-title {
    /* Fluid from phone to desktop — one rule instead of three breakpoints, and
       no 1.85rem-to-3.4rem jump the way the inherited CSS had. */
    font-size: clamp(2rem, 6.2vw, 3.5rem);
    line-height: 1.08;
    letter-spacing: -0.022em;
    margin-bottom: 0.85rem;
    text-wrap: balance;
}

.sp-hero .hero-subtitle {
    font-size: clamp(0.95rem, 1.6vw, 1.0625rem);
    line-height: 1.6;
    max-width: 46ch;
    margin-bottom: 1.5rem;
}

/* ---------- Calls to action ------------------------------------------------ */
.sp-hero .hero-cta {
    display: grid;
    grid-template-columns: 1fr;
    gap: 0.6rem;
    margin-bottom: 1.5rem;
}
@media (min-width: 480px) {
    .sp-hero .hero-cta { grid-template-columns: auto auto; justify-content: start; }
}
.sp-hero .hero-cta-primary,
.sp-hero .hero-cta-secondary {
    justify-content: center;
    min-height: 50px;
    padding-inline: 1.5rem;
    font-size: 0.94rem;
    white-space: nowrap;
}

/* ---------- Proof stats ---------------------------------------------------- */
.sp-proof {
    list-style: none;
    margin: 0 0 1.25rem;
    padding: 1rem 0 0;
    border-top: 1px solid var(--border-subtle);
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0.9rem 1.25rem;
}
@media (min-width: 900px) { .sp-proof { grid-template-columns: repeat(4, minmax(0, auto)); gap: 1.75rem; } }
.sp-proof li { min-width: 0; }
.sp-proof strong {
    display: block;
    font-family: var(--font-display, inherit);
    font-size: clamp(1.15rem, 3.4vw, 1.45rem);
    font-weight: 700;
    line-height: 1.1;
    color: var(--primary);
    letter-spacing: -0.01em;
}
.sp-proof span {
    display: block;
    margin-top: 0.15rem;
    font-size: 0.72rem;
    line-height: 1.35;
    color: var(--gray-600);
}

.sp-hero .hero-trust-row { gap: 0.65rem 1.1rem; }
.sp-hero .hero-trust-item { font-size: 0.78rem; }

/* ---------- Product shot --------------------------------------------------- */
.sp-shot {
    margin: 0 0 1rem;
    position: relative;
    background: linear-gradient(170deg, var(--porcelain), var(--surface-sunken));
    border: 1px solid var(--border-subtle);
    border-radius: 2px;
    /* The mark's shear, as the panel's one flourish. */
    clip-path: polygon(0 0, calc(100% - 22px) 0, 100% 22px, 100% 100%, 0 100%);
    overflow: hidden;
    display: grid;
    grid-template-columns: 128px minmax(0, 1fr);
    align-items: center;
    gap: 0.9rem;
    padding: 0.9rem 1rem 0.9rem 0.4rem;
}
@media (min-width: 900px) { .sp-shot { grid-template-columns: 168px minmax(0, 1fr); padding: 1.1rem 1.25rem 1.1rem 0.5rem; } }
.sp-shot img {
    width: 100%;
    height: auto;
    display: block;
    /* The renders sit on a white ground; multiply drops them onto the panel
       without needing a separate cut-out asset. */
    mix-blend-mode: multiply;
}
.sp-shot figcaption { min-width: 0; }
.sp-shot-lab {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    font-family: var(--font-mono, monospace);
    font-size: 0.7rem;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: #2f6040;
}
.sp-shot-lab i { font-size: 0.85em; }
.sp-shot-lot {
    display: block;
    margin-top: 0.35rem;
    font-family: var(--font-mono, monospace);
    font-size: 0.72rem;
    line-height: 1.45;
    color: var(--gray-600);
    overflow-wrap: anywhere;
}

/* ---------- Deal card ------------------------------------------------------ */
.sp-deal { margin: 0; }
.sp-deal-badge {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.6rem;
    flex-wrap: wrap;
    padding: 0.55rem 0.9rem;
}
.sp-deal-timer {
    display: inline-flex;
    align-items: baseline;
    gap: 0.4rem;
    white-space: nowrap;
}
.sp-deal-timer-lbl {
    font-size: 0.62rem;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    opacity: 0.85;
}

.sp-deal-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 1px;
    padding: 0;
    background: var(--border-subtle);
}
.sp-tier {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 0.2rem;
    margin: 0;
    padding: 0.7rem 0.85rem;
    border: 0;
    background: #fff;
    min-width: 0;
}
.sp-tier .deal-tier-label {
    font-size: 0.74rem;
    font-weight: 600;
    color: var(--gray-600);
    letter-spacing: 0.01em;
}
.sp-tier .deal-tier-value {
    font-family: var(--font-mono, monospace);
    font-size: 0.8rem;
    font-weight: 700;
    color: var(--primary);
    line-height: 1.3;
    overflow-wrap: anywhere;
}

.sp-deal-cta { padding: 0; border-top: 1px solid var(--border-subtle); }
.sp-deal-cta a {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    min-height: 48px;
    padding: 0.7rem 1rem;
    font-weight: 700;
    font-size: 0.9rem;
    text-decoration: none;
    color: #fff;
    background: var(--sp-ramp);
}
.sp-deal-cta a:hover { filter: brightness(1.08); }

/* ---------- Order on a phone ----------------------------------------------
   Copy and the primary action first, the product shot and the sale after it.
   The grid is a single column below 900px, so `order` is enough. */
@media (max-width: 899px) {
    .sp-hero-copy { order: 1; }
    .sp-hero-panel { order: 2; }
    .sp-hero .hero-trust-row { margin-bottom: 0.25rem; }
}

/* Very narrow phones: the four-up stat block would crush to two words a line. */
@media (max-width: 359px) {
    .sp-proof { grid-template-columns: 1fr; gap: 0.7rem; }
    .sp-deal-grid { grid-template-columns: 1fr; }
    .sp-shot { grid-template-columns: 96px minmax(0, 1fr); }
}

/* ---------- Hero, second pass ---------------------------------------------
   Three things the first render exposed, all of them inherited styling that
   my own selectors were not yet overriding:

   1. The timer sat inside `.deal-card-badge span:last-child`, which paints a
      dark pill, and `.deal-timer` sets color:var(--gray-900) — near-black type
      on a near-black pill on a dark red bar. Unreadable and cramped.
   2. `.deal-tier-value` carries a background + border, so every discount read
      as a disabled input rather than a value.
   3. The shot panel gave the vial 128px and the caption the rest, and the
      caption was two short lines — so most of the panel was empty. The vial is
      the best asset this shop has; give it room and give the caption something
      worth reading.
   -------------------------------------------------------------------------- */

/* 1. Timer — plain white on the ribbon, no pill, room to breathe. */
.sp-deal-badge .sp-deal-timer {
    background: none;
    padding: 0;
    border-radius: 0;
    font-size: 0.68rem;
    color: #fff;
    letter-spacing: 0.04em;
}
.sp-deal-badge .sp-deal-timer .deal-timer {
    color: #fff;
    font-size: 0.78rem;
    letter-spacing: 0.02em;
}
.sp-deal-badge .sp-deal-timer .timer-unit { color: rgba(255, 255, 255, 0.72); }
.sp-deal-badge .sp-deal-timer .timer-sep { color: rgba(255, 255, 255, 0.55); }
.sp-deal-timer-lbl { color: rgba(255, 255, 255, 0.8); }

/* 2. Discounts are values, not form fields. */
.sp-tier .deal-tier-value {
    background: none;
    border: 0;
    padding: 0;
    border-radius: 0;
    font-size: 0.82rem;
    color: var(--primary);
}

/* 3. The product shot, rebalanced. */
.sp-shot {
    grid-template-columns: minmax(0, 1fr);
    gap: 0.75rem;
    padding: 1.1rem 1.1rem 1.2rem;
    text-align: center;
}
.sp-shot img {
    width: auto;
    max-width: 100%;
    max-height: 208px;
    margin-inline: auto;
}
@media (min-width: 560px) {
    /* Side by side as soon as there is room, with the vial given real width
       and the caption set left so it does not read as a caption to nothing. */
    .sp-shot {
        grid-template-columns: 150px minmax(0, 1fr);
        align-items: center;
        gap: 1.1rem;
        text-align: left;
        padding: 1.1rem 1.25rem;
    }
    .sp-shot img { max-height: 230px; }
}
@media (min-width: 900px) { .sp-shot { grid-template-columns: 172px minmax(0, 1fr); } }

.sp-shot figcaption { display: block; }
.sp-shot-name {
    display: block;
    margin-top: 0.4rem;
    font-family: var(--font-display, inherit);
    font-size: 1.05rem;
    font-weight: 700;
    line-height: 1.2;
    color: var(--gray-900);
    letter-spacing: -0.01em;
}
.sp-shot-lot { margin-top: 0.3rem; }
.sp-shot-link {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    margin-top: 0.6rem;
    min-height: 44px;
    font-size: 0.78rem;
    font-weight: 700;
    color: var(--primary);
    text-decoration: none;
}
.sp-shot-link i { font-size: 0.75em; transition: transform 0.15s ease; }
.sp-shot-link:hover { text-decoration: underline; }
.sp-shot-link:hover i { transform: translateX(2px); }
@media (max-width: 559px) {
    /* Centred stack on a phone: the link needs its 44px box without pushing the
       panel taller than the vial already makes it. */
    .sp-shot-link { margin-top: 0.35rem; }
}

/* The trust row orphaned "Buyer protection" onto its own line at 390px. Three
   even columns keeps all three on one row down to the narrowest phone. */
@media (max-width: 559px) {
    .sp-hero .hero-trust-row {
        display: grid;
        grid-template-columns: repeat(3, minmax(0, 1fr));
        gap: 0.5rem;
        align-items: start;
    }
    .sp-hero .hero-trust-item { font-size: 0.7rem; line-height: 1.3; align-items: flex-start; }
    .sp-hero .hero-trust-item i { margin-top: 0.15rem; }
}

/* The bottom nav is fixed on a phone. Without this the last thing in the hero
   sits under it whenever the hero happens to end near the viewport bottom. */
@media (max-width: 767px) {
    .sp-hero { padding-bottom: 2.75rem; }
}

/* ---------- Hero, third pass: specificity and the product plate -----------
   The timer override in the pass above did not take. Measured rather than
   guessed: computed backgroundColor was still rgba(0,0,0,0.18).

   `.deal-card-badge span:last-child` is (0,2,1) — one class, one pseudo-class,
   one type — and `.sp-deal-badge .sp-deal-timer` is only (0,2,0). Two classes
   lose to one class plus a pseudo-class plus an element. Loading later does not
   help when the specificity is lower. Qualified with the element and the hero
   scope so it wins outright instead of by luck of source order.
   -------------------------------------------------------------------------- */
.sp-hero .sp-deal-badge span.sp-deal-timer {
    background: none;
    padding: 0;
    border-radius: 0;
    font-size: 0.68rem;
    color: #fff;
    letter-spacing: 0.04em;
}
/* `.deal-card-badge span:last-child` is a DESCENDANT selector, not a child one,
   so it also matched the inner #promoTimerCard span and repainted the dark pill
   one level down. Clear it on both. */
.sp-hero .sp-deal-badge span.sp-deal-timer .deal-timer {
    color: #fff;
    font-size: 0.78rem;
    background: none;
    padding: 0;
    border-radius: 0;
}
.sp-hero .sp-deal-badge span.sp-deal-timer .timer-unit { color: rgba(255, 255, 255, 0.72); }
.sp-hero .sp-deal-badge span.sp-deal-timer .timer-sep { color: rgba(255, 255, 255, 0.55); }

/* Same reason: `.deal-tier-value` is (0,1,0) but it is set on the element in a
   later stylesheet than mine would be if the identity layer is regenerated, so
   scope it to the hero to keep it stable. */
.sp-hero .sp-tier .deal-tier-value {
    background: none;
    border: 0;
    padding: 0;
    border-radius: 0;
    font-size: 0.82rem;
    color: var(--primary);
}

/* The vial renders carry their own soft studio ground, so `mix-blend-mode:
   multiply` was darkening a rectangle into the panel gradient rather than
   dropping it out — a blend artefact that reads as a mistake. Give the render
   an explicit white plate instead: deliberate, and it makes the glass read. */
.sp-shot img {
    mix-blend-mode: normal;
    background: #fff;
    border: 1px solid var(--border-subtle);
    border-radius: 2px;
    padding: 0.35rem;
}

/* ---------- Hero, fourth pass: getting the CTAs above the floating buttons --
   At 320px the fixed support buttons were sitting on top of the SECONDARY CTA
   — an actual control, not just decoration. The buttons are shared fleet
   chrome fixed to the viewport, so no rule here can stop them overlaying
   whatever happens to be beneath them; what this pass does is shorten the
   copy above the CTAs so both buttons land higher than the button stack at
   rest, which is the view that matters. (Runbook 9.5: neither the contrast nor
   the mobile audit can see occlusion — this was found by looking.)

   Measured at 320x700 before: secondary CTA top at ~1150px of a 1400px
   device-pixel viewport, squarely inside the button band.
   -------------------------------------------------------------------------- */

/* The eyebrow was wrapping to two lines on every phone. */
@media (max-width: 559px) {
    .sp-hero .hero-eyebrow {
        /* 0.7rem = 11.2px. mobile-audit enforces an 11px floor and a smaller
           value here read as 9.3px — legible on a desktop simulator, not on a
           phone. Tighter tracking buys back the width the larger size costs, so
           it still holds one line at 390px and wraps to two only at 320px. */
        font-size: 0.7rem;
        letter-spacing: 0.05em;
        padding: 0.3rem 0.6rem;
        margin-bottom: 0.7rem;
    }
    .sp-hero .hero-title { margin-bottom: 0.6rem; }
    .sp-hero .hero-subtitle { margin-bottom: 0.95rem; }
    .sp-hero .hero-cta { margin-bottom: 1rem; gap: 0.5rem; }
    /* 48px still clears the 44px tap floor with room, and two buttons at 48
       instead of 50 buys back the 4px that put 360px within 7px of the fixed
       support buttons. Clearance is measured, not assumed — see below. */
    .sp-hero .hero-cta-primary,
    .sp-hero .hero-cta-secondary { min-height: 48px; }
}

/* The three-item trust row repeats the sticky ticker at the top of every page
   ("JANOSHIK TESTED · PEPTIDEMETER VERIFIED · …") almost word for word. On a
   phone that redundancy costs a whole row in the first viewport and gives the
   floating buttons something to sit on. Keep it from 560px up, where it is
   free, and let the ticker carry it below that. The PeptideMeter citation is
   not lost: it is also in the header's Verified On menu on every breakpoint. */
@media (max-width: 559px) {
    .sp-hero .hero-trust-row { display: none; }
    .sp-proof { margin-bottom: 0; }
}

/* Four across as soon as the row fits, rather than waiting for 900px — at 768
   the two-column version left a lot of air between the pairs. */
@media (min-width: 600px) {
    .sp-proof { grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 1.25rem; }
}

/* At 320px the eyebrow wrapped to two lines even at 11.2px, and that second
   line pushed the secondary CTA back down to 5px of clearance from the fixed
   support buttons — technically clear, but one font-metric change from
   colliding again. Drop the leading words on the narrowest phones: "Changzhou
   (常州) · since 2011" still carries the provenance, and the headline already
   says the material is made in house. Measured after: 320px clearance 25px. */
@media (max-width: 379px) {
    .sp-eb-long { display: none; }
}
