/* ==========================================================================
   K&L Research Supply — design system
   Palette pulled from the brand mark: near-black ground, brushed silver,
   electric lab blue.
   ========================================================================== */

:root {
  /* ---- Brand palette (sampled from Brand assets/K&L Guidline.jpeg) ----
     Background black, background dark gray, card gray, electric blue accents,
     white / light gray text. These nine are the whole palette. */
  --bg:        #000101;   /* Background Black       */
  --bg-2:      #090d14;   /* Background Dark Gray   */
  --bg-3:      #0f1219;
  --panel:     #14171d;   /* Card Gray              */
  --panel-2:   #1b1f27;

  --line:      rgba(255, 255, 255, .08);
  --line-2:    rgba(255, 255, 255, .15);

  --txt:       #fdfdfd;   /* Text White             */
  --txt-dim:   #9fa5b1;   /* Text Light Gray        */
  --muted:     #767d89;

  --blue:      #2371f1;   /* Primary Blue           */
  --blue-2:    #4897f9;   /* Light Blue             */
  --blue-3:    #1751b8;
  --blue-soft: rgba(72, 151, 249, .14);
  --blue-glow: rgba(72, 151, 249, .38);

  --ok:        #29b74f;   /* Success Green          */
  --err:       #e33e3b;   /* Error Red              */

  --silver:    linear-gradient(180deg, #ffffff 0%, #e4e9f1 42%, #a9b0bc 78%, #d2d8e2 100%);
  --blue-grad: linear-gradient(180deg, #4897f9 0%, #2371f1 45%, #1751b8 80%, #4897f9 100%);

  /* Borrowed from the holographic label stock on the actual vials. */
  --holo: linear-gradient(165deg,
            #ffffff 0%, #e3e9f2 20%, #ded5ee 38%, #ffffff 54%,
            #c9d4e4 72%, #ecdfe9 87%, #f6f8fc 100%);

  --ink:       #0d1220;   /* legacy: text on any light surface */
  --ink-2:     #4a5568;

  --font-sans: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  /* Analytical data — lot numbers, CAS, formulas, retention times — is set in
     mono because that is how it reads on the certificate itself. */
  --font-mono: "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  /* Extended grotesque, used only for the hero nameplate. */
  --font-display: "Archivo", "Helvetica Neue", Arial, sans-serif;

  --wrap: 1240px;
  --r-sm: 6px;
  --r:    10px;
  --r-lg: 16px;

  --shadow:    0 18px 44px rgba(0, 0, 0, .55);
  --shadow-sm: 0 6px 20px rgba(0, 0, 0, .35);

  --ease: cubic-bezier(.4, 0, .2, 1);
}

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

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--txt);
  font-family: var(--font-sans);
  font-size: 16px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

img, svg { max-width: 100%; display: block; }
a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; cursor: pointer; background: none; border: 0; }
input, select, textarea { font: inherit; color: inherit; }
h1, h2, h3, h4 { margin: 0; line-height: 1.12; font-weight: 800; letter-spacing: -.02em; }
p { margin: 0; }
ul { margin: 0; padding: 0; list-style: none; }

::selection { background: var(--blue); color: #fff; }

:focus-visible {
  outline: 2px solid var(--blue-2);
  outline-offset: 3px;
  border-radius: 3px;
}

.wrap { width: 100%; max-width: var(--wrap); margin-inline: auto; padding-inline: 22px; }

.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* ==========================================================================
   Logo
   ========================================================================== */
/* The supplied lockup, displayed as an asset. Nothing here recreates, recolours
   or reproportions it — width is the only thing set, height follows from the
   asset's own aspect ratio so it can never be stretched. */
.logo { display: inline-flex; --logo-w: 200px; }
.logo picture { display: block; }
/* Per-context widths. Desktop header is the ~200px the brand calls for; the
   drawer and footer scale from the same asset. */
.header__brand .logo { --logo-w: 200px; }
.drawer__head  .logo { --logo-w: 168px; }
.footer__about .logo { --logo-w: 230px; }

@media (max-width: 640px) {
  .header__inner { min-height: 92px; }
  .header__brand .logo { --logo-w: 150px; }
  .footer__about .logo { --logo-w: 200px; }
}

.logo__img {
  display: block;
  width: var(--logo-w);
  height: auto;
  aspect-ratio: 900 / 439;   /* matches the asset, so no layout shift on load */
  object-fit: contain;
}

/* ==========================================================================
   Buttons
   ========================================================================== */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 9px;
  padding: 15px 28px;
  border-radius: var(--r-sm);
  font-size: 13px; font-weight: 700;
  letter-spacing: .09em; text-transform: uppercase;
  transition: transform .18s var(--ease), box-shadow .18s var(--ease), background .18s var(--ease), border-color .18s var(--ease);
  white-space: nowrap;
}
/* Icons inside buttons carry a viewBox but no intrinsic size, so without this
   they collapse to 0×0 and an icon-only button renders as a blank slab. Placed
   here so the more specific per-component rules below still win. */
.btn svg { width: 16px; height: 16px; flex: none; }
.btn:hover { transform: translateY(-2px); }
.btn:active { transform: translateY(0) scale(.985); }

/* Primary: lit from above via the inset highlight, sitting in its own pool of
   blue light. Hover deepens the pool and sweeps a sheen across the face. */
.btn--primary {
  position: relative; overflow: hidden;
  background: linear-gradient(180deg, var(--blue-2), var(--blue));
  color: #fff;
  box-shadow: 0 8px 24px rgba(22, 104, 227, .35),
              inset 0 1px 0 rgba(255, 255, 255, .28);
}
.btn--primary::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(105deg, transparent 40%, rgba(255, 255, 255, .28) 50%, transparent 60%);
  transform: translateX(-130%);
  transition: transform .7s var(--ease);
  pointer-events: none;
}
.btn--primary:hover {
  box-shadow: 0 16px 42px rgba(46, 134, 255, .55),
              0 0 0 1px rgba(122, 176, 255, .4),
              inset 0 1px 0 rgba(255, 255, 255, .38);
}
.btn--primary:hover::after { transform: translateX(130%); }

.btn--ghost {
  border: 1px solid var(--line-2); color: var(--txt);
  -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px);
}
.btn--ghost:hover {
  border-color: rgba(46, 134, 255, .7);
  background: var(--blue-soft);
  box-shadow: 0 10px 30px rgba(22, 104, 227, .22);
}

