/* gohorsepeakgelatin.com - Horse Peak Gelatin, USA Authorized Retailer.
   Design slot: gohorsepeakgelatin.com in _generators/batch10_assignments.py.
   Bitter / Mulish, a TOASTED ROSE ground over cream that gradients on purpose,
   a wide cream masthead with the identity centred and the order rail beneath
   it, and a rose closing band whose seals sit in one row above a plain index.

   THE GROUND IS THE POINT, AND IT IS THE OPPOSITE OF THE SISTER DESK.
   The live sister for this product sells the same black-and-crimson bottle on
   a flat pale mint field with no gradient anywhere - not the ground, not a
   button, not the hero. This desk answers the same bottle the other way: a
   warm toasted rose washing down into cream, a gradient behind the product, a
   gradient on the primary button, a gradient across the closing band. Same
   label, opposite temperature, and nothing either page does can be mistaken
   for the other.

   The accent is the label's own red pulled deeper (#b41f28), so it reads as a
   line rather than a shout on a warm ground, and the deep wine (#5d1b21) does
   the work a black band would do on a cooler page.

   Everything above CRITICAL-END is inlined into every page head. */

/* ---- tokens */
:root{
  --paper:#fbf3ec;          /* the page ground: warm cream */
  --paper-2:#f4ddd4;        /* toasted rose, the tint band */
  --panel:#fffaf6;          /* cards and plates */
  --tint:#f4ddd4;
  --ink:#2a1a17;            /* body text, a warm near-black */
  --ink-2:#6a4f48;          /* secondary */
  --ink-3:#6f564e;          /* captions, meta. Darkened from #8b7069, which measured 3.46:1 on the tinted band */
  --deep:#5d1b21;           /* deep wine: topline, dark bands, buybar */
  --deep-2:#47141a;
  --red:#b41f28;            /* the label's red, deepened for a warm ground */
  --red-d:#8e161e;
  --red-l:#f9e7e6;
  --rose:#c9827a;           /* toasted rose, the secondary ramp */
  --rose-d:#8e4640;         /* the eyebrow colour. #a85a52 measured 3.34:1 on the rose ground */
  --line:#e8cec5;
  --line-2:#d6ab9f;
  --good:#276b4b;
  --warn:#8a5a10;
  --wrap:1160px;
  --measure:760px;
  --measure-wide:980px;
  --radius:3px;
  --radius-lg:8px;
  --shadow:0 1px 2px rgba(42,26,23,.05), 0 12px 30px rgba(42,26,23,.08);
  --shadow-lg:0 22px 56px rgba(93,27,33,.18);
  --navh:132px;
  --display:"Bitter",Georgia,"Times New Roman",serif;
  --text:"Mulish",system-ui,-apple-system,"Segoe UI",sans-serif;
}

/* ---- base */
*,*::before,*::after{box-sizing:border-box}
html,body{margin:0;padding:0}
html{overflow-x:clip;-webkit-text-size-adjust:100%}
body{
  overflow-x:clip;color:var(--ink);
  background:var(--paper);
  font-family:var(--text);font-size:17px;line-height:1.74;font-weight:400;
  -webkit-font-smoothing:antialiased;
}
img{max-width:100%;height:auto;display:block}
a{color:var(--red-d);text-underline-offset:3px}
a:hover{color:var(--red)}
h1,h2,h3,h4{font-family:var(--display);color:var(--ink);font-weight:700;line-height:1.2;margin:0 0 .5em}
/* Bitter is a slab with a large x-height and a wide set, so the display cap
   sits lower than a humanist face would take. At 2.9rem this H1 ran to four
   lines at 1440 and put the CTA through the 900px fold; 2.55rem holds it to
   three and leaves the CTA at 726. Measured with the webfont blocked as well,
   where Georgia sets one line narrower, not wider (hero.md). */
