/* ==== font fallback metrics (fix_font_shift.py) ==== */
@font-face{font-family:"Domine Fallback";src:local("Georgia");font-weight:400;size-adjust:109.80%;ascent-override:81.97%;descent-override:21.86%;line-gap-override:0.00%}
@font-face{font-family:"Domine Fallback";src:local("Georgia Bold");font-weight:600 900;size-adjust:96.11%;ascent-override:93.64%;descent-override:24.97%;line-gap-override:0.00%}
@font-face{font-family:"Overpass Fallback";src:local("Arial");font-weight:400;size-adjust:101.15%;ascent-override:87.29%;descent-override:37.86%;line-gap-override:0.00%}
@font-face{font-family:"Overpass Fallback";src:local("Arial Bold");font-weight:600 900;size-adjust:98.09%;ascent-override:90.02%;descent-override:39.05%;line-gap-override:0.00%}
/* ==== end font fallback metrics ==== */
/* glproroutine.com - GLPro, USA Authorized Retailer desk.

   Design slot row 36 (_generators/batch7_assignments.py):
   Domine / Overpass, chalk white with terracotta bands, the bottle centred on a
   terracotta disc with the copy wrapped beneath it in two columns, a long soft
   shadow to one side, a two-row header whose upper row is the terracotta trust
   rule, and a footer that is a terracotta contact band over a white
   three-column link grid. Hero motif: pulse-column.

   WHERE THE COLOUR COMES FROM
   The bottle is white with a deep petrol-teal label band and a thin warm cream
   rule. Petrol teal is the live sister desk's accent (glprodaily is teal + gold
   on mint-white), so it cannot be this desk's as well. Terracotta carries the
   bands, and the bottle's own petrol teal is kept as the secondary ramp --
   --petrol -- for figures, meters, quotes and the seal captions. The two sit
   together the way the label does: warm earth against cool teal on chalk.

   Everything above CRITICAL-END is inlined into every page head, so the first
   screen paints without waiting for this file. The topline strip and the hero
   motif both live up there on purpose: appended to the end of the sheet they
   load async and flash unstyled at the very top of the page.

   NOTE FOR ANYONE EDITING THIS FILE: run
   python _generators/restamp_assets.py glproroutine.com
   afterwards, or a returning visitor keeps last year's stylesheet for a year
   (pitfall 49), and rebuild, or ~31 inlined copies go stale (pitfall 47). */

/* ---- tokens */
:root{
  /* ground: chalk, warm, never pure white -- the bottle is the white object */
  --paper:#fcfaf7;
  --tint:#f6f0e8;            /* the warm band between white sections */
  --panel:#ffffff;           /* cards, the product ground */
  /* ink */
  --ink:#231a15;
  --ink-2:#5b4d44;
  --ink-3:#786659;           /* 5.2:1 on --paper; do not lighten */
  --line:#e8dfd4;
  --line-2:#d6c6b5;
  /* accent: terracotta, the site's bands */
  --accent:#b4442a;
  --accent-d:#8b3220;
  --accent-l:#fbeee8;
  --accent-line:#eccfc1;
  --accent-ink:#fbeae2;      /* text on a terracotta band. 4.73:1 on --accent and
                                6.98:1 on --accent-d, both above the 4.5 AA floor for
                                the 14px topline. Do NOT darken this towards the
                                terracotta: #f7ddd2 read 4.27 and shipped once. */
  /* secondary ramp, read off the GLPro label */
  --petrol:#00606c;
  --petrol-d:#00434c;
  --petrol-l:#e7f1f2;
  /* states */
  --good:#1c6b45;
  --warn:#8a5a10;
  /* metrics */
  --wrap:1160px;
  --measure:760px;
  --measure-wide:980px;
  --radius:3px;
  --radius-card:10px;
  --navh:88px;
  --pack-img:170px;
  --figw:340px;
  --shadow:0 1px 2px rgba(60,32,20,.05), 0 10px 26px rgba(60,32,20,.07);
  --shadow-lg:0 20px 54px rgba(60,32,20,.16);
  --serif:"Domine","Domine Fallback",Georgia,"Times New Roman",serif;
  --sans:"Overpass","Overpass Fallback",system-ui,-apple-system,"Segoe UI",Roboto,sans-serif;
}

/* ---- base */
*,*::before,*::after{box-sizing:border-box}
*{min-width:0}
html,body{margin:0;padding:0}
html{overflow-x:clip;-webkit-text-size-adjust:100%;scroll-padding-top:104px}
body{
  overflow-x:clip;
  background:var(--paper);
  color:var(--ink);
  font-family:var(--sans);
  font-size:17px;
  line-height:1.72;
  -webkit-font-smoothing:antialiased;
}
img,svg,video{max-width:100%;height:auto;display:block}
table{max-width:100%}
a{color:var(--accent-d);text-underline-offset:3px}
a:hover{color:var(--accent)}
h1,h2,h3,h4{font-family:var(--serif);color:var(--ink);font-weight:700;line-height:1.2;margin:0 0 .5em}
h1{font-size:clamp(1.95rem,1.3rem + 2vw,2.85rem);letter-spacing:-.012em;line-height:1.16}
h2{font-size:clamp(1.45rem,1.16rem + 1.1vw,2.05rem);letter-spacing:-.006em}
h3{font-size:1.16rem}
h4{font-size:1.02rem}
p,li{font-size:1.0625rem}
p{margin:0 0 1.05em}
/* The gutter comes from a WIDTH constraint, not from padding, so no component
   sharing the element can wipe it with a `padding: 12px 0` shorthand -- the
   defect in pitfall 46, which is invisible above the container's max-width and
   which no overflow test can see. */