.btn--light { background: #fff; color: var(--ink); }
.btn--light:hover { box-shadow: 0 12px 28px rgba(0, 0, 0, .4); }

.btn--block { width: 100%; }
.btn--sm { padding: 10px 16px; font-size: 12px; }
.btn[disabled] { opacity: .45; pointer-events: none; }
/* A dimmed primary button still reads as blue, i.e. as the thing you should
   click. An unavailable one must not — it takes the same neutral treatment as
   an out-of-stock card CTA so the state is unmistakable at a glance. */
.btn--primary[disabled] {
  opacity: 1;
  background: rgba(255, 255, 255, .06);
  color: var(--muted);
  box-shadow: none;
  border-color: transparent;
}

.btn__arrow { transition: transform .18s var(--ease); }
.btn:hover .btn__arrow { transform: translateX(4px); }

/* ==========================================================================
   Announcement bar
   ========================================================================== */
.announce {
  background: #04050a;
  border-bottom: 1px solid var(--line);
  font-size: 11.5px;
  letter-spacing: .06em;
  color: var(--muted);
}
.announce__inner {
  display: flex; align-items: center; justify-content: space-between; gap: 18px;
  min-height: 36px;
}
.announce__group { display: flex; align-items: center; gap: 22px; }
.announce__item { display: inline-flex; align-items: center; gap: 7px; white-space: nowrap; }
.announce__item svg { width: 13px; height: 13px; flex: none; color: var(--blue-2); }
.announce__item--ok svg { color: var(--ok); }
.announce a.announce__item:hover { color: var(--txt); }
.announce__sep { width: 1px; height: 12px; background: var(--line-2); }

@media (max-width: 900px) {
  .announce__group--right { display: none; }
  .announce__group--left { width: 100%; justify-content: center; gap: 16px; }
  .announce__item--hide-sm { display: none; }
}

/* ==========================================================================
   Header
   ========================================================================== */
.header {
  position: sticky; top: 0; z-index: 80;
  background: rgba(6, 8, 14, .86);
  backdrop-filter: saturate(160%) blur(14px);
  -webkit-backdrop-filter: saturate(160%) blur(14px);
  border-bottom: 1px solid var(--line);
}
.header__inner {
  display: flex; align-items: center; gap: 26px;
  /* Grown from 74px: the official lockup is 2.05:1, so at the requested 200px
     width it stands 98px tall and needs the extra room. */
  min-height: 116px;
}
.header__brand { flex: none; }

.nav { display: flex; align-items: center; gap: 4px; margin-inline: auto; }
.nav__item { position: relative; }
.nav__link {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 26px 14px;
  font-size: 12.5px; font-weight: 600; letter-spacing: .11em; text-transform: uppercase;
  color: var(--txt-dim);
  transition: color .18s var(--ease);
}
.nav__link:hover { color: #fff; }
.nav__link svg { width: 10px; height: 10px; opacity: .7; transition: transform .18s var(--ease); }
.nav__item:hover .nav__link svg { transform: rotate(180deg); }

.nav__link.is-active { color: #fff; }
.nav__link.is-active::after {
  content: ""; position: absolute; left: 14px; right: 14px; bottom: 18px;
  height: 2px; border-radius: 2px;
  background: linear-gradient(90deg, var(--blue-2), var(--blue));
}

/* dropdown */
.nav__menu {
  position: absolute; top: 100%; left: 0;
  min-width: 232px; padding: 8px;
  background: var(--panel);
  border: 1px solid var(--line-2);
  border-radius: var(--r);
  box-shadow: var(--shadow);
  opacity: 0; visibility: hidden; transform: translateY(8px);
  transition: opacity .18s var(--ease), transform .18s var(--ease), visibility .18s;
}
.nav__item:hover .nav__menu,
.nav__item:focus-within .nav__menu { opacity: 1; visibility: visible; transform: translateY(0); }
.nav__menu a {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 9px 12px; border-radius: var(--r-sm);
  font-size: 13.5px; color: var(--txt-dim);
  transition: background .15s var(--ease), color .15s var(--ease);
}
.nav__menu a:hover { background: var(--blue-soft); color: #fff; }
.nav__menu .count { font-size: 11px; color: var(--muted); }

.header__actions { display: flex; align-items: center; gap: 6px; flex: none; }
.icon-btn {
  position: relative;
  width: 40px; height: 40px;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: var(--r-sm);
  color: var(--txt-dim);
  transition: background .16s var(--ease), color .16s var(--ease);
}
.icon-btn:hover { background: rgba(255, 255, 255, .07); color: #fff; }
.icon-btn svg { width: 19px; height: 19px; }

.cart-count {
  position: absolute; top: 3px; right: 2px;
  min-width: 17px; height: 17px; padding: 0 4px;
  display: grid; place-items: center;
  border-radius: 99px;
  background: var(--blue);
  color: #fff; font-size: 10px; font-weight: 700; line-height: 1;
  border: 2px solid var(--bg);
}

.burger { display: none; }

@media (max-width: 1080px) {
  .nav { display: none; }
  .burger { display: inline-flex; }
  .header__inner { justify-content: space-between; }
  .header__brand .logo { --logo-w: 166px; }
}

/* mobile drawer */
.drawer {
  position: fixed; inset: 0; z-index: 120;
  visibility: hidden;
}
.drawer.is-open { visibility: visible; }
.drawer__scrim {
  position: absolute; inset: 0;
  background: rgba(2, 3, 7, .7);
  opacity: 0; transition: opacity .25s var(--ease);
}
.drawer.is-open .drawer__scrim { opacity: 1; }
.drawer__panel {
  position: absolute; inset: 0 0 0 auto;
  width: min(360px, 88vw);
  background: var(--bg-2);
  border-left: 1px solid var(--line);
  padding: 20px 22px 40px;
  overflow-y: auto;
  transform: translateX(100%);
  transition: transform .28s var(--ease);
}
.drawer.is-open .drawer__panel { transform: translateX(0); }
.drawer__head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 22px; }
.drawer__nav a {
  display: block; padding: 14px 2px;
  border-bottom: 1px solid var(--line);
  font-size: 14px; font-weight: 600; letter-spacing: .09em; text-transform: uppercase;
  color: var(--txt-dim);
}
.drawer__nav a:hover { color: #fff; }
.drawer__nav .sub { padding-left: 16px; font-size: 12.5px; letter-spacing: .05em; text-transform: none; color: var(--muted); }
.drawer__cta { margin-top: 26px; }

/* ==========================================================================
   Hero
   ========================================================================== */
.hero {
  position: relative;
  overflow: hidden;
  background:
    radial-gradient(900px 520px at 76% 28%, rgba(46, 134, 255, .17), transparent 62%),
    radial-gradient(700px 420px at 8% 84%, rgba(22, 104, 227, .10), transparent 64%),
    linear-gradient(180deg, #080b13 0%, #0a0e18 58%, #06080e 100%);
  border-bottom: 1px solid var(--line);
}
/* ---------- ambient lighting ----------
   Two large, slowly drifting radial washes. Pure CSS on a single composited
   layer, so they cost nothing per frame beyond a transform. */
.hero__ambient { position: absolute; inset: 0; overflow: hidden; pointer-events: none; z-index: 0; }
.hero__glow {
  position: absolute; display: block; border-radius: 50%;
  filter: blur(58px); will-change: transform;
}
.hero__glow--a {
  top: -18%; right: 2%; width: 46vw; height: 46vw; max-width: 720px; max-height: 720px;
  background: radial-gradient(circle, rgba(46, 134, 255, .22), transparent 68%);
  animation: drift-a 22s ease-in-out infinite alternate;
}
.hero__glow--b {
  bottom: -26%; left: -6%; width: 40vw; height: 40vw; max-width: 620px; max-height: 620px;
  background: radial-gradient(circle, rgba(22, 104, 227, .17), transparent 70%);
  animation: drift-b 28s ease-in-out infinite alternate;
}
@keyframes drift-a { to { transform: translate3d(-5%, 6%, 0) scale(1.12); } }
@keyframes drift-b { to { transform: translate3d(7%, -5%, 0) scale(1.08); } }

/* ---------- molecular network ----------
   Sits above the ambient wash, below all content. Edge-masked so nodes fade out
   rather than being clipped by the viewport. */
.hero__molecules {
  position: absolute; inset: 0; width: 100%; height: 100%;
  z-index: 0; pointer-events: none;
  /* Weighted toward the product side so the network never competes with body
     copy for legibility on the left. */
  mask-image: radial-gradient(105% 95% at 68% 44%, #000 30%, transparent 84%);
  -webkit-mask-image: radial-gradient(105% 95% at 68% 44%, #000 30%, transparent 84%);
}

.hero__inner {
  position: relative;
  display: grid; grid-template-columns: minmax(0, 1.02fr) minmax(0, .98fr);
  gap: 48px; align-items: center;
  padding: 104px 0 132px;
}

.kicker {
  display: inline-flex; align-items: center; gap: 9px;
  font-family: var(--font-mono);
  font-size: 11px; font-weight: 500; letter-spacing: .22em; text-transform: uppercase;
  color: var(--blue-2);
  margin-bottom: 22px;
}
.kicker::before {
  content: ""; width: 0; height: 0;
  border-left: 7px solid var(--blue-2);
  border-block: 4.5px solid transparent;
}
.kicker--silver { color: var(--txt-dim); }
.kicker--silver::before { border-left-color: var(--blue-2); }

.hero__title { margin-bottom: 32px; }
/* Hero wordmark.
   Set in Archivo at its widest optical width and heaviest weight — an extended
   grotesque, which is the register luxury automotive and premium technology
   brands use for a nameplate. Wide apertures and flat terminals keep it legible
   at display size where a high-contrast serif would start to sparkle. The
   header logo is untouched; this is the headline voice, not the mark. */
.hero__kl {
  font-family: var(--font-display);
  font-size: clamp(60px, 9.2vw, 130px);
  font-weight: 900;
  font-stretch: 125%;
  line-height: .84;
  letter-spacing: -.035em;
  display: flex; align-items: baseline; gap: .01em;
  /* Faint blue bloom plus a tight dark edge for weight. Applied to the
     container: text-shadow cannot show through background-clip:text glyphs. */
  filter: drop-shadow(0 0 34px rgba(46, 134, 255, .28))
          drop-shadow(0 2px 1px rgba(0, 0, 0, .5));
}
.hero__kl .k,
.hero__kl .amp,
.hero__kl .l { background-clip: text; -webkit-background-clip: text; color: transparent; }

/* White K with a glass edge: near-white throughout, with one cool band low in
   the letterform so it catches light instead of reading as flat fill. */
.hero__kl .k {
  background-image: linear-gradient(172deg,
    #ffffff 0%, #ffffff 42%, #dae3f0 56%, #ffffff 70%, #eef3fa 100%);
}
/* Cobalt with the same band position, so both halves share one light source. */
.hero__kl .amp,
.hero__kl .l {
  background-image: linear-gradient(172deg,
    #7cb6ff 0%, #3f8dfa 30%, #1560d4 52%, #5aa4ff 64%, #0f57bd 84%, #2f81f0 100%);
}

/* Mirrors the logo lockup rather than inventing a second treatment for the same
   two words: letterspaced caps between two blue rules, scaled up. */
.hero__sub-title {
  display: flex; align-items: center; gap: 14px;
  width: max-content; max-width: 100%;
  margin-top: 20px;
  font-size: clamp(13px, 1.5vw, 19px);
  font-weight: 600; letter-spacing: .42em; text-transform: uppercase;
  color: #dbe3ee;
  white-space: nowrap;
}
.hero__sub-title::before,
.hero__sub-title::after {
  content: ""; height: 1px; flex: 0 0 auto; width: clamp(28px, 5vw, 64px);
  background: linear-gradient(90deg, transparent, var(--blue-2));
}
.hero__sub-title::after { background: linear-gradient(90deg, var(--blue-2), transparent); }

.hero__lede {
  max-width: 48ch;
  color: var(--txt-dim);
  font-size: 17.5px; line-height: 1.72;
  margin-bottom: 38px;
}

.hero__actions { display: flex; gap: 12px; flex-wrap: wrap; }
.hero__badges { display: flex; flex-wrap: wrap; gap: 32px; margin-top: 44px; }
.hero__badge { display: flex; align-items: center; gap: 11px; }
.hero__badge svg { width: 21px; height: 21px; color: var(--blue-2); flex: none; }
.hero__badge b {
  display: block; font-size: 12px; font-weight: 700;
  letter-spacing: .1em; text-transform: uppercase; color: #dfe5ee;
  line-height: 1.35; max-width: 12ch;
}

.hero__art { position: relative; display: grid; place-items: center; min-height: 460px; }

/* ==========================================================================
   Product display — hero bottle arrangement
   One wrapper, three explicitly positioned bottles, an ambient pool behind and
   a bench surface below. Every size is clamp()-driven, so the composition
   scales continuously instead of jumping at breakpoints.
   ========================================================================== */

/* Single source of truth for bottle heights: the wrapper derives its own height
   from these, so the box can never disagree with its contents. */
.product-display {
  /* Centre runs 25% taller than the flanking pair. Both derive from the same
     clamp, so the ratio holds exactly at every viewport width. */
  --bottle-center: clamp(232px, 25vw, 380px);
  --bottle-side:   clamp(186px, 20vw, 304px);
  --bench: 52px;
  /* The flanking bottles read as further back on the same bench, so their bases
     sit slightly higher — that is what perspective does, and it also guarantees
     their full glass foot clears the surface glow. */
  --lift: 26px;

  position: relative; z-index: 1;
  width: min(100%, 600px);
  height: calc(var(--bottle-center) + var(--bench) + 34px);
  min-height: calc(var(--bottle-side) + var(--bench) + var(--lift) + 34px);
  margin-inline: auto;
  will-change: transform;
}

/* Ambient pool: blue and violet offset from each other so they read as one
   blended light source rather than two stacked circles. Sits behind the
   bottles, never over them, so label text is never washed out. */
.product-display__glow {
  position: absolute; left: 50%; top: 44%;
  width: 116%; aspect-ratio: 1.4 / 1;
  transform: translate(-50%, -50%);
  z-index: 0; pointer-events: none;
  background:
    radial-gradient(closest-side at 62% 40%, rgba(126, 96, 255, .30), transparent 72%),
    radial-gradient(closest-side at 36% 58%, rgba(46, 134, 255, .34), transparent 70%);
  filter: blur(30px);
}

/* Bench: a light pool with a hairline edge catching the key light. */
.product-display__surface {
  position: absolute; left: 50%; bottom: calc(var(--bench) - 8px);
  width: 104%; height: 132px;
  transform: translateX(-50%);
  z-index: 0; pointer-events: none;
  background:
    radial-gradient(58% 40% at 50% 0%, rgba(46, 134, 255, .18), transparent 74%),
    radial-gradient(34% 24% at 50% 2%, rgba(196, 206, 255, .12), transparent 72%);
}
.product-display__surface::before {
  content: ""; position: absolute; left: 10%; right: 10%; top: 0; height: 1px;
  background: linear-gradient(90deg, transparent, rgba(150, 186, 255, .48), transparent);
}

.product-display__row { position: absolute; inset: 0; z-index: 1; }

.product-display__item { position: absolute; bottom: var(--bench); margin: 0; line-height: 0; }
.product-display__item picture { display: block; }
.product-display__item img {
  display: block; width: auto; object-fit: contain;
  aspect-ratio: 1024 / 1536;   /* matches the supplied renders exactly */
  /* Matched across all three: same key light, same rim, same sharpness. Depth
     comes from scale and stacking order, not from blurring the outer two. */
  filter: drop-shadow(0 20px 28px rgba(0, 0, 0, .58))
          drop-shadow(0 0 24px rgba(104, 142, 255, .24));
  animation: bottle-float 7s ease-in-out infinite alternate;
}

/* Centre bottle is the focal point: largest, fully lit, in front. */
.product-display__item--center { left: 50%; transform: translateX(-50%); z-index: 3; }
.product-display__item--center img { height: var(--bottle-center); }

/* Flanking bottles: smaller and fractionally dimmed for depth, but identical in
   sharpness and colour so the set reads as one shoot. */
/* Flanking bottles: smaller, raised, evenly and symmetrically placed. Identical
   brightness, sharpness and colour to the centre — depth comes from scale and
   baseline, never from dimming or blurring. */
.product-display__item--left,
.product-display__item--right { z-index: 2; bottom: calc(var(--bench) + var(--lift)); }
.product-display__item--left  { left: 3%; }
.product-display__item--right { right: 3%; }
.product-display__item--left img,
.product-display__item--right img { height: var(--bottle-side); }

/* Per-render correction. The three supplied files are framed almost, but not
   exactly, alike: the Tesamorelin glass is 1256px tall in a 1536px frame and
   sits 124px off the bottom, where the other two are 1207px and sit 171px off.
   Given identical CSS heights that would render Tesamorelin ~4% larger with its
   base ~3% lower. Scaling its frame by 1207/1256 equalises the glass, and
   lifting it by the 3.37% padding difference puts all three feet on one line.
   Measured from the assets, not eyeballed. */
.product-display__item--left img { height: calc(var(--bottle-side) * 0.961); }
.product-display__item--left {
  bottom: calc(var(--bench) + var(--lift) + var(--bottle-side) * 0.0337);
}
.product-display__item--left  img { animation-duration: 8.5s; animation-delay: -3s; }
.product-display__item--right img { animation-duration: 9.5s; animation-delay: -6s; }

/* Contact shadow: an ellipse tucked under the glass foot, blurred so it reads
   as cast light rather than a drawn oval. Sits behind the bottle it grounds. */
.product-display__item::after {
  content: ""; position: absolute; left: 50%; bottom: -6px;
  width: 92%; height: 26px; transform: translateX(-50%);
  background: radial-gradient(closest-side, rgba(0, 0, 0, .72), rgba(0, 0, 0, .28) 58%, transparent 82%);
  filter: blur(5px);
  z-index: -1; pointer-events: none;
}
/* The centre bottle is nearer and larger, so it casts the heavier shadow. */
.product-display__item--center::after {
  width: 96%; height: 32px; bottom: -9px;
  background: radial-gradient(closest-side, rgba(0, 0, 0, .8), rgba(0, 0, 0, .32) 56%, transparent 84%);
  filter: blur(7px);
}

@keyframes bottle-float { from { transform: translateY(0); } to { transform: translateY(-12px); } }

/* Tablet: pull the flanking bottles inward so the group stays compact. */
@media (max-width: 1024px) {
  .product-display__item--left  { left: 5%; }
  .product-display__item--right { right: 5%; }
}

/* Phone: the hero has already stacked to one column, so the display sits below
   the headline and buttons rather than over them. Tighten the spread so the
   three bottles stay within the viewport. */
@media (max-width: 560px) {
  .product-display { --bench: 34px; --lift: 18px; width: min(100%, 340px); }
  .product-display__item--left  { left: 0; }
  .product-display__item--right { right: 0; }
  .product-display__glow { width: 128%; }
}

@media (prefers-reduced-motion: reduce) {
  .product-display__item img { animation: none; }
}


@media (max-width: 940px) {
  .hero__inner { grid-template-columns: 1fr; gap: 34px; padding: 52px 0 74px; text-align: left; }
  .hero__art { min-height: 300px; }
  .hero__badges { gap: 20px; }
}

/* ==========================================================================
   Trust strip — dark glass, laps the hero
   The four claims a buyer needs answered, immediately below the fold.
   ========================================================================== */
.trust {
  position: relative; z-index: 5;
  margin-top: -58px; margin-bottom: 84px;
}
.trust__grid {
  display: grid; grid-template-columns: repeat(4, 1fr);
  gap: 1px;
  border-radius: var(--r-lg);
  overflow: hidden;
  border: 1px solid rgba(255, 255, 255, .1);
  background: rgba(255, 255, 255, .07);      /* shows through the 1px gaps as hairlines */
  box-shadow: 0 30px 70px rgba(0, 0, 0, .6);
}
.trust__cell {
  display: flex; align-items: flex-start; gap: 13px;
  padding: 26px 24px;
  background: linear-gradient(168deg, rgba(20, 27, 43, .92), rgba(11, 15, 25, .94));
  -webkit-backdrop-filter: blur(18px) saturate(140%);
  backdrop-filter: blur(18px) saturate(140%);
  transition: background .25s var(--ease);
}
.trust__cell:hover { background: linear-gradient(168deg, rgba(26, 35, 56, .95), rgba(14, 19, 31, .95)); }
.trust__tick {
  display: grid; place-items: center; flex: none;
  width: 22px; height: 22px; margin-top: 1px;
  border-radius: 50%;
  background: var(--blue-soft);
  color: var(--blue-2);
  box-shadow: inset 0 0 0 1px rgba(46, 134, 255, .35);
}
.trust__tick svg { width: 12px; height: 12px; }
.trust__cell b {
  display: block; color: #eaeff7;
  font-size: 13px; font-weight: 700; letter-spacing: .005em; line-height: 1.35;
  margin-bottom: 5px;
}
.trust__cell span { display: block; color: var(--muted); font-size: 12.5px; line-height: 1.55; }

@media (max-width: 900px) {
  .trust { margin-bottom: 60px; }
  .trust__grid { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 520px) {
  .trust { margin-top: -34px; }
  .trust__grid { grid-template-columns: 1fr; }
}

/* ==========================================================================
   Reveal on scroll — one-shot fade and rise, driven by motion.js
   ========================================================================== */
.js [data-reveal] {
  opacity: 0; transform: translateY(18px);
  transition: opacity .7s var(--ease), transform .7s var(--ease);
}
.js [data-reveal].is-in { opacity: 1; transform: none; }

/* A group container stays put and staggers its children instead, using the --i
   index motion.js writes onto each child. */
.js [data-reveal][data-reveal-group] { opacity: 1; transform: none; transition: none; }
.js [data-reveal-group] > * {
  opacity: 0; transform: translateY(16px);
  transition: opacity .6s var(--ease), transform .6s var(--ease);
  transition-delay: calc(var(--i, 0) * 70ms);
}
.js [data-reveal-group].is-in > * { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  .js [data-reveal], .js [data-reveal-group] > * { opacity: 1; transform: none; transition: none; }
  .btn:hover, .btn:active { transform: none; }
  .btn--primary::after { display: none; }
  /* Ambient drift and bottle float stop entirely — they are decorative. */
  .hero__glow { animation: none; }
}

/* ==========================================================================
   Section furniture
   ========================================================================== */
.section { padding: 104px 0; }
.section--tight { padding: 72px 0; }
.section--alt { background: var(--bg-2); border-block: 1px solid var(--line); }

.section__head {
  display: flex; align-items: flex-end; justify-content: space-between; gap: 28px;
  margin-bottom: 46px;
}
.section__title {
  font-size: clamp(30px, 4vw, 46px);
  letter-spacing: -.025em; line-height: 1.08;
}
.section__title span { color: var(--muted); font-weight: 700; }
.section__lede { color: var(--muted); max-width: 58ch; margin-top: 16px; font-size: 16px; line-height: 1.7; }

.link-more {
  display: inline-flex; align-items: center; gap: 8px;
  font-size: 12px; font-weight: 700; letter-spacing: .12em; text-transform: uppercase;
  color: var(--blue-2); white-space: nowrap;
}
.link-more:hover { color: #6fb0ff; }
.link-more svg { width: 14px; height: 14px; transition: transform .18s var(--ease); }
.link-more:hover svg { transform: translateX(4px); }

@media (max-width: 640px) {
  .section__head { flex-direction: column; align-items: flex-start; }
}

/* ==========================================================================
   Product cards
   ========================================================================== */
.rail { position: relative; }
.rail__track {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: minmax(214px, 1fr);
  gap: 18px;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scroll-behavior: smooth;
  scrollbar-width: none;

  /* Room for the hover state. `overflow-x: auto` forces the vertical axis to
     compute as auto too — a scroll container cannot clip one axis and let the
     other overflow — so a card lifting on hover was being sliced off at the top.
     The card rises 4px and casts `0 20px 44px`, which reaches ~2px above its own
     edge and ~42px below it. Pad for both, then pull the same amount back with
     negative margin so nothing around the rail moves. */
  padding-top: 18px;
  padding-bottom: 28px;
  margin-top: -18px;
  margin-bottom: -22px;   /* leaves the 6px of breathing room it had before */
}
.rail__track::-webkit-scrollbar { display: none; }
.rail__track > * { scroll-snap-align: start; }

.rail__btn {
  position: absolute; top: 50%; transform: translateY(-50%);
  width: 40px; height: 40px; z-index: 6;
  display: grid; place-items: center;
  border-radius: 99px;
  background: rgba(255, 255, 255, .95);
  color: var(--ink);
  box-shadow: 0 8px 22px rgba(0, 0, 0, .5);
  transition: background .16s var(--ease), opacity .16s var(--ease);
}
.rail__btn:hover { background: #fff; }
.rail__btn svg { width: 17px; height: 17px; }
.rail__btn--prev { left: -18px; }
.rail__btn--next { right: -18px; }
.rail__btn[disabled] { opacity: 0; pointer-events: none; }

@media (max-width: 1300px) {
  .rail__btn--prev { left: 4px; }
  .rail__btn--next { right: 4px; }
}

.grid-products {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(224px, 1fr));
  gap: 20px;
}

.card {
  position: relative;
  display: flex; flex-direction: column;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  overflow: hidden;
  transition: transform .2s var(--ease), box-shadow .2s var(--ease), border-color .2s var(--ease);
}
.card:hover {
  transform: translateY(-4px);
  border-color: rgba(72, 151, 249, .35);
  box-shadow: 0 20px 44px rgba(0, 0, 0, .55);
}

.card__media {
  position: relative;
  display: grid; place-items: center;
  padding: 24px 18px 12px;
  background: radial-gradient(78% 62% at 50% 38%, rgba(72, 151, 249, .10), transparent 72%);
  min-height: 182px;
}
.card__media .vial { width: 82px; transition: transform .25s var(--ease); }
.card:hover .card__media .vial { transform: translateY(-4px) scale(1.04); }

/* Product photography sits in the same footprint as the drawn vial, so a
   half-photographed catalog still lines up on the grid. The photos are cut to a
   3:4 frame with the vial normalised inside it, so matching that ratio here
   means every card shows the glass at an identical size with no letterboxing. */
.card__media .pmedia {
  height: 152px; aspect-ratio: 2 / 3; width: auto;
  object-fit: contain;
  transition: transform .25s var(--ease);
}
.card:hover .card__media .pmedia { transform: translateY(-4px) scale(1.04); }
/* The renders are opaque cutouts, so they read directly on the dark panel. */
.search__hit .pmedia {
  height: 40px; aspect-ratio: 2 / 3; width: auto; flex: none; object-fit: contain;
}

.card__badge {
  position: absolute; top: 10px; left: 10px;
  padding: 4px 9px; border-radius: 99px;
  font-size: 9.5px; font-weight: 800; letter-spacing: .1em; text-transform: uppercase;
  /* Solid Primary Blue puts white at 4.46:1, just under AA. Grading into
     blue-3 keeps the brand hue and lifts the text to ~5.3:1. */
  background: linear-gradient(180deg, var(--blue), #1f66db); color: #fff;
}
.card__badge--sale  { background: #d64545; }
.card__badge--new   { background: var(--ok); }
.card__badge--out   { background: #6b7688; }

/* flex:1 lets the body absorb whatever slack the row's tallest card creates, so
   the Add to cart button lands on the same line across the row. Without it a
   one-line subtitle (Tesamorelin, CJC-1295) sits its button 20px above the
   two-line ones (MOTS-C, NAD+) beside it, which reads as the button being
   raised. */
.card__body { display: flex; flex-direction: column; gap: 4px; padding: 14px 16px 16px; flex: 1; }
.card__purity {
  display: inline-flex; align-items: center; gap: 5px;
  align-self: flex-start;
  font-family: var(--font-mono);
  font-size: 9.5px; font-weight: 600; letter-spacing: .12em; text-transform: uppercase;
  color: var(--blue-2);
}
.card__purity::before {
  content: ""; width: 6px; height: 6px; border-radius: 99px;
  background: var(--blue-2); box-shadow: 0 0 0 3px rgba(72, 151, 249, .18);
}
.card__name { color: var(--txt); font-size: 14.5px; font-weight: 800; letter-spacing: -.01em; line-height: 1.3; }
.card__name a:hover { color: var(--blue-2); }
/* --txt-dim, not --muted: on Card Gray the latter is 4.33:1 and fails AA. */
.card__dose { color: var(--txt-dim); font-size: 12.5px; }
.card__price { color: var(--txt); font-size: 17px; font-weight: 800; margin-top: 6px; }
.card__price s { color: var(--muted); font-size: 13px; font-weight: 600; margin-left: 7px; }
.card__from { font-size: 11px; font-weight: 700; color: var(--muted); letter-spacing: .06em; text-transform: uppercase; margin-right: 4px; }

.card__cta {
  margin: 10px 16px 16px;
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  padding: 11px 14px; border-radius: var(--r-sm);
  background: var(--blue); color: #fff;
  font-size: 11.5px; font-weight: 800; letter-spacing: .1em; text-transform: uppercase;
  transition: background .16s var(--ease);
}
.card__cta:hover { background: var(--blue-3); }
/* Awaiting-price state: reads as deliberately not-yet-available rather than as
   a broken buy button. */
.card__cta:disabled {
  background: rgba(255, 255, 255, .06); color: var(--muted);
  cursor: default; box-shadow: none;
}
.card__cta:disabled:hover { background: rgba(255, 255, 255, .06); }
.card__price--soon { font-size: 14px; font-weight: 700; color: var(--blue-2); }
.pdp__soon { font-size: 22px; color: var(--blue-2); }
.card__cta svg { width: 14px; height: 14px; }
.card__cta.is-added { background: var(--ok); }

/* ==========================================================================
   Standard / feature blocks
   ========================================================================== */
.feature-grid {
  display: grid;
  /* min() guards the track from overflowing on very narrow screens. auto-fit
     lands on 3 columns at desktop, 2 at tablet, 1 on phones. */
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 288px), 1fr));
  /* Equal-height cards across every row, not just within a row. */
  grid-auto-rows: 1fr;
  gap: 22px;
}
/* Glassmorphism cards: translucent panel, blurred backdrop, hairline edge, and
   a light source implied by the inset highlight along the top edge. The sheen
   sweep on hover is a pseudo-element transform, so it composites cheaply. */
.feature {
  position: relative; overflow: hidden;
  /* Column layout so the body copy sits directly under the heading and the card
     can stretch to the row height without the text floating mid-card. */
  display: flex; flex-direction: column;
  padding: 32px 30px 34px;
  border-radius: var(--r-lg);
  background: linear-gradient(160deg, rgba(255, 255, 255, .062), rgba(255, 255, 255, .018));
  -webkit-backdrop-filter: blur(16px) saturate(150%);
  backdrop-filter: blur(16px) saturate(150%);
  border: 1px solid rgba(255, 255, 255, .085);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .09), 0 12px 34px rgba(0, 0, 0, .34);
  transition: transform .28s var(--ease), border-color .28s var(--ease), box-shadow .28s var(--ease);
}
.feature::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(115deg, transparent 38%, rgba(255, 255, 255, .07) 50%, transparent 62%);
  transform: translateX(-120%);
  transition: transform .8s var(--ease);
  pointer-events: none;
}
.feature:hover {
  transform: translateY(-6px);
  border-color: rgba(46, 134, 255, .42);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .13),
              0 24px 54px rgba(0, 0, 0, .5),
              0 0 0 1px rgba(46, 134, 255, .12);
}
.feature:hover::after { transform: translateX(120%); }
@media (prefers-reduced-motion: reduce) {
  .feature, .feature::after, .feature__icon { transition: none; }
  .feature:hover { transform: none; }
  .feature:hover .feature__icon { transform: none; }
}
.feature__icon {
  width: 46px; height: 46px; border-radius: var(--r-sm);
  display: grid; place-items: center;
  background: var(--blue-soft); color: var(--blue-2);
  box-shadow: inset 0 0 0 1px rgba(46, 134, 255, .22);
  margin-bottom: 20px;
  transition: transform .28s var(--ease), background .28s var(--ease), box-shadow .28s var(--ease);
}
/* The icon lifts and brightens with the card — one gesture, not two. */
.feature:hover .feature__icon {
  transform: translateY(-2px);
  background: rgba(46, 134, 255, .22);
  box-shadow: inset 0 0 0 1px rgba(46, 134, 255, .45), 0 8px 20px rgba(22, 104, 227, .28);
}
.feature__icon svg { width: 22px; height: 22px; }
.feature h3 { font-size: 17px; margin-bottom: 11px; letter-spacing: -.012em; line-height: 1.25; }
.feature p { color: var(--txt-dim); font-size: 14px; line-height: 1.7; max-width: 42ch; }

.split { display: grid; grid-template-columns: 1fr 1fr; gap: 52px; align-items: center; }
@media (max-width: 900px) { .split { grid-template-columns: 1fr; gap: 32px; } }

.stat-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: 18px; }
.stat { padding: 20px 22px; border: 1px solid var(--line); border-radius: var(--r); background: var(--bg-3); }
.stat b { display: block; font-size: 30px; font-weight: 800; letter-spacing: -.02em; color: #fff; }
.stat b em { font-style: normal; color: var(--blue-2); }
.stat span { font-size: 12px; letter-spacing: .09em; text-transform: uppercase; color: var(--muted); }

.checklist li {
  display: flex; align-items: flex-start; gap: 12px;
  padding: 11px 0;
  border-bottom: 1px dashed var(--line);
  color: var(--txt-dim); font-size: 14.5px;
}
.checklist li:last-child { border-bottom: 0; }
.checklist svg { width: 18px; height: 18px; color: var(--blue-2); flex: none; margin-top: 2px; }
.checklist b { color: #fff; font-weight: 700; }

/* QC steps */
.steps { display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); gap: 16px; counter-reset: step; }
.step {
  position: relative;
  padding: 24px 20px 20px;
  border: 1px solid var(--line);
  border-radius: var(--r);
  background: var(--bg-3);
}
.step::before {
  counter-increment: step; content: "0" counter(step);
  display: block; font-size: 12px; font-weight: 800; letter-spacing: .16em;
  color: var(--blue-2); margin-bottom: 10px;
}
.step h4 { font-size: 14.5px; margin-bottom: 6px; }
.step p { font-size: 13px; color: var(--muted); }

/* ==========================================================================
   FAQ accordion
   ========================================================================== */
.faq { display: grid; gap: 10px; }
.faq__item { border: 1px solid var(--line); border-radius: var(--r); background: var(--bg-3); overflow: hidden; }
.faq__item[open] { border-color: rgba(46, 134, 255, .4); }
.faq__q {
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
  padding: 18px 20px;
  font-size: 15px; font-weight: 700; color: #fff;
  cursor: pointer; list-style: none;
}
.faq__q::-webkit-details-marker { display: none; }
.faq__q::after {
  content: ""; flex: none; width: 10px; height: 10px;
  border-right: 2px solid var(--blue-2); border-bottom: 2px solid var(--blue-2);
  transform: rotate(45deg) translateY(-3px);
  transition: transform .2s var(--ease);
}
.faq__item[open] .faq__q::after { transform: rotate(225deg) translateY(-3px); }
.faq__a { padding: 0 20px 20px; color: var(--muted); font-size: 14.5px; }
.faq__a p + p { margin-top: 10px; }

/* ==========================================================================
   Newsletter
   ========================================================================== */
.newsletter {
  display: grid; grid-template-columns: 1fr auto; gap: 30px; align-items: center;
  padding: 36px 38px;
  border: 1px solid rgba(46, 134, 255, .28);
  border-radius: var(--r-lg);
  background:
    radial-gradient(560px 240px at 88% 20%, rgba(46, 134, 255, .18), transparent 70%),
    linear-gradient(180deg, var(--panel), var(--bg-3));
}
.newsletter h3 { font-size: 22px; margin-bottom: 7px; }
.newsletter p { color: var(--muted); font-size: 14px; }
@media (max-width: 800px) { .newsletter { grid-template-columns: 1fr; padding: 28px 24px; } }

.field-row { display: flex; gap: 10px; }
/* The input is width:100%, so without this it crushes the submit button next to
   it down to its padding and squashes the icon inside. */
.field-row > .btn { flex: none; }
.field, .select, textarea.field {
  width: 100%;
  padding: 13px 15px;
  background: rgba(255, 255, 255, .04);
  border: 1px solid var(--line-2);
  border-radius: var(--r-sm);
  color: var(--txt);
  font-size: 14px;
  transition: border-color .16s var(--ease), background .16s var(--ease);
}
.field::placeholder { color: #6f7a8d; }
.field:focus, .select:focus, textarea.field:focus { outline: none; border-color: var(--blue-2); background: rgba(46, 134, 255, .07); }
textarea.field { resize: vertical; min-height: 130px; }
.select { appearance: none; cursor: pointer;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5 6 6.5 11 1.5' stroke='%238d97ab' stroke-width='1.6' fill='none' stroke-linecap='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 13px center; background-size: 11px;
  padding-right: 34px;
}
.select option { background: var(--panel); color: var(--txt); }
.label { display: block; font-size: 11.5px; font-weight: 700; letter-spacing: .1em; text-transform: uppercase; color: var(--muted); margin-bottom: 7px; }
.form-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
.form-grid .full { grid-column: 1 / -1; }
@media (max-width: 620px) { .form-grid { grid-template-columns: 1fr; } }

.form-note { font-size: 12px; color: var(--muted); margin-top: 12px; }
.form-ok {
  display: none; align-items: center; gap: 10px;
  margin-top: 16px; padding: 13px 16px;
  border: 1px solid rgba(47, 191, 113, .4); background: rgba(47, 191, 113, .1);
  border-radius: var(--r-sm); color: #b7f0d0; font-size: 14px;
}
.form-ok.is-visible { display: flex; }
.form-ok svg { width: 18px; height: 18px; color: var(--ok); flex: none; }

/* ==========================================================================
   Footer
   ========================================================================== */
.footer { background: #04060b; border-top: 1px solid var(--line); padding-top: 56px; }
.footer__grid {
  display: grid; grid-template-columns: 1.5fr 1fr 1fr 1fr 1.5fr; gap: 36px;
  padding-bottom: 44px;
}
.footer__about p { color: var(--muted); font-size: 13.5px; margin-top: 16px; max-width: 34ch; }
.footer h4 {
  font-size: 11.5px; font-weight: 800; letter-spacing: .16em; text-transform: uppercase;
  color: #fff; margin-bottom: 16px;
}
/* Footer column headings. Promoted from <h4> to <h2> so the document
   outline does not skip a level; this rule keeps them looking identical. */
.footer__title { font-size: 12px; font-weight: 700; letter-spacing: .13em;
  text-transform: uppercase; color: #fff; margin-bottom: 14px; }
.footer__links li { margin-bottom: 10px; }
.footer__links a { color: var(--muted); font-size: 13.5px; transition: color .15s var(--ease); }
.footer__links a:hover { color: var(--blue-2); }

.socials { display: flex; gap: 9px; margin-top: 20px; }
.socials a {
  width: 34px; height: 34px; display: grid; place-items: center;
  border: 1px solid var(--line-2); border-radius: var(--r-sm);
  color: var(--muted);
  transition: border-color .16s var(--ease), color .16s var(--ease), background .16s var(--ease);
}
.socials a:hover { border-color: var(--blue-2); color: var(--blue-2); background: var(--blue-soft); }
.socials svg { width: 16px; height: 16px; }

.footer__bar {
  display: flex; align-items: center; justify-content: space-between; gap: 20px; flex-wrap: wrap;
  padding: 20px 0 30px;
  border-top: 1px solid var(--line);
  font-size: 12px; color: var(--muted);
}
.pay { display: flex; gap: 7px; align-items: center; }
.pay span {
  display: grid; place-items: center;
  width: 40px; height: 26px; border-radius: 4px;
  background: #fff; color: #1a2233;
  font-size: 8px; font-weight: 800; letter-spacing: .02em;
}

@media (max-width: 1000px) { .footer__grid { grid-template-columns: 1fr 1fr 1fr; } .footer__news { grid-column: 1 / -1; } }
@media (max-width: 640px)  { .footer__grid { grid-template-columns: 1fr 1fr; } .footer__about { grid-column: 1 / -1; } }

/* ==========================================================================
   Page header (interior pages)
   ========================================================================== */
.page-head {
  position: relative;
  padding: 52px 0 40px;
  background:
    radial-gradient(700px 300px at 78% 10%, rgba(46, 134, 255, .16), transparent 66%),
    linear-gradient(180deg, #080b13, #06080e);
  border-bottom: 1px solid var(--line);
}
.crumbs { display: flex; align-items: center; gap: 8px; font-size: 12px; color: var(--muted); margin-bottom: 14px; flex-wrap: wrap; }
.crumbs a:hover { color: var(--blue-2); }
.crumbs span { opacity: .5; }
.page-head h1 { font-size: clamp(30px, 5vw, 46px); }
.page-head p { color: var(--muted); max-width: 66ch; margin-top: 14px; }

/* ==========================================================================
   Shop layout
   ========================================================================== */
.shop { display: grid; grid-template-columns: 244px minmax(0, 1fr); gap: 34px; align-items: start; padding-block: 40px 70px; }
.filters { position: sticky; top: 96px; display: grid; gap: 22px; }
.filter__title { font-size: 11.5px; font-weight: 800; letter-spacing: .14em; text-transform: uppercase; color: #fff; margin-bottom: 12px; }
.filter__list li { margin-bottom: 3px; }
.filter__list button {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  width: 100%; padding: 8px 11px; border-radius: var(--r-sm);
  font-size: 13.5px; color: var(--txt-dim); text-align: left;
  transition: background .15s var(--ease), color .15s var(--ease);
}
.filter__list button:hover { background: rgba(255, 255, 255, .05); color: #fff; }
.filter__list button.is-active { background: var(--blue-soft); color: #fff; box-shadow: inset 2px 0 0 var(--blue-2); }
.filter__list .count { font-size: 11px; color: var(--muted); }

.shop__bar {
  display: flex; align-items: center; justify-content: space-between; gap: 16px; flex-wrap: wrap;
  margin-bottom: 22px;
}
.shop__count { font-size: 13px; color: var(--muted); }
.shop__count b { color: #fff; }
.shop__tools { display: flex; align-items: center; gap: 10px; }
.shop__tools .select, .shop__tools .field { width: auto; min-width: 178px; padding-block: 10px; font-size: 13px; }
.filters-toggle { display: none; }

.empty { padding: 60px 20px; text-align: center; color: var(--muted); }
.empty b { display: block; color: #fff; font-size: 18px; margin-bottom: 8px; }

@media (max-width: 900px) {
  .shop { grid-template-columns: 1fr; }
  .filters { position: static; display: none; }
  .filters.is-open { display: grid; }
  .filters-toggle { display: inline-flex; }

  /* The toolbar could not fit a phone: .shop__tools is a flex row whose search
     and sort controls carry min-width:178px, so at 390px it measured 467px and
     could neither shrink nor wrap. That 77px overhang then stretched the product
     grid and every card with it. Let the row wrap and the controls shrink. */
  .shop__bar { align-items: stretch; }
  .shop__tools { flex-wrap: wrap; width: 100%; }
  .shop__tools .select,
  .shop__tools .field { min-width: 0; flex: 1 1 150px; }
  .filters-toggle { flex: 0 0 auto; }
}

/* ==========================================================================
   Product detail
   ========================================================================== */
.pdp { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 52px; padding-block: 40px 24px; align-items: start; }
.pdp__media {
  position: relative;
  display: grid; place-items: center;
  min-height: 440px; padding: 40px;
  background: radial-gradient(70% 58% at 50% 40%, rgba(72, 151, 249, .12), transparent 74%), var(--bg-2);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  overflow: hidden;
}
.pdp__media::after {
  content: ""; position: absolute; inset: auto 0 0 0; height: 44%;
  background: linear-gradient(180deg, transparent, rgba(13, 18, 32, .07));
}
.pdp__media .vial { width: 188px; position: relative; z-index: 1; filter: drop-shadow(0 26px 30px rgba(13, 18, 32, .28)); }
.pdp__photo {
  height: 380px; aspect-ratio: 2 / 3; width: auto; max-width: 100%;
  object-fit: contain; position: relative; z-index: 1;
}
.pdp__ruo {
  position: absolute; top: 16px; right: 16px; z-index: 2;
  padding: 6px 11px; border-radius: 99px;
  background: rgba(13, 18, 32, .07); color: #4a5568;
  font-size: 10px; font-weight: 800; letter-spacing: .12em; text-transform: uppercase;
}

.pdp__cat { font-size: 11px; font-weight: 800; letter-spacing: .16em; text-transform: uppercase; color: var(--blue-2); margin-bottom: 12px; }
.pdp h1 { font-size: clamp(28px, 4vw, 40px); margin-bottom: 10px; }
.pdp__sub { color: var(--muted); font-size: 15px; margin-bottom: 20px; }

.pdp__price { display: flex; align-items: baseline; gap: 12px; margin-bottom: 22px; }
.pdp__price b { font-size: 32px; font-weight: 800; letter-spacing: -.02em; }
.pdp__price s { color: var(--muted); font-size: 17px; }
.pdp__price .save { padding: 4px 9px; border-radius: 99px; background: rgba(214, 69, 69, .16); color: #ff8b8b; font-size: 11px; font-weight: 800; letter-spacing: .06em; }

.opt { margin-bottom: 22px; }
.opt__label { display: flex; align-items: center; justify-content: space-between; margin-bottom: 10px; }
.opt__label .label { margin: 0; }
.opt__label .stock { font-size: 12px; color: var(--ok); display: inline-flex; align-items: center; gap: 6px; }
.opt__label .stock::before { content: ""; width: 7px; height: 7px; border-radius: 99px; background: var(--ok); }
.opt__choices { display: flex; flex-wrap: wrap; gap: 9px; }
.chip {
  padding: 11px 17px; border-radius: var(--r-sm);
  border: 1px solid var(--line-2);
  font-size: 13.5px; font-weight: 600; color: var(--txt-dim);
  transition: all .16s var(--ease);
}
.chip:hover { border-color: var(--blue-2); color: #fff; }
.chip.is-active { border-color: var(--blue-2); background: var(--blue-soft); color: #fff; }
.chip small { display: block; font-size: 11px; color: var(--muted); font-weight: 500; }
.chip.is-active small { color: #a9cdff; }

.qty { display: inline-flex; align-items: center; border: 1px solid var(--line-2); border-radius: var(--r-sm); overflow: hidden; }
.qty button { width: 42px; height: 46px; color: var(--txt-dim); font-size: 18px; transition: background .15s var(--ease); }
.qty button:hover { background: rgba(255, 255, 255, .06); color: #fff; }
.qty input { width: 50px; height: 46px; text-align: center; background: none; border: 0; font-weight: 700; }
.qty input::-webkit-outer-spin-button, .qty input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }

.pdp__buy { display: flex; gap: 12px; margin-bottom: 22px; flex-wrap: wrap; }
.pdp__buy .btn { flex: 1; min-width: 190px; }

.pdp__assure { display: grid; gap: 12px; padding: 18px 20px; border: 1px solid var(--line); border-radius: var(--r); background: var(--bg-3); margin-bottom: 24px; }
.pdp__assure div { display: flex; align-items: center; gap: 11px; font-size: 13.5px; color: var(--txt-dim); }
.pdp__assure svg { width: 17px; height: 17px; color: var(--blue-2); flex: none; }

.spec { width: 100%; border-collapse: collapse; font-size: 14px; }
.spec tr { border-bottom: 1px solid var(--line); }
.spec tr:last-child { border-bottom: 0; }
.spec th { text-align: left; padding: 12px 0; color: var(--muted); font-weight: 600; width: 40%; }
/* Values are analytical data — CAS, formula, mass, sequence — so they are set
   the way they appear on the certificate. */
.spec td {
  padding: 12px 0; color: var(--txt-dim); word-break: break-word;
  font-family: var(--font-mono); font-size: 13px; letter-spacing: -.01em;
}

.tabs { display: flex; gap: 4px; border-bottom: 1px solid var(--line); margin-bottom: 24px; flex-wrap: wrap; }
.tab {
  padding: 13px 18px;
  font-size: 12.5px; font-weight: 700; letter-spacing: .09em; text-transform: uppercase;
  color: var(--muted); border-bottom: 2px solid transparent; margin-bottom: -1px;
  transition: color .16s var(--ease), border-color .16s var(--ease);
}
.tab:hover { color: var(--txt); }
.tab.is-active { color: #fff; border-bottom-color: var(--blue-2); }
.tab-panel { display: none; color: var(--txt-dim); font-size: 15px; max-width: 78ch; }
.tab-panel.is-active { display: block; }
.tab-panel p + p, .tab-panel ul + p, .tab-panel p + ul { margin-top: 14px; }
.tab-panel li { position: relative; padding-left: 20px; margin-bottom: 9px; color: var(--txt-dim); }
.tab-panel li::before { content: ""; position: absolute; left: 2px; top: 9px; width: 6px; height: 6px; border-radius: 99px; background: var(--blue-2); }

@media (max-width: 900px) {
  .pdp { grid-template-columns: 1fr; gap: 30px; }
  .pdp__media { min-height: 320px; padding: 26px; }
  .pdp__media .vial { width: 140px; }
  .pdp__photo { height: 260px; }
}

/* ==========================================================================
   Cart
   ========================================================================== */
.cart { display: grid; grid-template-columns: minmax(0, 1fr) 340px; gap: 30px; align-items: start; padding-block: 40px 76px; }
.cart__list { border: 1px solid var(--line); border-radius: var(--r); overflow: hidden; }
.cart__row {
  display: grid; grid-template-columns: 78px minmax(0, 1fr) auto; gap: 16px; align-items: center;
  padding: 16px 18px; border-bottom: 1px solid var(--line);
}
.cart__row:last-child { border-bottom: 0; }
.cart__thumb { display: grid; place-items: center; padding: 8px; background: var(--bg-2); border: 1px solid var(--line); border-radius: var(--r-sm); }
.cart__thumb .vial { width: 42px; }
.cart__thumb .pmedia { height: 56px; aspect-ratio: 2 / 3; width: auto; object-fit: contain; }
.cart__name { font-weight: 700; font-size: 15px; }
.cart__name a:hover { color: var(--blue-2); }
.cart__meta { font-size: 12.5px; color: var(--muted); margin-top: 3px; }
.cart__right { display: flex; align-items: center; gap: 16px; }
.cart__line-price { font-weight: 800; min-width: 76px; text-align: right; }
.cart__remove { color: var(--muted); font-size: 12px; text-decoration: underline; }
.cart__remove:hover { color: #ff8b8b; }

.summary { padding: 22px; border: 1px solid var(--line); border-radius: var(--r); background: var(--bg-3); position: sticky; top: 96px; }
.summary h3 { font-size: 17px; margin-bottom: 18px; }
.summary__row { display: flex; justify-content: space-between; gap: 12px; padding: 9px 0; font-size: 14px; color: var(--txt-dim); }
.summary__row--total { border-top: 1px solid var(--line); margin-top: 8px; padding-top: 16px; font-size: 18px; font-weight: 800; color: #fff; }
.summary .btn { margin-top: 18px; }
.summary__note { font-size: 11.5px; color: var(--muted); margin-top: 14px; text-align: center; }

@media (max-width: 900px) {
  .cart { grid-template-columns: 1fr; }
  .summary { position: static; }
  .cart__row { grid-template-columns: 60px minmax(0, 1fr); }
  .cart__right { grid-column: 1 / -1; justify-content: space-between; }
}

/* ==========================================================================
   Toast
   ========================================================================== */
.toast-stack { position: fixed; right: 20px; bottom: 20px; z-index: 200; display: grid; gap: 10px; }
.toast {
  display: flex; align-items: center; gap: 12px;
  padding: 13px 17px; min-width: 250px;
  background: var(--panel-2); border: 1px solid rgba(46, 134, 255, .4);
  border-radius: var(--r); box-shadow: var(--shadow);
  font-size: 14px;
  animation: toast-in .28s var(--ease);
}
.toast svg { width: 18px; height: 18px; color: var(--ok); flex: none; }
.toast.is-leaving { animation: toast-out .22s var(--ease) forwards; }
@keyframes toast-in  { from { opacity: 0; transform: translateY(14px); } }
@keyframes toast-out { to   { opacity: 0; transform: translateY(10px); } }

/* ==========================================================================
   Search overlay
   ========================================================================== */
.search {
  position: fixed; inset: 0; z-index: 130;
  display: grid; place-items: start center;
  padding-top: 14vh;
  background: rgba(3, 5, 10, .82);
  backdrop-filter: blur(6px);
  visibility: hidden; opacity: 0;
  transition: opacity .2s var(--ease), visibility .2s;
}
.search.is-open { visibility: visible; opacity: 1; }
.search__box { width: min(620px, 92vw); }
.search__box .field { padding: 17px 19px; font-size: 16px; background: var(--panel); }
.search__results { margin-top: 12px; max-height: 52vh; overflow-y: auto; border-radius: var(--r); }
.search__hit {
  display: flex; align-items: center; gap: 13px;
  padding: 12px 15px; background: var(--panel);
  border-bottom: 1px solid var(--line);
}
.search__hit:hover { background: var(--panel-2); }
.search__hit .vial { width: 26px; flex: none; }
.search__hit b { font-size: 14px; }
.search__hit span { font-size: 12px; color: var(--muted); }
.search__hit .price { margin-left: auto; font-weight: 700; font-size: 14px; }

/* ==========================================================================
   Misc content
   ========================================================================== */
.prose { max-width: 76ch; color: var(--txt-dim); font-size: 15.5px; }
.prose h2 { font-size: 24px; margin: 38px 0 14px; color: #fff; }
.prose h3 { font-size: 17px; margin: 26px 0 10px; color: #fff; }
.prose p + p { margin-top: 14px; }
.prose ul { margin: 12px 0; }
.prose li { position: relative; padding-left: 20px; margin-bottom: 9px; }
.prose li::before { content: ""; position: absolute; left: 2px; top: 9px; width: 6px; height: 6px; border-radius: 99px; background: var(--blue-2); }
.prose a { color: var(--blue-2); text-decoration: underline; text-underline-offset: 3px; }
.prose strong { color: #fff; }
.prose hr { border: 0; border-top: 1px solid var(--line); margin: 32px 0; }

.notice {
  display: flex; gap: 13px;
  padding: 18px 20px; margin: 26px 0;
  border: 1px solid rgba(46, 134, 255, .3);
  background: var(--blue-soft);
  border-radius: var(--r);
  font-size: 14px; color: var(--txt-dim);
}
.notice svg { width: 20px; height: 20px; color: var(--blue-2); flex: none; margin-top: 1px; }
.notice b { color: #fff; }
.notice--warn { border-color: rgba(255, 193, 87, .32); background: rgba(255, 193, 87, .09); }
.notice--warn svg { color: #ffc157; }

.ruo-band {
  background: #04060b;
  border-top: 1px solid var(--line);
  padding: 16px 0;
  text-align: center;
  font-size: 11.5px; letter-spacing: .06em; color: var(--muted);
}
.ruo-band b { color: #cfd6e2; }

.team { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 18px; }
.contact-cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); gap: 16px; margin-bottom: 34px; }
.contact-card { padding: 22px; border: 1px solid var(--line); border-radius: var(--r); background: var(--bg-3); }
.contact-card svg { width: 20px; height: 20px; color: var(--blue-2); margin-bottom: 12px; }
.contact-card b { display: block; font-size: 14px; margin-bottom: 5px; }
.contact-card span, .contact-card a { font-size: 13.5px; color: var(--muted); }
.contact-card a:hover { color: var(--blue-2); }

/* reduced motion */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .01ms !important; transition-duration: .01ms !important; scroll-behavior: auto !important; }
}

/* ==========================================================================
   Age gate (21+)
   Blocking dialog shown once per 30 days. Built by assets/js/agegate.js.
   ========================================================================== */
html.is-gated, html.is-gated body { overflow: hidden; }

.agegate {
  position: fixed; inset: 0; z-index: 200;
  display: grid; place-items: center;
  padding: 24px;
  background: rgba(3, 5, 10, .88);
  -webkit-backdrop-filter: blur(10px) saturate(120%);
  backdrop-filter: blur(10px) saturate(120%);
  animation: agegate-in .28s var(--ease) both;
}
.agegate.is-leaving { animation: agegate-out .2s var(--ease) both; }

.agegate__panel {
  width: min(100%, 470px);
  padding: 38px 36px 30px;
  border-radius: var(--r-lg);
  background: linear-gradient(165deg, rgba(22, 29, 46, .96), rgba(11, 15, 25, .98));
  border: 1px solid rgba(255, 255, 255, .1);
  box-shadow: 0 40px 90px rgba(0, 0, 0, .7), inset 0 1px 0 rgba(255, 255, 255, .09);
  text-align: center;
  animation: agegate-rise .32s var(--ease) both;
}
.agegate__panel.is-denied { border-color: rgba(214, 69, 69, .5); }

.agegate__eyebrow {
  display: block;
  font-family: var(--font-mono);
  font-size: 10.5px; font-weight: 500;
  letter-spacing: .22em; text-transform: uppercase;
  color: var(--blue-2);
  margin-bottom: 14px;
}
.agegate__title { font-size: 26px; letter-spacing: -.02em; margin-bottom: 12px; }
.agegate__body { color: var(--txt-dim); font-size: 14.5px; line-height: 1.65; }
.agegate__actions {
  display: flex; flex-direction: column; gap: 10px;
  margin: 26px 0 18px;
}
.agegate__actions .btn { width: 100%; }
.agegate__fine { color: var(--muted); font-size: 12px; line-height: 1.6; }
.agegate__fine a { color: var(--blue-2); text-decoration: underline; text-underline-offset: 2px; }
.agegate__deny {
  margin-top: 16px; padding-top: 16px;
  border-top: 1px solid var(--line);
  color: #ff8b8b; font-size: 13.5px; font-weight: 600;
}

@keyframes agegate-in   { from { opacity: 0; } }
@keyframes agegate-out  { to   { opacity: 0; } }
@keyframes agegate-rise { from { opacity: 0; transform: translateY(14px) scale(.98); } }

@media (max-width: 420px) {
  .agegate__panel { padding: 30px 22px 24px; }
  .agegate__title { font-size: 22px; }
}
@media (prefers-reduced-motion: reduce) {
  .agegate, .agegate__panel { animation: none; }
}

/* ==========================================================================
   Shipping ETA on listings
   ========================================================================== */
.card__ship {
  display: flex; align-items: center; gap: 6px;
  margin-top: 8px;
  font-family: var(--font-mono);
  font-size: 10.5px; font-weight: 500; letter-spacing: .01em;
  color: var(--ok);
}
.card__ship svg { width: 13px; height: 13px; flex: none; }

/* Product page: the same answer, stated in full. */
/* A quiet line, not a filled panel — a coloured box here read as a stray bar
   sitting between the price and the size selector. */
.pdp__ship {
  display: flex; align-items: flex-start; gap: 9px;
  margin: -8px 0 22px;
  font-size: 13px; line-height: 1.5;
}
.pdp__ship svg { width: 15px; height: 15px; flex: none; margin-top: 2px; color: #7fd3a4; }
.pdp__ship b  { display: block; color: #7fd3a4; font-weight: 600; }
/* Today's actual answer, quieter than the standing policy above it. */
.pdp__ship em { display: block; margin-top: 2px; font-style: normal; color: var(--muted); font-size: 12.5px; }


/* ==========================================================================
   Checkout gating — mode choice + terms agreement
   ========================================================================== */
.cochoice {
  margin: 18px 0 4px; padding: 0; border: 0;
  display: grid; gap: 8px;
}
.cochoice legend {
  padding: 0; margin-bottom: 10px;
  font-size: 11px; font-weight: 700;
  letter-spacing: .1em; text-transform: uppercase;
  color: var(--muted);
}
.cochoice__opt {
  display: flex; align-items: flex-start; gap: 11px;
  padding: 13px 14px;
  border: 1px solid var(--line); border-radius: var(--r-sm);
  background: rgba(255, 255, 255, .022);
  cursor: pointer;
  transition: border-color .18s var(--ease), background .18s var(--ease);
}
.cochoice__opt:hover { border-color: var(--line-2); }
/* :has lets the whole tile show selection; browsers without it still show the
   native radio, so the control is never ambiguous. */
.cochoice__opt:has(input:checked) {
  border-color: rgba(46, 134, 255, .6);
  background: var(--blue-soft);
}
.cochoice__opt input { margin-top: 3px; accent-color: var(--blue-2); flex: none; }
.cochoice__opt b { display: block; font-size: 13.5px; color: var(--txt); }
.cochoice__opt small { display: block; margin-top: 3px; font-size: 12px; color: var(--muted); line-height: 1.5; }
.cochoice__join { padding: 4px 2px 2px; }
.cochoice__join .label { display: block; margin-bottom: 6px; }

.agree {
  display: flex; align-items: flex-start; gap: 11px;
  margin: 16px 0 14px;
  font-size: 12.5px; line-height: 1.55; color: var(--txt-dim);
  cursor: pointer;
}
.agree input { margin-top: 2px; width: 17px; height: 17px; accent-color: var(--blue-2); flex: none; }
.agree a { color: var(--blue-2); text-decoration: underline; text-underline-offset: 2px; }
.agree__hint {
  margin: 8px 0 0; text-align: center;
  font-size: 12px; color: var(--muted);
}
.btn[disabled] { opacity: .45; pointer-events: none; }

/* ==========================================================================
   Footer business identity
   ========================================================================== */
.footer__biz {
  display: grid; gap: 7px;
  margin: 16px 0 18px;
  font-style: normal;   /* <address> italicises by default */
  font-size: 13px; line-height: 1.5;
}
.footer__biz b { color: var(--txt); font-size: 13.5px; font-weight: 700; letter-spacing: -.005em; }
.footer__biz span,
.footer__biz a { display: flex; align-items: center; gap: 8px; color: var(--muted); }
.footer__biz a:hover { color: var(--blue-2); }
.footer__biz svg { width: 14px; height: 14px; flex: none; color: var(--blue-2); }

/* ==========================================================================
   Whole-card click target
   The overlay sits above the card surface but below the name link and the
   Add-to-cart button, so those keep their own behaviour and their own focus
   ring. It is aria-hidden and untabbable: the visible name link is already in
   the tab order, and a second link to the same place would be noise for a
   screen reader.
   ========================================================================== */
.card { position: relative; }
.card__hit { position: absolute; inset: 0; z-index: 1; border-radius: inherit; }
/* The whole card is a link, so it has to look like one. Without this the hit
   area works but gives no affordance, which reads as "not clickable". */
.card { cursor: pointer; }
.card__cta { cursor: pointer; }
.card__name a,
.card__cta { position: relative; z-index: 2; }
/* Keyboard focus on the name should still light the whole card. */
.card:focus-within { outline: 2px solid var(--blue-2); outline-offset: 3px; }
.card__name a:focus-visible { outline: none; }

/* Error state for form feedback (success state already exists as .is-visible). */
.form-ok.is-error { color: #ff8b8b; }
.form-ok.is-error svg { color: #ff8b8b; }

/* Per-line shipping ETA in the cart, matching the listing treatment. */
.cart__ship {
  display: flex; align-items: center; gap: 6px;
  margin-top: 5px;
  font-family: var(--font-mono);
  font-size: 10.5px; font-weight: 500;
  color: #7fd3a4;
}
.cart__ship svg { width: 12px; height: 12px; flex: none; }

/* ==========================================================================
   Skip link — first tab stop, so keyboard and screen-reader users can jump
   past the nav instead of tabbing through it on every page.
   ========================================================================== */
.skip-link {
  position: absolute; left: 12px; top: -60px; z-index: 300;
  padding: 12px 18px; border-radius: var(--r-sm);
  background: var(--blue); color: #fff;
  font-size: 13px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
  transition: top .18s var(--ease);
}
.skip-link:focus { top: 12px; }
main:focus { outline: none; }


/* Quantity ceiling notices. Stock-limited, not an error — muted, not red, and
   only present when the limit is actually reached. */
.qty-note,
.cart__cap {
  font-size: 12.5px;
  color: var(--muted);
  line-height: 1.5;
}
.cart__cap { display: block; margin-top: 6px; max-width: 150px; }
.qty-note:empty { display: none; }
