@font-face{font-family:'Manrope';src:url('../fonts/manrope.woff2') format('woff2-variations');
  font-weight:300 800;font-style:normal;font-display:swap}

:root{
  --brand:#19ed56;
  --brand-hi:#33ff6c;
  --brand-deep:#0b9c3b;      /* green for fills, borders and marks */
  --brand-text:#098231;      /* same hue, darkened so green TEXT clears 4.5:1 on every light panel */
  --brand-tint:#e9fdef;
  --on-brand:#05170c;
  --ink:#0d1211;
  --ink-2:#556059;
  --ink-3:#69736d;           /* 4.5:1 on white AND on the tinted panels; #8d9791 was 3.01 */
  --line:#e7ebe8;
  --line-2:#d8ded9;
  --paper:#ffffff;
  --soft:#f5f7f6;
  --well:#f4f6f5;
  --sans:'Manrope',-apple-system,BlinkMacSystemFont,'Segoe UI',Helvetica,Arial,sans-serif;
  --maxw:1320px;
  --gut:clamp(18px,3.6vw,48px);
  --ease:cubic-bezier(.22,1,.36,1);
  --shadow:0 1px 2px rgba(13,18,17,.04),0 8px 24px -12px rgba(13,18,17,.14);
  --shadow-lg:0 2px 4px rgba(13,18,17,.04),0 22px 48px -18px rgba(13,18,17,.22);
}

*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%;scroll-behavior:smooth}
body{margin:0;background:var(--paper);color:var(--ink);font-family:var(--sans);
  font-size:16px;line-height:1.6;font-weight:450;
  -webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;overflow-x:hidden}
img{max-width:100%;display:block}
a{color:inherit;text-decoration:none}
button{font:inherit;color:inherit;background:none;border:0;cursor:pointer}
h1,h2,h3,h4{margin:0;font-weight:800;letter-spacing:-.03em;line-height:1.06}
p{margin:0}
::selection{background:var(--brand);color:var(--on-brand)}
:focus-visible{outline:2.5px solid var(--brand-deep);outline-offset:2px;border-radius:6px}
.wrap{width:100%;max-width:var(--maxw);margin-inline:auto;padding-inline:var(--gut)}
@supports(padding:max(0px)){
  .wrap{padding-left:max(var(--gut),env(safe-area-inset-left));
        padding-right:max(var(--gut),env(safe-area-inset-right))}
}
.sr{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0)}
section[id],footer[id]{scroll-margin-top:96px}

/* ══ buttons ══ */
.btn{display:inline-flex;align-items:center;justify-content:center;gap:10px;height:52px;padding:0 28px;
  border-radius:999px;font-weight:700;font-size:15px;letter-spacing:-.01em;white-space:nowrap;
  transition:transform .18s var(--ease),background .2s var(--ease),color .2s var(--ease),
             border-color .2s var(--ease),box-shadow .25s var(--ease)}