.wrap{width:min(var(--wrap),calc(100% - 40px));margin-inline:auto}
.skip{position:absolute;left:-9999px;top:0;background:var(--accent);color:#fff;padding:12px 18px;z-index:200}
.skip:focus{left:8px;top:8px}
:focus-visible{outline:3px solid var(--accent);outline-offset:2px}

/* The eyebrow names the JOB of the section under it. Every section has one. */
.eyebrow{
  display:inline-block;font-size:.85rem;font-weight:800;letter-spacing:.15em;
  text-transform:uppercase;color:var(--accent-d);margin:0 0 12px;
  padding-bottom:6px;border-bottom:2px solid var(--accent-line);
}

/* ---- buttons: square-ish terracotta blocks, no gradient, no pill */
.btn{
  display:inline-flex;align-items:center;justify-content:center;gap:10px;
  min-height:52px;padding:14px 28px;
  font-family:var(--sans);font-size:1rem;font-weight:700;letter-spacing:.01em;
  border:2px solid var(--accent);border-radius:var(--radius);cursor:pointer;
  text-decoration:none;background:var(--accent);color:#fff;
  transition:background .18s ease,border-color .18s ease,transform .18s ease;
}
.btn:hover{background:var(--accent-d);border-color:var(--accent-d);color:#fff}
.btn:active{transform:translateY(1px)}
.btn--cta{box-shadow:0 3px 0 0 var(--accent-d)}
.btn--cta:hover{box-shadow:0 3px 0 0 #6d2716}
.btn--lg{min-height:60px;padding:16px 36px;font-size:1.06rem}
.btn--ghost{background:transparent;color:var(--accent-d);border-color:var(--line-2)}
.btn--ghost:hover{background:var(--accent-l);color:var(--accent-d);border-color:var(--accent-line)}
.btn--block{width:100%}

/* ---- topline strip: the five trust facts, ABOVE the navigation.
   Role, lot, dose and count, guarantee, order phone. It exists so the nav does
   not have to carry them: getexitide shipped without one, pushed the lot into
   the menu as a chip, crowded the navigation and still left the other four
   facts off the page entirely (hero.md). This is also the upper of the two
   header rows the design slot asks for. */
.util{background:var(--accent);color:var(--accent-ink);font-size:.875rem;line-height:1.5}
.util__row{display:flex;flex-wrap:wrap;align-items:center;gap:2px 18px;padding-block:7px}
.util__item{display:inline-flex;align-items:center;gap:7px;white-space:nowrap}
.util__item+.util__item::before{
  content:"";width:4px;height:4px;border-radius:50%;background:#e9a993;
  flex:0 0 auto;margin-right:11px;
}
.util b{color:#fff;font-weight:700}
.util__tel{margin-left:auto;color:#fff;font-weight:800;white-space:nowrap;text-decoration:none}
.util__tel:hover{color:#fff;text-decoration:underline}

/* ---- header, lower row: wordmark left, menu right, on chalk */
.nav{position:sticky;top:0;z-index:100;background:var(--paper);border-bottom:1px solid var(--line)}
.nav__row{display:flex;align-items:center;justify-content:space-between;gap:24px;
  padding-block:11px;flex-wrap:nowrap}
/* The STACK construction: the mark sits ABOVE the wordmark, centred, and the
   whole block sits at the left of the row. brand_marks.py appends the same
   three declarations to the END of this stylesheet; they are repeated here, in
   the critical block, because the header is the first thing painted and a
   rule that only arrives with the async sheet makes the brand flash from a row
   into a column. The duplicate below CRITICAL-END is the tool's record that it
   has run, and is harmless. */
.brand{display:flex;flex-direction:column;align-items:center;gap:4px;text-align:center;
  text-decoration:none;color:var(--ink);flex:none}
.brand>svg{width:26px;height:26px;flex:0 0 auto;margin-right:0}
.bw{display:flex;flex-direction:column;line-height:1.08;align-items:center}
.bw b{font-family:var(--serif);font-size:1.34rem;font-weight:700;letter-spacing:-.02em}
.bw b em{font-style:normal;color:var(--accent)}
.bw small{font-size:0.9062rem;font-weight:600;color:var(--ink-3);letter-spacing:.02em}
.nav__right{display:flex;align-items:center;gap:22px;min-width:0}
.menu{display:flex;flex-wrap:nowrap;gap:22px;list-style:none;margin:0;padding:0}
.menu a{display:inline-block;padding:8px 0;font-size:.95rem;font-weight:600;
  color:var(--ink-2);text-decoration:none;white-space:nowrap;
  border-bottom:2px solid transparent}
.menu a:hover{color:var(--accent-d)}
.menu a[aria-current="page"]{color:var(--accent-d);border-bottom-color:var(--accent)}
.nav__buy{flex:none;min-height:44px;padding:10px 20px;font-size:.94rem;white-space:nowrap}
.burger{display:none;width:46px;height:44px;background:transparent;
  border:1px solid var(--line-2);border-radius:var(--radius);cursor:pointer;padding:11px 10px}
.burger span{display:block;height:2px;background:var(--ink);margin:0 0 5px}
.burger span:last-child{margin:0}

/* ---- the hero -----------------------------------------------------------
   A STACKED hero: eyebrow and headline centred, the bottle beneath them on a
   terracotta disc, and the copy wrapped under the disc in two columns.

   The headline sits ABOVE the disc rather than under it, and that is
   deliberate. femipros put the product above the headline and buried its H1 at
   y=796 on a 1440x900 screen, with the Quick Answer at 1200 and the CTA at 1651
   (pitfall 86 / 103). Here the H1 top lands around y=190: the whole point of the
   arrangement -- one centred product with the reading matter wrapped beneath --
   survives, and the first screen still opens with a sentence. hero.md: where
   the design slot and the hero spec disagree, the hero spec wins.

   .hero__grid keeps ONE column at every width. hero_sticky.py reads that and
   skips the site, which is right: a stacked hero has no taller sibling for a
   sticky column to travel against. */
.hero{position:relative;padding:40px 0 52px;border-bottom:1px solid var(--line)}
.hero__grid{display:grid;grid-template-columns:1fr;gap:0}
.hero .eyebrow{justify-self:center}
.hero h1{margin:0 auto 6px;max-width:19ch;text-align:center}
.h1__key{display:block;color:var(--accent-d);font-size:.62em;letter-spacing:.02em;
  text-transform:uppercase;margin-bottom:.42em}

/* the product: a terracotta disc, the bottle standing on it, one long soft
   shadow falling to the right. The pulse columns that fill, hold and empty are
   the motif's pseudo-elements on .hero__media, sized to land in the gap between
   the disc and the edge of this box -- which is why the box is wider than the
   disc and why the disc is centred inside it. */
.hero__media{position:relative;width:min(540px,100%);margin:14px auto 2px;
  display:flex;align-items:center;justify-content:center;padding-block:6px 18px}
/* position:relative is declared HERE as well as by the motif. The motif writes
   it through :where(), which carries zero specificity and only exists once that
   tool has run -- without this line .hero__tag would anchor to the wrong
   ancestor on a fresh build. */
/* The long soft shadow, falling to the right of the disc. Kept inside the media
   box on purpose: .hero clips horizontally, so an overhang would never widen the
   document, but it would still show up in a per-element overflow sweep as a
   thing hanging off the page, and "it is only the shadow" is not a report
   anybody should have to make twice. */
.hero__shadow{
  position:absolute;left:50%;bottom:3%;width:70%;height:14%;
  transform:translateX(-30%) rotate(-3deg);border-radius:50%;
  background:linear-gradient(90deg,rgba(74,32,18,.42),rgba(74,32,18,.20) 56%,transparent);
  filter:blur(13px);z-index:1;pointer-events:none;
}
.hero__card{
  position:relative;z-index:2;width:min(356px,78%);aspect-ratio:1;border-radius:50%;
  background:radial-gradient(closest-side at 44% 38%,#c4573b,var(--accent) 58%,#98371f);
  box-shadow:inset 0 -14px 34px rgba(80,32,16,.32), 0 18px 40px rgba(74,32,18,.18);
}
/* The shot: 768x768, transparent ground, the right-hand bottle front-on. It
   stands ON the disc and overhangs its lower edge, into the shadow, so the
   product reads as an object in front of a roundel rather than a picture
   pasted inside one. NEVER animated: it is the LCP element and it is preloaded
   (hero.md).

   Two selectors deep on purpose. hero_motifs.py writes
   `.hero__card img{position:relative;z-index:3}` into the critical block on
   every run, and that block is inserted AFTER these rules -- a single-class
   selector here would lose the cascade to it and the bottle would drop out of
   the disc the first time the motif was applied. */
.hero .hero__card img{
  position:absolute;left:50%;bottom:-6%;translate:-50% 0;
  width:98%;height:auto;z-index:3;
}
.hero__tag{
  position:absolute;right:2%;bottom:6%;z-index:4;margin:0;
  background:var(--panel);border:1px solid var(--line);border-radius:var(--radius);
  padding:7px 12px;font-size:.9375rem;font-weight:700;color:var(--ink-2);
  box-shadow:var(--shadow);
}
.hero__tag b{color:var(--petrol-d)}

/* The copy, wrapped beneath the disc in two columns.

   The CTA sits at the TOP of the right column, directly under the four tick
   lines, rather than on a row of its own below everything. Measured at
   1440x900 the row-of-its-own version put the order button at y=1156; this
   puts it at roughly y=1000, which is inside the fold on the 1080p screens
   most desktop visitors actually use. On a stacked hero the fold is the whole
   argument, so the reading path is: answer, four ticks, button. */
.hero__copy{
  display:grid;grid-template-columns:minmax(0,1.02fr) minmax(0,.98fr);
  gap:2px 46px;align-items:start;margin:22px 0 0;
  grid-template-areas:
    "answer ticks"
    "answer cta"
    "road   seals"
    "pay    pay";
}
.hero .answer{grid-area:answer;align-self:start}
.hero__road{grid-area:road}
.hero .ticks{grid-area:ticks}
.hero .trust__row{grid-area:seals}
.hero__cta{grid-area:cta;align-self:start}
.hero .pay{grid-area:pay;align-self:center;justify-content:center}

.answer{
  background:var(--panel);border:1px solid var(--line);border-left:4px solid var(--accent);
  border-radius:0 var(--radius-card) var(--radius-card) 0;padding:20px 22px;margin:0 0 16px;
  box-shadow:var(--shadow);
}
.answer .qtag{
  display:inline-block;font-size:.85rem;font-weight:800;letter-spacing:.13em;
  text-transform:uppercase;color:var(--accent-d);margin-bottom:7px;
}
.answer p{margin:0;font-size:1.0625rem}
.hero__road{font-size:1rem;color:var(--ink-2);margin:0 0 14px}
.ticks{list-style:none;margin:0 0 16px;padding:0}
.ticks li{position:relative;padding-left:28px;margin:0 0 .55em;font-size:1rem}
.ticks li::before{content:"\2713";position:absolute;left:0;top:0;color:var(--good);font-weight:800}
.trust__row{display:flex;flex-wrap:wrap;gap:8px 20px;margin-block:0 18px;padding:0;list-style:none;
  font-size:1rem;font-weight:600;color:var(--ink-2)}
.trust__row li{display:inline-flex;align-items:center;gap:8px}
.trust__row li::before{content:"";width:9px;height:9px;flex:0 0 auto;
  background:var(--petrol);clip-path:polygon(50% 0,100% 50%,50% 100%,0 50%)}
.hero__cta{display:flex;flex-wrap:wrap;gap:12px;margin:0 0 14px}
/* --ink-2, not --ink-3. The payment line is the only hero text that sits on the
   bare motif gradient rather than on a card, and --ink-3 measured 4.04:1 against
   the gradient's #efd9d2 mid stop -- fine on --paper at 5.24, below AA there.
   Measure hero copy against every stop of the gradient, not against the token's
   usual ground (responsive.md proof 4). */
.pay{display:flex;flex-wrap:wrap;align-items:center;gap:10px 14px;margin:0 0 14px;
  font-size:.9375rem;color:var(--ink-2)}
.pay img{width:180px;height:25px}

/* the three fact blocks at the foot of the hero copy column. Stripped from
   twenty-six heroes on 17 Sep 2026 by a pass asked to change the CONTENT, and
   restored the next day -- pitfall 76. They stay. */
.hero__sub{
  display:flex;flex-wrap:wrap;justify-content:center;gap:8px 22px;margin:20px 0 0;
  font-size:1rem;font-weight:600;color:var(--ink-2);
}
.hero__sub span{display:inline-flex;align-items:center;gap:8px}
.hero__sub span::before{content:"";width:7px;height:7px;border-radius:50%;
  background:var(--accent);flex:0 0 auto}
.factpills{display:flex;flex-wrap:wrap;justify-content:center;gap:9px;
  list-style:none;margin:16px 0 0;padding:0}
.factpills li{font-size:.9375rem;font-weight:600;color:var(--ink-2);
  background:var(--panel);border:1px solid var(--line);padding:7px 14px;border-radius:999px}
.factpills li b{color:var(--ink);font-weight:800}
.figures{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:14px;margin:18px 0 0}
.figures div{background:var(--panel);border:1px solid var(--line);border-top:3px solid var(--petrol);
  border-radius:0 0 var(--radius-card) var(--radius-card);padding:14px 16px;text-align:center}
.figures b{display:block;font-family:var(--serif);font-size:1.55rem;font-weight:700;
  color:var(--petrol-d);line-height:1.1}
.figures span{display:block;font-size:0.9062rem;font-weight:600;color:var(--ink-3);margin-top:3px}

/* ---- inner page head */
.phead{padding:30px 0 6px;background:var(--paper);border-bottom:1px solid var(--line)}
.crumbs{font-size:.9375rem;color:var(--ink-3);margin:0 0 14px}
.crumbs a{color:var(--ink-2);text-decoration:none}
.crumbs a:hover{color:var(--accent-d)}
.lead{font-size:1.14rem;color:var(--ink-2);max-width:var(--measure)}



/* ---- hero motif -- pulse-column ---------------------------------------- */
.hero{position:relative;overflow-x:clip;overflow-y:visible}
:where(.hero__media){position:relative}
.hero__card{position:relative;z-index:2}
.hero__card img{position:relative;z-index:3}
.hero{background:linear-gradient(150deg,#fcfaf7,#efd9d2 46%,#fcfaf7)}.hero__media::before{content:'';position:absolute;left:7%;top:12%;width:8px;height:76%;border-radius:999px;background:rgba(180,68,42,0.50);z-index:1;pointer-events:none;transform-origin:50% 100%;animation:grFill 9s ease-in-out infinite}.hero__media::after{content:'';position:absolute;right:8%;top:20%;width:8px;height:60%;border-radius:999px;background:rgba(180,68,42,0.38);z-index:1;pointer-events:none;transform-origin:50% 100%;animation:grFill 9s ease-in-out infinite;animation-delay:2.2s}@keyframes grFill{0%,100%{transform:scaleY(.18);opacity:.35}40%,62%{transform:scaleY(1);opacity:.85}}
@media(prefers-reduced-motion:reduce){.hero__card{animation:none!important}.hero__media::before,.hero__media::after{animation:none!important;opacity:0!important}}









/*!SITE-HOME-CRIT-START*/
/* ---- home first screen, design slot "circulate" -------------------------
   Geometry, plus the hero motif, which has to paint WITH the first screen:
   appended to the end of the sheet it would load async and the old pulse
   columns would flash first. Comments are stripped by tpl._critical_css, so
   the inlined cost of this block is about 1.1KB on each of the 31 pages --
   and every rule that is not already inside .hero is scoped with
   body:has(.hero), which matches on index.html and nowhere else.

   Anything here is inlined into EVERY page at build time, so this block is
   only ever changed by a REBUILD (python _generators/glproroutine/build.py),
   never by a restamp alone. */

/* 1. The order button on the first screen.
   Measured in a real browser at 1440x900: the button opened at y=948, 48px
   under the fold, because the four tick lines held the top of the right
   column and the button sat under them. Button and ticks swap rows, so the
   right column now reads BUTTON first and the evidence under it, and the
   button opens at about y=815 with its whole 65px inside the fold. Desktop
   only in effect: under 900px .hero__copy is display:contents and this
   template does not apply, so the hand-ordered phone hero is untouched. */
.hero__copy{
  grid-template-areas:
    "answer cta"
    "answer ticks"
    "road   seals"
    "pay    pay";
}

/* 2. Room for the arcs. They are deliberately larger than the disc, so the
   media box has to carry them or they cross the H1 above and the quick
   answer card below. +10px of margin and +20px of padding moves the disc
   down 20px and the copy under it 30px, which the fold fix above pays for
   several times over.

   20/24 rather than the 6/18 it had: the arcs are centred on the MEDIA box,
   the disc is centred between the paddings, and every pixel of difference
   between the two paddings is half a pixel of eccentricity in a 420px ring.
   The box is the same 400px tall either way, so the lot tag and the long
   shadow, which are positioned against it in per-cent, do not move. */
.hero__media{margin-top:24px;padding-block:20px 24px}

/* 3. The motif -- slot "circulate": two counter-rotating arcs, the inner one
   tighter, suggesting flow. One full turn takes 58s and 82s: this is a
   capsule taken daily for weeks, not an energy drink.

   They live on the two pseudo-elements of the MEDIA column and replace the
   pulse columns declared above (that block is left where it is -- it is
   another tool's, and every property it sets is overridden here by name).
   The bottle itself is never animated: it is the LCP element and it is
   preloaded.

   Sized OUTSIDE the disc on purpose. .hero__card is an opaque terracotta
   roundel at min(356px,78%) of this box, so a shape sized inside it renders
   nothing at all. Each arc is therefore sized FROM the disc's own expression
   plus a fixed ring gap, not from a percentage of its own: a percentage has
   to be re-proved at every width and the first phone reading came back with
   7px of clearance and the outer arc 2px over the quick-answer card. The
   disc is min(356px,78%) here and min(320px,86%) under 760px, so both are
   restated below and the gap is a constant 32px and 16px either way. */
.hero__media::before,
.hero__media::after{
  content:"";position:absolute;left:50%;top:50%;right:auto;bottom:auto;
  translate:-50% -50%;transform-origin:50% 50%;
  height:auto;aspect-ratio:1;background:none;
  border:2px solid transparent;border-radius:50%;
  z-index:1;pointer-events:none;
}
.hero__media::before{
  width:calc(min(356px,78%) + 64px);
  border-top-color:rgba(180,68,42,.42);
  border-left-color:rgba(180,68,42,.42);
  animation:glpCirc 58s linear infinite;
}
.hero__media::after{
  width:calc(min(356px,78%) + 32px);
  border-right-color:rgba(0,96,108,.34);
  border-bottom-color:rgba(0,96,108,.34);
  animation:glpCirc 82s linear infinite reverse;
}
/* grFill and grLift are already taken in this stylesheet. */
@keyframes glpCirc{from{transform:rotate(0)}to{transform:rotate(360deg)}}

/* Under 900px the hero stacks and the quick answer follows the disc with 2px
   between them instead of the copy grid's 22px, so the outer arc loses its
   10px of overhang: disc + the two paddings IS the media box's own height, so
   it cannot reach the card below at any width. Measured at 768 before this
   line: the arc crossed 8px into the answer. */
@media (max-width:900px){
  .hero__media::before{width:calc(min(356px,78%) + 44px)}
}
@media (max-width:760px){
  /* and here the disc itself drops to min(320px,86%) */
  .hero__media::before{width:calc(min(320px,86%) + 44px)}
  .hero__media::after{width:calc(min(320px,86%) + 24px)}
}

/* Switched off, not hidden. The pulse-column block above ends with
   opacity:0!important on both pseudo-elements; a later !important of equal
   specificity wins, so the arcs stand still instead of disappearing. */
@media (prefers-reduced-motion:reduce){
  .hero__media::before,
  .hero__media::after{animation:none!important;opacity:1!important}
  .hero__media::before{transform:rotate(-28deg)}
  .hero__media::after{transform:rotate(152deg)}
}

/* 4. The recommended pack is raised with a NEGATIVE MARGIN, never a
   transform: the reveal pass settles every card at transform:none, and the
   three Add To Cart buttons are held on one baseline by margin-top:auto
   against a shared card bottom. A negative top margin on a stretched grid
   item grows the card UPWARDS and leaves that bottom exactly where it was,
   so the baseline survives -- measured at 1440 after the change, all three
   buttons still open on the same pixel. Guarded above the 760px stack, where
   the three cards are one column and a negative margin would overlap them.
   Margin is geometry, which is why these two lines are up here. */
@media (min-width:761px){
  body:has(.hero) .buy__card--feature{margin-top:-16px}
}
/*!SITE-HOME-CRIT-END*/

/* --- hero responsive rules, copied into the critical block
   A phone painted the desktop hero from the inline block and then
   jumped when the async sheet arrived -- 692px on one site, CLS 0.95.
   These are COPIES: the originals stay below, so the cascade is
   unchanged and the first paint is already correct. */
@media (max-width:1060px){
  .hero__copy{gap:2px 32px}
  .hero h1{max-width:22ch}
}
@media (max-width:900px){
  /* The stacked hero on a phone, ordered by hand. The copy column is promoted with display:contents so its children become grid items -- and every sibling it exposes gets an explicit order, or an unordered one defaults to 0 and jumps above the eyebrow (hero.md). The shot goes directly after the H1: a buyer landing from an ad wants the bottle before the 60-word answer, not after it. */ .hero__copy{display:contents}
  .hero .eyebrow{order:1}
  .hero h1{order:2;max-width:100%}
  .hero__media{order:3}
  .hero .answer{order:4}
  /* The roadmap line moves BELOW the CTA on a phone. hero.md's mobile order is eyebrow, H1, shot, Quick Answer, CTA, sub, ticks, payment -- the roadmap sentence is not in it, and leaving it between the answer and the button put the button at y=1183 against a ~1,100 target on a 390x844 screen. */ .hero__cta{order:5}
  .hero__road{order:6}
  .hero__sub{order:8}
  .hero .ticks{order:9}
  .hero .trust__row{order:10}
  .hero .pay{order:11;justify-content:flex-start}
}
@media (max-width:760px){
  .hero{padding:30px 0 40px}
  .hero__media{margin-top:16px}
  .hero__card{width:min(320px,86%)}
}
@media (max-width:430px){
  .hero__tag{right:0;bottom:2%;padding:6px 10px}
}

/*!CRITICAL-END*/

/* ---- sections: chalk and terracotta-tinted bands, hairline seams */
.sec{padding:58px 0;position:relative}
.sec--tight{padding:34px 0 10px}
.sec--tint{background:var(--tint);border-block:1px solid var(--line)}
.sec--panel{background:var(--panel);border-block:1px solid var(--line)}
.sec--band{background:var(--accent-d);color:var(--accent-ink);border-block:0}
.sec--band h2,.sec--band h3{color:#fff}
.sec--band p,.sec--band li{color:var(--accent-ink)}
.sec--band .eyebrow{color:#f0bda9;border-bottom-color:rgba(255,255,255,.28)}
.sec--band a{color:#ffd9cb}
.sec--center{text-align:center}
.sec__head{max-width:var(--measure);margin:0 0 26px}
.sec__head h2{margin:0 0 10px}
.sec__head p,.sec__head .lead{color:var(--ink-2);margin:0}
.sec--center .sec__head{margin-inline:auto}
.sec--center .sec__head .lead{margin-inline:auto}

/* One measure, centred. Single-column content gets --measure; multi-column
   components keep the full wrap. Released below 1060px or a tablet gets a fixed
   760px box in a 700px viewport (responsive.md). */
@media (min-width:1060px){
  .sec>.wrap>h2,.sec>.wrap>h3,.sec>.wrap>h4,.sec>.wrap>p,
  .sec>.wrap>ul,.sec>.wrap>ol,.sec>.wrap>.sec__head,.sec>.wrap>.callout,
  .sec>.wrap>.alert,.sec>.wrap>.byline,.sec>.wrap>.refs,.sec>.wrap>.pullquote,
  .sec>.wrap>.keypoints,.sec>.wrap>blockquote{max-width:var(--measure);margin-inline:auto}
  .sec>.wrap>.tablewrap,.sec>.wrap>.faq,.sec>.wrap>.steps{
    max-width:var(--measure-wide);margin-inline:auto}
}

/* ---- tables */
.tablewrap{overflow-x:auto;margin:0 0 1.2em;border:1px solid var(--line);
  border-radius:var(--radius-card);background:var(--panel)}
table{border-collapse:collapse;width:100%;min-width:520px;font-size:1rem}
caption{text-align:left;padding:14px 16px 0;font-size:.9375rem;color:var(--ink-3)}
th,td{padding:13px 16px;text-align:left;border-bottom:1px solid var(--line);vertical-align:top}
th{font-family:var(--sans);font-weight:700;color:var(--ink);background:var(--tint);font-size:.95rem}
tbody tr:last-child td{border-bottom:0}
td b{color:var(--ink)}
.dtable{min-width:520px}
.note{font-size:.9375rem;color:var(--ink-3)}

/* ---- lists that carry content */
.chips{display:flex;flex-wrap:wrap;gap:10px 18px;list-style:none;margin:0 0 1.2em;padding:0}
.chips li{display:inline-flex;align-items:flex-start;gap:9px;font-size:1rem;color:var(--ink-2)}
.chips .ck{color:var(--good);font-weight:800}

/* ---- numbered steps */
.steps{display:grid;gap:16px;margin:0 0 1.2em;counter-reset:s}
.step{position:relative;background:var(--panel);border:1px solid var(--line);
  border-radius:var(--radius-card);padding:20px 22px 20px 68px}
.step__n{position:absolute;left:20px;top:19px;width:34px;height:34px;display:grid;
  place-items:center;background:var(--accent);color:#fff;font-family:var(--serif);
  font-weight:700;font-size:1rem;border-radius:50%}
.step__n::before{counter-increment:s;content:counter(s)}
.step h3{margin:0 0 6px}
.step p:last-child{margin:0}

/* ---- cards */
.grid{display:grid;gap:18px}
.grid.g2{grid-template-columns:repeat(2,minmax(0,1fr))}
.grid.g3{grid-template-columns:repeat(3,minmax(0,1fr))}
.grid.g4{grid-template-columns:repeat(4,minmax(0,1fr))}
.grid>*{min-width:0}
.card,.whycard{position:relative;background:var(--panel);border:1px solid var(--line);
  border-radius:var(--radius-card);padding:22px 24px}
.card::before,.whycard::before{content:"";position:absolute;left:24px;top:0;width:34px;height:3px;
  background:var(--accent)}
.card h3,.whycard h3{margin:0 0 8px}
.card p:last-child,.card ul:last-child,.whycard p:last-child{margin-bottom:0}
.whygrid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:18px}
.whygrid>*{min-width:0}

/* ---- callout, alert, quote, keypoints */
.callout{background:var(--petrol-l);border:1px solid #c7dfe1;border-radius:var(--radius-card);
  padding:20px 22px;margin:0 0 1.2em}
.callout b:first-child{display:block;margin-bottom:6px;color:var(--petrol-d)}
.callout p:last-child{margin:0}
.alert{background:#fdf5e8;border:1px solid #eedcbb;border-left:4px solid var(--warn);
  border-radius:0 var(--radius-card) var(--radius-card) 0;padding:20px 22px;margin:0 0 1.2em}
.alert b:first-child{display:block;margin-bottom:6px;color:var(--warn)}
.alert p:last-child{margin:0}
.pullquote{font-family:var(--serif);font-size:1.3rem;line-height:1.5;color:var(--ink);
  border-left:4px solid var(--petrol);padding:4px 0 4px 22px;margin:0 0 1.2em}
.pullquote cite{display:block;font-family:var(--sans);font-size:.9375rem;font-style:normal;
  color:var(--ink-3);margin-top:8px}
.keypoints{background:var(--accent-l);border:1px solid var(--accent-line);
  border-left:4px solid var(--accent);border-radius:0 var(--radius-card) var(--radius-card) 0;
  padding:20px 22px;margin:0 0 1.2em}
.keypoints>b{display:block;margin-bottom:8px}
.keypoints ul{margin:0;padding-left:20px}
.keypoints li{margin:0 0 .5em}
.flag{display:inline-block;font-size:.85rem;font-weight:800;letter-spacing:.09em;
  text-transform:uppercase;color:#fff;background:var(--accent);padding:4px 11px;
  border-radius:999px;margin-bottom:9px}
.pill{display:inline-block;font-size:.85rem;font-weight:700;color:var(--petrol-d);
  background:var(--petrol-l);border-radius:999px;padding:4px 12px}

/* ---- image beside copy */
.split{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:34px;
  align-items:center;margin:0 0 1.2em}
.split>*,.split__media{min-width:0}
.split--rev .split__media{order:-1}
.split__media img{width:100%;border:1px solid var(--line);border-radius:var(--radius-card);
  background:var(--panel)}
.split p:last-child{margin:0}

/* ---- captioned images. There is no bare image grid in this system: .gallery
   is retired and every .shots figure carries a heading and 30-45 words. */
.shots{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:20px;margin:0 0 1.2em}
.shots--wide{grid-template-columns:repeat(3,minmax(0,1fr))}
.shots>*{min-width:0}
.shots figure{margin:0;background:var(--panel);border:1px solid var(--line);
  border-radius:var(--radius-card);overflow:hidden}
.shots img{width:100%}
.shots figcaption{padding:16px 18px;font-size:.9375rem}
.shots figcaption b{display:block;margin-bottom:5px;font-size:1.0625rem;color:var(--ink)}
.shots figcaption span,.shots figcaption p{color:var(--ink-2)}
figure.portrait img{width:var(--figw,340px);margin-inline:auto}

/* ---- seal wall */
/* auto-fit rather than a fixed four, because a nested-or-narrow card row is the
   defect, not the nesting: at 768 the fixed four columns gave 169px a card and
   the seal captions wrapped to one word a line (responsive.md proof 2). The
   240px floor resolves to 4 columns at 1440, 2 at 768 and 1 on a phone, with no
   breakpoint to keep in step. */
.badgewall{display:grid;grid-template-columns:repeat(auto-fit,minmax(240px,1fr));
  gap:18px;margin:0 0 1.2em}
.badgewall>*{min-width:0}
.badgewall figure{margin:0;text-align:center;background:var(--panel);border:1px solid var(--line);
  border-radius:var(--radius-card);padding:18px 16px}
.badgewall img{width:72px;height:72px;object-fit:contain;margin:0 auto 10px}
.badgewall b{display:block;font-size:1rem;margin-bottom:4px}
.badgewall span{font-size:.9375rem;color:var(--ink-2)}

/* ---- the hero trust strip repeated as a page band */
.trust{background:var(--panel);border-block:1px solid var(--line)}
.trust .trust__row{display:flex;flex-wrap:wrap;align-items:center;gap:18px 30px;padding-block:20px;margin-block:0}
.trust figure{margin:0;display:flex;align-items:center;gap:10px;font-size:.9375rem;font-weight:600}
.trust figure img{width:56px;height:56px;object-fit:contain}
.trust__note{flex:1 1 280px;font-size:.9375rem;color:var(--ink-3);margin:0}

/* ---- star distribution */
.meter{margin:0 0 1.2em}
.meter__row{display:grid;grid-template-columns:74px 1fr 54px;gap:12px;align-items:center;
  margin:0 0 8px;font-size:.9375rem}
.meter__bar{height:10px;background:var(--line);border-radius:999px;overflow:hidden}
.meter__bar i{display:block;height:100%;background:var(--petrol)}
.stars{color:#c07a12;letter-spacing:1px}
.stats{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:20px;text-align:center}
.stats div b{display:block;font-family:var(--serif);font-size:2.1rem;font-weight:700;line-height:1.1}
.stats div span{display:block;font-size:.9375rem;margin-top:4px}

/* ---- who it is for */
.whofor{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:20px;margin:0 0 1.2em}
.whofor>*{min-width:0}
.forlist{background:var(--panel);border:1px solid var(--line);border-top:3px solid var(--good);
  border-radius:var(--radius-card);padding:22px 24px}
.forlist--no{border-top-color:var(--accent)}
.forlist ul{list-style:none;margin:0;padding:0}
.forlist li{position:relative;padding-left:26px;margin:0 0 .6em;font-size:1.062rem}
.forlist li::before{content:"\2713";position:absolute;left:0;color:var(--good);font-weight:800}
.forlist--no li::before{content:"\2715";color:var(--accent)}

/* ---- add-to-cart pricing panel: the shared component on home and pricing */
.buy{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:20px;
  align-items:stretch;margin:0 0 20px}
.buy>*{min-width:0}
.buy__card{display:flex;flex-direction:column;background:var(--panel);
  border:2px solid transparent;box-shadow:inset 0 0 0 1px var(--line);
  border-radius:var(--radius-card);overflow:hidden;position:relative}
/* Every card gets the 2px border and only the featured one colours it in:
   box-sizing is border-box, so a border on one card alone steals 2px from its
   content box and drops its button out of line with the other two
   (responsive.md proof 3). */
.buy__card--feature{border-color:var(--accent);box-shadow:var(--shadow-lg)}
.buy__head{background:var(--tint);border-bottom:1px solid var(--line);padding:14px 18px}
.buy__card--feature .buy__head{background:var(--accent);border-bottom-color:var(--accent)}
.buy__card--feature .buy__head .buy__name,
.buy__card--feature .buy__head .buy__supply{color:#fff}
.buy__card--feature .buy__flag{background:#fff;color:var(--accent-d)}
.buy__flag{display:inline-block;font-size:.85rem;font-weight:800;letter-spacing:.08em;
  text-transform:uppercase;background:var(--accent-l);color:var(--accent-d);
  padding:3px 10px;border-radius:999px;margin-bottom:7px}
.buy__name{font-family:var(--serif);font-size:1.22rem;font-weight:700;margin:0 0 2px}
.buy__supply{font-size:.9375rem;font-weight:600;color:var(--ink-3);margin:0}
.buy__body{display:flex;flex-direction:column;flex:1;padding:20px 20px 22px}
.buy__img{width:auto;max-width:100%;height:var(--pack-img,170px);object-fit:contain;
  margin-inline:auto;margin-bottom:14px}
.buy__price{font-family:var(--serif);font-size:2.35rem;font-weight:700;line-height:1;
  text-align:center;margin:0}
.buy__cur{font-size:1.1rem;font-weight:700;vertical-align:.6em}
.buy__per{display:block;font-family:var(--sans);font-size:0.9062rem;font-weight:700;
  color:var(--ink-3);margin-top:5px}
.buy__total{text-align:center;font-size:1rem;margin:12px 0 14px}
.buy__total s{color:var(--ink-3);font-weight:600;margin-left:8px}
.buy__perks{list-style:none;margin:0 0 18px;padding:0;font-size:.9375rem}
.buy__perks li{position:relative;padding-left:24px;margin:0 0 6px;color:var(--ink-2)}
.buy__perks li::before{content:"\2713";position:absolute;left:0;color:var(--good);font-weight:800}
.buy__add{margin-top:auto}
.buy__cart{flex:0 0 auto}
.buy__pay{width:180px;height:25px;margin:12px auto 0}
/* The "why this pack" note sits ABOVE the button, and the button is followed
   only by the payment strip, which is the same height on all three cards.
   With the note underneath instead, three different blurb lengths produced
   three different button tops (10550 / 10576 / 10602 at 1440) inside three
   cards of identical height -- responsive.md proof 3. margin-top:auto on the
   button then pushes it to one baseline, because everything below it is
   fixed. Reason, then action, is also the better reading order. */
.buy__why{font-size:.9375rem;color:var(--ink-3);margin:12px 0 16px}
.buy__foot{margin:0}

/* ---- FAQ. The padding lives on <summary>, the click target: on <details> the
   row measures ~30px against the 44px minimum (pitfall 73). */
.faq{border:1px solid var(--line);border-radius:var(--radius-card);overflow:hidden;
  background:var(--panel);margin:0 0 1.2em;text-align:left}
.faq details{border-bottom:1px solid var(--line)}
.faq details:last-child{border-bottom:0}
.faq summary{padding:17px 48px 17px 20px;cursor:pointer;position:relative;list-style:none;
  font-family:var(--serif);font-weight:700;font-size:1.06rem}
.faq summary::-webkit-details-marker{display:none}
.faq summary::after{content:"+";position:absolute;right:19px;top:50%;translate:0 -50%;
  font-family:var(--sans);font-size:1.4rem;font-weight:400;color:var(--accent)}
.faq details[open] summary::after{content:"\2212"}
.faq__b{padding:0 20px 18px}
.faq__b p:last-child,.faq__b ul:last-child{margin-bottom:0}

/* ---- the editorial score card */
.facts{background:var(--panel);border:1px solid var(--line);border-radius:var(--radius-card);
  overflow:hidden;margin:0 0 1.2em}
.facts__h{background:var(--petrol);color:#fff;font-family:var(--serif);font-weight:700;
  padding:13px 18px}
.facttab{min-width:0}
.facttab th{background:transparent;font-weight:600;color:var(--ink-2)}

/* ---- references and byline */
.refs{margin:0 0 1.2em}
.refs ol{padding-left:22px;margin:0}
.refs li{font-size:1.062rem;color:var(--ink-2);margin:0 0 .6em}
/* A printed URL is one unbreakable token, and at 390px it pushed a single <a>
   past the viewport on eleven pages of another site -- clipped, unscrollable
   and invisible to every static check. `anywhere` also lowers the element's
   min-content, which is what stops an ancestor being sized by the longest URL. */
.refs li,.refs li a{overflow-wrap:anywhere}
.byline{display:flex;gap:18px;background:var(--panel);border:1px solid var(--line);
  border-left:4px solid var(--accent);border-radius:0 var(--radius-card) var(--radius-card) 0;
  padding:22px 24px;margin:0 0 1.2em;text-align:left}
.byline__mark{flex:0 0 auto;width:52px;height:52px;display:grid;place-items:center;
  background:var(--accent-d);color:#fff;font-family:var(--serif);font-weight:700;
  font-size:1.06rem;border-radius:50%}
.byline b{display:block;margin-bottom:6px}
.byline p{font-size:.9375rem;color:var(--ink-2);margin:0}
.meta{font-size:.9375rem;color:var(--ink-3)}

/* ---- closing CTA */
.final{background:var(--panel);border:1px solid var(--line);border-top:4px solid var(--accent);
  border-radius:0 0 var(--radius-card) var(--radius-card);padding:30px 32px;text-align:left}
.final--media{display:grid;grid-template-columns:auto minmax(0,1fr);gap:30px;align-items:center}
.final__img img{width:300px}
.final h2{margin:0 0 10px}
.final__price{font-weight:700;color:var(--ink-2)}
.final__sm{font-size:.9375rem;color:var(--ink-3);margin:12px 0 0}

/* ---- related */
.rel{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:18px;text-align:left}
.rel>*{min-width:0}
.rel a{display:block;background:var(--panel);border:1px solid var(--line);
  border-radius:var(--radius-card);padding:20px 22px;text-decoration:none;color:var(--ink);
  transition:border-color .18s ease}
.rel a:hover{border-color:var(--accent)}
.rel b{display:block;font-family:var(--serif);font-size:1.06rem;margin-bottom:5px}
.rel span{font-size:.9375rem;color:var(--ink-2)}

/* ---- forms. 16px minimum on inputs, or iOS Safari zooms on focus and never
   zooms back (pitfall 86). */
.form{display:grid;gap:16px;max-width:var(--measure)}
.formcard{background:var(--panel);border:1px solid var(--line);border-radius:var(--radius-card);
  padding:24px 26px;margin:0 0 1.2em}
.field label{display:block;font-weight:700;font-size:.9688rem;margin-bottom:6px}
.field input,.field select,.field textarea{width:100%;font-family:var(--sans);font-size:16px;
  padding:13px 14px;border:1px solid var(--line-2);border-radius:var(--radius);
  background:var(--panel);color:var(--ink)}
.field textarea{min-height:140px;resize:vertical}
.field small{display:block;font-size:.9375rem;color:var(--ink-3);margin-top:5px}

/* ---- blog */
.article{max-width:var(--measure);margin-inline:auto}
.postmeta{display:flex;flex-wrap:wrap;gap:6px 16px;font-size:.9375rem;color:var(--ink-3);
  border-block:1px solid var(--line);padding-block:12px;margin:0 0 22px}
.toc{background:var(--tint);border:1px solid var(--line);border-radius:var(--radius-card);
  padding:20px 24px;margin:0 0 28px}
.toc b{display:block;margin-bottom:8px}
.toc ol{margin:0;padding-left:20px}
.toc li{margin:0 0 5px;font-size:1.062rem}
.article h2{scroll-margin-top:110px}
.posts{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:20px}
.posts>*{min-width:0}
.posts article{background:var(--panel);border:1px solid var(--line);
  border-radius:var(--radius-card);overflow:hidden}
.posts article img{width:100%}
.posts .posts__b{padding:20px 22px}
.posts h3{margin:0 0 8px;font-size:1.1rem}
.posts p{font-size:1.062rem;color:var(--ink-2);margin:0 0 .6em}
.article .final--media{grid-template-columns:1fr;gap:18px}
.article .final__img img{width:220px}

/* ---- footer: a terracotta contact band, then a white three-column link grid,
   then the legal slab. The contact band comes first because the two things a
   reader hunts for in this footer are the refund phone number and the returns
   address. */
.fdesk{background:var(--accent-d);color:var(--accent-ink)}
.fdesk__grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:30px;
  padding-block:34px}
.fdesk__grid>*{min-width:0}
.fdesk__k{display:block;font-size:.85rem;font-weight:800;letter-spacing:.14em;
  text-transform:uppercase;color:#f0bda9;margin-bottom:8px}
.fdesk__card b{display:block;font-family:var(--serif);font-size:1.1rem;color:#fff;margin-bottom:8px}
.fdesk__card p{font-size:1.062rem;color:var(--accent-ink);margin:0}
.fdesk__card a{color:#fff;font-weight:600}
footer{background:var(--panel);border-top:1px solid var(--line)}
.fgrid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:0;padding-block:34px}
.fgrid>*{min-width:0}
.fgrid>div{padding-inline:30px;border-left:1px solid var(--line)}
.fgrid>div:first-child{padding-left:0;border-left:0}
.fgrid>div:last-child{padding-right:0}
.fh{font-size:.85rem;font-weight:800;letter-spacing:.13em;text-transform:uppercase;
  color:var(--ink-3);margin:0 0 10px;font-family:var(--sans)}
.fgrid ul{list-style:none;margin:0 0 22px;padding:0}
.fgrid li{margin:0}
/* inline-block, not block: the box still shrink-wraps to the text so the hover
   underline stays the width of the words, and the negative margin gives the row
   its height back, so the footer is unchanged to the pixel (pitfall 82). */
footer li a{display:inline-block;padding-block:5px;margin-block:-5px;font-size:.9688rem;
  color:var(--ink-2);text-decoration:none}
footer li a:hover{color:var(--accent-d)}
.fseals{display:flex;flex-wrap:wrap;align-items:center;gap:12px;padding-block:20px;
  border-top:1px solid var(--line)}
.fseals img{width:44px;height:44px;object-fit:contain}
.fseals span{flex:1 1 260px;font-size:.9375rem;color:var(--ink-3)}
.fpay{display:flex;flex-wrap:wrap;align-items:center;gap:16px;padding-bottom:26px}
.fpay img{width:212px;height:30px}
.fpay span{font-size:.9375rem;color:var(--ink-3)}
.disc{background:var(--tint);border-top:1px solid var(--line);padding-block:30px 34px}
.disc p,.disc li{font-size:.9375rem;color:var(--ink-2)}
.disc b{color:var(--ink)}
.copy{margin:18px 0 0;padding-top:16px;border-top:1px solid var(--line-2);font-size:.9375rem;
  color:var(--ink-3)}
.legal p,.legal li{font-size:1.0625rem}

/* ---- sticky buy bar */
.buybar{position:fixed;left:0;right:0;bottom:0;z-index:90;background:var(--accent-d);
  color:#fff;transform:translateY(105%);transition:transform .25s ease}
.buybar.show{transform:none}
.buybar__in{display:flex;align-items:center;gap:18px;width:min(var(--wrap),calc(100% - 40px));
  margin-inline:auto;padding-block:12px}
.buybar__t{font-size:.9375rem;min-width:0}
.buybar__t b{display:block;font-size:1rem}
.buybar__t span{color:var(--accent-ink)}
.buybar .btn{margin-left:auto;flex:0 0 auto;background:#fff;color:var(--accent-d);
  border-color:#fff;box-shadow:none}
.buybar .btn:hover{background:var(--accent-l);color:var(--accent-d);border-color:var(--accent-l)}

/* ---- reveal */
[data-reveal]{opacity:0;transform:translateY(14px);transition:opacity .5s ease,transform .5s ease}
[data-reveal].in{opacity:1;transform:none}
@media (prefers-reduced-motion:reduce){
  [data-reveal]{opacity:1;transform:none;transition:none}
  html{scroll-behavior:auto}
}

/* ---- responsive.
   The nav row SHEDS rather than wraps: menu gaps tighten, then the CTA goes,
   then the menu collapses to the burger. A wrapped header row measures 100px+
   instead of ~66px and looks broken (design-system.md). */
@media (max-width:1180px){
  .menu{gap:17px}
  .menu a{font-size:.9rem}
  .fgrid>div{padding-inline:22px}
}
@media (max-width:1120px){
  /* The topline sheds before it wraps, exactly as the nav row does. Five items
     need about 1,150px; at 1,024 they wrapped to two lines and the strip went
     from 35px to 58px. The dose goes first -- it is on how-to-use.html and in
     the hero's own fact pills -- and the lot follows at phone width. */
  .util__item--trim2{display:none}
}
@media (max-width:1060px){
  .menu{gap:13px}
  .menu a{font-size:.875rem}
  .hero__copy{gap:2px 32px}
  .hero h1{max-width:22ch}
}
@media (max-width:980px){
  .nav__buy{display:none}
}
@media (max-width:900px){
  :root{--navh:74px}
  .burger{display:block}
  .menu{display:none;position:absolute;left:0;right:0;top:100%;flex-direction:column;
    gap:0;background:var(--panel);border-block:1px solid var(--line);
    padding:6px 20px 14px;box-shadow:var(--shadow-lg)}
  .menu.open{display:flex}
  .menu a{padding:12px 0;border-bottom:1px solid var(--line)}
  .menu a[aria-current="page"]{border-bottom-color:var(--line)}
  .nav{position:sticky}
  .nav__right{gap:12px}

  /* The stacked hero on a phone, ordered by hand. The copy column is promoted
     with display:contents so its children become grid items -- and every
     sibling it exposes gets an explicit order, or an unordered one defaults to
     0 and jumps above the eyebrow (hero.md). The shot goes directly after the
     H1: a buyer landing from an ad wants the bottle before the 60-word answer,
     not after it. */
  .hero__copy{display:contents}
  /* display:contents promotes the copy column's children into .hero__grid --
     AND THEY BRING THEIR grid-area NAMES WITH THEM. Those names ("answer",
     "ticks", "cta", ...) belong to .hero__copy's template, which no longer
     exists, so the browser treats each one as a line name it cannot resolve
     and opens IMPLICIT COLUMNS to place them in. Measured before this reset:
     the single-column hero laid out in two, the bottle sat in the right-hand
     half at x=360 of a 768px viewport, and the Quick Answer and the CTA both
     reported a top of 574 because they were side by side. Every `order` value
     below was correct the whole time, which is why reading the computed order
     alone would have said the hero was fine. */
  .hero .hero__copy>*{grid-area:auto}
  .hero .eyebrow{order:1}
  .hero h1{order:2;max-width:100%}
  .hero__media{order:3}
  .hero .answer{order:4}
  /* The roadmap line moves BELOW the CTA on a phone. hero.md's mobile order is
     eyebrow, H1, shot, Quick Answer, CTA, sub, ticks, payment -- the roadmap
     sentence is not in it, and leaving it between the answer and the button put
     the button at y=1183 against a ~1,100 target on a 390x844 screen. */
  .hero__cta{order:5}
  .hero__road{order:6}
  .hero__sub{order:8}
  .hero .ticks{order:9}
  .hero .trust__row{order:10}
  .hero .pay{order:11;justify-content:flex-start}
  .factpills{order:12}
  .figures{order:13}

  .whygrid,.grid.g3,.grid.g4{grid-template-columns:repeat(2,minmax(0,1fr))}
  .stats{grid-template-columns:repeat(2,minmax(0,1fr))}
  .fdesk__grid{grid-template-columns:1fr;gap:22px}
  .fgrid{grid-template-columns:1fr;gap:0}
  .fgrid>div{padding-inline:0;border-left:0}
  .final--media{grid-template-columns:1fr;gap:20px}
  .final__img img{width:240px}
}
@media (max-width:760px){
  /* Five topline items wrap to three lines and eat 103px of an 844px screen.
     Keep the role, the guarantee and the order phone; the lot and the dose are
     on the pages that need them (hero.md). */
  .util__item--trim{display:none}
  .util__row{gap:2px 14px}
  .util__tel{margin-left:0}

  .sec{padding:44px 0}
  .hero{padding:30px 0 40px}
  .hero__media{margin-top:16px}
  .hero__card{width:min(320px,86%)}
  .hero h1{text-align:left;margin-inline:0}
  .hero .eyebrow{justify-self:start}
  .hero__sub,.factpills{justify-content:flex-start}
  .figures{grid-template-columns:1fr;gap:10px}
  .figures div{text-align:left}

  .grid.g2,.grid.g3,.grid.g4,.whygrid{grid-template-columns:1fr}
  .buy{grid-template-columns:1fr;max-width:430px;margin-inline:auto}
  /* Stacked, the ladder must not lead with the smallest pack. DOM order stays
     2, 3, 6; the best-value card comes first on a phone (design-system.md). */
  .buy__card:nth-child(1){order:3}
  .buy__card:nth-child(2){order:1}
  .buy__card:nth-child(3){order:2}
  .shots,.shots--wide{grid-template-columns:1fr}
  .rel,.posts{grid-template-columns:1fr}
  .split,.whofor{grid-template-columns:1fr}
  .split--rev .split__media{order:0}
  .meter__row{grid-template-columns:62px 1fr 48px}
  .buybar__in{flex-wrap:wrap;gap:10px;padding-block:10px}
  .buybar .btn{width:100%;margin-left:0}
  .final{padding:24px 22px}
}
@media (max-width:430px){
  .stats{grid-template-columns:1fr}
  .hero__tag{right:0;bottom:2%;padding:6px 10px}
}

/* ---- hero: the product breathes on its disc -------------------------------
   The float goes on .hero__card, never on the <img>. The image is the LCP
   element and it is preloaded; an animation on it moves the LCP time
   (hero.md). Transform only -- an element that starts at opacity:0 is not
   recorded as painted at all.

   hero_motifs.py owns the movement AROUND the bottle (the two pulse columns).
   This is the one thing it does not own: the disc itself lifting and settling,
   slow enough to read as patience rather than as a bounce. */
@media (prefers-reduced-motion:no-preference){
  .hero__card{animation:grLift 9s ease-in-out infinite}
  @keyframes grLift{0%,100%{transform:translateY(0)}50%{transform:translateY(-9px)}}
}
/* brand mark: stack construction */
.brand{flex-direction:column;align-items:center;gap:4px;text-align:center}.brand svg{width:26px;height:26px;margin-right:0!important}

/* ==== fix_layout_breaks.py ==== */
/* A figure alone on its row, and components whose own
   background fights the band they sit in. Appended: each
   rule below is correct in isolation and only their
   combination fails, so the originals stay as written. */
.shots>figure:last-child:nth-child(odd){grid-column:1/-1;max-width:calc((100% - 20px) / 2);margin-inline:auto}
.sec--band .lead{color:#fbeae2}
.sec--band .note{color:#fbeae2}
.sec--band .tablewrap,.sec--band .tablewrap p,.sec--band .tablewrap li,.sec--band .tablewrap td,.sec--band .tablewrap th,.sec--band .tablewrap caption{color:var(--ink)}
.sec--band .callout,.sec--band .callout p,.sec--band .callout li,.sec--band .callout td,.sec--band .callout th,.sec--band .callout caption{color:var(--ink)}
/* ==== end fix_layout_breaks.py ==== */

/* ==== directional chrome (fix_chrome_scroll.py) ==== */
.nav,#nav{transition:transform .28s ease}
@media(prefers-reduced-motion:reduce){.nav,#nav{transition:none}}
.nav--away{transform:translateY(-100%)}
html.chrome-up .buybar{transform:translateY(105%)}
/* ==== end directional chrome ==== */

/* ==== tables never fade (reveal_skip_tables.py) ==== */
/* A comparison table is reference content the reader scrolled to on
   purpose. Fading it in leaves it illegible for half a second at exactly
   that moment, which reads as broken text rather than as motion. The
   reveal stays on cards and callouts, which are decorative arrivals. */
.tablewrap[data-reveal],.tablewrap.reveal{opacity:1;transform:none;transition:none}
/* ==== end tables never fade ==== */
/*!SITE-HOME-PAINT-START*/
/* ---- home page surface, design slot "circulate" -------------------------
   24px on cards and panels, 16px on controls, and a two-stop CRISP shadow
   (0 1px 1px / 0 4px 10px) tinted with this site's own ink, 35,26,21, never
   neutral black.

   Paint only -- radius, shadow, colour, gradient, transform and transition
   move no box -- so this block sits below the critical marker and needs
   `python _generators/restamp_assets.py glproroutine.com`, not a rebuild.

   Every selector is scoped to the HOME PAGE, either through .hero (which is
   on index.html and nowhere else on this site) or with body:has(.hero). That
   scope is also what keeps the block alive: modern_surface.py re-appends its
   own .card / .answer radius AFTER this one on every build, so these rules
   beat it on specificity rather than on source order. */

body:has(.hero){
  --shadow:0 1px 1px rgba(35,26,21,.07), 0 4px 10px rgba(35,26,21,.10);
  --lift:0 2px 3px rgba(35,26,21,.08), 0 10px 22px rgba(35,26,21,.16);
  --radius-card:24px;
}

/* panels and cards: 24px. Listed one by one rather than raising --radius,
   because --radius is what the BUTTONS read and the slot puts controls at
   16px and cards at 24px. */
body:has(.hero) .card,
body:has(.hero) .step,
body:has(.hero) .callout,
body:has(.hero) .keypoints,
body:has(.hero) .alert,
body:has(.hero) .tablewrap,
body:has(.hero) .faq,
body:has(.hero) .final,
body:has(.hero) .byline,
body:has(.hero) .forlist,
body:has(.hero) .shots figure,
body:has(.hero) .rel a,
body:has(.hero) .split__media img,
body:has(.hero) .answer{border-radius:24px}
/* these two keep a square top edge: a 3px/4px coloured rule sits on it */
body:has(.hero) .figures div{border-radius:0 0 24px 24px}

/* .card carries a 34x3 terracotta rule at left:24px, top:0. At 16px of radius
   that was the flat top edge; at 24px it is the middle of the corner curve,
   and the rule was photographed floating clear of the card with daylight
   under it. Moved past the tangent, widened and given its bottom corners, so
   it reads as a tab sitting ON the edge. An absolutely positioned decoration
   reflows nothing, which is why this is paint and not geometry. */
body:has(.hero) .card::before{left:30px;width:40px;height:4px;border-radius:0 0 4px 4px}

/* shade: the panels that carried a hairline border and no shadow at all */
body:has(.hero) .card,
body:has(.hero) .step,
body:has(.hero) .forlist,
body:has(.hero) .faq,
body:has(.hero) .final,
body:has(.hero) .byline,
body:has(.hero) .figures div,
body:has(.hero) .shots figure{box-shadow:var(--shadow)}

/* the hero disc keeps its inset modelling and gains the same two stops */
body:has(.hero) .hero__card{
  box-shadow:inset 0 -14px 34px rgba(80,32,16,.32),
             0 1px 1px rgba(35,26,21,.07),
             0 18px 38px rgba(74,32,18,.20);
}

/* ---- the buying CTA is the only gradient on the page.
   The hero's secondary button is left SOLID, so the pair reads as two
   weights rather than two colours. The nav button and the sticky buy bar are
   deliberately not in this list: they are chrome, they appear on all 31
   pages, and this block is the home page's. */
.hero__cta .btn--cta,
body:has(.hero) .buy__add,
body:has(.hero) .final .btn--cta{
  background-image:linear-gradient(180deg,#c2512f,var(--accent) 46%,var(--accent-d));
  border-color:var(--accent-d);
  box-shadow:0 1px 1px rgba(35,26,21,.10), 0 4px 10px rgba(180,68,42,.30);
  transition:background-color .18s ease,border-color .18s ease,
             box-shadow .2s ease,transform .2s ease;
}
/* .btn:hover sets the `background` SHORTHAND, which would blank the gradient,
   so the hover state restates the image as well as the colour. */
.hero__cta .btn--cta:hover,
body:has(.hero) .buy__add:hover,
body:has(.hero) .final .btn--cta:hover{
  background-color:var(--accent-d);
  background-image:linear-gradient(180deg,var(--accent),#a03a22 46%,#7a2a18);
  box-shadow:0 2px 3px rgba(35,26,21,.12), 0 10px 22px rgba(180,68,42,.34);
  transform:translateY(-2px);
}
.hero__cta .btn--cta:active,
body:has(.hero) .buy__add:active,
body:has(.hero) .final .btn--cta:active{transform:translateY(0)}

/* the secondary: solid, raised, and the same 2px answer to the pointer */
.hero__cta .btn--ghost{
  background-color:var(--panel);background-image:none;
  border-color:var(--line-2);
  box-shadow:0 1px 1px rgba(35,26,21,.06), 0 4px 10px rgba(35,26,21,.07);
  transition:background-color .18s ease,border-color .18s ease,
             box-shadow .2s ease,transform .2s ease;
}
.hero__cta .btn--ghost:hover{
  background-color:var(--accent-l);background-image:none;
  border-color:var(--accent-line);
  box-shadow:0 2px 3px rgba(35,26,21,.08), 0 10px 22px rgba(35,26,21,.14);
  transform:translateY(-2px);
}

/* the global focus ring is 3px of --accent, which is the button's own colour
   on every one of these buttons. Petrol is the label's other ink and reads
   against both the terracotta and the chalk. */
.hero__cta .btn:focus-visible,
body:has(.hero) .buy__add:focus-visible,
body:has(.hero) .final .btn:focus-visible{
  outline:3px solid var(--petrol-d);outline-offset:3px;
}

@media (prefers-reduced-motion:reduce){
  .hero__cta .btn--cta:hover,
  .hero__cta .btn--ghost:hover,
  body:has(.hero) .buy__add:hover,
  body:has(.hero) .final .btn--cta:hover{transform:none}
}

/* ---- the three packs */
body:has(.hero) .buy__card{
  border-radius:24px;
  box-shadow:inset 0 0 0 1px var(--line),
             0 1px 1px rgba(35,26,21,.07), 0 4px 10px rgba(35,26,21,.10);
}
/* 22px, not 24: the head sits inside the card's 2px border */
body:has(.hero) .buy__card .buy__head{border-radius:22px 22px 0 0}

body:has(.hero) .buy__card--feature{
  overflow:visible;
  border-color:var(--accent);
  background:linear-gradient(180deg,#fdf3ee,var(--panel) 34%);
  box-shadow:0 2px 4px rgba(35,26,21,.10), 0 18px 38px rgba(35,26,21,.20);
}
/* --accent to --accent-d, both of which carry white at 5.5:1 or better. A
   lighter top stop was measured first and read 4.56:1, which is inside AA by
   0.06 and not worth the ribbon. */
body:has(.hero) .buy__card--feature .buy__head{
  background:linear-gradient(180deg,var(--accent),var(--accent-d));
}
/* the ribbon: a tab standing above the card. It carries no text of its own --
   the card already says what it is, and this pass changes no content. */
body:has(.hero) .buy__card--feature::before{
  content:"";position:absolute;left:50%;top:-11px;translate:-50% 0;
  width:132px;height:13px;border-radius:13px 13px 0 0;
  background:linear-gradient(180deg,#c2512f,var(--accent-d));
  box-shadow:0 -1px 2px rgba(35,26,21,.10);
}

/* dashed separators between the feature rows, PAINTED as a background rule
   rather than drawn as a border. A border or a padding here would add a pixel
   per row, and the three Add To Cart buttons share one baseline that is held
   by margin-top:auto against the card bottom -- a background changes no
   height at all, so the baseline cannot move. */
body:has(.hero) .buy__perks li{
  background-image:repeating-linear-gradient(90deg,
      var(--line-2) 0 5px,rgba(0,0,0,0) 5px 10px);
  background-repeat:no-repeat;background-size:100% 1px;background-position:0 100%;
}
body:has(.hero) .buy__perks li:last-child{background-image:none}
/*!SITE-HOME-PAINT-END*/
/* ==== footer type floor (footer_type.py) ==== */
/* The footer carried the smallest text on the page -- the legal pages,
   the guarantee and the contact routes, set as fine print. Running text
   and links sit at 16px, column headings at 15px (uppercase and
   letter-spaced, so they read larger than the number). Last in the file
   on purpose: it outranks the phone breakpoints that shrank them. */
footer li a{font-size:16px}
footer .copy{font-size:16px}
footer .disc li{font-size:16px}
footer .disc p{font-size:16px}
footer .fh{font-size:15px}
footer .fpay span{font-size:16px}
footer .fseals span{font-size:16px}
/* ==== end footer type floor ==== */

/* ==== modern surface (modern_surface.py) ==== */
/* House rule 11. This stylesheet had 18 box-shadow declaration(s)
   and 8 of them layered, so every panel read flat however generous
   the radius was. Two stops -- a tight contact shadow and a wide
   ambient one -- is what makes a surface look raised. The tint is
   this site's own ink (35,26,21), not neutral black.

   Paint only: border-radius, box-shadow and transform change no
   geometry, so this is safe below the critical marker and needs a
   restamp rather than a rebuild. */
:root{
  --radius:16px;
  --shadow:0 1px 2px rgba(35,26,21,.06), 0 6px 18px rgba(35,26,21,.07);
  --lift:0 2px 6px rgba(35,26,21,.09), 0 16px 34px rgba(35,26,21,.14);
}

/* These panels declared no radius of their own, so raising
   the token alone left them square. House rule 11 is a
   floor: it outranks a slot that chose square corners. */
.card,
.step,
.keypoints,
.callout,
.alert,
.toc,
.byline,
.posts article,
.shots figure,
.badgewall figure,
.tablewrap,
.faq,
.final,
.answer,
.whycard{border-radius:var(--radius)}

/* A surface a reader can click answers the pointer. 2px
   registers without reflowing the row beside it. */
.rel a,
.posts article,
.shots figure,
.badgewall figure{transition:box-shadow .2s ease, transform .2s ease}
.rel a:hover,
.posts article:hover,
.shots figure:hover,
.badgewall figure:hover{box-shadow:var(--lift);transform:translateY(-2px)}
@media(prefers-reduced-motion:reduce){
.rel a:hover,
.posts article:hover,
.shots figure:hover,
.badgewall figure:hover{transform:none}
}
/* ==== end modern surface ==== */
.review-foot{margin:0;padding:.6rem 0;font-size:.92rem}.review-foot a{font-weight:600}