h1{font-size:clamp(1.78rem,1.12rem + 1.78vw,2.35rem);letter-spacing:-.014em}
h2{font-size:clamp(1.38rem,1.08rem + 1.15vw,2rem);letter-spacing:-.01em}
h3{font-size:1.16rem}
h4{font-size:1.02rem}
p,li{font-size:1.0625rem}
p{margin:0 0 1.05em}
b,strong{font-weight:700}
.wrap{width:100%;max-width:var(--wrap);margin-inline:auto;padding-inline:24px}
.skip{position:absolute;left:-9999px;top:0;background:var(--deep);color:#fff;padding:12px 18px;z-index:200}
.skip:focus{left:8px;top:8px}
:focus-visible{outline:3px solid var(--red);outline-offset:2px}

/* the eyebrow names the JOB of the section beneath it */
.eyebrow{
  display:inline-flex;align-items:center;gap:9px;
  font-family:var(--text);font-size:0.8125rem;font-weight:800;
  letter-spacing:.17em;text-transform:uppercase;color:var(--rose-d);
  margin:0 0 11px;
}
.eyebrow::before{content:"";width:26px;height:3px;border-radius:2px;
  background:linear-gradient(90deg,var(--red),var(--rose))}

/* ---- buttons: the gradient the sister desk does not have */
.btn{
  display:inline-flex;align-items:center;justify-content:center;gap:9px;
  min-height:54px;padding:15px 30px;
  font-family:var(--text);font-size:1rem;font-weight:800;letter-spacing:.015em;
  border:0;border-radius:var(--radius);cursor:pointer;text-decoration:none;
  background:linear-gradient(180deg,var(--deep),var(--deep-2));color:#fff;
  transition:filter .18s ease,transform .18s ease;
}
.btn:hover{filter:brightness(1.12);color:#fff}
.btn:active{transform:translateY(1px)}
.btn--red{background:linear-gradient(180deg,#c9262f,var(--red-d))}
.btn--red:hover{color:#fff}
.btn--lg{min-height:62px;padding:17px 36px;font-size:1.06rem}
.btn--ghost{background:none;color:var(--ink);box-shadow:inset 0 0 0 2px var(--line-2)}
.btn--ghost:hover{background:var(--paper-2);color:var(--ink);filter:none}
.btn--wide{width:100%}

/* ---- topline strip: the five trust facts, above the navigation.
   Role, lot, dose and count, guarantee, order phone. It exists so the menu
   does not have to carry them (hero.md). It sits ABOVE CRITICAL-END because
   it is the first thing painted. */
.util{background:linear-gradient(90deg,var(--deep-2),var(--deep) 45%,#6d2229);
  color:#e3bdb9;font-size:.8125rem;line-height:1.5}
.util__row{display:flex;flex-wrap:wrap;align-items:center;justify-content:center;
  gap:4px 18px;padding-block:8px}
.util__item{display:inline-flex;align-items:center;gap:7px;white-space:nowrap;min-width:0}
.util__item+.util__item::before{content:"";width:3px;height:3px;border-radius:50%;
  background:#a9666a;flex:0 0 auto;margin-right:11px}
.util b{color:#fff;font-weight:700}
.util a{color:inherit;text-decoration:none}
.util a:hover{text-decoration:underline}
@media (max-width:820px){
  /* Five items wrap to three lines and eat 103px of an 844px screen (hero.md).
     Keep role, guarantee and phone; the lot and the dose live on the pages
     whose subject they are. */
  .util__item--trim{display:none}
  .util__row{gap:4px 14px}
}

/* ---- header: a wide cream bar, the identity centred, the order rail beneath.
   Two tiers and nothing beside the name. The mark is the `stack` construction,
   which sets a small ringed glyph ABOVE the wordmark, so a centred masthead is
   what it was drawn for. `padding-block`, never the shorthand: .nav__id also
   carries .wrap and `padding:18px 0` would wipe the page gutter (pitfall 46). */
.nav{position:sticky;top:0;z-index:100;background:var(--panel);
  box-shadow:0 1px 0 var(--line),0 6px 22px rgba(42,26,23,.05)}
.nav__id{display:flex;justify-content:center;padding-block:9px 7px}
.brand{display:flex;flex-direction:column;align-items:center;gap:6px;
  text-align:center;text-decoration:none;color:var(--ink);min-width:0}
.brand__glyph{width:26px;height:26px;flex:0 0 auto}
/* Size the mark by ELEMENT as well as by class: brand_marks.py replaces the
   <svg> inside .brand and does not carry class="brand__glyph" onto the
   replacement, so a rule keyed only to the class stops applying the moment the
   tool runs and the glyph renders at its intrinsic size (pitfall 16). */
.brand>svg{width:26px;height:26px;flex:0 0 auto}
.bw{display:flex;flex-direction:column;gap:2px;min-width:0}
.bw b{font-family:var(--display);font-size:1.34rem;font-weight:700;
  letter-spacing:-.015em;line-height:1.06}
.bw b em{font-style:normal;color:var(--red)}
.bw small{font-size:0.75rem;font-weight:800;letter-spacing:.14em;
  color:var(--ink-3);text-transform:uppercase}
/* the order rail: destinations left, the price and the button right, on a
   toasted-rose strip under the cream bar */
.nav__rail{background:linear-gradient(180deg,var(--paper-2),#efd2c8);
  border-top:1px solid var(--line)}
.nav__railrow{display:flex;align-items:center;gap:18px;padding-block:4px}
.menu{display:flex;flex-wrap:wrap;gap:0 22px;list-style:none;margin:0;padding:0;
  align-items:center;min-height:42px}
.menu a{display:inline-block;padding:11px 0;font-family:var(--text);
  font-size:.9375rem;font-weight:700;color:var(--ink-2);text-decoration:none;
  border-bottom:2px solid transparent}
.menu a:hover{color:var(--ink)}
.menu a[aria-current="page"]{color:var(--red-d);border-bottom-color:var(--red)}
.menu__more{display:none}
.nav__buy{margin-left:auto;display:flex;align-items:center;gap:14px;flex:0 0 auto}
.nav__price{text-align:right;line-height:1.2}
.nav__price b{display:block;font-family:var(--display);font-size:1.02rem;
  font-weight:700;color:var(--ink)}
.nav__price span{font-size:.7188rem;font-weight:700;color:var(--ink-3)}
.nav__cta{min-height:42px;padding:9px 20px;font-size:.9062rem}
.burger{display:none;width:48px;height:44px;background:transparent;
  border:1px solid var(--line-2);border-radius:var(--radius);cursor:pointer;
  padding:11px 11px}
.burger span{display:block;height:2px;background:var(--ink);margin:0 0 5px}
.burger span:last-child{margin:0}

/* ---- hero: the bottle LEFT on a soft rose gradient, the copy RIGHT.
   The sister desk puts the bottle on a white card at the right of a flat
   field. Here the product leads the reading order on a wide screen and sits on
   a gradient plate with no hard card edge at all, which is the arrangement
   difference rather than a recolour. */
.hero{position:relative;padding:32px 0 52px;overflow-x:clip;
  background:linear-gradient(176deg,var(--paper-2),var(--paper) 58%,var(--paper))}
.hero__grid{position:relative;z-index:1;display:grid;
  grid-template-columns:minmax(0,.74fr) minmax(0,1.26fr);gap:40px;align-items:center}
.hero__copy{display:flex;flex-direction:column;min-width:0}
.hero h1{margin:0 0 16px}
.hero h1 em{font-style:normal;color:var(--red)}
.answer{background:var(--panel);border:1px solid var(--line);
  border-top:4px solid var(--red);border-radius:0 0 var(--radius) var(--radius);
  padding:18px 22px;margin:0 0 16px;box-shadow:var(--shadow)}
.answer p{margin:0 0 .7em;font-size:1rem}
.answer p:last-child{margin:0}
.hero__road{font-size:.9688rem;color:var(--ink-2);margin:0 0 18px;max-width:68ch}
.hero__cta{display:flex;flex-wrap:wrap;gap:12px;margin:0 0 20px}
.hero__sub{display:flex;flex-wrap:wrap;gap:8px 20px;margin:0 0 18px;
  font-size:0.9688rem;font-weight:700;color:var(--ink-2)}
.hero__sub span{display:inline-flex;align-items:center;gap:7px}
.hero__sub span::before{content:"\2713";color:var(--good);font-weight:800}
.factpills{display:flex;flex-wrap:wrap;gap:8px;list-style:none;margin:0 0 18px;padding:0}
.factpills li{font-size:0.9062rem;font-weight:700;color:var(--ink-2);
  background:var(--panel);border:1px solid var(--line);padding:7px 14px;border-radius:999px}
.factpills li b{color:var(--red-d);font-weight:800}
.figures{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:12px;margin:0}
.figures div{background:linear-gradient(180deg,var(--panel),#fff3ec);
  border:1px solid var(--line);padding:13px 15px;border-radius:var(--radius);min-width:0}
.figures b{display:block;font-family:var(--display);font-size:1.42rem;font-weight:700;
  color:var(--red-d);line-height:1.1}
.figures span{display:block;font-size:0.9062rem;font-weight:700;color:var(--ink-3);margin-top:3px}
.hero__media{position:relative;align-self:center;min-width:0}
/* No card edge. The plate IS a gradient, which is the thing the sister page
   refuses to do anywhere on its own site. */
.hero__card{position:relative;z-index:2;text-align:center;border-radius:var(--radius-lg);
  padding:20px 18px 14px;
  background:radial-gradient(78% 62% at 50% 44%,#fff6f0,rgba(244,221,212,.72) 62%,rgba(244,221,212,0))}
/* The vendor shot is an opaque white field, so on the rose plate it read as a
   hard square rectangle pasted over a rounded one. Same radius as the plate,
   and the two become one object. */
.hero__card img{width:100%;max-width:342px;height:auto;margin-inline:auto;
  border-radius:12px}
.hero__cap{margin:10px 0 0;font-size:.8125rem;font-weight:700;color:var(--ink-3);text-align:center}
/* On a phone the hero stacks and this bottle is a 1460x1600 portrait, so at the
   desktop cap it renders ~330px tall and pushes the Quick Answer past the
   first screen. Capping it INSIDE the critical section means the first paint is
   already the right size rather than reflowing when the async sheet lands. */
@media (max-width:760px){
  .hero__card{padding:8px 10px 6px}
  .hero__card img{max-width:214px}
  .hero__cap{margin-top:8px}
}
.trust__row{display:flex;flex-wrap:wrap;gap:10px 22px;margin:0;padding:0;list-style:none;
  font-size:0.9062rem;font-weight:700;color:var(--ink-2)}
.trust__row li{display:inline-flex;align-items:center;gap:8px}
.trust__row li::before{content:"\2713";color:var(--good);font-weight:800}

/* ---- inner page head */
.phead{padding:32px 0 12px;
  background:linear-gradient(178deg,var(--paper-2),var(--paper) 72%);
  border-bottom:1px solid var(--line)}
.crumbs{font-size:0.9062rem;color:var(--ink-3);margin:0 0 13px}
.crumbs a{color:var(--ink-2);text-decoration:none}
.crumbs a:hover{color:var(--red-d)}
.phead h1{margin:0 0 16px;max-width:var(--measure-wide)}
.phead .answer{max-width:var(--measure-wide)}
.lead{font-size:1.12rem;color:var(--ink-2);max-width:var(--measure)}

/* --- 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:980px){
  .hero__grid{grid-template-columns:1fr;gap:24px}
  /* display:contents so the copy column's CHILDREN become grid items and can be ordered individually. Without it only .hero__media is a grid item and every other order value silently does nothing (hero.md). */ .hero__copy{display:contents}
  .hero .eyebrow{order:1}
  .hero h1{order:2}
  .hero__media{order:3;margin:4px 0 18px}
  .hero__cta{order:5}
  .hero__road{order:6}
  .hero__sub{order:8}
}
@media (max-width:760px){
  .hero{padding:24px 0 38px}
}
@media (min-width: 981px){
  .hero__media{position: sticky; top: calc(var(--navh, 132px) + 12px); align-self: start; min-height: calc(100vh - var(--navh, 132px) - 26px); min-height: calc(100svh - var(--navh, 132px) - 26px); display: flex; flex-direction: column; align-items: center; justify-content: center;}
}
@media (prefers-reduced-motion: reduce){
  .hero__media{position: relative; top: 0; min-height: 0;}
}


/*!SITE-HOME-CRIT-START*/
/* ---- hero: the stacking context the plate needs on the first paint ----
   The motif that used to sit here (`crest-roll`) was PAINT -- a gradient, a
   blur and a keyframe -- inlined into the head of all 32 pages, and 31 of
   those have no .hero for it to attach to. It has been replaced by the slot
   motif, which lives below CRITICAL-END with the rest of the paint. What
   stays above the marker is the stacking order and the hero ground, because
   both are wrong for one frame if they arrive with the async sheet. */
.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(172deg,#eecdc9,#fbf3ec 50%,#fbf3ec)}

/* The one rule in this pass that moves a box, which is why it is up here and
   why the site is rebuilt rather than re-stamped.

   The recommended tier stands 14px proud of the other two. margin-top, never
   transform: fix_reveal.py settles every card at transform:none, so a
   transform lift is wiped the instant the observer fires. .prices is
   align-items:stretch, so a negative top margin grows the featured card
   UPWARD and leaves its bottom edge on the row line -- which is what keeps
   the three Add-To-Cart buttons on one baseline. Measured at 1440 after the
   change: three button tops identical, and identical to before it.

   Only where the row is three columns. Under 761px .prices is one column and
   the raise would just eat the gap above it. */
@media (min-width:761px){
  body:has(.hero) .card--pack.featured{margin-top:-14px}
}
/*!SITE-HOME-CRIT-END*/

/* ---- hero motif -- crest-roll ---------------------------------------- */
.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(172deg,#eecdc9,#fbf3ec 50%,#fbf3ec)}.hero__media::before{content:'';position:absolute;left:-16%;right:-16%;top:36%;height:34%;z-index:1;pointer-events:none;filter:blur(10px);border-radius:50%;background:linear-gradient(90deg,transparent,rgba(180,31,40,0.34) 42%,rgba(180,31,40,0.42) 58%,transparent);animation:ghpCrest 12s cubic-bezier(.4,.1,.5,1) infinite}@keyframes ghpCrest{0%{transform:translateX(-22%) scaleY(.8);opacity:0}35%{opacity:.7}70%{transform:translateX(18%) scaleY(1.1);opacity:.45}100%{transform:translateX(22%) scaleY(.9);opacity:0}}
@media(prefers-reduced-motion:reduce){.hero__card{animation:none!important}.hero__media::before,.hero__media::after{animation:none!important;opacity:0!important}}

/*!CRITICAL-END*/
/* ---- sections */
.sec{padding:58px 0;position:relative}
.sec--tint{background:linear-gradient(180deg,var(--paper-2),#f7e6de)}
.sec--panel{background:var(--panel)}
.sec--dark{background:linear-gradient(160deg,var(--deep-2),var(--deep) 60%,#6d2229);color:#eed7d4}
.sec--dark h2,.sec--dark h3{color:#fff}
.sec--dark p,.sec--dark li{color:#e7cbc7}
.sec--dark .eyebrow{color:#f0b0ab}
.sec--dark .eyebrow::before{background:linear-gradient(90deg,#f0b0ab,#c9827a)}
.sec--dark a{color:#f5c6c2}
.sec--center{text-align:center}
.sec--center .sec__head{margin-inline:auto}
/* The two quarantine sections. Every gap in this formula is stated inside one
   of these, once, and the class is what marks them: preflight's absence-density
   check measures the prose OUTSIDE them, because concentrating the detail here
   is the rule's own prescribed fix (pitfall 88). Visually they are a plain
   field between two red rules, so a reader can see where the candour lives. */
.sec--honest{background:var(--panel);border-block:2px solid var(--red)}
.sec--honest .sec__head h2{color:var(--red-d)}
.sec__head{max-width:var(--measure);margin:0 0 26px}
.sec__head h2{margin:0 0 10px}
.sec__head p{color:var(--ink-2);margin:0}
.sec--dark .sec__head p{color:#e7cbc7}

/* one measure, centred; multi-column components keep the full wrap */
@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>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}
}

/* ---- lists */
.ticks{list-style:none;margin:0 0 1.1em;padding:0}
.ticks li{position:relative;padding-left:28px;margin:0 0 .5em}
.ticks li::before{content:"\2713";position:absolute;left:0;top:0;color:var(--good);font-weight:800}
.sec--dark .ticks li::before{color:#7ed0a6}

/* ---- tables */
.tablewrap{overflow-x:auto;margin:0 0 1.2em;border:1px solid var(--line);
  border-radius:var(--radius);background:var(--panel)}
table{border-collapse:collapse;width:100%;min-width:520px;font-size:1rem}
th,td{padding:13px 16px;text-align:left;border-bottom:1px solid var(--line);vertical-align:top}
th{font-family:var(--display);font-weight:700;letter-spacing:.01em;color:#fff;
  background:linear-gradient(180deg,#6d2229,var(--deep));font-size:.9375rem}
tbody tr:nth-child(even){background:#fdf3ee}
tbody tr:last-child td{border-bottom:0}
td b{color:var(--ink)}
.tnote{font-size:.9375rem;color:var(--ink-3);margin:-.4em 0 1.2em}

/* ---- numbered steps */
.steps{display:grid;gap:16px;margin:0 0 1.2em;counter-reset:s}
.steps>*{min-width:0}
.step{position:relative;background:var(--panel);border:1px solid var(--line);
  border-radius:var(--radius);padding:20px 22px 20px 72px}
.step::before{counter-increment:s;content:counter(s);
  position:absolute;left:20px;top:19px;width:38px;height:38px;
  display:grid;place-items:center;
  background:linear-gradient(160deg,#c9262f,var(--red-d));color:#fff;
  font-family:var(--display);font-weight:700;font-size:1.02rem;border-radius:50%}
.step h3{margin:0 0 6px}
.step p:last-child{margin:0}

/* ---- cards: a rose wash at the foot rather than a rule at the top */
.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))}
/* A grid item's default min-width is auto, which floors at min-content, so a
   card holding a table or a nowrap chip refuses to shrink and overflows the
   phone silently. min-width:0 at every width, not only in a media query. */
.grid>*{min-width:0}
.card{position:relative;border:1px solid var(--line);border-radius:var(--radius);
  padding:24px 22px 22px;overflow:hidden;
  background:linear-gradient(180deg,var(--panel) 60%,#fdf0e9)}
.card h3{margin:0 0 8px}
.card p:last-child,.card ul:last-child{margin-bottom:0}
.sec--dark .card{background:linear-gradient(180deg,#5a1c22,#4a151b);border-color:#7a3239}

/* ---- AI quick summary. `.qa` is the speakable pair to `.answer`. */
.qa{max-width:var(--measure-wide)}
.qa>p:first-child{border-left:3px solid var(--red);padding-left:16px;margin:0 0 1.2em;color:var(--ink)}
.qa>.tablewrap:last-child{margin-bottom:0}

/* ---- callout, alert, quote, keypoints */
.callout{background:linear-gradient(180deg,var(--paper-2),#f9e9e2);
  border:1px solid var(--line);border-radius:var(--radius);padding:20px 22px;margin:0 0 1.2em}
.callout b:first-child{display:block;margin-bottom:6px;color:var(--ink)}
.callout p:last-child{margin:0}
.alert{background:#fdf6ea;border:1px solid #efdcbc;border-left:4px solid var(--warn);
  border-radius:0 var(--radius) var(--radius) 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(--display);font-size:1.24rem;font-weight:400;line-height:1.52;
  color:var(--ink);border-left:4px solid var(--rose);padding:4px 0 4px 22px;margin:0 0 1.2em}
.pullquote cite{display:block;font-family:var(--text);font-size:.9375rem;font-style:normal;
  font-weight:700;color:var(--ink-3);margin-top:8px}
.keypoints{background:var(--panel);border:1px solid var(--line);
  border-left:4px solid var(--red);border-radius:0 var(--radius) var(--radius) 0;
  padding:20px 22px;margin:0 0 1.2em}
.keypoints>b{display:block;margin-bottom:8px}
.keypoints ul{margin:0;padding-left:20px}

/* ---- image beside copy */
/* A .split is a pair: the picture and the paragraph that belongs to it start
   on the same line. Centring them left the first line of copy 119-176px below the top of
   its own image (measured on this site at 1440), so the copy floated in the
   middle of the column with dead air above and below it and stopped reading as
   part of the picture beside it. Nothing overlaps and nothing overflows, which
   is why no checker has ever seen it. */
.split{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:32px;
  align-items:start;margin:0 0 1.2em}
.split--flip .split__img{order:2}
/* Same family as .grid above: a .tablewrap holding a 520px-min table keeps its
   column 520px wide however narrow the grid gets, and the right-hand half is
   then clipped away by body overflow-x:clip with nothing to scroll and nothing
   to report. min-width:0 is the fix and it belongs at every width. */
.split__img,.split__body{min-width:0}
.split__img img{width:100%;border:1px solid var(--line);border-radius:var(--radius);
  background:var(--panel)}
.split__body p:last-child{margin:0}
/* The artwork is sized by the artwork, not by half the wrap. Filled to its
   own column these square and portrait shots stand two to five times the
   height of the two or three paragraphs beside them, and no alignment rescues
   a pair that far out of proportion. The cap is on the HEIGHT and the width
   follows it, so a wide panel shot -- whose height is set by the column width
   and not by this rule -- is untouched, and the picture keeps its aspect-ratio
   box so the cap costs no CLS. Desktop only: below the stacking breakpoint the
   split is one column and the picture should fill the phone. */
@media (min-width:761px){
  .split__img img{max-height:420px;width:auto;margin-inline:auto}
}


/* ---- stat band */
.stats{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:20px;text-align:center}
.stats>*{min-width:0}
.stats div b{display:block;font-family:var(--display);font-size:2.05rem;font-weight:700;
  color:#fff;line-height:1.1}
.stats div span{display:block;font-size:.9375rem;color:#e7cbc7;margin-top:4px}

/* ---- label versus research */
.versus{display:grid;grid-template-columns:1.05fr .85fr 1.5fr;border:1px solid var(--line);
  border-radius:var(--radius);overflow:hidden;background:var(--panel);margin:0 0 1.2em}
.versus>div{padding:13px 16px;border-bottom:1px solid var(--line);font-size:.98rem;min-width:0}
.versus>div:nth-child(3n+1){font-weight:700;background:#fdf3ee}
.versus__h{background:linear-gradient(180deg,#6d2229,var(--deep))!important;color:#fff;
  font-family:var(--display);font-weight:700;font-size:.92rem}

/* ---- ingredient cards */
.inglist{display:grid;gap:16px}
/* .ing__dose is white-space:nowrap and one of these labels renders past 200px,
   which sets the card's min-content floor. min-width:0 lets the card shrink;
   .ingcard__top already wraps, so the chip drops onto its own line and fits. */
.inglist>*{min-width:0}
.ingcard{background:var(--panel);border:1px solid var(--line);border-left:4px solid var(--rose);
  border-radius:0 var(--radius) var(--radius) 0;padding:22px 24px}
.ingcard__top{display:flex;flex-wrap:wrap;align-items:baseline;gap:8px 12px;margin:0 0 10px}
.ingcard__top h3{margin:0}
.ing__latin{font-size:.9375rem;font-style:italic;color:var(--ink-3)}
.ing__dose{margin-left:auto;font-size:.9375rem;font-weight:800;color:#fff;
  background:linear-gradient(180deg,#c9262f,var(--red-d));padding:4px 12px;
  border-radius:999px;white-space:nowrap}
.ingcard p:last-child{margin:0}

/* ---- add-to-cart pricing panel */
.prices{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:20px;
  align-items:stretch;margin:0 0 20px}
.prices>*{min-width:0}
.card--pack{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-lg);overflow:hidden;position:relative}
/* No lift on the featured card. A negative margin raises its box, which makes
   it taller than its siblings and trips the rule that a pricing row shares one
   height and one button baseline. The card is already unmistakable from its
   border, its shadow, its head band and its flag. */
.card--pack.featured{border-color:var(--red);box-shadow:var(--shadow-lg)}
.pack__head{background:linear-gradient(180deg,var(--paper-2),#efd2c8);
  border-bottom:1px solid var(--line);padding:14px 20px;display:flex;align-items:center;gap:10px}
.card--pack.featured .pack__head{background:linear-gradient(180deg,#6d2229,var(--deep));
  border-bottom-color:var(--deep)}
.card--pack.featured .pack__head b,.card--pack.featured .pack__head span{color:#fff}
.pack__head b{font-family:var(--display);font-size:1.08rem;font-weight:700}
.pack__head span{font-size:.8125rem;font-weight:800;color:var(--ink-3);margin-left:auto}
.pack__flag{position:absolute;right:0;top:0;background:linear-gradient(180deg,#c9262f,var(--red-d));
  color:#fff;font-family:var(--text);font-size:0.75rem;font-weight:800;letter-spacing:.09em;
  text-transform:uppercase;padding:6px 13px;z-index:3;border-radius:0 0 0 var(--radius)}
.pack__body{display:flex;flex-direction:column;flex:1;padding:20px 20px 22px}
.card--pack img{width:auto;max-width:100%;height:var(--pack-img,168px);object-fit:contain;
  margin-inline:auto;margin-bottom:14px}
.pack__per{font-family:var(--display);font-size:2.26rem;font-weight:700;color:var(--ink);
  line-height:1;text-align:center}
.pack__per sup{font-size:1rem;top:-.7em}
.pack__unit{display:block;text-align:center;font-size:.875rem;font-weight:800;
  color:var(--ink-3);margin:4px 0 12px}
.pack__tot{display:flex;align-items:baseline;justify-content:center;gap:9px;
  margin:0 0 14px;font-size:1rem}
.pack__tot b{font-weight:800}
.pack__was{color:var(--ink-3);text-decoration:line-through;font-weight:700}
.pack__perks{list-style:none;margin:0 0 18px;padding:0;font-size:.9375rem}
.pack__perks li{position:relative;padding-left:24px;margin:0 0 6px;color:var(--ink-2)}
.pack__perks li::before{content:"\2713";position:absolute;left:0;color:var(--good);font-weight:800}
.card--pack>.pack__body>.btn{margin-top:auto}
.pack__marks{display:flex;flex-wrap:wrap;gap:4px 12px;justify-content:center;margin:12px 0 0;
  font-size:.8125rem;color:var(--ink-3)}
.buy__note{font-size:.9375rem;color:var(--ink-3);text-align:center;margin:0}

/* ---- captioned images */
.shots{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:20px;margin:0 0 1.2em}
.shots.s2{grid-template-columns:repeat(2,minmax(0,1fr))}
.shots.s1{grid-template-columns:minmax(0,1fr)}
.shots>*{min-width:0}
.shots figure{margin:0;background:var(--panel);border:1px solid var(--line);
  border-radius:var(--radius);overflow:hidden}
.shots img{width:100%}
.shots figcaption{padding:16px 18px}
.shots figcaption b{display:block;margin-bottom:5px;color:var(--ink)}
.shots figcaption span{font-size:.9375rem;color:var(--ink-2)}
figure.portrait img{width:var(--figw,320px);margin-inline:auto}

/* ---- seal wall */
.badgewall{display:grid;grid-template-columns:repeat(4,minmax(0,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);padding:18px 16px}
.badgewall img{width:74px;height:74px;object-fit:contain;margin:0 auto 10px}
.badgewall b{display:block;font-size:.98rem;margin-bottom:4px;color:var(--ink)}
.badgewall span{font-size:.875rem;color:var(--ink-2)}

/* ---- star distribution */
.meter{margin:0 0 1.2em}
.meter__row{display:grid;grid-template-columns:76px 1fr 52px;gap:12px;align-items:center;
  margin:0 0 8px;font-size:.9375rem}
.meter__row>*{min-width:0}
.meter__bar{height:10px;background:var(--line);border-radius:999px;overflow:hidden}
.meter__bar i{display:block;height:100%;background:linear-gradient(90deg,var(--rose),var(--red))}
.stars{color:#c8920f;letter-spacing:1px}
.stars i{font-style:normal;opacity:.34}

/* ---- FAQ. Padding on <summary>, which is the click target (pitfall 73). */
.faq{border:1px solid var(--line);border-radius:var(--radius);overflow:hidden;
  background:var(--panel);margin:0 0 1.2em}
.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(--display);font-weight:700;font-size:1.02rem;color:var(--ink)}
.faq summary::-webkit-details-marker{display:none}
.faq summary::after{content:"+";position:absolute;right:20px;top:50%;translate:0 -50%;
  font-family:var(--text);font-size:1.34rem;font-weight:400;color:var(--red)}
.faq details[open] summary::after{content:"\2212"}
.faq__body{padding:0 20px 18px}
.faq__body p:last-child,.faq__body ul:last-child{margin-bottom:0}

/* ---- 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}
/* The reference list prints each source's full URL as the link TEXT, and a URL
   is one unbreakable token. `anywhere` rather than `break-word` because it also
   lowers the element's min-content, which is what stops an ancestor being sized
   by the longest URL in the list. */
.refs li,.refs li a{overflow-wrap:anywhere}
.byline{display:flex;gap:18px;background:linear-gradient(180deg,var(--panel),#fdf0e9);
  border:1px solid var(--line);border-left:4px solid var(--red);
  border-radius:0 var(--radius) var(--radius) 0;padding:22px 24px;margin:0 0 1.2em}
.byline__mark{flex:0 0 auto;width:54px;height:54px;display:grid;place-items:center;
  background:linear-gradient(160deg,#6d2229,var(--deep-2));color:#fff;
  font-family:var(--display);font-weight:700;font-size:1.04rem;border-radius:var(--radius)}
.byline b{display:block;margin-bottom:6px;color:var(--ink)}
.byline p{font-size:.9688rem;color:var(--ink-2);margin:0}

/* ---- closing CTA */
.final{background:linear-gradient(180deg,var(--panel),#fdf0e9);border:1px solid var(--line);
  border-left:4px solid var(--red);border-radius:0 var(--radius) var(--radius) 0;padding:30px 32px}
.final--media{display:grid;grid-template-columns:auto minmax(0,1fr);gap:30px;align-items:center}
.final--media>*{min-width:0}
.final__img img{width:200px}
.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);padding:20px 22px;text-decoration:none;color:var(--ink);
  transition:border-color .18s ease,transform .18s ease}
.rel a:hover{border-color:var(--rose);transform:translateY(-2px)}
.rel b{display:block;font-family:var(--display);font-size:1.05rem;font-weight:700;
  color:var(--ink);margin-bottom:5px}
.rel span{font-size:.9375rem;color:var(--ink-2)}

/* ---- forms. 16px minimum or iOS Safari zooms on focus (pitfall 86). */
.form{display:grid;gap:16px;max-width:var(--measure)}
.field label{display:block;font-weight:800;font-size:.9688rem;margin-bottom:6px}
.field input,.field select,.field textarea{width:100%;font-family:var(--text);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:0.9062rem;color:var(--ink-3);margin-top:5px}

/* ---- blog */
.article{max-width:var(--measure);margin-inline:auto}
.postmeta{font-size:.9375rem;color:var(--ink-3);margin:0 0 20px}
.toc{background:linear-gradient(180deg,var(--paper-2),#f9e9e2);border:1px solid var(--line);
  border-radius:var(--radius);padding:20px 24px;margin:0 0 28px}
.toc b{display:block;margin-bottom:8px;color:var(--ink)}
.toc ol{margin:0;padding-left:20px}
.toc li{margin:0 0 5px;font-size:1.062rem}
.article h2{scroll-margin-top:170px}
.posts{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:20px}
.posts>*{min-width:0}
.posts article{background:var(--panel);border:1px solid var(--line);
  border-radius:var(--radius);padding:22px 24px}
.posts h3{margin:0 0 8px}
.posts p{font-size:1.062rem;color:var(--ink-2)}
.dtable{min-width:520px}
/* The mid-article CTA sits in a 760px reading column, not the full wrap, so
   the 200px product shot beside it leaves too little for the copy (pitfall 24). */
.article .final--media{grid-template-columns:auto minmax(0,1fr);gap:22px}
.article .final__img img{width:132px}

/* ---- footer: a rose band, the seals in ONE row above a plain index */
.fcta{background:linear-gradient(155deg,var(--deep-2),var(--deep) 55%,#78262d);
  color:#fff;padding:50px 0}
.fcta h2,.fcta__h{color:#fff}
.fcta__box{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:34px;align-items:center}
.fcta__box>*{min-width:0}
.fcta__eye{display:inline-block;font-family:var(--text);font-size:.78125rem;font-weight:800;
  letter-spacing:.17em;text-transform:uppercase;color:#f0b0ab;margin-bottom:8px}
.fcta__h{font-family:var(--display);font-size:1.58rem;font-weight:700;line-height:1.26;margin:0 0 10px}
.fcta p{color:#e7cbc7}
.fcta__sm{font-size:.9375rem;color:#d3a9a5;margin:12px 0 0}
.fcta__sm a,.fcta p a{color:#f5c6c2}
.fcta__img img{width:280px}
footer{background:var(--panel);border-top:1px solid var(--line)}
/* The rose band: seals in one row, the payment strip beside them, nothing
   else. It is the only place on the site where the toasted rose runs edge to
   edge at full strength. */
.fband{background:linear-gradient(90deg,#efd2c8,var(--paper-2) 50%,#efd2c8);
  border-bottom:1px solid var(--line)}
.fband__row{display:flex;flex-wrap:wrap;align-items:center;gap:12px 16px;padding-block:20px}
.fband__row img{width:46px;height:46px;object-fit:contain;flex:0 0 auto}
.fband__note{flex:1 1 220px;min-width:0;font-size:.9375rem;color:var(--ink-2)}
.fpay{display:flex;flex-wrap:wrap;align-items:center;gap:16px;padding-block:0 20px}
.fpay img{width:220px;height:auto}
.fpay span{font-size:.9375rem;color:var(--ink-3)}
/* The plain index: the name, the desk, then every page in four ruled columns.
   No flowing rows, no oversized wordmark - the band above is the flourish and
   the index underneath is deliberately ordinary. */
.findex{padding-block:34px 10px}
.fname{font-family:var(--display);font-weight:700;font-size:1.62rem;line-height:1.1;
  color:var(--ink);margin:0}
.fname em{font-style:normal;color:var(--red)}
.frole{font-size:.9375rem;color:var(--ink-2);margin:6px 0 24px;max-width:var(--measure)}
.fcols{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:22px 26px;
  padding-block:22px 26px;border-top:1px solid var(--line)}
.fcols>*{min-width:0}
.fcols h3{font-family:var(--text);font-size:.78125rem;font-weight:800;letter-spacing:.14em;
  text-transform:uppercase;color:var(--ink-3);margin:0 0 10px}
.fcols ul{list-style:none;margin:0;padding:0}
.fcols li{margin:0 0 2px}
/* inline-block, not block: the box shrink-wraps so the hover underline stays
   the width of the words, and the negative margin gives the row height back
   (pitfall 82). */
footer li a{display:inline-block;padding-block:7px;margin-block:-7px;font-size:.9688rem;
  color:var(--ink-2);text-decoration:none}
footer li a:hover{color:var(--red-d)}
.fcols li span{font-size:.9688rem;color:var(--ink-3)}
.disc{background:linear-gradient(180deg,var(--paper-2),#f9e9e2);border-top:1px solid var(--line);
  padding-block:28px 32px}
.disc p,.disc li{font-size:.9375rem;color:var(--ink-2)}
.disc b{color:var(--ink)}
.disc__list{columns:2;column-gap:38px;list-style:none;margin:14px 0 0;padding:0}
.disc__list li{break-inside:avoid;margin:0 0 9px;padding-left:16px;position:relative}
.disc__list li::before{content:"";position:absolute;left:0;top:.66em;width:8px;height:2px;
  background:var(--rose-d)}
.copy{margin:18px 0 0;padding-top:16px;border-top:1px solid var(--line);font-size:.9375rem}

/* ---- sticky buy bar */
.buybar{position:fixed;left:0;right:0;bottom:0;z-index:90;
  background:linear-gradient(180deg,var(--deep),var(--deep-2));color:#fff;
  transform:translateY(105%);transition:transform .25s ease}
.buybar.show{transform:none}
.buybar__in{display:flex;align-items:center;gap:18px;max-width:var(--wrap);margin-inline:auto;
  padding:12px 24px}
.buybar__t{font-size:.9375rem;min-width:0}
.buybar__t b{display:block;font-size:1rem}
.buybar__t span{color:#e3bdb9}
.buybar .btn{margin-left:auto;flex:0 0 auto}

/* ---- 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 */
@media (max-width:1180px){
  .menu{gap:0 16px}
  .menu a{font-size:.9062rem}
}
@media (max-width:1100px){
  .versus{grid-template-columns:1fr .8fr 1.3fr}
  .fcols{grid-template-columns:repeat(2,minmax(0,1fr))}
}
@media (max-width:980px){
  :root{--navh:132px}
  .hero__grid{grid-template-columns:1fr;gap:24px}
  /* display:contents so the copy column's CHILDREN become grid items and can be
     ordered individually. Without it only .hero__media is a grid item and every
     other order value silently does nothing (hero.md). */
  .hero__copy{display:contents}
  .hero .eyebrow{order:1}
  .hero h1{order:2}
  .hero__media{order:3;margin:4px 0 18px}
  .answer{order:4}
  .hero__cta{order:5}
  .hero__road{order:6}
  .hero__sub{order:8}
  .trust__row{order:9}
  .factpills{order:10}
  .figures{order:11}
  .nav__price{display:none}
  .menu{display:none;flex-direction:column;align-items:stretch;gap:0;padding:6px 0 12px;
    min-height:0}
  .menu.open{display:flex}
  .menu__more{display:block}
  .menu a{padding:12px 0;border-bottom:1px solid var(--line-2)}
  .menu a[aria-current="page"]{border-bottom-color:var(--line-2)}
  .burger{display:block;order:-1}
  .nav__railrow{padding-block:8px;gap:12px;flex-wrap:wrap}
  .nav__buy{margin-left:auto}
  .grid.g4{grid-template-columns:repeat(2,minmax(0,1fr))}
  .stats{grid-template-columns:repeat(2,minmax(0,1fr));gap:24px}
  .fcta__box{grid-template-columns:1fr}
  .fcta__img{display:none}
  .final--media{grid-template-columns:1fr;gap:20px}
}
@media (max-width:760px){
  body{font-size:16.5px}
  .sec{padding:42px 0}
  .hero{padding:24px 0 38px}
  .nav__id{padding-block:8px 6px}
  .bw b{font-size:1.28rem}
  /* The role line under the wordmark repeats the topline strip word for word
     and wraps to two lines on a phone. Dropping it takes 20px off the
     masthead, which the sticky header pays for on every scroll. */
  .bw small{display:none}
  .grid.g2,.grid.g3,.grid.g4{grid-template-columns:1fr}
  .prices{grid-template-columns:1fr}
  .card--pack.featured{order:-1}
  .shots,.shots.s2{grid-template-columns:1fr}
  .badgewall{grid-template-columns:repeat(2,minmax(0,1fr))}
  .rel,.posts{grid-template-columns:1fr}
  .split,.split--flip .split__img{grid-template-columns:minmax(0,1fr);order:0}
  .versus{grid-template-columns:1fr}
  .versus>div:nth-child(3n+1){border-top:2px solid var(--line-2)}
  /* The dose chip is white-space:nowrap and margin-left:auto, so on a narrow
     card it is pushed to the right of a line with no room for it and overhangs
     the card edge. On a phone let it start its own line and wrap its own text. */
  .ing__dose{margin-left:0;white-space:normal}
  .disc__list{columns:1}
  .fcols{grid-template-columns:1fr;gap:18px}
  .figures{grid-template-columns:1fr;gap:8px}
  .buybar__in{flex-wrap:wrap;gap:10px;padding-block:10px}
  .buybar .btn{width:100%;margin-left:0}
  .article .final--media{grid-template-columns:1fr}
}

/* ---- hero: the bottle settles on its plate ------------------------------
   Transform only, NEVER opacity: the bottle is the LCP element and an element
   starting at opacity:0 is not recorded as painted (hero.md). The movement is
   on the CARD, never on the <img>, which is preloaded. */
.hero__card{isolation:isolate}
@media (prefers-reduced-motion:no-preference){
  .hero__card{animation:ghpSettle 10s ease-in-out infinite}
  @keyframes ghpSettle{0%,100%{transform:translateY(0)}50%{transform:translateY(-9px)}}
}

/* ---- hero: sticky, centred product column -------------------------------
   The product column holds its place, vertically centred, until the hero has
   fully scrolled past. --navh is measured and published by site.js, because
   this masthead is an identity bar plus an order rail and its height changes
   between breakpoints.

   min-height makes the sticky box a full screen tall so the shot can be
   CENTRED inside it. Requires .hero NOT to clip on the block axis: any
   non-visible overflow on an ancestor becomes the scrollport sticky resolves
   against (pitfall 65). */
@media (min-width: 981px) {
  .hero__grid { align-items: start; }
  .hero__media {
    position: sticky;
    top: calc(var(--navh, 132px) + 12px);
    align-self: start;
    min-height: calc(100vh - var(--navh, 132px) - 26px);
    min-height: calc(100svh - var(--navh, 132px) - 26px);
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
  }
}
/* Cancelling the sticky column must NOT cancel the containing block. Every
   hero motif sizes its .hero__media pseudo-elements in PERCENT, so they
   resolve against the nearest positioned ancestor; `static` re-parents them to
   a box several times wider -- measured at 1800px against a 523px column --
   and the ring lands across the headline. Worse, the same query stops it
   animating, so it SITS there: ask for less motion, get the one broken hero.

   `relative` lays out identically to `static` and keeps the containing block.
   `top:0` is not decoration: the rule above sets a top offset of one nav height
   plus 14px, which a relative box would apply for real and push the plate
   ~110px down the page (pitfall 65). Written WITHOUT naming that custom
   property in the usual var() form on purpose -- preflight's undefined-variable
   check reads comments too, so a property named here is a property it believes
   the sheet uses. Measured on 7 sites before and after (pitfall 107). */
@media (prefers-reduced-motion: reduce) {
  .hero__media { position: relative; top: 0; min-height: 0; }
}

/* --- pack cards read as one repeated object ------------------------------
   A pricing row is three cards that have to share their edges, their image
   slot and their button baseline. The three pack shots here are 1080x1080,
   1800x1108 and 1800x689 - three different shapes - so without these rules the
   images render at three sizes and the buttons sit at three heights.

   The height lives here and not on the <img> attributes on purpose: those must
   keep stating each file's true ratio, or fix_img_dims.py rewrites them on
   every build and the layout shift gets worse (pitfall 91). */
.card--pack{display:flex;flex-direction:column}
.card--pack img{width:auto;max-width:100%;height:var(--pack-img,150px);
  object-fit:contain;margin-inline:auto;margin-bottom:14px}
.card--pack>.btn{margin-top:auto}
/* 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}

/* ==== 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 -- modern surface and the hero motif.   gohorsepeakgelatin.com
   Design slot: motif "rise"; card 16px / control 10px; depth = one deep,
   very diffuse ambient stop (0 22px 60px) over a hairline ring; ribbon = a
   tab above the card.

   SCOPE. Every rule is prefixed body:has(.hero). class="hero" is on
   index.html and on no other page of this site, so .btn, .card, .pack__flag
   and .buybar -- all of which exist on the other 31 pages -- are reached
   here on the home page only.

   SPECIFICITY, NOT ORDER. modern_surface.py and footer_type.py strip and
   re-append their own blocks on every build and land after this one, and
   modern_surface targets .card and .card--pack at (0,1,0). body:has(.hero)
   plus a class is (0,2,1), so these win wherever the two meet, whatever the
   source order ends up being.

   Paint only: radius, shadow, background, colour, transform, transition and
   animation move no box, so this belongs below the critical marker. The one
   rule of this pass that does move a box is above the marker, inside the
   SITE-HOME-CRIT block.
   ====================================================================== */
:root{
  --ghp-card:16px;                                /* panels and cards */
  --ghp-ctl:10px;                                 /* buttons and controls */
  --ghp-ring:inset 0 0 0 1px rgba(93,27,33,.10);  /* the hairline, in wine */
  --ghp-amb:0 16px 40px rgba(93,27,33,.10);       /* the small panels */
  --ghp-amb-d:0 22px 60px rgba(93,27,33,.16);     /* the slot's own depth */
  --ghp-amb-x:0 26px 70px rgba(93,27,33,.24);     /* hover, featured tier */
  --ghp-ease:cubic-bezier(.2,.7,.3,1);
}

/* ---- surfaces: one ring plus one very diffuse ambient stop.
   Tinted 93,27,33 -- this site's own deep wine -- never neutral black, which
   greys a warm cream ground. */
body:has(.hero) .card,
body:has(.hero) .faq,
body:has(.hero) .callout,
body:has(.hero) .ingcard,
body:has(.hero) .byline,
body:has(.hero) .tablewrap,
body:has(.hero) .shots figure,
body:has(.hero) .badgewall figure{border-radius:var(--ghp-card);
  box-shadow:var(--ghp-ring),var(--ghp-amb)}

/* The Quick Answer and the closing panel are the two boxes the page is read
   for, so they carry the deep stop rather than the shallow one. */
body:has(.hero) .answer,
body:has(.hero) .final{border-radius:var(--ghp-card);
  box-shadow:var(--ghp-ring),var(--ghp-amb-d)}

/* The plate behind the bottle has no card edge by design -- it is a radial
   gradient that fades out. The SHOT is the object, so the depth goes on the
   shot. No animation on it at any point: it is the LCP element and it is
   preloaded. */
body:has(.hero) .hero__card{border-radius:var(--ghp-card)}
body:has(.hero) .hero__card img{border-radius:14px;box-shadow:var(--ghp-amb-d)}

/* ---- controls at the slot's 10px, against 16px panels, so a button never
   reads as a small card. */
body:has(.hero) .btn,
body:has(.hero) .burger{border-radius:var(--ghp-ctl)}
body:has(.hero) .btn{transition:transform .22s var(--ghp-ease),
  box-shadow .22s ease,filter .22s ease,background-color .22s ease}
body:has(.hero) .btn:hover{transform:translateY(-2px)}
body:has(.hero) .btn:active{transform:translateY(0)}
/* The house focus ring is 3px solid var(--red), which is invisible on the red
   buying button. On this page the ring is the wine. */
body:has(.hero) .btn:focus-visible,
body:has(.hero) .menu a:focus-visible{outline:3px solid var(--deep);
  outline-offset:3px}

/* The buying button is the only gradient of the pair. The secondary stays
   solid, so the two read as two weights rather than as two colours. */
body:has(.hero) .btn--red{
  background-image:linear-gradient(150deg,#d43a42 0%,var(--red) 46%,var(--red-d) 100%);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.22),0 14px 34px rgba(142,22,30,.26)}
body:has(.hero) .btn--red:hover{
  box-shadow:inset 0 1px 0 rgba(255,255,255,.22),0 20px 46px rgba(142,22,30,.36)}
body:has(.hero) .btn--ghost{background:var(--panel);color:var(--ink);
  box-shadow:inset 0 0 0 1.5px var(--line-2),0 1px 2px rgba(42,26,23,.06)}
body:has(.hero) .btn--ghost:hover{background:var(--paper-2);
  box-shadow:inset 0 0 0 1.5px var(--rose),0 10px 24px rgba(93,27,33,.13)}

/* ---- the pricing row.
   overflow is opened so the tab can sit above the card edge; the head band
   takes the radius the card used to clip for it (16px of card less its 2px
   border). Nothing here touches the flex column, the image box or the
   margin-top:auto that share the button baseline. */
body:has(.hero) .card--pack{border-radius:var(--ghp-card);overflow:visible;
  box-shadow:var(--ghp-ring),var(--ghp-amb);
  transition:box-shadow .24s ease,transform .24s var(--ghp-ease)}
body:has(.hero) .card--pack .pack__head{border-radius:14px 14px 0 0}
body:has(.hero) .card--pack:hover{transform:translateY(-2px);
  box-shadow:var(--ghp-ring),var(--ghp-amb-x)}

/* The recommended tier: raised above (in the critical block), ringed in the
   label's red, and carrying the deep stop while its neighbours carry the
   shallow one. */
body:has(.hero) .card--pack.featured{border-color:var(--red);
  box-shadow:inset 0 0 0 1px rgba(180,31,40,.30),var(--ghp-amb-d)}
body:has(.hero) .card--pack.featured:hover{
  box-shadow:inset 0 0 0 1px rgba(180,31,40,.30),var(--ghp-amb-x)}

/* The ribbon is a tab above the card, centred on its top edge, red on the
   recommended tier and wine on the other, so the row says which one it means
   twice over. Position and paint only -- the padding it had is untouched. */
body:has(.hero) .pack__flag{left:50%;right:auto;top:-14px;
  transform:translateX(-50%);border-radius:999px;
  background-image:linear-gradient(150deg,#7c2a30,var(--deep-2));
  box-shadow:0 8px 20px rgba(93,27,33,.30)}
body:has(.hero) .card--pack.featured .pack__flag{
  background-image:linear-gradient(150deg,#d43a42,var(--red-d));
  box-shadow:0 8px 22px rgba(142,22,30,.40)}

/* Dashed separators between the feature rows, drawn as a repeating
   background on the bottom edge. A border would add a pixel to every row and
   grow all three cards, and growing a pricing card is how a shared button
   baseline gets lost. */
body:has(.hero) .pack__perks li:not(:last-child){
  background-image:linear-gradient(90deg,rgba(93,27,33,.26) 52%,transparent 0);
  background-size:7px 1px;background-repeat:repeat-x;background-position:0 100%}

/* ---- hero motif: RISE.
   Warmth rising from the base of the bottle, drifting up and fading out.

   On the pseudo-elements of the media column, never on the <img>. Both are
   sized well OUTSIDE the plate -- the plate is 391px wide at 1440 and these
   run 540px and 500px -- because a shape sized inside it is covered by an
   opaque product shot and renders as nothing at all, which is what the
   motif it replaces was doing.

   They bleed 52% to the LEFT and only 8% to the right on purpose. The media
   column is position:sticky, so it is a positioned box and it paints ABOVE
   the static copy column beside it -- tested at right:-60%, where the wash
   came down over the roadmap paragraph and tinted live body text. At -8% it
   stops 7px short of the copy column's left edge.

   The core of each shape sits just BELOW the plate rather than behind its
   middle. At 1440 the plate is 391px of a 397px column and the product shot
   inside it is opaque, so a core behind the middle is covered and the whole
   thing renders as nothing -- which is what the motif it replaces was doing.
   The free canvas is the 159px left of the plate, the 141px under it and the
   140px above it, and that is where these are aimed. Checked against the same
   crop with the motif switched off, so the difference is a difference a
   reader can actually see.

   Slow: 30s and 38s. This is a gummy taken once a day for weeks, not an
   energy drink. transform and opacity only -- no blur filter, no animated
   geometry, nothing on the <img> -- and no new network request. Both
   keyframe names are new to this sheet, which already holds ghpCrest and
   ghpSettle. */
body:has(.hero) .hero__media::before,
body:has(.hero) .hero__media::after{content:'';position:absolute;z-index:1;
  pointer-events:none;left:-52%;right:-8%}

/* the hearth: the pool of warmth the rise comes out of, centred a little
   under the base of the bottle */
body:has(.hero) .hero__media::before{top:calc(50% + 150px);height:300px;
  transform-origin:46% 39%;
  background:radial-gradient(54% 52% at 46% 39%,rgba(142,22,30,.56),
    rgba(180,31,40,.28) 46%,rgba(201,130,122,0) 76%);
  animation:ghpHearth 30s ease-in-out infinite}

/* the plume: it leaves the base, drifts up past the top of the plate, fades */
body:has(.hero) .hero__media::after{top:calc(50% - 300px);height:580px;
  background:
    radial-gradient(34% 40% at 38% 92%,rgba(142,22,30,.40),rgba(142,22,30,0) 72%),
    radial-gradient(26% 42% at 62% 98%,rgba(180,31,40,.30),rgba(180,31,40,0) 72%),
    linear-gradient(0deg,rgba(142,22,30,.28),rgba(201,130,122,.13) 42%,
      rgba(201,130,122,0) 74%);
  animation:ghpRise 38s linear infinite}

@keyframes ghpHearth{
  0%,100%{transform:scale(.94);opacity:.60}
  50%{transform:scale(1.07);opacity:.95}
}
@keyframes ghpRise{
  0%{transform:translate3d(0,11%,0) scale(1);opacity:0}
  20%{opacity:.85}
  64%{opacity:.46}
  100%{transform:translate3d(0,-15%,0) scale(1.07);opacity:0}
}

/* Under 981px the media column is no longer the sticky full-height box it is
   on a wide screen -- it is the plate and nothing else -- so the two shapes
   are anchored to its own edges instead of to its centre. */
@media (max-width:980px){
  body:has(.hero) .hero__media::before,
  body:has(.hero) .hero__media::after{left:-22%;right:-22%}
  body:has(.hero) .hero__media::before{top:auto;bottom:-26%;height:64%}
  body:has(.hero) .hero__media::after{top:-10%;height:122%}
}

/* ---- ask for less motion, get none of it. */
@media (prefers-reduced-motion:reduce){
  body:has(.hero) .hero__media::before,
  body:has(.hero) .hero__media::after{animation:none;opacity:.42}
  body:has(.hero) .btn{transition:none}
  body:has(.hero) .btn:hover,
  body:has(.hero) .card--pack:hover{transform:none}
  body:has(.hero) .card--pack{transition:none}
}
/*!SITE-HOME-PAINT-END*/
/* ==== modern surface (modern_surface.py) ==== */
/* House rule 11. This stylesheet had 18 box-shadow declaration(s)
   and 2 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 (42,26,23), 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(42,26,23,.06), 0 6px 18px rgba(42,26,23,.07);
  --lift:0 2px 6px rgba(42,26,23,.09), 0 16px 34px rgba(42,26,23,.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. */
.keypoints,
.alert,
.byline,
.ingcard,
.final,
.split__img,
.answer{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,
.card--pack,
.badgewall figure{transition:box-shadow .2s ease, transform .2s ease}
.rel a:hover,
.posts article:hover,
.shots figure:hover,
.card--pack: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,
.card--pack:hover,
.badgewall figure:hover{transform:none}
}
/* ==== end modern surface ==== */

/* ==== 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 .fband__note{font-size:16px}
footer .fcols h3{font-size:15px}
footer .fcols li span{font-size:16px}
footer .fpay span{font-size:16px}
/* ==== end footer type floor ==== */