.btn:active{transform:scale(.96)}
.btn--primary{background:var(--brand);color:var(--on-brand);box-shadow:0 8px 20px -8px rgba(25,237,86,.75)}
.btn--primary:hover{background:var(--brand-hi);box-shadow:0 12px 26px -8px rgba(25,237,86,.85)}
.btn--dark{background:var(--ink);color:#fff}
.btn--dark:hover{background:#1d2523}
.btn--soft{background:var(--soft);color:var(--ink)}
.btn--soft:hover{background:#eceff0}
.btn--line{border:1.5px solid var(--line-2);color:var(--ink)}
.btn--line:hover{border-color:var(--ink);background:var(--soft)}
.btn svg{width:16px;height:16px;stroke:currentColor;fill:none;stroke-width:2;
  transition:transform .28s var(--ease)}
.btn:hover svg{transform:translateX(4px)}
.btn--sm{height:44px;padding:0 20px;font-size:14px}

/* ══ announcement ══ */
/* The height is declared here, not left to the spans JS injects. Before, the
   bar was 0px until the script ran and 38px after, which shoved the whole page
   down 38px and scored CLS 0.92 on a phone. */
.topbar{height:38px;background:var(--brand);color:var(--on-brand);overflow:hidden;position:relative}
.topbar__track{display:flex;width:max-content;will-change:transform}
.topbar__set{display:flex;align-items:center;flex:none}
.topbar span{display:inline-flex;align-items:center;gap:10px;padding:0 30px;height:38px;
  font-size:12.5px;font-weight:700;letter-spacing:.005em;white-space:nowrap;color:var(--on-brand)}
.topbar i{width:5px;height:5px;border-radius:50%;background:var(--on-brand);opacity:.55;flex:none}

/* ══ header ══ */
.hdr{position:sticky;top:0;z-index:60;background:#000;color:#fff;
  border-bottom:1px solid rgba(255,255,255,.08);
  transition:box-shadow .3s var(--ease)}
.hdr.stuck{box-shadow:0 10px 30px -22px rgba(0,0,0,.9)}
.hdr__in{display:flex;align-items:center;gap:clamp(14px,2.4vw,36px);height:78px;
  transition:height .3s var(--ease)}
.hdr.stuck .hdr__in{height:70px}
.brand{display:flex;align-items:center;flex:none}
/* Pinned with !important for the same reason as the age-gate mark: caching and
   image-optimisation plugins inject a blanket img{height:auto!important} to
   chase layout shift, which would otherwise draw this at its natural 750px and
   shove the whole header off screen. */
.brand{height:42px}
.brand img{height:42px!important;max-height:42px!important;width:auto!important;
  max-width:none!important;display:block!important;transition:height .3s var(--ease)}
.hdr.stuck .brand{height:38px}
.hdr.stuck .brand img{height:38px!important;max-height:38px!important}
.foot .brand{height:46px}
.foot .brand img{height:46px!important;max-height:46px!important}

.nav{display:flex;align-items:center;gap:4px;margin-inline-start:8px}
.nav>li{list-style:none;position:relative}
.nav>li>a,.nav>li>button{display:inline-flex;align-items:center;gap:6px;height:40px;padding:0 14px;
  border-radius:999px;font-size:14.5px;font-weight:600;color:#fff;
  transition:background .2s var(--ease),color .2s var(--ease)}
.nav>li>a:hover,.nav>li>button:hover,.nav>li.on>button{background:rgba(255,255,255,.1)}
.nav .chev{width:11px;height:11px;stroke:currentColor;fill:none;stroke-width:2.4;
  transition:transform .25s var(--ease)}
.nav>li.on .chev{transform:rotate(180deg)}
.drop{position:absolute;top:100%;left:0;margin-top:12px;min-width:232px;padding:8px;background:#121816;
  border:1px solid rgba(255,255,255,.12);border-radius:16px;box-shadow:0 24px 48px -20px rgba(0,0,0,.8);
  opacity:0;visibility:hidden;transform:translateY(-6px);
  transition:opacity .22s var(--ease),transform .22s var(--ease),visibility .22s}
/* invisible bridge across the gap — without it the pointer leaves the <li>
   on its way down and the panel closes before it can be clicked */
.drop::before{content:'';position:absolute;left:0;right:0;top:-14px;height:14px}
.nav>li[data-drop]{padding-bottom:2px}
.drop a{position:relative;z-index:1}
.nav>li.on .drop{opacity:1;visibility:visible;transform:none}
.drop a{display:block;padding:10px 14px;border-radius:10px;font-size:14.5px;font-weight:600;
  color:#c3ccc7;transition:background .18s,color .18s}
.drop a:hover{background:rgba(255,255,255,.09);color:#fff}

.tools{display:flex;align-items:center;gap:6px;margin-inline-start:auto;flex:none}
.icn{width:42px;height:42px;display:grid;place-items:center;border-radius:999px;color:var(--ink);
  transition:background .2s var(--ease)}
.icn:hover{background:var(--soft)}
.hdr .icn{color:#fff}
.hdr .icn:hover{background:rgba(255,255,255,.12)}
.icn svg{width:19px;height:19px;stroke:currentColor;fill:none;stroke-width:1.7}
.icn--cart{position:relative}
.cartn{position:absolute;top:2px;right:2px;min-width:19px;height:19px;padding:0 5px;border-radius:999px;
  background:var(--brand);color:var(--on-brand);font-size:11px;font-weight:800;display:grid;place-items:center;
  transform:scale(0);transition:transform .3s var(--ease)}
.icn--cart.has .cartn{transform:scale(1)}
.burger{display:none}

/* ══ hero ══ */
.hero{position:relative;overflow:hidden;padding-block:clamp(28px,4vw,58px) clamp(30px,4vw,56px)}
.hero__grid{display:grid;grid-template-columns:minmax(0,1.04fr) minmax(0,1fr);
  gap:clamp(24px,3vw,48px);align-items:center}

.pill{display:inline-flex;align-items:center;gap:9px;height:36px;padding:0 16px;border-radius:999px;
  background:var(--brand-tint);color:#0a7a30;font-size:13px;font-weight:700;
  border:1px solid rgba(11,156,59,.16)}
.pill i{width:7px;height:7px;border-radius:50%;background:var(--brand-deep);
  box-shadow:0 0 0 3px rgba(11,156,59,.16);animation:blip 2.6s var(--ease) infinite}
@keyframes blip{0%,100%{opacity:1}50%{opacity:.4}}

/* 800 is the top of Manrope's weight axis (200–800), so the headline is already
   as heavy as the family goes. What was thinning it is the site-wide
   -webkit-font-smoothing:antialiased, which strips the stroke on large display
   type; letting this one heading render with the default smoothing puts that
   weight back, and a slightly tighter track makes the line read denser still. */
h1.hero__h{margin-top:20px;font-size:clamp(31px,3.55vw,47px);line-height:1.06;letter-spacing:-.042em;
  font-weight:800;font-variation-settings:'wght' 800;
  -webkit-font-smoothing:auto;-moz-osx-font-smoothing:auto;
  text-wrap:balance}
h1.hero__h .g{color:var(--brand-text)}
.hero__lead{margin-top:20px;max-width:46ch;color:var(--ink-2);font-size:clamp(15.5px,1.15vw,17.5px);
  line-height:1.62}
.hero__cta{display:flex;flex-wrap:wrap;gap:12px;margin-top:30px}

/* ══ hero facts ══
   Desktop is the original static row: three figures separated by hairlines, no
   band, no motion. The extra five facts and the slider treatment belong to the
   phone layout only — see the 940px block below. */
.stats{margin-top:clamp(30px,3.4vw,46px)}
.stats--low{display:none}
.stats .stats__track{display:block}
.stats .stats__set{display:flex;flex-wrap:wrap;gap:clamp(18px,2.6vw,38px)}
/* Figure centred over its label, matching the phone cards. The cell is only
   as wide as its longest line, so a short figure like 24h would otherwise
   hang left of the label beneath it. */
.stats div{position:relative;text-align:center;padding-right:clamp(18px,2.6vw,38px)}
.stats div+div{border-left:1px solid var(--line);padding-left:clamp(18px,2.6vw,38px)}
.stats div:nth-child(n+4){display:none}
.stats b{display:block;font-size:clamp(24px,2.3vw,31px);font-weight:800;letter-spacing:-.035em;
  color:var(--brand-text);font-variant-numeric:tabular-nums}
.stats span{display:block;margin-top:2px;font-size:12.5px;font-weight:600;color:var(--ink-3)}

/* ══ the phone slider ══
   Below the two-column hero the three figures would be squeezed into thirds of
   a small screen, so instead all eight facts ride cards in a full-bleed band
   that drifts left to right. */
@media (max-width:940px){
  .stats--hero{display:none}
  /* the hero band breaks out of .wrap's padding with negative margins; the
     relocated one is already a full-width child of #home, so those margins
     would push it wider than the viewport */
  /* .stats.stats--low, not .stats--low — the base .stats rule below sets the
     negative margins and would otherwise win on source order */
  .stats.stats--low{display:block;margin:0}
  .stats{position:relative;overflow:hidden;margin-top:26px;padding:11px 0;
    border-block:1px solid var(--line);background:var(--soft);
    margin-left:calc(-1 * max(var(--gut), env(safe-area-inset-left, 0px)));
    margin-right:calc(-1 * max(var(--gut), env(safe-area-inset-right, 0px)))}
  /* cards dissolve at the edges rather than being guillotined */
  .stats::before,.stats::after{content:'';position:absolute;top:1px;bottom:1px;
    width:clamp(28px,7%,60px);z-index:2;pointer-events:none}
  .stats::before{left:0;background:linear-gradient(90deg,var(--soft) 30%,rgba(245,247,246,0))}
  .stats::after{right:0;background:linear-gradient(270deg,var(--soft) 30%,rgba(245,247,246,0))}
  .stats .stats__track{display:flex;width:max-content;will-change:transform}
  .stats .stats__set{display:flex;flex:none;gap:8px;padding-inline:8px}
  /* Each card is only as wide as its longest line, so a short value like "Free"
     or "Fast" hangs off the left edge above a much longer label. Centring the
     column sits the value over the middle of the card instead. */
  .stats div{flex:none;display:flex;flex-direction:column;justify-content:center;
    align-items:center;text-align:center;
    min-height:58px;padding:10px 18px;border-radius:14px;
    background:#fff;border:1px solid var(--line);
    box-shadow:0 1px 2px rgba(13,18,17,.04),0 10px 22px -16px rgba(13,18,17,.3)}
  .stats div+div{padding-left:18px}
  .stats div:nth-child(n+4){display:flex}
  .stats b{font-size:17px;letter-spacing:-.03em;line-height:1.15;white-space:nowrap}
  .stats span{margin-top:3px;font-size:11.5px;line-height:1.3;white-space:nowrap}
  /* reduce-motion: the row holds still and is scrolled by hand */
  .stats .stats__track[data-static]{width:100%;overflow-x:auto;
    scrollbar-width:none;will-change:auto}
  .stats .stats__track[data-static]::-webkit-scrollbar{display:none}
}

/* ══ benefits marquee ══
   Separate cards rather than one ruled strip: each benefit reads as its own
   object, which survives being clipped at the band's edges far better than a
   continuous row of dividers. Light band, white cards, at every width. */
/* The cards are written by site.js, so without a reserved height this strip is
   just its own padding until the script runs and then jumps to full size,
   shoving the catalogue down with it. Measured from the rendered strip. */
.belt{min-height:145px;position:relative;background:var(--soft);border-block:1px solid var(--line);
  overflow:hidden;padding-block:16px}
/* cards dissolve at the edges instead of being cut mid-word */
.belt::before,.belt::after{content:'';position:absolute;top:1px;bottom:1px;
  width:clamp(34px,5%,80px);z-index:2;pointer-events:none}
.belt::before{left:0;background:linear-gradient(90deg,var(--soft) 30%,rgba(245,247,246,0))}
.belt::after{right:0;background:linear-gradient(270deg,var(--soft) 30%,rgba(245,247,246,0))}
.belt__track{display:flex;width:max-content;will-change:transform}
.belt__set{display:flex;flex:none;gap:12px;padding-right:12px}
.belt__i{display:flex;align-items:center;gap:14px;width:340px;padding:16px 20px;
  border-radius:16px;background:#fff;border:1px solid var(--line);
  box-shadow:0 1px 2px rgba(13,18,17,.04),0 10px 22px -16px rgba(13,18,17,.3)}
.belt__i svg{width:22px;height:22px;stroke:var(--brand-deep);fill:none;stroke-width:1.7;flex:none}
.belt__i b{display:block;font-size:14px;font-weight:800;letter-spacing:-.02em}
.belt__i span{display:block;font-size:12.5px;color:var(--ink-2);line-height:1.45}
.belt__s{display:none}
@media (max-width:640px){
  /* title plus one short line — the full sentence wraps to four lines at this
     width and makes the strip taller than the product row underneath it */
  .belt{min-height:61px;padding-block:6px}
  .belt__set{gap:7px;padding-right:7px}
  .belt__i{width:auto;max-width:260px;padding:8px 13px;gap:9px;border-radius:14px}
  .belt__i svg{width:17px;height:17px}
  .belt__i b{font-size:12px;line-height:1.2;white-space:nowrap}
  .belt__i span{display:none}
  .belt__s{display:block;margin-top:1px;font-style:normal;font-size:11px;line-height:1.3;
    color:var(--ink-2);white-space:nowrap}
}

/* ══ hero facts ══
   Desktop is the original static row: three figures separated by hairlines, no
   band, no motion. The extra five facts and the slider treatment belong to the
   phone layout only — see the 940px block below. */
.stats{margin-top:clamp(30px,3.4vw,46px)}
.stats .stats__track{display:block}
.stats .stats__set{display:flex;flex-wrap:wrap;gap:clamp(18px,2.6vw,38px)}
/* Figure centred over its label, matching the phone cards. The cell is only
   as wide as its longest line, so a short figure like 24h would otherwise
   hang left of the label beneath it. */
.stats div{position:relative;text-align:center;padding-right:clamp(18px,2.6vw,38px)}
.stats div+div{border-left:1px solid var(--line);padding-left:clamp(18px,2.6vw,38px)}
.stats div:nth-child(n+4){display:none}
.stats b{display:block;font-size:clamp(24px,2.3vw,31px);font-weight:800;letter-spacing:-.035em;
  color:var(--brand-text);font-variant-numeric:tabular-nums}
.stats span{display:block;margin-top:2px;font-size:12.5px;font-weight:600;color:var(--ink-3)}

/* ══ the phone slider ══
   Below the two-column hero the three figures would be squeezed into thirds of
   a small screen, so instead all eight facts ride cards in a full-bleed band
   that drifts left to right. */
@media (max-width:940px){
  .stats{position:relative;overflow:hidden;margin-top:26px;padding:11px 0;
    border-block:1px solid var(--line);background:var(--soft);
    margin-left:calc(-1 * max(var(--gut), env(safe-area-inset-left, 0px)));
    margin-right:calc(-1 * max(var(--gut), env(safe-area-inset-right, 0px)))}
  /* cards dissolve at the edges rather than being guillotined */
  .stats::before,.stats::after{content:'';position:absolute;top:1px;bottom:1px;
    width:clamp(28px,7%,60px);z-index:2;pointer-events:none}
  .stats::before{left:0;background:linear-gradient(90deg,var(--soft) 30%,rgba(245,247,246,0))}
  .stats::after{right:0;background:linear-gradient(270deg,var(--soft) 30%,rgba(245,247,246,0))}
  .stats .stats__track{display:flex;width:max-content;will-change:transform}
  .stats .stats__set{display:flex;flex:none;gap:8px;padding-inline:8px}
  /* Each card is only as wide as its longest line, so a short value like "Free"
     or "Fast" hangs off the left edge above a much longer label. Centring the
     column sits the value over the middle of the card instead. */
  .stats div{flex:none;display:flex;flex-direction:column;justify-content:center;
    align-items:center;text-align:center;
    min-height:58px;padding:10px 18px;border-radius:14px;
    background:#fff;border:1px solid var(--line);
    box-shadow:0 1px 2px rgba(13,18,17,.04),0 10px 22px -16px rgba(13,18,17,.3)}
  .stats div+div{padding-left:18px}
  .stats div:nth-child(n+4){display:flex}
  .stats b{font-size:17px;letter-spacing:-.03em;line-height:1.15;white-space:nowrap}
  .stats span{margin-top:3px;font-size:11.5px;line-height:1.3;white-space:nowrap}
  /* reduce-motion: the row holds still and is scrolled by hand */
  .stats .stats__track[data-static]{width:100%;overflow-x:auto;
    scrollbar-width:none;will-change:auto}
  .stats .stats__track[data-static]::-webkit-scrollbar{display:none}
}

/* ══ sections ══ */
.sec{padding-block:clamp(52px,6vw,92px)}
.sec--soft{background:var(--soft)}
.shead{display:flex;align-items:flex-end;justify-content:space-between;gap:24px;flex-wrap:wrap;
  margin-bottom:clamp(24px,2.6vw,34px)}
.shead h2{font-size:clamp(28px,3.2vw,44px)}
.shead p{margin-top:12px;color:var(--ink-2);max-width:52ch;font-size:15.5px}
.kick{display:inline-block;margin-bottom:14px;font-size:12px;font-weight:800;letter-spacing:.14em;
  text-transform:uppercase;color:var(--brand-text)}
.center{text-align:center}
.center .shead{flex-direction:column;align-items:center}
.center p{margin-inline:auto}

/* ══ filters ══ */
/* One line, always. Eight chips wrapped onto a second row at desktop widths,
   which read as an overflow rather than a design. They are a shade smaller now
   so the full set fits, and the row scrolls sideways rather than wrapping if a
   narrower window still cannot hold them — the same behaviour the phone
   already had. margin-inline and padding-inline must stay equal or the row
   drags the page sideways. */
.chips{display:flex;gap:6px;flex-wrap:nowrap;overflow-x:auto;margin-bottom:26px;
  scrollbar-width:none;-ms-overflow-style:none;
  margin-inline:calc(var(--gut) * -1);padding-inline:var(--gut)}
.chips::-webkit-scrollbar{display:none}
.chip{flex:none;height:36px;padding:0 12px;border-radius:999px;border:1.5px solid var(--line);
  font-size:13px;font-weight:700;color:var(--ink-2);display:inline-flex;align-items:center;gap:7px;
  transition:background-color .22s var(--ease),border-color .22s var(--ease),color .22s var(--ease)}
.chip:hover{border-color:var(--line-2);color:var(--ink)}
.chip[aria-pressed="true"]{background:var(--ink);border-color:var(--ink);color:#fff}
.chip u{text-decoration:none;font-size:11px;opacity:.55}

/* ══ product grid ══ */
.grid{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:clamp(12px,1.2vw,18px)}
.pc{position:relative;background:#fff;border:1px solid var(--line);border-radius:16px;overflow:hidden;
  display:flex;flex-direction:column;transition:box-shadow .32s var(--ease),transform .32s var(--ease),
  border-color .32s var(--ease)}
.pc:hover{box-shadow:var(--shadow-lg);transform:translateY(-4px);border-color:var(--line-2)}
.pc.hide{display:none}
.pc__media{position:relative;background:var(--well);display:flex;align-items:center;justify-content:center;
  aspect-ratio:1/1;overflow:hidden}
.pc__media img{width:100%;height:100%;object-fit:cover;transition:transform .6s var(--ease)}
.pc:hover .pc__media img{transform:scale(1.045)}
.pc__quick{position:absolute;top:12px;left:12px;width:38px;height:38px;border-radius:999px;background:#fff;
  display:grid;place-items:center;box-shadow:var(--shadow);z-index:2;
  transition:background .2s var(--ease),color .2s var(--ease),transform .2s var(--ease)}
.pc__quick svg{width:17px;height:17px;stroke:currentColor;fill:none;stroke-width:1.7}
@media (hover:hover){
  .pc__quick:hover{background:var(--brand);color:var(--on-brand);transform:scale(1.07)}
}
.pc__body{padding:16px 16px 18px;display:flex;flex-direction:column;flex:1}
.tag{display:inline-block;align-self:flex-start;padding:4px 10px;border-radius:6px;font-size:10.5px;
  font-weight:800;letter-spacing:.05em;text-transform:uppercase;background:var(--brand-tint);color:#0a7a30}
.tag--n{background:#eef1f3;color:#5a6570}
/* A product can carry two categories, so the tag is now a row rather than a
   single chip. align-self moves to the wrapper — .tag keeps its own so a lone
   tag elsewhere on the site is unaffected. Wraps on a narrow card rather than
   pushing the name out of the way. */
.tags{display:flex;flex-wrap:wrap;gap:5px;align-self:flex-start}
.tags .tag{align-self:auto}
/* On a phone a product card is 135-170px of content and a single category chip
   is 92-128px of it, so two names can never share a line — three categories
   would always cost three rows and push the price down the card. The card shows
   the first two; the product page still lists every category, and the product
   still appears under all of them in search, the category pages and the sliding
   rows. Shrinking the type was the alternative and it would have needed a ~5px
   font to fit two names on one line. */
@media (max-width:640px){
  .pc .tags .tag:nth-child(n+3){display:none}
}
.pc h3{margin-top:10px;font-size:17px;letter-spacing:-.028em}
.pc__sizes{display:flex;gap:6px;flex-wrap:wrap;margin-top:12px}
.size{height:28px;padding:0 10px;border-radius:8px;border:1.5px solid var(--line);font-size:12px;
  font-weight:700;color:var(--ink-2);display:inline-flex;align-items:center;
  transition:background-color .2s var(--ease),border-color .2s var(--ease),color .2s var(--ease)}
.size:hover{border-color:var(--line-2)}
/* The chosen dosage is a decision the shopper has made, so it carries the
   brand colour rather than plain ink — the same green as every other active
   state on the site. Black read as disabled next to the green Add button
   directly beneath it. */
.size.on{border-color:var(--brand);color:var(--on-brand);background:var(--brand)}
.size.on:hover{border-color:var(--brand)}
.pc__foot{display:flex;align-items:flex-end;justify-content:space-between;gap:10px;margin-top:auto;
  padding-top:16px}
.pc__foot .add{flex:none;white-space:nowrap}
.price{font-size:16px;font-weight:800;letter-spacing:-.02em;min-width:0}
/* the reference takes its own line so the live figure and its qualifier stay
   together on one, whatever the card width */
.price__ref{display:block;margin-bottom:1px;font-size:12px;font-weight:600;color:var(--ink-3);
  text-decoration:line-through;text-decoration-thickness:1.5px;line-height:1.2}
.price__l{display:flex;align-items:baseline;gap:5px;white-space:nowrap}
/* The qualifier is a phone treatment: a wide card has room for the dosage
   buttons, so the figure there is already tied to a chosen size and "From"
   only adds noise. A phone card hides those buttons, so it needs the word. */
.price em{display:none;font-style:normal;font-size:12px;font-weight:600;color:var(--ink-3);margin-right:5px}
.add{height:38px;padding:0 16px;border-radius:999px;background:var(--soft);font-size:13px;font-weight:800;
  display:inline-flex;align-items:center;gap:6px;
  transition:background-color .22s var(--ease),color .22s var(--ease),transform .22s var(--ease)}
@media (hover:hover){ .add:hover{background:var(--brand);color:var(--on-brand)} }
/* the grid's .add is a soft pill, but on the product page the same class
   sits on the primary CTA — keep the primary treatment there */
.btn--primary.add{background:var(--brand);color:var(--on-brand)}
@media (hover:hover){ .btn--primary.add:hover{background:var(--brand-hi)} }
.add.done{background:var(--brand);color:var(--on-brand)}
.more{display:flex;justify-content:center;margin-top:clamp(28px,3vw,40px)}

/* ══ whole card is the link ══
   A stretched pseudo-element over the card makes the entire tile clickable;
   the size chips, add button and quick-add sit above it so they still work. */
.pc h3 a::after{content:'';position:absolute;inset:0;z-index:1}
/* these sit above the stretched link so they stay independently clickable.
   .pc__quick keeps its own absolute placement — setting position:relative
   here would drop it out of the image's top-left corner. */
.pc__sizes,.pc__foot{position:relative;z-index:2}
.pc__quick{z-index:3}
.pc{cursor:pointer}

/* ══ product page: quantity, breaks, water notice, COA ══ */
.qsel{display:inline-flex;align-items:center;gap:4px;margin-top:10px;border:1.5px solid var(--line-2);
  border-radius:999px;padding:4px}
.qsel button{width:40px;height:40px;border-radius:999px;display:grid;place-items:center;
  font-size:19px;font-weight:800;color:var(--ink-2);transition:background .18s var(--ease)}
.qsel button:hover{background:var(--soft);color:var(--ink)}
.qsel b{min-width:34px;text-align:center;font-size:16px;font-weight:800;font-variant-numeric:tabular-nums}
.breaks{list-style:none;display:flex;gap:8px;margin:18px 0 0;padding:0}
.breaks li{flex:1;border:1.5px solid var(--line);border-radius:12px;padding:10px 8px;text-align:center;
  transition:border-color .2s var(--ease),background .2s var(--ease)}
.breaks li.on{border-color:var(--brand-deep);background:var(--brand-tint)}
.breaks b{display:block;font-size:16px;font-weight:800;letter-spacing:-.02em}
.breaks span{display:block;margin-top:2px;font-size:12px;font-weight:700;color:var(--ink-3)}
.breaks li.on span{color:var(--brand-text)}

/* ── Certificate of Analysis: a disclosure, not a wall ──────────────────
   Collapsed it is one row — the claim and the number behind it. Expanding
   reveals the measured figures and then the laboratory's own document, in
   full, in the page. Nothing about the certificate is redrawn or summarised
   in place of it; the figures below are the ones printed on it. */
/* The quiet alternative to the certificate panel, for a product with no
   published report. Deliberately lighter than .coabox — no shadow, no accent
   border, no status pill — so it reads as one more link on the page rather
   than a box announcing something is absent. */
.coalink{display:flex;align-items:center;gap:13px;margin-top:26px;padding:14px 16px;
  border:1px solid var(--line);border-radius:18px;background:#fff;color:inherit;
  text-decoration:none;transition:border-color .2s var(--ease),background .2s var(--ease)}
.coalink:hover{border-color:var(--line-2);background:var(--well)}
.coalink__ico{display:grid;place-items:center;width:38px;height:38px;flex:none;
  border-radius:11px;background:var(--well);color:var(--ink-2)}
.coalink__ico svg{width:18px;height:18px;fill:none;stroke:currentColor;stroke-width:1.7;
  stroke-linecap:round;stroke-linejoin:round}
.coalink__t{display:flex;flex-direction:column;gap:2px;min-width:0}
.coalink__t b{font-size:14.5px;font-weight:800;letter-spacing:-.01em}
.coalink__t span{font-size:12.5px;color:var(--ink-3);line-height:1.45}
.coalink__go{margin-left:auto;flex:none;color:var(--ink-3);transition:transform .2s var(--ease)}
.coalink__go svg{width:17px;height:17px;fill:none;stroke:currentColor;stroke-width:1.8;
  stroke-linecap:round;stroke-linejoin:round;display:block}
.coalink:hover .coalink__go{transform:translateX(3px);color:var(--ink)}
@media (max-width:640px){
  .coalink{gap:11px;padding:13px 14px}
  .coalink__ico{width:34px;height:34px}
}

.coabox{margin-top:26px;border:1px solid var(--line);border-radius:18px;background:#fff;
  box-shadow:var(--shadow);overflow:hidden}
.coabox--has{border-color:rgba(11,156,59,.28)}

.coabox__top{display:flex;align-items:center;gap:12px;width:100%;padding:14px 16px;
  border:0;background:#fff;font:inherit;color:inherit;text-align:left;cursor:pointer;
  transition:background .2s var(--ease)}
.coabox__top--flat{cursor:default}
@media (hover:hover){.coabox__top:not(.coabox__top--flat):hover{background:var(--soft)}}
.coabox__top:focus-visible{outline:2px solid var(--brand-deep);outline-offset:-2px}
.coabox__ico{flex:none;width:42px;height:42px;border-radius:13px;display:grid;place-items:center;
  background:var(--brand-tint);border:1px solid rgba(11,156,59,.18)}
.coabox__ico svg{width:20px;height:20px;fill:none;stroke:var(--brand-deep);stroke-width:1.7;
  stroke-linejoin:round;stroke-linecap:round}
.coabox__ttl{flex:1 1 auto;min-width:0;font-size:16px;font-weight:800;letter-spacing:-.025em;
  line-height:1.25;text-wrap:balance}
.coabox__pct{flex:none;padding:6px 12px;border-radius:999px;background:var(--brand-tint);
  color:#0a7a30;font-size:13px;font-weight:800;letter-spacing:-.01em;white-space:nowrap;
  font-variant-numeric:tabular-nums}
.coabox__pct--n{background:var(--soft);color:var(--ink-3)}
.coabox__chev{flex:none;width:20px;height:20px;fill:none;stroke:var(--ink-3);stroke-width:2;
  stroke-linecap:round;stroke-linejoin:round;transition:transform .3s var(--ease)}
.coabox.open .coabox__chev{transform:rotate(180deg);stroke:var(--ink)}

/* 0fr → 1fr animates the panel open without measuring anything */
.coabox__wrap{display:grid;grid-template-rows:0fr;transition:grid-template-rows .34s var(--ease)}
.coabox.open .coabox__wrap{grid-template-rows:1fr}
.coabox__panel{min-height:0;overflow:hidden}
.coabox__inner{padding:2px 16px 16px}
@media (prefers-reduced-motion:reduce){
  .coabox__wrap{transition:none}
  .coabox__chev{transition:none}
  /* the gate is the first thing a visitor meets — it must not move for
     someone who has asked the system for less motion */
  .gate__card{animation:none}
  .btn:active,.tier2:active,.verify:active{transform:none}
}

.coabox__d{display:grid;grid-template-columns:1fr 1fr;gap:1px;margin:0;
  background:var(--line);border:1px solid var(--line);border-radius:14px;overflow:hidden}
.coabox__d>div{background:var(--soft);padding:11px 13px}
.coabox__d dt{margin:0;font-size:10px;font-weight:800;letter-spacing:.11em;text-transform:uppercase;
  color:var(--ink-3)}
.coabox__d dd{margin:4px 0 0;font-size:14.5px;font-weight:800;letter-spacing:-.02em;
  font-variant-numeric:tabular-nums;overflow-wrap:anywhere}
.coabox__hero{font-size:19px;color:var(--brand-text)}

/* the laboratory's document, whole, inside the page */
.coabox__doc{display:block;position:relative;width:100%;margin-top:12px;padding:0;
  border:1px solid var(--line);border-radius:14px;overflow:hidden;background:var(--soft);
  cursor:zoom-in;-webkit-tap-highlight-color:transparent}
.coabox__doc img{display:block;width:100%;height:auto;background:#fff;
  transition:transform .45s var(--ease)}
.coabox__doc:focus-visible{outline:2px solid var(--brand-deep);outline-offset:2px}
@media (hover:hover){.coabox__doc:hover img{transform:scale(1.012)}}
.coabox__mag{position:absolute;right:12px;bottom:12px;display:inline-flex;align-items:center;gap:7px;
  padding:8px 14px;border-radius:999px;background:rgba(9,12,11,.86);color:#fff;
  font-size:12.5px;font-weight:800;letter-spacing:-.01em;
  backdrop-filter:blur(6px);-webkit-backdrop-filter:blur(6px)}
.coabox__mag svg{width:14px;height:14px;fill:none;stroke:currentColor;stroke-width:2;
  stroke-linecap:round}
.coabox__cta{width:100%;margin-top:14px}
/* The header has to hold title, figure and chevron on one line: on a phone the
   fixed furniture gives up width in steps so the title never wraps. */
@media (max-width:430px){
  .coabox__top{gap:9px;padding:12px 14px}
  .coabox__ico{width:34px;height:34px;border-radius:11px}
  .coabox__ico svg{width:17px;height:17px}
  .coabox__ttl{font-size:15px}
  .coabox__pct{padding:5px 10px;font-size:12px}
  .coabox__inner{padding:2px 14px 14px}
}
@media (max-width:374px){
  .coabox__top{gap:8px;padding:11px 13px}
  .coabox__ico{width:30px;height:30px;border-radius:10px}
  .coabox__ttl{font-size:14px}
  .coabox__pct{padding:5px 9px;font-size:11.5px}
  .coabox__inner{padding:2px 13px 13px}
}
@media (max-width:359px){
  .coabox__ico{display:none}
  .coabox__d{grid-template-columns:1fr}
}
.coabox__view{flex:1 1 60%}
.coabox__verify{flex:1 1 30%}
.coabox__row .btn svg{width:15px;height:15px;stroke:currentColor;fill:none;stroke-width:1.8;
  stroke-linejoin:round;stroke-linecap:round}
.coabox__row .btn:hover svg{transform:none}

/* ══ quantity tiers ══
   Three cards, each showing what one vial costs at that quantity, so the
   saving is a price the shopper can read rather than a percentage to apply. */
.pdp__lbl--tier{margin-top:24px}
.tiers2{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:8px;margin-top:10px}
.tier2{position:relative;display:flex;flex-direction:column;align-items:center;gap:3px;
  padding:13px 8px 11px;border:1.5px solid var(--line);border-radius:14px;background:#fff;
  text-align:center;cursor:pointer;
  transition:border-color .2s var(--ease),background .2s var(--ease),
             box-shadow .25s var(--ease),transform .18s var(--ease)}
.tier2__q{font-size:14.5px;font-weight:800;letter-spacing:-.02em;color:var(--ink)}
.tier2__u{display:flex;flex-direction:column;align-items:center;gap:1px;
  font-size:12.5px;font-weight:700;color:var(--ink-3);font-variant-numeric:tabular-nums;
  line-height:1.25}
.tier2__u s{font-size:11px;font-weight:700;color:var(--ink-3);opacity:.75;text-decoration-thickness:1px}
.tier2__u span{display:block}
.tier2__u b{font-size:13.5px;font-weight:800;color:var(--ink);letter-spacing:-.02em}
.tier2.on .tier2__u b{color:var(--ink)}
.tier2__b{margin-top:4px;padding:3px 9px;border-radius:999px;background:var(--brand-tint);
  color:#0a7a30;font-size:10.5px;font-weight:800;letter-spacing:.05em;text-transform:uppercase;
  white-space:nowrap}
.tier2__b--flat{background:var(--soft);color:var(--ink-3)}
.tier2.on{border-color:var(--ink);box-shadow:0 0 0 1.5px var(--ink) inset,var(--shadow)}
.tier2.on .tier2__u{color:var(--ink-2)}
.tier2.on .tier2__b{background:var(--brand);color:var(--on-brand)}
.tier2.on .tier2__b--flat{background:var(--ink);color:#fff}
.tier2:active{transform:scale(.96)}
@media (hover:hover){.tier2:hover{border-color:var(--line-2)}.tier2.on:hover{border-color:var(--ink)}}

/* ══ the purchase panel ══
   Dosage, quantity, what buying more costs each, the water the vial needs,
   then the total — one bordered block so the buying decision reads as one
   thing, and the width is used rather than trailing off to the right. */
.buy{margin-top:20px;border:1px solid var(--line);border-radius:18px;background:#fff;
  box-shadow:var(--shadow);overflow:hidden}
.buy__sec{padding:15px 16px;border-bottom:1px solid var(--line)}
.buy__sec .pdp__lbl{margin-top:0}
.buy__sec .pc__sizes{margin-top:9px}
.buy__sec .tiers2{margin-top:11px}
.buy__row{display:flex;align-items:center;justify-content:space-between;gap:14px}
.buy__sec--one{display:flex;align-items:center;justify-content:space-between;gap:14px}
.buy__sec--one .pc__sizes{margin-top:0}
.buy__row .qsel{margin-top:0}

.buy__req{display:flex;align-items:center;gap:8px;font-size:10.5px;font-weight:800;
  letter-spacing:.11em;text-transform:uppercase;color:var(--brand-text)}
.buy__dot{width:7px;height:7px;border-radius:999px;background:var(--brand);flex:none;
  box-shadow:0 0 0 3px var(--brand-tint)}

/* the water add-on: its own line, its own price, ticked but never locked */
.wrow{display:flex;align-items:center;gap:11px;margin-top:11px;padding:10px 11px;
  border:1.5px solid var(--line);border-radius:14px;background:var(--soft);cursor:pointer;
  transition:border-color .2s var(--ease),background .2s var(--ease)}
.wrow__cb{position:absolute;opacity:0;width:0;height:0}
.wrow__box{flex:none;width:22px;height:22px;border-radius:7px;border:1.8px solid var(--line-2);
  background:#fff;display:grid;place-items:center;
  transition:background .18s var(--ease),border-color .18s var(--ease)}
.wrow__box svg{width:13px;height:13px;fill:none;stroke:#fff;stroke-width:3.2;
  stroke-linecap:round;stroke-linejoin:round;opacity:0;transform:scale(.4);
  transition:opacity .18s var(--ease),transform .18s var(--ease)}
.wrow__cb:checked+.wrow__box{background:var(--brand-deep);border-color:var(--brand-deep)}
.wrow__cb:checked+.wrow__box svg{opacity:1;transform:none}
.wrow__cb:focus-visible+.wrow__box{outline:2px solid var(--brand-deep);outline-offset:2px}
.wrow__img{flex:none;width:38px;height:38px;border-radius:10px;object-fit:cover;background:#fff;
  border:1px solid rgba(0,0,0,.06)}
.wrow__t{flex:1 1 auto;min-width:0;display:flex;flex-direction:column;gap:2px}
.wrow__t b{font-size:14px;font-weight:800;letter-spacing:-.02em;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.wrow__t i{font-style:normal;font-size:11.5px;font-weight:700;color:var(--ink-3)}
.wrow__p{flex:none;display:flex;flex-direction:column;align-items:flex-end;gap:2px;
  font-variant-numeric:tabular-nums}
.wrow__p b{font-size:14.5px;font-weight:800;letter-spacing:-.02em;white-space:nowrap}
.wrow__p i{font-style:normal;font-size:11px;font-weight:700;color:var(--ink-3);white-space:nowrap}
.wrow.off{background:#fff;border-color:var(--line)}
.wrow.off .wrow__t b,.wrow.off .wrow__p b{color:var(--ink-3)}
@media (hover:hover){.wrow:hover{border-color:var(--line-2)}}
.wrow__n{margin:9px 2px 0;font-size:11.5px;line-height:1.5;color:var(--ink-3)}

.buy__total{display:flex;align-items:center;justify-content:space-between;gap:14px;
  padding:15px 16px;background:var(--soft)}
.buy__tl{font-size:11px;font-weight:800;letter-spacing:.11em;text-transform:uppercase;
  color:var(--ink-3)}
.buy__tv{display:flex;flex-direction:column;align-items:flex-end;gap:2px}
.buy__tv b{font-size:24px;font-weight:800;letter-spacing:-.03em;
  font-variant-numeric:tabular-nums;line-height:1.1}
.buy__tv i:not(:empty){font-style:normal;padding:2px 9px;border-radius:999px;
  background:var(--brand-tint);color:#0a7a30;font-size:11.5px;font-weight:800}

/* the CTA owns the moment: nothing beside it, nothing outlined competing */
.pdp__buy{display:block;margin-top:14px}
.pdp__buy .add{width:100%;height:58px;font-size:17px;border-radius:999px}
/* a link, not a button — but still a 42px target */
.stacklink{display:inline-flex;align-items:center;gap:7px;margin-top:10px;padding:11px 4px;
  font-size:13.5px;font-weight:800;color:var(--ink-2);letter-spacing:-.01em;
  transition:color .2s var(--ease)}
.stacklink svg{width:15px;height:15px;fill:none;stroke:currentColor;stroke-width:2;
  stroke-linecap:round;stroke-linejoin:round;transition:transform .22s var(--ease)}
@media (hover:hover){.stacklink:hover{color:var(--brand-text)}
  .stacklink:hover svg{transform:translateX(3px)}}

/* ══ COA viewer ══ */
.coav{position:fixed;inset:0;z-index:130;display:grid;place-items:center;padding:20px;
  background:rgba(9,12,11,.55);backdrop-filter:blur(6px);-webkit-backdrop-filter:blur(6px);
  opacity:0;transition:opacity .22s var(--ease)}
.coav.open{opacity:1}
.coav[hidden]{display:none}
/* The card hugs the page: --cw is measured from the document's own aspect
   ratio so the sheet is page-shaped, not a wide box with grey gutters. */
.coav__card{width:min(var(--cw,760px),100%);height:min(96vh,1180px);max-height:calc(100vh - 40px);background:#fff;border-radius:20px;
  display:flex;flex-direction:column;overflow:hidden;box-shadow:0 40px 90px -30px rgba(0,0,0,.55);
  transform:translateY(8px) scale(.99);transition:transform .28s var(--ease)}
.coav.open .coav__card{transform:none}
.coav__top{display:flex;align-items:center;justify-content:space-between;gap:14px;
  padding:14px 16px 14px 18px;border-bottom:1px solid var(--line)}
.coav__ttl{min-width:0}
.coav__top b{display:block;font-size:15px;letter-spacing:-.02em;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.coav__src{display:block;margin-top:3px;font-size:11.5px;font-weight:700;color:var(--ink-3);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

/* the document itself: a scrollable stage the customer can zoom and pan */
.coav__stage{flex:1;min-height:0;overflow:auto;background:#f4f6f5;
  -webkit-overflow-scrolling:touch;overscroll-behavior:contain;
  touch-action:pan-x pan-y;scrollbar-width:thin}
.coav__sheet{padding:16px;display:flex;flex-direction:column;justify-content:center;
  min-height:100%;box-sizing:border-box}
/* Width, not transform: the scroll container then sees the zoomed size and
   pans natively. --fitw is the width at which the WHOLE page fits the stage,
   measured on open from the file's own proportions, so zoom 1 = fit page.
   Auto margins centre it while it fits and collapse to the left edge once it
   is wider than the stage, so nothing is ever clipped. */
.coav__doc{display:block;margin:0 auto;flex:0 0 auto;
  width:calc(var(--z,1) * var(--fitw,100%));max-width:none;height:auto;
  border-radius:8px;background:#fff;box-shadow:0 10px 30px -14px rgba(0,0,0,.35);
  cursor:zoom-in;-webkit-user-select:none;user-select:none;-webkit-user-drag:none}
.coav__stage.z .coav__doc{cursor:grab}
.coav__stage.drag .coav__doc{cursor:grabbing}
.coav__bar{display:flex;align-items:center;gap:8px;flex-wrap:wrap;
  padding:12px 16px;border-top:1px solid var(--line);background:#fff}
.coav__zoom{display:flex;align-items:center;gap:2px;padding:3px;
  border:1px solid var(--line);border-radius:999px;background:var(--soft)}
.coav__zoom button{width:34px;height:34px;display:grid;place-items:center;border:0;border-radius:999px;
  background:transparent;color:var(--ink);cursor:pointer;font:inherit;
  transition:background .18s var(--ease),color .18s var(--ease)}
.coav__zoom button:disabled{opacity:.35;cursor:default}
.coav__zoom svg{width:17px;height:17px;fill:none;stroke:currentColor;stroke-width:1.9;
  stroke-linecap:round}
.coav__pct{min-width:56px;text-align:center;font-size:12.5px;font-weight:800;
  font-variant-numeric:tabular-nums;color:var(--ink-2)}
.coav__acts{display:flex;gap:8px;flex-wrap:wrap;margin-left:auto}
.coav__acts .btn{flex:0 0 auto;min-width:0}
.coav__hint{width:100%;margin:0;font-size:11.5px;line-height:1.5;color:var(--ink-3)}
.coav__vl{margin-left:-6px}
@media (max-width:359px){
  .coav__vl{display:none}
  /* a batch number is an identifier: one field per row so it never
     breaks across two lines on the narrowest phones */
  .coabox__d{grid-template-columns:1fr}
}
.coav__pdf{width:100%;height:min(76vh,860px);border:0;display:block;background:var(--soft)}
/* short laptop screens: give every spare pixel to the page */
@media (min-width:701px) and (max-height:820px){
  .coav__hint{display:none}
  .coav__sheet{padding:12px}
  .coav__bar{padding:10px 16px}
}
.coav__none{margin:0;padding:24px 6px;max-width:46ch;font-size:13.5px;line-height:1.6;color:var(--ink-3)}
.coabox__n{margin-top:12px;font-size:12.5px;line-height:1.55;color:var(--ink-3)}
.coabox__n b{color:var(--ink-2);font-weight:800}
.coabox__row{display:flex;gap:8px;flex-wrap:wrap;margin-top:14px}
.coabox__row .btn{flex:1 1 180px}

/* ══ cart: discounts, add-on, totals ══ */
.ci__off,.ci__hint{display:block;margin-top:4px;font-style:normal;font-size:11.5px;font-weight:800;
  letter-spacing:.01em}
.ci__off{color:var(--brand-text)}
.ci__hint{color:var(--ink-3)}
/* Struck figure and live figure share one line, old on the left so the eye
   reads the drop in the direction it already scans. */
.ci__p{display:flex;align-items:baseline;justify-content:flex-end;gap:7px;flex-wrap:wrap}
.ci__was{text-decoration:line-through;color:var(--ink-3);font-size:12px;font-weight:600;
  text-decoration-thickness:1.5px}
/* the live figure goes green only when there is something to compare it to */
.ci__now{color:var(--brand-text)}
.ci__save{display:block;margin-top:4px;font-style:normal;font-size:11.5px;font-weight:800;
  letter-spacing:-.005em;color:var(--brand-text)}
.ci--addon img{opacity:.9}
.qty__rm{width:26px;height:26px;border-radius:999px;display:grid;place-items:center;color:var(--ink-3);
  margin-left:2px;transition:background .18s,color .18s}
.qty__rm:hover{background:var(--soft);color:#c0392b}
.qty__rm svg{width:14px;height:14px;stroke:currentColor;fill:none;stroke-width:1.8;
  stroke-linecap:round;stroke-linejoin:round}
.cart__lines{margin-bottom:4px}
.crow{display:flex;justify-content:space-between;align-items:baseline;gap:12px;padding:5px 0;
  font-variant-numeric:tabular-nums;
  font-size:13.5px;color:var(--ink-2)}
.crow em{font-style:normal;display:inline-block;margin-left:6px;padding:2px 7px;border-radius:999px;
  background:var(--soft);border:1px solid var(--line);font-size:10px;font-weight:800;
  letter-spacing:.06em;text-transform:uppercase;color:var(--ink-3)}
.crow--save{color:var(--brand-text);font-weight:800}
/* zero-height trip wire; the observer's rootMargin does the anticipating */
.gsent{height:1px;margin:0;pointer-events:none}
/* newly revealed cards ease in rather than snapping into the layout */
@keyframes pcin{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:none}}
.pc--new{animation:pcin .34s var(--ease) both}

/* ══ quality split ══ */
.split{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1.02fr);gap:clamp(28px,4vw,68px);
  align-items:center}
/* The browser's default ul padding-inline-start was never reset here, so this
   list sat 40px right of the kicker, heading, paragraph and button it belongs
   with — a second left edge nobody chose. The tick now starts on the same line
   as everything else in the block. */
.ticks{margin-top:26px;display:grid;gap:14px;padding-left:0;margin-left:0}
.ticks li{list-style:none;display:flex;gap:12px;color:var(--ink-2);font-size:15.5px;line-height:1.5}
.ticks svg{width:21px;height:21px;flex:none;margin-top:1px}
/* "Tested by content" with its one-line explanation, used wherever a batch has
   no purity percentage. The note is the same size as a caption so it reads as
   an aside rather than competing with the figure it replaces. */
.coa__na,.coabox__na{display:block;font-size:15px;font-weight:800;letter-spacing:-.02em;
  color:var(--ink);line-height:1.2}
.coa__na i,.coabox__na i{display:block;margin-top:4px;font-style:normal;font-size:11.5px;
  font-weight:600;line-height:1.35;color:var(--ink-3);letter-spacing:0;text-wrap:pretty}
@media (max-width:640px){
  .coa__na,.coabox__na{font-size:14px}
  .coa__na i,.coabox__na i{font-size:11px}
}

/* ══ certificate carousel ══
   The card itself is untouched — same size, same position, same styling. The
   wrapper only adds the two arrows and a quiet counter around it. */
.coawrap{position:relative;display:grid;align-items:center;
  grid-template-columns:auto minmax(0,1fr) auto;
  grid-template-areas:"prev card next" "count count count";
  gap:0 clamp(8px,1.4vw,18px)}
.coawrap .coa{grid-area:card}
.coanav--prev{grid-area:prev}
.coanav--next{grid-area:next}
.coawrap__count{grid-area:count}
.coanav{display:grid;place-items:center;width:44px;height:44px;border-radius:999px;
  background:#fff;border:1px solid var(--line);color:var(--ink);cursor:pointer;
  box-shadow:0 1px 2px rgba(13,18,17,.05),0 10px 24px -14px rgba(13,18,17,.35);
  transition:background-color .2s var(--ease),border-color .2s var(--ease),transform .18s var(--ease)}
.coanav svg{width:20px;height:20px;fill:none;stroke:currentColor;stroke-width:2.1;
  stroke-linecap:round;stroke-linejoin:round}
@media (hover:hover){.coanav:hover{background:var(--soft);border-color:var(--line-2)}}
.coanav:active{transform:scale(.96)}
.coanav:focus-visible{outline:2.5px solid var(--brand-deep);outline-offset:2px}
.coawrap__count{margin:14px 0 0;text-align:center;
  font-size:11.5px;font-weight:700;letter-spacing:.1em;text-transform:uppercase;
  color:var(--ink-3);font-variant-numeric:tabular-nums}
@media (prefers-reduced-motion:reduce){.coanav{transition:none}.coanav:active{transform:none}}

/* Once the split collapses there is no room beside the card, and floating the
   arrows over it would cover the batch figures — the one thing a reader is here
   for. They move to a control row underneath instead. */
@media (max-width:980px){
  .coawrap{position:static;grid-template-columns:auto 1fr auto;
    grid-template-areas:"card card card" "prev count next";
    justify-items:center;gap:0}
  .coanav{position:static;width:48px;height:48px;margin-top:16px;
    background:#fff;backdrop-filter:none;-webkit-backdrop-filter:none}
  .coanav--prev{justify-self:start}
  .coanav--next{justify-self:end}
  .coawrap__count{margin:16px 0 0;align-self:center}
}
@media (max-width:420px){
  .coanav{width:46px;height:46px}
  .coawrap__count{font-size:11px}
}

.coa{background:#fff;border:1px solid var(--line);border-radius:22px;box-shadow:var(--shadow-lg);
  overflow:hidden}
.coa__top{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:16px 22px;
  border-bottom:1px solid var(--line)}
.coa__top b{font-size:14px;font-weight:800}
.verified{display:inline-flex;align-items:center;gap:7px;padding:5px 11px;border-radius:999px;
  background:var(--brand-tint);color:#0a7a30;font-size:11.5px;font-weight:800}
.verified svg{width:13px;height:13px;stroke:currentColor;fill:none;stroke-width:2.6}
.coa__peek{display:block;position:relative;width:100%;padding:0;border:0;cursor:pointer;
  background:linear-gradient(180deg,#fbfdfc,#fff);overflow:hidden;aspect-ratio:620/205}
.coa__peek img{width:100%;height:100%;object-fit:cover;object-position:50% 0;display:block;
  transition:transform .5s var(--ease)}
.coa__peek::after{content:'';position:absolute;inset:auto 0 0;height:48%;
  background:linear-gradient(180deg,rgba(255,255,255,0),#fff 78%)}
.coa__cap{margin:0;padding:0 22px 15px;font-size:12px;font-weight:800;color:var(--ink-3);
  letter-spacing:-.01em}
@media (hover:hover){.coa__peek:hover img{transform:scale(1.03)}}
.coa__rows{display:grid;grid-template-columns:1fr 1fr}
.coa__rows div{padding:15px 22px;border-top:1px solid var(--line)}
.coa__rows div:nth-child(odd){border-right:1px solid var(--line)}
.coa__rows dt{margin:0;font-size:11.5px;font-weight:700;letter-spacing:.08em;text-transform:uppercase;
  color:var(--ink-3)}
.coa__rows dd{margin:5px 0 0;font-size:15px;font-weight:800;letter-spacing:-.02em}
.coa__foot{padding:16px 22px;border-top:1px solid var(--line);background:var(--soft)}

/* ══ resource cards ══ */
.res{display:grid;grid-template-columns:repeat(3,1fr);gap:clamp(14px,1.4vw,20px)}
.res article{background:#fff;border:1px solid var(--line);border-radius:20px;padding:clamp(22px,2.2vw,30px);
  display:flex;flex-direction:column;transition:box-shadow .3s var(--ease),transform .3s var(--ease)}
.res article:hover{box-shadow:var(--shadow-lg);transform:translateY(-4px)}
.res .ico{width:54px;height:54px;border-radius:16px;background:var(--brand-tint);display:grid;
  place-items:center;margin-bottom:20px}
.res .ico svg{width:25px;height:25px;stroke:var(--brand-deep);fill:none;stroke-width:1.7}
.res h3{font-size:20px}
.res p{margin-top:10px;color:var(--ink-2);font-size:15px;line-height:1.55;flex:1}
.res .btn{margin-top:22px;width:100%}

/* ══ contact ══ */
.form{display:grid;gap:12px;max-width:660px;margin-inline:auto}
.row2{display:grid;grid-template-columns:1fr 1fr;gap:12px}
.field{width:100%;height:54px;padding:0 18px;border:1.5px solid var(--line);border-radius:14px;
  background:#fff;font:inherit;font-size:15px;color:var(--ink);transition:border-color .22s var(--ease),
  box-shadow .22s var(--ease)}
textarea.field{height:130px;padding-top:15px;resize:vertical;line-height:1.55}
.field::placeholder{color:var(--ink-3)}
.field:focus{outline:none;border-color:var(--brand-deep);box-shadow:0 0 0 4px rgba(11,156,59,.1)}

/* ══ footer ══ */
.foot{position:relative;background:var(--ink);color:#e6ebe8;padding-block:clamp(48px,5vw,74px) 26px}
/* The wave is an opaque band sitting on top of whatever section precedes the
   footer, so anything in that section's last row has to clear its full height —
   otherwise it slices straight across the content. */
/* top:1px, not -1px: translateY(-100%) puts the wave's bottom edge one pixel
   ABOVE the footer at -1px, and that gap shows the light section behind it as a
   hairline across the whole page. Overlapping into the footer by a pixel hides
   the seam — the wave's bottom row is solid ink at every x. */
.foot__wave{position:absolute;top:1px;left:0;width:100%;height:clamp(34px,4vw,58px);
  /* transparent, not --soft: the wave sits on whatever section precedes the
   footer, and a hard-coded grey painted a strip across a white one */
  transform:translateY(-100%);display:block;fill:var(--ink);background:transparent;
  pointer-events:none}
#contact{padding-bottom:calc(clamp(52px,6vw,92px) + clamp(34px,4vw,58px))}
.foot__grid{display:grid;grid-template-columns:minmax(0,1.4fr) repeat(3,minmax(0,1fr));
  gap:clamp(26px,3vw,44px);align-items:start}
.foot h4,.foot__h{margin:0 0 18px;font-size:12px;font-weight:800;letter-spacing:.14em;text-transform:uppercase;
  color:#7f8a84}
.foot__grid ul{list-style:none;margin:0;padding:0;display:grid;gap:13px;justify-items:start}
.foot__grid ul a{font-size:14.5px;color:#c3ccc7;transition:color .2s var(--ease)}
.foot__grid ul a:hover{color:var(--brand)}
.foot__note{margin-top:16px;color:#9aa39e;font-size:14px;max-width:34ch;line-height:1.62;
  text-wrap:pretty}
.sub{display:flex;gap:10px;margin-top:22px;max-width:400px}
.sub input{flex:1;min-width:0;height:50px;padding:0 18px;border-radius:999px;border:1.5px solid rgba(255,255,255,.18);
  background:rgba(255,255,255,.04);color:#fff;font:inherit;font-size:14.5px}
.sub input::placeholder{color:#7f8a84}
.sub input:focus{outline:none;border-color:var(--brand)}
/* ══ accepted payment ══ */
/* The row is a fixed five-column track that is centred in the footer rather
   than stretched across it. Fixed columns mean every box is exactly the same
   width by construction, and one `gap` means every interval is identical —
   neither can drift as the footer resizes. */
.pay{list-style:none;margin:clamp(30px,3.4vw,44px) 0 0;padding:clamp(20px,2.2vw,26px) 0 0;
  border-top:1px solid rgba(255,255,255,.1);
  display:grid;grid-template-columns:repeat(5,92px);justify-content:center;gap:10px}
.pay__i{display:flex;align-items:center;justify-content:center;gap:7px;
  height:44px;padding:0 10px;overflow:hidden;
  border-radius:11px;border:1px solid rgba(255,255,255,.14);
  background:rgba(255,255,255,.04);color:#d5ddd8;white-space:nowrap}
/* COD has no brand mark, so the van + wordmark are set to carry the same
   visual weight as the four logos beside it rather than read as a caption. */
.pay__i svg.pay__van{width:15px;height:15px;flex:none;fill:none;stroke:#fff;stroke-width:1.8;
  stroke-linecap:round;stroke-linejoin:round;opacity:1}
.pay__wm{font-size:11px;font-weight:800;letter-spacing:.045em;color:#fff;line-height:1}
/* Real brand artwork. Mastercard keeps its own colours because they read on
   black; Visa and Apple Pay ship dark, so they are knocked out to white — the
   reversed treatment both brands publish for dark backgrounds. Tamara's file
   is already white. */
.pay__l{display:block;object-fit:contain;object-position:50% 50%}
.pay__l--white{filter:brightness(0) invert(1)}
/* ── optical sizing ──
   These five marks run from 1.41:1 (Mastercard) to 5.1:1 (Tamara). Setting one
   flat height makes the round mark look tiny and the long wordmark look huge,
   so each height is scaled by its own aspect ratio — h = 12px × (3.09/aspect)^0.36,
   a partial correction toward equal area. The result is optically even without
   any logo being redrawn or cropped.
   max-width + object-fit is the safety net: if a box is ever narrower than the
   mark, the logo scales down inside it instead of clipping.
   !important throughout, because a blanket img{height:auto!important} from a
   caching plugin otherwise renders every logo at natural size and blows the
   whole row apart. */
.pay__l{width:auto!important;max-width:100%!important}
.pay__l--visa  {height:12px!important;max-height:12px!important}
.pay__l--apple {height:13px!important;max-height:13px!important}
.pay__l--mc    {height:17px!important;max-height:17px!important}
.pay__l--tamara{height:10px!important;max-height:10px!important}

/* ══ research use disclosure ══
   Collapsed by default: the notice has to be on every page, but it is a legal
   disclosure rather than something a visitor needs to read to shop. */
.rud{margin-top:clamp(20px,2.2vw,28px)}
.rud__t{display:inline-flex;align-items:center;gap:9px;min-height:44px;padding:0;
  background:none;border:0;cursor:pointer;color:#9aa39e;
  font-size:11px;font-weight:800;letter-spacing:.15em;text-transform:uppercase;
  transition:color .2s var(--ease)}
@media (hover:hover){.rud__t:hover{color:#e6ebe8}}
.rud__chev{width:15px;height:15px;flex:none;fill:none;stroke:currentColor;stroke-width:2.2;
  stroke-linecap:round;stroke-linejoin:round;transition:transform .3s var(--ease)}
.rud.open .rud__chev{transform:rotate(180deg)}
.rud__wrap{display:grid;grid-template-rows:0fr;transition:grid-template-rows .34s var(--ease)}
.rud.open .rud__wrap{grid-template-rows:1fr}
.rud__panel{min-height:0;overflow:hidden}
.rud__panel p{margin:0;padding-top:12px;max-width:96ch;color:#9aa39e;
  font-size:13.5px;line-height:1.65;text-wrap:pretty}
@media (prefers-reduced-motion:reduce){
  .rud__wrap{transition:none}
  .rud__chev{transition:none}
}
@media (max-width:640px){
  /* ── phone: compact pills, sized to their own logo ──
     Stretching five equal columns across the gutter made every box far wider
     than the mark inside it, so the padding was doing the work the logo should
     do. Here each pill is only as wide as its logo plus a tight, equal inset,
     the height is uniform, and the row scrolls sideways if a very narrow screen
     cannot take all five — shrinking the marks further would cost more than a
     scroll does. The two flex spacers centre the row while it fits and collapse
     to nothing once it overflows, which keeps the leftmost pill reachable;
     plain justify-content:center would strand it off-screen. */
  .pay{display:flex;justify-content:flex-start;gap:0;
    overflow-x:auto;overscroll-behavior-x:contain;-webkit-overflow-scrolling:touch;
    scrollbar-width:none;-ms-overflow-style:none;
    margin-inline:calc(var(--gut) * -1);padding-inline:var(--gut)}
  .pay::-webkit-scrollbar{display:none}
  .pay::before,.pay::after{content:'';flex:1 0 0;min-width:0}
  .pay__i{flex:0 0 auto;height:32px;padding:0 9px;gap:5px;border-radius:9px}
  .pay__i + .pay__i{margin-left:7px}
  .pay__wm{font-size:10px;letter-spacing:.03em}
  .pay__i svg.pay__van{width:14px;height:14px}
  /* Same optical ratios as desktop — each mark's height scaled by its own
     aspect, so the round Mastercard and the long Tamara wordmark carry equal
     weight — but set from a 12.5px Visa rather than 8.5px, so the logos read at
     roughly the size Nova's do instead of floating inside empty boxes. */
  .pay__l--visa  {height:12.5px!important;max-height:12.5px!important}
  .pay__l--apple {height:13.5px!important;max-height:13.5px!important}
  .pay__l--mc    {height:16.5px!important;max-height:16.5px!important}
  .pay__l--tamara{height:10.5px!important;max-height:10.5px!important}
  .rud__panel p{font-size:13px}
}

/* The disclosure toggle above this is a single short line, so a 58px gap before
   the rule left an obvious void at the bottom of the page. Brought in line with
   the rest of the footer's spacing. */
.foot__bot{display:flex;flex-wrap:wrap;gap:12px 26px;justify-content:space-between;align-items:center;
  margin-top:clamp(26px,2.8vw,38px);padding-top:22px;border-top:1px solid rgba(255,255,255,.1);
  color:#7f8a84;font-size:13px}

/* ══ cart drawer ══ */
/* pointer-events is driven by the class, never by the transition. These
   overlays used visibility alone to stop intercepting clicks, so a toggle that
   interrupted the fade could leave an invisible sheet over the whole page
   swallowing every click — reproducible by opening and closing the cart a few
   times quickly. Class-driven, that cannot happen. */
.scrim{position:fixed;inset:0;z-index:90;background:rgba(13,18,17,.42);backdrop-filter:blur(3px);
  opacity:0;visibility:hidden;pointer-events:none;
  transition:opacity .3s var(--ease),visibility .3s}
.scrim.open{opacity:1;visibility:visible;pointer-events:auto}
.cart{position:fixed;top:0;right:0;bottom:0;z-index:95;width:min(420px,100%);background:#fff;
  display:flex;flex-direction:column;transform:translateX(102%);
  transition:transform .42s var(--ease);box-shadow:-24px 0 60px -30px rgba(13,18,17,.5)}
.cart.open{transform:none}
.cart__top{display:flex;align-items:center;justify-content:space-between;padding:20px 22px;
  border-bottom:1px solid var(--line)}
.cart__top b{font-size:18px;font-weight:800;letter-spacing:-.02em}
.ship{padding:16px 22px;border-bottom:1px solid var(--line);background:var(--soft)}
.ship p{font-size:13px;font-weight:600;color:var(--ink-2)}
.ship .bar{height:6px;border-radius:999px;background:#e2e7e4;margin-top:10px;overflow:hidden}
.ship .bar i{display:block;height:100%;background:var(--brand);border-radius:999px;width:0;
  transition:width .5s var(--ease)}
.cart__scroll{flex:1;min-height:0;overflow-y:auto}
.cart__items{padding:8px 22px}
.ci{display:flex;gap:12px;padding:12px 0;border-bottom:1px solid var(--line)}
/* The sources are all square. A 58×74 portrait box with object-fit:cover was
   cropping the sides off each one, and because the vial sits at a different
   height in every photo the crop landed differently — which is what read as one
   product being more zoomed in than another. A square box at the source's own
   aspect shows each frame whole, so the framing is identical by construction. */
/* The tile is its own element, so the photograph can never decide the box.
   Earlier the <img> WAS the box: a 2px padded contain fit, so any source whose
   aspect or transparency did not match exactly let the grey well show through
   as bars. Now the span owns a hard 72x72 square and the image fills it with
   cover — a mismatched or non-square photo is cropped, never letterboxed, and
   there is no padding ring left for a background to appear in. The !important
   on the image's own box is deliberate: cache plugins inject a global
   img{height:auto!important} that would otherwise collapse this back. */
/* Stepper and price share one row beneath the dosage. Stacking the stepper on
   its own line would have cost ~34px an item; beside the price it fills space
   that was already empty, so the line gets shorter rather than taller. */
.ci__foot{display:flex;align-items:flex-end;justify-content:space-between;gap:10px;margin-top:6px}
/* 84px made the rail 123px tall and the whole line 152px, which pushed the
   suggestions below the fold on an 844px phone. 60px keeps the vial readable at
   a glance while giving 34px per line back to the basket. */
/* A FIXED SQUARE, never a stretched box.
   `align-self:stretch` used to size this tile to the text column, so a line
   carrying a sale price and a "you save" line got a taller tile than a plain
   one — GHK-CU rendered visibly larger than bacteriostatic water in the same
   basket. Worse, a taller box meant object-fit:cover cropped the sides off a
   square photograph, and because the vial sits at a slightly different height
   in every shot the crop landed differently each time, which read as some
   products being off-centre.
   Every product source is square (verified across all 64), so a square tile
   shows each frame whole: identical size and identical framing by
   construction, whatever the peptide and whether or not it is on sale.
   The trade-off is that the tile's bottom no longer lands on the stepper's —
   it cannot, while sale and non-sale lines differ in height — so it is centred
   against the text column instead. */
.ci__ph{width:72px;height:72px;flex:none;align-self:center;border-radius:10px;
  overflow:hidden;background:#fff;display:block;position:relative}
.ci__ph img{width:100%!important;height:100%!important;object-fit:cover;
  display:block;border-radius:inherit;padding:0;background:none}
.ci b{display:block;font-size:14.5px;font-weight:800;letter-spacing:-.02em}
/* the rule above makes every <b> in a cart line a block, which put the live
   figure on its own row — inside the price pair it has to stay inline */
.ci .ci__p{display:flex;align-items:baseline;justify-content:flex-end;gap:8px;flex-wrap:nowrap}
.ci .ci__p b{display:inline;font-size:15.5px;color:var(--ink)}
/* the sale price keeps the green; only the plain one changes */
.ci .ci__p b.ci__now{color:var(--brand-text)}
.ci .ci__p .ci__was{display:inline;flex:none}
.ci span{display:block;font-size:12.5px;color:var(--ink-3)}
.ci__b{flex:1 1 auto;min-width:0;position:relative}
/* Only the name yields room for the corner control. Padding the whole column
   would have pushed the right-aligned price inward too, breaking its alignment
   with the Subtotal figure directly below it. */
.ci__b > b{padding-right:30px}
/* Remove moves out of the stepper and up to the corner of the line it deletes.
   Keeping it inside the stepper put a destructive control one pixel from the
   quantity buttons, which is a mis-tap waiting to happen; up here it is nowhere
   near them. The 44px hit area is padded outward so it stays reachable without
   the icon itself growing. */
.ci__x{position:absolute;top:-5px;right:0;width:30px;height:30px;display:grid;
  place-items:center;border-radius:999px;color:var(--ink-3);transition:color .18s,background .18s}
.ci__x svg{width:15px;height:15px;fill:none;stroke:currentColor;stroke-width:2;stroke-linecap:round}
/* The 44x44 hit area grows up, down and inward only — expanding it to the
   right pushed past the line box and put a scrollbar in the drawer. */
.ci__x::after{content:"";position:absolute;top:-7px;bottom:-7px;left:-14px;right:0}
@media (hover:hover){.ci__x:hover{color:var(--ink);background:var(--soft)}}
/* The price pair takes the whole line: a struck figure beside a live one needs
   roughly 226px, and sharing the line with the stepper left it 140. */
.ci__r{margin-top:0;text-align:right;font-variant-numeric:tabular-nums;flex:1 1 auto;min-width:0}
.qty{display:inline-flex;align-items:center;gap:2px;margin-top:8px;border:1.5px solid var(--line);
  border-radius:999px;padding:2px}
/* in the body column now, so it sizes to its own content */
.ci__foot .qty{margin-top:0;flex:none;padding:1px 3px;border-width:1.5px}
/* Visually 24px so the pill still fits under a 60px tile, but the tappable
   area is grown vertically — WCAG 2.2's 24px floor is a floor, not a target,
   and these are the most-used controls in the drawer. Grown vertically only:
   spreading them sideways would close the gap between - and + and trade one
   guideline for another. */
.ci__foot .qty button{position:relative;flex:none;width:26px;height:26px;font-size:14px}
.ci__foot .qty button::after{content:"";position:absolute;left:0;right:0;top:-7px;bottom:-7px}
.ci__foot .qty s{min-width:16px;font-size:13px}
/* At 320px the struck price, the live price and the stepper cannot share a
   row, so it wrapped to two and the line grew by 44px. A step down in the price
   pair recovers the single row; below that the wrap is the honest outcome and
   it still fits without overflow. */
@media (max-width:360px){
  .ci__foot{gap:7px}
  .ci .ci__p{gap:6px}
  .ci .ci__p b{font-size:14px}
  .ci .ci__was{font-size:11px}
  .ci__save{font-size:10.5px}
  .ci__foot .qty button{width:24px;height:24px}
  .ci__foot .qty s{min-width:14px;font-size:12.5px}
}
.qty button{width:26px;height:26px;border-radius:999px;display:grid;place-items:center;font-weight:800;
  font-size:14px;color:var(--ink-2);transition:background .18s}
.qty button:hover{background:var(--soft)}
.qty s{text-decoration:none;min-width:20px;text-align:center;font-size:13.5px;font-weight:800}
.cart__empty{padding:52px 22px;text-align:center;color:var(--ink-3)}
.cart__foot{padding:7px 20px 9px;border-top:1px solid var(--line)}
.cart__sum{display:flex;justify-content:space-between;align-items:baseline;margin-bottom:5px}
.cart__sumv{display:inline-flex;align-items:baseline;gap:9px}
.cart__sumv s{text-decoration:line-through;text-decoration-thickness:1.6px;color:var(--ink-3);
  font-size:15px;font-weight:600;font-variant-numeric:tabular-nums}
.cart__sumv s[hidden]{display:none}
.cart__sum b{font-size:20px;font-weight:800;letter-spacing:-.02em;font-variant-numeric:tabular-nums}
.cart__foot .btn{width:100%}
.cart__foot .btn--primary{height:48px}
.cart__foot small{display:block;margin-top:5px;text-align:center;color:var(--ink-3);font-size:12px}

/* ══ mobile sheet ══ */
.sheet{position:fixed;inset:0;z-index:92;background:#fff;display:flex;flex-direction:column;
  padding:16px var(--gut) 32px;transform:translateY(-100%);transition:transform .4s var(--ease);
  overflow-y:auto}
.sheet.open{transform:none}
.sheet__top{display:flex;align-items:center;justify-content:space-between;height:58px}
.sheet nav{margin-top:22px}
.sheet nav a,.sheet nav>details>summary{display:block;padding:15px 0;font-size:22px;font-weight:800;
  letter-spacing:-.03em;border-bottom:1px solid var(--line);list-style:none;cursor:pointer}
.sheet details summary::-webkit-details-marker{display:none}
.sheet details[open] summary{border-bottom-color:transparent}
.sheet details a{font-size:16px;font-weight:600;color:var(--ink-2);padding:10px 0 10px 16px;
  border-bottom:0}
.sheet details div{border-bottom:1px solid var(--line);padding-bottom:8px}
.sheet .btn{margin-top:26px;width:100%}

/* ══ hero — vials floating over a lit podium ══ */
.stage{position:relative;display:grid;place-items:center;isolation:isolate;
  min-height:clamp(430px,47vw,620px)}
/* the stage sits on clean white — no green wash behind the vials */
.stage__aura{display:none}

/* ══ proof badges ══
   Two claims pinned to the composition like annotations on a specimen: one at
   the shoulder of the left vial, one out to the right of the third. They sit
   in the empty white either side of the trio, well above the plinth, and drift
   on the same slow rhythm as the vials so the group reads as one object. */
.proof{position:absolute;z-index:5;display:inline-flex;align-items:center;gap:10px;
  padding:11px 16px;border-radius:15px;
  background:rgba(255,255,255,.9);backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);
  border:1px solid var(--line);
  box-shadow:0 1px 2px rgba(13,18,17,.05),0 18px 40px -20px rgba(13,18,17,.4)}
.proof b{font-size:13px;font-weight:800;letter-spacing:-.015em;line-height:1.2;white-space:nowrap}
.proof>svg{width:21px;height:21px;flex:none;stroke:var(--brand-deep);fill:none;stroke-width:1.7;
  stroke-linecap:round;stroke-linejoin:round}
.proof__tick{width:21px;height:21px;flex:none;border-radius:999px;background:var(--brand);
  display:grid;place-items:center}
.proof__tick svg{width:12px;height:12px;stroke:var(--on-brand);fill:none;stroke-width:3;
  stroke-linecap:round;stroke-linejoin:round}
/* clear of the vials: one out in the white left of GHK-CU, one right of
   TB-500, both well above the plinth. They rise and fall on the vials' rhythm
   but never rotate — a tilted label reads as a mistake, not a flourish. */
.proof--a{left:-5%;top:12%;animation:proofA 9.5s cubic-bezier(.45,0,.55,1) infinite}
.proof--b{right:-4%;top:21%;animation:proofB 8.3s cubic-bezier(.45,0,.55,1) infinite -5.1s}
@keyframes proofA{0%,100%{transform:translate3d(0,0,0)}50%{transform:translate3d(0,-13px,0)}}
@keyframes proofB{0%,100%{transform:translate3d(0,0,0)}50%{transform:translate3d(0,-17px,0)}}
@media (max-width:1330px){.proof--a{left:-2%}.proof--b{right:-1%}}
@media (max-width:1150px){.proof--a{left:0;top:10%}.proof--b{right:0;top:19%}}
/* below the two-column hero the stage is too narrow to carry them */
@media (max-width:940px){.proof{display:none}}
@media (prefers-reduced-motion:reduce){.proof{animation:none}}

.fv{position:absolute;margin:0;will-change:transform;z-index:2}
/* the vial artwork already carries its own studio lighting, so this is only a
   whisper of ambient depth — enough to lift it off the page, not enough to
   read as a pasted-on shadow */
.fv img{width:100%;height:auto;display:block;
  filter:drop-shadow(0 16px 20px rgba(13,18,17,.11)) drop-shadow(0 3px 7px rgba(13,18,17,.06))}

/* ── float: slow, offset phases, seamless because 0% and 100% match ── */
.fv__i{will-change:transform}
/* The supplied artwork already leans: GHK-CU −14.8°, BPC-157 +14.6°,
   TB-500 +22.7°. These rotations are corrections applied on top, easing each
   vial back to a restrained resting angle (−6° / +5° / +9°) without touching a
   pixel of the files. The ±1.3° drift on top of that is the float itself. */
@keyframes floatL{
  0%,100%{transform:translate3d(0,0,0) rotate(8.8deg)}
  50%    {transform:translate3d(0,-15px,0) rotate(10.1deg)}
}
@keyframes floatC{
  0%,100%{transform:translate3d(0,0,0) rotate(-9.6deg)}
  50%    {transform:translate3d(0,-19px,0) rotate(-8.2deg)}
}
@keyframes floatR{
  0%,100%{transform:translate3d(0,0,0) rotate(-13.7deg)}
  50%    {transform:translate3d(0,-13px,0) rotate(-14.8deg)}
}
.fv--l{animation:floatL 9.5s cubic-bezier(.45,0,.55,1) infinite}
.fv--c{animation:floatC 11.2s cubic-bezier(.45,0,.55,1) infinite -2.4s}
.fv--r{animation:floatR 8.3s  cubic-bezier(.45,0,.55,1) infinite -5.1s}
@media (prefers-reduced-motion:reduce){
  .fv--l{transform:rotate(8.8deg)}
  .fv--c{transform:rotate(-9.6deg)}
  .fv--r{transform:rotate(-13.7deg)}
}

/* centre vial reads as the hero: wider, higher, slight natural tilt */
/* the widths differ because each file's bounding box carries a different
   amount of tilt padding — tuned so the vials themselves read at roughly
   280 / 222 / 213 px tall, with BPC-157 clearly the largest */
.fv--c{width:42%;left:50%;top:16%;margin-left:-21%;z-index:3}
.fv--l{width:30%;left:1%;top:30%;z-index:2}
.fv--r{width:35%;right:0;top:32%;z-index:2}

/* platform: the supplied podium render, sized so the trio floats clear of its
   top surface the way the reference composition does */
.podium{position:absolute;left:50%;bottom:5%;width:80%;transform:translateX(-50%);z-index:1;pointer-events:none}
.podium img{width:100%;height:auto;display:block}
.podium::after{content:'';position:absolute;left:50%;bottom:-6%;width:86%;aspect-ratio:8/1;
  transform:translateX(-50%);border-radius:50%;
  background:radial-gradient(ellipse at center,rgba(13,18,17,.10),transparent 72%);filter:blur(14px);z-index:-1}
/* the podium render carries its own light ring; no CSS glow on top */
.podium__glow{display:none}

/* The two proof chips sit on the visual rather than in the copy column, so the
   claim reads against the product it is about. Pointer events stay off the row
   so they never intercept a tap meant for the vials behind them. */

@media (max-width:940px){.stage{width:100%;max-width:520px;margin-inline:auto;min-height:400px}}
@media (max-width:640px){
  .stage{width:100%;max-width:390px;min-height:340px}
  .fv--c{width:38%;top:6%;margin-left:-19%}
  .fv--l{width:28%;left:0;top:21%}
  .fv--r{width:32%;right:-2%;top:23%}
  .podium{width:92%;bottom:4%}
  /* Room under the plinth so the chips sit below the vials, not across them. */
  .stage{min-height:400px}
  .podium{bottom:16%}
}

/* ══ mega menu / accents ══ */
.drop--mega{display:grid;grid-template-columns:repeat(2,minmax(190px,1fr));gap:6px 22px;padding:18px 20px;min-width:470px}
.drop--mega h5{margin:0 0 10px;padding-left:14px;font-size:10.5px;font-weight:800;letter-spacing:.16em;
  text-transform:uppercase;color:#7f8a84}
.mini,.pill10{font-style:normal;display:inline-block;margin-left:6px;padding:2px 7px;border-radius:999px;
  background:var(--brand);color:var(--on-brand);font-size:10px;font-weight:800;letter-spacing:.03em;
  vertical-align:middle}
.nav--accent{color:var(--brand) !important}
.nav>li>a.nav--accent:hover{background:rgba(25,237,86,.14)}
.sheet .pill10{font-size:10px}

/* ══ routed pages ══ */
.page{padding-block:clamp(30px,4vw,54px) clamp(50px,6vw,86px)}
.crumb{display:flex;gap:8px;align-items:center;font-size:13px;font-weight:600;color:var(--ink-3);margin-bottom:18px}
.crumb a:hover{color:var(--brand-text)}
/* The trail links rendered 21px tall — under the 24px minimum target size, and
   unlike a link inside a sentence these are standalone controls, so the
   exemption does not apply. Padding grows the hit area without moving anything
   on screen: the row is already 24px+ and the negative margin absorbs it. */
.crumb a{display:inline-block;padding-block:3px;margin-block:-3px}
/* An article title in the trail can be long. Truncate it to one line rather
   than letting it wrap the row into two ragged lines on a narrow screen —
   the heading directly beneath already carries the title in full. */
.crumb>a,.crumb>span{flex:none;white-space:nowrap}
.crumb>span:last-child{flex:0 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis}
.phead{margin-bottom:clamp(24px,3vw,38px)}
.phead h1{font-size:clamp(30px,3.6vw,48px);letter-spacing:-.035em}
.phead p{margin-top:14px;color:var(--ink-2);max-width:62ch;font-size:16px}
.prose{max-width:74ch}
.prose h2{margin-top:38px;font-size:22px}
.prose p,.prose li{margin-top:12px;color:var(--ink-2);font-size:15.5px;line-height:1.7}
.prose ul{margin:6px 0 0;padding-left:20px}
.prose strong{color:var(--ink);font-weight:800}
.catgrid{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:clamp(12px,1.2vw,18px)}
.cattile{position:relative;min-width:0;overflow:hidden;border:1px solid var(--line);border-radius:16px;padding:22px;background:#fff;
  transition:box-shadow .3s var(--ease),transform .3s var(--ease),border-color .3s var(--ease)}
.cattile:hover{box-shadow:var(--shadow-lg);transform:translateY(-4px);border-color:var(--line-2)}
.cattile b{display:block;font-size:18px;letter-spacing:-.025em}
.cattile span{display:block;margin-top:6px;font-size:13.5px;color:var(--ink-3);font-weight:600}
.empty{border:1px dashed var(--line-2);border-radius:18px;padding:44px 24px;text-align:center;color:var(--ink-2)}
.empty b{display:block;font-size:19px;color:var(--ink);margin-bottom:8px}
.faq details{border-bottom:1px solid var(--line);padding:6px 0}
.faq summary{cursor:pointer;list-style:none;padding:16px 0;font-size:16.5px;font-weight:800;letter-spacing:-.02em;
  display:flex;justify-content:space-between;gap:16px}
.faq summary::-webkit-details-marker{display:none}
.faq summary::after{content:'+';font-weight:700;color:var(--brand-text);font-size:20px;line-height:1}
.faq details[open] summary::after{content:'–'}
.faq p{padding:0 0 16px;color:var(--ink-2);font-size:15.5px;line-height:1.7;max-width:70ch}
.tbl{width:100%;border-collapse:collapse;margin-top:18px;font-size:15px}
.tbl th,.tbl td{text-align:left;padding:14px 16px;border-bottom:1px solid var(--line)}
.tbl th{font-size:11.5px;letter-spacing:.12em;text-transform:uppercase;color:var(--ink-3)}
.tbl td:last-child{font-weight:800}
.postlist{display:grid;gap:14px}
.post{display:flex;gap:18px;align-items:center;border:1px solid var(--line);border-radius:16px;padding:18px 20px;
  background:#fff;transition:box-shadow .3s var(--ease),transform .3s var(--ease)}
.post:hover{box-shadow:var(--shadow-lg);transform:translateY(-3px)}
.post b{display:block;font-size:17px;letter-spacing:-.025em}
.post span{display:block;margin-top:5px;color:var(--ink-2);font-size:14.5px}
.post i{flex:none;width:46px;height:46px;border-radius:12px;background:var(--brand-tint);display:grid;
  place-items:center;font-style:normal;font-weight:800;color:#0a7a30;font-size:13px}

/* Article covers. `.post span` above sets display/margin/colour on every span in
   the card, so the cover's own frame has to say otherwise explicitly — it is a
   span too. A post with no cover keeps the numbered tile and this never
   applies, so an article published without artwork still renders a full card. */
.post--img{padding:14px;gap:16px}
/* The cover frame is a span too, so every `> span` rule here has to exclude it
   or it inherits the text wrapper's padding and the picture stops filling it. */
.post--img>span:not(.post__ph){margin-top:0}
.post__ph{flex:none;width:170px;height:113px;margin-top:0;border-radius:12px;overflow:hidden;
  background:var(--brand-tint)}
.post__ph img{display:block;width:100%;height:100%;object-fit:cover;
  transition:transform .5s var(--ease)}
.post--img:hover .post__ph img{transform:scale(1.045)}

.postcover{margin:0 0 26px;max-width:820px;border:1px solid var(--line);border-radius:18px;
  overflow:hidden;background:var(--brand-tint)}
.postcover img{display:block;width:100%;height:auto;aspect-ratio:3/2;object-fit:cover}

@media (prefers-reduced-motion:reduce){
  .post__ph img{transition:none}
  .post--img:hover .post__ph img{transform:none}
}

@media (max-width:640px){
  /* Full-bleed cover on top, text beneath — the card becomes the article. */
  .post--img{flex-direction:column;align-items:stretch;padding:0;gap:0}
  .post__ph{width:100%;height:auto;aspect-ratio:3/2;border-radius:0}
  .post--img>span:not(.post__ph){padding:13px 16px 15px}
  .postcover{margin-bottom:20px;border-radius:14px}
}

/* ══ stack builder ══ */
.stack{display:grid;grid-template-columns:minmax(0,1fr) 340px;gap:clamp(20px,2.4vw,34px);align-items:start}
/* Pack-size chooser. The stepper is the primary control — it is the thing that
   answers "how many do I want" — with the two ladder thresholds beside it as
   shortcuts so the rates stay visible without a customer having to step to them
   to find out. Disabled ends are real disabled attributes, not just styling, so
   the bounds are announced rather than merely looking unavailable. */
.packset{margin-bottom:22px;padding:14px 16px;border:1.5px solid var(--line);
  border-radius:16px;background:var(--soft)}
.packset__row{display:flex;align-items:center;gap:14px;flex-wrap:wrap}
.packset__l{font-size:12.5px;font-weight:800;letter-spacing:.06em;text-transform:uppercase;
  color:var(--ink-3)}
.packq{display:inline-flex;align-items:center;gap:4px;background:#fff;
  border:1.5px solid var(--line);border-radius:999px;padding:3px}
.packq button{width:34px;height:34px;border-radius:999px;display:grid;place-items:center;
  font-size:17px;font-weight:800;color:var(--ink-2);transition:background .18s var(--ease)}
@media (hover:hover){.packq button:not(:disabled):hover{background:var(--soft)}}
.packq button:disabled{opacity:.32;cursor:not-allowed}
.packq b{min-width:30px;text-align:center;font-size:16px;font-weight:800;
  font-variant-numeric:tabular-nums}
.packset__q{display:inline-flex;align-items:center;gap:7px;margin-left:auto}
.packset__ql{font-style:normal;font-size:11px;font-weight:800;letter-spacing:.08em;
  text-transform:uppercase;color:var(--ink-3);margin-right:1px}
.pchip{padding:7px 13px;min-height:34px;border-radius:999px;border:1.5px solid var(--line);
  background:#fff;font-size:12.5px;font-weight:800;color:var(--ink-2);white-space:nowrap;
  transition:border-color .2s var(--ease),background .2s var(--ease),color .2s var(--ease)}
@media (hover:hover){.pchip:hover{border-color:var(--line-2)}}
.pchip[aria-pressed="true"]{border-color:var(--brand-deep);background:var(--brand-tint);
  color:var(--brand-text)}
.packset__n{margin:10px 0 0;font-size:12.5px;font-weight:700;color:var(--ink-2)}
.packset__n:empty{display:none}
@media (max-width:560px){
  /* The label sits beside the stepper rather than owning a row, and the
     "Quick set" caption goes: the chips now read "4 vials -10%", which says
     what they do without a heading over them. Five stacked rows became three. */
  .packset{padding:12px 13px}
  .packset__row{gap:10px 12px}
  .packset__l{font-size:11.5px}
  .packset__ql{display:none}
  .packset__q{margin-left:0;width:100%;gap:8px}
  .packset__q .pchip{flex:1 1 0;text-align:center;padding-inline:8px}
  .packset__n{margin-top:9px;font-size:12px}
}
.tiers{display:flex;gap:10px;flex-wrap:wrap;margin-bottom:22px}
.tier{position:relative;border:1.5px solid var(--line);border-radius:14px;padding:14px 20px;background:#fff;
  text-align:left;min-width:190px;
  transition:background-color .24s var(--ease),border-color .24s var(--ease),box-shadow .24s var(--ease)}
.tier:hover{border-color:var(--line-2)}
.tier[aria-pressed="true"]{border-color:var(--brand-deep);background:var(--brand-tint)}
.tier b{font-size:20px;font-weight:800;letter-spacing:-.03em}
.tier b em{font-style:normal;font-size:12.5px;font-weight:700;color:var(--brand-text);margin-left:6px}
.tier span{display:block;margin-top:3px;font-size:12.5px;color:var(--ink-3);font-weight:600}
.tier .badge{position:absolute;top:-9px;right:14px;padding:3px 9px;border-radius:999px;background:var(--ink);
  color:#fff;font-size:10px;font-weight:800;letter-spacing:.08em;text-transform:uppercase}
.sgrid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:12px}
.sc{position:relative;border:1px solid var(--line);border-radius:14px;overflow:hidden;background:#fff;
  transition:box-shadow .3s var(--ease),border-color .3s var(--ease)}
.sc:hover{box-shadow:var(--shadow);border-color:var(--line-2)}
.sc img{width:100%;aspect-ratio:1/1;object-fit:cover;display:block}
.sc__b{padding:12px 14px 14px}
.sc__b b{display:block;font-size:14.5px;letter-spacing:-.02em}
.sc__p{margin-top:6px;font-size:14px;font-weight:800}
.sc__p s{color:var(--ink-3);font-weight:600;font-size:12.5px;margin-left:6px}
.sc__m{margin-top:4px;font-size:11px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:var(--ink-3)}
.sc__add{position:absolute;right:10px;top:10px;width:34px;height:34px;border-radius:999px;background:var(--brand);
  color:var(--on-brand);display:grid;place-items:center;font-size:19px;font-weight:800;line-height:1;
  box-shadow:var(--shadow);transition:transform .2s var(--ease)}
.sc__add:hover{transform:scale(1.08)}
.panel{position:sticky;top:96px;border:1px solid var(--line);border-radius:18px;background:#fff;
  box-shadow:var(--shadow-lg);overflow:hidden}
.panel__t{display:flex;align-items:center;justify-content:space-between;padding:16px 18px;
  border-bottom:1px solid var(--line);width:100%;text-align:left;font:inherit;color:inherit;
  background:none;border-inline:0;border-top:0;cursor:default}
.panel__chev{display:none}
.panel__t b{font-size:17px;letter-spacing:-.02em}
.slots{display:flex;flex-wrap:wrap;gap:7px;padding:16px 18px}
.slot{width:42px;height:42px;border-radius:10px;border:1.5px dashed var(--line-2);background:var(--soft);
  overflow:hidden;position:relative;padding:0}
/* a filled slot is a button, so it needs to look like one under the finger */
button.slot{cursor:pointer;transition:border-color .18s var(--ease),transform .18s var(--ease)}
button.slot:active{transform:scale(.94)}
@media (hover:hover){button.slot:hover{border-color:#c0392b}
  button.slot:hover .slot__x{background:#c0392b}}
.slot__x{position:absolute;top:0;right:0;display:grid;place-items:center;width:17px;height:17px;
  border-radius:0 8px 0 8px;background:rgba(13,18,17,.72);color:#fff;
  transition:background-color .18s var(--ease)}
.slot__x svg{width:9px;height:9px;fill:none;stroke:currentColor;stroke-width:3;stroke-linecap:round}
.slot img{width:100%;height:100%;object-fit:cover}
.slot.full{border-style:solid;border-color:var(--brand-deep)}
.slist{padding:0 18px;max-height:250px;overflow-y:auto}
.sl{display:flex;align-items:center;gap:10px;padding:11px 0;border-top:1px solid var(--line);font-size:14px}
.sl b{font-weight:800;letter-spacing:-.02em}
.sl span{color:var(--ink-3);font-size:12.5px}
.sl button{margin-left:auto;width:24px;height:24px;border-radius:999px;color:var(--ink-3);font-size:16px;
  line-height:1;transition:background .18s,color .18s}
.sl button:hover{background:var(--soft);color:var(--ink)}
.panel__f{padding:16px 18px;border-top:1px solid var(--line);background:var(--soft)}
.panel__row{display:flex;justify-content:space-between;align-items:baseline;font-size:14px;margin-bottom:8px}
.panel__row b{font-size:22px;font-weight:800;letter-spacing:-.025em}
.panel__f .btn{width:100%;margin-top:8px}
.saveline{color:var(--brand-text);font-weight:800}
@media (max-width:1150px){.catgrid{grid-template-columns:repeat(3,minmax(0,1fr))}}
@media (max-width:980px){
  .stack{grid-template-columns:1fr}
  .panel{position:static}
  .drop--mega{grid-template-columns:1fr;min-width:260px}
}
@media (max-width:640px){
  .catgrid{grid-template-columns:repeat(2,minmax(0,1fr))}
  .sgrid{grid-template-columns:repeat(2,minmax(0,1fr))}
  .tier{min-width:0;flex:1 1 46%;padding:12px 14px}
  .tbl th,.tbl td{padding:11px 10px;font-size:14px}
}

/* ══ age gate ══ */
.gate{position:fixed;inset:0;z-index:200;display:grid;place-items:center;padding:20px;
  background:rgba(9,12,11,.82);backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px)}
.gate[hidden]{display:none}
.gate__card{width:min(468px,100%);background:#fff;border-radius:24px;
  padding:clamp(30px,4.6vw,42px) clamp(22px,4vw,38px) clamp(26px,4vw,34px);
  text-align:center;box-shadow:0 40px 90px -30px rgba(0,0,0,.6);animation:gatein .5s var(--ease)}
@keyframes gatein{from{opacity:0;transform:translateY(14px) scale(.98)}to{opacity:1;transform:none}}
/* height AND width are pinned, and the intrinsic size is set on the tag itself, so a
   theme or plugin rule like img{height:auto} cannot blow the mark up to full width. */
/* The mark is pinned four ways — a fixed box, an image that cannot outgrow it,
   intrinsic width/height on the tag, and !important — because caching and
   image-optimisation plugins commonly inject a blanket img{height:auto!important}
   for layout shift, which would otherwise draw this at its natural 750px. */
.gate__mark{display:block;width:100%;height:34px;margin:0 auto 22px;overflow:hidden}
.gate .gate__logo{display:block!important;height:34px!important;max-height:34px!important;
  width:auto!important;max-width:100%!important;margin:0 auto!important;object-fit:contain}
.gate__kick{display:flex;align-items:center;justify-content:center;gap:9px;
  font-size:10.5px;font-weight:800;letter-spacing:.2em;text-transform:uppercase;
  color:var(--brand-text)}
.gate__rule{display:block;width:20px;height:2px;border-radius:2px;background:currentColor;flex:none}
.gate h2{margin-top:13px;text-wrap:balance;font-size:clamp(25px,3.2vw,31px);letter-spacing:-.03em;line-height:1.14}
.gate__body{margin-top:14px;color:var(--ink-2);font-size:14.5px;line-height:1.72;
  text-wrap:pretty;max-width:37ch;margin-inline:auto}
.gate__policy{display:inline-block;margin-top:14px;padding:12px 8px;color:var(--ink);
  font-size:13.5px;font-weight:600;text-decoration:underline;text-underline-offset:3px;
  text-decoration-thickness:1px;text-decoration-color:var(--line-2);transition:text-decoration-color .2s var(--ease),color .2s var(--ease)}
@media (hover:hover){.gate__policy:hover{color:var(--brand-text);text-decoration-color:currentColor}}
.gate__btns{display:grid;gap:10px;margin-top:12px}
.gate__btns .btn{width:100%;min-height:54px;font-size:13px;font-weight:800;
  letter-spacing:.1em;text-transform:uppercase}
.gate__ruo{display:flex;align-items:center;justify-content:center;gap:7px;margin-top:20px;
  color:var(--ink-3);font-size:10.5px;font-weight:700;letter-spacing:.15em;text-transform:uppercase}
.gate__ruo svg{width:13px;height:13px;flex:none;fill:none;stroke:currentColor;
  stroke-width:1.6;stroke-linecap:round;stroke-linejoin:round}
.gate__deny{display:none;margin-top:22px;padding-top:20px;border-top:1px solid var(--line)}
.gate__deny b{display:block;font-size:17px}
.gate__deny p{margin-top:6px;font-size:14px}
.gate.denied .gate__btns,.gate.denied .gate__ruo,.gate.denied .gate__policy{display:none}
.gate.denied .gate__deny{display:block}

/* ══ search ══ */
.srch{position:fixed;inset:0;z-index:120;background:rgba(9,12,11,.5);backdrop-filter:blur(6px);
  padding:clamp(60px,10vh,120px) 20px 20px;opacity:0;visibility:hidden;pointer-events:none;
  transition:opacity .25s var(--ease),visibility .25s}
.srch.open{opacity:1;visibility:visible;pointer-events:auto}
.srch__box{width:min(660px,100%);margin-inline:auto;background:#fff;border-radius:20px;overflow:hidden;
  box-shadow:0 40px 80px -30px rgba(0,0,0,.55)}
/* The field carries the row's height instead of the row's padding carrying it,
   so tapping anywhere on the visible bar lands in the input. Same 60px overall. */
.srch__in{display:flex;align-items:center;gap:12px;padding:8px 18px;border-bottom:1px solid var(--line)}
.srch__in svg{width:20px;height:20px;stroke:var(--ink-3);fill:none;stroke-width:1.8;flex:none}
.srch__in input{flex:1;min-height:44px;border:0;outline:0;font:inherit;font-size:17px;font-weight:600;
  color:var(--ink);background:none}
.srch__res{max-height:min(52vh,440px);overflow-y:auto;padding:8px}
.sres{display:flex;align-items:center;gap:14px;padding:10px 12px;border-radius:12px;transition:background .18s}
.sres:hover{background:var(--soft)}
.sres img{width:46px;height:46px;border-radius:10px;object-fit:cover;flex:none}
.sres b{display:block;font-size:15px;letter-spacing:-.02em}
.sres span{display:block;font-size:12.5px;color:var(--ink-3);font-weight:600}
.sres em{margin-left:auto;font-style:normal;font-weight:800;font-size:14px;white-space:nowrap}
.srch__none{padding:30px 16px;text-align:center;color:var(--ink-3);font-size:14.5px}

/* ══ account ══ */

/* ══ lab results table ══ */
.labbar{display:flex;align-items:center;gap:16px;flex-wrap:wrap;margin-bottom:20px}
.labsearch{display:flex;align-items:center;gap:10px;flex:1;min-width:240px;max-width:400px;
  border:1.5px solid var(--line);border-radius:999px;padding:0 18px;height:50px;background:#fff}
.labsearch svg{width:18px;height:18px;stroke:var(--ink-3);fill:none;stroke-width:1.8;flex:none}
.labsearch input{flex:1;min-height:44px;border:0;outline:0;font:inherit;font-size:15px;background:none;
  color:var(--ink)}
.labcount{font-size:13.5px;font-weight:700;color:var(--ink-3)}
.tblwrap{overflow-x:auto;border:1px solid var(--line);border-radius:16px;background:#fff}
.tbl--lab{margin-top:0;min-width:860px}
.tbl--lab thead th{background:var(--soft);white-space:nowrap}
.tbl--lab td{font-size:14.5px;vertical-align:middle}
.tbl--lab td:last-child{font-weight:400}
.tbl--lab .mono{font-variant-numeric:tabular-nums;letter-spacing:.01em;color:var(--ink-2)}
.pass{display:inline-block;padding:4px 10px;border-radius:999px;background:var(--brand-tint);color:#0a7a30;
  font-size:12.5px;font-weight:800}
.verify{display:inline-flex;align-items:center;justify-content:center;gap:7px;padding:8px 14px;
  border-radius:999px;border:1.5px solid var(--line-2);font-size:13px;font-weight:800;
  white-space:nowrap;min-width:0;
  transition:background .2s var(--ease),border-color .2s var(--ease),
             color .2s var(--ease),transform .18s var(--ease)}
.verify:active{transform:scale(.96)}
.verify svg{width:14px;height:14px;stroke:currentColor;fill:none;stroke-width:1.8;stroke-linejoin:round}
.verify:hover{border-color:var(--brand-deep);color:var(--brand-text);background:var(--brand-tint)}
button.verify{background:none;color:inherit;font-family:inherit;cursor:pointer}
.verify.verify--doc{border-color:var(--ink);background:var(--ink);color:#fff}
.verify.verify--doc:hover{border-color:var(--ink);background:var(--ink-2);color:#fff}
.labacts{display:flex;gap:8px;justify-content:flex-end}
/* Desktop only: let the certificate column hug its two buttons. Inside the
   phone breakpoint the table is re-laid-out as stacked cards, where this would
   collapse the actions cell — hence the media query, not a bare selector. */
@media (min-width:641px){
  .tbl--lab th:last-child,.tbl--lab td:last-child{width:1%;white-space:nowrap}
}

/* ══ affiliate ══ */
.afpills{display:flex;gap:9px;flex-wrap:wrap}
.afpill{padding:9px 16px;border-radius:999px;background:var(--brand-tint);color:#0a7a30;
  font-size:13px;font-weight:700;border:1px solid rgba(11,156,59,.16)}
.afband{display:grid;grid-template-columns:repeat(4,1fr);gap:1px;background:rgba(255,255,255,.08);
  margin-top:44px;border-radius:20px;overflow:hidden;background-color:var(--ink)}
.afband>div{background:var(--ink);padding:26px 24px;color:#c3ccc7}
.afband span{display:block;font-size:10.5px;font-weight:800;letter-spacing:.16em;text-transform:uppercase;color:#7f8a84}
.afband b{display:block;margin-top:10px;font-size:clamp(30px,3.4vw,42px);font-weight:800;letter-spacing:-.04em;color:var(--brand)}
.afband b em{font-style:normal;font-size:16px;color:#7f8a84;margin-left:4px}
.afband p{margin-top:8px;font-size:13.5px;line-height:1.55;color:#9aa39e}
.calc{display:grid;grid-template-columns:minmax(0,1.2fr) minmax(0,.9fr);gap:clamp(18px,2.4vw,30px);
  border:1px solid var(--line);border-radius:22px;background:#fff;padding:clamp(22px,2.6vw,34px);box-shadow:var(--shadow)}
.calc__in{display:grid;gap:26px;align-content:start}
.calc__in label{display:block;font-size:14.5px;font-weight:700;color:var(--ink-2)}
.calc__in label b{float:right;font-size:16px;font-weight:800;color:var(--ink)}
/* ── slider ──
   The control's box is 44px tall so a thumb can actually catch it; the visible
   track stays 6px, drawn by the track pseudo-element rather than the input's
   own background. The negative top margin holds the track on the exact line it
   sat on before the box grew, so nothing below it moves. */
.calc__in input[type=range]{-webkit-appearance:none;appearance:none;display:block;width:100%;
  height:44px;margin:-5px 0 -17.5px;background:none;outline:0;cursor:pointer}
.calc__in input[type=range]::-webkit-slider-runnable-track{height:6px;border-radius:999px;
  background:linear-gradient(90deg,var(--brand-deep) var(--fill,0%),#e2e7e4 var(--fill,0%))}
.calc__in input[type=range]::-moz-range-track{height:6px;border-radius:999px;
  background:linear-gradient(90deg,var(--brand-deep) var(--fill,0%),#e2e7e4 var(--fill,0%))}
.calc__in input[type=range]::-webkit-slider-thumb{-webkit-appearance:none;width:22px;height:22px;border-radius:999px;
  margin-top:-8px;background:#fff;border:3px solid var(--brand-deep);box-shadow:var(--shadow);cursor:grab}
.calc__in input[type=range]::-moz-range-thumb{width:22px;height:22px;border-radius:999px;background:#fff;
  border:3px solid var(--brand-deep);cursor:grab}
.calc__out{background:var(--soft);border-radius:16px;padding:22px}
.calc__row{display:flex;justify-content:space-between;align-items:baseline;font-size:14px;
  padding:9px 0;border-bottom:1px solid var(--line);color:var(--ink-2)}
.calc__row b{font-size:15.5px;font-weight:800;color:var(--ink)}
.calc__total{margin-top:18px;font-size:clamp(30px,3.4vw,40px);font-weight:800;letter-spacing:-.04em;color:var(--brand-text)}
.calc__cap{display:block;margin-top:2px;font-size:11px;font-weight:800;letter-spacing:.14em;
  text-transform:uppercase;color:var(--ink-3)}
.afpays{display:flex;gap:6px;flex-wrap:wrap;margin-top:16px}
.afpays span{padding:6px 11px;border-radius:8px;border:1px solid var(--line);font-size:11px;
  font-weight:800;letter-spacing:.06em;text-transform:uppercase;color:var(--ink-2)}
@media (max-width:860px){
  .afband{grid-template-columns:1fr 1fr}
  .calc{grid-template-columns:1fr}
}
@media (max-width:520px){.afband{grid-template-columns:1fr}}

/* ══ currency picker ══ */
.curwrap{position:relative;flex:none}
.curbtn{display:inline-flex;align-items:center;gap:8px;height:38px;padding:0 14px;border-radius:999px;
  border:1px solid rgba(255,255,255,.22);color:#fff;font-size:13.5px;font-weight:800;
  transition:background .2s var(--ease)}
.curbtn:hover{background:rgba(255,255,255,.12)}
.curbtn svg{width:16px;height:16px;stroke:currentColor;fill:none;stroke-width:1.6}
.curdrop{position:absolute;top:calc(100% + 10px);right:0;min-width:250px;padding:10px;background:#121816;
  border:1px solid rgba(255,255,255,.12);border-radius:16px;box-shadow:0 24px 48px -20px rgba(0,0,0,.8);
  opacity:0;visibility:hidden;transform:translateY(-6px);z-index:70;
  transition:opacity .22s var(--ease),transform .22s var(--ease),visibility .22s}
.curwrap.on .curdrop{opacity:1;visibility:visible;transform:none}
.curdrop::before{content:'';position:absolute;left:0;right:0;top:-12px;height:12px}
.curdrop h5{margin:0 0 8px;padding-left:12px;font-size:10px;font-weight:800;letter-spacing:.16em;
  text-transform:uppercase;color:#7f8a84}
.curdrop button{display:flex;align-items:center;gap:12px;width:100%;padding:10px 12px;border-radius:10px;
  color:#c3ccc7;font-size:14px;transition:background .18s,color .18s;text-align:left}
.curdrop button:hover{background:rgba(255,255,255,.09);color:#fff}
.curdrop button b{width:38px;flex:none;font-weight:800;color:#fff}
.curdrop button span{flex:1;font-weight:600}
.curdrop .tickmark{opacity:0;font-style:normal;color:var(--brand);font-weight:800}
.curdrop button.on .tickmark{opacity:1}
.curdrop button.on b{color:var(--brand)}

/* ══ product detail ══ */
.pdp{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:clamp(24px,3.4vw,52px);align-items:start}
.pdp__img{border:1px solid var(--line);border-radius:20px;overflow:hidden;background:var(--well)}
.pdp__img img{width:100%;aspect-ratio:1/1;object-fit:cover;display:block}
.pdp__info h1{margin-top:12px;font-size:clamp(28px,3.2vw,40px);letter-spacing:-.035em}
.pdp__lbl{margin-top:22px;font-size:11.5px;font-weight:800;letter-spacing:.12em;text-transform:uppercase;color:var(--ink-3)}
.pdp .pc__sizes{margin-top:10px}
.pdp .size{height:38px;padding:0 16px;font-size:13.5px;border-radius:10px}
.pdp__facts{list-style:none;margin:28px 0 0;padding:0;border-top:1px solid var(--line)}
.pdp__facts li{display:flex;gap:18px;padding:13px 0;border-bottom:1px solid var(--line);font-size:14.5px}
.pdp__facts b{flex:none;width:100px;font-weight:800}
.pdp__facts span{color:var(--ink-2)}
.pdp__note{margin-top:18px;color:var(--ink-3);font-size:13px;line-height:1.6}

/* ══ account dashboard ══ */
.acctpage{display:grid;grid-template-columns:270px minmax(0,1fr);gap:clamp(18px,2.4vw,32px);align-items:start}
.acctnav{border:1px solid var(--line);border-radius:20px;background:#fff;padding:18px;box-shadow:var(--shadow)}
.acctnav__me{display:flex;gap:12px;align-items:center;padding-bottom:16px;border-bottom:1px solid var(--line)}
.avatar{width:44px;height:44px;border-radius:999px;background:var(--brand-tint);color:#0a7a30;display:grid;
  place-items:center;font-weight:800;font-size:15px;flex:none}
.acctnav__me i{display:block;font-style:normal;font-size:10px;font-weight:800;letter-spacing:.14em;
  text-transform:uppercase;color:var(--brand-text)}
.acctnav__me b{display:block;font-size:15px;letter-spacing:-.02em}
.acctnav__me small{display:block;color:var(--ink-3);font-size:12px;word-break:break-all}
.acctnav nav{display:grid;gap:2px;margin-top:14px}
.acctnav nav button{text-align:left;padding:11px 14px;border-radius:10px;font-size:14.5px;font-weight:700;
  color:var(--ink-2);
  transition:background-color .18s var(--ease),color .18s var(--ease)}
.acctnav nav button:hover{background:var(--soft);color:var(--ink)}
.acctnav nav button.on{background:var(--ink);color:#fff}
.acctnav__out{margin-top:8px;border-top:1px solid var(--line);border-radius:0 !important;color:var(--brand-text) !important}
.acctmain{border:1px solid var(--line);border-radius:20px;background:#fff;padding:clamp(22px,2.6vw,34px);
  box-shadow:var(--shadow);min-height:340px}
.acctmain h2{font-size:clamp(22px,2.6vw,30px);letter-spacing:-.03em}
.acctmain__lead{margin-top:12px;color:var(--ink-2);font-size:15.5px;max-width:52ch;line-height:1.6}
.acctiles{display:grid;grid-template-columns:1fr 1fr;gap:12px;margin-top:24px}
.acctile{display:block;text-align:left;border:1px solid var(--line);border-radius:14px;padding:18px;
  background:#fff;transition:box-shadow .26s var(--ease),transform .26s var(--ease)}
.acctile:hover{box-shadow:var(--shadow-lg);transform:translateY(-3px)}
.acctile__i{display:grid;place-items:center;width:38px;height:38px;border-radius:11px;background:var(--brand-tint);
  color:#0a7a30;font-size:16px;margin-bottom:12px}
.acctile b{display:block;font-size:15.5px;letter-spacing:-.02em}
.acctile i{display:block;font-style:normal;margin-top:3px;font-size:13px;color:var(--ink-3)}
.addrgrid{display:grid;grid-template-columns:1fr 1fr;gap:12px;margin-top:20px}
.addr{border:1px solid var(--line);border-radius:14px;padding:18px}
.addr b{font-size:15px}.addr p{margin:8px 0 14px;color:var(--ink-3);font-size:14px}

/* ══ calculator ══ */
.calcwrap{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1.05fr);gap:clamp(20px,2.6vw,36px);align-items:start}
.calcform{display:grid;gap:6px}
.fl{font-size:11px;font-weight:800;letter-spacing:.14em;text-transform:uppercase;color:var(--ink-3);margin-top:14px}
.frow{display:flex;gap:10px;align-items:center}
.frow .field{flex:1;min-width:0}
.sel{flex:0 0 108px;cursor:pointer}
.unit{flex:0 0 40px;font-size:14px;font-weight:700;color:var(--ink-3)}
.segs{display:inline-flex;gap:4px;background:var(--soft);padding:4px;border-radius:999px;margin-top:6px;
  align-self:start}
.segs button{height:36px;padding:0 18px;border-radius:999px;font-size:13.5px;font-weight:800;color:var(--ink-2);
  transition:background-color .2s var(--ease),color .2s var(--ease)}
.segs button.on{background:var(--ink);color:#fff}
.calcview{background:var(--soft);border:1px solid var(--line);border-radius:20px;padding:clamp(18px,2.2vw,28px)}
.syr{width:100%;height:auto;display:block}
.kunits{margin-top:6px;font-size:14px;font-weight:700;color:var(--brand-text)}
.kunits b{font-size:19px;font-weight:800}
.kunits s{text-decoration:none;color:#c0392b;font-weight:700;font-size:12.5px}
.kout{margin-top:18px;padding-top:16px;border-top:1px solid var(--line);color:var(--ink-2);font-size:14.5px}
.krow{display:flex;justify-content:space-between;align-items:baseline;padding:9px 0;border-bottom:1px solid var(--line)}
.krow b{font-size:16px;font-weight:800;color:var(--ink);font-variant-numeric:tabular-nums}
.kdisc{margin-top:22px;color:var(--ink-3);font-size:13px;max-width:76ch}
.kdisc b{color:var(--brand-text)}

@media (max-width:940px){
  /* minmax(0,1fr), not 1fr: an auto track takes the widest child's
     min-content, which let the purchase panel push the page sideways */
  .pdp{grid-template-columns:minmax(0,1fr)}
  .acctpage{grid-template-columns:1fr}
  .acctnav nav{grid-template-columns:repeat(2,1fr);display:grid}
  .calcwrap{grid-template-columns:1fr}
}
@media (max-width:640px){
  .acctiles,.addrgrid{grid-template-columns:1fr}
  .curbtn{height:34px;padding:0 10px;font-size:12.5px}
  .curbtn svg{width:14px;height:14px}
  .pdp__facts b{width:80px}
  .pdp__buy .btn{width:100%}
  .segs{width:100%}
  .segs button{flex:1}
  .sel{flex:0 0 92px}
}

/* ══ whatsapp ══ */
/* ══ mobile buy bar ══
   The product page keeps its full-size layout and spacing; the CTA is brought
   to the customer instead of the layout being squeezed up to the CTA. The bar
   carries the live price and forwards its tap to the real Add to cart button,
   so quantity, dosage, tier discount and the bac-water add-on all behave
   exactly as they do inline. It hides itself whenever the real button — or the
   footer — is on screen, so it never duplicates or covers anything. */
.buybar{position:fixed;left:0;right:0;bottom:0;z-index:86;display:none;
  transform:translateY(102%);transition:transform .26s var(--ease);pointer-events:none}
.buybar.in{transform:none;pointer-events:auto}
.buybar__in{display:flex;align-items:center;gap:12px;
  padding:10px 16px calc(10px + env(safe-area-inset-bottom,0px));
  background:rgba(255,255,255,.94);backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px);
  border-top:1px solid var(--line);box-shadow:0 -12px 32px -20px rgba(0,0,0,.5)}
.buybar__p{min-width:0;display:flex;flex-direction:column;justify-content:center;line-height:1.15}
.buybar__p span{font-size:10px;font-weight:800;letter-spacing:.1em;text-transform:uppercase;
  color:var(--ink-3);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.buybar__p b{margin-top:3px;font-size:17px;letter-spacing:-.025em;
  font-variant-numeric:tabular-nums;white-space:nowrap}
.buybar__go{flex:1 1 auto;height:48px;padding:0 18px;font-size:15px}
@media (max-width:640px){ .buybar{display:block} }
@media (prefers-reduced-motion:reduce){ .buybar{transition:none} }
/* the chat button steps up so the two never share a corner */
.wa{transition:transform .26s var(--ease)}
body.buybar-on .wa{transform:translateY(-66px)}

.wa{position:fixed;right:clamp(14px,2vw,26px);bottom:clamp(14px,2vw,26px);z-index:88;
  width:58px;height:58px;border-radius:999px;background:#25d366;color:#fff;
  display:grid;place-items:center;box-shadow:0 10px 26px -8px rgba(37,211,102,.7),0 2px 6px rgba(0,0,0,.18);
  transition:transform .22s var(--ease),box-shadow .22s var(--ease)}
.wa svg{width:32px;height:32px;display:block}
.wa:hover{transform:translateY(-3px) scale(1.04);box-shadow:0 16px 32px -8px rgba(37,211,102,.8)}
.wa:active{transform:translateY(0) scale(.98)}
@media (max-width:640px){.wa{width:52px;height:52px}.wa svg{width:29px;height:29px}}

/* ══ toast ══ */
.toast{position:fixed;left:50%;bottom:26px;z-index:99;
  transform:translate(-50%,14px) scale(.97);
  display:flex;align-items:center;gap:11px;padding:12px 22px 12px 14px;border-radius:999px;
  background:rgba(13,18,17,.94);backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px);
  border:1px solid rgba(255,255,255,.09);
  color:#fff;font-size:14px;font-weight:600;letter-spacing:-.005em;opacity:0;pointer-events:none;
  transition:opacity .26s var(--ease),transform .4s var(--ease);
  box-shadow:0 2px 6px rgba(0,0,0,.28),0 18px 44px -16px rgba(0,0,0,.7)}
.toast.show{opacity:1;transform:translate(-50%,0) scale(1)}
/* one badge, two faces: a quiet dot for information, a green tick once
   something has actually landed in the cart */
.toast__mark{position:relative;display:grid;place-items:center;flex:none;
  width:26px;height:26px;border-radius:999px;background:rgba(255,255,255,.08)}
.toast__mark i{width:6px;height:6px;border-radius:50%;background:var(--brand);
  transition:opacity .2s var(--ease),transform .2s var(--ease)}
.toast__mark svg{position:absolute;width:14px;height:14px;stroke:var(--on-brand);fill:none;
  stroke-width:3;stroke-linecap:round;stroke-linejoin:round;
  opacity:0;transform:scale(.25);filter:blur(4px);
  transition:opacity .24s cubic-bezier(.2,0,0,1),transform .24s cubic-bezier(.2,0,0,1),
             filter .24s cubic-bezier(.2,0,0,1)}
.toast--ok .toast__mark{background:var(--brand)}
.toast--ok .toast__mark i{opacity:0;transform:scale(.25)}
.toast--ok .toast__mark svg{opacity:1;transform:scale(1);filter:blur(0)}
@media (prefers-reduced-motion:reduce){
  .toast{transition:opacity .2s linear;transform:translate(-50%,0) scale(1)}
  .toast__mark i,.toast__mark svg{transition:none}
}

/* ══ reveal ══ */
[data-rv]{opacity:0;transform:translateY(18px)}
[data-rv].in{opacity:1;transform:none;transition:opacity .8s var(--ease),transform .8s var(--ease)}

/* ══ responsive ══ */
@media (max-width:1150px){
  .grid{grid-template-columns:repeat(3,minmax(0,1fr))}
  .nav{display:none}
  .burger{display:grid}
}
@media (max-width:940px){
  .hero__grid{grid-template-columns:1fr;gap:8px}
  .hero__copy{order:2}
  .stage{order:1}
  .hero{padding-top:12px}
  .split{grid-template-columns:1fr;gap:32px}
  .res{grid-template-columns:1fr}
  .foot__grid{grid-template-columns:1fr 1fr}
  .foot__grid>:first-child{grid-column:1/-1}
}
@media (max-width:640px){
  .grid{grid-template-columns:repeat(2,minmax(0,1fr))}
  .hdr__in{height:64px}
  .hdr.stuck .hdr__in{height:60px}
  .brand img{height:34px}
  .hdr.stuck .brand img{height:32px}
  .hero{padding-block:14px 26px}
  h1.hero__h{margin-top:16px}
  .hero__lead{margin-top:14px;font-size:15.5px}
  .hero__cta{margin-top:22px;gap:8px}
  .hero__cta .btn{flex:1 1 100%}
  .chips{flex-wrap:nowrap;overflow-x:auto;scrollbar-width:none;-ms-overflow-style:none;
    margin-inline:calc(var(--gut) * -1);padding-inline:var(--gut)}
  .chips::-webkit-scrollbar{display:none}
  .chip{flex:none;height:38px;padding:0 15px;font-size:13.5px}
  .tag{font-size:10px;letter-spacing:.04em}

  /* ── product cards, restructured for two-up on a phone ──
     The square media box plus a dosage row plus a full-width Add button made
     the card ~470px tall, so the first row's prices sat below the fold. The
     media is shallower, the dosage choice moves to the product page, and the
     cart icon already on the image becomes the add control — the same
     information in roughly half the height. */
  /* contain, not cover: the cap and the base of the vial both have to be
     visible, and a 4:3 crop of a square photo cuts one or the other */
  /* The vial photos are square; the card's media box is 4:3, so `contain`
     letterboxes them and the pale --well showed as two white bars. This
     gradient is sampled from the photographs themselves — backdrop at the top,
     the table line at 72%, white surface below — so the letterbox reads as a
     continuation of the picture rather than a border. Nothing is cropped and
     the card gains no height. */
  /* The photographs are square. Matching a gradient to the 4:3 letterbox got
     close but never all the way — six different shots, each scaling slightly
     differently — so the box matches the picture instead. No bars to hide, and
     nothing cropped. The height this costs is taken back below. */
  .pc__media{aspect-ratio:1/1;padding:0;background:var(--well)}
  /* !important, like the hero vials and the brand marks: a blanket
     img{height:auto!important} from a caching or image-optimisation plugin
     makes this image render at its natural size, and the card's overflow
     clips the cap — which reads exactly like the crop this rule exists to
     prevent. The sizing has to outrank that. */
  .pc__media img{width:100%!important;height:100%!important;
    object-fit:contain!important;object-position:50% 50%}
  .pc__body{padding:8px 10px 9px}
  .pc h3{font-size:14px;line-height:1.16;letter-spacing:-.025em}
  /* Card-only. Unscoped, this also hit the product page's dosage selector —
     which reuses the same class inside .buy__sec — so on a phone a customer
     could not choose between 50 MG and 100 MG at all. */
  .pc .pc__sizes{display:none}
  .pc .add{display:none}
  .pc__foot{flex-direction:row;align-items:center;justify-content:flex-start;gap:8px}
  .row2{grid-template-columns:1fr}
  .coa__rows{grid-template-columns:1fr}
  .coa__rows div:nth-child(odd){border-right:0}
  .foot__grid{grid-template-columns:1fr}
  .belt__i{width:290px}
}

/* ══════════════════════════════════════════════════════════════════════
   MOBILE LAYER — phones only (<=940 / <=640 / <=400 / <=360).
   Nothing here is allowed to touch the desktop layout: every rule lives
   inside a max-width query at or below the point the design already
   collapses to one column.
   ══════════════════════════════════════════════════════════════════════ */

/* the stack bar measures itself and publishes its height here */
:root{--stackbar:0px}
/* On desktop the dock disappears entirely, so .panel stays a direct grid item
   of .stack and its sticky behaviour is exactly what it always was. */
.panel-dock{display:contents}

@media (max-width:940px){
  /* ── hero: one proportional composition, scales as a unit ──
     aspect-ratio (not a fixed min-height) is what keeps the three vials and
     the whole podium in the same relationship at every phone width. */
  .stage{width:100%;max-width:min(430px,88vw);margin-inline:auto;
    aspect-ratio:1.06/1;min-height:0}
  .fv--c{width:38%;left:50%;top:8%;margin-left:-19%}
  .fv--l{width:28%;left:1%;top:23%}
  .fv--r{width:32%;right:0;top:25%}
  .podium{width:86%;bottom:7%}
  .stage__aura{top:56%;width:96%}
  /* keep the drift inside the hero box */
  .hero{overflow:hidden}

  /* ── Build a Stack: the panel becomes a bottom bar ── */
  .panel__chev{display:block;width:18px;height:18px;stroke:var(--ink-3);fill:none;stroke-width:2.2;
    flex:none;transition:transform .28s var(--ease)}
  .panel--open .panel__chev{transform:rotate(180deg)}
  /* The dock holds the panel's slot in the flow and is exactly as tall as the
     panel, so switching between floating and docked moves nothing.
     It also breaks out of the page gutters: a fixed bar is viewport-wide, so
     the docked one has to be too, or the hand-off would change the panel's
     width — and with it the text wrapping and the bar's height. */
  .panel-dock{display:block;min-height:var(--stackbar);
    margin-left:calc(-1 * max(var(--gut), env(safe-area-inset-left, 0px)));
    margin-right:calc(-1 * max(var(--gut), env(safe-area-inset-right, 0px)))}
  .stack .panel{position:static;left:0;right:0;bottom:0;top:auto;z-index:87;
    width:100%;max-width:none;border:0;border-top:1px solid var(--line);
    border-radius:18px 18px 0 0;box-shadow:0 -10px 34px -14px rgba(13,18,17,.34);
    display:flex;flex-direction:column;max-height:min(80vh,600px)}
  /* identical in every way except how it is positioned — that is what stops
     the hand-off from being visible */
  .stack .panel--float{position:fixed}
  .stack .panel__t{padding:12px 16px;gap:10px}
  .stack .slots{padding:0 16px 10px;gap:6px}
  /* the slot is now the remove control, so it keeps a usable target on a phone
     rather than shrinking to a decorative 34px */
  .stack .slot{width:42px;height:42px;border-radius:9px}
  .stack .slist{display:none;padding:0 16px;max-height:min(26vh,190px);
    border-top:1px solid var(--line)}
  .stack .panel--open .slist{display:block}
  .stack .panel__f{padding:12px 16px;padding-bottom:calc(12px + env(safe-area-inset-bottom,0px))}
  .stack .panel__row{margin-bottom:4px;font-size:13.5px}
  .stack .panel__row b{font-size:19px}
  .stack .panel__f .btn{margin-top:8px;height:50px}
  body[data-route="stack"] .page{padding-bottom:30px}
  body[data-route="stack"] .wa{bottom:calc(16px + env(safe-area-inset-bottom,0px))}
  /* only lift the chat bubble while the bar is actually floating over things */
  body.stack-float[data-route="stack"] .wa{bottom:calc(var(--stackbar) + 14px)}
  /* the expanded list reaches up past the chat bubble — get it out of the way
     rather than letting it sit on top of the remove buttons */
  body.stack-open .wa{opacity:0;transform:scale(.9);pointer-events:none}
}

@media (max-width:640px){
  /* anything scrolled into view — an anchor, a focused field, a tapped card —
     must clear the sticky header and the Build-a-Stack bar, or it lands
     underneath them and cannot be tapped */
  html{scroll-padding-top:74px;scroll-padding-bottom:calc(var(--stackbar) + 18px)}

  /* ── header: fits 320px without shedding anything ── */
  .hdr__in{gap:8px}
  .tools{gap:3px}
  .icn{width:40px;height:40px}
  .icn svg{width:20px;height:20px}
  .curbtn{height:40px;padding:0 12px;gap:6px;font-size:13px}
  /* the panel hangs off the button on desktop; on a phone it detaches and
     spans the viewport instead, so it cannot run off either edge at any width */
  .curdrop{position:fixed;left:12px;right:12px;top:calc(106px + env(safe-area-inset-top,0px));
    width:auto;min-width:0;transform:translateY(-6px)}
  .hdr.stuck .curdrop{top:calc(66px + env(safe-area-inset-top,0px))}
  .curwrap.on .curdrop{transform:none}
  .curdrop button{padding:13px 12px}
  .curdrop button b{width:44px}

  /* ── mobile sheet: notch and home-indicator aware ── */
  .sheet{padding-top:calc(14px + env(safe-area-inset-top,0px));
    padding-bottom:calc(32px + env(safe-area-inset-bottom,0px));
    overscroll-behavior:contain}
  .sheet nav a,.sheet nav>details>summary{font-size:20px;padding:14px 0}
  .sheet details a{padding:12px 0 12px 14px;font-size:15.5px}

  /* ── hero copy ── */
  h1.hero__h{font-size:clamp(27px,7.6vw,34px);letter-spacing:-.032em}
  .hero__lead{font-size:15px;line-height:1.6;max-width:none}
  .hero__cta .btn{flex:1 1 100%;height:52px}
  .pill{height:34px;font-size:12.5px;padding:0 14px}

  /* three stats read better as three columns than 2 + 1 orphan */

  /* ── product cards: bigger tap targets, no cramped rows ── */
  .grid{gap:10px}
  .pc__body{padding:10px 11px 12px}
  .pc h3{font-size:14px;margin-top:7px}
  /* the whole card is already the link (.pc h3 a::after covers it), so the
     title needs no padded hit area of its own */
  .pc h3 a{display:inline;padding:0}
  .tag{padding:3px 8px;font-size:10px}
  .pc__foot{padding-top:6px;gap:8px}
  .price{font-size:14.5px}
  .price em{font-size:10.5px;margin-right:4px}
  .pc__quick{width:38px;height:38px;top:8px;left:8px}
  .chip{height:40px}

  /* ── section rhythm ── */
  .sec{padding-block:clamp(40px,10vw,58px)}
  .shead h2{font-size:clamp(25px,7vw,31px)}
  .shead p{font-size:15px;margin-top:10px}
  .page{padding-block:16px 44px}
  .phead h1{font-size:clamp(26px,7.4vw,33px)}
  .phead p{font-size:15.5px;margin-top:12px}
  .crumb{margin-bottom:11px;gap:10px}
  /* The visible line is short but the tap area is not: the pseudo-element
     extends it to ~42px without spending 42px of the first screen. Horizontal
     growth stays inside the 10px gap, so two crumbs never share a hit area. */
  .crumb a{display:inline-flex;align-items:center;min-height:24px;padding-inline:2px;position:relative}
  .crumb a::after{content:'';position:absolute;top:-9px;right:-4px;bottom:-9px;left:-4px}
  .prose h2{margin-top:30px;font-size:20px}
  .prose p,.prose li{font-size:15.5px}

  /* ── quality / COA panel on the home page ── */
  .coa__top{padding:14px 16px}
  .coa__rows div{padding:13px 16px}
  .coa__foot{padding:14px 16px}
  .ticks li{font-size:15px}
  .res .ico{width:48px;height:48px;margin-bottom:16px}
  .res h3{font-size:18.5px}

  /* ── generic tables become label/value cards ── */
  .tblwrap{border:0;border-radius:0;background:none;overflow:visible}
  .tbl--lab,.tbl--cards{min-width:0;width:100%;display:block;margin-top:4px}
  .tbl--lab thead,.tbl--cards thead{display:none}
  .tbl--cards tbody,.tbl--cards tr,.tbl--cards td{display:block;width:100%}
  .tbl--cards tr{border:1px solid var(--line);border-radius:16px;background:#fff;
    padding:6px 14px 12px;margin-bottom:12px;box-shadow:var(--shadow)}
  .tbl--cards td{border:0;padding:10px 0;display:flex;align-items:baseline;
    justify-content:space-between;gap:16px;border-bottom:1px solid var(--line);font-size:14.5px;
    text-align:right;font-variant-numeric:tabular-nums;min-width:0}
  .tbl--cards td::before{content:attr(data-l);flex:none;font-size:11px;
    font-weight:800;letter-spacing:.1em;text-transform:uppercase;color:var(--ink-3);text-align:left}
  .tbl--cards tr td:last-child{border-bottom:0}
  .tbl--cards td[colspan]{justify-content:center;text-align:center}
  .tbl--cards td[colspan]::before{display:none}

  /* ── batch results: a dense card, not a stack of label/value rows ────
     The seven cells are placed into a four-row grid: identity, provenance,
     the two measured figures as tiles, then the actions. Same data, same
     order in the DOM, roughly half the height. */
  .tbl--lab tbody{display:grid;gap:10px}
  .tbl--lab tr{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);
    column-gap:10px;row-gap:8px;align-items:center;
    border:1px solid var(--line);border-radius:16px;background:#fff;
    padding:12px 13px;box-shadow:var(--shadow)}
  .tbl--lab td{display:block;border:0;padding:0;min-width:0;font-size:13px;
    font-variant-numeric:tabular-nums}
  .tbl--lab td::before{display:none}

  .tbl--lab td[data-l="Product"]{grid-column:1;grid-row:1;font-size:15.5px;
    font-weight:800;letter-spacing:-.025em;line-height:1.2}
  .tbl--lab td[data-l="Size"]{grid-column:2;grid-row:1;justify-self:end;
    padding:3px 9px;border-radius:999px;background:var(--soft);border:1px solid var(--line);
    font-size:11.5px;font-weight:800;color:var(--ink-2);white-space:nowrap}
  .tbl--lab td[data-l="Batch #"]{grid-column:1;grid-row:2;font-size:11.5px;
    color:var(--ink-3);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  .tbl--lab td[data-l="Tested"]{grid-column:2;grid-row:2;justify-self:end;
    font-size:11.5px;color:var(--ink-3);white-space:nowrap}

  /* the two measured figures, side by side, each in its own tile */
  .tbl--lab td[data-l="Purity"],.tbl--lab td[data-l="Net content"]{
    grid-row:3;padding:7px 10px 8px;border:1px solid var(--line);border-radius:12px;
    background:var(--soft);line-height:1.15}
  .tbl--lab td[data-l="Purity"]{grid-column:1}
  .tbl--lab td[data-l="Net content"]{grid-column:2;font-size:15px;font-weight:800;
    letter-spacing:-.02em}
  .tbl--lab td[data-l="Purity"]::before,.tbl--lab td[data-l="Net content"]::before{
    display:block;content:attr(data-l);margin-bottom:3px;font-size:10px;font-weight:800;
    letter-spacing:.11em;text-transform:uppercase;color:var(--ink-3)}
  /* purity is the headline number, so it drops the pill and speaks plainly */
  .tbl--lab td[data-l="Purity"] .pass{background:none;padding:0;border-radius:0;
    font-size:15px;font-weight:800;letter-spacing:-.02em;color:var(--brand-text)}

  .tbl--lab td[data-l=""]{grid-column:1/-1;grid-row:4}
  .tbl--lab tr.labrow--multi td[data-l="Purity"]{grid-column:1/-1;grid-row:3;
    display:flex;align-items:baseline;gap:9px;padding:6px 10px}
  .tbl--lab tr.labrow--multi td[data-l="Purity"]::before{margin-bottom:0}
  .tbl--lab tr.labrow--multi td[data-l="Net content"]{grid-column:1/-1;grid-row:4;
    font-size:12.5px;font-weight:700;line-height:1.4;letter-spacing:-.01em}
  .tbl--lab tr.labrow--multi td[data-l=""]{grid-row:5}

  .tbl--lab td[colspan]{grid-column:1/-1;grid-row:1;padding:16px 0;text-align:center}
  /* two balanced halves: compact, still a full 42px target each */
  .labacts{display:grid;grid-template-columns:1fr 1fr;gap:8px}
  .verify{width:100%;height:42px;padding:0 10px;font-size:13px;flex:none}
  .verify svg{width:15px;height:15px}

  .labbar{flex-direction:column;align-items:stretch;gap:10px;margin-bottom:14px}
  .labsearch{flex:none;min-width:0;max-width:none;width:100%;height:50px}
  .labcount{font-size:12.5px}

  /* ── stack builder ── */
  .tiers{gap:8px;margin-bottom:18px}
  .tier{padding:12px 14px}
  .tier b{font-size:18px}
  .sgrid{gap:10px}
  .sc__add{width:40px;height:40px;right:8px;top:8px;font-size:21px}
  .sc__b{padding:10px 12px 12px}
  .sc__b b{font-size:13.5px}
  .sl button{width:36px;height:36px;font-size:19px;margin-left:auto}

  /* ── quantity tiers + COA viewer on a phone ── */
  .coabox__row .btn{flex:1 1 130px}
  .tiers2{gap:6px}
  .tier2{padding:11px 5px 10px;border-radius:12px}
  .tier2__q{font-size:13.5px}
  .tier2__u{font-size:11px}
  .tier2__b{font-size:10px;padding:3px 7px;letter-spacing:.03em}
  .coav{padding:0}
  .coav__card{width:100%;height:100%;max-height:100dvh;border-radius:0}
  .coav__top{padding:12px 12px 12px 15px;
    padding-top:calc(12px + env(safe-area-inset-top,0px))}
  .coav__top b{font-size:14px}
  .coav__src{margin-top:2px;font-size:11px}
  .coav__sheet{padding:10px}
  .coav__bar{gap:6px;padding:10px 12px;
    padding-bottom:calc(10px + env(safe-area-inset-bottom,0px))}
  .coav__zoom button{width:44px;height:44px}
  .coav__acts{width:100%;margin-left:0}
  .coav__acts .btn{flex:1 1 120px;min-width:0}
  .coav__hint{display:none}

  /* ── product detail ──────────────────────────────────────────────
     The v29 layout, unchanged in structure, proportion and type. The
     only edits below are seam-level: a few pixels come out of the
     margins between sections so the CTA sits higher. The image, the type
     and every control keep their v29 size. Nothing is restructured. */
  .pdp{gap:18px}
  .pdp .size{height:40px;padding:0 16px;font-size:14px}
  .pdp__lbl{margin-top:17px}
  .pdp .pc__sizes{margin-top:9px}
  .qsel{margin-top:9px}
  .tiers2{margin-top:9px}
  .buy{margin-top:16px;border-radius:16px}
  .buy__sec{padding:13px 14px}
  .buy__total{padding:13px 14px}
  .buy__tv b{font-size:22px}
  .wrow{padding:9px 10px;gap:10px}
  .wrow__img{width:34px;height:34px}
  .pdp__buy{margin-top:13px}
  .pdp__buy .add{height:56px;font-size:16.5px}
  .stacklink{margin-top:8px;font-size:13px;padding:11px 4px}
  .pdp__facts li{gap:14px;font-size:14px}
  .pdp__facts b{width:88px}

  /* ── calculator ── */
  .calcwrap{gap:18px}
  .frow{gap:8px}
  .segs button{height:42px;font-size:13.5px;padding:0 10px}
  .calcview{padding:16px}
  .kdisc{font-size:12.5px}

  /* ── affiliate ── */
  .afband{margin-top:30px}
  .afband>div{padding:20px 18px}
  .calc{padding:20px}
  .calc__out{padding:18px}

  /* ── account ── */
  .acctnav,.acctmain{border-radius:16px}
  .acctnav nav{grid-template-columns:1fr 1fr}
  .acctnav nav button{padding:12px}

  /* ── contact form ── */
  .form{gap:10px}
  .field{height:52px;border-radius:12px}
  textarea.field{height:140px}
  .form .btn{width:100%;margin-top:4px}

  /* ── cart drawer ── */
  .cart{width:100%}
  .cart__top{padding:16px 18px;padding-top:calc(16px + env(safe-area-inset-top,0px))}
  .cart__items{padding:8px 18px}
  .ship{padding:14px 18px}
  .cart__foot{padding:9px 18px;padding-bottom:calc(9px + env(safe-area-inset-bottom,0px))}
  .qty button{width:32px;height:32px}

  /* ── search overlay ── */
  .srch{padding:calc(20px + env(safe-area-inset-top,0px)) 14px 14px}
  .srch__in{padding:6px 16px}
  .sres{padding:12px;min-height:64px}

  /* ── footer ── */
  .foot__grid{gap:28px;grid-template-columns:minmax(0,1fr)}
  .foot__grid>*{min-width:0}
  .foot__note,.foot__grid ul a,.foot__bot{overflow-wrap:anywhere}
  .foot__grid ul{gap:4px}
  .foot__grid ul a{display:inline-block;padding:8px 0;min-width:44px;font-size:15px}
  .sub{max-width:none}
  .foot__bot{gap:10px 18px;font-size:12.5px}
  .foot__note{max-width:none}

  /* ── iOS refuses to not zoom on focus below 16px ── */
  .field,.sub input,.labsearch input,.srch__in input,
  input[type=number],input[type=email],input[type=text],select,textarea{font-size:16px}

  /* ── faq ── */
  .faq summary{font-size:16px;padding:15px 0;gap:12px}
  .faq p{font-size:15px}

  /* ── age gate ── */
  .gate{padding:16px}
  .gate__card{padding:28px 20px 24px;border-radius:20px}
  .gate__mark{height:30px;margin-bottom:18px}
  .gate .gate__logo{height:30px!important;max-height:30px!important}
  .gate h2{font-size:25px}
  .gate__body{font-size:14px;line-height:1.68}
  .gate__btns .btn{min-height:52px;font-size:12.5px}

  /* ── toast clears the home indicator ── */
  /* clears the cart drawer's checkout button and the stack bar's CTA */
  .toast{bottom:calc(92px + env(safe-area-inset-bottom,0px));max-width:calc(100vw - 32px);
    text-align:center;padding:12px 18px}
  .wa{bottom:calc(16px + env(safe-area-inset-bottom,0px))}
}

/* ── small phones: 320–400 ── */
@media (max-width:400px){
  .hdr__in{gap:6px}
  .tools{gap:1px}
  /* 4 × 40px icons + the currency pill only fit 320px once the globe goes;
     the label is what carries the meaning anyway */
  .curbtn{height:40px;padding:0 9px;gap:0;font-size:12.5px}
  .curbtn svg{display:none}
  .brand img{height:31px}
  .hdr.stuck .brand img{height:29px}
  .grid,.sgrid{gap:9px}
  .pc__body{padding:11px 11px 13px}
  .pc h3{font-size:14.5px}
  .size{height:32px;padding:0 8px;font-size:11px}
  .pc .add{height:40px;font-size:13px}
  .price{font-size:15px}
  .tier{flex:1 1 100%}
  .topbar span{padding:0 22px;font-size:12px}
  .belt__i{padding:7px 11px}
}

@media (max-width:360px){
  .curbtn{padding:0 8px;font-size:12px}
  .brand img{height:29px}
}

/* ══════════════════════════════════════════════════════════════════════
   PHONE STOREFRONT — a mobile-first arrangement, not a shrunken desktop.
   Goal: the shopper sees real products without scrolling first, so the
   hero is compressed to a headline, one line of value, the vial trio and
   the two CTAs; trust facts collapse into one thin strip; the catalogue
   head loses its marketing paragraph and hands straight to the chips.
   Everything here is phone-only — desktop never sees a line of it.
   ══════════════════════════════════════════════════════════════════════ */
.hero__lead--m{display:none}

@media (max-width:640px){

  /* ── section order: products come before the marketing furniture ── */
  /* :not([hidden]) matters — a bare #home{display:flex} outranks the UA's
     [hidden]{display:none}, which would leave the home page painted on top
     of every routed page */
  #home:not([hidden]){display:flex;flex-direction:column}
  #home>.hero{order:1}
  /* the benefits slider belongs directly under the hero, not below the grid */
  #home>.belt{order:2}
  #home>#shop{order:3}
  #home>.stats--low{order:4}
  #home>#quality{order:5}
  #home>#learn{order:6}
  #home>#contact{order:7}

  /* ── hero: one column, resequenced ──
     .hero__copy dissolves so its children and the vial stage can be
     ordered against each other in a single flex column. */
  .hero{padding-block:10px 0;overflow:hidden}
  /* the desktop grid centres its two columns; as a flex column that would
     centre every child horizontally instead of filling the width */
  .hero__grid{display:flex;flex-direction:column;gap:0;align-items:stretch}
  .hero__copy{display:contents}
  h1.hero__h{order:1;margin-top:2px;font-size:clamp(21px,5.9vw,25px);line-height:1.14;
    letter-spacing:-.036em;text-wrap:balance}
  .hero__lead--m{order:2;display:block;margin-top:5px;font-size:13.5px;line-height:1.34;
    color:var(--ink-2);max-width:none}
  /* Measured with the float paused on its highest frame, the glass comes within
     ~4px of the copy above — so the top gap has almost nothing to give. It loses
     2px, and the float's lift loses the same 2px (floatLm/Cm/Rm below), which
     keeps the closest approach exactly where it was. The real slack was always
     underneath, and that is trimmed via #home>.hero padding-bottom. */
  .stage{order:3;margin-top:8px;margin-bottom:0}
  /* the catalogue starts a few hundred pixels below, so a pair of buttons
     pointing at it is a step the visitor does not need to take */
  .hero__cta{display:none}
  /* the primary button carries a soft green glow; without this the slider
     band that follows clips it and the pair reads as cut off */
  /* Trimmed from 12px: the band under the vials measured 25–45px depending on
     width, which read as dead space. The float only ever carries the vials
     upward, so shortening this edge can never bring them closer to anything. */
  #home>.hero{padding-bottom:4px}
  .stats{order:5}
  /* folded into the trust strip below, or simply redundant on a phone */
  .pill,.hero__lead:not(.hero__lead--m){display:none}
  /* the two proof chips stay, riding the bottom of the composition where the
     plinth would be, so the claim is still next to the product on a phone */

  /* the composition keeps its parts and their relationship, but lies
     wide and shallow so it costs ~230px of the fold instead of ~330 */
  /* no plate on a phone — the trio floats on clean white — and with the
     podium gone the vials close ranks so the group reads as one object
     instead of three spread across the width. Sizes, angles and artwork
     are untouched; only their left/right positions move inward. */
  .stage{width:100%;max-width:none;aspect-ratio:2.7/1;margin-inline:0}
  /* Width-driven sizing let the vials grow taller than the shortened stage and
     spill into the strip below. Driving them from the stage's height instead
     makes the overlap arithmetically impossible: each vial's top plus its own
     height is a fixed share of the box, so the lowest point of the tallest one
     always lands above the floor, at every width. */
  /* The hero's animation area is the .stage box, and on a phone the vials have
     to live entirely inside it. Sizing them from their WIDTH (as desktop does)
     makes their height a function of the image ratio, so a shorter stage left
     them taller than their own container and the strip below covered whatever
     hung out. Driving them from the stage HEIGHT instead makes the floor
     arithmetic, not a guess: top% + height% is the vial's lowest edge as a
     share of the box, and every one is capped at 79% — a fifth of the stage is
     kept clear beneath them at every width. The float only ever travels
     upward, so the resting position is also the lowest position. */
  /* !important for the same reason the header and gate marks carry it: caching
     and image-optimisation plugins inject a blanket img{height:auto!important}
     to chase layout shift. This sizing IS the containment — if it loses, the
     vials snap to their natural 1454px and pour out of the hero. */
  .fv{width:auto}
  .fv .fv__i{height:100%!important}
  .fv img{width:auto!important;height:100%!important;max-height:100%!important;
    max-width:none!important;display:block!important}
  /* A smaller travel on a phone: the box is a third of its desktop height, so a
     19px rise is a fifth of it. Same motion, proportionate amplitude — and it
     keeps the top of the cycle inside the hero rather than nudging the line of
     copy above. Upward only, so the resting frame stays the lowest one. */
  .fv--l{animation-name:floatLm}
  .fv--c{animation-name:floatCm}
  .fv--r{animation-name:floatRm}
  /* Lowest edge 86% of the stage — a seventh of the box stays clear beneath
     them. The vials are as large as that floor allows; the way to make them
     larger is to give the stage more height, which the taller phones below do. */
  /* The grey polygon behind each vial was the drop-shadow: a filter on an
     element that is both rotated and promoted to its own layer by will-change
     gets rasterised against the element's BOX, not the PNG's alpha, so the
     shadow shows as a tilted rectangle — and repaints away on scroll, which is
     why it looked intermittent. The artwork carries its own studio lighting, so
     on a phone the filter and the layer promotions come off entirely. */
  .fv img{filter:none!important}
  .fv,.fv__i{will-change:auto}

  .fv--c{width:auto;height:82%;top:4%;margin-left:0}   /* lowest edge 86% */
  .fv--l{width:auto;height:69%;top:17%}                /* lowest edge 86% */
  .fv--r{width:auto;height:71%;top:15%;right:auto}     /* lowest edge 86% */
  .podium{display:none}

  .hero__cta .btn{flex:1 1 0;min-width:0;height:48px;padding:0 12px;font-size:14.5px}
  .hero__cta .btn--primary{flex:1.45 1 0}
  .hero__cta .btn svg{display:none}

  /* ── trust strip: three facts, one hairline band, full bleed ── */
  /* On a phone the three facts scroll instead of squeezing: the band runs
     full bleed and the track drifts left to right, the same treatment as the
     announcement bar, so nothing is cramped into a third of a small screen. */

  /* ── catalogue: no preamble, straight to the chips and the grid ── */
  #shop.sec{padding-block:3px 28px}
  #shop .shead{display:block;margin-bottom:8px}
  #shop .shead p,#shop .shead>a,#shop .shead .kick{display:none}
  /* the grid is self-evident on a phone; this line only pushed product down */
  /* The catalogue's intro block is not drawn on a phone, but display:none on
     the whole thing also dropped its <h2> out of the heading outline, leaving
     the page jumping <h1> straight to the <h3> on each card. The block is
     hidden and the heading alone is kept, clipped, so the structure survives. */
  #shop .shead{display:block;height:0;margin:0;overflow:hidden}
  #shop .shead > div > :not(h2){display:none}
  #shop .shead h2{position:absolute;width:1px;height:1px;margin:-1px;padding:0;
    overflow:hidden;clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap}
  /* 4px ran the filter row straight into the first product row. 14px separates
     the two without costing the fold — the first card still clears the bottom of
     the screen at 320, 360, 390 and 430. The 10px above does the same job on the
     other side: the section's own padding left only 3px between the benefit
     strip and the chips, so the two ran together. */
  .chips{margin-top:10px;margin-bottom:14px}
  .chip{height:38px;font-size:13px;padding:0 14px}

  /* ── product cards: tighter, with price and action on one line ── */
  .grid{gap:10px}
  .pc{border-radius:14px}
  .pc__body{padding:10px 11px 11px}
  .pc .tag{padding:3px 7px;font-size:10px;border-radius:5px}
  .pc h3{font-size:14.5px;margin-top:1px;line-height:1.25}
  /* The bottom half of this padding was the whole gap between the product name
     and its price. It is not doing any tap-target work — .pc h3 a::after already
     stretches the link across the entire card — so it comes down to 4px. The top
     stays put; it is what separates the name from the category tag. */
  .pc h3 a{display:block;padding:10px 0 0}
  /* compact dosage chips: a horizontal rail that scrolls rather than
     wrapping to a second row, so a 4-dose product costs the same vertical
     space as a 1-dose one. 34px keeps them comfortably tappable. */
  .pc__sizes{margin-top:6px;gap:4px;flex-wrap:nowrap;overflow-x:auto;
    scrollbar-width:none;-ms-overflow-style:none;
    -webkit-mask-image:linear-gradient(90deg,#000 88%,transparent);
    mask-image:linear-gradient(90deg,#000 88%,transparent)}
  .pc__sizes::-webkit-scrollbar{display:none}
  .size{flex:none;height:34px;min-width:44px;justify-content:center;padding:0 9px;
    font-size:11.5px;font-weight:800;border-radius:8px;border-width:1.5px;letter-spacing:-.01em}
  /* On a product page the dosage is the decision, so every option stays
     visible: the rail is for cards, where a hidden option costs nothing. */
  .pdp .pc__sizes{flex-wrap:wrap;overflow:visible;-webkit-mask-image:none;mask-image:none;gap:6px}
  .pdp .size{flex:0 0 auto}
  .size.on{background:var(--brand);border-color:var(--brand);color:var(--on-brand)}
  /* The price is the one thing in the foot that must never be squeezed: it
     was set to shrink with nowrap, so on a 360px screen it printed straight
     over the button. It now holds its width and the button takes the rest —
     the button already swaps its label to "Add", so it reads fine narrow. */
  .pc__foot .price{flex:0 0 auto;font-size:14px}
  .pc__foot .add{flex:1 1 auto;width:auto;min-width:0}
  /* price and action share one line — worth ~46px per card row */
  .pc__foot{flex-direction:row;align-items:center;justify-content:space-between;
    gap:6px;padding-top:5px}
  .price{font-size:14.5px;white-space:nowrap;flex:0 1 auto;min-width:0}
  .price em{display:inline}
  /* "Add to cart" is too wide for a half-width card; the label is swapped
     through ::after so the button never reflows and the confirmed state
     still reads. The real text stays for screen readers. */
  /* the short label is a grid-card affordance only — the product page's
     primary CTA keeps its full "Add to cart" wording */
  .pc .add{width:auto;height:38px;padding:0 12px;font-size:0;flex:none;min-width:54px;
    justify-content:center}
  .pc .add::after{content:'Add';font-size:12.5px;font-weight:800;letter-spacing:-.01em}
  .pc .add.done::after{content:'✓';font-size:15px}
  .pc__quick{width:36px;height:36px;top:8px;left:8px}
  .more{margin-top:20px}
  .more .btn{width:100%}

  /* ── the rest: same content, less air ── */
  .sec{padding-block:34px}
  .belt__i{padding:7px 10px;gap:7px}
  .belt__i svg{width:17px;height:17px}
  .belt__i b{font-size:13px}
  .belt__i span{font-size:11.5px}
  #quality .shead h2,#quality h2{font-size:23px !important}
  .ticks{margin-top:18px;gap:11px}
  .ticks li{font-size:14.5px;line-height:1.45}
  .ticks svg{width:19px;height:19px}
  #quality .btn{margin-top:22px !important;width:100%}
  .coa{border-radius:16px}
  #learn.sec{padding-block:34px}
  /* the footer wave is 34px tall here — the Send button has to clear it */
  #contact.sec{padding-block:34px calc(34px + 34px)}
  .res{gap:11px}
  .res article{padding:18px;border-radius:16px}
  .res .ico{width:42px;height:42px;border-radius:12px;margin-bottom:13px}
  .res .ico svg{width:21px;height:21px}
  .res h3{font-size:17px}
  .res p{margin-top:7px;font-size:14.5px;line-height:1.5}
  .res .btn{margin-top:16px}
  .shead{margin-bottom:16px}
  .shead h2{font-size:23px}
  .shead p{font-size:14.5px;margin-top:8px}
  .kick{margin-bottom:8px}

  /* category tiles are labels, not cards — full-height boxes pushed the
     actual products 800px down the All Products page */
  .catgrid{grid-template-columns:1fr 1fr;gap:8px}
  .cattile{padding:13px 13px 14px;border-radius:12px}
  .cattile b{font-size:14.5px;letter-spacing:-.02em;line-height:1.25}
  .cattile span{margin-top:3px;font-size:12px}

  /* footer link lists run two-up — a single column of 14 links is 600px of
     scrolling for navigation almost nobody uses on a phone */
  .foot__grid{gap:22px}
  .foot__grid ul{grid-template-columns:1fr 1fr;column-gap:14px}
  .foot__grid ul a{font-size:14px;padding:9px 0;min-width:44px}
  .foot h4,.foot__h{margin-bottom:8px}
  .foot{padding-block:34px 22px}
  .foot__note{margin-top:12px;font-size:13.5px}
  .sub{margin-top:14px}
  .foot__bot{margin-top:26px;padding-top:16px}
}

/* very small phones: hold the two CTAs on one line — stacking them costs
   56px of the fold, which is the difference between seeing product and not */
@media (max-width:359px){
  h1.hero__h{font-size:19.5px;line-height:1.12}
  .hero__lead--m{font-size:13.5px;margin-top:6px}
  .hero__cta{gap:6px}
  .hero__cta .btn{height:46px;padding:0 8px;font-size:12.5px;letter-spacing:-.02em}
  /* the primary label is the longer of the two, so it takes the larger share */
  .hero__cta .btn--primary{flex:1.75 1 0}
  .stage{aspect-ratio:1.62/1}
  /* below 360 the two no longer fit side by side */
  .pc__foot{flex-direction:column;align-items:stretch;gap:8px}
  .price{font-size:14.5px}
  .pc .add{width:100%;min-width:0;height:38px}
  #shop .shead h2{font-size:18px}
}

@media (prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  *,*::before,*::after{animation-duration:.001ms !important;animation-iteration-count:1 !important;
    transition-duration:.001ms !important}
  [data-rv]{opacity:1;transform:none}
  /* The hero vials are exempt. The blanket rule above collapses their float to
     nothing, which left the hero dead on any machine with the OS animation
     setting switched off while the three strips carried on — the store is asked
     to look the same everywhere, so the drift stays. It is a slow few-pixel
     rise, not a transition or a reveal. */
  .fv--l,.fv--c,.fv--r{animation-duration:9.5s !important;animation-iteration-count:infinite !important}
  .fv--c{animation-duration:11.2s !important}
  .fv--r{animation-duration:8.3s !important}
}

/* 4px short of a complete first row on a 360×740 screen — the composition gives
   it up rather than the product card */
/* At 360×740 the square media costs more than the fold can spare, so the
   composition gives up the difference. The vials are smallest at this width
   either way; a visible product row is worth more here than 16px of hero. */
@media (max-width:380px){
  .stage{aspect-ratio:3.5/1}
  .fv--l{left:16.27%}
  .fv--c{left:41.70%}
  .fv--r{left:68.99%}
  .pc__body{padding-bottom:8px}
}

/* 320px is the tightest screen we support and the least forgiving: the hero,
   the strip and the chips leave barely 230px for a product. The composition and
   the media box both give up a little more so the row still lands. */
@media (max-width:340px){
  .stage{aspect-ratio:3.5/1}
  .belt{min-height:61px;padding-block:7px}
  .pc__media{aspect-ratio:1.45/1}
  .pc__body{padding:8px 9px 9px}
  .pc__foot{padding-top:7px}
}

@keyframes floatLm{
  0%,100%{transform:translate3d(0,0,0) rotate(8.8deg)}
  50%    {transform:translate3d(0,-5px,0) rotate(9.35deg)}
}
@keyframes floatCm{
  0%,100%{transform:translate3d(0,0,0) rotate(-9.6deg)}
  50%    {transform:translate3d(0,-6px,0) rotate(-9.05deg)}
}
@keyframes floatRm{
  0%,100%{transform:translate3d(0,0,0) rotate(-13.7deg)}
  50%    {transform:translate3d(0,-4px,0) rotate(-14.05deg)}
}

/* The vials are sized from the stage, so the stage's height IS their size. On
   the taller phones there is fold to spare, so it takes it back and they read
   large again; at 360 and below every pixel is already spoken for by the
   product row, so it stays shallow there. */
@media (min-width:391px) and (max-width:640px){
  .stage{aspect-ratio:1.78/1}
  /* Solved from the rendered artwork, not the element boxes: each vial is a
     rotated PNG with transparent margins, so its layout box says nothing about
     where the glass actually starts. These offsets put an equal gap between the
     visible silhouettes, and the same gap again either side of the group. */
  .fv--l{left:7.97%}
  .fv--c{left:34.33%}
  .fv--r{left:64.62%}
}
@media (min-width:361px) and (max-width:390px){
  .stage{aspect-ratio:2.05/1}
  .fv--l{left:10.19%}
  .fv--c{left:36.50%}
  .fv--r{left:66.05%}
}

/* ══ touch targets ══
   The card's cart button is drawn at 36×36, under the 44px comfort target, and
   it cannot simply grow — at 44px the white disc sits heavily over the product
   photo. So it keeps its drawn size and gains the missing millimetres from a
   transparent pseudo-element: the finger target is 44×44 while the layout and
   the artwork are pixel-for-pixel unchanged. The ring stays inside the card, so
   the card's own rounded clipping never eats it.

   The filter chips are deliberately NOT treated the same way. They are 38px
   tall — comfortably past the 24px WCAG minimum, just under the 44px comfort
   figure — and the row is a horizontal scroller, so a taller hit area would
   either be clipped away by the scroller (leaving the target no bigger than it
   looks) or push the first product row further down the phone screen. Keeping
   the products reachable without scrolling is worth more than the last 6px. */
.pc__quick::after{content:'';position:absolute;top:-4px;right:-4px;bottom:-4px;left:-4px;
  border-radius:inherit}

/* ══ loading placeholders ══
   The catalogue is client-rendered, so before site.js runs the section was
   108px tall and then snapped to its full height — the page below lurched and
   the phone home page scored CLS 0.45. These hold the exact space the real
   markup takes, using the same classes so the geometry cannot drift, and read
   as a loading state rather than an empty hole. They are replaced wholesale the
   moment the real cards render. */
.pc--skel{pointer-events:none}
.pc--skel .pc__media{background:var(--well);border-radius:inherit}
.pc--skel .tag,.pc--skel h3,.pc--skel .size,
.pc--skel .price,.pc--skel .add{
  color:transparent;background:var(--soft);border-color:transparent;border-radius:6px}
.pc--skel h3{max-width:78%}
.pc--skel .price{display:inline-block;min-width:74px}
.chip--skel{width:118px;background:var(--soft);border-color:transparent;pointer-events:none}
.chip--skel:nth-child(2){width:150px}
.chip--skel:nth-child(3){width:132px}
.chip--skel:nth-child(4){width:164px}
/* a slow, low-contrast breathe so it reads as "loading" without drawing the eye */
@media (prefers-reduced-motion:no-preference){
  .pc--skel .pc__media,.pc--skel .tag,.pc--skel h3,.pc--skel .size,
  .pc--skel .price,.pc--skel .add,.chip--skel{animation:skelPulse 1.5s ease-in-out infinite}
}
@keyframes skelPulse{0%,100%{opacity:1}50%{opacity:.62}}

/* ══ visually hidden ══
   For headings that structure the page for a screen reader without being drawn.
   The listing pages went straight from <h1> to the <h3> on each product card,
   which reads to assistive tech as a missing level. Clip rather than
   display:none — the latter takes it out of the accessibility tree too. */
.vh{position:absolute!important;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;
  clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap;border:0}
/* The footer column headings became <h2> for the same reason; they are folded
   into the existing .foot h4 rule above rather than restyled here. */

/* The placeholder grid is rendered at the widest case (4 columns × 3 rows = 12).
   Narrower layouts want fewer, so the surplus is hidden rather than a different
   number being rendered — the count has to match firstBatch() in site.js or the
   page shifts when the real cards arrive. */
@media (max-width:1150px){ .pc--skel:nth-child(n+10){display:none} }   /* 3 cols × 3 rows */
@media (max-width:640px){  .pc--skel:nth-child(n+9){display:none} }    /* 2 cols × 4 rows */

/* ══ help: FAQs / contact ══
   One switch, two panels. The dark pill is a single element that slides and
   resizes to whichever tab is live — one object moving reads as a control,
   whereas two backgrounds swapping on and off reads as a flicker. */
.help{max-width:820px;margin-inline:auto;text-align:left}
.help__tabs{position:relative;display:flex;gap:4px;padding:5px;margin:0 auto 26px;width:max-content;
  background:var(--soft);border:1px solid var(--line);border-radius:999px}
.help__ink{position:absolute;top:5px;left:0;height:calc(100% - 10px);width:0;border-radius:999px;
  background:var(--ink);box-shadow:0 10px 22px -12px rgba(13,18,17,.7);
  transform:translateX(0);will-change:transform,width;
  transition:transform .44s cubic-bezier(.32,.72,0,1),width .44s cubic-bezier(.32,.72,0,1)}
.help__tab{position:relative;z-index:1;height:44px;padding:0 28px;border:0;background:none;
  border-radius:999px;font:inherit;font-size:15px;font-weight:800;letter-spacing:-.012em;
  color:var(--ink-2);cursor:pointer;white-space:nowrap;
  transition:color .3s cubic-bezier(.32,.72,0,1)}
.help__tab[aria-selected="true"]{color:var(--paper)}
/* Until the script marks the strip ready, the sliding pill has no width, so the
   selected tab paints its own — otherwise a JS failure leaves white-on-white. */
.help__tabs:not(.is-ready) .help__tab[aria-selected="true"]{background:var(--ink)}
@media (hover:hover){.help__tab:not([aria-selected="true"]):hover{color:var(--ink)}}

.help__panel[hidden]{display:none}
.help__panel.is-on{animation:helpIn .38s cubic-bezier(.32,.72,0,1) both}
@keyframes helpIn{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:none}}

/* The FAQ rows are written by site.js. Reserving the collapsed height here
   stops the section growing under the reader when they arrive. */
.faq--wait{min-height:356px}

/* A superseded certificate stays in the table so an older vial can still be
   looked up; it is muted and labelled rather than removed. */
.archtag{display:inline-block;margin-left:8px;padding:2px 7px;border-radius:999px;
  background:var(--well);border:1px solid var(--line);color:var(--ink-3);
  font-size:10px;font-weight:800;letter-spacing:.09em;text-transform:uppercase;
  vertical-align:middle}
.labrow--arch td{color:var(--ink-3)}
.labrow--arch td b{font-weight:700;color:var(--ink-2)}

/* ══ FAQ page ═══════════════════════════════════════════════════════════
   Grouped into sections with a card per question. The cards were white on a
   white page with a hairline border, so they dissolved into the background —
   the list now sits on a tinted panel and the cards are the only white
   surfaces on it, which is what makes each one read as a distinct object.
   Card styling is scoped to .faqgrp: the same rows are reused inside .faq on
   the home page's help panel, where a flat bordered list is right. */
.faqhead{max-width:680px;margin:0 auto 26px;padding:38px 24px 32px;text-align:center;
  border-radius:26px;background:linear-gradient(180deg,var(--brand-tint) 0%,rgba(233,253,239,0) 78%)}
.eyebrow{display:inline-flex;align-items:center;gap:10px;font-size:11px;font-weight:800;
  letter-spacing:.16em;text-transform:uppercase;color:var(--brand-text)}
.eyebrow i{display:block;width:26px;height:2px;background:var(--brand);border-radius:2px}
.faqhead h1{margin:15px 0 12px;font-size:clamp(29px,4.4vw,46px);font-weight:800;
  letter-spacing:-.035em;line-height:1.06}
.faqhead p{margin:0;color:var(--ink-2);font-size:16px;line-height:1.65}

.faqwrap{max-width:800px;margin:0 auto;padding:28px 24px 14px;border-radius:26px;
  background:var(--well);border:1px solid var(--line)}
.faqgrp{margin-bottom:28px}
.faqgrp:last-child{margin-bottom:16px}
.faqgrp h2{display:flex;align-items:center;gap:10px;margin:0 0 13px;font-size:18px;
  font-weight:800;letter-spacing:-.025em}
.faqgrp h2::before{content:'';flex:none;width:4px;height:17px;border-radius:3px;background:var(--brand)}
.faqgrp__n{margin-left:auto;font-size:12px;font-weight:800;color:var(--ink-3);
  letter-spacing:.04em}

.faqgrp .fq{background:var(--paper);border:1px solid var(--line-2);border-radius:14px;
  margin-bottom:9px;box-shadow:0 1px 2px rgba(13,18,17,.04);
  transition:border-color .2s var(--ease),box-shadow .2s var(--ease),transform .2s var(--ease)}
.faqgrp .fq:hover{border-color:#c9d2cc;box-shadow:var(--shadow);transform:translateY(-1px)}
.faqgrp .fq summary{display:flex;align-items:center;justify-content:space-between;gap:14px;
  cursor:pointer;list-style:none;padding:15px 16px;font-size:15.5px;font-weight:700;
  letter-spacing:-.015em;color:var(--ink);border-radius:13px}
.faqgrp .fq summary::-webkit-details-marker{display:none}
.faqgrp .fq summary::after{content:'';flex:none;width:28px;height:28px;border-radius:50%;
  background:var(--brand-tint) url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23098231' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E") center/13px no-repeat;
  transition:transform .25s var(--ease),background-color .2s var(--ease)}
.faqgrp .fq[open]{border-color:var(--brand);box-shadow:0 3px 20px rgba(25,237,86,.18);transform:none}
.faqgrp .fq[open] summary{background:var(--brand-tint);border-radius:13px 13px 0 0}
.faqgrp .fq[open] summary::after{transform:rotate(180deg);background-color:var(--paper)}
.faqgrp .fq__a{padding:14px 16px 16px;color:var(--ink-2);font-size:15px;line-height:1.72;
  max-width:70ch;border-top:1px solid var(--line)}
.faqgrp .fq__a a{color:var(--brand-text);font-weight:700}
.faqgrp .fq__a strong{color:var(--ink);font-weight:800}

/* faqRow wraps the answer in a div, so the help panel needs the rule the old
   <p> was getting */
.faq .fq__a{padding:0 0 16px;color:var(--ink-2);font-size:15.5px;line-height:1.7;max-width:70ch}
.faq .fq__a a{color:var(--brand-text);font-weight:700}

.faqcta{max-width:800px;margin:26px auto 0;padding:42px 26px;border-radius:26px;
  text-align:center;background:var(--ink);color:#fff;
  background-image:radial-gradient(120% 90% at 50% 0%,rgba(25,237,86,.16),transparent 60%)}
.faqcta b{display:block;font-size:clamp(22px,3vw,30px);font-weight:800;letter-spacing:-.03em}
.faqcta p{margin:11px auto 22px;max-width:48ch;color:rgba(255,255,255,.72);
  font-size:15px;line-height:1.65}

@media (prefers-reduced-motion:reduce){
  .faqgrp .fq,.faqgrp .fq summary::after{transition:none}
  .faqgrp .fq:hover{transform:none}
}
@media (max-width:640px){
  .faqhead{padding:28px 16px 24px;margin-bottom:20px;border-radius:20px}
  .faqwrap{padding:20px 14px 8px;border-radius:20px}
  .faqgrp{margin-bottom:24px}
  .faqgrp .fq summary{padding:14px;font-size:14.8px}
  .faqgrp .fq__a{padding:13px 14px 15px;font-size:14.6px}
  .faqcta{padding:32px 20px;border-radius:20px;margin-top:20px}
}

/* A superseded certificate stays in the table so an older vial can still be
   looked up; it is muted and labelled rather than removed. */
.archtag{display:inline-block;margin-left:8px;padding:2px 7px;border-radius:999px;
  background:var(--well);border:1px solid var(--line);color:var(--ink-3);
  font-size:10px;font-weight:800;letter-spacing:.09em;text-transform:uppercase;
  vertical-align:middle}
.labrow--arch td{color:var(--ink-3)}
.labrow--arch td b{font-weight:700;color:var(--ink-2)}

/* ══ FAQ page ═══════════════════════════════════════════════════════════
   Grouped into sections with a card per question, so a long list scans by
   category instead of as one undifferentiated column. Card styling is scoped
   to .faqgrp: the same rows are reused inside .faq on the home page's help
   panel, where the flat bordered list is the right density. */
.faqhead{max-width:660px;margin:0 auto 36px;text-align:center}
.eyebrow{display:inline-flex;align-items:center;gap:10px;font-size:11px;font-weight:800;
  letter-spacing:.16em;text-transform:uppercase;color:var(--brand-text)}
.eyebrow i{display:block;width:26px;height:2px;background:var(--brand);border-radius:2px}
.faqhead h1{margin:15px 0 12px;font-size:clamp(29px,4.4vw,46px);font-weight:800;
  letter-spacing:-.035em;line-height:1.06}
.faqhead p{margin:0;color:var(--ink-2);font-size:16px;line-height:1.65}

.faqwrap{max-width:760px;margin:0 auto}
.faqgrp{margin-bottom:32px}
.faqgrp h2{margin:0 0 13px;font-size:19px;font-weight:800;letter-spacing:-.025em}

.faqgrp .fq{border:1px solid var(--line);border-radius:14px;background:var(--paper);
  margin-bottom:10px;transition:border-color .22s var(--ease),box-shadow .22s var(--ease)}
.faqgrp .fq:hover{border-color:var(--line-2)}
.faqgrp .fq summary{display:flex;align-items:center;justify-content:space-between;gap:14px;
  cursor:pointer;list-style:none;padding:15px 16px;font-size:15.5px;font-weight:700;
  letter-spacing:-.015em;color:var(--ink);border-radius:14px}
.faqgrp .fq summary::-webkit-details-marker{display:none}
.faqgrp .fq summary::after{content:'';flex:none;width:28px;height:28px;border-radius:50%;
  background:var(--brand-tint) url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%230a7a30' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E") center/13px no-repeat;
  transition:transform .25s var(--ease)}
.faqgrp .fq[open]{border-color:var(--brand);box-shadow:0 2px 16px rgba(25,237,86,.12)}
.faqgrp .fq[open] summary::after{transform:rotate(180deg)}
.faqgrp .fq__a{padding:0 16px 16px;color:var(--ink-2);font-size:15px;line-height:1.72;max-width:70ch}
.faqgrp .fq__a a{color:var(--brand-text);font-weight:700}
.faqgrp .fq__a strong{color:var(--ink);font-weight:800}

/* faqRow now wraps the answer in a div, so the help panel needs the rule the
   old <p> was getting */
.faq .fq__a{padding:0 0 16px;color:var(--ink-2);font-size:15.5px;line-height:1.7;max-width:70ch}
.faq .fq__a a{color:var(--brand-text);font-weight:700}

.faqcta{max-width:760px;margin:6px auto 0;padding:40px 26px;border-radius:20px;
  text-align:center;background:var(--ink);color:#fff}
.faqcta b{display:block;font-size:clamp(22px,3vw,30px);font-weight:800;letter-spacing:-.03em}
.faqcta p{margin:11px auto 22px;max-width:48ch;color:rgba(255,255,255,.72);
  font-size:15px;line-height:1.65}

@media (prefers-reduced-motion:reduce){
  .faqgrp .fq summary::after{transition:none}
}
@media (max-width:640px){
  .faqhead{margin-bottom:28px}
  .faqgrp{margin-bottom:26px}
  .faqgrp .fq summary{padding:14px;font-size:14.8px}
  .faqgrp .fq__a{padding:0 14px 15px;font-size:14.6px}
  .faqcta{padding:32px 20px;border-radius:16px}
}
.help__more{display:inline-flex;align-items:center;gap:8px;margin-top:20px;min-height:44px;
  font-size:14.5px;font-weight:800;letter-spacing:-.01em;color:var(--brand-text)}
.help__more svg{width:17px;height:17px;fill:none;stroke:currentColor;stroke-width:2.2;
  stroke-linecap:round;stroke-linejoin:round;transition:transform .3s cubic-bezier(.32,.72,0,1)}
@media (hover:hover){.help__more:hover svg{transform:translateX(4px)}}

/* ── direct routes ── */
.ways{display:grid;gap:10px;margin-bottom:26px}
.way{display:flex;align-items:center;gap:14px;padding:14px 18px;background:var(--paper);
  border:1px solid var(--line);border-radius:16px;
  transition:border-color .24s var(--ease),transform .24s var(--ease),box-shadow .24s var(--ease)}
@media (hover:hover){.way:hover{border-color:var(--line-2);transform:translateY(-2px);
  box-shadow:0 14px 30px -22px rgba(13,18,17,.7)}}
.way__i{flex:none;display:grid;place-items:center;width:42px;height:42px;border-radius:12px;
  background:var(--brand-tint);color:var(--brand-text)}
.way__i svg{width:21px;height:21px;fill:none;stroke:currentColor;stroke-width:1.8;
  stroke-linecap:round;stroke-linejoin:round}
.way__i--wa{background:#e9fdef}
.way__t{display:flex;flex-direction:column;min-width:0;flex:1 1 auto}
.way__t b{font-size:15.5px;font-weight:800;letter-spacing:-.02em;color:var(--ink)}
.way__t i{font-style:normal;margin-top:2px;font-size:13px;color:var(--ink-3)}
.way__v{flex:none;font-size:14px;font-weight:700;color:var(--ink-2);white-space:nowrap}
.form--help{margin-inline:0;max-width:none}
.form--help .btn{justify-self:start;min-width:200px}

@media (max-width:640px){
  .help__tabs{width:100%;margin-bottom:20px}
  .help__tab{flex:1 1 0;padding:0 12px;font-size:14.5px}
  .faq--wait{min-height:342px}
  .way{padding:12px 14px;gap:12px}
  /* the value is the least important part of the row, so on a phone it drops
     under the label instead of squeezing the label into two lines */
  .way{flex-wrap:wrap}
  .way__v{width:100%;padding-left:54px;margin-top:-2px;font-size:13.5px}
  .way__t i{display:none}
  .form--help .btn{justify-self:stretch;width:100%}
}
@media (prefers-reduced-motion:reduce){
  .help__ink{transition:none}
  .help__panel.is-on{animation:none}
  .help__more svg{transition:none}
}

/* Below ~356px two of the questions wrap onto a second line, so the collapsed
   list is taller than the 390px case reserves. Measured, not guessed: 343px at
   360 and above, 369px at 355, 394px at 350 and below. */
@media (max-width:356px){ .faq--wait{min-height:394px} }


/* ══ sale price ══
   The struck figure is a reference, not the price charged — it is set quieter
   and lighter than the live number so the eye lands on what is actually paid. */
/* cart lines and suggestion cards keep the inline treatment; product cards use
   .price__ref above */
.us__p s,.ci .ci__was{text-decoration-thickness:1.5px}
.price--sale .price__n{color:var(--brand-text)}
/* the discount flag, opposite the cart button so the two never collide */
/* ── availability on the shelf ──────────────────────────────────────
   The photograph is left exactly as it is. Desaturating it made the whole
   grid look broken rather than making one product look unavailable, and the
   vial is the thing a shopper is scanning for. The button carries the message
   on its own: it sits where the eye already goes to act. */
.pc--out .price{color:var(--ink-3)}
.pc--out .price s{opacity:.6}
/* Keeps its size and position so the grid stays on its rhythm, but stops
   looking like the primary action on the card. */
.add--out{background:transparent;color:var(--ink-2);border:1.5px solid var(--line-2);cursor:default}
.add--out:hover{background:var(--well);color:var(--ink);border-color:var(--ink-3)}
/* A single unavailable dosage inside an otherwise stocked product. The chip
   stays legible and stays selectable — choosing it is how a shopper reaches
   the notify form — it simply stops claiming to be for sale. */
.size--gone{color:var(--ink-3);border-style:dashed;text-decoration:line-through;
  text-decoration-thickness:1px;text-underline-offset:2px}
.size--gone.on{background:var(--well);border-color:var(--line-2);color:var(--ink-2)}
@media (max-width:640px){
}

.pc__sale{position:absolute;top:12px;right:12px;z-index:3;
  padding:5px 11px;border-radius:999px;background:var(--brand);color:var(--on-brand);
  font-size:11px;font-weight:800;letter-spacing:.02em;line-height:1;
  box-shadow:0 8px 18px -10px rgba(11,156,59,.75)}
@media (max-width:640px){
  .pc__sale{top:8px;right:8px;padding:4px 9px;font-size:10px}
  .price s{margin-right:5px;font-size:.74em}
}

/* ══ sale line, product page ══ */
.pdp__sale{display:inline-flex;align-items:center;gap:10px;margin:12px 0 0;padding:7px 8px 7px 7px;
  border-radius:999px;background:var(--brand-tint);border:1px solid color-mix(in srgb,var(--brand-deep) 22%,transparent)}
.pdp__sale__pct{padding:5px 10px;border-radius:999px;background:var(--brand);color:var(--on-brand);
  font-size:11.5px;font-weight:800;letter-spacing:.02em;line-height:1}
.pdp__sale__t{padding-right:6px;font-size:13.5px;font-weight:600;color:var(--ink-2)}
.pdp__sale__t s{color:var(--ink-3);text-decoration-thickness:1.5px}
.pdp__sale__t b{font-weight:800;color:var(--brand-text)}
@media (max-width:640px){
  .pdp__sale{margin-top:10px;gap:8px;padding:6px 7px 6px 6px}
  .pdp__sale__pct{padding:4px 8px;font-size:11px}
  .pdp__sale__t{font-size:12.5px}
}

/* ══ cart: free-shipping timeline ══
   One track, two rewards. The fill measures the whole run to the second goal,
   and the first stop sits at its true position along it — so the gap a shopper
   sees between the two is the gap in money. */
/* The stop labels are positioned under the track rather than in flow, so the
   panel has to carry their height in its own padding — at 26px they escaped the
   bottom edge and sat on the first basket line. */
.ship{padding:16px 20px 44px;border-bottom:1px solid var(--line)}
.ship p{margin:0 0 18px;font-size:13.5px;font-weight:600;color:var(--ink-2);text-align:center}
.ship p b{font-weight:800;color:var(--ink)}
.ship__track{position:relative;height:4px;margin:0 34px}
.ship__rail{position:absolute;inset:0;border-radius:999px;background:var(--line)}
.ship__fill{position:absolute;left:0;top:0;bottom:0;width:0;border-radius:999px;
  background:linear-gradient(90deg,var(--brand-deep),var(--brand));
  transition:width .5s cubic-bezier(.32,.72,0,1)}
.ship__stop{position:absolute;top:50%;transform:translate(-50%,-50%);display:flex;
  flex-direction:column;align-items:center;gap:0}
.ship__dot{display:grid;place-items:center;width:30px;height:30px;border-radius:999px;
  background:var(--paper);border:2px solid var(--line);color:var(--ink-3);
  transition:border-color .35s var(--ease),background-color .35s var(--ease),
             color .35s var(--ease),transform .35s cubic-bezier(.32,.72,0,1)}
.ship__dot svg{width:16px;height:16px;fill:none;stroke:currentColor;stroke-width:1.7;
  stroke-linecap:round;stroke-linejoin:round}
.ship__stop b{position:absolute;top:34px;white-space:nowrap;font-size:11px;font-weight:800;
  letter-spacing:.01em;color:var(--ink-3);transition:color .35s var(--ease)}
.ship__stop.on .ship__dot{background:var(--brand-deep);border-color:var(--brand-deep);
  color:var(--on-brand);transform:scale(1.08)}
.ship__stop.on b{color:var(--brand-text)}
/* With the first stop at 70% there is only 30% of the track between the two
   labels — about 90px — and each label is roughly 90px wide, so centring both
   under their dots guarantees a collision. The first label therefore sits to
   the left of its own checkpoint and the second hugs the end of the track, so
   they read outward from the gap between them instead of into it. */
#shipStop1 b{left:50%;right:auto;transform:translateX(-50%);text-align:center}
#shipStop2 b{left:auto;right:0;transform:none;text-align:right}
/* Narrow phones only: a touch smaller so the two single-line labels keep their
   clearance. The marker itself also steps left at this width (see UAE_AT in
   site.js) — wrapping the labels was the alternative and it broke them onto
   three lines and pushed them out of the section. */
@media (max-width:380px){
  .ship__stop b{font-size:10.5px;letter-spacing:0}
}

/* ══ cart: you may also like ══ */
/* Pinned between the basket and the foot: never scrolls away, so it holds a
   fixed, compact height rather than the tall picture cards it used to. */
.upsell{flex:none;padding:10px 16px;border-top:1px solid var(--line);background:var(--soft)}
/* the button in the cart foot is full width by default; the Apply beside the
   code field is the one exception */
.promo .btn{width:auto;flex:none;padding-inline:17px;height:36px}
.upsell__h{margin:0 0 9px;font-size:11px;font-weight:800;letter-spacing:.13em;
  text-transform:uppercase;color:var(--ink-3)}
/* The negative margin has to match the parent's padding exactly. It was -20px
   against .upsell's 16px, which made this row 8px wider than the drawer and
   left the whole drawer scrolling 4px sideways. Pre-dates the snap change. */
.upsell__row{display:flex;gap:10px;overflow-x:auto;scrollbar-width:none;
  margin-inline:-16px;padding-inline:16px;scroll-snap-type:x proximity;
  scroll-padding-left:16px}
/* the flex row would otherwise collapse the trailing pad on overflow */
.upsell__row::after{content:"";flex:0 0 4px}
.upsell__row::-webkit-scrollbar{display:none}
/* Two per view, and a column so the price block can absorb the difference
     between a one-line and a two-line price — otherwise the Add button rides up
     on whichever card has the shorter price. */
/* A row, not a card: thumbnail, name, price and the add control on one line.
   The tall version was 225px and could never fit above the foot. */
/* Centre-snapped, not start-snapped. With start alignment a full-card step
   always parks the previous card completely off the left edge — that is true
   at any card width, so narrowing it would not have helped. Centring the
   active card leaves a strip of the previous one on the left and the next on
   the right, so paging keeps its context instead of teleporting. */
.us{position:relative;flex:0 0 76%;scroll-snap-align:center;display:flex;
  flex-direction:row;align-items:center;gap:9px;padding:7px 9px 7px 7px;
  background:var(--paper);border:1px solid var(--line);
  border-radius:12px;overflow:hidden;transition:border-color .22s var(--ease)}
@media (hover:hover){.us:hover{border-color:var(--line-2)}}
/* A square shot made each suggestion 273px tall — taller than the space left
   after two basket lines, so the row only ever showed its top edge. 4:3 keeps
   the vial whole (it sits well inside the frame) and takes ~45px off the card. */
.us__m{position:relative;display:block;flex:none;width:46px;height:46px;border-radius:8px;background:#fff;overflow:hidden}
.us__m img{width:100%!important;height:100%!important;object-fit:cover!important;display:block}
.us__sale{position:absolute;top:6px;left:6px;padding:3px 8px;border-radius:999px;
  background:var(--brand);color:var(--on-brand);font-size:9.5px;font-weight:800;line-height:1}
.us__b{flex:1 1 auto;min-width:0;display:flex;flex-direction:column;padding:0}
.us__b b{display:block;font-size:12.5px;font-weight:800;letter-spacing:-.02em;color:var(--ink);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.us__p{display:block;margin-top:1px;padding-top:0;font-size:12px;font-weight:800;color:var(--ink-2)}
/* Compact row internals. The middle column has to be allowed to shrink or the
   name pushes the price and the Add button out of the card — min-width:0 is
   what lets ellipsis actually happen inside a flex child. */
.upsell .us__b b{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
  font-size:12.5px;line-height:1.25}
.upsell .us__p{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
/* The struck price doubles the width of this line and the Sale pill already
   says the same thing, so in the compact row only the payable figure shows. */
.upsell .us__p s{display:none}
.upsell .us__sale{top:3px;left:3px;padding:2px 6px;font-size:9px;border-radius:6px}
.upsell .us__add{font-size:12px;padding-inline:11px;height:28px}
.us__p s{margin-right:5px;font-size:.85em;font-weight:600;color:var(--ink-3)}
.us__add{flex:none;width:auto;margin:0;padding-inline:13px;height:30px;border-radius:999px;
  background:var(--ink);color:var(--paper);font-size:12px;font-weight:800;cursor:pointer;
  transition:background-color .2s var(--ease)}
@media (hover:hover){.us__add:hover{background:var(--brand-deep)}}

/* ══ cart: discount code ══ */
.promo{display:flex;gap:8px;margin-bottom:6px}
.promo__f{position:relative;flex:1 1 auto;display:flex;align-items:center;gap:9px;
  min-width:0;padding:0 13px;height:38px;background:var(--paper);
  border:1.5px solid var(--line);border-radius:999px;
  transition:border-color .22s var(--ease)}
.promo__f svg{flex:none;width:16px;height:16px;fill:none;stroke:var(--ink-3);stroke-width:1.8;
  stroke-linecap:round;stroke-linejoin:round}
.promo__f input{flex:1 1 auto;min-width:0;border:0;outline:0;background:none;font:inherit;
  font-size:14px;font-weight:700;letter-spacing:.02em;color:var(--ink)}
.promo__f:focus-within{border-color:var(--ink-3)}
.promo--on .promo__f{border-color:var(--brand-deep)}

.promo__note{margin:-4px 0 12px;font-size:12.5px;font-weight:600;color:var(--ink-2)}
.promo__note b{font-weight:800;color:var(--brand-text);letter-spacing:.02em}

@media (max-width:640px){
  .ship{padding:14px 16px 40px}
  .ship__track{margin:0 30px}
  .ship__stop b{font-size:10px;top:32px}
  /* the row's negative margin is tied to this pad, so both move together —
     otherwise the first card loses its inset on phones */
  .upsell{padding:12px 20px}
  .upsell__row{margin-inline:-20px;padding-inline:20px;scroll-padding-left:20px}
  /* Was two picture-cards per view. As a compact row, one-and-a-bit per view
     leaves the middle column wide enough for a full name and a price on one
     line, and the peek still signals there are more. */
  .us{flex:0 0 84%}
}
@media (prefers-reduced-motion:reduce){
  .ship__fill,.ship__dot{transition:none}
}

/* ══ cart: points earned ══ */
.pts{display:flex;align-items:center;gap:8px;margin:0 0 5px;padding:4px 10px;
  border-radius:14px;background:var(--brand-tint);
  border:1px solid color-mix(in srgb,var(--brand-deep) 20%,transparent);
  font-size:13.5px;font-weight:600;color:var(--ink-2)}
.pts b{font-weight:800;color:var(--brand-text)}
.pts__i{flex:none;display:grid;place-items:center;width:21px;height:21px;border-radius:999px;
  background:var(--paper);color:var(--brand-deep)}
.pts__i svg{width:15px;height:15px;fill:currentColor;stroke:none}
@media (max-width:640px){ .pts{padding:5px 10px;font-size:12px;gap:8px} }

/* ══ cart: suggestion arrows ══ */
.upsell__top{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-bottom:12px}
.upsell__top .upsell__h{margin:0}
.upsell__nav{display:flex;gap:6px}
.usnav{display:grid;place-items:center;width:30px;height:30px;border-radius:999px;
  background:var(--paper);border:1px solid var(--line);color:var(--ink-2);cursor:pointer;
  transition:border-color .2s var(--ease),color .2s var(--ease),opacity .2s var(--ease)}
.usnav svg{width:15px;height:15px;fill:none;stroke:currentColor;stroke-width:2.2;
  stroke-linecap:round;stroke-linejoin:round}
@media (hover:hover){.usnav:not(:disabled):hover{border-color:var(--ink-3);color:var(--ink)}}
.usnav:disabled{opacity:.34;cursor:default}
/* the arrows are the control, so the row itself no longer needs to be dragged */
.upsell__row{scroll-behavior:smooth}
@media (prefers-reduced-motion:reduce){ .upsell__row{scroll-behavior:auto} }



/* ══ buy sheet ══
   Dosage and quantity in one modal. A sheet rather than an overlay on the card:
   a phone card is 172px wide and this carries a stepper, a discount ladder, the
   water line and a total. */
.pbuy{position:fixed;inset:0;z-index:96;display:flex;align-items:flex-end;justify-content:center}
.pbuy[hidden]{display:none}
.pbuy__card{width:min(460px,100%);max-height:88vh;display:flex;flex-direction:column;
  background:var(--paper);border-radius:22px 22px 0 0;
  padding:10px 18px calc(16px + env(safe-area-inset-bottom,0px));
  box-shadow:0 -20px 50px -24px rgba(13,18,17,.5);
  transform:translateY(100%);transition:transform .34s cubic-bezier(.32,.72,0,1)}
.pbuy.open .pbuy__card{transform:none}
.pbuy__grip{display:block;width:38px;height:4px;margin:0 auto 12px;border-radius:999px;background:var(--line)}
.pbuy__top{display:flex;align-items:center;gap:12px;padding-bottom:12px;flex:none;
  border-bottom:1px solid var(--line)}
.pbuy__top img{width:44px;height:44px;border-radius:10px;object-fit:contain;background:var(--well);
  flex:none;padding:2px}
.pbuy__t{flex:1 1 auto;min-width:0;display:flex;flex-direction:column}
.pbuy__t span{font-size:11px;font-weight:800;letter-spacing:.12em;text-transform:uppercase;color:var(--ink-3)}
.pbuy__t b{margin-top:2px;font-size:16px;font-weight:800;letter-spacing:-.02em;color:var(--ink);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.pbuy__body{flex:1 1 auto;min-height:0;overflow-y:auto;padding-top:12px;
  scrollbar-width:none;-ms-overflow-style:none}
.pbuy__body::-webkit-scrollbar{display:none}

/* step one */
.pbuy__opts{display:grid;gap:8px}
.pbopt{display:flex;align-items:center;gap:12px;width:100%;min-height:56px;padding:0 14px;
  background:var(--paper);border:1.5px solid var(--line);border-radius:14px;cursor:pointer;
  transition:border-color .18s var(--ease),background-color .18s var(--ease)}
.pbopt:active{background:var(--soft)}
@media (hover:hover){.pbopt:hover{border-color:var(--ink-3)}}
.pbopt__s{flex:1 1 auto;text-align:left;font-size:15.5px;font-weight:800;letter-spacing:-.02em;color:var(--ink)}
.pbopt__p{flex:none;display:flex;align-items:baseline;gap:7px;font-size:15px;font-weight:800;
  color:var(--brand-text);font-variant-numeric:tabular-nums}
.pbopt__p s{font-size:12px;font-weight:600;color:var(--ink-3);text-decoration-thickness:1.5px}
.pbopt__c{flex:none;width:16px;height:16px;fill:none;stroke:var(--ink-3);stroke-width:2.2;
  stroke-linecap:round;stroke-linejoin:round}

/* step two */
.pbuy__back,.pbuy__one{display:flex;align-items:center;gap:9px;width:100%;min-height:44px;
  padding:0 12px;border-radius:12px;background:var(--soft);border:1px solid var(--line)}
.pbuy__back{cursor:pointer}
.pbuy__back svg{flex:none;width:15px;height:15px;fill:none;stroke:var(--ink-2);stroke-width:2.2;
  stroke-linecap:round;stroke-linejoin:round}
.pbuy__back b,.pbuy__one b{font-size:14.5px;font-weight:800;letter-spacing:-.02em;color:var(--ink)}
.pbuy__back span,.pbuy__one span{flex:1 1 auto;text-align:left;font-size:14px;font-weight:700;
  color:var(--brand-text);font-variant-numeric:tabular-nums}
.pbuy__back i{font-style:normal;font-size:12px;font-weight:800;letter-spacing:.04em;
  text-transform:uppercase;color:var(--ink-3)}
.pbuy__lbl{margin:16px 0 8px;font-size:11px;font-weight:800;letter-spacing:.13em;
  text-transform:uppercase;color:var(--ink-3)}
.pbuy__q{display:flex;align-items:center;gap:4px;width:max-content;padding:4px;
  border:1.5px solid var(--line);border-radius:999px}
.pbuy__q button{width:44px;height:44px;border-radius:999px;font-size:20px;font-weight:800;
  color:var(--ink);cursor:pointer;transition:background-color .16s var(--ease)}
.pbuy__q button:disabled{opacity:.35;cursor:default}
@media (hover:hover){.pbuy__q button:not(:disabled):hover{background:var(--soft)}}
.pbuy__q b{min-width:44px;text-align:center;font-size:17px;font-weight:800;
  font-variant-numeric:tabular-nums}

.pbuy__tiers{display:grid;gap:8px}
.pbtier{display:flex;align-items:center;gap:10px;width:100%;min-height:54px;padding:0 14px;
  background:var(--paper);border:1.5px solid var(--line);border-radius:14px;cursor:pointer;
  transition:border-color .18s var(--ease),background-color .18s var(--ease)}
.pbtier.on{border-color:var(--brand-deep);background:var(--brand-tint)}
@media (hover:hover){.pbtier:not(.on):hover{border-color:var(--ink-3)}}
.pbtier__q{flex:1 1 auto;text-align:left;font-size:14.5px;font-weight:800;letter-spacing:-.02em;color:var(--ink)}
.pbtier__b{flex:none;padding:4px 9px;border-radius:999px;background:var(--brand);color:var(--on-brand);
  font-size:10.5px;font-weight:800;letter-spacing:.02em;line-height:1}
.pbtier__b--flat{background:var(--soft);color:var(--ink-3)}
.pbtier__p{flex:none;font-size:14px;font-weight:800;color:var(--ink);font-variant-numeric:tabular-nums}
.pbtier__p i{font-style:normal;font-size:11.5px;font-weight:600;color:var(--ink-3)}

/* Now a label wrapping a checkbox, so the whole row is the hit target — well
   past the 44px minimum — and the tick state is native to the input rather than
   mirrored in a class. Ticked it carries the brand tint so it reads as an
   active inclusion; unticked it stays in place, greyed, with the price struck,
   so the state is legible without relying on colour alone. */
.pbuy__w{display:flex;align-items:center;gap:10px;margin-top:12px;padding:11px 13px;
  border-radius:14px;background:var(--brand-tint);cursor:pointer;
  border:1.5px solid color-mix(in srgb,var(--brand-deep) 26%,transparent);
  transition:background .2s var(--ease),border-color .2s var(--ease),opacity .2s var(--ease)}
.pbuy__w--off{background:var(--soft);border-color:var(--line);border-style:dashed}
.pbuy__w--off .pbuy__w__t b,.pbuy__w--off .pbuy__w__i{color:var(--ink-3)}
.pbuy__w--off .pbuy__w__p{color:var(--ink-3);text-decoration:line-through;
  text-decoration-thickness:1.5px}
.pbuy__w__cb{position:absolute;opacity:0;width:0;height:0}
.pbuy__w__box{flex:none;width:22px;height:22px;border-radius:7px;border:1.8px solid var(--line-2);
  background:#fff;display:grid;place-items:center;
  transition:background .18s var(--ease),border-color .18s var(--ease)}
.pbuy__w__box svg{width:13px;height:13px;fill:none;stroke:#fff;stroke-width:3.2;
  stroke-linecap:round;stroke-linejoin:round;opacity:0;transform:scale(.4);
  transition:opacity .18s var(--ease),transform .18s var(--ease)}
.pbuy__w__cb:checked+.pbuy__w__box{background:var(--brand-deep);border-color:var(--brand-deep)}
.pbuy__w__cb:checked+.pbuy__w__box svg{opacity:1;transform:none}
.pbuy__w__cb:focus-visible+.pbuy__w__box{outline:2px solid var(--brand-deep);outline-offset:2px}
@media (hover:hover){.pbuy__w:hover{border-color:var(--brand-deep)}}
@media (prefers-reduced-motion:reduce){
  .pbuy__w,.pbuy__w__box,.pbuy__w__box svg{transition:none}
}
/* Now a product photo, so it takes the square tile the cart lines use rather
   than the round icon chip — same shape as the item it represents elsewhere in
   the flow. White ground, since the shot's own backdrop stops at its edge. */
.pbuy__w__i{flex:none;width:38px;height:38px;border-radius:10px;overflow:hidden;
  background:#fff;display:block;border:1px solid rgba(0,0,0,.06)}
.pbuy__w__i img{width:100%!important;height:100%!important;object-fit:cover;display:block}
/* At 320px the photo and the price leave the text column too narrow and the
   line ran to four rows. The tile gives a few pixels back and the copy steps
   down a size, which brings it to two. */
@media (max-width:360px){
  .pbuy__w{gap:8px;padding:9px 10px}
  .pbuy__w__i{width:32px;height:32px}
  .pbuy__w__t i{font-size:10.5px;line-height:1.35}
  .pbuy__w__t b{font-size:12.5px}
  .pbuy__w__p{font-size:13px}
}
.pbuy__w__t{flex:1 1 auto;min-width:0;display:flex;flex-direction:column}
.pbuy__w__t b{font-size:13.5px;font-weight:800;letter-spacing:-.02em;color:var(--ink)}
.pbuy__w__t i{font-style:normal;margin-top:1px;font-size:11.5px;color:var(--ink-3)}
.pbuy__w__p{flex:none;font-size:14px;font-weight:800;font-variant-numeric:tabular-nums}

.pbuy__sum{margin-top:14px;padding-top:12px;border-top:1px solid var(--line)}
.pbuy__sr{display:flex;align-items:baseline;justify-content:space-between;gap:12px;
  font-size:14px;font-weight:700;color:var(--ink-2);font-variant-numeric:tabular-nums}
.pbuy__sr + .pbuy__sr{margin-top:5px}
.pbuy__sr s{color:var(--ink-3);font-weight:600;text-decoration-thickness:1.5px;margin-right:5px}
.pbuy__sr--m{font-size:13px;color:var(--ink-3)}
.pbuy__sr--t{margin-top:8px;font-size:15px;color:var(--ink)}
.pbuy__sr--t b{font-size:20px;font-weight:800;letter-spacing:-.02em}
.pbuy__save{margin:7px 0 0;font-size:13px;font-weight:800;color:var(--brand-text)}
.pbuy__cta{width:100%;margin-top:14px;height:52px}
@media (prefers-reduced-motion:reduce){ .pbuy__card{transition:none} }

/* ── payment marks inside the cart drawer ──
   The footer row is the reference, but that one sits on black inside a wide
   page; this one sits on a light panel in a 380px drawer directly under the
   Checkout button, where vertical space is the scarce resource. So the boxes
   are dropped and the marks run as a plain centred row: the trust signal is
   the logos themselves, not the chrome around them. Heights are the footer's
   optical scale, since the same aspect-ratio problem applies at any size. */
.pay--cart{margin:8px 0 0;padding:8px 0 0;border-top:1px solid var(--line);
  display:flex;flex-wrap:nowrap;align-items:center;justify-content:center;gap:16px;
  grid-template-columns:none}
.pay--cart .pay__i{height:auto;padding:0;border:0;background:none;gap:5px;
  color:var(--ink-2);flex:0 0 auto}
/* light panel: the van and wordmark take the page ink, not the footer's white */
.pay--cart svg.pay__van{stroke:var(--ink-2);width:14px;height:14px}
.pay--cart .pay__wm{color:var(--ink-2);font-size:10.5px}
/* Tamara ships white artwork, which would be invisible here — knock it black.
   Visa and Apple Pay ship dark, so they are left exactly as supplied. */
.pay__l--dark{filter:brightness(0)}
.pay--cart .pay__l--visa  {height:11px!important;max-height:11px!important}
.pay--cart .pay__l--apple {height:12px!important;max-height:12px!important}
.pay--cart .pay__l--mc    {height:15px!important;max-height:15px!important}
.pay--cart .pay__l--tamara{height:9px!important;max-height:9px!important}
@media (max-width:380px){ .pay--cart{gap:12px} }

/* ═══ account: signed-out ═══════════════════════════════════════════
   The reference this was modelled on runs cream and terracotta; SHLabz runs
   black, white and #19ed56, so the structure is borrowed and the palette is
   ours. The dark panel carries the argument for having an account, the white
   card carries the single field that makes one. */
.auth{display:grid;grid-template-columns:1.15fr .85fr;gap:22px;align-items:stretch;
  margin-top:6px}
.auth__pitch{position:relative;overflow:hidden;border-radius:22px;padding:38px 36px;
  background:radial-gradient(120% 130% at 88% 4%,#123c22 0%,#0b1a12 42%,var(--ink) 100%);
  color:#fff;display:flex;flex-direction:column}
/* a soft brand bloom, so the panel is not a flat black rectangle */
.auth__pitch::after{content:"";position:absolute;top:-30%;right:-18%;width:60%;aspect-ratio:1;
  border-radius:50%;background:radial-gradient(circle,rgba(25,237,86,.20),transparent 68%);
  pointer-events:none}
.auth__kick{display:flex;align-items:center;gap:10px;font-size:11px;font-weight:800;
  letter-spacing:.16em;text-transform:uppercase;color:var(--brand)}
.auth__kick i{width:26px;height:2px;border-radius:2px;background:var(--brand);flex:none}
.auth__pitch h2{margin:16px 0 0;font-size:clamp(28px,3.2vw,38px);font-weight:800;
  letter-spacing:-.035em;line-height:1.06}
.auth__pitch > p{margin:12px 0 0;max-width:38ch;color:rgba(255,255,255,.74);font-size:14.5px;
  line-height:1.6}
.auth__pts{list-style:none;margin:auto 0 0;padding:26px 0 0;display:grid;gap:14px}
.auth__pts li{display:flex;align-items:flex-start;gap:12px;font-size:13.5px;font-weight:600;
  color:rgba(255,255,255,.9);line-height:1.45}
.auth__pts svg{flex:none;width:19px;height:19px;margin-top:1px;fill:none;stroke:var(--brand);
  stroke-width:1.7;stroke-linecap:round;stroke-linejoin:round}

.auth__card{background:var(--paper);border:1px solid var(--line);border-radius:22px;
  padding:26px 26px 24px;display:flex;flex-direction:column;box-shadow:var(--shadow)}
.auth__tabs{display:flex;gap:4px;padding:4px;border-radius:999px;background:var(--soft);
  border:1px solid var(--line)}
.auth__tabs button{flex:1;min-height:40px;border-radius:999px;font-size:13.5px;font-weight:800;
  color:var(--ink-2);transition:background .22s var(--ease),color .22s var(--ease)}
.auth__tabs button.on{background:var(--ink);color:#fff}
.auth__tabs button:not(.on):hover{color:var(--ink)}
.auth__h{margin:26px 0 0;font-size:21px;font-weight:800;letter-spacing:-.03em}
.auth__lead{margin:9px 0 0;font-size:13.5px;line-height:1.6;color:var(--ink-2)}
/* the offer is stated where the decision is made, not only in the popup */
.auth__perk{margin:16px 0 0;padding:11px 13px;border-radius:13px;background:var(--brand-tint);
  border:1.5px solid color-mix(in srgb,var(--brand-deep) 24%,transparent);display:grid;gap:2px}
.auth__perk b{font-size:13.5px;font-weight:800;color:var(--brand-text);letter-spacing:-.02em}
.auth__perk span{font-size:12px;color:var(--ink-2);font-weight:600}
.auth__form{margin-top:18px;display:grid;gap:9px}
.auth__lab{font-size:12.5px;font-weight:700;color:var(--ink-2)}
.auth__lab em{font-style:normal;color:#c0392b}
.auth__go{width:100%;height:48px;margin-top:3px}
.auth__err{margin:0;font-size:12.5px;font-weight:700;color:#c0392b}
.auth__err[hidden]{display:none}
.auth__fine{margin:14px 0 0;font-size:11.5px;line-height:1.55;color:var(--ink-3)}
.auth__fine a{color:var(--brand-text);font-weight:700}
.auth__done{text-align:center;padding:14px 0 6px}
.auth__done__i{display:grid;place-items:center;width:52px;height:52px;margin:8px auto 0;
  border-radius:999px;background:var(--brand-tint);color:var(--brand-deep)}
.auth__done__i svg{width:25px;height:25px;fill:none;stroke:currentColor;stroke-width:2.6;
  stroke-linecap:round;stroke-linejoin:round}
.auth__done .auth__lead{max-width:34ch;margin-inline:auto}
@media (max-width:900px){
  .auth{grid-template-columns:1fr;gap:16px}
  .auth__pitch{padding:30px 24px;order:2}
  .auth__card{order:1}
  .auth__pts{padding-top:22px}
}
@media (max-width:560px){
  .auth__card{padding:20px 18px 18px;border-radius:18px}
  .auth__pitch{border-radius:18px}
}

/* ═══ first-order offer ═════════════════════════════════════════════
   The previous site put the vial flat-lay behind the whole card and washed it
   out; that idea is kept, but the wash is a CSS layer rather than baked into
   the file, so the text contrast can be tuned and verified rather than hoped
   for. Every foreground colour here clears 4.5:1 against the washed plate. */
.offer{position:fixed;inset:0;z-index:90;display:grid;place-items:center;padding:20px;
  background:rgba(8,14,11,.62);backdrop-filter:blur(5px);opacity:0;
  transition:opacity .26s var(--ease)}
.offer.open{opacity:1}
.offer[hidden]{display:none}
/* The card itself no longer scrolls — its body does. When the card was the
   scroller, the photo and its wash sized to the card's VISIBLE height while the
   content ran past it, so scrolling to the end exposed a band of raw, unwashed
   photograph below the fine print. Making the body the scroller keeps the
   backdrop pinned to exactly what is on screen, at any viewport height. */
.offer__card{position:relative;isolation:isolate;width:min(440px,100%);
  max-height:calc(100dvh - 40px);overflow:hidden;border-radius:24px;
  display:flex;flex-direction:column;
  background:var(--paper);border:1px solid var(--line);
  box-shadow:0 30px 80px rgba(6,12,9,.36);
  transform:translateY(14px) scale(.985);transition:transform .3s var(--ease)}
.offer.open .offer__card{transform:none}
/* the photograph, full bleed and behind everything */
.offer__bg{position:absolute;inset:0;z-index:-2;width:100%;height:100%;object-fit:cover;
  display:block}
/* the wash: near-opaque at the bottom where the form sits, lighter at the top
   so the vials still read as a photograph rather than a texture */
.offer__wash{position:absolute;inset:0;z-index:-1;pointer-events:none;
  background:
    linear-gradient(180deg,rgba(255,255,255,.62) 0%,rgba(255,255,255,.88) 38%,
                    rgba(255,255,255,.97) 62%,var(--paper) 100%),
    radial-gradient(120% 80% at 50% 0%,rgba(25,237,86,.16),transparent 62%)}

.offer__x{position:absolute;top:12px;right:12px;z-index:2;width:36px;height:36px;
  display:grid;place-items:center;border-radius:999px;background:rgba(255,255,255,.82);
  border:1px solid rgba(0,0,0,.06);color:var(--ink-2);backdrop-filter:blur(4px);
  transition:background .2s var(--ease),color .2s var(--ease)}
.offer__x svg{width:16px;height:16px;fill:none;stroke:currentColor;stroke-width:2.2;
  stroke-linecap:round}
@media (hover:hover){.offer__x:hover{background:#fff;color:var(--ink)}}

/* min-height:0 is load-bearing: a flex child defaults to min-height:auto and
   would refuse to shrink below its content, so the card would grow past the
   viewport instead of the body scrolling. */
.offer__b{position:relative;flex:1 1 auto;min-height:0;overflow-y:auto;
  padding:52px 26px 18px;text-align:center;overscroll-behavior:contain}
.offer__kick{display:block;font-size:10.5px;font-weight:800;letter-spacing:.17em;
  text-transform:uppercase;color:var(--brand-text)}
/* balance stops the last word dropping to a line of its own — "order" was
   sitting alone under a full-width first line */
.offer__h{margin:10px auto 0;max-width:19ch;font-size:clamp(24px,6.1vw,29px);font-weight:800;
  letter-spacing:-.04em;line-height:1.12;color:var(--ink);text-wrap:balance}
/* the number is the hook, so it carries the brand weight the rest of the line does not */
.offer__h span{color:var(--brand-text)}
.offer__p{margin:11px auto 0;max-width:36ch;font-size:13px;line-height:1.6;color:var(--ink-2)}

.offer__form{margin-top:16px;display:grid;gap:8px}
/* A visible label, because the placeholder was carrying that job alone — it
   disappears the moment someone types, leaving the field unlabelled. Centred to
   sit in the card's composition rather than fighting it. */
.offer__lab{font-size:11.5px;font-weight:800;letter-spacing:.06em;word-spacing:.22em;text-transform:uppercase;
  color:var(--ink-3);text-align:center}
.offer__form .field{height:50px;background:#fff;border-radius:14px;font-size:14.5px}
.offer__form .btn{width:100%;height:50px;gap:8px;font-size:15px}
.offer__form .btn svg{width:18px;height:18px;fill:none;stroke:currentColor;stroke-width:2.1;
  stroke-linecap:round;stroke-linejoin:round;transition:transform .22s var(--ease)}
@media (hover:hover){.offer__form .btn:hover svg{transform:translateX(3px)}}
@media (prefers-reduced-motion:reduce){.offer__form .btn svg{transition:none}}
/* directly under the field it describes, not after the button */
.offer__err{margin:0;font-size:12px;font-weight:700;color:#c0392b;text-align:left}
.offer__err[hidden]{display:none}

/* Claims we can actually stand behind — purity and the published COA are on the
   site already, and "no spam" is a promise, not a statistic. Deliberately no
   customer count: an unverifiable number does not belong in a trust row. */
.offer__trust{list-style:none;margin:14px 0 0;padding:11px 0 0;display:flex;flex-wrap:wrap;
  justify-content:center;gap:5px 13px;border-top:1px solid rgba(0,0,0,.07)}
.offer__trust li{display:inline-flex;align-items:center;gap:5px;font-size:11.5px;
  font-weight:700;color:var(--ink-2);white-space:nowrap}
.offer__trust svg{width:13px;height:13px;flex:none;fill:none;stroke:var(--brand-deep);
  stroke-width:2.2;stroke-linecap:round;stroke-linejoin:round}

/* The tail used to be three stacked blocks — legal line, then terms, then a
   36px decline button — which ate more of the card than the form did. They are
   one centred line now, separated by middots. */
.offer__fine{margin:10px 0 0;font-size:11px;line-height:1.5;color:var(--ink-3)}
.offer__fine a{color:var(--brand-text);font-weight:700}
/* declining is a plain, findable control — not a shamed one */
/* On its own line now, with real clearance above it — the guidance calls for at
   least 8px between adjacent targets, and sharing a line with the legal text
   also made the one way to decline read as fine print. Block-level, so the 44px
   hit area comes from its own padding rather than an overlay. */
.offer__no{display:block;margin:10px auto 0;padding:9px 16px;min-height:36px;
  font-size:12.5px;font-weight:700;color:var(--ink-3);border-radius:999px;
  text-decoration:underline;text-underline-offset:3px;
  transition:color .2s var(--ease),background .2s var(--ease)}
.offer__no::after{content:"";position:absolute}
@media (hover:hover){.offer__no:hover{color:var(--ink);background:var(--soft)}}

/* the code reveal, once an address is in */
.offer__code{display:inline-flex;align-items:center;gap:10px;margin:14px 0 0;padding:12px 18px;
  border-radius:14px;background:var(--ink);color:#fff;font-size:20px;font-weight:800;
  letter-spacing:.14em;font-variant-numeric:tabular-nums}
.offer__code svg{width:18px;height:18px;flex:none;fill:none;stroke:var(--brand);
  stroke-width:2.6;stroke-linecap:round;stroke-linejoin:round}

@media (max-width:420px){
  .offer{padding:14px}
  .offer__b{padding:44px 18px 18px}
  .offer__trust{gap:5px 10px}
}
@media (prefers-reduced-motion:reduce){
  .offer,.offer__card{transition:none}
  .offer__card{transform:none}
}

/* visible to screen readers only — used where a field's label would otherwise
   duplicate the heading directly above it */
.sr-only{position:absolute!important;width:1px;height:1px;padding:0;margin:-1px;
  overflow:hidden;clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap;border:0}

/* ═══ category tile: peptide-name marquee ════════════════════════════
   A preview of what is inside each category, borrowed in structure from the
   reference and rebuilt in the SHLabz palette. The track holds the name set
   twice and slides exactly -50%, so the loop is seamless without measuring
   anything — no font-load race like the hero belt had.
   Two accessibility rules drive the rest: auto-rotating content needs a stop
   (it pauses on hover and on keyboard focus), and reduced motion must halt it
   entirely rather than merely slowing it. */
/* Every selector below is scoped to .cattile on purpose. The tile already has
   `.cattile span{display:block}` at 0,1,1 specificity, which outranks a bare
   class and turned the two marquee halves into stacked rows. */
.cattile .cmq{display:block;margin-top:14px;padding-top:12px;border-top:1px solid var(--line);
  overflow:hidden;position:relative;min-width:0;
  /* The track is width:max-content. A grid item defaults to min-width:auto, so
     that intrinsic width propagated up and stretched the whole catgrid past the
     viewport on phones — clipped visually, but the page still scrolled. Pinning
     the row to its own line box stops the intrinsic size escaping. */
  width:100%;
  -webkit-mask-image:linear-gradient(90deg,transparent,#000 8%,#000 88%,transparent);
          mask-image:linear-gradient(90deg,transparent,#000 8%,#000 88%,transparent)}
.cattile .cmq__track{display:flex;width:max-content;margin:0;will-change:transform;
  animation-name:cmqslide;animation-timing-function:linear;animation-iteration-count:infinite}
.cattile .cmq__set{display:flex;align-items:center;gap:9px;padding-right:9px;flex:none;margin:0}
.cattile .cmq__set i{font-style:normal;font-size:12.5px;font-weight:700;color:var(--ink-3);white-space:nowrap}
.cattile .cmq__set u{text-decoration:none;color:var(--brand-deep);font-size:12.5px;line-height:1;opacity:.55}
@keyframes cmqslide{ from{transform:translateX(0)} to{transform:translateX(-50%)} }
/* the stop control the guidance asks for: hovering or tabbing to the tile halts it */
.cattile:hover .cmq__track,
.cattile:focus-visible .cmq__track{animation-play-state:paused}
@media (prefers-reduced-motion:reduce){
  .cattile .cmq__track{animation:none}
}

/* A value and its unit are one token to the reader: "100 mg" was breaking after
   the number and dropping "mg" onto its own line. Size and Tested are always
   short, so nowrap is safe there. Net content is NOT — a multi-component
   result like the GHK-Cu breakdown cannot fit one line on a phone, and because
   the wrapper switches to overflow:visible at that width the unwrappable cell
   pushed the whole page sideways. It wraps freely now; the number and its unit
   are held together by a non-breaking space in the data instead. */
.tbl--lab td[data-l="Size"],
.tbl--lab td[data-l="Tested"]{white-space:nowrap}

/* ═══ category tiles as a compact row on phone ═══════════════════════
   Seven tiles in a two-column grid ran 489px down a phone screen before the
   first product — most of a viewport spent on navigation. On phone they become
   a single row of pills, the same shape as the catalogue filter chips directly
   above the grid, so the two read as one system.
   The guidance here is explicit that a chip collection must not be forced into
   a CLIPPED row with values hidden, so this one genuinely scrolls, keeps every
   label intact with no truncation, and is reachable by keyboard; the trailing
   pad leaves a sliver of the next pill visible so there is a cue that more
   exists. */
@media (max-width:640px){
  .catgrid{display:flex;grid-template-columns:none;gap:8px;overflow-x:auto;
    -webkit-overflow-scrolling:touch;scrollbar-width:none;
    margin-inline:-16px;padding-inline:16px;scroll-padding-left:16px}
  .catgrid::-webkit-scrollbar{display:none}
  .catgrid::after{content:"";flex:0 0 4px}
  .cattile{flex:0 0 auto;min-width:0;padding:0 15px;height:40px;border-radius:999px;
    display:inline-flex;align-items:center;gap:7px;overflow:visible;
    border:1.5px solid var(--line);background:#fff}
  .cattile:hover{transform:none;box-shadow:none;border-color:var(--line-2)}
  .cattile b{display:inline;font-size:13.5px;font-weight:700;letter-spacing:-.01em;
    white-space:nowrap;color:var(--ink-2)}
  /* the count keeps its number and drops the word, exactly like the chips do */
  .cattile .cattile__n{display:inline;margin:0;font-size:12px;color:var(--ink-3)}
  .cattile .cattile__n em{display:none}
  .cattile .cattile__n i{font-style:normal;opacity:.6}
  /* the name marquee is a desktop affordance; a pill has no room for it */
  .cattile .cmq{display:none}
}

/* ═══ shipping protection ════════════════════════════════════════════
   Opt-in, so it is styled as a quiet row rather than a promoted one: no green
   tint until it is actually chosen. Same checkbox mechanics as the BAC water
   add-on so the two read as one pattern. */
.prot{display:flex;align-items:center;gap:9px;margin:0 0 7px;padding:7px 10px;
  border-radius:13px;background:var(--soft);border:1.5px solid var(--line);
  cursor:pointer;transition:background .2s var(--ease),border-color .2s var(--ease)}
.prot[hidden]{display:none}
.prot--on{background:var(--brand-tint);
  border-color:color-mix(in srgb,var(--brand-deep) 26%,transparent)}
.prot__cb{position:absolute;opacity:0;width:0;height:0}
.prot__box{flex:none;width:20px;height:20px;border-radius:6px;border:1.8px solid var(--line-2);
  background:#fff;display:grid;place-items:center;
  transition:background .18s var(--ease),border-color .18s var(--ease)}
.prot__box svg{width:12px;height:12px;fill:none;stroke:#fff;stroke-width:3.2;
  stroke-linecap:round;stroke-linejoin:round;opacity:0;transform:scale(.4);
  transition:opacity .18s var(--ease),transform .18s var(--ease)}
.prot__cb:checked+.prot__box{background:var(--brand-deep);border-color:var(--brand-deep)}
.prot__cb:checked+.prot__box svg{opacity:1;transform:none}
.prot__cb:focus-visible+.prot__box{outline:2px solid var(--brand-deep);outline-offset:2px}
.prot__i{flex:none;display:grid;place-items:center;width:26px;height:26px;color:var(--ink-3)}
.prot__i svg{width:19px;height:19px;fill:none;stroke:currentColor;stroke-width:1.6;
  stroke-linecap:round;stroke-linejoin:round}
.prot--on .prot__i{color:var(--brand-deep)}
.prot__t{flex:1 1 auto;min-width:0;display:flex;flex-direction:column}
.prot__t b{font-size:13px;font-weight:800;letter-spacing:-.02em;color:var(--ink)}
.prot__t i{font-style:normal;margin-top:1px;font-size:11px;color:var(--ink-3)}
.prot__p{flex:none;font-size:13.5px;font-weight:800;font-variant-numeric:tabular-nums;
  color:var(--ink-2)}
.prot--on .prot__p{color:var(--brand-text)}
@media (max-width:360px){
  .prot{gap:7px;padding:6px 9px}
  .prot__t b{font-size:12.5px}
  .prot__t i{font-size:10.5px}
}
@media (prefers-reduced-motion:reduce){ .prot,.prot__box,.prot__box svg{transition:none} }

/* The help section is centred so its heading sits in the middle, and the
   blanket .center p{margin-inline:auto} was catching the FAQ answers with it:
   a 70ch paragraph inside a wider panel got auto-centred, so every answer began
   60px right of the question it belongs to. Inside an accordion the answer
   starts where its question starts. */
#contact .faq p{margin-inline:0;text-align:left}
#contact .faq summary{text-align:left}

/* ═══ customs note in the cart ═══════════════════════════════════════
   Fine print, so it reads as a condition rather than an offer: no tint, no
   border, sitting with the other caveats at the foot. The lead-in is bold so
   the subject is scannable without the whole block shouting. */
.cust{margin:9px 0 0;padding-top:9px;border-top:1px solid var(--line);
  font-size:10.5px;line-height:1.5;color:var(--ink-3);text-align:left}
.cust b{font-weight:800;color:var(--ink-2)}
.cust a{color:var(--brand-text);font-weight:700;text-decoration:underline;
  text-underline-offset:2px}
@media (max-width:360px){ .cust{font-size:10px} }

/* ═══ support hours ══════════════════════════════════════════════════
   Sits between the contact methods and the form: it qualifies when a reply
   comes, so it belongs after the ways to reach us and before the thing that
   sets an expectation. Quiet — a fact, not an offer. */
.hours{display:flex;align-items:center;gap:9px;margin:18px 0 0;padding:11px 13px;
  border-radius:13px;background:var(--soft);border:1px solid var(--line);
  font-size:13px;line-height:1.45;color:var(--ink-2);text-align:left;max-width:520px}
.hours svg{flex:none;width:17px;height:17px;fill:none;stroke:var(--brand-deep);
  stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round}
.hours b{font-weight:800;color:var(--ink)}
/* the help section is centred for its heading; this block is not a heading */
#contact .hours{margin-inline:auto}
@media (max-width:480px){ .hours{font-size:12.5px;padding:10px 12px} }

/* ═══ "no BAC water" reminder ════════════════════════════════════════
   Amber rather than green or red: this is neither a confirmation nor an error,
   it is a thing worth noticing before paying. Shown only when the basket holds
   vials and no water, and it carries the button that resolves it so noticing
   and fixing are one step. */
.nowat{display:flex;align-items:center;gap:10px;margin:0 0 7px;padding:8px 10px;
  border-radius:13px;background:#fff8ec;border:1.5px solid #f0d9a8}
.nowat[hidden]{display:none}
.nowat__i{flex:none;display:grid;place-items:center;width:26px;height:26px;color:#a9750a}
.nowat__i svg{width:19px;height:19px;fill:none;stroke:currentColor;stroke-width:1.7;
  stroke-linecap:round;stroke-linejoin:round}
.nowat__t{flex:1 1 auto;min-width:0;display:flex;flex-direction:column}
.nowat__t b{font-size:12.5px;font-weight:800;letter-spacing:-.02em;color:#6b4a05}
.nowat__t i{font-style:normal;margin-top:1px;font-size:11px;line-height:1.4;color:#8a6410}
.nowat .nowat__b{flex:none;width:auto;height:32px;padding-inline:14px;font-size:12.5px;
  background:#6b4a05;border-color:#6b4a05;color:#fff}
@media (hover:hover){ .nowat .nowat__b:hover{background:#523904;border-color:#523904} }
@media (max-width:360px){
  .nowat{gap:8px;padding:7px 9px}
  .nowat__t b{font-size:12px}
  .nowat__t i{font-size:10.5px}
  .nowat .nowat__b{height:30px;padding-inline:11px;font-size:12px}
}

/* ═══ blog ═══════════════════════════════════════════════════════════ */
.post__d{display:block;margin-top:6px;font-style:normal;font-size:12px;font-weight:700;
  letter-spacing:.04em;text-transform:uppercase;color:var(--ink-3)}
/* An imported article arrives as WordPress HTML, so the prose styles have to
   cover tags the storefront never writes itself. */
.postbody{max-width:74ch}
.postbody h2{margin:34px 0 10px;font-size:clamp(20px,2.2vw,25px);font-weight:800;
  letter-spacing:-.03em;line-height:1.25}
.postbody h3{margin:26px 0 8px;font-size:17px;font-weight:800;letter-spacing:-.02em}
.postbody p{margin:0 0 15px;font-size:16px;line-height:1.75;color:var(--ink-2)}
.postbody .lede em{font-style:normal;font-size:17.5px;color:var(--ink);font-weight:600}
.postbody ul,.postbody ol{margin:0 0 16px;padding-left:20px}
.postbody li{margin-bottom:8px;font-size:16px;line-height:1.7;color:var(--ink-2)}
.postbody strong{color:var(--ink);font-weight:800}
.postbody a{color:var(--brand-text);font-weight:700}
.postbody hr{border:0;border-top:1px solid var(--line);margin:30px 0 18px}
.postbody small{font-size:12.5px;line-height:1.6;color:var(--ink-3)}
.postbody img{max-width:100%;height:auto;border-radius:12px}
.postbody__wait{color:var(--ink-3)}

/* ── end-of-article invitation ───────────────────────────────────────
   An article is read by someone already interested in the subject; the end of
   it is the one moment they have both the context and the intent to act. The
   band is dark so it reads as a deliberate close rather than another
   paragraph, and it carries exactly one action — a second button would only
   split the decision.

   Same component on every article, different words on each: the design stays
   recognisable while the invitation stays specific to what was just read. */
/* Fixed sizes, not fluid ones. The band is the same object on a phone as on a
   desktop — same padding, same type, same button — so it is recognisable as
   one component wherever it is met. Only the line wrapping differs, because
   only the column width does. */
.postbody .bcta{margin:40px 0 8px;padding:36px 26px;
  border-radius:20px;background:var(--ink);color:#fff;text-align:center;
  position:relative;overflow:hidden}
/* A restrained wash rather than a spotlight. The earlier version put a bright
   green bloom behind the text, which read as a promotion; at this weight it
   only stops the panel from being a flat rectangle. */
.postbody .bcta::before{content:'';position:absolute;inset:0;
  background:radial-gradient(120% 90% at 50% -20%,rgba(25,237,86,.10),transparent 62%);
  pointer-events:none}
.postbody .bcta > *{position:relative}
.postbody .bcta__h{margin:0;font-size:26px;font-weight:800;
  letter-spacing:-.03em;line-height:1.2;color:#fff;text-wrap:balance}
.postbody .bcta__s{margin:11px auto 0;max-width:44ch;font-size:14.5px;line-height:1.65;
  color:rgba(255,255,255,.66)}
/* Small, set in caps, weighted — the proportions of a considered action rather
   than a shouted one. The glow is gone; a plain shadow is enough to lift it. */
.postbody .bcta__a{margin:22px 0 0}
.postbody .bcta__a a{display:inline-flex;align-items:center;gap:10px;min-height:46px;
  padding:0 26px;border-radius:999px;background:var(--brand);color:var(--on-brand);
  font-size:12.5px;font-weight:800;letter-spacing:.06em;text-transform:uppercase;
  text-decoration:none;box-shadow:0 10px 24px -14px rgba(0,0,0,.9);
  transition:background-color .2s var(--ease),transform .2s var(--ease)}
.postbody .bcta__a a:hover{background:#14d64c;transform:translateY(-1px)}
.postbody .bcta__a a::after{content:'\2192';font-weight:800;letter-spacing:0}
@media (prefers-reduced-motion:reduce){
  .postbody .bcta__a a{transition:none}
  .postbody .bcta__a a:hover{transform:none}
}

@media (max-width:640px){
  .postbody p,.postbody li{font-size:15.5px}
  .postbody h2{margin-top:28px}
}


/* ══ cart drawer ════════════════════════════════════════════════════════
   Priority order: the products, then the total and Checkout, then everything
   else. Two things were taking room from the products and giving nothing back
   — a customs paragraph (now on the checkout page, beside the total, which is
   where a condition of the order belongs) and a strip of payment logos that
   already appear in the site footer. Both are gone from the drawer.
   The rest of the foot was three bordered cards stacked on each other; it is
   now one quiet block, so the eye lands on the products and the button.
   Scoped to .cart throughout — no other page is touched. */

/* ── header ─────────────────────────────────────────────────────────── */
/* the 42px close button set this height, not the padding */
.cart .cart__top{padding:13px 20px}
.cart .cart__top b{font-size:17px}
/* the count answers "how many" in the header rather than in a row of its own */
.cart .cart__n{margin-left:6px;font-size:14px;font-weight:700;color:var(--ink-3)}
.cart .cart__top .icn{width:30px;height:30px;position:relative}
.cart .cart__top .icn::after{content:'';position:absolute;inset:-7px}
.cart .cart__top .icn svg{width:17px;height:17px}

/* ── shipping progress ──────────────────────────────────────────────── */
/* Clearances, not guesses. The dot is centred on the 4px track so it rises
   ~11px above it; a smaller margin under the message puts the text on the dot.
   The stop labels are absolutely positioned, so the bottom padding is the only
   thing reserving room for them. All three gaps clear by ~8px. */
.cart .ship{padding:9px 20px 42px}
.cart .ship p{margin:0 0 18px;font-size:12.5px;line-height:1.3}
.cart .ship__dot{width:22px;height:22px}
.cart .ship__dot svg{width:12px;height:12px}
.cart .ship__stop b{top:31px;font-size:10px}

/* ── products: the primary content ──────────────────────────────────── */
.cart .cart__items{padding:4px 22px 8px}
.cart .ci{padding:11px 0;gap:13px;align-items:flex-start}
.cart .ci:last-child{border-bottom:0}
.cart .ci__ph{width:68px;height:68px;border-radius:12px}
.cart .ci b{font-size:14.5px;line-height:1.3}
.cart .ci span{font-size:12.5px;line-height:1.3}
.cart .ci__foot{margin-top:7px}
/* savings stay, but as supporting detail rather than a second headline */
.cart .ci__save{margin-top:2px;font-size:10.5px;line-height:1.35;font-weight:700;
  color:var(--ink-3)}
.cart .ci .ci__p b{font-size:15px}
/* one row always survives, however short the screen */
.cart .cart__scroll{min-height:96px}

/* ── suggestions: present, not dominant ─────────────────────────────── */
.cart .upsell{padding:9px 16px 11px}
/* The row hangs on a negative margin that MUST equal the container's padding.
   An earlier media rule sets it to -20px; mismatched, the drawer scrolls
   sideways. Pinned together here so the pair cannot drift again. */
.cart .upsell__row{margin-inline:-16px;padding-inline:16px;scroll-padding-left:16px}
.cart .upsell__top{margin-bottom:7px}
.cart .us{padding:7px 9px 7px 7px;gap:9px}
.cart .us__m{width:44px;height:44px}
.cart .upsell .us__add{height:27px;font-size:11.5px;padding-inline:11px}

/* ── foot: one area, not four cards ─────────────────────────────────── */
.cart .cart__foot{padding:9px 20px 12px}
.cart .promo{margin-bottom:8px}
.cart .cart__lines{margin-bottom:2px}
.cart .cart__lines .crow{padding:3px 0;font-size:13px;line-height:1.3}
.cart .cart__sum{margin-bottom:4px;padding-top:7px;border-top:1px solid var(--line)}
/* rewards read as a line of copy, not a banner */
.cart .pts{margin:0 0 9px;padding:2px 0;border:0;background:none;font-size:12.5px}
.cart .pts__i{width:19px;height:19px;background:var(--brand-tint)}
.cart .pts__i svg{width:13px;height:13px}

/* ── short viewports ────────────────────────────────────────────────── */
@media (max-height:820px){
  .cart .cart__top{padding:11px 20px}
  .cart .ship{padding:8px 20px 40px}
  .cart .ship p{margin-bottom:17px;font-size:12px}
  .cart .ci{padding:9px 0}
  .cart .ci__ph{width:62px;height:62px}
  .cart .upsell{padding:8px 16px 9px}
  .cart .cart__foot{padding:7px 20px 10px}
}
@media (max-height:700px){
  .cart .cart__scroll{min-height:76px}
  .cart .ship{padding:8px 20px 38px}
  .cart .ship p{margin-bottom:16px;font-size:11.5px}
  .cart .ship__dot{width:20px;height:20px}
  .cart .ship__dot svg{width:11px;height:11px}
  .cart .ship__stop b{top:28px;font-size:9.5px}
  .cart .ci{padding:8px 0}
  .cart .ci__ph{width:58px;height:58px}
  /* a 360x640 phone ran 7px over; taken from the foot's own breathing room
     rather than from the basket or from anything the customer needs to read */
  .cart .upsell{padding:7px 16px 8px}
  .cart .cart__foot{padding:6px 20px 9px}
  .cart .pts{margin-bottom:6px}
}

/* The very smallest phones still ran 4px over. The basket's floor gives it
   up rather than the foot: at this size the scroller is showing part of a row
   either way, and it can still be scrolled. */
@media (max-height:660px){
  .cart .cart__scroll{min-height:70px}
}

/* ── phones: spacing designed here, not shrunk from desktop ─────────── */
@media (max-width:640px){
  .cart .cart__top{padding:13px 16px}
  .cart .ship{padding:9px 16px 42px}
  .cart .cart__items{padding:4px 16px 8px}
  .cart .ci{padding:12px 0;gap:12px}
  .cart .ci__ph{width:66px;height:66px}
  .cart .ci b{font-size:14.5px}
  .cart .ci span{font-size:12.5px}
  /* horizontal padding stays 16px — see the upsell__row note above */
  .cart .upsell{padding:8px 16px 10px}
  .cart .cart__foot{padding:9px 16px 12px}
}


/* ══ out of stock ═══════════════════════════════════════════════════════
   A dosage can be unavailable while its siblings are not, so the state lives
   on the dosage button and the buy panel swaps to a notify form beneath it.
   The button stays selectable on purpose: a shopper who wants that dosage
   needs to be able to choose it and ask to be told. */
/* [hidden] is only a display:none default — .pdp__buy sets display:block, which
   beats it, so the Add button stayed on screen next to the notify form. */
.pdp__buy[hidden]{display:none}
/* The button is a flex row, so the note has to claim its own line rather than
   sitting against the dosage. Fixed height gives way to auto for these. */
.size--out{position:relative;height:auto;min-height:28px;flex-wrap:wrap;justify-content:center;
  padding-block:4px;line-height:1.15;color:var(--ink-3);border-style:dashed}
.size--out.on{background:var(--well);border-color:var(--line-2);color:var(--ink-2)}
.size__out{display:block;flex:0 0 100%;margin-top:2px;text-align:center;font-style:normal;font-size:9.5px;font-weight:800;
  letter-spacing:.06em;text-transform:uppercase;color:var(--ink-3);line-height:1.1}
/* the quantity, water and total rows have nothing to act on for a dosage that
   cannot be bought */
.buy--out .buy__sec + .buy__sec,
.buy--out .wrow,
.buy--out .buy__total{display:none}
/* The one thing that stays: what the dosage costs. Hidden until the panel is
   in its sold-out state, where it takes the place the total would have had. */
.buy__oos{display:none}
.buy--out .buy__oos{display:flex;align-items:baseline;justify-content:space-between;gap:12px;
  margin-top:14px;padding-top:14px;border-top:1px solid var(--line)}
.buy__oos span{font-size:11px;font-weight:800;letter-spacing:.1em;text-transform:uppercase;
  color:var(--ink-3)}
.buy__oos b{font-size:22px;font-weight:800;letter-spacing:-.02em;color:var(--ink)}

.notify{margin-top:12px;padding:15px 16px 16px;border:1.5px solid var(--line);
  border-radius:16px;background:var(--soft)}
.notify[hidden]{display:none}
.notify__h{display:flex;align-items:center;gap:8px;margin:0 0 4px;font-size:14px;color:var(--ink)}
.notify__h svg{flex:none;width:18px;height:18px;fill:none;stroke:currentColor;stroke-width:1.7;
  stroke-linecap:round;stroke-linejoin:round}
.notify__h b{font-weight:800;letter-spacing:-.01em}
.notify__s{margin:0 0 11px;font-size:13.5px;line-height:1.5;color:var(--ink-2)}
.notify__row{display:flex;gap:8px}
.notify__row .field{flex:1 1 auto;min-width:0;height:44px}
.notify__row .btn{flex:none;height:44px;padding-inline:18px}
.notify__n{margin:9px 0 0;font-size:12.5px;line-height:1.5;font-weight:700}
.notify__n[hidden]{display:none}
.notify__n--ok{color:var(--brand-text)}
.notify__n--bad{color:#b4231f}

/* Phone: the field and the button stack so neither is squeezed, and both keep
   a full-width target. */
@media (max-width:640px){
  .notify{padding:14px;border-radius:14px}
  .notify__row{flex-direction:column;gap:8px}
  .notify__row .field,.notify__row .btn{width:100%;height:46px}
  .notify__s{font-size:13px}
}
/* ── low stock ───────────────────────────────────────────────────────
   Shown only in the last few units. A badge that always says "in stock"
   teaches people to ignore it; a number that is running out is the one
   piece of stock information worth a line of the page.

   Amber rather than the brand green — green here would read as reassurance
   when the point is mild urgency — and it reuses the same warm palette as
   the BAC-water prompt so the drawer keeps two colours, not three. */
.low{display:inline-flex;align-items:center;gap:5px;margin-top:5px;
  font-style:normal;font-size:11.5px;font-weight:800;letter-spacing:-.01em;color:#a9750a}
.low[hidden]{display:none}
.low svg{width:12px;height:12px;flex:none;fill:currentColor;stroke:none}
.low--pdp{margin-top:12px;font-size:13px}
/* In the buy sheet the warning is the reason the stepper stops, so it sits
   directly under it at the size of a sentence rather than a footnote. */
.low--sheet{display:flex;margin:10px 0 0;font-size:12.5px}
/* A quantity the shelf cannot fill: still priced, still legible, plainly
   not available. */
.pbtier--gone{opacity:.42;cursor:not-allowed}
.pbtier--gone .pbtier__b{background:var(--soft);color:var(--ink-3)}
