/* ==== font fallback metrics (fix_font_shift.py) ==== */
@font-face{font-family:"Fraunces Fallback";src:local("Georgia");font-weight:400;size-adjust:105.95%;ascent-override:92.30%;descent-override:24.07%;line-gap-override:0.00%}
@font-face{font-family:"Fraunces Fallback";src:local("Georgia Bold");font-weight:600 900;size-adjust:96.71%;ascent-override:101.13%;descent-override:26.37%;line-gap-override:0.00%}
@font-face{font-family:"Figtree Fallback";src:local("Arial");font-weight:400;size-adjust:101.52%;ascent-override:93.58%;descent-override:24.63%;line-gap-override:0.00%}
@font-face{font-family:"Figtree Fallback";src:local("Arial Bold");font-weight:600 900;size-adjust:96.56%;ascent-override:98.39%;descent-override:25.89%;line-gap-override:0.00%}
@font-face{font-family:"IBM Plex Mono Fallback";src:local("Arial");font-weight:400;size-adjust:134.24%;ascent-override:76.36%;descent-override:20.49%;line-gap-override:0.00%}
@font-face{font-family:"IBM Plex Mono Fallback";src:local("Arial Bold");font-weight:600 900;size-adjust:123.96%;ascent-override:82.69%;descent-override:22.18%;line-gap-override:0.00%}
/* ==== end font fallback metrics ==== */
/* Sodaboostshop - deep navy, gold foil, one cream counterpoint.

   Cool porcelain, deep plum, one copper. This is
   a PREMIUM dark system, not a technical one: the weight sits in large
   photography, gold hairlines, a display serif, and wide letter-spaced small
   caps. A cream band opens the page up every few screens so the navy never
   runs more than one idea long.

   Colour carries meaning in exactly three places - the one printed amount, the
   bounds, and the ingredients no source speaks to - and those three hues are
   validated against this navy surface. Everything else is ink, gold or cream. */

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

