/* ============================================================================
   AION BIOGENX

   Structure and feel follow the reference the client approved (rxhere.com):
   centred container, rounded cards, pill buttons, alternating tinted bands, a
   formulation finder, a numbered onboarding row, a standards row, an FAQ
   accordion, and a full-screen mobile menu.

   Palette and typography are OURS and unchanged: the navy / steel / mint family
   from the client's own reference file, set in Geist and Geist Mono, self
   hosted. The reference is warm beige and Satoshi; we are cool navy and Geist,
   which is what keeps this from reading as a copy.

   This deliberately supersedes the previous radius-0 / no-cards / no-container
   system. Do not reintroduce those rules piecemeal: the two do not mix.
   ============================================================================ */

@font-face {
  font-family: 'Geist';
  font-style: normal; font-weight: 300 700; font-display: swap;
  src: url('../fonts/geist-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Geist';
  font-style: normal; font-weight: 300 700; font-display: swap;
  src: url('../fonts/geist-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
    U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020,
    U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Geist Mono';
  font-style: normal; font-weight: 400 600; font-display: swap;
  src: url('../fonts/geist-mono-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Geist Mono';
  font-style: normal; font-weight: 400 600; font-display: swap;
  src: url('../fonts/geist-mono-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
    U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020,
    U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}


/* ============================================================================
   TOKENS
   ============================================================================ */
:root {
  --navy-990: #04101B;
  --navy-900: #0A2038;
  --navy-700: #123456;

  --ink-2: #3E5C72;
  --ink-3: #4E6B82;   /* hard floor for text: 5.6:1 on paper, 4.8:1 on tint-200 */

  --steel-300: #7FAAC4;
  --steel-200: #ADC8D8;

  --paper:     #FCFDFD;
  --paper-050: #F7FAFA;
  --tint-100:  #F2F6F7;   /* the alternating band. Our cool answer to their beige. */
  --tint-200:  #E7EEF0;
  --line-300:  #DCE6E8;
  --line-400:  #C6D5D9;

  --mint-500: #4FBBA0;
  --mint-700: #1B7A63;
  --mint-100: #BFE8DA;

  --f-sans: 'Geist', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --f-mono: 'Geist Mono', ui-monospace, 'SFMono-Regular', Consolas, monospace;

  /* Rounded system, following the reference. One scale, applied consistently:
     pill for anything you press, 20px for cards, 14px for fields and media. */
  --r-pill: 999px;
  --r-card: 20px;
  --r-field: 14px;

  --wrap: 1200px;
  --gutter: clamp(20px, 4vw, 40px);
  --head-h: 76px;
  --ease: cubic-bezier(0.22, 0.61, 0.36, 1);
  --shadow-sm: 0 1px 2px rgba(10, 32, 56, .04), 0 8px 24px rgba(10, 32, 56, .05);
  --shadow-md: 0 2px 4px rgba(10, 32, 56, .05), 0 18px 44px rgba(10, 32, 56, .09);
}

/* ---------- Reset ---------- */
*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; padding: 0; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; scroll-padding-top: calc(var(--head-h) + 20px); }
body {
  background: var(--paper); color: var(--ink-2);
  font-family: var(--f-sans); font-size: 1.0625rem; line-height: 1.65;
  -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale;
  overflow-x: hidden;
}
img, svg { display: block; max-width: 100%; }
img { height: auto; }
a { color: inherit; text-decoration: none; }
button, input, select, textarea { font: inherit; color: inherit; }
button { background: none; border: 0; cursor: pointer; }
ul, ol { list-style: none; }
/* The hidden attribute must beat any layout display we set on a class.
   Without this, an element carrying both `hidden` and `display:flex` renders,
   which is how the empty quote-list banner shipped visible. */
[hidden] { display: none !important; }
h1, h2, h3, h4 { color: var(--navy-900); font-weight: 500; letter-spacing: -0.025em; line-height: 1.15; }
::selection { background: var(--mint-100); color: var(--navy-900); }
::placeholder { color: var(--ink-3); opacity: 1; }
:focus-visible { outline: 2px solid var(--mint-700); outline-offset: 3px; border-radius: 6px; }
.vh { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; }
.skip { position: absolute; left: 16px; top: -64px; z-index: 200; background: var(--navy-900); color: var(--paper); padding: 12px 20px; border-radius: var(--r-pill); transition: top .16s; }
.skip:focus { top: 12px; }

/* ---------- Layout ---------- */
.wrap { width: 100%; max-width: var(--wrap); margin-inline: auto; padding-inline: var(--gutter); }
.sec { padding-block: clamp(64px, 8vw, 112px); }
.sec--tint { background: var(--tint-100); }
.sec--ink { background: var(--navy-990); color: var(--steel-200); }

/* ---------- Type ---------- */
.h1 { font-size: clamp(2.25rem, 1.2rem + 3.6vw, 3.75rem); line-height: 1.06; letter-spacing: -0.035em; }
.h2 { font-size: clamp(1.875rem, 1.2rem + 2.2vw, 2.75rem); line-height: 1.12; letter-spacing: -0.03em; }
.lead { font-size: clamp(1.0625rem, 1rem + 0.35vw, 1.25rem); line-height: 1.6; color: var(--ink-2); }
.chip-label {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 7px 15px 7px 12px; border-radius: var(--r-pill);
  background: var(--mint-100); color: var(--navy-900);
  font-size: 0.8125rem; font-weight: 500;
}
.chip-label::before { content: ''; width: 6px; height: 6px; border-radius: 50%; background: var(--mint-700); }
.sec-head { max-width: 44rem; margin-bottom: clamp(38px, 5vw, 58px); }
.sec-head--center { margin-inline: auto; text-align: center; }
.sec-head .lead { margin-top: 18px; }
.mono { font-family: var(--f-mono); font-variant-numeric: tabular-nums slashed-zero; }

/* ---------- Buttons ---------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 9px;
  min-height: 52px; padding: 0 28px; border-radius: var(--r-pill);
  font-size: 0.9688rem; font-weight: 600; white-space: nowrap;
  transition: background-color .2s var(--ease), box-shadow .2s var(--ease), transform .12s var(--ease);
}
.btn:active { transform: translateY(1px); }
.btn--primary { background: var(--navy-900); color: var(--paper); }
.btn--primary:hover { background: var(--navy-700); box-shadow: var(--shadow-md); }
.btn--mint { background: var(--mint-500); color: var(--navy-990); }
.btn--mint:hover { background: #62C7AE; box-shadow: var(--shadow-md); }
.btn--ghost { background: transparent; color: var(--navy-900); box-shadow: inset 0 0 0 1px var(--line-400); }
.btn--ghost:hover { box-shadow: inset 0 0 0 1px var(--navy-900); background: var(--paper-050); }
.btn--sm { min-height: 42px; padding: 0 20px; font-size: 0.9063rem; }
.btn[disabled] { opacity: .5; pointer-events: none; }
.arrow { width: 16px; height: 16px; flex: none; transition: transform .2s var(--ease); }
.btn:hover .arrow { transform: translateX(3px); }

/* ============================================================================
   SELECT. The native option list is drawn by the operating system and CSS
   cannot reach it, which is why the lot picker opened as a white OS menu on a
   navy card. So every <select> is progressively enhanced: the real element
   stays in the DOM, clipped, and keeps carrying the value, the required
   attribute, form submission and the change event that main.js and catalog.js
   listen to. Only the presentation is ours. With JavaScript off, the native
   select is unclipped and everything still works.
   ============================================================================ */
.sel { position: relative; }
.sel > select {
  position: absolute; 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;
}
.sel__btn {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  width: 100%; min-height: 50px; padding: 13px 16px; text-align: left;
  background: var(--tint-100); color: var(--navy-900);
  border: 1px solid transparent; border-radius: var(--r-field); font-size: 1rem;
  transition: background-color .18s, border-color .18s, box-shadow .18s;
}
.sel__btn:hover { border-color: var(--line-400); }
.sel__btn svg { width: 16px; height: 16px; flex: none; color: var(--ink-3); transition: transform .22s var(--ease); }
.sel[data-open='true'] .sel__btn { background: var(--paper); border-color: var(--mint-700); box-shadow: 0 0 0 4px color-mix(in srgb, var(--mint-500) 20%, transparent); }
.sel[data-open='true'] .sel__btn svg { transform: rotate(180deg); }
.sel__btn.is-placeholder { color: var(--ink-3); }

.sel__list {
  position: absolute; z-index: 90; top: calc(100% + 8px); left: 0; right: 0;
  background: var(--paper); border: 1px solid var(--line-300); border-radius: var(--r-field);
  box-shadow: var(--shadow-md); padding: 6px; max-height: 17rem; overflow-y: auto;
  opacity: 0; visibility: hidden; transform: translateY(-6px);
  transition: opacity .18s var(--ease), transform .18s var(--ease), visibility .18s;
}
.sel[data-open='true'] .sel__list { opacity: 1; visibility: visible; transform: none; }
.sel__opt {
  padding: 11px 14px; border-radius: 10px; font-size: 0.9688rem; color: var(--ink-2);
  cursor: pointer; display: flex; align-items: center; justify-content: space-between; gap: 10px;
}
.sel__opt:hover, .sel__opt.is-active { background: var(--tint-100); color: var(--navy-900); }
.sel__opt[aria-selected='true'] { color: var(--navy-900); font-weight: 500; }
.sel__opt[aria-selected='true']::after { content: ''; width: 7px; height: 7px; border-radius: 50%; background: var(--mint-700); flex: none; }

/* Dark context: the lot picker sits on the navy certificate card. */
.sel--dark .sel__btn { background: rgba(255,255,255,.06); border-color: rgba(255,255,255,.18); color: var(--paper); border-radius: var(--r-pill); min-height: 42px; padding: 0 18px; font-size: 0.875rem; font-family: var(--f-mono); }
.sel--dark .sel__btn:hover { border-color: rgba(255,255,255,.34); }
.sel--dark .sel__btn svg { color: var(--steel-300); }
.sel--dark[data-open='true'] .sel__btn { background: rgba(255,255,255,.1); border-color: var(--mint-500); box-shadow: 0 0 0 4px rgba(79,187,160,.22); }
.sel--dark .sel__list { background: var(--navy-900); border-color: rgba(255,255,255,.14); box-shadow: 0 24px 60px rgba(0,0,0,.5); }
.sel--dark .sel__opt { color: var(--steel-200); font-family: var(--f-mono); font-size: 0.875rem; }
.sel--dark .sel__opt:hover, .sel--dark .sel__opt.is-active { background: rgba(255,255,255,.08); color: var(--paper); }
.sel--dark .sel__opt[aria-selected='true'] { color: var(--paper); }
.sel--dark .sel__opt[aria-selected='true']::after { background: var(--mint-500); }

/* Pill context: the catalogue toolbar. */
.sel--pill .sel__btn { background: var(--paper); border-color: var(--line-400); border-radius: var(--r-pill); padding: 0 20px; font-size: 0.9375rem; }
.sel--pill .sel__btn:hover { border-color: var(--navy-700); }

.field.is-error .sel__btn { border-color: var(--navy-900); border-width: 2px; }

/* ============================================================================
   HEADER
   ============================================================================ */
.hdr {
  position: sticky; top: 0; z-index: 100;
  background: color-mix(in srgb, var(--paper) 88%, transparent);
  backdrop-filter: blur(14px) saturate(160%); -webkit-backdrop-filter: blur(14px) saturate(160%);
  border-bottom: 1px solid transparent; transition: border-color .3s, background .3s;
}
.hdr.is-stuck { border-bottom-color: var(--line-300); background: color-mix(in srgb, var(--paper) 96%, transparent); }
@supports not (backdrop-filter: blur(1px)) { .hdr { background: var(--paper); } }
.hdr__in { display: flex; align-items: center; justify-content: space-between; gap: 24px; height: var(--head-h); }
/* The brand lockup is the supplied logo, not type set by hand: the mark and the
   wordmark are both extracted from it with transparent backgrounds. Everything
   is height-driven so no aspect ratio is ever distorted, and the accessible
   name lives in the wordmark's alt rather than in visible text. */
.brand { display: inline-flex; align-items: center; gap: 12px; flex: none; }
.brand__mark { height: 38px; width: auto; flex: none; }
/* The wordmark is a two-line stack: AION takes 55% of its height and BIOGENX
   only 22%. Sized off the total, so 34px keeps the lower line near 8px and
   legible. Anything under about 28px turns BIOGENX into a smudge. */
.brand__word { height: 34px; width: auto; flex: none; }
.nav { display: flex; align-items: center; gap: 4px; }
.nav a { padding: 9px 14px; border-radius: var(--r-pill); font-size: 0.9375rem; font-weight: 500; color: var(--ink-2); transition: background-color .18s, color .18s; }
.nav a:hover, .nav a[aria-current='page'] { color: var(--navy-900); background: var(--tint-100); }
.hdr__end { display: flex; align-items: center; gap: 10px; flex: none; }
.qpill { display: none; align-items: center; gap: 7px; padding: 9px 15px; border-radius: var(--r-pill); background: var(--tint-100); font-size: 0.875rem; font-weight: 500; color: var(--navy-900); }
.qpill.is-on { display: inline-flex; }
.qpill .n { font-family: var(--f-mono); font-variant-numeric: tabular-nums; color: var(--mint-700); }

/* Two-bar mark, as the reference, that folds into a cross when open. */
.burger { display: none; width: 44px; height: 44px; border-radius: var(--r-pill); position: relative; flex: none; }
.burger span { position: absolute; left: 12px; width: 20px; height: 1.75px; background: var(--navy-900); border-radius: 2px; transition: transform .3s var(--ease); }
.burger span:nth-child(1) { top: 19px; }
.burger span:nth-child(2) { top: 25px; }
.burger[aria-expanded='true'] span:nth-child(1) { transform: translateY(3px) rotate(45deg); }
.burger[aria-expanded='true'] span:nth-child(2) { transform: translateY(-3px) rotate(-45deg); }

/* ============================================================================
   MOBILE MENU. The reference's full-screen takeover, rebuilt bigger and
   grouped: its 15px 600-weight rows become 1.75rem rows with real tap targets,
   the flat list gains labelled groups, the catalogue rows carry their real SKU
   counts, the primary action is pinned to the bottom instead of floating in
   the list, and the groups stagger in so the takeover has a reading direction.
   ============================================================================ */
.mnav {
  position: fixed; inset: 0; z-index: 150; background: var(--paper);
  display: flex; flex-direction: column;
  opacity: 0; visibility: hidden; transform: translateY(-8px);
  transition: opacity .32s var(--ease), transform .32s var(--ease), visibility .32s;
}
.mnav.is-open { opacity: 1; visibility: visible; transform: none; }
.mnav__top { display: flex; align-items: center; justify-content: space-between; height: var(--head-h); flex: none; }
.mnav__body { flex: 1; overflow-y: auto; -webkit-overflow-scrolling: touch; padding-bottom: 20px; }
.mnav__label { font-family: var(--f-mono); font-size: 0.6875rem; letter-spacing: 0.12em; text-transform: uppercase; color: var(--ink-3); padding: 24px 0 8px; }
.mnav__link {
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
  padding: 15px 0; font-size: 1.75rem; font-weight: 500; letter-spacing: -0.03em;
  color: var(--navy-900); border-bottom: 1px solid var(--line-300);
}
.mnav__link .c { font-family: var(--f-mono); font-size: 0.875rem; font-weight: 400; color: var(--ink-3); font-variant-numeric: tabular-nums; }
.mnav__link:active { color: var(--mint-700); }
.mnav__foot { flex: none; padding: 20px 0 max(24px, env(safe-area-inset-bottom)); border-top: 1px solid var(--line-300); display: grid; gap: 14px; justify-items: center; }
/* Not full bleed. Edge to edge, the CTA reads as a bar welded to the bottom of
   the screen; hugging its label with generous padding lets it sit as an object
   with air around it, and 260px is still a comfortable thumb target. */
.mnav__foot .btn { width: auto; min-width: min(17rem, 76%); padding-inline: 36px; }
.mnav__mail { text-align: center; font-size: 0.875rem; color: var(--ink-3); }
.mnav.is-open .mnav__group { animation: mrise .42s var(--ease) backwards; }
.mnav.is-open .mnav__group:nth-child(1) { animation-delay: .05s; }
.mnav.is-open .mnav__group:nth-child(2) { animation-delay: .11s; }
.mnav.is-open .mnav__group:nth-child(3) { animation-delay: .17s; }
@keyframes mrise { from { opacity: 0; transform: translateY(14px); } }

/* ============================================================================
   HERO
   ============================================================================ */
.hero { padding-block: clamp(40px, 6vw, 76px) clamp(56px, 7vw, 96px); }
.hero__grid { display: grid; grid-template-columns: minmax(0, 1.05fr) minmax(0, 0.95fr); gap: clamp(32px, 5vw, 64px); align-items: center; }
.hero h1 { margin: 20px 0 22px; max-width: 15ch; }
.hero .lead { max-width: 46ch; }
.hero__cta { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 34px; }
.hero__trust { display: flex; flex-wrap: wrap; gap: 10px 26px; margin-top: 36px; padding-top: 26px; border-top: 1px solid var(--line-300); }
.hero__trust li { display: flex; align-items: center; gap: 9px; font-size: 0.9375rem; color: var(--ink-2); }
.hero__trust svg { width: 17px; height: 17px; color: var(--mint-700); flex: none; }
/* --- Apertura ---------------------------------------------------------------
   Sigue el mockup que aprobó el cliente: cintillo, titular, dos llamadas, tres
   cifras y el dial de pureza en lugar de una foto. La tipografía es la del
   sitio (Geist): el acento del titular va en color, no en cursiva. */
.hero__eyebrow {
  display: flex; align-items: center; gap: 12px;
  font-family: var(--f-mono); font-size: 0.6875rem; font-weight: 500;
  letter-spacing: 0.14em; text-transform: uppercase; color: var(--ink-3);
}
.hero__eyebrow::before { content: ''; width: 28px; height: 1px; background: var(--line-400); flex: none; }
.hero__h1 {
  font-weight: 500;
  font-size: clamp(2.5rem, 1.1rem + 4.4vw, 4.25rem);
  line-height: 1.06; letter-spacing: -0.035em; max-width: 17ch;
}
/* Geist no tiene cursiva: el acento del titular se marca en color. */
.hero__h1 em { font-style: normal; color: var(--navy-700); }
.hero__stats { display: flex; flex-wrap: wrap; gap: 16px 46px; margin-top: 40px; padding-top: 26px; border-top: 1px solid var(--line-300); }
.hero__stats div { min-width: 0; }
.hero__stats dt {
  font-family: var(--f-mono); font-size: clamp(1.375rem, 1.1rem + 0.9vw, 1.75rem);
  font-weight: 500; letter-spacing: -0.02em; color: var(--navy-900);
  font-variant-numeric: tabular-nums;
}
.hero__stats dd { margin: 7px 0 0; font-size: 0.6875rem; letter-spacing: 0.1em; text-transform: uppercase; color: var(--ink-3); }

/* Laboratory backdrop behind the purity dial: rows of lyophilized vials on a
   steel tray (navy caps, matching the product label). Asked for by Gary on
   22 Aug 2026 and made clearly visible per Maykel on 25 Aug 2026. Decorative,
   so it is a CSS background and not an <img>. The mask stays clear in the
   middle, so the image never sits under the figure and the 5.6:1 floor on
   .dial__n and .dial__k holds unchanged. */
.hero__dial { position: relative; isolation: isolate; }
.hero__dial::before {
  content: '';
  position: absolute; inset: -12% -8%; z-index: -1;
  background: url('../img/lab-vials.jpg') center / cover no-repeat;
  border-radius: var(--r-card);
  opacity: .55;
  filter: contrast(.92);
  -webkit-mask-image: radial-gradient(closest-side, transparent 30%, #000 62%, transparent 100%);
  mask-image: radial-gradient(closest-side, transparent 30%, #000 62%, transparent 100%);
}

.dial { position: relative; width: min(100%, 300px); aspect-ratio: 1; margin-inline: auto; }
.dial svg { width: 100%; height: 100%; transform: rotate(-90deg); overflow: visible; }
.dial__track { fill: none; stroke: var(--line-300); stroke-width: 0.9; }
.dial__arc {
  fill: none; stroke: var(--mint-500); stroke-width: 1.2; stroke-linecap: round;
  /* 2 * PI * 47, el radio del anillo en el viewBox de 100 */
  stroke-dasharray: 295.31; stroke-dashoffset: 295.31;
  transition: stroke-dashoffset 1.6s var(--ease) .25s;
}
.rv.in .dial__arc { stroke-dashoffset: 1.18; }   /* 295.31 * (1 - 0.996) */
.dial__mid { position: absolute; inset: 0; display: grid; place-content: center; text-align: center; }
.dial__n { font-family: var(--f-mono); font-size: clamp(1.75rem, 1.2rem + 1.6vw, 2.25rem); font-weight: 500; letter-spacing: -0.03em; color: var(--navy-900); font-variant-numeric: tabular-nums; }
.dial__k { margin-top: 12px; font-family: var(--f-mono); font-size: 0.6875rem; letter-spacing: 0.14em; text-transform: uppercase; color: var(--ink-3); }
.dial__lot { margin-top: 6px; font-family: var(--f-mono); font-size: 0.6875rem; letter-spacing: 0.08em; color: var(--mint-700); }

.hero__media { position: relative; }
.hero__media img { width: 100%; aspect-ratio: 4 / 3.4; object-fit: cover; border-radius: var(--r-card); }
.hero__badge {
  position: absolute; left: -18px; bottom: 26px; background: var(--paper);
  border-radius: var(--r-field); box-shadow: var(--shadow-md);
  padding: 15px 20px; display: flex; align-items: center; gap: 14px;
}
.hero__badge .ring { width: 40px; height: 40px; border-radius: 50%; background: var(--mint-100); display: grid; place-items: center; flex: none; }
.hero__badge .ring svg { width: 20px; height: 20px; color: var(--mint-700); }
.hero__badge .k { display: block; font-size: 0.75rem; color: var(--ink-3); }
.hero__badge .v { font-size: 0.9375rem; font-weight: 600; color: var(--navy-900); }

/* ============================================================================
   FINDER. The reference's "find the right formulation, instantly" block, made
   live: it searches the real 111 SKU dataset instead of showing fixed cards.
   ============================================================================ */
.finder__search { max-width: 40rem; margin: 0 auto clamp(26px, 3vw, 34px); position: relative; }
.finder__search > svg { position: absolute; left: 20px; top: 50%; transform: translateY(-50%); width: 19px; height: 19px; color: var(--ink-3); pointer-events: none; }
.finder__search input {
  width: 100%; min-height: 58px; padding: 0 20px 0 52px;
  background: var(--paper); border: 1px solid var(--line-400); border-radius: var(--r-pill);
  font-size: 1.0625rem; color: var(--navy-900); box-shadow: var(--shadow-sm);
  transition: border-color .2s, box-shadow .2s;
}
.finder__search input:focus { outline: none; border-color: var(--mint-700); box-shadow: 0 0 0 4px color-mix(in srgb, var(--mint-500) 22%, transparent); }
.finder__chips { display: flex; flex-wrap: wrap; justify-content: center; gap: 8px; margin-bottom: 32px; }
.chip {
  padding: 9px 16px; border-radius: var(--r-pill); background: var(--paper);
  border: 1px solid var(--line-300); font-size: 0.875rem; font-weight: 500; color: var(--ink-2);
  transition: background-color .18s, border-color .18s, color .18s;
}
.chip:hover { border-color: var(--line-400); color: var(--navy-900); }
.chip[aria-pressed='true'] { background: var(--navy-900); border-color: var(--navy-900); color: var(--paper); }

.pgrid { display: grid; grid-template-columns: repeat(auto-fill, minmax(232px, 1fr)); gap: 16px; }
.pcard {
  background: var(--paper); border: 1px solid var(--line-300); border-radius: var(--r-card);
  padding: 0; overflow: hidden; display: flex; flex-direction: column;
  transition: transform .22s var(--ease), box-shadow .22s var(--ease), border-color .22s;
}
.pcard:hover { transform: translateY(-3px); box-shadow: var(--shadow-md); border-color: transparent; }
/* One shared product photograph for now. When per-SKU photography arrives, give
   each product an `img` key in products.js and read it in place of PRODUCT_IMG. */
/* The image is a button: it opens the price bands. Display and width are the
   only things a <button> needs here, because the global reset already strips
   its background, border and font. */
.pcard__media { position: relative; display: block; width: 100%; text-align: left; background: var(--tint-100); overflow: hidden; }
/* Square, not 4:3: the vial is a quarter of the photo's width, and on ~300 px
   cards the label could not be read. Cover at 1:1 shows the vial 33 % larger
   and only crops plain backdrop at the sides. The peeled -label photo's wings
   span 12.2 %-87.8 % of the width and the square crop keeps 12.5 %-87.5 %, so
   they still fit; that is also why peel cards do not zoom on hover, since
   scale(1.04) clipped the wing edges. */
.pcard__media img { width: 100%; aspect-ratio: 1 / 1; object-fit: cover; transition: transform .5s var(--ease); }
.pcard:hover .pcard__media img { transform: scale(1.04); }
.pcard[data-peel]:hover .pcard__media img { transform: none; }
/* The cue names what the click does. It appears on hover and on keyboard
   focus, and stays put on touch, where there is no hover to reveal it. */
.pcard__cue {
  position: absolute; right: 10px; bottom: 10px;
  padding: 6px 12px; border-radius: var(--r-pill);
  background: color-mix(in srgb, var(--navy-990) 82%, transparent);
  color: var(--paper); font-size: 0.75rem; font-weight: 600; letter-spacing: 0.01em;
  opacity: 0; transform: translateY(4px);
  transition: opacity .18s var(--ease), transform .18s var(--ease);
}
.pcard:hover .pcard__cue, .pcard__media:focus-visible .pcard__cue { opacity: 1; transform: none; }
@media (hover: none) {
  .pcard__cue { opacity: 1; transform: none; }
}
/* On the landing page the body is still one big link to the catalogue, now
   that the card is an <article> and the image has taken the click. */
.pcard--link .pcard__body { position: relative; }
.pcard--link .pcard__name::after { content: ''; position: absolute; inset: 0; }
.pcard__body { padding: 18px 20px 20px; display: flex; flex-direction: column; gap: 8px; flex: 1; }
.pcard__cat { font-family: var(--f-mono); font-size: 0.6875rem; letter-spacing: 0.1em; text-transform: uppercase; color: var(--mint-700); }
.pcard__name { font-size: 1.0625rem; font-weight: 500; color: var(--navy-900); line-height: 1.3; }
.pcard__name a { color: inherit; text-decoration: none; }
.pcard__name a:hover { text-decoration: underline; text-underline-offset: 3px; }
/* The opening band price. Mono for the figure, a small sans tag naming the
   band so the number is never ambiguous about which one it is. */
.pcard__price { display: flex; align-items: baseline; gap: 8px; font-family: var(--f-mono); font-size: 1.125rem; font-weight: 600; color: var(--navy-900); font-variant-numeric: tabular-nums; }
.pcard__price i { font-style: normal; font-family: var(--f-sans); font-size: 0.6875rem; font-weight: 500; letter-spacing: 0.08em; text-transform: uppercase; color: var(--mint-700); }
.pcard__price.is-quote { font-family: var(--f-sans); font-size: 0.875rem; font-weight: 500; color: var(--ink-3); }
.pcard__meta { display: flex; flex-wrap: wrap; gap: 6px; margin-top: auto; padding-top: 12px; }
.pcard__meta span { padding: 4px 11px; border-radius: var(--r-pill); background: var(--tint-100); font-size: 0.75rem; color: var(--ink-2); }
/* Scroll position indicator. Desktop shows the whole grid at once and needs no
   indicator, so it only exists below 640px where the grid becomes a track. */
.ptrack { display: none; align-items: center; gap: 14px; margin-top: 18px; }
.ptrack__bar { position: relative; flex: 1; height: 3px; border-radius: var(--r-pill); background: var(--tint-200); overflow: hidden; }
.ptrack__bar i { position: absolute; top: 0; left: 0; height: 100%; border-radius: var(--r-pill); background: var(--mint-700); will-change: transform; }
.ptrack__n { flex: none; font-family: var(--f-mono); font-size: 0.8125rem; color: var(--ink-3); font-variant-numeric: tabular-nums; }

.finder__foot { display: flex; align-items: center; justify-content: space-between; gap: 20px; flex-wrap: wrap; margin-top: 34px; }
.finder__count { font-size: 0.9375rem; color: var(--ink-3); }
.finder__count b { color: var(--navy-900); font-weight: 600; }
.finder__empty { grid-column: 1 / -1; text-align: center; padding: 54px 20px; color: var(--ink-3); }

/* ============================================================================
   STEPS
   ============================================================================ */
.steps { display: grid; grid-template-columns: repeat(4, 1fr); gap: 16px; }
.step-c { background: var(--paper); border-radius: var(--r-card); padding: 26px 24px 28px; box-shadow: var(--shadow-sm); display: flex; flex-direction: column; gap: 9px; }
.step-c__n { width: 38px; height: 38px; border-radius: 50%; background: var(--navy-900); color: var(--paper); display: grid; place-items: center; font-family: var(--f-mono); font-size: 0.875rem; margin-bottom: 6px; }
.step-c h3 { font-size: 1.0625rem; }
.step-c p { font-size: 0.9375rem; line-height: 1.55; color: var(--ink-2); }
.step-c__flag { margin-top: auto; padding-top: 14px; font-size: 0.8125rem; color: var(--mint-700); font-weight: 500; display: flex; align-items: center; gap: 7px; }
.step-c__flag svg { width: 15px; height: 15px; flex: none; }

/* ============================================================================
   STANDARDS
   ============================================================================ */
.std__grid { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: clamp(32px, 5vw, 60px); align-items: center; }
.std__list { display: grid; gap: 14px; }
.std-c { background: var(--paper); border-radius: var(--r-card); padding: 22px 24px; box-shadow: var(--shadow-sm); display: flex; gap: 16px; }
.std-c__ico { width: 42px; height: 42px; border-radius: 12px; background: var(--tint-100); display: grid; place-items: center; flex: none; }
.std-c__ico svg { width: 20px; height: 20px; color: var(--navy-700); }
.std-c h3 { font-size: 1rem; margin-bottom: 5px; }
.std-c p { font-size: 0.9063rem; line-height: 1.55; color: var(--ink-2); }
.std__media img { width: 100%; aspect-ratio: 4 / 3; object-fit: cover; border-radius: var(--r-card); }

/* ============================================================================
   CERTIFICATE. Our own asset, kept: the one thing the reference cannot show.
   ============================================================================ */
.cert__grid { display: grid; grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.1fr); gap: clamp(32px, 5vw, 60px); align-items: center; }
.sec--ink .h2, .sec--ink h3 { color: var(--paper); }
.sec--ink .lead { color: var(--steel-200); }
.sec--ink .chip-label { background: rgba(79, 187, 160, .16); color: var(--mint-100); }
.sec--ink .chip-label::before { background: var(--mint-500); }
.cert { background: var(--navy-900); border-radius: var(--r-card); padding: clamp(24px, 3vw, 34px); box-shadow: 0 30px 70px rgba(0, 0, 0, .35); }
.cert__top { display: flex; align-items: flex-end; justify-content: space-between; gap: 16px; margin-bottom: 20px; }
.cert__lot { font-family: var(--f-mono); font-size: clamp(2rem, 1.2rem + 2.6vw, 3.25rem); font-weight: 500; color: var(--mint-500); line-height: 1; letter-spacing: -0.02em; }
.cert__lotk { font-size: 0.75rem; color: var(--steel-300); display: block; margin-bottom: 8px; }
.cert__pick {
  background: rgba(255,255,255,.06); color: var(--paper); border: 1px solid rgba(255,255,255,.18);
  border-radius: var(--r-pill); min-height: 42px; padding: 0 38px 0 16px; font-size: 0.875rem; appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%237FAAC4' stroke-width='1.8'%3E%3Cpath d='M5 9l7 7 7-7'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 14px center; background-size: 15px;
}
.cert__pick option { background: var(--navy-900); color: var(--paper); }
.cert__id { display: flex; align-items: baseline; gap: 14px; flex-wrap: wrap; padding-bottom: 18px; border-bottom: 1px solid rgba(255,255,255,.12); }
.cert__prod { font-size: 1.0625rem; color: var(--paper); font-weight: 500; }
.cert__sku { font-family: var(--f-mono); font-size: 0.8125rem; color: var(--steel-200); }
.cert__rows { display: grid; transition: opacity .2s; }
.cert.is-loading .cert__rows { opacity: .25; }
.cert__row { display: grid; grid-template-columns: minmax(0,1fr) auto 88px; gap: 14px; align-items: baseline; padding: 13px 0; }
.cert__row + .cert__row { border-top: 1px solid rgba(255,255,255,.07); }
.cert__k { font-size: 0.9375rem; color: var(--steel-200); }
.cert__v { font-family: var(--f-mono); font-size: 0.875rem; color: var(--paper); text-align: right; font-variant-numeric: tabular-nums; }
.cert__m { font-family: var(--f-mono); font-size: 0.6875rem; letter-spacing: 0.08em; text-transform: uppercase; color: var(--steel-300); text-align: right; }
.cert__band { margin-top: 20px; background: var(--mint-500); color: var(--navy-990); border-radius: var(--r-pill); min-height: 52px; padding: 12px 22px; display: flex; align-items: center; justify-content: space-between; gap: 14px; flex-wrap: wrap; }
.cert__band b { font-size: 0.8125rem; letter-spacing: 0.1em; text-transform: uppercase; font-family: var(--f-mono); font-weight: 600; }
.cert__band .d { font-family: var(--f-mono); font-size: 0.9375rem; }
.cert__note { margin-top: 14px; font-size: 0.8125rem; color: var(--steel-300); }

/* ============================================================================
   FAQ
   ============================================================================ */
.faq { max-width: 52rem; margin-inline: auto; display: grid; gap: 12px; }
.faq__item { background: var(--paper); border: 1px solid var(--line-300); border-radius: var(--r-field); transition: border-color .2s, box-shadow .2s; }
.faq__item[open] { border-color: transparent; box-shadow: var(--shadow-md); }
.faq__q { display: flex; align-items: center; justify-content: space-between; gap: 18px; padding: 19px 24px; font-size: 1.0625rem; font-weight: 500; color: var(--navy-900); cursor: pointer; list-style: none; }
.faq__q::-webkit-details-marker { display: none; }
.faq__q::after { content: ''; width: 11px; height: 11px; flex: none; border-right: 2px solid var(--ink-3); border-bottom: 2px solid var(--ink-3); transform: rotate(45deg) translate(-2px, -2px); transition: transform .25s var(--ease); }
.faq__item[open] .faq__q::after { transform: rotate(-135deg) translate(-4px, -4px); }
.faq__a { padding: 0 24px 22px; font-size: 0.9688rem; line-height: 1.65; color: var(--ink-2); max-width: 62ch; }

/* ============================================================================
   CTA + FORM
   ============================================================================ */
.cta__grid { display: grid; grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.1fr); gap: clamp(32px, 5vw, 60px); align-items: start; }
.cta__meta { display: grid; gap: 16px; margin-top: 28px; }
.cta__meta div { display: flex; gap: 13px; }
.cta__meta svg { width: 18px; height: 18px; color: var(--mint-700); flex: none; margin-top: 3px; }
.cta__meta p { font-size: 0.9375rem; line-height: 1.55; }
.form { background: var(--paper); border-radius: var(--r-card); padding: clamp(24px, 3vw, 36px); box-shadow: var(--shadow-md); }
/* minmax(0, 1fr), not 1fr. A bare 1fr floors at the column's min-content, and
   an input's min-content is its default intrinsic size, so the two columns
   together measured wider than the card and the fields hung off the right
   edge. The min-width reset on the controls themselves closes the same hole. */
.form__grid { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 18px; }
.field { display: flex; flex-direction: column; gap: 7px; min-width: 0; }
.field input, .field select, .field textarea { width: 100%; min-width: 0; max-width: 100%; }
.field--wide { grid-column: 1 / -1; }
.field label { font-size: 0.8438rem; font-weight: 500; color: var(--ink-2); }
/* Filled, not outlined. A white field inside a white card reads as a floating
   outline rather than something you type into, which is exactly how the first
   cut of this form looked. The tint gives each field a body; focus lifts it to
   paper so the active field is the brightest thing in the card. */
.field input, .field select, .field textarea {
  min-height: 50px; padding: 13px 16px; background: var(--tint-100); color: var(--navy-900);
  border: 1px solid transparent; border-radius: var(--r-field); font-size: 1rem; appearance: none;
  transition: background-color .18s, border-color .18s, box-shadow .18s;
}
.field input:hover, .field select:hover, .field textarea:hover { border-color: var(--line-400); }
.field textarea { min-height: 84px; resize: vertical; }
.field select { padding-right: 40px; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%234E6B82' stroke-width='1.8'%3E%3Cpath d='M5 9l7 7 7-7'/%3E%3C/svg%3E"); background-repeat: no-repeat; background-position: right 14px center; background-size: 16px; }
.field input:focus, .field select:focus, .field textarea:focus { outline: none; background: var(--paper); border-color: var(--mint-700); box-shadow: 0 0 0 4px color-mix(in srgb, var(--mint-500) 20%, transparent); }
/* The brand set contains no red, so the error signal is a 16:1 navy rather than
   an invented hue at 4.5:1. */
.field.is-error input, .field.is-error select, .field.is-error textarea { border-color: var(--navy-900); border-width: 2px; }
.field.is-error label { color: var(--navy-900); font-weight: 600; }
.field__err { font-size: 0.8125rem; font-weight: 500; color: var(--navy-900); min-height: 1.1em; }
.field__help { font-size: 0.8125rem; color: var(--ink-3); }
/* The consent row is a decision, not a field, so it gets its own surface and
   sits tight against the button it gates. */
.consent { grid-column: 1 / -1; display: flex; gap: 12px; align-items: flex-start; padding: 14px 16px; background: var(--tint-100); border-radius: var(--r-field); }
.consent input { width: 19px; height: 19px; margin-top: 2px; flex: none; accent-color: var(--mint-700); border-radius: 5px; }
.consent label { font-size: 0.875rem; line-height: 1.5; color: var(--ink-2); }
.form__foot { margin-top: 22px; display: flex; align-items: center; gap: 16px; flex-wrap: wrap; }
.form__foot .btn { flex: 1 1 auto; }
/* The carried quote list is context for the form, so it belongs above it as a
   readable line, not dangling under the submit button looking like debug output. */
.form__carry { display: flex; align-items: center; gap: 10px; margin-bottom: 20px; padding: 12px 16px; border-radius: var(--r-field); background: color-mix(in srgb, var(--mint-500) 12%, var(--paper)); font-size: 0.9063rem; color: var(--navy-900); }
.form__carry::before { content: ''; width: 8px; height: 8px; border-radius: 50%; background: var(--mint-700); flex: none; }
.form__carry b { font-family: var(--f-mono); font-variant-numeric: tabular-nums; font-weight: 500; }
.form__status { margin-top: 18px; font-size: 0.9375rem; display: none; }
.form__status[data-state] { display: block; color: var(--navy-900); }
.form__status[data-state='err'] { font-weight: 600; }

/* ============================================================================
   FOOTER
   ============================================================================ */
.ftr { background: var(--navy-990); color: var(--steel-200); padding-block: clamp(52px, 6vw, 76px) 30px; }
.ftr__top { display: grid; grid-template-columns: minmax(0, 1.5fr) repeat(3, minmax(0, 1fr)); gap: 36px; padding-bottom: 42px; }
/* The footer ground is navy and so is the logo, so it carries the wordmark
   alone in its light version. A simplified lockup is the normal answer in a
   footer, and it beats sitting the full logo on a white tile. */
.ftr .brand__word { height: 40px; }
.ftr__blurb { margin-top: 16px; font-size: 0.9375rem; line-height: 1.6; max-width: 32ch; }
.ftr__col h2 { font-size: 0.9375rem; color: var(--paper); margin-bottom: 14px; font-weight: 500; }
.ftr__col a { display: block; font-size: 0.9375rem; color: var(--steel-200); margin-bottom: 10px; transition: color .18s; }
.ftr__col a:hover { color: var(--paper); }
.ftr__legal { border-top: 1px solid rgba(255,255,255,.12); padding-top: 24px; font-size: 0.8125rem; line-height: 1.6; color: var(--steel-300); }
.ftr__legal p + p { margin-top: 8px; }

/* ============================================================================
   CATALOGUE PAGE
   ============================================================================ */
.cat-hero { padding-block: clamp(38px, 5vw, 60px) clamp(24px, 3vw, 36px); }
.toolbar { position: sticky; top: var(--head-h); z-index: 60; background: color-mix(in srgb, var(--paper) 94%, transparent); backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px); border-bottom: 1px solid var(--line-300); padding-block: 16px; }
.toolbar__row { display: flex; gap: 12px; align-items: center; flex-wrap: wrap; }
.toolbar .finder__search { margin: 0; flex: 1 1 240px; max-width: none; }
.toolbar .finder__search input { min-height: 50px; }
.toolbar select { min-height: 50px; padding: 0 42px 0 18px; border: 1px solid var(--line-400); border-radius: var(--r-pill); background: var(--paper); font-size: 0.9375rem; color: var(--navy-900); appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%234E6B82' stroke-width='1.8'%3E%3Cpath d='M5 9l7 7 7-7'/%3E%3C/svg%3E"); background-repeat: no-repeat; background-position: right 16px center; background-size: 16px; }
.cat-chips { display: flex; gap: 8px; overflow-x: auto; padding-top: 12px; scrollbar-width: none; }
.cat-chips::-webkit-scrollbar { display: none; }
.cat-chips .chip { flex: none; }
.cat-meta { display: flex; justify-content: space-between; align-items: center; gap: 16px; flex-wrap: wrap; padding-block: 26px 6px; font-size: 0.9375rem; color: var(--ink-3); }
.cat-meta b { color: var(--navy-900); }
.cat-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(248px, 1fr)); gap: 16px; padding-bottom: 96px; }
.pcard__add { margin-top: 12px; align-self: flex-start; display: inline-flex; align-items: center; gap: 7px; padding: 8px 16px; border-radius: var(--r-pill); background: var(--tint-100); font-size: 0.8438rem; font-weight: 600; color: var(--navy-900); transition: background-color .18s, color .18s; }
.pcard__add:hover { background: var(--tint-200); }
.pcard.is-picked { border-color: var(--mint-500); box-shadow: 0 0 0 1px var(--mint-500); }
.pcard.is-picked .pcard__add { background: var(--mint-500); color: var(--navy-990); }
.sk { background: var(--paper); border: 1px solid var(--line-300); border-radius: var(--r-card); padding: 22px; display: grid; gap: 11px; }
.sk i { display: block; height: 12px; border-radius: 6px; background: linear-gradient(90deg, var(--tint-100) 0%, var(--tint-200) 50%, var(--tint-100) 100%); background-size: 300% 100%; animation: shimmer 1.3s linear infinite; }
.sk i:nth-child(1) { width: 40%; } .sk i:nth-child(2) { width: 84%; height: 16px; } .sk i:nth-child(3) { width: 58%; }
@keyframes shimmer { to { background-position: -300% 0; } }

.qfab { position: fixed; right: 20px; bottom: 20px; z-index: 80; display: inline-flex; align-items: center; gap: 10px; min-height: 54px; padding: 0 24px; border-radius: var(--r-pill); background: var(--navy-900); color: var(--paper); font-size: 0.9375rem; font-weight: 600; box-shadow: var(--shadow-md); transform: translateY(140%); transition: transform .4s var(--ease); }
.qfab.is-on { transform: none; }
.qfab .n { font-family: var(--f-mono); background: var(--mint-500); color: var(--navy-990); border-radius: var(--r-pill); padding: 2px 9px; font-variant-numeric: tabular-nums; }
.scrim { position: fixed; inset: 0; z-index: 110; background: rgba(10,32,56,.45); opacity: 0; pointer-events: none; transition: opacity .3s; }
.scrim.is-open { opacity: 1; pointer-events: auto; }
.drawer { position: fixed; inset: 0 0 0 auto; z-index: 120; width: min(440px, 100vw); background: var(--paper); display: flex; flex-direction: column; transform: translateX(100%); transition: transform .38s var(--ease); box-shadow: -20px 0 60px rgba(10,32,56,.16); }
.drawer.is-open { transform: none; }
.drawer__head { display: flex; align-items: center; justify-content: space-between; gap: 16px; padding: 24px 24px 16px; }
.drawer__head h2 { font-size: 1.375rem; }
.drawer__x { width: 40px; height: 40px; border-radius: var(--r-pill); background: var(--tint-100); display: grid; place-items: center; color: var(--ink-2); }
.drawer__x:hover { background: var(--tint-200); color: var(--navy-900); }
.drawer__x svg { width: 17px; height: 17px; }
.drawer__list { flex: 1; overflow-y: auto; padding: 0 24px; }
.ditem { display: flex; align-items: flex-start; gap: 14px; padding: 16px 0; }
.ditem + .ditem { border-top: 1px solid var(--line-300); }
.ditem .info { flex: 1; min-width: 0; }
.ditem .nm { font-size: 0.9375rem; color: var(--navy-900); line-height: 1.35; }
.ditem .sku { font-family: var(--f-mono); font-size: 0.75rem; color: var(--ink-3); margin-top: 3px; }
.qty { display: flex; align-items: center; background: var(--tint-100); border-radius: var(--r-pill); }
.qty button { width: 32px; height: 34px; color: var(--ink-2); font-size: 1.0625rem; line-height: 1; }
.qty button:hover { color: var(--navy-900); }
.qty span { min-width: 28px; text-align: center; font-family: var(--f-mono); font-size: 0.875rem; color: var(--navy-900); }
.ditem .rm { font-size: 0.8125rem; color: var(--ink-3); padding: 4px; }
.ditem .rm:hover { color: var(--navy-900); }
.drawer__empty { padding: 60px 24px; text-align: center; color: var(--ink-3); font-size: 0.9375rem; }
.drawer__foot { padding: 20px 24px max(24px, env(safe-area-inset-bottom)); border-top: 1px solid var(--line-300); display: grid; gap: 10px; }
.drawer__foot .btn { width: 100%; }

/* ---------- Reveal ---------- */
.rv { opacity: 0; transform: translateY(18px); transition: opacity .6s var(--ease), transform .6s var(--ease); transition-delay: var(--d, 0ms); }
.rv.in { opacity: 1; transform: none; }

/* ============================================================================
   RESPONSIVE
   ============================================================================ */
@media (max-width: 1080px) {
  .hero__grid, .std__grid, .cert__grid, .cta__grid { grid-template-columns: 1fr; }
  .hero__badge { left: auto; right: 16px; bottom: 16px; }
  .steps { grid-template-columns: repeat(2, 1fr); }
  .ftr__top { grid-template-columns: 1fr 1fr; }
}
@media (max-width: 900px) {
  .nav { display: none; }
  .burger { display: block; }
  .hdr__end .btn { display: none; }
}
@media (max-width: 640px) {
  :root { --head-h: 68px; }
  .steps { grid-template-columns: 1fr; }
  .form__grid { grid-template-columns: 1fr; }
  .ftr__top { grid-template-columns: 1fr; gap: 30px; }
  .cat-grid { grid-template-columns: 1fr; }

  /* The finder grid becomes a swipeable track. Stacked full-width cards made
     the preview taller than the section it previews; a track shows the same
     eight products in one screen and keeps the thumb where it already is. */
  .pgrid {
    display: flex; gap: 12px;
    overflow-x: auto; overscroll-behavior-x: contain;
    scroll-snap-type: x mandatory; -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
    /* Bleed to the viewport edge so the next card peeks and the swipe is legible. */
    margin-inline: calc(var(--gutter) * -1);
    padding: 2px var(--gutter) 6px;
  }
  .pgrid::-webkit-scrollbar { display: none; }
  .pgrid > .pcard { flex: 0 0 76%; scroll-snap-align: start; }
  /* The last card can never reach the start edge, so it aligns to the end
     instead. Without this the track stops one card short of its own end. */
  .pgrid > .pcard:last-child { scroll-snap-align: end; }
  .pgrid > .finder__empty { flex: 1 0 100%; }
  .ptrack { display: flex; }
  .hero__badge { position: static; margin-top: 14px; box-shadow: var(--shadow-sm); }
  /* The test name takes the full width, then the value and its method sit on
     one line beneath it. Before this the method was auto-placed into a second
     row on its own, floating right with nothing to belong to. */
  .cert__row { grid-template-columns: minmax(0, 1fr) auto; row-gap: 3px; }
  .cert__k { grid-column: 1 / -1; }
  .cert__v { grid-column: 1; text-align: left; }
  .cert__m { grid-column: 2; text-align: right; align-self: baseline; }

  /* A pill is the wrong shape once the content needs two lines: the 999px
     radius eats the corners and crushes the text. On mobile the release
     becomes a stamped block, read top to bottom. */
  .cert__band {
    border-radius: var(--r-field);
    padding: 16px 20px;
    display: grid; gap: 4px; justify-items: start;
  }
  .cert__band .d { font-size: 1.5rem; line-height: 1.1; }
  .cert__band > span:last-child { font-size: 0.8125rem; opacity: .85; }
  .qfab { left: 20px; right: 20px; justify-content: center; }
  .mnav__link { font-size: 1.5rem; }
  .cert__top { flex-direction: column; align-items: flex-start; }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation-duration: .01ms !important; animation-iteration-count: 1 !important; transition-duration: .01ms !important; }
  .rv { opacity: 1; transform: none; }
  .mnav.is-open .mnav__group { animation: none; }
}

/* ============================================================================
   PRICE BANDS. The four bands of the source sheet, named rather than numbered,
   opened from a product image. Built by main.js on first open and reused, so
   there is no dialog in either HTML file.
   ============================================================================ */
.bands { position: fixed; inset: 0; z-index: 220; display: grid; place-items: center; padding: clamp(16px, 4vw, 40px); }
.bands__scrim { position: absolute; inset: 0; background: color-mix(in srgb, var(--navy-990) 46%, transparent); opacity: 0; transition: opacity .22s var(--ease); }
.bands.is-open .bands__scrim { opacity: 1; }
.bands__panel {
  position: relative; width: min(100%, 520px); max-height: 100%; overflow-y: auto;
  padding: clamp(22px, 3vw, 30px); border-radius: var(--r-card);
  background: var(--paper); box-shadow: var(--shadow-md);
  opacity: 0; transform: translateY(10px) scale(.985);
  transition: opacity .22s var(--ease), transform .22s var(--ease);
}
.bands.is-open .bands__panel { opacity: 1; transform: none; }
.bands__x { position: absolute; top: 14px; right: 14px; width: 38px; height: 38px; display: grid; place-items: center; border-radius: 50%; color: var(--ink-2); transition: background-color .18s, color .18s; }
.bands__x:hover { background: var(--tint-100); color: var(--navy-900); }
.bands__x svg { width: 19px; height: 19px; }
.bands__head { display: flex; gap: 16px; align-items: flex-start; padding-right: 34px; }
.bands__shot { flex: none; width: 108px; border-radius: var(--r-field); overflow: hidden; background: var(--tint-100); }
.bands__shot img { width: 100%; aspect-ratio: 4 / 3; object-fit: cover; }
.bands__id { min-width: 0; }
.bands__name { margin: 7px 0 6px; font-size: 1.25rem; line-height: 1.25; }
.bands__meta { font-size: 0.8125rem; color: var(--ink-3); line-height: 1.5; }
.bands__list { margin: 22px 0 0; border-top: 1px solid var(--line-300); }
.bands__row {
  display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 2px 16px;
  align-items: baseline; padding: 13px 0; border-bottom: 1px solid var(--line-300);
}
.bands__k { display: flex; align-items: center; gap: 9px; font-size: 0.9375rem; font-weight: 600; color: var(--navy-900); }
.bands__note { grid-column: 1; font-size: 0.8125rem; color: var(--ink-3); }
.bands__v { grid-column: 2; grid-row: 1 / span 2; display: flex; flex-direction: column; align-items: flex-end; font-size: 1.125rem; font-weight: 600; color: var(--navy-900); }
.bands__v i { font-style: normal; font-family: var(--f-sans); font-size: 0.6875rem; font-weight: 500; letter-spacing: 0.08em; text-transform: uppercase; color: var(--ink-3); }
.bands__v--quote { font-size: 0.875rem; font-weight: 500; color: var(--ink-3); }
.bands__row--quote { grid-template-columns: 1fr; }
.bands__row--quote .bands__k { color: var(--navy-900); }
/* The four dots are the only place a band name carries a colour. They are
   decoration on top of a written label, never the label itself. */
.bands__dot { width: 9px; height: 9px; border-radius: 50%; flex: none; }
.bands__dot--bronze { background: #A9713F; }
.bands__dot--silver { background: #8C9BA5; }
.bands__dot--gold { background: #C2952E; }
.bands__dot--platinum { background: var(--navy-700); }
.bands__foot { margin: 16px 0 20px; font-size: 0.8125rem; line-height: 1.6; color: var(--ink-3); }

@media (max-width: 460px) {
  .bands__head { flex-direction: column; }
  /* Full width, but letterboxed: at 4/3 the photograph pushed the whole
     ladder below the fold on a phone, which is the one thing the dialog
     exists to show. */
  .bands__shot { width: 100%; }
  .bands__shot img { aspect-ratio: 16 / 7; }
}
@media (prefers-reduced-motion: reduce) {
  .bands__scrim, .bands__panel { transition: none; }
}

@media print {
  .hdr, .toolbar, .qfab, .drawer, .scrim, .mnav, .form, .bands { display: none !important; }
  .hero__dial::before, .pcard__cue { display: none !important; }
  body { background: #fff; color: #000; }
  .sec--ink, .ftr, .cert { background: #fff !important; color: #000 !important; }
  .cert__lot, .cert__k, .cert__v, .cert__m, .cert__prod, .cert__sku { color: #000 !important; }
  .cert__band { background: #fff !important; color: #000 !important; border: 2px solid #000; }
}

/* ============================================================================
   ACCESS TABS + LOGIN CHOOSER. The two applications share one section, and
   Login is a chooser because clinical credentials open both portals while
   research credentials open one.
   ============================================================================ */
.atabs {
  display: flex; gap: 6px; background: var(--paper);
  border: 1px solid var(--line-300); border-radius: var(--r-pill);
  padding: 6px; width: max-content; max-width: 100%; overflow-x: auto;
}
.atabs [role="tab"] {
  font: inherit; font-size: 0.9375rem; font-weight: 600; color: var(--ink-3);
  background: transparent; border: 0; border-radius: var(--r-pill);
  padding: 10px 22px; cursor: pointer; white-space: nowrap;
}
.atabs [role="tab"][aria-selected="true"] { background: var(--navy-900); color: #fff; }

.lmodal { position: fixed; inset: 0; z-index: 90; display: grid; place-items: center; padding: 20px; opacity: 0; transition: opacity .25s var(--ease); }
.lmodal.is-open { opacity: 1; }
.lmodal__scrim { position: absolute; inset: 0; background: rgba(6, 18, 32, .55); }
.lmodal__panel {
  position: relative; background: var(--paper); border-radius: var(--r-card);
  box-shadow: 0 30px 70px rgba(0, 0, 0, .35); padding: 30px 28px 22px; width: min(460px, 100%);
}
.lmodal__x {
  position: absolute; top: 14px; right: 14px; width: 36px; height: 36px;
  display: grid; place-items: center; background: transparent; border: 0;
  border-radius: 50%; cursor: pointer; color: var(--ink-3);
}
.lmodal__x:hover { background: var(--tint-100); color: var(--navy-900); }
.lmodal__x svg { width: 18px; height: 18px; }
.lopt {
  display: flex; align-items: center; justify-content: space-between; gap: 14px;
  border: 1px solid var(--line-300); border-radius: var(--r-field);
  padding: 16px 18px; margin-bottom: 12px; color: var(--navy-900); text-decoration: none;
  transition: border-color .18s, background .18s;
}
.lopt:hover, .lopt:focus-visible { border-color: var(--mint-500); background: var(--mint-100); }
.lopt b { display: block; font-size: 1rem; }
.lopt > span > span { display: block; font-size: 0.8125rem; color: var(--ink-3); margin-top: 3px; }
.lopt > svg { width: 18px; height: 18px; flex: none; color: var(--steel); }
.lmodal__foot { font-size: 0.8125rem; color: var(--ink-3); margin-top: 8px; }

/* ============================================================================
   RESEARCHER VERIFICATION GATE. Mismo funel que la referencia del cliente:
   pantalla completa antes de entrar, boton bloqueado hasta confirmar 21+ y rol.
   El select queda nativo a proposito: el gate corre antes que main.js.
   ============================================================================ */
.rgate {
  position: fixed; inset: 0; z-index: 300; overflow-y: auto;
  background: var(--tint-100);
  display: grid; place-items: center; padding: 24px;
  transition: opacity .3s var(--ease);
}
.rgate.is-leaving { opacity: 0; pointer-events: none; }
.rgate__box { width: min(560px, 100%); text-align: center; }
.rgate__logo { width: 190px; height: auto; margin: 0 auto 26px; }
.rgate__card {
  background: var(--paper); border-radius: var(--r-card);
  box-shadow: var(--shadow-md); padding: clamp(26px, 4vw, 40px);
  text-align: left;
}
.rgate__card h1 { font-size: clamp(1.5rem, 1.2rem + 1.2vw, 2rem); margin-bottom: 12px; }
.rgate__intro { font-size: 0.9688rem; color: var(--ink-2); margin-bottom: 22px; }
.rgate__check {
  display: flex; align-items: center; gap: 12px; cursor: pointer;
  border: 1px solid var(--line-300); border-radius: var(--r-field);
  padding: 16px 18px; margin-bottom: 20px; font-size: 1rem; color: var(--navy-900);
}
.rgate__check input { width: 20px; height: 20px; accent-color: var(--mint-700); flex: none; cursor: pointer; }
.rgate__label { display: block; font-size: 0.9375rem; font-weight: 600; color: var(--navy-900); margin-bottom: 8px; }
.rgate__label em { font-style: normal; color: #C0392B; font-weight: 500; }
.rgate select {
  width: 100%; appearance: auto; -webkit-appearance: menulist;
  border: 1px solid var(--line-300); border-radius: var(--r-field);
  padding: 14px 16px; background: var(--paper); color: var(--navy-900);
  font-size: 1rem; margin-bottom: 22px;
}
.rgate select:focus { outline: 2px solid var(--mint-500); outline-offset: 1px; }
.rgate__enter {
  width: 100%; min-height: 54px; border-radius: var(--r-pill);
  background: var(--navy-900); color: var(--paper);
  font-size: 1rem; font-weight: 600;
  transition: background-color .2s var(--ease), opacity .2s;
}
.rgate__enter:hover:not(:disabled) { background: var(--navy-700); }
.rgate__enter:disabled { background: var(--tint-200); color: var(--ink-3); cursor: not-allowed; }
.rgate__exit { text-align: center; margin-top: 16px; font-size: 0.9375rem; color: var(--ink-2); }
.rgate__exit a { color: var(--steel, #2F6C93); text-decoration: underline; }
.rgate__legal { font-size: 0.8125rem; font-style: italic; color: var(--ink-3); margin-top: 20px; text-align: left; }

/* Agotados: tachado y en gris, sin boton de pedido (peticion de Trevor,
   27 ago 2026, estilo peptiumlab). Se marca con "stock": false en products.js;
   sin la clave, el producto esta disponible. */
.pcard.is-oos .pcard__media img { filter: grayscale(1); opacity: .45; }
.pcard.is-oos .pcard__name { text-decoration: line-through; color: var(--ink-3); }
.pcard.is-oos .pcard__price, .pcard.is-oos .pcard__meta, .pcard.is-oos .pcard__cat { opacity: .55; }
.pcard.is-oos .pcard__add:disabled { background: var(--tint-200); color: var(--ink-3); cursor: not-allowed; }

/* ============================================================================
   FICHA DE PRODUCTO  (/product/?sku=...)   prefijo .abp-
   Todo lo de esta seccion es propiedad de /product/index.html.  Prefijo propio
   para no chocar con el catalogo (.pcard, .bands) ni con la home.
   La pieza central es la escalera de SEIS niveles: nombre, banda de volumen y
   precio por vial.  Los numeros los pone window.AionPricing, nunca el HTML.
   ============================================================================ */

.abp-crumbs {
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px;
  padding-block: 18px 0; font-size: 0.8438rem; color: var(--ink-3);
}
.abp-crumbs a { color: var(--ink-2); }
.abp-crumbs a:hover { color: var(--navy-900); text-decoration: underline; }
.abp-crumbs span[aria-current] { color: var(--navy-900); }
.abp-crumbs i { font-style: normal; color: var(--line-400); }

.abp-top { padding-block: clamp(18px, 3vw, 30px) clamp(30px, 4vw, 44px); }
.abp-top__grid {
  display: grid; grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.1fr);
  gap: clamp(24px, 4vw, 52px); align-items: start;
}
.abp-shot {
  border-radius: var(--r-card); overflow: hidden; background: var(--tint-100);
  box-shadow: var(--shadow-sm);
}
.abp-shot img { display: block; width: 100%; aspect-ratio: 4 / 3; object-fit: cover; }
.abp-shot__cue {
  display: block; padding: 10px 16px; font-family: var(--f-mono);
  font-size: 0.6875rem; letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--ink-3); border-top: 1px solid var(--line-300); background: var(--paper);
}
/* El cambio de foto va en un boton y no en el hover: en un telefono no hay
   hover, y la etiqueta con el QR del lote es justo lo que se quiere ver. */
.abp-shot__swap {
  font: inherit; letter-spacing: inherit; text-transform: inherit; color: inherit;
  text-decoration: underline; text-underline-offset: 3px; cursor: pointer;
}
.abp-shot__swap:hover { color: var(--navy-900); }

.abp-id__cat { font-family: var(--f-mono); font-size: 0.6875rem; letter-spacing: 0.1em; text-transform: uppercase; color: var(--mint-700); }
.abp-id__name { font-size: clamp(1.5rem, 1.15rem + 1.5vw, 2.25rem); line-height: 1.15; margin: 10px 0 4px; color: var(--navy-900); }
.abp-id__sub { font-size: 0.9375rem; color: var(--ink-2); }

/* Rango compacto: el mismo string que la tarjeta del catalogo, al centimo. */
.abp-range { margin-top: 22px; padding-top: 20px; border-top: 1px solid var(--line-300); }
.abp-range__k { font-family: var(--f-mono); font-size: 0.6875rem; letter-spacing: 0.1em; text-transform: uppercase; color: var(--ink-3); }
.abp-range__v {
  display: block; margin-top: 8px; font-family: var(--f-mono);
  font-size: clamp(1.5rem, 1.1rem + 1.6vw, 2rem); font-weight: 600;
  color: var(--navy-900); font-variant-numeric: tabular-nums slashed-zero;
}
.abp-range__u { display: block; margin-top: 6px; font-size: 0.8438rem; color: var(--ink-3); }
.abp-range__v--quote { font-size: 1.25rem; color: var(--ink-2); }

/* Los cuatro niveles, junto al vial.  Trevor, 22-sep: "Move the volume pricing
   up beside the vial image. Show all four level prices there. There is no
   second pricing block."  Antes aqui iba el rango compacto (.abp-range) y la
   tabla completa se repetia abajo en .abp-ladder; ahora la tabla vive aqui y
   aquella seccion se retiro.  Se reaprovecha .abp-tbl, solo se aprieta. */
.abp-levels { margin-top: 22px; padding-top: 20px; border-top: 1px solid var(--line-300); }
.abp-levels__k {
  display: block; font-family: var(--f-mono); font-size: 0.6875rem;
  letter-spacing: 0.1em; text-transform: uppercase; color: var(--ink-3);
}
.abp-levels__card {
  margin-top: 12px; border: 1px solid var(--line-300);
  border-radius: var(--r-card); overflow: hidden; background: var(--paper);
}
.abp-levels__u { display: block; margin-top: 10px; font-size: 0.8125rem; color: var(--ink-3); }

.abp-levels .abp-tbl { font-size: 0.875rem; }
.abp-levels .abp-tbl caption { display: none; }
.abp-levels .abp-tbl th, .abp-levels .abp-tbl td { padding: 9px 12px; }
.abp-levels .abp-tbl thead th {
  font-family: var(--f-mono); font-size: 0.625rem; letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--ink-3);
}
.abp-levels .abp-tbl__band { font-size: 0.8125rem; color: var(--ink-2); white-space: nowrap; }
.abp-levels .abp-tbl__price {
  text-align: right; font-family: var(--f-mono); font-weight: 600;
  color: var(--navy-900); font-variant-numeric: tabular-nums slashed-zero;
  white-space: nowrap;
}
.abp-levels .abp-tbl__lvl { display: inline-flex; align-items: center; gap: 7px; font-weight: 600; }
.abp-levels .abp-flags { margin-top: 4px; }

/* En pantalla estrecha la banda de volumen se lleva demasiado sitio: se apila
   bajo el nombre del nivel en vez de pelear por el ancho con el precio. */
@media (max-width: 460px) {
  .abp-levels .abp-tbl__band { font-size: 0.75rem; white-space: normal; }
  .abp-levels .abp-tbl th, .abp-levels .abp-tbl td { padding: 8px 9px; }
}

.abp-meta { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 20px; }
.abp-meta span {
  font-size: 0.75rem; color: var(--ink-3); background: var(--tint-100);
  border-radius: var(--r-pill); padding: 5px 11px;
}
.abp-meta .mono { font-variant-numeric: tabular-nums slashed-zero; }

/* Anadir al pedido.  El pedido vive en el mismo localStorage que el catalogo
   ("ab-order", cantidades en CAJAS), asi que lo que se anada aqui aparece en
   el cajon de /portal/ sin ningun puente. */
.abp-buy { display: flex; flex-wrap: wrap; align-items: center; gap: 12px; margin-top: 24px; }
.abp-qty { display: flex; align-items: center; background: var(--tint-100); border-radius: var(--r-pill); }
.abp-qty button { width: 40px; height: 46px; color: var(--ink-2); font-size: 1.125rem; line-height: 1; }
.abp-qty button:hover { color: var(--navy-900); }
.abp-qty span { min-width: 34px; text-align: center; font-family: var(--f-mono); font-size: 0.9375rem; color: var(--navy-900); font-variant-numeric: tabular-nums; }
.abp-buy__note { flex-basis: 100%; font-size: 0.8125rem; color: var(--ink-3); }
.abp-buy__note a { color: var(--navy-900); font-weight: 600; text-decoration: underline; }

/* Escalera de seis niveles. */
.abp-ladder { padding-block: clamp(34px, 5vw, 56px); background: var(--tint-100); }
.abp-ladder__head { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: 12px; margin-bottom: 18px; }
.abp-ladder__h { font-size: clamp(1.25rem, 1.05rem + 0.8vw, 1.625rem); color: var(--navy-900); }
.abp-ladder__sub { font-size: 0.9063rem; color: var(--ink-2); max-width: 46ch; }

.abp-card { background: var(--paper); border-radius: var(--r-card); box-shadow: var(--shadow-sm); overflow: hidden; }

.abp-tbl { width: 100%; border-collapse: collapse; }
.abp-tbl caption { text-align: left; padding: 18px 22px 0; font-size: 0.8438rem; color: var(--ink-3); }
.abp-tbl th, .abp-tbl td { text-align: left; padding: 14px 22px; border-bottom: 1px solid var(--line-300); vertical-align: middle; }
.abp-tbl thead th {
  font-family: var(--f-mono); font-size: 0.6875rem; letter-spacing: 0.1em;
  text-transform: uppercase; color: var(--ink-3); font-weight: 500;
  border-bottom: 1px solid var(--line-400); white-space: nowrap;
}
.abp-tbl tbody tr:last-child th, .abp-tbl tbody tr:last-child td { border-bottom: 0; }
.abp-tbl__lvl { display: flex; align-items: center; gap: 10px; font-size: 0.9375rem; font-weight: 600; color: var(--navy-900); }
.abp-tbl__band { font-family: var(--f-mono); font-size: 0.875rem; color: var(--ink-2); font-variant-numeric: tabular-nums slashed-zero; white-space: nowrap; }
.abp-tbl__price {
  text-align: right; font-family: var(--f-mono); font-size: 1.0625rem; font-weight: 600;
  color: var(--navy-900); font-variant-numeric: tabular-nums slashed-zero; white-space: nowrap;
}

/* Los puntos son decoracion encima de una etiqueta escrita, nunca la etiqueta:
   el nivel siempre se lee, con color o sin el.  Hay uno por banda de la
   escalera publicada (hoy cuatro: Bronze, Silver, Gold, Platinum).  Si algun
   dia se publica una quinta banda hay que anadir aqui su color; sin regla el
   punto sale transparente, que se ve raro pero no esconde el nombre. */
.abp-dot { width: 9px; height: 9px; border-radius: 50%; flex: none; }
.abp-dot--1 { background: #A9713F; }
.abp-dot--2 { background: #8C9BA5; }
.abp-dot--3 { background: #C2952E; }
.abp-dot--4 { background: var(--navy-700); }

/* Filas marcadas: la del nivel al que transacciona la cuenta y la que alcanza
   el pedido de ahora.  El color no va solo: cada una lleva su etiqueta. */
.abp-tbl tr.is-standing > * { background: color-mix(in srgb, var(--mint-500) 10%, var(--paper)); }
.abp-tbl tr.is-order > * { background: color-mix(in srgb, var(--steel-300) 16%, var(--paper)); }
.abp-tbl tr.is-standing.is-order > * { background: color-mix(in srgb, var(--mint-500) 16%, var(--paper)); }
.abp-flags { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 6px; }
.abp-flag {
  font-family: var(--f-mono); font-size: 0.625rem; letter-spacing: 0.06em;
  text-transform: uppercase; padding: 3px 9px; border-radius: var(--r-pill);
  background: var(--navy-900); color: var(--paper); white-space: nowrap;
}
.abp-flag--standing { background: var(--mint-700); }

/* Estado del pedido de ahora: valor, nivel aplicado y distancia al siguiente.
   Las cifras salen de AionPricing.quoteOrder, el mismo calculo que el cajon. */
.abp-order { margin-top: 16px; display: grid; gap: 10px; }
.abp-order__row {
  display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between;
  gap: 8px 16px; background: var(--paper); border: 1px solid var(--line-300);
  border-radius: var(--r-field); padding: 14px 18px; font-size: 0.9063rem; color: var(--ink-2);
}
.abp-order__row b { color: var(--navy-900); font-weight: 600; }
.abp-order__row .mono { font-variant-numeric: tabular-nums slashed-zero; color: var(--navy-900); }
.abp-order__row--warn { border-color: var(--line-400); background: color-mix(in srgb, var(--steel-300) 10%, var(--paper)); }
.abp-order__row--good { border-color: var(--mint-100); background: color-mix(in srgb, var(--mint-500) 10%, var(--paper)); }

/* Copy de Trevor, literal. */
.abp-copy { padding-block: clamp(34px, 5vw, 56px); }
.abp-copy__grid { display: grid; grid-template-columns: minmax(0, 0.8fr) minmax(0, 1.2fr); gap: clamp(20px, 4vw, 52px); align-items: start; }
.abp-copy__h { font-size: clamp(1.25rem, 1.05rem + 0.8vw, 1.625rem); color: var(--navy-900); }
.abp-copy__body p { font-size: 0.9688rem; line-height: 1.7; color: var(--ink-2); max-width: 62ch; }
.abp-copy__body p + p { margin-top: 16px; }
.abp-copy__min { margin-top: 20px; font-family: var(--f-mono); font-size: 0.8125rem; color: var(--ink-3); }

/* Otras presentaciones del mismo compuesto. */
.abp-sib { padding-bottom: clamp(48px, 6vw, 80px); }
.abp-sib__h { font-size: 1.0625rem; color: var(--navy-900); margin-bottom: 12px; }
.abp-sib__list { display: flex; flex-wrap: wrap; gap: 8px; }
.abp-sib__list a {
  display: inline-flex; align-items: baseline; gap: 8px; padding: 9px 16px;
  border-radius: var(--r-pill); background: var(--paper); border: 1px solid var(--line-300);
  font-size: 0.875rem; color: var(--navy-900); transition: border-color .18s;
}
.abp-sib__list a:hover { border-color: var(--navy-700); }
.abp-sib__list a .mono { font-size: 0.8125rem; color: var(--ink-3); font-variant-numeric: tabular-nums; }

.abp-empty { padding-block: clamp(60px, 9vw, 120px); text-align: center; }
.abp-empty p { color: var(--ink-3); margin: 12px 0 22px; }

@media (max-width: 900px) {
  .abp-top__grid, .abp-copy__grid { grid-template-columns: 1fr; }
  .abp-shot { max-width: 520px; }
}

/* La tabla de seis filas en movil.  No se deja desbordar ni se manda a un
   scroll horizontal: la fila se convierte en bloque, con el nivel y el precio
   en la primera linea y la banda de volumen debajo.  La tabla sigue siendo una
   tabla para el lector de pantalla; solo cambia como se dibuja.  El encabezado
   se oculta porque cada celda ya dice lo que es. */
@media (max-width: 620px) {
  .abp-tbl, .abp-tbl tbody, .abp-tbl tr, .abp-tbl td, .abp-tbl th { display: block; }
  .abp-tbl thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; }
  /* Un table-caption dentro de una tabla ya convertida en bloque se queda en
     una columna de una palabra por linea: tambien pasa a bloque. */
  .abp-tbl caption { display: block; padding: 16px 18px 0; }
  .abp-tbl tbody tr {
    display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 2px 14px;
    padding: 14px 18px; border-bottom: 1px solid var(--line-300);
  }
  .abp-tbl tbody tr:last-child { border-bottom: 0; }
  .abp-tbl tbody th, .abp-tbl tbody td { padding: 0; border: 0; }
  .abp-tbl tbody th { grid-column: 1; grid-row: 1; }
  .abp-tbl__band { grid-column: 1; grid-row: 2; font-size: 0.8125rem; white-space: normal; }
  .abp-tbl__price { grid-column: 2; grid-row: 1 / span 2; align-self: center; font-size: 1rem; }
  /* El fondo de la fila marcada se pinta en la fila, no en las celdas, porque
     en bloque las celdas ya no cubren el ancho. */
  .abp-tbl tr.is-standing > *, .abp-tbl tr.is-order > *, .abp-tbl tr.is-standing.is-order > * { background: none; }
  .abp-tbl tbody tr.is-standing { background: color-mix(in srgb, var(--mint-500) 10%, var(--paper)); }
  .abp-tbl tbody tr.is-order { background: color-mix(in srgb, var(--steel-300) 16%, var(--paper)); }
  .abp-tbl tbody tr.is-standing.is-order { background: color-mix(in srgb, var(--mint-500) 16%, var(--paper)); }
  .abp-buy { gap: 10px; }
  .abp-buy .btn { flex: 1 1 auto; justify-content: center; }
}

/* ============================================================================
   NIVELES POR VOLUMEN (catalogo)
   Sustituye al modelo viejo de cuatro bandas. La tarjeta ya no ensena un
   precio suelto de la primera banda: ensena el RANGO al centimo, del nivel
   mas caro al mas barato, y el panel explica que hace falta para bajarlo.
   Las seis filas del panel las pinta catalog.js desde la escalera viva, nunca
   desde una tabla escrita a mano.
   ============================================================================ */

/* Rango en la tarjeta. Un grado menos de cuerpo que el precio suelto de antes,
   porque son dos cifras y un separador donde habia una: a 1.125rem el rango
   partia la linea en las tarjetas estrechas de la rejilla. */
/* Los cuatro niveles en la tarjeta.  Sustituyen al rango compacto y al boton
   que abria el panel: Trevor, 22-sep, "Show all four level prices there".
   Rejilla de dos columnas para que quepan en la tarjeta sin alargarla; en
   pantalla estrecha pasa a una. El numero de filas lo decide la escalera. */
.pcard__levels {
  display: grid; grid-template-columns: 1fr 1fr; gap: 4px 14px; margin-top: 2px;
}
/* El nivel va en dos lineas: nombre arriba, precio abajo. En una sola linea
   "Bronze" y "Platinum" no caben en media tarjeta y se recortaban. */
.pcard__lv { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.pcard__lvn {
  display: flex; align-items: center; gap: 5px;
  font-weight: 500; font-size: 0.6875rem; color: var(--ink-3);
  letter-spacing: 0.04em; text-transform: uppercase; white-space: nowrap;
}
.pcard__lv em {
  font-style: normal; font-family: var(--f-mono);
  font-size: 0.8125rem; font-weight: 600; color: var(--navy-900);
  font-variant-numeric: tabular-nums slashed-zero; white-space: nowrap;
}
.pcard__unit {
  display: block; margin-top: 7px; font-size: 0.6875rem; font-weight: 500;
  letter-spacing: 0.08em; text-transform: uppercase; color: var(--mint-700);
}
.pcard.is-oos .pcard__levels, .pcard.is-oos .pcard__unit { opacity: .55; }
@media (max-width: 420px) {
  .pcard__levels { grid-template-columns: 1fr; }
}

.pcard__price--range { font-size: 1rem; flex-wrap: wrap; gap: 4px 8px; }
.pcard__price--range i { flex: none; }
.pcard__vp {
  align-self: flex-start; margin-top: -2px;
  font-size: 0.75rem; font-weight: 500; color: var(--ink-3);
  text-align: left; text-decoration: underline; text-underline-offset: 3px;
  text-decoration-color: var(--line-400);
  transition: color .18s, text-decoration-color .18s;
}
.pcard__vp:hover { color: var(--navy-900); text-decoration-color: var(--navy-900); }
.pcard.is-oos .pcard__vp { opacity: .55; }

/* Accesos al panel: barra de resultados y cajon del pedido. */
.cat-meta__acts { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.vpbtn {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 9px 16px; border-radius: var(--r-pill);
  background: var(--tint-100); border: 1px solid transparent;
  font-size: 0.875rem; font-weight: 600; color: var(--navy-900);
  transition: background-color .18s, border-color .18s;
}
.vpbtn::before { content: ''; width: 6px; height: 6px; border-radius: 50%; background: var(--mint-700); flex: none; }
.vpbtn:hover { background: var(--paper); border-color: var(--navy-900); }

/* El panel. z-index por encima del cajon (120) porque se abre desde el. */
.vp { position: fixed; inset: 0; z-index: 230; display: grid; place-items: center; padding: clamp(16px, 4vw, 40px); }
.vp__scrim { position: absolute; inset: 0; background: color-mix(in srgb, var(--navy-990) 46%, transparent); opacity: 0; transition: opacity .22s var(--ease); }
.vp.is-open .vp__scrim { opacity: 1; }
.vp__panel {
  position: relative; width: min(100%, 560px); max-height: 100%; overflow-y: auto;
  padding: clamp(22px, 3vw, 30px); border-radius: var(--r-card);
  background: var(--paper); box-shadow: var(--shadow-md);
  opacity: 0; transform: translateY(10px) scale(.985);
  transition: opacity .22s var(--ease), transform .22s var(--ease);
}
.vp.is-open .vp__panel { opacity: 1; transform: none; }
.vp__x { position: absolute; top: 14px; right: 14px; width: 38px; height: 38px; display: grid; place-items: center; border-radius: 50%; color: var(--ink-2); transition: background-color .18s, color .18s; }
.vp__x:hover { background: var(--tint-100); color: var(--navy-900); }
.vp__x svg { width: 19px; height: 19px; }
.vp__h { font-size: 1.375rem; line-height: 1.2; padding-right: 40px; }
.vp__min { margin-top: 8px; font-size: 0.875rem; color: var(--ink-3); }

/* Ventana de opciones del pedido (Trevor, 22-sep). Reutiliza el armazon de
   .vp (scrim, panel, cierre) y solo anade los controles, que .vp no tenia. */
.oo__body { margin-top: 20px; display: grid; gap: 16px; }
.oo__check {
  display: flex; align-items: flex-start; gap: 11px; cursor: pointer;
  padding: 13px 14px; border: 1px solid var(--line-300); border-radius: var(--r-card);
  background: var(--tint-100); transition: border-color .18s, background-color .18s;
}
.oo__check:hover { border-color: var(--line-400); }
.oo__check:has(input:checked) {
  border-color: var(--mint-500);
  background: color-mix(in srgb, var(--mint-500) 8%, var(--paper));
}
.oo__check input { margin-top: 2px; width: 17px; height: 17px; flex: none; accent-color: var(--navy-700); }
.oo__check span { font-size: 0.9063rem; line-height: 1.45; color: var(--navy-900); }
.oo__field { display: grid; gap: 6px; }
.oo__field label {
  font-family: var(--f-mono); font-size: 0.6875rem; letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--ink-3);
}
.oo__field select {
  width: 100%; padding: 11px 13px; font-size: 0.9375rem; color: var(--navy-900);
  border: 1px solid var(--line-300); border-radius: var(--r-input, 10px);
  background: var(--paper);
}
.oo__field select:focus-visible { outline: 2px solid var(--navy-700); outline-offset: 1px; }

.vp__list { margin: 20px 0 0; }
.vp__row {
  display: grid; grid-template-columns: 1fr auto; gap: 2px 16px;
  align-items: center; padding: 12px 14px; border-radius: var(--r-field);
  border: 1px solid transparent;
}
.vp__row + .vp__row { margin-top: 2px; }
.vp__row:nth-child(odd) { background: var(--tint-100); }
.vp__name { grid-column: 1; grid-row: 1; font-size: 0.9375rem; font-weight: 600; color: var(--navy-900); }
.vp__range { grid-column: 1; grid-row: 2; font-size: 0.8125rem; color: var(--ink-3); }
/* Sin nombres de nivel el rango en dolares es el titulo de la fila. */
.vp__list--noname .vp__range { grid-row: 1; font-size: 0.9375rem; font-weight: 600; color: var(--navy-900); }
.vp__tag {
  grid-column: 1; justify-self: start; margin-top: 6px;
  padding: 3px 10px; border-radius: var(--r-pill);
  background: var(--mint-100); color: var(--navy-900);
  font-size: 0.6875rem; font-weight: 600; letter-spacing: 0.04em;
}
/* La fila del nivel que la cuenta tiene ganado, y la del que gana el pedido
   que hay ahora mismo en el cajon. El borde es decoracion sobre una etiqueta
   escrita, nunca la etiqueta: sin sesion no se marca ninguna. */
.vp__row.is-standing { background: var(--paper); border-color: var(--mint-500); box-shadow: 0 0 0 1px var(--mint-500); }
.vp__row.is-order { background: var(--paper); border-color: var(--navy-700); box-shadow: 0 0 0 1px var(--navy-700); }
.vp__row.is-order .vp__tag { background: var(--tint-200); }
.vp__row--note { grid-template-columns: 1fr; font-size: 0.875rem; color: var(--ink-3); }

/* La misma marca, sobre la tabla "Volume pricing" que ya trae la pagina del
   catalogo: catalog.js le anade la clase y la etiqueta cuando hay sesion, sin
   tocar las cifras que pinta la propia pagina. */
.vp-mark--standing .vp-name, .vp-mark--standing .vp-range { color: var(--navy-900); font-weight: 600; }
.vp-mark--standing .vp-range, .vp-mark--order .vp-range { white-space: normal; }
.vp-mark__tag {
  display: inline-block; margin-left: 10px;
  padding: 2px 9px; border-radius: var(--r-pill);
  background: var(--mint-100); color: var(--navy-900);
  font-family: var(--f-sans); font-size: 0.6875rem; font-weight: 600; letter-spacing: 0.04em;
}
.vp-mark--order .vp-mark__tag { background: var(--tint-200); }

.vp__copy { margin: 22px 0 20px; border-top: 1px solid var(--line-300); padding-top: 18px; }
.vp__copy p { font-size: 0.8125rem; line-height: 1.65; color: var(--ink-3); }
.vp__copy p + p { margin-top: 12px; }

@media (prefers-reduced-motion: reduce) {
  .vp__scrim, .vp__panel { transition: none; }
}
@media print {
  .vp { display: none !important; }
}

/* ---------- Certificados de analisis (/coa/) ----------
   Punto 4 de la lista de Trevor, 23-sep-2026. Modelado sobre la pagina de
   DirectPeptides que el paso como referencia, pero con los tokens de la casa:
   nada de azules prestados. Una tarjeta por FAMILIA de producto; las dosis son
   chips y los lotes botones. La ventana de "todos los lotes" reutiliza el
   componente .vp que ya usa el pop-up de opciones de pedido. */
.coa-bar { display: flex; flex-wrap: wrap; gap: 14px 24px; align-items: center; justify-content: space-between; margin: 0 0 26px; }
.coa-search { position: relative; flex: 1 1 320px; max-width: 460px; }
.coa-search svg { position: absolute; left: 14px; top: 50%; transform: translateY(-50%); width: 18px; height: 18px; color: var(--ink-3); pointer-events: none; }
.coa-search input { width: 100%; padding: 12px 16px 12px 42px; border: 1px solid var(--line-400); border-radius: var(--r-pill); background: var(--paper); font: inherit; color: var(--navy-900); }
.coa-search input:focus-visible { outline: 2px solid var(--mint-700); outline-offset: 1px; border-color: var(--mint-700); }
.coa-count { color: var(--ink-3); font-size: .875rem; }

.coa-list { display: grid; gap: 12px; }
.coa-card { border: 1px solid var(--line-300); border-radius: var(--r-card); background: var(--paper); padding: 20px; }
.coa-card[hidden] { display: none; }
.coa-pills { display: flex; gap: 8px; margin: 0 0 14px; }
.coa-pill { font-size: .6875rem; font-weight: 500; padding: 4px 11px; border-radius: var(--r-pill); border: 1px solid var(--line-400); background: var(--paper); color: var(--ink-3); transition: background-color .18s, color .18s, border-color .18s; }
.coa-pill[aria-pressed="true"] { background: color-mix(in srgb, var(--mint-500) 12%, transparent); border-color: var(--mint-700); color: var(--mint-700); }
.coa-body { display: grid; grid-template-columns: 64px 1fr auto; gap: 14px 18px; align-items: start; }
.coa-thumb { width: 64px; height: 64px; border-radius: var(--r-field); background: var(--tint-100); object-fit: cover; grid-row: span 2; }
.coa-lab { display: block; font-size: .625rem; font-weight: 600; letter-spacing: .04em; text-transform: uppercase; color: var(--ink-3); margin: 0 0 4px; }
.coa-name { font-size: .9375rem; font-weight: 700; color: var(--navy-900); }
.coa-doses { justify-self: end; text-align: right; }
.coa-chips { display: flex; flex-wrap: wrap; gap: 6px; justify-content: flex-end; }
.coa-chip { font-size: .75rem; padding: 4px 11px; border-radius: var(--r-pill); border: 1px solid var(--line-400); background: var(--paper); color: var(--ink-3); }
.coa-chip[aria-pressed="true"] { border-color: var(--mint-700); color: var(--mint-700); font-weight: 600; }
.coa-lots-wrap { grid-column: 2 / -1; }
.coa-lots { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.coa-lot { font-family: var(--f-mono); font-size: .75rem; padding: 6px 14px; border-radius: var(--r-pill); background: var(--navy-900); color: #fff; transition: background-color .18s; }
.coa-lot:hover { background: var(--navy-700); }
.coa-lot--none { background: var(--tint-200); color: var(--ink-3); cursor: not-allowed; }
.coa-empty { font-size: .8125rem; color: var(--ink-3); }
.coa-all { grid-column: 2 / -1; justify-self: start; font-size: .75rem; font-weight: 600; padding: 6px 14px; border-radius: var(--r-pill); border: 1px solid var(--line-300); background: var(--paper); color: var(--ink-3); }
.coa-all:hover { background: var(--tint-100); color: var(--navy-900); }
.coa-none { color: var(--ink-3); padding: 28px 0; }

/* La ventana de todos los lotes. Panel mas ancho que el de opciones de pedido
   porque aqui hay una lista larga, y la cabecera de cada dosis se queda pegada
   arriba al hacer scroll, que es lo unico que se copia tal cual de la referencia. */
.coa-vp .vp__panel { width: min(100%, 640px); }
.coa-grp + .coa-grp { margin-top: 22px; }
.coa-grp__dose { position: sticky; top: 0; z-index: 1; background: var(--paper); padding: 8px 0; font-size: .875rem; font-weight: 600; color: var(--navy-900); display: flex; justify-content: space-between; align-items: baseline; gap: 12px; }
.coa-grp__n { font-size: .75rem; font-weight: 400; color: var(--ink-3); }
.coa-row { display: flex; justify-content: space-between; align-items: center; gap: 14px; padding: 11px 0; border-top: 1px solid var(--line-300); }
.coa-row__lot { font-family: var(--f-mono); font-size: .875rem; color: var(--navy-900); }
.coa-row__date { font-size: .75rem; color: var(--ink-3); }
.coa-certs { display: flex; gap: 8px; flex-shrink: 0; }

@media (max-width: 640px) {
  .coa-body { grid-template-columns: 52px 1fr; }
  .coa-thumb { width: 52px; height: 52px; grid-row: span 1; }
  .coa-doses { grid-column: 1 / -1; justify-self: start; text-align: left; }
  .coa-chips { justify-content: flex-start; }
  .coa-lots-wrap, .coa-all { grid-column: 1 / -1; }
}
/* Un informe superado por otro mas reciente: sigue accesible pero no compite
   visualmente con el vigente. */
.coa-lot--old { background: var(--tint-200); color: var(--ink-3); }
.coa-lot--old:hover { background: var(--line-300); color: var(--navy-900); }