/* ---------- tokens ---------- */
:root{
  /* ink on cool near-white */
  --ink:#111820; --ink-2:#46525F; --ink-3:#5F6B78;
  --bg:#FBFCFD; --bg-2:#EEF2F6; --surface:#FFFFFF; --tint:#E9F0F8; --pink:#E9F0F8;
  --line:#D8E0E8; --rule:#E7ECF1;
  /* ink blue takes WHITE text. Every value was computed against the surface
     it actually sits on, and check.py recomputes the whole table on build. */
  --accent:#1B4F8F; --accent-fill:#1B4F8F; --accent-mid:#143C6E;
  --accent-deep:#0C2544; --accent-2:#A8431A;
  /* the DARK counterpoint band */
  --dark:#0C1A2B; --dark-ink:#F1F5F9; --dark-ink-2:#BAC7D4;
  --dark-ink-3:#93A2B2; --dark-accent:#7FC2F5; --dark-line:#1E3147;
  --warn:#8A3A06; --warn-bg:#FBEFE4; --warn-line:#E8C9A6;
  /* the three categories on THIS panel: the line checks out, there is no
     Daily Value to check it against, or it does not check out */
  --cat-checks:#128060; --cat-nodv:#2563A8; --cat-fails:#A8431A;
  --cat-checks-t:#0F6B51; --cat-nodv-t:#1B4F8F; --cat-fails-t:#8F3714;
  --foil:linear-gradient(118deg,#23619F 0%,#1B4F8F 46%,#143C6E 100%);
  /* ink on porcelain */
  /* plum takes WHITE text. Every value here was computed against the surface
     it actually sits on, and check.py recomputes the whole table on build. */
  /* the DARK counterpoint band: the summary block, the CTA and the footer */
  /* mark colours, validated for this porcelain surface */
  /* gold takes DARK text, always. White on gold is 2.25:1 and is never used. */
  /* The accent gradient. Site 12's was a five-stop gold foil; this one is a
     plum that darkens left to right, which is what a flat colour cannot do
     and what keeps a filled button from looking like a rectangle of paint. */
  /* the CREAM counterpoint: the summary block, the CTA panel and the footer rail */
  /* mark colours, validated for this navy surface */
  /* lighter steps of the same three hues, for 11.5px type where 4.5:1 applies */
  /* Radii opened up from 6px. The crest read as severe rather than premium:
     a 6px corner with no shadow is the look of a 2014 enterprise table, and
     that is the single biggest reason this skin read as dated. */
  --radius:14px; --radius-sm:10px; --radius-xs:7px; --pill:999px;
  /* a real elevation scale: a tight contact shadow plus a wide soft one, so
     a raised surface reads as lifted rather than as outlined */
  --sh-1:0 1px 2px rgba(23,22,28,.07), 0 4px 12px -6px rgba(23,22,28,.16);
  --sh-2:0 2px 4px rgba(23,22,28,.08), 0 14px 34px -14px rgba(23,22,28,.20);
  --sh-3:0 4px 10px rgba(23,22,28,.10), 0 34px 70px -24px rgba(23,22,28,.26);
  --shadow:var(--sh-2);
  --lift:var(--sh-3);
  --glow:0 8px 26px -8px rgba(27,79,143,.30);
  /* the inner top highlight that makes a surface look lit from above */
  --ring:inset 0 1px 0 rgba(255,255,255,.80);
  --ring-gold:inset 0 1px 0 rgba(255,255,255,.26);
  /* surface gradients: every panel is lit, none is a flat fill */
  --grad-card:linear-gradient(176deg,#FFFFFF 0%,#FDFEFF 62%,#F8FBFD 100%);
  --grad-tint:linear-gradient(176deg,#EFF5FB 0%,#E7EEF6 100%);
  --grad-bg2:linear-gradient(180deg,#F2F6FA 0%,#EAEFF5 100%);
  --grad-rule:linear-gradient(90deg,transparent,rgba(27,79,143,.42) 18%,
    rgba(27,79,143,.42) 82%,transparent);
  --grad-aurora:radial-gradient(640px 420px at 14% 0%, rgba(27,79,143,.07), transparent 70%),
    radial-gradient(560px 380px at 88% 12%, rgba(168,67,26,.05), transparent 68%);
  --s1:.5rem; --s2:.875rem; --s3:1.25rem; --s4:2rem; --s5:3rem; --s6:4.5rem;
  --ease:cubic-bezier(.16,1,.3,1);
  --t-hover:160ms; --t-ui:300ms; --t-reveal:700ms;
  --wrap:1220px; --text:720px; --wide:980px;
  --display:"Fraunces","Fraunces Fallback",Georgia,"Times New Roman",serif;
  --sans:"Figtree","Figtree Fallback",system-ui,-apple-system,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;
  --mono:"IBM Plex Mono","IBM Plex Mono Fallback",ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;
  --head-h:74px; --w:1; --mx:50%; --my:0%;
}



/* ---------- base ---------- */
html{-webkit-text-size-adjust:100%;overflow-x:clip;
  scroll-padding-top:calc(var(--head-h) + 1.25rem);scroll-padding-bottom:7.5rem}
body{margin:0;overflow-x:clip;background:var(--bg);color:var(--ink-2);
  font:400 17px/1.72 var(--sans);-webkit-font-smoothing:antialiased}
h1,h2,h3{color:var(--ink);font-family:var(--display);font-weight:600;line-height:1.14;
  letter-spacing:-.016em;margin:0 0 .7rem}
h1{font-size:clamp(1.95rem,3.4vw,3rem);letter-spacing:-.022em;font-weight:600}
h2{font-size:clamp(1.5rem,2.5vw,2.15rem);letter-spacing:-.018em;font-weight:600}
h3{font-size:1.16rem;line-height:1.32;letter-spacing:-.016em}
.h3{font-size:1.16rem;line-height:1.32;font-family:var(--display);font-weight:600;
  color:var(--ink);margin:0 0 .5rem;letter-spacing:-.014em}
p{margin:0 0 1.1rem}
a{color:var(--accent);text-underline-offset:3px;text-decoration-thickness:1px}
a:hover{color:#8FEBCC}
img{max-width:100%;height:auto;display:block}
.wrap{width:min(100% - 3rem,var(--wrap));margin-inline:auto}
.mid{width:min(100% - 3rem,var(--wide));margin-inline:auto}
.sr{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;
  clip:rect(0 0 0 0);white-space:nowrap;border:0}
.skip{position:absolute;left:1rem;top:.5rem;z-index:200;background:var(--accent-fill);color:var(--bg);
  padding:.75rem 1.2rem;border-radius:var(--radius);text-decoration:none;font-weight:700;
  transform:translateY(-200%);transition:transform var(--t-ui) var(--ease)}
.skip:focus{transform:none}
:focus-visible{outline:2px solid var(--accent);outline-offset:3px;border-radius:2px}
/* The page ground is dark and the counterpoint is light, so this is the
   reverse of the last ten sites: the default --accent ring belongs to the dark
   ground, and the LIGHT surfaces are the ones that need an override. */
.band-dark :focus-visible,.shot :focus-visible{outline-color:var(--dark-accent)}
.no{color:var(--ink-3);font-style:italic}
.lede{font-size:clamp(1.04rem,1.5vw,1.2rem);line-height:1.64;color:var(--ink-2);
  max-width:64ch;margin:0 0 1.2rem}
.disc{font-size:14.5px;line-height:1.68;color:var(--ink-3)}
.disc a,.note a,.foot a{overflow-wrap:anywhere}
a[href^="mailto:"],a[href^="http"]{overflow-wrap:anywhere}
td,th,li,p{overflow-wrap:break-word}
/* ---------- top strip ---------- */
.strip{background:var(--bg-2);color:var(--ink-2);border-bottom:2px solid var(--accent-fill)}
.strip .wrap{display:flex;gap:.45rem 1.4rem;align-items:center;justify-content:center;
  flex-wrap:wrap;padding:.55rem 0;text-align:center;
  font:600 12px/1.4 var(--sans);letter-spacing:.06em;text-transform:uppercase}
.strip b{color:var(--accent);font-weight:600}
.strip a{color:var(--ink);text-decoration:none;font-weight:600;
  display:inline-block;padding-block:.95rem;min-height:44px;box-sizing:border-box}
.strip a:hover{color:var(--accent)}
.strip .dot{width:4px;height:4px;border-radius:var(--pill);background:var(--line);flex:none}

/* ---------- header ---------- */
.head{position:sticky;top:0;z-index:90;background:rgba(251,252,253,.88);
  backdrop-filter:saturate(1.35) blur(14px);border-bottom:1px solid var(--rule);
  transition:transform var(--t-ui) var(--ease),box-shadow var(--t-ui) var(--ease)}
/* once the page has moved under it the bar earns a shadow; at the top it has
   nothing to sit above and a shadow there just looks like a mistake */
.head--float{box-shadow:0 1px 0 rgba(232,181,92,.14), 0 14px 34px -20px rgba(0,0,0,.6)}
.head--hide{transform:translateY(-108%)}
.head .wrap{display:flex;align-items:center;gap:1.1rem;min-height:var(--head-h)}
.brand{display:flex;align-items:center;gap:.7rem;text-decoration:none;color:var(--ink);
  flex:0 1 auto;min-width:0}
/* the wordmark is the one thing in the bar that can give way; without
   min-width:0 a flex item refuses to shrink below its content and pushes
   the menu button off the right edge at 360px. */
.brand .nm{min-width:0;overflow:hidden}
.brand .mark{width:42px;height:42px;flex:none;display:grid;place-items:center;
  border-radius:3px;background:var(--foil);color:#fff;
  box-shadow:0 4px 14px -6px rgba(217,164,65,.6)}
.brand .mark svg{width:24px;height:24px}
.brand .nm{font:700 19px/1.05 var(--display);letter-spacing:-.022em;font-stretch:112%}
.brand .nm small{display:block;font:500 9.5px/1.4 var(--sans);letter-spacing:.11em;
  text-transform:uppercase;color:var(--ink-3);margin-top:3px}
.nav{margin-left:auto;display:flex;align-items:center;gap:.05rem;flex-wrap:nowrap;min-width:0}
.nav a{color:var(--ink-2);text-decoration:none;font-size:14px;font-weight:600;
  padding:.5rem .68rem;border-radius:var(--radius-sm);white-space:nowrap;position:relative;
  transition:color var(--t-hover) var(--ease),background var(--t-hover) var(--ease)}
.nav a:hover{color:var(--ink);background:var(--bg-2)}
.nav a[aria-current=page]{color:var(--accent);background:var(--tint)}
.head .tel{font:600 14px/1 var(--sans);color:var(--ink);text-decoration:none;
  white-space:nowrap;flex:none}
.head .tel:hover{color:var(--accent)}
.burger{display:none;width:46px;height:46px;border:1px solid var(--line);background:var(--surface);
  border-radius:14px;cursor:pointer;place-items:center;flex:none;box-shadow:var(--shadow)}
.burger span{display:block;width:18px;height:2px;background:var(--ink);position:relative}
.burger span::before,.burger span::after{content:"";position:absolute;left:0;width:18px;height:2px;
  background:var(--ink)}
.burger span::before{top:-6px}.burger span::after{top:6px}
.drawer{display:none}

/* ---------- buttons: pill-cut, lit from above, with a sheen on hover -------
   A button is the one element a visitor is meant to want to press, so it gets
   the full treatment: a gradient fill rather than a flat one, an inner top
   highlight so it reads as a raised object, a soft coloured shadow under it,
   a sheen that sweeps across on hover, and a real press state. All of it is
   transform / opacity / box-shadow, so none of it costs a layout. */
.btn{position:relative;isolation:isolate;overflow:hidden;
  display:inline-flex;align-items:center;justify-content:center;gap:.6rem;
  font:700 13px/1 var(--sans);letter-spacing:.09em;text-transform:uppercase;
  padding:1.1rem 1.9rem;border-radius:var(--pill);text-decoration:none;
  border:1px solid transparent;cursor:pointer;text-align:center;
  transition:transform var(--t-hover) var(--ease),box-shadow var(--t-hover) var(--ease),
    background var(--t-hover) var(--ease),color var(--t-hover) var(--ease),
    border-color var(--t-hover) var(--ease)}
/* the sheen: one pass of a soft white band, left to right, on hover only */
@media (hover:hover) and (pointer:fine){
  .btn::before{content:"";position:absolute;inset:0;z-index:-1;border-radius:inherit;
    background:linear-gradient(105deg,transparent 30%,rgba(255,255,255,.34) 48%,transparent 66%);
    translate:-130% 0;transition:translate 620ms var(--ease)}
  .btn:hover::before{translate:130% 0}
}
.btn:active{transform:translateY(1px) scale(.995)}
.btn::after{content:"";width:14px;height:8px;flex:none;
  background:currentColor;
  -webkit-mask:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 14 8'><path d='M0 4h11M8 1l3 3-3 3' fill='none' stroke='black' stroke-width='1.6'/></svg>") no-repeat center/contain;
  mask:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 14 8'><path d='M0 4h11M8 1l3 3-3 3' fill='none' stroke='black' stroke-width='1.6'/></svg>") no-repeat center/contain;
  transition:translate var(--t-hover) var(--ease)}
.btn:hover::after{translate:3px 0}
/* gold takes DARK text. White on this gold is 2.25:1 and never appears. */
.btn.btn--primary{background:var(--foil);color:#fff;
  box-shadow:var(--glow),var(--ring-gold)}
.btn.btn--primary:hover{transform:translateY(-2px);color:#fff;
  box-shadow:0 14px 38px -10px rgba(217,164,65,.58),var(--ring-gold)}
.btn.btn--ghost{background:var(--grad-card);color:var(--ink);border-color:var(--line);
  box-shadow:var(--sh-1),var(--ring)}
.btn.btn--ghost:hover{transform:translateY(-2px);border-color:var(--accent);color:var(--accent);
  box-shadow:var(--sh-2),var(--ring)}
.btn.btn--onDark{background:var(--bg);color:var(--accent);
  box-shadow:var(--sh-1);border-color:var(--accent-deep)}
.btn.btn--onDark:hover{transform:translateY(-2px);background:var(--foil);color:#fff;
  border-color:transparent;box-shadow:var(--glow),var(--ring-gold)}
.btn.btn--wide{width:100%}

/* ---------- breadcrumb, keep reading, progress ---------- */
.crumb{font:500 13px/1.5 var(--sans);color:var(--ink-3);padding:1.4rem 0 0}
.crumb ol{list-style:none;display:flex;gap:.45rem;flex-wrap:wrap;margin:0;padding:0}
.crumb li::after{content:"/";margin-left:.45rem;color:var(--line)}
.crumb li:last-child::after{content:""}
.crumb a{color:var(--ink-3);text-decoration:none}
.crumb a:hover{color:var(--accent)}
.kr a{text-decoration:none;color:inherit}
.kr .card h3{color:var(--accent)}
.progress{position:fixed;left:0;top:0;height:3px;z-index:120;width:100%;transform-origin:left;
  transform:scaleX(0);background:var(--accent-fill);transition:transform .12s linear}

/* ---------- sticky buy bar ---------- */
/* :focus-within brings it back. It is position:fixed, so when the keyboard
   reaches the button while the bar is translated away the browser cannot
   scroll it into view - focus simply vanishes for one stop, on the primary
   call to action. */
.buybar:focus-within{transform:none!important}
.buybar{position:fixed;left:0;right:0;bottom:0;z-index:100;
  background:rgba(255,255,255,.94);backdrop-filter:saturate(1.3) blur(14px);
  border-top:1px solid var(--rule);color:var(--ink-2);
  box-shadow:0 -10px 40px -20px rgba(20,32,29,.35);
  transform:translateY(105%);transition:transform var(--t-ui) var(--ease)}
.buybar--on{transform:none}
.buybar .wrap{display:flex;align-items:center;justify-content:space-between;gap:1rem;
  padding:.8rem 0;flex-wrap:wrap}
.buybar__txt{display:grid;gap:.15rem;font-size:14px}
.buybar__txt b{color:var(--ink);font-size:15.5px}
.buybar .btn{padding:.85rem 1.5rem;font-size:13px}

/* ---------- section progress nav ---------- */
.secnav{display:flex;gap:.3rem;flex-wrap:wrap;padding:.3rem;border-radius:var(--radius);
  background:var(--surface);border:1px solid var(--line);margin:0 auto 2.2rem;
  width:fit-content;max-width:100%;list-style:none;box-shadow:var(--shadow)}
.secnav a{display:block;padding:.55rem .95rem;border-radius:var(--radius-sm);
  text-decoration:none;font:600 13px/1 var(--sans);color:var(--ink-3);white-space:nowrap;
  transition:color var(--t-hover) var(--ease),background var(--t-hover) var(--ease)}
.secnav a:hover{color:var(--ink);background:var(--tint)}
.secnav a.is-on{color:var(--bg);background:var(--accent-fill)}
/* .secnav--sticky is deliberately NOT position:sticky. Its parent is a
   section wrapper only a little taller than the bar, so a sticky bar there
   travels a few pixels and stops - it reads as a bug, not a feature. The
   index rail is the thing that stays on screen on this site. */
.secnav--sticky{z-index:60;background:var(--bg)}

/* ---------- section headings ---------- */
.sec-head{max-width:70ch;margin:0 0 2.1rem}
.sec-head.center{margin-inline:auto;text-align:center}
.sec-head.center .lede{margin-inline:auto}
.kicker{font:600 11px/1 var(--sans);letter-spacing:.17em;text-transform:uppercase;
  color:var(--accent);margin:0 0 .85rem;display:flex;align-items:center;gap:.65rem}
.kicker::before{content:"";width:16px;height:2px;background:var(--accent-fill)}
.sec-head.center .kicker{justify-content:center}
section{padding:clamp(2.7rem,4.6vw,4.8rem) 0}

/* ---------- layout primitives (duplicated into the inlined CSS on purpose:
   leaving them out lets the page lay itself out twice) ---------- */
.split{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);
  gap:clamp(1.6rem,3.2vw,3.2rem);align-items:center}
.grid{display:grid;gap:1.1rem}
.grid>*{min-width:0}
.g2{grid-template-columns:repeat(2,minmax(0,1fr))}
.g3{grid-template-columns:repeat(3,minmax(0,1fr))}
.g4{grid-template-columns:repeat(4,minmax(0,1fr))}
/* Each section carries its OWN measured height in --cvh, written into the
   markup after the build by cvsize.js; the 700px here is only the fallback for
   a section that pass never saw. A single flat figure was wrong in both
   directions - the home page ran 36% short, pricing 15% long - and a document
   whose height moves while you scroll it is a scrollbar that moves under your
   cursor. `auto` means the browser swaps in the real height the moment the
   section renders, so these figures only govern the first pass. */
.cv{content-visibility:auto;contain-intrinsic-size:auto var(--cvh,700px)}
main>section.cv:nth-of-type(-n+3){content-visibility:visible}
/* A card is a lit panel, not an outlined box: a gradient surface, a hairline
   border, an inner top highlight and a real shadow. The old 3px gold cap is
   now a gradient rule that fades at both ends, which stops a row of cards
   reading as a row of file tabs. */
.card{position:relative;isolation:isolate;overflow:hidden;border-radius:var(--radius);
  background:var(--grad-card);border:1px solid var(--line);
  box-shadow:var(--sh-1),var(--ring);
  padding:1.5rem 1.55rem;display:flex;flex-direction:column;gap:.5rem;
  transition:transform var(--t-hover) var(--ease),box-shadow var(--t-hover) var(--ease),
    border-color var(--t-hover) var(--ease)}
.card::before{content:"";position:absolute;inset:0 0 auto;height:2px;
  background:var(--grad-rule)}
.card p{margin:0;font-size:15.5px;color:var(--ink-2)}
.note{position:relative;overflow:hidden;background:var(--grad-card);
  border:1px solid var(--line);border-radius:var(--radius);padding:1.5rem 1.6rem;
  box-shadow:var(--sh-1),var(--ring)}
.note::before{content:"";position:absolute;inset:0 auto 0 0;width:3px;
  background:linear-gradient(180deg,var(--accent),var(--accent-deep))}

/* ---------- above-the-fold primitives ---------- */
/* These paint in the first screen of EVERY page, not just the home page,
   because the inner-page header is an h1 followed by an .answer block. They
   therefore live above the hero marker, where critical_css() inlines them
   whether or not the page has a hero. Site 8 learned this the hard way: a
   rule that only arrives with the async stylesheet moves everything under
   it, and the reflow lands about a second in, which is exactly where CLS
   is still counting. */
.eyebrow{display:inline-flex;align-items:center;gap:.55rem;font:600 11px/1 var(--sans);
  letter-spacing:.17em;text-transform:uppercase;color:var(--accent);margin:0 0 1rem;
  padding:.55rem 1rem;border-radius:var(--pill);letter-spacing:.2em;
  background:rgba(217,164,65,.08);border:1px solid rgba(232,181,92,.3);align-self:flex-start}
.answer{background:var(--surface);border:1px solid var(--rule);
  border-left:4px solid var(--accent-fill);
  border-radius:var(--radius);padding:1.4rem 1.6rem;font-size:16.5px;line-height:1.7;
  color:var(--ink-2);margin:0 0 1.3rem;box-shadow:var(--shadow)}
.answer__tag{margin:0 0 .5rem;font:600 10px/1 var(--sans);letter-spacing:.19em;
  text-transform:uppercase;color:var(--accent)}
.answer b,.answer strong{color:var(--ink);font-weight:700}
.pills{display:flex;flex-wrap:wrap;gap:.4rem;margin:0 0 1.1rem;padding:0;list-style:none}
.pills li{font:500 12.5px/1 var(--sans);color:var(--ink-2);border:1px solid var(--rule);
  background:var(--surface);border-radius:var(--pill);padding:.55rem .9rem;
  box-shadow:0 1px 2px rgba(20,32,29,.04)}

.ticks{list-style:none;margin:0 0 1.3rem;padding:0;display:grid;gap:.55rem;counter-reset:tk}
.ticks li{counter-increment:tk;position:relative;padding-left:2rem;font-size:16px;
  color:var(--ink-2)}
.ticks li::before{content:counter(tk,decimal-leading-zero);position:absolute;left:0;top:.16em;
  font:600 11px/1.5 var(--sans);color:var(--accent);letter-spacing:.04em}
.cta-row{display:flex;flex-wrap:wrap;gap:.7rem;margin-bottom:1rem}
.microcopy{font-size:14px;color:var(--ink-3);margin:0 0 1.1rem}

/* ---------- 12. the 60-second summary ---------- */
/* the 60-second block is the one place on a light page that goes dark: it is
   the answer before the argument starts, and it should read as a different
   kind of thing from the prose around it */
.sixty{border-radius:var(--radius);background:var(--dark);color:var(--dark-ink-2);
  padding:clamp(1.4rem,2.8vw,2.2rem);box-shadow:var(--lift);
  background-image:radial-gradient(620px 320px at 88% -10%,rgba(79,221,176,.14),transparent 70%)}
.sixty h2,.sixty .h3{color:var(--dark-ink)}
.sixty__h{display:flex;align-items:baseline;gap:.7rem;flex-wrap:wrap;margin:0 0 .9rem}
.sixty__h h2,.sixty__h .h3{margin:0}
.sixty__t{font:600 10.5px/1 var(--sans);letter-spacing:.16em;text-transform:uppercase;
  color:var(--dark-accent);border:1px solid rgba(255,255,255,.18);padding:.45rem .7rem;
  border-radius:var(--pill)}
.sixty ol{margin:0;padding:0;list-style:none;display:grid;gap:.1rem;counter-reset:sx}
.sixty li{counter-increment:sx;display:grid;grid-template-columns:2.2rem minmax(0,1fr);
  gap:.9rem;padding:.85rem 0;border-top:1px solid rgba(255,255,255,.11);font-size:15.5px;
  line-height:1.62;color:var(--dark-ink-2)}
.sixty li:first-child{border-top:0;padding-top:0}
.sixty li::before{content:counter(sx,decimal-leading-zero);font:600 11px/1.75 var(--sans);
  color:var(--dark-accent);letter-spacing:.04em}
.sixty li b{color:var(--dark-ink);font-weight:700}
.sixty a{color:var(--dark-accent)}

/* ---------- exhibits and the index rail ---------- */
/* Site 10 grouped sections into chapter markers you scrolled past once
   you scrolled past once. This one keeps the index ON SCREEN: a numbered rail
   down the left that marks where you are, so the structure stays available all
   the way down rather than only at the joins. Defined above the hero marker on
   purpose - everything above it is inlined into every page, and a rail that
   arrives with the async stylesheet moves the column beside it. */
.dossier{display:grid;grid-template-columns:186px minmax(0,1fr);
  gap:clamp(1.4rem,3vw,3rem);align-items:start}
/* sticky goes on the GRID ITEM, not on the list inside it. A sticky element
   only travels within its own containing block, and the <nav> is exactly as
   tall as the list, so sticking the list to the nav pinned it to nothing and
   the rail scrolled away with the first screen. */
.dossier>nav{position:sticky;top:calc(var(--head-h) + 1.3rem);align-self:start}
.idx{margin:0;padding:0;list-style:none;display:grid;gap:.15rem;
  border-left:2px solid var(--rule);
  /* the buy bar is fixed over the bottom of the viewport, so the rail has to
     stop above it or its last two items are unreachable */
  max-height:calc(100vh - var(--head-h) - 8.5rem);
  /* the ring is 2px at a 3px offset, and an overflow:auto box clips it to the
     one edge that happens to sit inside. Give the scroller the 5px back. */
  padding:5px;margin-inline:-5px;
  overflow:auto}
.idx li{margin:0}
.idx a{display:grid;grid-template-columns:2.1rem minmax(0,1fr);gap:.2rem;align-items:baseline;
  padding:.62rem .7rem;color:var(--ink-3);text-decoration:none;font:500 13px/1.35 var(--sans);
  border-left:2px solid transparent;margin-left:-1px;
  transition:color var(--t-hover) var(--ease),border-color var(--t-hover) var(--ease)}
.idx a i{font:600 10.5px/1.5 var(--mono);color:var(--ink-3);font-style:normal;
  letter-spacing:.06em}
.idx a:hover{color:var(--ink)}
.idx a.is-on{color:var(--ink);border-left-color:var(--accent);background:var(--surface);
  border-radius:0 var(--radius-sm) var(--radius-sm) 0;box-shadow:var(--shadow);
  font-weight:600}
.idx a.is-on i{color:var(--accent)}
/* An implicit grid track is sized to its widest item, so a section holding a
   640px-min table made the whole column 640px wide and every heading in it
   overhung a 390px screen. The track is pinned, and the sections are allowed
   to shrink below their content. */
.dossier__body{min-width:0;display:grid;grid-template-columns:minmax(0,1fr);
  gap:clamp(2rem,4.5vw,3.6rem)}
/* no scroll-margin-top here: html's scroll-padding-top already clears the
   sticky header, and the two offsets ADD - together they put every anchor
   348px below the heading it was meant to land on. */
.exhibit{min-width:0}
.exhibit__no{display:inline-flex;align-items:center;gap:.6rem;margin:0 0 .7rem;
  font:600 10.5px/1 var(--sans);letter-spacing:.17em;text-transform:uppercase;
  color:var(--accent)}
.exhibit__no::before{content:"";width:26px;height:2px;border-radius:2px;
  background:var(--accent);flex:none}

/* ---------- above the fold: the header button, the hero buy row, the slots
   ----------
   Everything from here to the hero marker is INLINED on every page. These
   three live here rather than in the tail of the file because they paint in
   the first viewport, and a rule that arrives with the external stylesheet
   resizes what it touches: the fixed-width header button measured 0.19 CLS
   at 1280px while it was still down there, because the nav is right-aligned
   against it. Anything below the fold stays below the marker. */
.btn--big{padding:1rem 1.6rem;font-size:15px;letter-spacing:.04em}
/* The two-line header button is the one element whose height depends on two
   different font sizes, so the webfont swap was resizing the header and
   shifting the nav under it: 0.066 CLS at 1200px, on a page that had measured
   0.0000 everywhere. The height and both line boxes are therefore fixed in
   pixels, which no font metric can change. */
.head__cta{display:inline-grid;gap:0;align-content:center;height:48px;
  flex:none;width:184px;padding:0 .6rem;text-align:center;white-space:nowrap;
  overflow:hidden}
.head__cta span{font-size:13px;line-height:17px;letter-spacing:.08em}
.head__cta small{font:600 10.5px/13px var(--sans);letter-spacing:.06em;opacity:.78}
/* .btn draws an arrow as a flex child; inside a two-row grid button it lands
   on a third row and pushes out of the fixed 48px box */
.head__cta::after{display:none}
.reassure{display:flex;flex-wrap:wrap;justify-content:center;gap:.5rem 1.4rem;
  margin:1.1rem 0 0;padding:0;list-style:none}
.reassure li{display:flex;align-items:center;gap:.45rem;font-size:12.5px;line-height:1.5;
  color:var(--ink-2)}
/* The list items carry a real <svg> icon now, so the masked tick that used to
   stand in for one is a second glyph beside it. */
.reassure li .ico{color:var(--accent)}
.band-dark .reassure li .ico{color:var(--dark-accent)}
.reassure--hero{justify-content:flex-start;gap:.5rem 1.2rem}
.band-dark .reassure li{color:var(--dark-ink-2)}
.cta-act{margin-top:1.4rem}

/* ---------- fill-in slots ---------- */
/* Pasted exactly as specified. The colours are deliberately fixed and
   deliberately foreign to this palette: a slot has to look the same on every
   site and on every background, and it has to look like scaffolding rather
   than like design, so nobody ships it by accident. Nothing below is themed,
   recoloured or softened to suit the navy. */
.slot{background:#FFE14D;color:#1B1208;font-weight:750;font-style:normal;padding:1px 7px 1px 5px;border-radius:6px;outline:2px dashed #C2410C;outline-offset:1px;-webkit-box-decoration-break:clone;box-decoration-break:clone;white-space:normal}
.slot::before{content:"\270E";display:inline-block;margin-right:4px;font-weight:400}
a .slot{text-decoration:none}
.slot.is-flash{animation:slotflash 1.4s ease-out}
@keyframes slotflash{0%,40%{box-shadow:0 0 0 0 rgba(194,65,12,.8)}100%{box-shadow:0 0 0 14px rgba(194,65,12,0)}}
.rvw--slot{position:relative;outline:2px dashed #C2410C;outline-offset:-2px}
.rvw--slot::after{content:"Fill in";position:absolute;top:-11px;right:14px;padding:1px 9px;border-radius:999px;background:#FFE14D;color:#1B1208;font-size:12px;font-weight:800}
.rs .slot,.rvw__meta .slot,.rvw__foot .slot{white-space:nowrap}
/* ---------- the slot contract, defended against this site's cascade ---------
   The pasted .slot rule is a single class, so ANY site rule that colours a
   descendant beats it: the byline's small type, a .disc line, a table cell,
   a footer link. Measured before this block existed, the slot in the byline
   rendered #93A2BC on #FFE14D - 1.9:1 - on all 31 pages. The slot colours are
   a fixed contract that has to look identical on every site and every
   background, so they are the one place on this stylesheet where !important
   is the correct tool rather than a patch. The gradient-text heading on the
   home page also sets -webkit-text-fill-color, which would render a slot
   inside it invisible, so that is reset too. */
mark.slot,mark.slot *{color:#1B1208!important;-webkit-text-fill-color:#1B1208!important}
mark.slot{background:#FFE14D!important;background-image:none!important}
/* the pencil is a ::before, so a slot that wraps can leave the glyph alone at
   the end of a line with its text on the next one. Every placeholder is two
   or three short words, so keeping each mark on one line costs nothing - and
   a FILLED value is no longer a mark, so a long real name still wraps. */
mark.slot{white-space:nowrap}

/* The finder button is appended by deferred JS. Until position:fixed reaches
   it, it is a static block at the end of <body> and lengthens the document -
   0.036 CLS at 1920px. It is an overlay in the first viewport, so its rules
   are inlined with everything else that paints there. */
.slotfind{position:fixed;left:14px;bottom:84px;z-index:70;display:flex;align-items:center;gap:8px;min-height:44px;padding:0 14px;border:2px dashed #C2410C;border-radius:12px;background:#FFE14D;color:#1B1208;font:inherit;font-size:14.5px;font-weight:800;cursor:pointer;box-shadow:0 10px 24px -10px rgba(0,0,0,.4)}
.slotfind:focus-visible{outline:3px solid #1B1208;outline-offset:2px}
/* The finder is scaffolding and it is position:fixed, so it will always sit
   over SOMETHING. It must not be a buy button. Right-aligned and auto-width
   on every size, so it covers a corner rather than a full-width CTA, and it
   is behind the buy bar in the stack rather than on top of it. */
.slotfind{left:auto;right:14px}
@media(max-width:560px){
  .slotfind{left:auto;right:10px;bottom:90px;max-width:72vw;font-size:12.5px;
    padding:0 11px;justify-content:flex-start}
}
@media(max-width:380px){.slotfind{max-width:84vw;font-size:11.5px}}
@media print{.slotfind{display:none}}

/* ---------- icons ---------- */
/* One sprite, every glyph inherits currentColor, sized in em so it tracks the
   text it sits beside rather than being pinned to a pixel size that is wrong
   at half the places it appears. */
.sprite{position:absolute;width:0;height:0;overflow:hidden}
.ico{width:1.12em;height:1.12em;flex:none;display:inline-block;vertical-align:-.16em;
  stroke:currentColor;fill:none}
.ico--lg{width:1.5em;height:1.5em}
.ico--box{width:38px;height:38px;padding:9px;border-radius:11px;box-sizing:border-box;
  background:var(--grad-tint);border:1px solid var(--line);color:var(--accent);
  box-shadow:var(--ring)}

/* ---------- section motion: every section, not just the decorated ones -----
   The entrance is one composited pair - opacity and translate - on a wrapper
   that is already in the document at its final size, so nothing here can move
   a neighbour or cost a layout pass. Scroll-driven where the browser supports
   it, IntersectionObserver elsewhere, and both are switched off entirely under
   prefers-reduced-motion further down this file. */
@supports (animation-timeline: view()) {
  .js-reveal main>section>.wrap>*,
  .js-reveal main>section>.mid>*{
    animation:secRise linear both;
    animation-timeline:view();
    animation-range:entry 40px entry 330px}
  .js-reveal .hero .wrap>*{animation:none}
}
@keyframes secRise{from{opacity:0;transform:translateY(26px)}to{opacity:1;transform:none}}

/* a gradient hairline above every section head, drawn left to right */
.sec-head{position:relative}
.sec-head::before{content:"";position:absolute;top:-1.15rem;left:0;width:84px;height:2px;
  border-radius:2px;background:linear-gradient(90deg,var(--accent),transparent);
  transform-origin:left}
.js-reveal .sec-head.in::before{animation:drawX .7s var(--ease) both}

/* ---------- decorative graphics ----------
   Two shapes, both pure CSS, both behind everything, both contained so they
   can never extend the document: a dotted field that gives the navy some
   texture, and a soft aurora wash that stops a long dark page reading flat.
   No image request, no canvas, nothing to decode. */
.band-tint,.band-2{position:relative;isolation:isolate}
/* No mask here on purpose. A masked pseudo-element is promoted to its own
   composited layer on every band it appears on; a flat field at a low enough
   opacity needs none and reads the same. */
.band-tint::before,.band-2::before{content:"";position:absolute;inset:0;z-index:-1;
  pointer-events:none;contain:strict;
  background-image:radial-gradient(rgba(143,184,238,.07) 1px, transparent 1px);
  background-size:26px 26px}
.aurora{position:relative;isolation:isolate}
.aurora::after{content:"";position:absolute;inset:0;z-index:-1;pointer-events:none;
  contain:strict;background:var(--grad-aurora)}

/* ---------- tables, inlined ----------
   The Supplement Facts transcript sits INSIDE the hero on this site, so
   every table rule paints in the first viewport. Left below the marker they
   arrived with the async stylesheet and reflowed the transcript: 0.0006 CLS
   at 1199 and 1200px, the two widths where the table sits exactly at its
   minimum and one cell rewraps. */
/* scrollbar-gutter keeps the horizontal scrollbar's space reserved whether
   or not the table currently overflows. Without it the scrollbar appears when
   the async stylesheet lands and the panel transcript under the hero changed
   height: 0.0006 CLS at 1199 and 1200px, the two widths where this table sits
   exactly at its minimum. */
.tbl-wrap{background:var(--surface);border-color:var(--line);
  box-shadow:var(--sh-1);scrollbar-gutter:stable}

table{border-collapse:collapse;width:100%;font-size:15.5px}

th,td{text-align:left;padding:.86rem 1.25rem;border-bottom:1px solid var(--rule);
  vertical-align:top;color:var(--ink-2)}

tbody th{color:var(--ink);font-weight:700;font-size:15.5px}

tbody tr:hover{background:var(--tint)}

/* The hero's panel transcript is the one table that paints above the fold at
   every width. table-layout:fixed makes its column widths a function of the
   first row rather than of the content, so a cell cannot rewrap when the rest
   of the stylesheet lands - which is what was moving the figure by 3px at
   1199 and 1200px, the two widths where it sits at its minimum. */
.hero__fig table{table-layout:fixed}
.hero__fig th:first-child,.hero__fig td:first-child{width:38%}

/* ---------- hero: the ledger ----------
   The panel IS the argument, so it takes the wide column and the bottle is a
   thumbnail at the top of the narrow rail, at the size a document would print
   it. 8/4, head first, nothing staged: no slab, no tint, no contact shadow.
   Only the placement and the staging change; the class names are the ones the
   markup already uses, so the responsive fold below still applies. */
.hero--ledger .hero__cols{grid-template-columns:minmax(0,8fr) minmax(0,4fr);align-items:start}
.hero--ledger .hero__head{grid-column:1;grid-row:1}
.hero--ledger .hero__slab{grid-column:2;grid-row:1;background:none;box-shadow:none;
  border-radius:0;border-top:2px solid var(--accent);padding:1.1rem 0 0}
.hero--ledger .hero__slab::after{display:none}
.hero--ledger .hero__shot{margin:0;max-width:200px}
.hero--ledger .hero__slab figcaption{border-top:0;margin-top:.9rem;padding-top:0}
/* the ledger itself: a wide first column, and every figure column mono and
   tabular so a printed percentage and a recomputed one line up digit for
   digit - which is the entire point of putting them side by side */
.hero--ledger .hero__fig th:first-child,
.hero--ledger .hero__fig td:first-child{width:34%}
.hero--ledger .hero__fig td:nth-child(2),
.hero--ledger .hero__fig td:nth-child(3),
.hero--ledger .hero__fig td:nth-child(4){font-family:var(--mono);
  font-variant-numeric:tabular-nums;white-space:nowrap}
.hero--ledger .hero__fig tbody td:last-child{color:var(--ink-3);font-size:14px}
.hero--ledger .hero__fig tbody td:last-child b{color:var(--accent-2)}
/* the price panel that replaces a price ladder */
.nopack__h{margin:0 0 .3rem;font:700 11px/1.4 var(--sans);letter-spacing:.14em;
  text-transform:uppercase;color:var(--accent)}
.nopack p+.nopack__h{margin-top:1.1rem}

/* ---------- hero: the readout ---------- */
/* This label's argument IS its Supplement Facts panel, so the panel is the
   hero. The bottle stands on a tinted slab in the narrower left column, the
   argument takes the wider right, and the panel is transcribed line by line
   across the full width beneath both. No frame, no wash, no vignette: site
   12 had all three and this one is deliberately none of them.

   Source order is head then slab, so a screen reader and the mobile fold
   both meet the headline first; the slab is PLACED in column one rather than
   written there. */
.hero{position:relative;isolation:isolate;overflow:clip;
  padding:clamp(2rem,4vw,4.2rem) 0 clamp(2.2rem,4vw,3.6rem);text-align:left}
.hero .wrap{position:relative;z-index:1}
.hero__cols{display:grid;grid-template-columns:minmax(0,5fr) minmax(0,7fr);
  gap:clamp(1.6rem,3.4vw,3.4rem);align-items:center}
.hero__head{grid-column:2;grid-row:1;max-width:none}
.hero__slab{grid-column:1;grid-row:1;position:relative;margin:0;
  border-radius:var(--radius);background:var(--tint);box-shadow:var(--sh-1);
  padding:clamp(1.4rem,3vw,2.4rem) clamp(1rem,2.4vw,1.8rem) clamp(1rem,2vw,1.4rem)}
/* the contact shadow: the bottle STANDS on the slab rather than floating
   over it, which is the whole difference between a plinth and a backdrop */
.hero__slab::after{content:"";position:absolute;left:50%;bottom:clamp(3.4rem,7vw,5rem);
  width:62%;height:18px;translate:-50% 0;z-index:0;pointer-events:none;
  border-radius:50%;filter:blur(9px);background:rgba(23,22,28,.22)}
.hero__shot{position:relative;z-index:1;margin:0 auto;width:100%;max-width:520px}
.hero__shot img{width:100%;height:auto;display:block}
.hero__slab figcaption{position:relative;z-index:1;margin:clamp(.9rem,2vw,1.3rem) 0 0;
  padding-top:.9rem;border-top:1px solid var(--line);
  font-size:12.5px;line-height:1.6;color:var(--ink-3)}
.hero h1{margin-bottom:1rem;text-wrap:balance}
.hero__deck{font-size:clamp(1.04rem,1.45vw,1.2rem);line-height:1.68;color:var(--ink-2);
  max-width:60ch;margin:0 0 1.6rem}
.hero .cta-row{justify-content:flex-start}
/* the panel transcript, full width under both columns */
.hero__fig{margin-top:clamp(1.6rem,3vw,2.6rem)}
.hero__seals{display:flex;flex-wrap:wrap;align-items:center;justify-content:flex-start;
  gap:.7rem 1.3rem;border-top:1px solid var(--rule);padding-top:1.3rem;margin-top:1.6rem}
.hero__seals img{width:46px;height:46px;opacity:.95}
.hero__seals p{margin:0;font-size:12.5px;line-height:1.55;color:var(--ink-3);max-width:40ch;
  text-align:left}

/* the four-figure strip */
.spec{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:1px;margin:0 0 1.3rem;
  background:var(--rule);border:1px solid var(--rule);border-radius:var(--radius);
  overflow:hidden;text-align:left}
.spec div{background:var(--bg-2);padding:1.1rem 1.2rem}
.spec dt{margin:0 0 .4rem;font:600 10px/1.4 var(--sans);letter-spacing:.16em;
  text-transform:uppercase;color:var(--ink-3)}
.spec dd{margin:0;font:600 1.5rem/1.1 var(--display);letter-spacing:-.02em;color:var(--accent)}
.spec dd small{display:block;margin-top:.35rem;font:400 11.5px/1.5 var(--sans);
  letter-spacing:0;color:var(--ink-3)}

/* ---------- acts: the numbered section rhythm ---------- */
.act{padding:clamp(2.6rem,4.6vw,4.6rem) 0}
.act__no{display:flex;align-items:center;gap:1rem;margin:0 0 .9rem}
.act__rule{height:1px;width:clamp(28px,6vw,72px);flex:none;
  background:linear-gradient(90deg,var(--accent),transparent)}
.act__no i{font:600 11px/1 var(--sans);letter-spacing:.24em;text-transform:uppercase;
  color:var(--accent);font-style:normal}
.act__h{max-width:22ch}

/* ---------- the animated step explainer ---------- */
/* The connector draws itself as each step arrives. It is a scaleY on a
   pseudo-element, so it runs on the compositor and costs no layout; with JS
   off every step is simply visible, and under reduced motion the connector is
   drawn at full height from the start. */
.asteps__list{list-style:none;margin:0;padding:0;display:grid;gap:0;counter-reset:as}
.astep{position:relative;display:grid;grid-template-columns:auto minmax(0,1fr);
  gap:clamp(1rem,2.4vw,1.8rem);padding:0 0 clamp(1.6rem,3vw,2.4rem)}
.astep:last-child{padding-bottom:0}
.astep__n{position:relative;z-index:1;width:46px;height:46px;flex:none;display:grid;
  place-items:center;border-radius:50%;background:var(--bg-2);
  border:1px solid var(--line);color:var(--accent);
  font:600 13px/1 var(--mono);letter-spacing:.04em}
/* the connector between one numeral and the next */
.astep:not(:last-child)::before{content:"";position:absolute;left:23px;top:46px;bottom:0;
  width:1px;background:linear-gradient(180deg,var(--accent),var(--rule));
  transform-origin:top;transform:scaleY(0)}
.js-reveal .asteps.in .astep:not(:last-child)::before{animation:drawLine .7s var(--ease) forwards}
.js-reveal .asteps.in .astep:nth-child(2)::before{animation-delay:.12s}
.js-reveal .asteps.in .astep:nth-child(3)::before{animation-delay:.24s}
.js-reveal .asteps.in .astep:nth-child(4)::before{animation-delay:.36s}
.js-reveal .asteps.in .astep:nth-child(n+5)::before{animation-delay:.48s}
@keyframes drawLine{to{transform:scaleY(1)}}
.astep__b h3{margin:.55rem 0 .4rem}
.astep__b p{margin:0;color:var(--ink-2)}
.js-reveal .asteps .astep__n{opacity:0;transform:translateY(8px)}
.js-reveal .asteps.in .astep__n{animation:rise .5s var(--ease) forwards}
.js-reveal .asteps .astep__b{opacity:0}
.js-reveal .asteps.in .astep__b{animation:fadeUp .55s var(--ease) .1s forwards}
.js-reveal .asteps.in .astep:nth-child(2) .astep__n,
.js-reveal .asteps.in .astep:nth-child(2) .astep__b{animation-delay:.14s}
.js-reveal .asteps.in .astep:nth-child(3) .astep__n,
.js-reveal .asteps.in .astep:nth-child(3) .astep__b{animation-delay:.28s}
.js-reveal .asteps.in .astep:nth-child(4) .astep__n,
.js-reveal .asteps.in .astep:nth-child(4) .astep__b{animation-delay:.42s}
.js-reveal .asteps.in .astep:nth-child(n+5) .astep__n,
.js-reveal .asteps.in .astep:nth-child(n+5) .astep__b{animation-delay:.56s}
@keyframes rise{to{opacity:1;transform:none}}

/* ---------- the byline and the vacant clinician slot ---------- */
.byline{margin:0 0 1.4rem;padding:.9rem 0 0;border-top:1px solid var(--rule)}
.byline__line{display:flex;flex-wrap:wrap;align-items:center;gap:.5rem .75rem;margin:0;
  font-size:13.5px;line-height:1.6;color:var(--ink-3)}
.byline__line a{color:var(--ink-2)}
.byline__dot{width:3px;height:3px;border-radius:50%;background:var(--line);flex:none}
.byline__who b{color:var(--ink-2);font-weight:600}
/* the empty slot is drawn as an empty slot: a dashed box with nothing in it */
.byline__who--open{color:var(--ink-3)}
.byline .slot{font-style:normal;font-family:var(--mono);font-size:12px;
  border:1px dashed var(--line);border-radius:var(--radius-sm);padding:.2rem .5rem;
  color:var(--ink-3);white-space:nowrap}
.byline__why{margin:.55rem 0 0;font-size:12.5px;line-height:1.6;color:var(--ink-3);
  max-width:72ch}

/* ---------- supplied, not verified ---------- */
/* Everything inside this frame came from the seller. The frame is not
   decoration: it is the difference between publishing a claim and making one. */
.supplied{position:relative;border:1px solid var(--line);border-radius:var(--radius);
  background:var(--bg-2);padding:clamp(1.2rem,2.4vw,1.8rem);margin:0 0 1.4rem}
.supplied::before{content:"";position:absolute;inset:0;border-radius:var(--radius);
  pointer-events:none;
  background:repeating-linear-gradient(135deg,rgba(203,82,131,.05) 0 10px,transparent 10px 20px)}
.supplied>*{position:relative}
.supplied__flag{margin:0 0 .8rem}
.supplied__flag span{display:inline-flex;align-items:center;gap:.5rem;
  font:600 10.5px/1 var(--sans);letter-spacing:.17em;text-transform:uppercase;
  color:var(--cat-fails-t);border:1px solid rgba(143,55,20,.4);
  border-radius:var(--pill);padding:.45rem .8rem}
.supplied__h{margin:0 0 .8rem}
.supplied__src{margin:1rem 0 0;padding-top:.8rem;border-top:1px solid var(--rule);
  font-size:12.5px;line-height:1.6;color:var(--ink-3)}

/* ---------- sections ---------- */
.band-tint{background:var(--bg-2);border-block:1px solid var(--rule)}
.band-warm{background:var(--tint);border-block:1px solid var(--line)}
.band-dark{background:var(--dark);color:var(--dark-ink-2);border-block:1px solid var(--dark-line)}
.band-dark h1,.band-dark h2,.band-dark h3,.band-dark .h3{color:var(--dark-ink)}
.band-dark a{color:var(--dark-accent)}
.band-dark a:hover{color:#FBD3E2}
.band-dark .lede,.band-dark p{color:var(--dark-ink-2)}
/* bold text inside the cream band was still carrying the navy-ground ink */
.band-dark b,.band-dark strong{color:var(--dark-ink)}
/* A table dropped into the cream band keeps its navy surface, but the band's
   caption and figcaption rules still match it - so the caption was cream-band
   ink on a navy panel. Give the whole table the cream treatment instead, which
   closes the class of bug rather than this one instance. */
/* A WHITE table inside the DARK band is a page surface sitting in a band
   surface, so it takes PAGE inks. Site 12 had this the other way round - a
   white card on a cream band - and the same rule written for that arrangement
   put --dark-ink (#F7F2F5) on #FFFFFF here: 1.11:1, on every page that
   carries a table inside the summary band. The fix is to give the whole table
   the page treatment rather than to patch one cell. */
.band-dark .band-dark .tbl-wrap caption{color:var(--ink-3);background:var(--surface)}
.band-dark thead th{background:var(--bg-2);color:var(--ink-2);border-color:var(--line)}
.band-dark th,.band-dark td{border-color:var(--line);color:var(--ink-2)}
.band-dark tbody th{color:var(--ink)}
.band-dark tbody tr:hover{background:var(--bg-2)}
.band-dark .tbl-wrap b,.band-dark .tbl-wrap strong{color:var(--ink)}
.band-dark .tbl-wrap a{color:var(--accent)}
.band-dark .tbl-wrap .disc{color:var(--ink-3)}
/* and the warm caution panel: cream ground, so its bold text is dark too */
.note--warn,.note--warn p,.note--warn li{color:var(--warn)}
.note--warn b,.note--warn strong{color:#5C3304}
.band-dark .kicker{color:var(--dark-accent)}
.band-dark .kicker::before{background:var(--dark-accent)}
.band-dark .disc{color:var(--dark-ink-3)}
/* A <caption> belongs to its TABLE's surface, and on this site every table
   inside the dark band is white. Scoping this to figcaption only - and giving
   the caption the page ink beside its table - closes the 3.1:1 the crawler
   found on the home page. */
.band-dark figcaption{color:var(--dark-ink-3)}
.band-dark caption,.band-dark table caption{color:var(--ink-3)}
.band-dark .card p,.band-dark .note p,.band-dark .card .disc{color:var(--dark-ink-2)}
.band-dark summary{color:var(--dark-ink-2)}
.band-dark .fig img{border-color:var(--dark-line)}
/* The light counterpoint band only ever carries prose and links - never a
   card, a table, a pack or a figure. The twenty-five rules that used to sit
   here restyled all of those for a band none of them appear in, and one of
   them (a #243040 table-row hover) would have shipped at 1.56:1 the first day
   a table landed in one. */
.band-dark{background-image:radial-gradient(760px 380px at 85% -20%,
  rgba(79,221,176,.12),transparent 70%)}
.band-dark .card,.band-dark .note{background:rgba(255,255,255,.05);
  border-color:var(--dark-line);color:var(--dark-ink-2);box-shadow:none}
.band-dark .card::before{background:var(--dark-accent)}
.band-dark .card h3,.band-dark .note h3{color:var(--dark-ink)}

.split{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);
  gap:clamp(1.6rem,3.2vw,3.2rem);align-items:center}
.grid{display:grid;gap:1.1rem}
.grid>*{min-width:0}
.g2{grid-template-columns:repeat(2,minmax(0,1fr))}
.g3{grid-template-columns:repeat(3,minmax(0,1fr))}
.g4{grid-template-columns:repeat(4,minmax(0,1fr))}

/* ---------- cards: flat, outlined, coloured top rule ---------- */
.card{position:relative;isolation:isolate;overflow:hidden;border-radius:var(--radius);
  background:var(--surface);border:1px solid var(--rule);
  padding:1.6rem 1.7rem;display:flex;flex-direction:column;gap:.55rem;
  transition:transform var(--t-hover) var(--ease),box-shadow var(--t-hover) var(--ease),
    border-color var(--t-hover) var(--ease)}
/* one gold hairline across the whole top edge: the card is a plate, not a tile */
.card::before{content:"";position:absolute;inset:0 0 auto;height:2px;background:var(--foil)}
.card:hover{transform:translateY(-3px);box-shadow:var(--lift);border-color:var(--line)}
.card h3{margin:0}
.card p{margin:0;font-size:15.5px;color:var(--ink-2)}

/* ---------- tables ---------- */
.tbl-wrap{position:relative;overflow-x:auto;border-radius:var(--radius);
  background:var(--surface);border:1px solid var(--rule);box-shadow:var(--shadow)}caption{text-align:left;font-size:13px;color:var(--ink-2);padding:1rem 1.25rem .3rem}thead th{font:600 11.5px/1.4 var(--sans);letter-spacing:.09em;text-transform:uppercase;
  color:var(--ink-3);background:var(--bg-2);white-space:nowrap}tbody tr:last-child th,tbody tr:last-child td{border-bottom:0}
tbody tr{transition:background var(--t-hover) var(--ease)}
/* ---------- callouts, steps, figures ---------- */
.note{background:var(--surface);border:1px solid var(--rule);
  border-left:4px solid var(--accent-fill);
  border-radius:var(--radius);padding:1.5rem 1.7rem;box-shadow:var(--shadow)}
.note h3{margin:0 0 .6rem;font-size:1.04rem}
.note p:last-child{margin-bottom:0}
.note--warn{background:var(--warn-bg);border-color:var(--warn-line);border-left-color:var(--warn)}
.note--warn h3{color:var(--warn)}
.steps{list-style:none;counter-reset:s;margin:0;padding:0;display:grid;gap:1rem}
.steps li{counter-increment:s;position:relative;padding:1.3rem 1.5rem 1.3rem 4.2rem;
  border-radius:var(--radius);background:var(--surface);border:1px solid var(--rule);
  box-shadow:var(--shadow);
  transition:border-color var(--t-hover) var(--ease),transform var(--t-hover) var(--ease)}
.steps li:hover{border-color:var(--accent);transform:translateY(-2px)}
.steps li::before{content:counter(s,decimal-leading-zero);position:absolute;left:1.35rem;
  top:1.42rem;font:600 1.05rem/1 var(--sans);color:var(--accent)}
.steps h3{margin:0 0 .3rem}
.steps p{margin:0;font-size:15.5px}
.fig{margin:0}
.fig img{border-radius:var(--radius);border:1px solid var(--rule);box-shadow:var(--shadow)}
figcaption{font-size:13px;line-height:1.65;color:var(--ink-3);margin-top:.85rem;max-width:58ch}

/* ---------- evidence chips ---------- */
.tag{display:inline-flex;align-items:flex-start;gap:.45rem;font:600 11.5px/1.35 var(--sans);
  letter-spacing:.03em;padding:.45rem .7rem;border-radius:var(--radius-sm);
  border:1px solid currentColor;
  /* not nowrap: these labels are sentences, and at 320px a nowrap chip runs off
     the side of a page whose html is overflow-x:clip, so the end of the label
     is gone and no scroll brings it back */
  white-space:normal;overflow-wrap:anywhere;max-width:100%}
.tag::before{content:"";width:8px;height:8px;border-radius:50%;background:currentColor;
  flex:none;margin-top:.24em}
.tag--checks{color:var(--cat-checks-t)}
.tag--nodv{color:var(--cat-nodv-t)}
.tag--fails{color:var(--cat-fails-t)}

.legend{display:flex;flex-wrap:wrap;gap:.5rem;margin:0 0 1.5rem;padding:0;list-style:none}

/* ---------- interactive components ---------- */
/* 1. flip cards */
.flip{position:relative}
.flip__btn{display:inline-flex;align-items:center;gap:.5rem;background:none;border:0;
  padding:.55rem 0;margin:.15rem 0 .5rem;min-height:26px;cursor:pointer;
  font:600 12px/1 var(--sans);letter-spacing:.06em;text-transform:uppercase;color:var(--accent);
  align-self:flex-start}
.flip:not(.flip--on) .flip__btn{display:none}
.flip__btn::after{content:"";width:9px;height:9px;border-right:2px solid currentColor;
  border-bottom:2px solid currentColor;rotate:45deg;translate:0 -2px;
  transition:rotate var(--t-ui) var(--ease)}
.flip.is-flipped .flip__btn::after{rotate:225deg;translate:0 2px}
.flip__in{display:grid;gap:1rem}
.flip--on .flip__in{display:block}
.flip--on .flip__b{display:none}
.flip--on.is-flipped .flip__a{display:none}
.flip--on.is-flipped .flip__b{display:block;animation:fadeUp .3s var(--ease) both}
@keyframes fadeUp{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:none}}
.flip__b{border-top:1px solid var(--rule);padding-top:.9rem}

/* 2. image hotspots */
.hotspots__frame{position:relative;display:inline-block;max-width:100%}
.hotspot{display:none}
.hotspots--on .hotspot{display:grid;position:absolute;place-items:center;width:30px;height:30px;
  translate:-50% -50%;border:2px solid var(--surface);cursor:pointer;
  background:var(--accent-fill);color:#fff;font:700 12.5px/1 var(--sans);
  border-radius:50%;box-shadow:0 2px 10px rgba(20,32,29,.35);
  transition:transform var(--t-hover) var(--ease)}
.hotspots--on .hotspot:hover{transform:translate(-50%,-50%) scale(1.14)}
.hotspots--on .hotspot.is-on{box-shadow:0 0 0 4px rgba(11,122,96,.22),0 2px 10px rgba(20,32,29,.35);
  background:var(--accent-deep);color:#fff;transform:translate(-50%,-50%) scale(1.1)}
.hotspot__panels{margin-top:1.15rem;display:grid;gap:.8rem}
.hotspots--on .hotspot__panels{min-height:9rem}
.hotspot__panel{background:var(--surface);border:1px solid var(--rule);
  border-left:4px solid var(--accent-fill);border-radius:var(--radius);
  padding:1.2rem 1.4rem;box-shadow:var(--shadow)}
.hotspot__panel h3{margin:0 0 .35rem;font-size:1rem}
.hotspot__panel p{margin:0;font-size:15.5px}
.hotspot__panel .n{font-family:var(--sans);color:var(--accent);margin-right:.5rem}
.hotspots__hint{font:500 12px/1.5 var(--sans);color:var(--ink-3);margin:.9rem 0 0}
.hotspots:not(.hotspots--on) .hotspots__hint{display:none}

/* 3. tabs */
.tabs__list{display:flex;gap:.25rem;flex-wrap:wrap;margin:0 0 1.4rem;padding:.3rem;
  background:var(--bg-2);border-radius:var(--pill);width:fit-content;max-width:100%}
.tabs:not(.tabs--on) .tabs__list{display:none}
.tabs__list button{background:none;border:0;
  border-bottom:0;cursor:pointer;padding:.7rem 1.15rem;font:600 13.5px/1 var(--sans);
  border-radius:var(--pill);color:var(--ink-3);
  transition:color var(--t-hover) var(--ease),background var(--t-hover) var(--ease),
    box-shadow var(--t-hover) var(--ease)}
.tabs__list button:hover{color:var(--ink)}
.tabs__list button[aria-selected=true]{color:var(--ink);background:var(--surface);
  box-shadow:var(--shadow)}
.tabs--on [role=tabpanel]{animation:fadeUp .28s var(--ease) both}
.tabs__h{font:700 1.1rem/1.34 var(--display);color:var(--ink);margin:0 0 .55rem;
  letter-spacing:-.014em}
.tabs--on .tabs__h{margin:0 0 .9rem;display:none}

/* 4. FAQ filter */
.faqfilter__bar{display:none}
.faqfilter--on .faqfilter__bar{display:flex;gap:.8rem;align-items:center;flex-wrap:wrap;
  margin:0 0 1.25rem}
.faqfilter__bar input{flex:1;min-width:14rem;background:var(--surface);
  border:1px solid var(--line);border-radius:var(--pill);color:var(--ink);
  font:400 15px/1 var(--sans);padding:1rem 1.3rem;box-shadow:var(--shadow)}
.faqfilter__bar input::placeholder{color:var(--ink-3)}
.faqfilter__bar input:focus-visible{border-color:var(--accent);
  outline:2px solid var(--accent);outline-offset:2px}
.faqfilter__count{font:500 12px/1 var(--sans);color:var(--ink-3);white-space:nowrap}
.faqfilter__empty{margin:0;padding:1.2rem 1.4rem;background:var(--surface);
  border:1px solid var(--rule);border-radius:var(--radius);font-size:15.5px;
  box-shadow:var(--shadow)}

/* 5. fit check */
.fitcheck{background:var(--surface);border:1px solid var(--line);border-radius:var(--radius);
  padding:1.6rem 1.7rem;box-shadow:var(--shadow)}
.fitcheck__q{border-top:1px solid var(--rule);padding:1rem 0;display:flex;gap:1rem;
  align-items:flex-start;justify-content:space-between;flex-wrap:wrap}
.fitcheck__q:first-of-type{border-top:0;padding-top:0}
.fitcheck__q p{margin:0;font-size:16px;color:var(--ink);max-width:52ch}
.fitcheck__opts{display:flex;gap:.4rem;flex:none}
.fitcheck__opts label{position:relative;cursor:pointer}
.fitcheck__opts input{position:absolute;opacity:0;width:100%;height:100%;left:0;top:0;margin:0;
  cursor:pointer}
.fitcheck__opts span{display:block;padding:.58rem 1.1rem;border-radius:var(--radius-sm);
  border:1px solid var(--line);font:700 12.5px/1 var(--sans);color:var(--ink-2);
  transition:color var(--t-hover) var(--ease),background var(--t-hover) var(--ease),
    border-color var(--t-hover) var(--ease)}
.fitcheck__opts input:checked + span{background:var(--accent-fill);border-color:var(--accent-fill);
  color:#fff}
.fitcheck__opts input:focus-visible + span{outline:2px solid var(--accent);outline-offset:2px}
.fitcheck__out{margin-top:1.3rem;padding:1.2rem 1.35rem;border-radius:var(--radius-sm);
  background:var(--bg-2);border:1px solid var(--line);border-left:3px solid var(--accent-fill)}
.fitcheck__out.is-in{animation:fadeUp .36s var(--ease) both}
.fitcheck__out[data-state=stop]{border-left-color:var(--warn);background:var(--warn-bg);
  border-color:var(--warn-line)}
.fitcheck__out[data-state=ok]{border-left-color:var(--cat-checks)}
.fitcheck__out h3{margin:0 0 .35rem;font-size:1.02rem}
.fitcheck__out p{margin:0;font-size:15.5px}
.fitcheck__note{margin:1rem 0 0;font-size:13px;line-height:1.65;color:var(--ink-3)}

/* 7. carousel */
.carousel{position:relative}
.carousel__track{display:grid;grid-auto-flow:column;grid-auto-columns:min(100%,20.5rem);
  gap:1rem;overflow-x:auto;scroll-snap-type:x mandatory;padding-bottom:.6rem;
  scrollbar-width:thin;scrollbar-color:var(--line) transparent}
.carousel__item{scroll-snap-align:start}
.carousel__nav{display:none}
.carousel--on .carousel__nav{display:flex;gap:.5rem;justify-content:flex-end;margin-bottom:.9rem}
.carousel__nav button{width:42px;height:42px;display:grid;place-items:center;cursor:pointer;
  border-radius:var(--radius-sm);background:var(--surface);border:1px solid var(--line);
  color:var(--ink);transition:color var(--t-hover) var(--ease),
    border-color var(--t-hover) var(--ease)}
.carousel__nav button:hover[aria-disabled=false]{border-color:var(--accent);color:var(--accent)}
.carousel__nav button[aria-disabled=true]{color:var(--ink-3);border-color:var(--rule);
  cursor:default}
.carousel__nav svg{width:15px;height:15px;fill:none;stroke:currentColor;stroke-width:2;
  stroke-linecap:round;stroke-linejoin:round}

/* 8. scrollytelling */
.scrolly{display:grid;grid-template-columns:minmax(0,5fr) minmax(0,7fr);
  gap:clamp(1.5rem,3vw,3rem);align-items:start}
.scrolly__figure{position:relative;border-radius:var(--radius);background:var(--surface);
  border:1px solid var(--line);padding:1.5rem;min-height:18rem;display:grid;place-items:center;
  box-shadow:var(--shadow)}
.scrolly--on .scrolly__figure{position:sticky;top:calc(var(--head-h) + 5rem)}
.scrolly__layer{grid-area:1/1;width:100%}
.scrolly--on .scrolly__layer{transition:opacity var(--t-ui) var(--ease)}
.scrolly__steps{display:grid;gap:1rem}
.scrolly__step{border-radius:var(--radius);background:var(--surface);
  border:1px solid var(--line);border-left:3px solid var(--line);padding:1.4rem 1.5rem;
  transition:border-color var(--t-ui) var(--ease),opacity var(--t-ui) var(--ease)}
.scrolly--on .scrolly__step{opacity:.86}
.scrolly--on .scrolly__step.is-on{opacity:1;border-left-color:var(--accent-fill);
  box-shadow:var(--shadow)}
.scrolly__step h3{margin:0 0 .4rem}
.scrolly__step p:last-child{margin-bottom:0}
.scrolly__n{display:inline-flex;align-items:center;justify-content:center;width:1.6rem;
  height:1.6rem;border-radius:var(--radius-sm);background:var(--ink);color:var(--bg);
  font:600 .8rem/1 var(--sans);margin-bottom:.65rem}

/* 10. ingredient explorer */
/* the same segmented control as .tabs, so two components that do the same job
   on the same page do not look like two different ideas */
.explorer__list{display:flex;gap:.25rem;flex-wrap:wrap;margin:0 0 1.5rem;padding:.3rem;
  background:var(--bg-2);border-radius:var(--pill);width:fit-content;max-width:100%}
.explorer:not(.explorer--on) .explorer__list{display:none}
.explorer__list button{display:flex;align-items:center;gap:.5rem;background:none;border:0;
  cursor:pointer;padding:.7rem 1.1rem;border-radius:var(--pill);
  font:600 13.5px/1 var(--sans);color:var(--ink-3);
  transition:color var(--t-hover) var(--ease),background var(--t-hover) var(--ease),
    box-shadow var(--t-hover) var(--ease)}
.explorer__list button:hover{color:var(--ink)}
.explorer__list button[aria-selected=true]{color:var(--ink);background:var(--surface);
  box-shadow:var(--shadow)}
.explorer__list button i{width:9px;height:9px;border-radius:50%;background:var(--ink-3);
  flex:none;transition:background var(--t-hover) var(--ease)}
.explorer__list button[aria-selected=true] i{background:var(--accent-fill)}
.explorer__h{font:700 1.12rem/1.34 var(--display);color:var(--ink);margin:0 0 .55rem;
  letter-spacing:-.014em}
.explorer--on .explorer__h{margin:0 0 .9rem;display:none}
.explorer--on [data-ex-panel]{animation:fadeUp .26s var(--ease) both}
::view-transition-old(root),::view-transition-new(root){animation-duration:.26s}

/* 11. label ticker */
.ticker{overflow:hidden;border-block:1px solid var(--line);padding:.8rem 0;
  background:var(--bg-2);display:flex;gap:0}
.ticker__row{display:flex;gap:2.4rem;align-items:center;flex:none;padding-right:2.4rem;
  font:500 12px/1 var(--sans);letter-spacing:.09em;text-transform:uppercase;color:var(--ink-3);
  white-space:nowrap}
.ticker--on .ticker__row{animation:slide 36s linear infinite}
.ticker--on:hover .ticker__row{animation-play-state:paused}
.ticker--on.is-paused .ticker__row{animation-play-state:paused}
.ticker__row span::after{content:"";display:inline-block;width:4px;height:4px;
  background:var(--accent);margin-left:2.4rem;vertical-align:middle}
/* The Pause control is injected by deferred JS, so until it arrives the page
   is 38px shorter and everything under the ticker moves when it lands -
   0.0005 CLS at 1280px. The strip it needs is reserved here instead, and the
   button is placed inside it, so the injection changes nothing. Without JS
   the strip is simply empty padding. */
.ticker{position:relative;padding-bottom:38px}
.ticker__stop{position:absolute;bottom:.5rem;left:50%;translate:-50% 0;
  background:var(--surface);
  border:1px solid var(--line);border-radius:var(--radius-sm);color:var(--ink-3);
  font:600 12px/1 var(--sans);padding:.5rem 1rem;cursor:pointer;min-height:28px}
.ticker__stop:hover{color:var(--ink)}
@keyframes slide{to{transform:translateX(-100%)}}

/* ---------- the verdict scale (the signature figure) ---------- */
.scale-wrap{overflow-x:auto;border-radius:var(--radius);background:var(--surface);
  border:1px solid var(--line);padding:1.4rem 1.5rem}
.scale{width:100%;min-width:620px;height:auto;display:block}

/* ---------- pack cards ---------- */
.packs{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:1.2rem;align-items:start}
.pack{position:relative;isolation:isolate;border-radius:var(--radius);overflow:hidden;
  background:var(--surface);border:1px solid var(--rule);display:flex;flex-direction:column;
  box-shadow:var(--shadow);
  transition:border-color var(--t-hover) var(--ease),transform var(--t-hover) var(--ease),
    box-shadow var(--t-hover) var(--ease)}
.pack:hover{transform:translateY(-4px);box-shadow:var(--lift)}
/* the recommended pack is lifted out of the row rather than merely outlined:
   three identical rectangles with one different border colour is a table, not
   a choice */
.pack--best{border-color:rgba(11,122,96,.35);box-shadow:var(--lift);
  transform:translateY(-10px)}
.pack--best:hover{transform:translateY(-14px)}
.pack__flag{margin:0;text-align:center;font:700 11px/1 var(--sans);letter-spacing:.13em;
  text-transform:uppercase;padding:.85rem;background:var(--bg-2);color:var(--ink-3)}
.pack--best .pack__flag{background:var(--foil);color:#fff}
.pack__body{padding:1.4rem 1.5rem 1.6rem;display:flex;flex-direction:column;gap:.5rem;flex:1}
.pack__name{margin:0;font-size:1.3rem}
.pack__supply{margin:0;font:500 12px/1.4 var(--sans);color:var(--ink-3)}
/* one height for all three, or the price lines do not sit on a line */
.pack__shot{margin:.7rem 0;display:grid;place-items:center;height:160px}
.pack__shot img{max-height:160px;width:auto;max-width:100%}
.pack__each{font:800 2.5rem/1 var(--display);color:var(--accent);letter-spacing:-.03em}
.pack__each span{font:500 12px/1 var(--mono);color:var(--ink-3)}
.pack__tot{margin:.2rem 0 .5rem;font-size:15px;color:var(--ink-2)}
.pack__tot b{color:var(--ink)}
.pack__tot s{color:var(--ink-3);margin-left:.45rem}
.pack__perks{list-style:none;margin:.3rem 0 1rem;padding:0;display:grid;gap:.45rem;
  font-size:14.5px;color:var(--ink-2)}
.pack__perks li{position:relative;padding-left:1.35rem}
.pack__perks li::before{content:"";position:absolute;left:0;top:.42em;width:.85rem;height:.85rem;
  border-radius:50%;background:var(--tint);
  box-shadow:inset 0 0 0 1.5px var(--accent-fill)}
.pack__foot{margin-top:auto;display:grid;gap:.75rem;justify-items:center}

/* ---------- FAQ ---------- */
.faq{display:grid;gap:.7rem}
.faq details{border-radius:var(--radius);background:var(--surface);border:1px solid var(--rule);
  box-shadow:var(--shadow);
  transition:border-color var(--t-hover) var(--ease),box-shadow var(--t-hover) var(--ease)}
.faq details:hover{border-color:var(--line)}
.faq details[open]{border-color:rgba(11,122,96,.3);box-shadow:var(--lift)}
.faq summary{cursor:pointer;list-style:none;padding:1.25rem 3.2rem 1.25rem 1.5rem;
  position:relative;font:700 1.02rem/1.4 var(--sans);color:var(--ink);
  border-radius:var(--radius)}
.faq summary::-webkit-details-marker{display:none}
/* the chevron sits in its own tinted disc: a bare arrow on a white card is
   easy to miss, and it is the only affordance the row has */
.faq summary::before{content:"";position:absolute;right:1.15rem;top:50%;translate:0 -50%;
  width:28px;height:28px;border-radius:50%;background:var(--tint);
  transition:background var(--t-hover) var(--ease)}
.faq details[open] summary::before{background:var(--accent-fill)}
.faq summary::after{content:"";position:absolute;right:1.66rem;top:calc(50% - 4px);
  width:9px;height:9px;
  border-right:2px solid var(--accent);border-bottom:2px solid var(--accent);rotate:45deg;
  transition:rotate var(--t-ui) var(--ease),border-color var(--t-hover) var(--ease)}
.faq details[open] summary::after{rotate:225deg;top:calc(50% - 1px);border-color:#fff}
.faq .a{padding:0 1.5rem 1.4rem;font-size:15.5px;color:var(--ink-2)}
.faq .a p:last-child{margin-bottom:0}

/* ---------- footer ---------- */
/* Five columns after a CTA block, then a seal row, a payment row, the legal
   block and a return-to-top rule. Headings are h2.h3 so the document outline
   does not gain twenty orphan h3s under the last section's h2. */
/* .btn.btn--ghost is (0,2,0) and lives in the inlined critical CSS, which the
   document places AFTER the async stylesheet link - so an equal-specificity
   override down here loses and the button renders white on white. Match .btn
   as well to take it to (0,3,0). */

/* The footer is the one full-width dark surface on the site. On a warm-paper
   page it closes the document instead of fading out of it, and it is where
   every reference site puts its weight too. Inks come from the --dark-* set,
   which check.py measures against this exact ground. */
.foot{background:var(--dark);color:var(--dark-ink-2);font-size:16px;padding-bottom:130px;
  background-image:radial-gradient(900px 420px at 12% -10%,rgba(79,221,176,.10),transparent 68%)}
.foot a{color:var(--dark-ink);text-decoration:none}
.foot a:hover{color:var(--dark-accent)}
.foot__top{display:grid;grid-template-columns:1.6fr 1fr 1fr 1fr 1.15fr;gap:1.8rem;
  padding:var(--s5) 0 var(--s4)}
.foot h2,.foot h3,.foot .h3{font:600 11.5px/1.4 var(--sans);letter-spacing:.15em;
  text-transform:uppercase;color:var(--dark-accent);margin:0 0 1rem}
.foot ul{list-style:none;margin:0;padding:0;display:grid;gap:.55rem}
.foot .brand .nm{color:var(--dark-ink)}
.foot .brand .nm small{color:var(--dark-ink-3)}
.foot .brand .mark{background:linear-gradient(145deg,var(--dark-accent) 0%,var(--accent-fill) 100%);
  box-shadow:none;color:var(--dark)}
.foot__about{font-size:15px;line-height:1.65;color:var(--dark-ink-2);margin:1rem 0 0;
  max-width:40ch}
.foot__sub{color:var(--dark-ink-3);font-size:14px;line-height:1.55}
.foot__sub b{color:var(--dark-ink)}
.foot__strip{border-top:1px solid var(--dark-line);padding:1.35rem 0;display:flex;
  align-items:center;gap:1.1rem;flex-wrap:wrap;justify-content:space-between}
.foot__strip .seals{display:flex;gap:.55rem;align-items:center;flex-wrap:wrap}
/* the seal artwork is drawn for white paper; on a dark band each one gets its
   own small white chip rather than floating on the ground looking cut out */
.foot__strip .seals img{width:44px;height:44px;background:#fff;border-radius:12px;
  padding:4px;transition:transform var(--t-hover) var(--ease)}
.foot__strip .seals img:hover{transform:translateY(-3px)}
.foot__pay{border-top:1px solid var(--dark-line);padding:1.2rem 0;display:flex;
  align-items:center;gap:.9rem 1.6rem;flex-wrap:wrap}
.foot__pay img{background:#fff;border-radius:10px;padding:5px 8px}
.foot__pay p{margin:0;font-size:13px;line-height:1.55;color:var(--dark-ink-3);max-width:46ch}
.foot__legal{border-top:1px solid var(--dark-line);padding:1.35rem 0 1.4rem;font-size:13.5px;
  line-height:1.72;color:var(--dark-ink-3);display:grid;gap:.75rem}
.foot__legal b{color:var(--dark-ink-2);font-weight:700}
.foot__end{border-top:1px solid var(--dark-line);padding:1rem 0 1.2rem;display:flex;
  align-items:center;justify-content:space-between;gap:1rem;flex-wrap:wrap;
  font:500 12.5px/1.5 var(--sans);color:var(--dark-ink-3)}
.totop{display:inline-flex;align-items:center;gap:.5rem;color:var(--dark-ink);
  text-decoration:none;border:1px solid var(--dark-line);padding:.7rem 1rem;
  border-radius:var(--pill);min-height:44px;box-sizing:border-box;
  font:600 12px/1 var(--sans);letter-spacing:.1em;text-transform:uppercase;
  transition:background var(--t-hover) var(--ease),border-color var(--t-hover) var(--ease)}
.totop:hover{background:rgba(255,255,255,.07);border-color:var(--dark-accent)}
.totop svg{width:12px;height:12px;fill:none;stroke:currentColor;stroke-width:2.2;
  stroke-linecap:round;stroke-linejoin:round}

/* ---------- 13. the cost calculator ---------- */
.calc{border:1px solid var(--rule);background:var(--surface);box-shadow:var(--lift);
  border-radius:var(--radius);overflow:hidden}
/* The inputs appear only once interact.js has wired them up. Three selects
   that change nothing, under a note saying "it is an assumption you choose
   here", is worse than not offering the choice. The default row below is
   already a correct answer, and the table under it carries every combination. */
.calc__in{display:none;grid-template-columns:repeat(3,minmax(0,1fr));
  border-bottom:1px solid var(--rule);background:var(--bg-2)}
.calc--on .calc__in{display:grid}
.calc__f{padding:1.1rem 1.3rem;border-right:1px solid var(--rule);min-width:0}
.calc__f:last-child{border-right:0}
.calc__f label{display:block;margin:0 0 .5rem;font:600 10px/1.4 var(--sans);
  letter-spacing:.14em;text-transform:uppercase;color:var(--ink-3)}
.calc__f select,.calc__f input{width:100%;font:500 15px/1.3 var(--sans);color:var(--ink);
  background:var(--bg);border:1px solid var(--line);border-radius:10px;
  padding:.7rem .8rem;min-height:44px}
.calc__f input[type=range]{padding:0;border:0;background:transparent;accent-color:var(--accent-fill)}
.calc__f .v{display:block;margin-top:.45rem;font:600 13px/1.3 var(--mono);color:var(--ink)}
.calc__out{display:grid;grid-template-columns:repeat(4,minmax(0,1fr))}
.calc__o{padding:1.2rem 1.3rem;border-right:1px solid var(--rule);min-width:0}
.calc__o:last-child{border-right:0}
.calc__o dt{margin:0 0 .35rem;font:600 10px/1.4 var(--sans);letter-spacing:.14em;
  text-transform:uppercase;color:var(--ink-3)}
.calc__o dd{margin:0;font:800 clamp(1.15rem,2vw,1.6rem)/1.1 var(--display);
  letter-spacing:-.03em;color:var(--ink);font-variant-numeric:tabular-nums}
.calc__o dd small{display:block;margin-top:.25rem;font:400 11.5px/1.45 var(--sans);
  letter-spacing:0;color:var(--ink-3)}
.calc__note{border-top:1px solid var(--rule);background:var(--bg-2);padding:1rem 1.3rem;
  margin:0;font-size:13.5px;line-height:1.6;color:var(--ink-2)}
.calc__note b{color:var(--ink)}

/* ---------- 14. the label lightbox ---------- */
.zoom{position:relative;display:block;width:100%;padding:0;border:1px solid var(--rule);
  background:var(--surface);color:inherit;text-align:left;border-radius:var(--radius);
  overflow:hidden;box-shadow:var(--shadow)}
/* Same reasoning: no cursor and no "tap to enlarge" until there is something
   to tap. The image underneath is the whole picture at full width either way. */
.zoom--on{cursor:zoom-in}
.zoom__hint{display:none}
.zoom--on .zoom__hint{display:inline-flex}
.zoom img{width:100%;height:auto;display:block}
.zoom__hint{position:absolute;right:.55rem;bottom:.55rem;align-items:center;
  gap:.45rem;background:#122622;color:#F2F7F5;padding:.5rem .8rem;
  border-radius:var(--pill);backdrop-filter:blur(6px);
  font:600 10.5px/1 var(--sans);letter-spacing:.1em;text-transform:uppercase}
.zoom__hint svg{width:12px;height:12px;fill:none;stroke:currentColor;stroke-width:2.2;
  stroke-linecap:round}
.lb{position:fixed;inset:0;z-index:300;background:rgba(10,10,12,.93);
  grid-template-rows:auto minmax(0,1fr);padding:0;border:0;max-width:100%;max-height:100%;
  width:100%;height:100%}
/* [open] is load-bearing, not decoration. An author `display` declaration beats
   the UA stylesheet's dialog:not([open]){display:none} at any specificity, so a
   bare `.lb{display:grid}` leaves a closed dialog covering the whole page and
   swallowing every click underneath it. */
.lb[open]{display:grid}
.lb::backdrop{background:rgba(10,10,12,.93)}
.lb__bar{display:flex;align-items:center;justify-content:space-between;gap:1rem;
  padding:.8rem clamp(.9rem,3vw,1.6rem);border-bottom:1px solid rgba(255,255,255,.22);
  color:#BCCCC7;font:500 12.5px/1.5 var(--sans)}
/* The title is a full alt text. Left unclamped it wrapped to thirteen lines on
   a phone and took a third of the screen away from the thing being looked at. */
.lb__bar>p{min-width:0;margin:0}
.lb__bar b{color:#F2F7F5;display:block;overflow:hidden;
  display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2}
.lb__tools{display:flex;gap:.45rem;align-items:center}
.lb__tools{flex:none}
.lb__b{background:transparent;border:1px solid #93A5A0;color:#F2F7F5;
  font:600 11px/1 var(--sans);letter-spacing:.1em;text-transform:uppercase;
  padding:.55rem .7rem;cursor:pointer;white-space:nowrap}
.lb__b:hover{background:rgba(255,255,255,.22)}
.lb__b[aria-disabled=true]{color:#93A5A0;border-color:rgba(255,255,255,.22);
  cursor:default}
.lb__b:hover[aria-disabled=true]{background:transparent}
.lb__view{overflow:auto;overscroll-behavior:contain;padding:clamp(.6rem,2vw,1.4rem);
  display:grid;place-items:start center}
.lb__view:focus-visible{outline:2px solid var(--accent);outline-offset:-4px}
.lb__view img{max-width:none;width:calc(100% * var(--z,1));height:auto;
  transition:width var(--t-ui) var(--ease)}
.lb :focus-visible{outline-color:var(--accent)}

/* ====================================================================
   MOTION
   One rule governs everything below: animate TRANSFORM and OPACITY only.
   Both are composited, so none of this touches layout, none of it can move a
   neighbour, and the whole layer costs nothing on the main thread. Anything
   that would have animated a width, a height or a colour is drawn with a
   transform on a pseudo-element instead.

   Three guarantees hold across every rule here:
     - with JavaScript off, nothing is hidden: the .js-reveal class is added by
       main.js, and every selector below is scoped to it;
     - under prefers-reduced-motion the whole layer collapses to its end state
       in the block at the bottom of this file;
     - nothing animates a box that has not already been sized, so CLS stays 0.
   ==================================================================== */

/* ---------- the hero overture ---------- */
/* A short choreography on first paint, not on scroll - the hero is already in
   view, and waiting for an observer to fire would make it arrive late. Each
   step is a transform from a pre-set offset, so the finished layout is what
   the browser lays out and the motion is painted over the top of it. */
.js-reveal .hero__head>*{opacity:0;animation:heroRise .8s var(--ease) both}
.js-reveal .hero__head .eyebrow{animation-delay:.18s}
.js-reveal .hero__head h1{animation-delay:.26s}
.js-reveal .hero__head .hero__deck{animation-delay:.38s}
.js-reveal .hero__head .cta-row{animation-delay:.48s}
.js-reveal .hero__head .microcopy{animation-delay:.56s}
@keyframes heroRise{from{opacity:0;transform:translateY(16px)}to{opacity:1;transform:none}}
@keyframes drawX{to{transform:scaleX(1)}}
@keyframes popIn{from{opacity:0;transform:rotate(45deg) scale(.4)}
                 to{opacity:1;transform:rotate(45deg) scale(1)}}

/* the gold word: a single light sweep once the headline has landed */
.hero h1 em{position:relative;background-size:200% 100%}
.js-reveal .hero h1 em{animation:foilSweep 1.5s var(--ease) .75s both}
@keyframes foilSweep{from{background-position:120% 0}to{background-position:0 0}}

/* the bottle: rises in, then breathes. The float is 6px over 7 seconds -
   enough to read as alive, far too slow to read as motion. */
.js-reveal .hero__shot{opacity:0;animation:heroRise 1s var(--ease) .5s both,
  bottleFloat 7s ease-in-out 1.5s infinite}
@keyframes bottleFloat{0%,100%{translate:0 0}50%{translate:0 -6px}}
/* the glow behind it pulses on the opposite phase, which reads as the light
   staying still while the bottle moves through it */
.js-reveal .hero__shot::before{animation:glowPulse 7s ease-in-out 1.5s infinite}
@keyframes glowPulse{0%,100%{opacity:1;scale:1}50%{opacity:.82;scale:1.04}}

/* the hairline frame draws itself from the top-left corner */
@keyframes frameDraw{to{clip-path:inset(0 0 0 0)}}

/* ---------- counters ---------- */
/* The number is in the HTML. JavaScript only animates the digits between 0 and
   the value already there, so a reader without JS sees the final figure and a
   reader with JS sees it arrive. The span is inline-block with a min-width in
   ch set by main.js from the final string, so the digits cannot reflow the
   line while they count. */
.count{display:inline-block;font-variant-numeric:tabular-nums;text-align:left}

/* ---------- the act rule ---------- */
/* The 2.6s backstop in main.js adds .in to everything, so these can never be
   stranded - but they are also only ever hidden under .js-reveal, which is
   added by that same file. If it does not run, nothing below applies. */
.js-reveal .act .act__rule{transform:scaleX(0);transform-origin:left}
.js-reveal .act.in .act__rule{animation:drawX .7s var(--ease) both}
.js-reveal .act .act__no i{opacity:0}
.js-reveal .act.in .act__no i{animation:heroRise .6s var(--ease) .18s both}

/* ---------- cards: the gold hairline sweeps in ---------- */
.js-reveal .card::before{transform:scaleX(0);transform-origin:left}
.js-reveal .stagger.in .card::before,
.js-reveal .card.in::before{animation:drawX .6s var(--ease) .2s both}
.card{transition:transform var(--t-hover) var(--ease),box-shadow var(--t-hover) var(--ease),
  border-color var(--t-hover) var(--ease)}
.card:hover{box-shadow:var(--lift),0 0 0 1px rgba(232,181,92,.22)}

/* ---------- buttons: a gold sheen crosses on hover ---------- */
.btn{position:relative;overflow:hidden;isolation:isolate}
.btn::before{content:"";position:absolute;inset:0;z-index:-1;pointer-events:none;
  background:linear-gradient(100deg,transparent 20%,rgba(255,255,255,.38) 50%,transparent 80%);
  transform:translateX(-120%)}
.btn:hover::before{animation:sheen .7s var(--ease)}
@keyframes sheen{to{transform:translateX(120%)}}
.btn--ghost::before{background:linear-gradient(100deg,transparent 20%,
  rgba(232,181,92,.22) 50%,transparent 80%)}

/* ---------- the scale figure draws itself ---------- */
/* Each bar is scaled from its left edge rather than having its width animated,
   so the whole figure is one composited transform per bar. */
.js-reveal .scale rect{transform:scaleX(0);transform-origin:left;transform-box:fill-box}
.js-reveal .fig.in .scale rect{animation:drawX .8s var(--ease) both}
.js-reveal .fig.in .scale rect:nth-of-type(2){animation-delay:.05s}
.js-reveal .fig.in .scale rect:nth-of-type(3){animation-delay:.1s}
.js-reveal .fig.in .scale rect:nth-of-type(4){animation-delay:.15s}
.js-reveal .fig.in .scale rect:nth-of-type(5){animation-delay:.2s}
.js-reveal .fig.in .scale rect:nth-of-type(6){animation-delay:.25s}
.js-reveal .fig.in .scale rect:nth-of-type(7){animation-delay:.3s}
.js-reveal .fig.in .scale rect:nth-of-type(8){animation-delay:.35s}
.js-reveal .fig.in .scale rect:nth-of-type(n+9){animation-delay:.4s}
/* the dashed caffeine line is the point of the picture, so it draws last and
   on its own, downwards */
.js-reveal .scale line[stroke-dasharray]{transform:scaleY(0);transform-origin:top;
  transform-box:fill-box}
.js-reveal .fig.in .scale line[stroke-dasharray]{animation:drawY .6s var(--ease) .5s both}
@keyframes drawY{to{transform:scaleY(1)}}
.js-reveal .scale circle{opacity:0}
.js-reveal .fig.in .scale circle{animation:popDot .5s var(--ease) .35s both}
@keyframes popDot{from{opacity:0;transform:scale(.3)}to{opacity:1;transform:scale(1)}}

/* ---------- the supplied frame: its hatching drifts, very slowly ---------- */
.js-reveal .supplied::before{background-size:28px 28px;animation:drift 24s linear infinite}
@keyframes drift{to{background-position:28px 28px}}

/* ---------- section headings rise with their rule ---------- */
.js-reveal .sec-head .kicker::before{transform:scaleX(0);transform-origin:left}
.js-reveal .reveal.in .sec-head .kicker::before,
.js-reveal .sec-head.in .kicker::before{animation:drawX .6s var(--ease) both}

/* ---------- the spec strip counts up as it arrives ---------- */
.js-reveal .spec div{opacity:0}
.js-reveal .spec.in div{animation:heroRise .6s var(--ease) both}
.js-reveal .spec.in div:nth-child(2){animation-delay:.08s}
.js-reveal .spec.in div:nth-child(3){animation-delay:.16s}
.js-reveal .spec.in div:nth-child(4){animation-delay:.24s}

/* ---------- pack cards lift as a group ---------- */
.pack{transition:transform var(--t-hover) var(--ease),box-shadow var(--t-hover) var(--ease),
  border-color var(--t-hover) var(--ease)}
.pack:hover{box-shadow:var(--lift),0 0 0 1px rgba(232,181,92,.3)}

/* ---------- scroll-driven, where the browser will run it for free ---------- */
@supports (animation-timeline: view()){
  @media (prefers-reduced-motion: no-preference){
    /* the hero bottle drifts a little slower than the page it sits on */
    .js-reveal .hero__shot img{animation:heroPara linear both;
      animation-timeline:view();animation-range:cover 0% cover 100%}
    @keyframes heroPara{from{translate:0 -14px}to{translate:0 14px}}
  }
}

/* ---------- scroll reveal ---------- */
.js-reveal .reveal{opacity:0;transform:translateY(22px);
  transition:opacity var(--t-reveal) var(--ease),transform var(--t-reveal) var(--ease)}
.js-reveal .reveal.in{opacity:1;transform:none}
.js-reveal .stagger.in>*{animation:rise var(--t-reveal) var(--ease) both}
.js-reveal .stagger.in>*:nth-child(1){animation-delay:.04s}
.js-reveal .stagger.in>*:nth-child(2){animation-delay:.1s}
.js-reveal .stagger.in>*:nth-child(3){animation-delay:.16s}
.js-reveal .stagger.in>*:nth-child(4){animation-delay:.22s}
.js-reveal .stagger.in>*:nth-child(5){animation-delay:.28s}
.js-reveal .stagger.in>*:nth-child(6){animation-delay:.34s}
.js-reveal .stagger.in>*:nth-child(7){animation-delay:.4s}
.js-reveal .stagger.in>*:nth-child(8){animation-delay:.46s}
.js-reveal .stagger.in>*:nth-child(n+9){animation-delay:.52s}
@keyframes rise{from{opacity:0;transform:translateY(18px)}to{opacity:1;transform:none}}
.js-reveal .tbl-wrap.in tbody tr{animation:rowIn .5s var(--ease) both}
.js-reveal .tbl-wrap.in tbody tr:nth-child(1){animation-delay:.05s}
.js-reveal .tbl-wrap.in tbody tr:nth-child(2){animation-delay:.1s}
.js-reveal .tbl-wrap.in tbody tr:nth-child(3){animation-delay:.15s}
.js-reveal .tbl-wrap.in tbody tr:nth-child(4){animation-delay:.2s}
.js-reveal .tbl-wrap.in tbody tr:nth-child(5){animation-delay:.25s}
.js-reveal .tbl-wrap.in tbody tr:nth-child(n+6){animation-delay:.3s}
@keyframes rowIn{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:none}}
/* Each section carries its OWN measured height in --cvh, written into the
   markup after the build by cvsize.js; the 700px here is only the fallback for
   a section that pass never saw. A single flat figure was wrong in both
   directions - the home page ran 36% short, pricing 15% long - and a document
   whose height moves while you scroll it is a scrollbar that moves under your
   cursor. `auto` means the browser swaps in the real height the moment the
   section renders, so these figures only govern the first pass. */
.cv{content-visibility:auto;contain-intrinsic-size:auto var(--cvh,700px)}
main>section.cv:nth-of-type(-n+3){content-visibility:visible}

/* Scroll-driven, run by the browser on the compositor. */
@supports (animation-timeline: view()){
  @media (prefers-reduced-motion: no-preference){
    /* The range is an ABSOLUTE LENGTH, not a percentage. A percentage range
       is measured against the element's own height, so a tall block - the
       ten supplied review cards, a long table - only finishes its entrance
       after scrolling its whole height. Measured on reviews.html: a block
       sat at 0.48 opacity with its top 322px into the viewport and stayed
       there while the reader scrolled through it. 320px of scroll completes
       the entrance now, whatever the element is. */
    .js-reveal .reveal{opacity:1;transform:none;transition:none;
      animation:rise linear both;animation-timeline:view();
      animation-range:entry 40px entry 320px}
    .js-reveal .reveal.in{opacity:1;transform:none}
    .js-reveal .stagger>*,
    .js-reveal .stagger.in>*{animation:rise linear both;animation-timeline:view();
      animation-range:entry 30px entry 300px;animation-delay:0s}
    /* Table rows are deliberately NOT scroll-driven: .tbl-wrap is
       overflow-x:auto, so view() resolves against the table's own scroller,
       whose block axis never moves, and every row freezes part-way through.
       They stay on the IntersectionObserver path. */
    .progress{animation:grow linear both;animation-timeline:scroll(root block);transition:none}
    @keyframes grow{from{transform:scaleX(0)}to{transform:scaleX(1)}}
  }
}

.drawer__x{display:none}

/* ---------- responsive ---------- */
@media(max-width:1400px){
  .head .tel{display:none}
  .nav a{padding:.5rem .5rem;font-size:13px}
}
@media(max-width:1060px){
  .nav{display:none}
  .burger{display:grid;margin-left:auto}
  .drawer{display:block;position:fixed;inset:var(--head-h) 0 0;z-index:88;background:var(--bg);
    padding:1.2rem 1.25rem 3rem;overflow:auto;transform:translateX(100%);visibility:hidden;
    transition:transform var(--t-ui) var(--ease),visibility var(--t-ui)}
  .drawer--on{transform:none;visibility:visible;
    transition:transform var(--t-ui) var(--ease),visibility 0s}
  .drawer ul{list-style:none;margin:0 0 1.2rem;padding:0;display:grid;gap:.1rem}
  .drawer a{display:block;padding:.85rem .65rem;color:var(--ink);text-decoration:none;
    font-size:15px;font-weight:600;border-bottom:1px solid var(--rule)}
  .drawer a:hover{color:var(--accent)}
  .drawer__x{display:flex;align-items:center;gap:.5rem;margin:0 0 1rem auto;
    background:transparent;border:1px solid var(--line);border-radius:var(--radius-sm);
    color:var(--ink-2);font:600 12px/1 var(--sans);letter-spacing:.1em;
    text-transform:uppercase;padding:.6rem .8rem;cursor:pointer}
  .drawer__x:hover{color:var(--ink);border-color:var(--accent)}
  .drawer__x svg{width:14px;height:14px;stroke:currentColor;stroke-width:2;fill:none}
}
@media(max-width:960px){
  .hero .eyebrow{justify-self:start;margin-bottom:1rem}
.scrolly{grid-template-columns:minmax(0,1fr)}
  .scrolly--on .scrolly__figure{position:static}
  .g4{grid-template-columns:repeat(2,minmax(0,1fr))}
  .foot__top{grid-template-columns:repeat(2,minmax(0,1fr));gap:1.8rem}
  .split{align-items:start}
}
@media(max-width:820px){
  .g3,.g2{grid-template-columns:minmax(0,1fr)}
.split{grid-template-columns:minmax(0,1fr)}
  .packs{grid-template-columns:minmax(0,1fr);max-width:420px;margin-inline:auto}
  .pack--best{order:-1}
  .fitcheck__q{flex-direction:column;gap:.7rem}
}
@media(max-width:760px){
  .strip .m-hide{display:none}
  .head .btn--primary{display:none}
  .brand .nm{font-size:17px}
  .head .wrap{gap:.6rem}
}
@media(max-width:560px){
  .brand .nm{font-size:15.5px}
  .brand .nm small{font-size:8.5px;letter-spacing:.08em}
  .brand .mark{width:34px;height:34px}
  .head .wrap{gap:.7rem}
  body{font-size:16.5px}
.wrap,.mid{width:calc(100% - 2rem)}
  .g4{grid-template-columns:minmax(0,1fr)}
  .foot__top{grid-template-columns:minmax(0,1fr)}
  .cta-row .btn{width:100%}
  .buybar__txt span{display:none}
  /* three lines of strip is a third of a phone screen spent before the
     headline; below this width it keeps the guarantee and the number */
  .strip .s-hide{display:none}
  .strip .wrap{font-size:11px;gap:.35rem .9rem}
  .fitcheck{padding:1.25rem 1.15rem}
  .secnav{width:100%;justify-content:flex-start;overflow-x:auto;flex-wrap:nowrap}
}

/* --- the spotlight hero, folded down --- */
@media(max-width:1060px){
  .dossier{grid-template-columns:150px minmax(0,1fr)}
  .calc__out{grid-template-columns:repeat(2,minmax(0,1fr))}
}
@media(max-width:1000px){
  /* One column, and the bottle goes DIRECTLY AFTER THE H1 rather than after
     the whole copy block. On a phone the headline and the product are the two
     things worth seeing first; pushing the image below the deck, the buttons
     and the microcopy meant three scrolls before the reader saw what they
     were buying.

     display:contents promotes the head's own children to flex items of the
     same column, which is what lets the slab be ordered between the headline
     and the deck without moving anything in the markup - so the source order,
     and therefore the reading order for a screen reader, is untouched.
     gap is 0 because each child already carries its own margin; a flex gap
     here would double every one of them. */
  .hero__cols{display:flex;flex-direction:column;gap:0}
  .hero__head{display:contents}
  .hero .eyebrow{order:1}
  .hero__head h1{order:2}
  .hero__slab{order:3;margin:clamp(1.1rem,3vw,1.6rem) 0 clamp(1.3rem,3.4vw,1.9rem)}
  .hero__deck{order:4}
  .hero .cta-row{order:5}
  .hero .reassure{order:6}
  .hero .microcopy{order:7}
  .hero__shot{margin-inline:auto}
  .shot img{width:min(100%,250px)}
  .foot__top{grid-template-columns:1.4fr 1fr 1fr}
}
@media(max-width:760px){
  .cv{contain-intrinsic-size:auto var(--cvh-m,1200px)}
  /* below this width the index rail stops being a rail: sticky in a single
     column just eats the viewport, so it becomes a scrollable row of chips */
  .dossier{grid-template-columns:minmax(0,1fr);gap:.9rem}
  .dossier>nav{position:static}
  .idx{border-left:0;border-bottom:1px solid var(--line);max-height:none;
    grid-auto-flow:column;grid-auto-columns:max-content;overflow-x:auto;
    padding-bottom:.4rem;gap:.3rem}
  .idx a{grid-template-columns:auto;border-left:0;border-bottom:2px solid transparent;
    margin-left:0;white-space:nowrap;padding:.5rem .6rem}
  .idx a.is-on{border-left-color:transparent;border-bottom-color:var(--accent);
    border-radius:var(--radius-sm) var(--radius-sm) 0 0}
  .calc__in{grid-template-columns:minmax(0,1fr)}
  .calc__f{border-right:0;border-bottom:1px solid var(--rule)}
  .calc__f:last-child{border-bottom:0}
  .foot__top{grid-template-columns:1fr 1fr}
  .readout li{grid-template-columns:minmax(0,1fr) 4.6rem}
}
@media(max-width:560px){
  .spot{grid-template-columns:minmax(0,1fr)}
  .shot{border-radius:20px}
  .calc__out{grid-template-columns:minmax(0,1fr)}
  .calc__o{border-right:0;border-bottom:1px solid var(--rule)}
  .calc__o:last-child{border-bottom:0}
  .foot__top{grid-template-columns:minmax(0,1fr)}
  .readout{padding:.9rem}
  .sixty li{grid-template-columns:1.8rem minmax(0,1fr);gap:.7rem}
}

/* ---------- reduced motion ---------- */
@media(prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-duration:.001ms!important;animation-iteration-count:1!important;
    transition-duration:.001ms!important;scroll-behavior:auto!important}
  /* The whole motion layer collapses to its END state. Every rule above sets a
     transform or an opacity, so clearing both is enough - and it has to be
     done explicitly, because animation-duration:.001ms leaves the element at
     the animation's start if the animation never actually runs. */
  .js-reveal .hero__head>*,
  .js-reveal .hero__shot,.js-reveal .spec div,.js-reveal .act .act__no i,
  .js-reveal .scale circle,.js-reveal .asteps .astep__n,
  .js-reveal .asteps .astep__b{opacity:1!important;transform:none!important}
  .js-reveal .act .act__rule,.js-reveal .card::before,
  .js-reveal .sec-head .kicker::before,.js-reveal .scale rect,
  .js-reveal .astep:not(:last-child)::before{transform:scaleX(1)!important}
  .js-reveal .scale line[stroke-dasharray]{transform:scaleY(1)!important}
  .js-reveal .scale rect{transform:scaleX(1)!important}
    .js-reveal .hero__shot img{translate:0!important}
  .js-reveal .supplied::before{animation:none!important}
  .btn::before{display:none}
  .hero h1 em{background-position:0 0!important}
  .js-reveal .reveal{opacity:1!important;transform:none!important}
  .js-reveal .stagger.in>*,.js-reveal .stagger>*{animation:none!important}
  .js-reveal .tbl-wrap.in tbody tr{animation:none!important}
  .lb__view img{transition:none}
  .flip--on.is-flipped .flip__b,.tabs--on [role=tabpanel],.fitcheck__out.is-in,
  .explorer--on [data-ex-panel]{animation:none!important}
  .ticker__row{animation:none!important}
  .btn:hover::after{translate:0}
}
@media print{
  /* The screen theme is already ink on warm paper, so print only has to do
     four things: take the chrome off, turn the three DARK surfaces (the
     60-second block, the counterpoint band and the footer) back to paper,
     drop every shadow and glow, and give the body column the whole sheet. */
  :root{--bg:#FFFFFF; --bg-2:#FFFFFF; --surface:#FFFFFF; --tint:#F4F7F5;
    --shadow:none; --lift:none; --glow:none}
  html,body{background:#FFFFFF;color:#2A3633}
  .head,.strip,.buybar,.drawer,.drawer__x,.progress,.secnav,.carousel__nav,.ticker,
  .ticker__stop,.faqfilter__bar,.totop,.lb{display:none}
  /* these are shown by .calc--on / .zoom--on, which is (0,2,0); a bare
     .calc__in here at (0,1,0) loses to it even inside @media print */
  .calc--on .calc__in,.zoom--on .zoom__hint,
  .carousel--on .carousel__nav,.faqfilter--on .faqfilter__bar{display:none}
  /* the three dark surfaces. Printing a dark block wastes a cartridge and
     prints as a grey slab anyway, because backgrounds are off by default and
     the light ink on them is not. */
  .sixty,.band-dark,.foot{background:#FFFFFF!important;background-image:none!important;
    color:#2A3633!important;border:1px solid #C9D2CF}
  .sixty h2,.sixty .h3,.sixty li b,.band-dark h2,.band-dark h3,.foot a,.foot__sub b,
  .band-dark .card h3{color:#101A17!important}
  .sixty li,.band-dark p,.band-dark .lede,.foot__about,.foot__legal{color:#2A3633!important}
  .sixty li::before,.sixty__t,.foot h2,.foot h3,.foot .h3,.band-dark a{color:#07553F!important}
  .sixty li+li,.foot__strip,.foot__pay,.foot__legal,.foot__end{border-color:#D7DEDB!important}
  .band-dark .card,.band-dark .note{background:#FFFFFF!important}
  .card,.note,.pack,.sixty,.calc,.calc__o,.calc__f,.figpill,.readout,.shot,.exhibit,
  .fitcheck,.zoom,.tbl-wrap,.fig img,.faq details{box-shadow:none!important}
  .hero__slab::after,.shot::before,.card::before{display:none}
  /* the rail is screen furniture: in print it is a dead column that leaves the
     body 572px for a 680px table, and the percentages print sliced in half */
  .dossier{grid-template-columns:minmax(0,1fr)!important;gap:1.2rem}
  .dossier>nav{display:none}
  .idx{position:static;display:none}
  /* the panels are restored below, so their headings have to come back with
     them - otherwise three answers print as one paragraph - and the tab strip
     itself has to go, because on paper it is ink that does nothing */
  .tabs--on .tabs__h,.explorer--on .explorer__h{display:block!important}
  .tabs__list,.explorer__list{display:none}
  .readout__bar i{border:1px solid #000}
  .js-reveal .reveal{opacity:1!important;transform:none!important;animation:none!important}
  .js-reveal .stagger>*{animation:none!important;opacity:1!important}
  .cv{content-visibility:visible!important}
  .foot{padding-bottom:0}
  .tbl-wrap,.scale-wrap,.carousel__track{overflow:visible!important}
  /* the scroller is gone in print, so anything wider than the sheet is simply
     cut off it - a column header that refuses to wrap took the last column of
     eleven tables off the page */
  table{min-width:0!important;font-size:12.5px}
  thead th{white-space:normal}
  .scale{min-width:0}
  /* and the carousel, whose items are laid out in a row 1,360-2,048px wide:
     on paper they stack */
  .carousel__track{display:block!important}
  .carousel__item{width:auto!important;break-inside:avoid;margin-bottom:1rem}
  .flip__in{display:block!important}
  .flip--on .flip__b,.tabs--on [role=tabpanel][hidden],.hotspot__panel[hidden],
  .explorer--on [data-ex-panel][hidden],.scrolly--on .scrolly__layer{
    display:block!important;visibility:visible!important;opacity:1!important}
  .flip__btn{display:none}
  .scrolly--on .scrolly__figure{position:static}
  .pack--best{transform:none!important}
}

/* ---------- forced colors ---------- */
@media(forced-colors:active){
  /* -webkit-text-fill-color:transparent survives a forced palette, so the
     gradient word in the headline would print as nothing at all */
  .hero h1 em{-webkit-text-fill-color:currentColor;background:none;color:CanvasText}
  .scale text{fill:CanvasText}
  .scale rect{fill:Canvas;stroke:CanvasText}
  .scale circle{fill:CanvasText}
  .scale line{stroke:CanvasText}
  /* the diamonds and bars carry meaning as fills, and a fill is what
     forced colors throws away first */
  .scale path,.scale rect,.scale circle{forced-color-adjust:none}
.tag::before{forced-color-adjust:none}
  /* the arrow inherits currentColor, which forced colors resolves for us */
  .btn::after{background:ButtonText}
  .tag,.card,.note,.pack,.fitcheck,.scrolly__step,.scrolly__figure,
  .sixty,.calc,.calc__f,.calc__o,.zoom,.figpill,.readout,.shot{
    border:1px solid CanvasText}
  .btn,.lb__b,.totop{border:1px solid ButtonText}
  /* the readout bars carry the finding, so they must survive a palette that
     throws every background away */
  .readout__bar{border:1px solid CanvasText}
  .readout__bar i{forced-color-adjust:none;background:Highlight}
  .readout li.is-over .readout__bar i{background:Highlight;outline:2px solid CanvasText;
    outline-offset:-2px}
  /* the 100%-of-the-Daily-Value mark is a 1px background stripe */
  .readout__bar::after{background:CanvasText;forced-color-adjust:none;width:2px}
  /* the legend keys are 10px background chips; without this the legend reads
     as two unlabelled bullet points */
  .readout__key i{forced-color-adjust:none;border:1px solid CanvasText}
  .readout__key li:first-child i{background:Canvas}
  .readout__key li+li i{background:Highlight}
  .hotspots--on .hotspot.is-on{forced-color-adjust:none;background:Highlight;color:Canvas}
  /* the reskin's new surfaces: a gradient, a radial wash and a dot leader all
     paint as background, which is the first thing a forced palette throws out */
  .hero__slab,.shot::before,.band-dark,.sixty,.foot{background-image:none!important}
  .card::before{forced-color-adjust:none;background:Highlight}
  .btn.btn--primary{forced-color-adjust:none;background:Highlight;color:HighlightText}
  .tabs__list,.explorer__list{border:1px solid CanvasText}
  .tabs__list button[aria-selected=true],.explorer__list button[aria-selected=true]{
    forced-color-adjust:none;background:Highlight;color:HighlightText}
  .explorer__list button i{forced-color-adjust:none;background:CanvasText}
  .explorer__list button[aria-selected=true] i{background:HighlightText}
  .faq summary::before{forced-color-adjust:none;background:Canvas;
    box-shadow:inset 0 0 0 1px CanvasText}
  .faq details[open] summary::before{background:Highlight}
  .faq details[open] summary::after{border-color:HighlightText}
  .pack__perks li::before{forced-color-adjust:none;background:Canvas;
    box-shadow:inset 0 0 0 1.5px CanvasText}
  .foot__strip .seals img,.foot__pay img{background:Canvas}
  .brand .mark{forced-color-adjust:none;background:Highlight;color:HighlightText}
  .idx a.is-on{border-left-color:Highlight}
}


/* ---------- the surfaces the slots sit in ---------- */
/* These are this site's own, and they are the only part of the slot system
   that is allowed to match the navy. */
.byline__rev{display:flex;flex-wrap:wrap;align-items:center;gap:.4rem .7rem;
  margin:.55rem 0 0;font-size:12.5px;line-height:1.7;color:var(--ink-3)}
.byline__rk{font:700 10.5px/1 var(--sans);letter-spacing:.12em;text-transform:uppercase;
  color:var(--accent)}
.pagecheck{border-top:1px solid var(--rule);background:var(--bg-2);
  padding:clamp(1.3rem,2.4vw,1.9rem) 0}
.pagecheck__h{margin:0 0 .5rem;font:700 10.5px/1 var(--sans);letter-spacing:.14em;
  text-transform:uppercase;color:var(--accent)}
.pagecheck__p{margin:0 0 .45rem;font-size:13.5px;line-height:1.7;color:var(--ink-2);
  max-width:86ch}
.pagecheck__n{margin:.5rem 0 0;font-size:12.5px;line-height:1.65;color:var(--ink-3);
  max-width:80ch}
/* the rating summary: a score, a count and five bars, every figure a blank */
.rs{display:grid;grid-template-columns:auto minmax(0,1fr);gap:1.1rem 1.6rem;
  align-items:center;margin:0 0 1rem;padding:1.1rem 1.2rem;background:var(--surface);
  border-radius:var(--radius);border-top:2px solid var(--accent)}
.rs__score{margin:0;font:700 clamp(1.9rem,3.4vw,2.5rem)/1 var(--display);color:var(--ink)}
.rs__scale,.rs__n{margin:.3rem 0 0;font-size:12px;line-height:1.5;color:var(--ink-3)}
.rs__bars{list-style:none;margin:0;padding:0;display:grid;gap:.42rem}
.rs__bars li{display:grid;grid-template-columns:6.4rem minmax(0,1fr) auto;gap:.6rem;
  align-items:center}
.rs__k{font:600 11.5px/1 var(--sans);color:var(--ink-3)}
.rs__t{height:8px;border-radius:999px;background:var(--tint);overflow:hidden}
.rs__t i{display:block;height:100%;background:var(--foil)}
.rs__v{font:600 12px/1 var(--mono);color:var(--ink-2)}
/* the six empty review cards */
/* the pasted .rvw--slot rule hangs its "Fill in" tab 11px above the card, so
   the card cannot clip its own overflow - .card does by default here */
.rvw{display:grid;gap:.6rem;align-content:start}
.rvw--slot{overflow:visible;margin-top:11px}
.rvw__head{display:flex;align-items:center;gap:.7rem}
.rvw__av{width:44px;height:44px;border-radius:50%;flex:none;background:var(--tint);
  border:1px dashed var(--line)}
.rvw h3{margin:0;font-size:1rem}
.rvw__meta,.rvw__foot{margin:0}
.rvw blockquote{margin:0}
@media(max-width:560px){
  .rs{grid-template-columns:minmax(0,1fr)}
  .rs__bars li{grid-template-columns:5.6rem minmax(0,1fr) auto;gap:.45rem}
}


/* ---------- the buy path ----------
   Everything here is about making the one action on the page easy to find and
   easy to trust. Nothing here invents a reason to hurry: no countdown, no
   stock figure, no claim about other buyers, because none of those was
   supplied with this stock and check.py refuses all three on sight. What a
   buy button can honestly carry is the price, what happens if the buyer is
   wrong, and what actually arrives - so that is what it carries. */
/* the mid-page nudge: one line, one button, the same three facts */
.ctamid{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:1rem 1.6rem;
  align-items:center;padding:1.15rem 1.3rem;background:var(--surface);
  border-radius:var(--radius);border-left:3px solid var(--accent)}
.ctamid p{margin:0;font-size:14px;line-height:1.6;color:var(--ink-2)}
.ctamid b{color:var(--ink)}
.ctamid .reassure{justify-content:flex-start;margin:.5rem 0 0;gap:.35rem 1rem}
.ctamid .reassure li{font-size:11.5px}
@media(max-width:700px){
  .ctamid{grid-template-columns:minmax(0,1fr)}
  .ctamid .btn{width:100%}
}

/* the medical-review block at the foot of every page */
.pagecheck__grid{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,.9fr);
  gap:1.2rem 2.4rem;align-items:start}
.pagecheck__rev{padding-left:1.6rem;border-left:1px solid var(--rule)}
.pagecheck__rev .pagecheck__p{display:flex;flex-wrap:wrap;align-items:baseline;gap:.3rem .6rem;
  margin-bottom:.4rem}
.pagecheck__k{font:700 10px/1.6 var(--sans);letter-spacing:.12em;text-transform:uppercase;
  color:var(--accent);min-width:7.2rem;flex:none}
/* one flex child, so the comma between the name and the credentials is not
   pushed away from the name by the row gap */
.pagecheck__v{min-width:0}
@media(max-width:820px){
  .pagecheck__grid{grid-template-columns:minmax(0,1fr)}
  .pagecheck__rev{padding-left:0;border-left:0;border-top:1px solid var(--rule);
    padding-top:1.1rem}
  .pagecheck__k{min-width:6.4rem}
}

/* ---------- the modern surface pass ----------
   Everything below the fold that was a flat fill with a square corner. The
   rule is the same one the cards follow: a lit gradient, a hairline, an inner
   top highlight, a real shadow, and a hover that lifts rather than recolours. */
.pack{background:var(--grad-card);box-shadow:var(--sh-2),var(--ring);
  border-radius:var(--radius);transition:transform var(--t-hover) var(--ease),
    box-shadow var(--t-hover) var(--ease),border-color var(--t-hover) var(--ease)}
.pack--best{border-color:var(--accent-fill);box-shadow:var(--glow),var(--sh-2),var(--ring)}
@media (hover:hover) and (pointer:fine){
  .card:hover{transform:translateY(-3px);box-shadow:var(--sh-2),var(--ring);
    border-color:var(--accent-deep)}
  .kr .card:hover{border-color:var(--accent)}
  .pack:hover{transform:translateY(-4px);box-shadow:var(--sh-3),var(--ring)}
}
.fitcheck,.calc,.exhibit .tbl-wrap,.supplied,.answer,.scrolly__step,.rs,.ctamid{
  border-radius:var(--radius)}
.supplied{background:var(--grad-card);box-shadow:var(--sh-1),var(--ring)}
.answer{box-shadow:var(--sh-1),var(--ring);background:var(--grad-tint)}
.ctamid{background:var(--grad-tint);box-shadow:var(--sh-2),var(--ring);
  border-left:0;position:relative;overflow:hidden}
.ctamid::before{content:"";position:absolute;inset:0 auto 0 0;width:3px;
  background:linear-gradient(180deg,var(--accent),var(--accent-deep))}
.rs{background:var(--grad-card);box-shadow:var(--sh-1),var(--ring)}
.tag{border-radius:var(--pill)}
.eyebrow,.kicker,.exhibit__no{letter-spacing:.14em}
.eyebrow{border-radius:var(--pill);background:var(--grad-tint);box-shadow:var(--ring)}
.idx a{border-radius:var(--radius-xs)}
.buybar{box-shadow:0 -2px 10px rgba(0,0,0,.3), 0 -20px 50px -30px rgba(0,0,0,.8)}
.head--float{box-shadow:0 1px 0 rgba(232,181,92,.16), 0 12px 30px -18px rgba(0,0,0,.72)}
.pagecheck{background:var(--grad-bg2)}

/* footer column heads get an icon well, and the footer gets the same wash */
.foot__h{display:flex;align-items:center;gap:.5rem}
.foot__h .ico{color:var(--dark-accent)}

/* section heads: the kicker becomes a chip with an icon */
.kicker{display:inline-flex;align-items:center;gap:.45rem}

/* tables and figures stop being boxes and become panels */
.tbl-wrap{border-radius:var(--radius);box-shadow:var(--sh-1)}
.fig,figure.fig{border-radius:var(--radius);overflow:hidden}
.spec{border-radius:var(--radius);overflow:hidden;box-shadow:var(--sh-1),var(--ring)}

/* a figure scales up gently as it arrives, which a bar chart cannot do by
   growing its bars alone */
.js-reveal .fig.in,.js-reveal .zoom.in{animation:figIn .7s var(--ease) both}
@keyframes figIn{from{opacity:0;transform:translateY(18px) scale(.985)}
  to{opacity:1;transform:none}}

/* ---------- disclosure content never animates in ----------
   A scroll-driven timeline cannot run for an element inside a CLOSED
   <details>: while the disclosure is shut the element has no box, the
   timeline is inactive, and the animation holds at its from-state - opacity
   0. Opening the disclosure then reveals nothing. Measured on pricing.html:
   one 254px table and three rows stuck at opacity 0 with the disclosure open
   and the table squarely in the viewport.
   The open gesture IS the reveal, so content inside a disclosure gets no
   entrance of its own. This also covers the reduced-motion and no-JS paths,
   which were already correct, by making all three agree. */
details .reveal,details .act,details .sec-head,details .fig,
details tr,details .scale rect,details .count{
  animation:none!important;opacity:1!important;transform:none!important;
  clip-path:none!important}
