/* sodatides.com — SodaTide, the official U.S. shop desk.

   Design slot: batch11_assignments.py row 282. All six levers are assigned and
   all six are built here:

     Type    Rozha One over Rambla. A high-contrast editorial display face
             above a humanist text face -- headline register, not UI register.
     Layout  hero copy LEFT, product RIGHT; sections run full width and the
             reading column is centred inside them.
     Cards   hairline border, SQUARE corners, no fill. The ground shows through.
     Depth   none. No box-shadow and no drop-shadow anywhere on the site.
             Separation comes from a rule and a change of ground.
     Ground  ice blue page, sand panels.
     Motion  hero motif `scale-tip` (hero_motifs.py) plus the house reveal.

   Colour still comes from the bottle, as the skill requires: the SodaTide
   label is a black bottle with a white face, a violet band and a magenta
   particle wave across the middle. Violet is the ink, magenta is the accent.
   The ice-and-sand ground is the slot's, the two purples are the label's.

   The header is one bar split by a drawn diagonal, with the links riding the
   lower half. The footer prints its destinations as a continuous sentence
   broken by middots rather than as a column grid.

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

/* ---- tokens */
:root{
  --paper:#e3eef4;          /* ice blue: the page */
  --panel:#ffffff;
  --sand:#f4ead8;           /* sand: panels and bands */
  --sand-d:#e7d7b9;
  --ice-d:#cddfe9;
  --ink:#171c22;
  --ink-2:#414b57;
  --ink-3:#616e7c;
  --violet:#6b2088;         /* the label's band */
  --violet-d:#4d1364;
  --violet-2:#8a34a8;
  --mag:#b8368f;            /* the label's particle wave */
  --mag-d:#8e2470;
  --good:#146b47;
  --warn:#8a5510;
  --line:#b9cedb;           /* the hairline, on ice */
  --line-2:#93aec0;
  --line-sand:#d9c8a8;      /* the hairline, on sand */
  --wrap:1180px;
  --measure:742px;
  --measure-wide:960px;
  --radius:0px;             /* square corners, every component */
  --radius-lg:0px;
  --navh:112px;
  --display:"Rozha One",Georgia,"Times New Roman",serif;
  --text:"Rambla",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;background:var(--paper);color:var(--ink);
  font-family:var(--text);font-size:17px;line-height:1.76;font-weight:400;
  -webkit-font-smoothing:antialiased;
}
img{max-width:100%;height:auto;display:block}
a{color:var(--violet);text-underline-offset:3px}
a:hover{color:var(--mag-d)}
h1,h2,h3,h4{font-family:var(--display);color:var(--violet-d);font-weight:400;line-height:1.14;margin:0 0 .5em}
h1{font-size:clamp(2.1rem,1.34rem + 2.4vw,3.3rem);letter-spacing:0}
h2{font-size:clamp(1.62rem,1.24rem + 1.4vw,2.35rem)}
h3{font-size:1.32rem}
h4{font-size:1.12rem}
p,li{font-size:1.0625rem}
p{margin:0 0 1.05em}
.wrap{width:100%;max-width:var(--wrap);margin-inline:auto;padding-inline:22px}
.skip{position:absolute;left:-9999px;top:0;background:var(--violet-d);color:#fff;padding:12px 18px;z-index:200}
.skip:focus{left:8px;top:8px}
:focus-visible{outline:3px solid var(--mag);outline-offset:2px}

/* the eyebrow names the JOB of the section beneath it. Rambla, not Rozha:
   a Didone at 13px in caps with .16em tracking is a smear. */
.eyebrow{
  display:inline-flex;align-items:center;gap:10px;
  font-family:var(--text);font-size:0.9375rem;font-weight:700;
  letter-spacing:.14em;text-transform:uppercase;color:var(--mag-d);
  margin:0 0 12px;
}
.eyebrow::before{content:"";width:22px;height:2px;background:var(--mag)}

/* ---- buttons: square, no shadow, a 2px rule doing the work a shadow would */
.btn{
  display:inline-flex;align-items:center;justify-content:center;gap:9px;
  min-height:54px;padding:15px 32px;
  font-family:var(--text);font-size:1rem;font-weight:700;letter-spacing:.02em;
  border:2px solid var(--violet-d);border-radius:var(--radius);cursor:pointer;
  text-decoration:none;background:var(--violet-d);color:#fff;
  transition:background .18s ease,border-color .18s ease,color .18s ease;
}
.btn:hover{background:var(--violet);border-color:var(--violet);color:#fff}
.btn--cyan{background:var(--mag-d);border-color:var(--mag-d)}
.btn--cyan:hover{background:var(--violet-d);border-color:var(--violet-d)}
.btn--lg{min-height:62px;padding:17px 38px;font-size:1.08rem}
.btn--ghost{background:none;color:var(--violet-d);border-color:var(--violet-d)}
.btn--ghost:hover{background:var(--violet-d);color:#fff}
.btn--wide{width:100%}

/* ---- header: one bar split by a drawn diagonal, links on the lower half.
   The top half is the label's violet and carries the identity and the order
   rail; the lower half is sand and carries the menu. The boundary is cut on a
   slant and a magenta rule is drawn along the cut. */
.nav{position:sticky;top:0;z-index:100;background:var(--violet-d)}
/* padding-BLOCK, never the shorthand: this element also carries .wrap and
   `padding:14px 0` would set padding-inline to 0 and wipe the page gutter
   (pitfall 46). */
.nav__top{display:flex;align-items:center;gap:20px;padding-block:14px 26px}
.brand{display:flex;align-items:center;gap:13px;text-decoration:none;color:#fff}
.brand__glyph{width:38px;height:38px;flex:0 0 auto}
/* Size the mark by ELEMENT as well as by class: brand_marks.py rewrites the
   <svg> inside .brand and does not carry the class onto the replacement, so a
   class-only rule stops applying the moment that tool runs (pitfall 16). */
.brand>svg{width:38px;height:38px;flex:0 0 auto}
.bw{display:flex;flex-direction:column;line-height:1.05}
.bw b{font-family:var(--display);font-size:1.62rem;font-weight:400;letter-spacing:.005em;color:#fff}
.bw b em{font-style:normal;color:#eab6dd}
.bw small{font-family:var(--text);font-size:0.9062rem;font-weight:400;color:#d6bfe4}
.nav__rail{margin-left:auto;display:flex;align-items:center;gap:18px}
.nav__price{text-align:right;line-height:1.25}
.nav__price b{display:block;font-family:var(--display);font-size:1.3rem;font-weight:400;color:#fff}
.nav__price span{font-size:.8125rem;color:#d6bfe4}
.nav__buy{min-height:46px;padding:11px 20px;font-size:.95rem;background:var(--mag);border-color:var(--mag)}
.nav__buy:hover{background:#fff;border-color:#fff;color:var(--violet-d)}
.burger{
  display:none;width:48px;height:46px;background:transparent;border:2px solid #a678bd;
  border-radius:var(--radius);cursor:pointer;padding:12px 11px;
}
.burger span{display:block;height:2px;background:#fff;margin:0 0 5px}
.burger span:last-child{margin:0}
/* the lower half: sand, cut on a slant, with the diagonal drawn along the cut */
.nav__strip{position:relative;background:var(--sand);
  clip-path:polygon(0 24px,100% 0,100% 100%,0 100%)}
.nav__strip::before{content:"";position:absolute;inset:0;background:var(--mag);
  clip-path:polygon(0 24px,100% 0,100% 3px,0 27px)}
.menu{
  position:relative;display:flex;flex-wrap:wrap;gap:0 26px;list-style:none;
  margin:0;padding:22px 0 0;align-items:center;min-height:56px;
}
.menu a{
  display:inline-block;padding:9px 0;font-family:var(--text);
  font-size:.9688rem;font-weight:700;color:var(--ink-2);text-decoration:none;
  border-bottom:3px solid transparent;
}
.menu a:hover{color:var(--violet-d)}
.menu a[aria-current="page"]{color:var(--violet-d);border-bottom-color:var(--mag)}
.menu__more{display:none}

/* ---- hero: copy LEFT, product RIGHT on a white plate with a hairline frame */
.hero{position:relative;background:var(--paper);padding:52px 0 58px;overflow-x:clip}
.hero__grid{position:relative;z-index:1;display:grid;
  grid-template-columns:minmax(0,1.08fr) minmax(0,.92fr);gap:46px;align-items:center}
.hero__copy{display:flex;flex-direction:column;min-width:0}
.hero h1{margin:0 0 18px}
.hero h1 em{font-style:normal;color:var(--mag-d)}
.answer{
  background:var(--sand);border:1px solid var(--line-sand);
  border-left:5px solid var(--mag);border-radius:var(--radius);
  padding:20px 24px;margin:0 0 18px;
}
.answer p{margin:0 0 .75em;font-size:1.062rem}
.answer p:last-child{margin:0}
.hero__road{font-size:1rem;color:var(--ink-2);margin:0 0 20px;max-width:56ch}
.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:700}
.factpills{display:flex;flex-wrap:wrap;gap:8px;list-style:none;margin:0 0 18px;padding:0}
.factpills li{
  font-size:0.9062rem;color:var(--ink-2);background:none;
  border:1px solid var(--line);padding:7px 14px;border-radius:var(--radius);
}
.factpills li b{font-family:var(--display);font-weight:400;color:var(--violet-d);font-size:1.06rem}
.figures{display:grid;grid-template-columns:repeat(3,1fr);gap:0;margin:0;
  border:1px solid var(--line)}
.figures div{background:none;padding:14px 16px;border-right:1px solid var(--line)}
.figures div:last-child{border-right:0}
.figures b{display:block;font-family:var(--display);font-size:1.7rem;font-weight:400;color:var(--violet-d);line-height:1.08}
.figures span{display:block;font-size:0.9062rem;color:var(--ink-3);margin-top:3px}
.hero__media{position:relative;align-self:center}
/* The plate is capped NARROWER than the media column on purpose. `.hero__card`
   is opaque, so anything the hero motif draws behind it is invisible for the
   full width of the card; filling the column left only the 46px gutter for the
   motif to show in, and measured at 1440 the scale-tip beam's left pan landed
   on the edge of the Quick Answer box instead. Capping the plate at 432px
   leaves ~40px of column on each side plus the motif's own overhang, so the
   beam reads as passing BEHIND the bottle and its two pans hang clear of the
   copy at every width from 981 up. */
.hero__card{position:relative;z-index:2;text-align:center;padding:22px 18px 16px;
  max-width:432px;margin-inline:auto;
  background:var(--panel);border:1px solid var(--line)}
.hero__card img{width:100%;max-width:380px;height:auto;margin-inline:auto}
.hero__cap{margin:14px 0 0;font-size:.875rem;color:var(--ink-3);text-align:center}
.trust__row{display:flex;flex-wrap:wrap;gap:10px 22px;margin:0;padding:0;list-style:none;font-size:0.9062rem;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:700}

/* ---- inner page head */
.phead{padding:32px 0 14px;background:var(--panel);border-bottom:1px solid var(--line)}
.crumbs{font-size:0.9062rem;color:var(--ink-3);margin:0 0 14px}
.crumbs a{color:var(--ink-2);text-decoration:none}
.crumbs a:hover{color:var(--mag-d)}
.phead h1{margin:0 0 16px;max-width:var(--measure-wide)}
.phead .answer{max-width:var(--measure-wide)}
.lead{font-size:1.14rem;color:var(--ink-2);max-width:var(--measure)}

/* ---- topline strip: the five facts a buyer wants before reading anything,
   above the navigation, so the menu does not have to carry them. Above
   CRITICAL-END because it is the first thing painted. */
.util{background:var(--ink);color:#c2cbd4;font-size:.875rem;line-height:1.5}
.util__row{display:flex;flex-wrap:wrap;align-items:center;gap:4px 18px;padding-block:9px}
.util__item{display:inline-flex;align-items:center;gap:7px;white-space:nowrap}
.util__item+.util__item::before{content:"";width:8px;height:1px;
  background:#5d6a77;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:760px){
  /* Five items wrap to three lines on a phone. Keep the role, the guarantee
     and the order line; the lot and the dose are on the pages that need them. */
  .util__item--trim{display:none}
  .util__row{gap:4px 14px}
}

/* --- hero responsive rules, copied into the critical block by
   critical_hero.py. A phone otherwise paints the DESKTOP hero from the inline
   block and relays when the async sheet lands. These are COPIES: the
   originals stay below, so the cascade is unchanged. */
@media (max-width:980px){
  .hero__grid{grid-template-columns:1fr;gap:26px}
  .hero__copy{display:contents}
  .hero .eyebrow{order:1}
  .hero h1{order:2}
  .hero__media{order:3;margin:6px 0 20px}
  .hero__road{order:5}
  .hero__cta{order:6}
  .hero__sub{order:8}
}
@media (max-width:760px){
  .hero{padding:34px 0 42px}
}


/* ---- hero motif -- scale-tip ---------------------------------------- */
.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(168deg,#e0e3ee 0%,#d9c2dc 48%,#e3eef4 100%)}.hero__media::before{content:'';position:absolute;left:50%;top:50%;width:118%;height:168px;translate:-50% -50%;background:radial-gradient(circle 22px at 4% 50%,rgba(184,54,143,0.44) 0 44%,transparent 70%) 0 0/100% 100% no-repeat,radial-gradient(circle 22px at 96% 50%,rgba(120,35,93,0.40) 0 44%,transparent 70%) 0 0/100% 100% no-repeat,linear-gradient(90deg,transparent 0,rgba(184,54,143,0.58) 6%,rgba(184,54,143,0.58) 94%,transparent 100%) 0 50%/100% 3px no-repeat;animation:stTip 11s ease-in-out infinite;z-index:0;pointer-events:none}.hero__media::after{content:'';position:absolute;left:50%;top:50%;width:124%;aspect-ratio:1;translate:-50% -50%;border-radius:50%;background:radial-gradient(closest-side,rgba(184,54,143,0.34),rgba(184,54,143,0.15) 46%,transparent 74%);filter:blur(20px);animation:stSwell 11s ease-in-out infinite;z-index:0;pointer-events:none}@keyframes stTip{0%,100%{transform:rotate(-5deg)}50%{transform:rotate(5deg)}}@keyframes stSwell{0%,100%{transform:scale(.86);opacity:.30}52%{transform:scale(1.04);opacity:.70}}
@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 */
/* The header is sticky, so an in-page anchor lands UNDER it: caught in a
   screenshot of ingredients.html#label-analysis, where the H2 sat behind the
   menu strip. Every blog post's table of contents is in-page links, so this
   is not a corner case. --navh is measured and published by site.js; the
   fallback matches the token's own value for a page where JS has not run. */
:where([id]){scroll-margin-top:calc(var(--navh,104px) + 18px)}
.sec{padding:62px 0;position:relative;border-top:1px solid var(--line)}
.sec--tint{background:var(--sand);border-top-color:var(--line-sand)}
.sec--panel{background:var(--panel)}
.sec--dark{background:var(--violet-d);color:#e6d9ee;border-top-color:var(--violet-d)}
.sec--dark h2,.sec--dark h3{color:#fff}
.sec--dark p,.sec--dark li{color:#e0d0ea}
.sec--dark .eyebrow{color:#f0bfe0}
.sec--dark .eyebrow::before{background:#f0bfe0}
.sec--dark a{color:#f4cde8}
.sec--center{text-align:center}
.sec--center .sec__head{margin-inline:auto}
.sec--wedge{background:var(--panel)}
.sec__head{max-width:var(--measure);margin:0 0 28px}
.sec__head h2{margin:0 0 10px}
.sec__head p{color:var(--ink-2);margin:0}
.sec--dark .sec__head p{color:#e0d0ea}

/* one measure, centred inside a full-width band; multi-column components keep
   the full wrap. This is the slot's layout lever: no two-column page body. */
@media (min-width:1040px){
  .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:700}
.sec--dark .ticks li::before{color:#8fe0bb}

/* ---- tables */
.tablewrap{overflow-x:auto;margin:0 0 1.2em;border:1px solid var(--line);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(--text);font-weight:700;color:#fff;background:var(--violet-d);font-size:.9688rem}
tbody tr:nth-child(even){background:#f7fafc}
tbody tr:last-child td{border-bottom:0}
td b{color:var(--violet-d)}
.tnote{font-size:.9688rem;color:var(--ink-3);margin:-.4em 0 1.2em}

/* ---- numbered steps */
.steps{display:grid;gap:0;margin:0 0 1.2em;counter-reset:s;border:1px solid var(--line)}
.step{position:relative;background:none;border-bottom:1px solid var(--line);padding:22px 24px 22px 74px}
.step:last-child{border-bottom:0}
.step::before{
  counter-increment:s;content:counter(s);
  position:absolute;left:22px;top:20px;width:38px;height:38px;
  display:grid;place-items:center;
  background:var(--violet-d);color:#fff;
  font-family:var(--display);font-weight:400;font-size:1.2rem;
}
.step h3{margin:0 0 6px}
.step p:last-child{margin:0}

/* ---- cards: hairline border, square corners, NO FILL. The ground shows
   through, which is the whole of this site's separation language. */
.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))}
.card{position:relative;background:none;border:1px solid var(--line);
  border-radius:var(--radius);padding:24px 22px 22px}
.card h3{margin:0 0 8px}
.card p:last-child,.card ul:last-child{margin-bottom:0}
.sec--tint .card{border-color:var(--line-sand)}
.sec--dark .card{background:none;border-color:#7e4d97}

/* ---- callout, alert, quote, keypoints */
.callout{background:var(--panel);border:1px solid var(--line);padding:20px 22px;margin:0 0 1.2em}
.callout b:first-child{display:block;margin-bottom:6px;color:var(--violet-d)}
.callout p:last-child{margin:0}
.alert{background:#fbf3e4;border:1px solid #e6d3ad;border-left:5px solid var(--warn);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.5rem;font-weight:400;line-height:1.36;color:var(--violet-d);border-left:5px solid var(--mag);padding:6px 0 6px 24px;margin:0 0 1.2em}
.pullquote cite{display:block;font-family:var(--text);font-size:.9688rem;font-style:normal;color:var(--ink-3);margin-top:10px}
.keypoints{background:none;border:1px solid var(--line);border-top:4px solid var(--violet-d);padding:20px 22px;margin:0 0 1.2em}
.keypoints>b{display:block;margin-bottom:8px;color:var(--violet-d)}
.keypoints ul{margin:0;padding-left:20px}

/* ---- 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--flip .split__img{order:2}
/* A grid item's default min-width is auto, which floors at MIN-CONTENT, so a
   .tablewrap holding a 520px-min table keeps its column 520px wide however
   narrow the grid gets. min-width:0 is the fix and it belongs at every
   width, not only in the media query. */
.split__img,.split__body{min-width:0}
.split__img img{width:100%;border:1px solid var(--line);background:var(--panel)}
.split__body p:last-child{margin:0}

/* ---- stat band */
.stats{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:0;text-align:center}
.stats div{padding:6px 12px;border-right:1px solid #7e4d97}
.stats div:last-child{border-right:0}
.stats div b{display:block;font-family:var(--display);font-size:2.5rem;font-weight:400;color:#fff;line-height:1.06}
.stats div span{display:block;font-size:.9688rem;color:#e0d0ea;margin-top:4px}

/* ---- label versus research */
.versus{display:grid;grid-template-columns:1.05fr 1fr 1.1fr;border:1px solid var(--line);background:var(--panel);margin:0 0 1.2em}
.versus>div{padding:13px 16px;border-bottom:1px solid var(--line);font-size:.98rem}
.versus>div:nth-child(3n+1){font-weight:700;background:#f7fafc}
.versus__h{background:var(--violet-d)!important;color:#fff;font-family:var(--text);font-weight:700;font-size:.9375rem}

/* ---- ingredient cards */
.inglist{display:grid;gap:16px}
/* Same family as the .split fix. .ingcard is a grid item and a grid item's
   default min-width is auto, so a nowrap dose chip sets the column's floor. */
.inglist>*{min-width:0}
.ingcard{background:none;border:1px solid var(--line);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:.9688rem;font-style:italic;color:var(--ink-3)}
.ing__dose{margin-left:auto;font-size:.9375rem;font-weight:700;color:#fff;background:var(--violet-d);padding:4px 12px;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}
.card--pack{display:flex;flex-direction:column;background:var(--panel);
  border:1px solid var(--line);border-radius:var(--radius);position:relative}
/* The featured pack is marked by a 3px violet frame and a filled head band,
   never by a lift: a `margin-top:-12px` makes that card taller than its
   siblings and breaks the one-height, one-baseline rule in responsive.md. */
.card--pack.featured{border:3px solid var(--violet-d)}
.pack__head{background:var(--sand);border-bottom:1px solid var(--line-sand);padding:14px 20px;display:flex;align-items:center;gap:10px}
.card--pack.featured .pack__head{background:var(--violet-d);border-bottom-color:var(--violet-d)}
.card--pack.featured .pack__head b,.card--pack.featured .pack__head span{color:#fff}
.pack__head b{font-family:var(--display);font-size:1.3rem;font-weight:400}
.pack__head span{font-size:.8438rem;font-weight:700;color:var(--ink-3);margin-left:auto}
.pack__flag{position:absolute;right:0;top:0;background:var(--mag-d);color:#fff;font-family:var(--text);font-size:0.8438rem;font-weight:700;letter-spacing:.08em;text-transform:uppercase;padding:5px 13px;z-index:3}
.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.8rem;font-weight:400;color:var(--violet-d);line-height:1;text-align:center}
.pack__per sup{font-size:1.1rem;top:-.8em}
.pack__unit{display:block;text-align:center;font-size:.9062rem;font-weight:700;color:var(--ink-3);margin:6px 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:700}
.pack__was{color:var(--ink-3);text-decoration:line-through}
.pack__perks{list-style:none;margin:0 0 18px;padding:0;font-size:.9688rem}
.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:700}
.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:.8438rem;color:var(--ink-3)}
.buy__note{font-size:.9688rem;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 figure{margin:0;background:var(--panel);border:1px solid var(--line)}
.shots img{width:100%}
.shots figcaption{padding:16px 18px;border-top:1px solid var(--line)}
.shots figcaption b{display:block;margin-bottom:5px;color:var(--violet-d)}
.shots figcaption span{font-size:.9688rem;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 figure{margin:0;text-align:center;background:var(--panel);border:1px solid var(--line);padding:18px 16px}
.badgewall img{width:74px;height:74px;object-fit:contain;margin:0 auto 10px}
.badgewall b{display:block;font-size:1rem;margin-bottom:4px;color:var(--violet-d)}
.badgewall span{font-size:.9062rem;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:.9688rem}
.meter__bar{height:12px;background:none;border:1px solid var(--line-2);overflow:hidden}
.meter__bar i{display:block;height:100%;background:var(--violet)}
.stars{color:#c07a12;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);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:400;font-size:1.22rem;color:var(--violet-d)}
.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(--mag-d)}
.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 list prints each source's full URL as the link text and a URL is one
   unbreakable token. `anywhere` also lowers the element's MIN-CONTENT, which
   is what stops the ancestor being sized by the longest URL in the list. */
.refs li,.refs li a{overflow-wrap:anywhere}
.byline{display:flex;gap:18px;background:var(--panel);border:1px solid var(--line);border-left:5px solid var(--violet-d);padding:22px 24px;margin:0 0 1.2em}
.byline__mark{flex:0 0 auto;width:56px;height:56px;display:grid;place-items:center;background:var(--violet-d);color:#fff;font-family:var(--display);font-weight:400;font-size:1.3rem}
.byline b{display:block;margin-bottom:6px;color:var(--violet-d)}
.byline p{font-size:.9688rem;color:var(--ink-2);margin:0}

/* ---- closing CTA */
.final{background:var(--panel);border:1px solid var(--line);border-top:4px solid var(--violet-d);padding:30px 32px}
.final--media{display:grid;grid-template-columns:auto minmax(0,1fr);gap:30px;align-items:center}
.final__img img{width:200px}
.final h2{margin:0 0 10px}
.final__price{font-weight:700;color:var(--ink-2)}
.final__sm{font-size:.9688rem;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 a{display:block;background:var(--panel);border:1px solid var(--line);padding:20px 22px;text-decoration:none;color:var(--ink);transition:border-color .18s ease}
.rel a:hover{border-color:var(--mag)}
.rel b{display:block;font-family:var(--display);font-size:1.26rem;font-weight:400;color:var(--violet-d);margin-bottom:5px}
.rel span{font-size:.9688rem;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:700;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:.9688rem;color:var(--ink-3);margin:0 0 20px}
.toc{background:var(--panel);border:1px solid var(--line);padding:20px 24px;margin:0 0 28px}
.toc b{display:block;margin-bottom:8px;color:var(--violet-d)}
.toc ol{margin:0;padding-left:20px}
.toc li{margin:0 0 5px;font-size:1.062rem}
.posts{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:20px}
.posts article{background:var(--panel);border:1px solid var(--line);padding:22px 24px}
.posts h3{margin:0 0 8px}
.posts p{font-size:1.062rem;color:var(--ink-2)}
.dtable{min-width:520px}

/* ---- footer: a sand guarantee band, then the destinations printed as one
   continuous sentence broken by middots rather than as a column grid. */
.fcta{position:relative;background:var(--sand);color:var(--ink);padding:52px 0;border-top:3px solid var(--violet-d)}
.fcta h2,.fcta__h{color:var(--violet-d)}
.fcta__box{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:34px;align-items:center}
.fcta__eye{display:inline-block;font-family:var(--text);font-size:.9375rem;font-weight:700;letter-spacing:.14em;text-transform:uppercase;color:var(--mag-d);margin-bottom:10px}
.fcta__h{font-family:var(--display);font-size:1.95rem;font-weight:400;line-height:1.2;margin:0 0 10px}
.fcta p{color:var(--ink-2)}
.fcta__sm{font-size:.9688rem;color:var(--ink-3);margin:12px 0 0}
.fcta__img img{width:260px}
footer{background:var(--panel);border-top:1px solid var(--line)}
.fmast{display:grid;grid-template-columns:minmax(0,1.1fr) minmax(0,1fr);gap:34px;padding:44px 0 26px}
.fbrand{font-family:var(--display);font-size:2.1rem;font-weight:400;color:var(--violet-d);line-height:1}
.fbrand span{color:var(--mag-d)}
.frole{font-size:1rem;color:var(--ink-2);margin:10px 0 14px}
.fcard p{font-size:1.062rem;color:var(--ink-2);margin:0 0 .7em}
.fcard b{color:var(--violet-d)}
/* the continuous sentence: each run is a group label followed by its
   destinations, all of it reading as one line of running text */
.findex{border-top:1px solid var(--line);border-bottom:1px solid var(--line);padding:24px 0}
.findex p{margin:0 0 .9em;font-size:1.0625rem;color:var(--ink-2);line-height:2.1}
.findex p:last-child{margin:0}
.fh{display:inline;font-family:var(--text);font-size:.9375rem;font-weight:700;letter-spacing:.12em;text-transform:uppercase;color:var(--mag-d);margin:0 12px 0 0}
/* inline-block with padding given straight back, so the tap target is ~33px
   in a 35px row and nothing moves (pitfall 82). */
footer .findex a{display:inline-block;padding-block:6px;margin-block:-6px;color:var(--ink-2);text-decoration:none;border-bottom:1px solid var(--line)}
footer .findex a:hover{color:var(--violet-d);border-bottom-color:var(--mag)}
.fdot{color:var(--line-2);margin:0 7px}
.fseals{display:flex;flex-wrap:wrap;align-items:center;gap:14px;padding:22px 0}
.fseals img{width:44px;height:44px;object-fit:contain}
.fseals span{font-size:.9688rem;color:var(--ink-3)}
.fpay{display:flex;flex-wrap:wrap;align-items:center;gap:16px;padding:0 0 26px;border-top:1px solid var(--line);margin-top:0}
.fpay img{width:230px;height:auto}
.fpay span{font-size:.9688rem;color:var(--ink-3)}
.disc{background:var(--sand);border-top:1px solid var(--line-sand);padding:28px 0 32px}
.disc p,.disc li{font-size:.9688rem;color:var(--ink-2)}
.disc b{color:var(--violet-d)}
.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:.72em;width:8px;height:2px;background:var(--mag)}
.copy{margin:18px 0 0;padding-top:16px;border-top:1px solid var(--line-sand);font-size:.9688rem}

/* ---- sticky buy bar. Declared at the TOP LEVEL and never display:none:
   house rule 8 needs a bottom CTA that exists on desktop too. */
.buybar{position:fixed;left:0;right:0;bottom:0;z-index:90;display:block;
  background:var(--violet-d);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 22px}
.buybar__t{font-size:.9688rem;min-width:0}
.buybar__t b{display:block;font-size:1.02rem}
.buybar__t span{color:#dcc5e8}
.buybar .btn{margin-left:auto;flex:0 0 auto;background:var(--mag);border-color:var(--mag)}
.buybar .btn:hover{background:#fff;border-color:#fff;color:var(--violet-d)}

/* ---- 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:1100px){
  .fmast{grid-template-columns:1fr;gap:22px}
}
@media (max-width:980px){
  :root{--navh:104px}
  .hero__grid{grid-template-columns:1fr;gap:26px}
  .hero__copy{display:contents}
  .hero .eyebrow{order:1}
  .hero h1{order:2}
  .hero__media{order:3;margin:6px 0 20px}
  .answer{order:4}
  .hero__road{order:5}
  .hero__cta{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:26px 0 12px}
  .menu.open{display:flex}
  .menu__more{display:block}
  .menu a{padding:12px 0;border-bottom:1px solid var(--line-sand)}
  .menu a[aria-current="page"]{border-bottom-color:var(--mag)}
  .burger{display:block}
  .nav__buy{display:none}
  .grid.g4{grid-template-columns:repeat(2,minmax(0,1fr))}
  .stats{grid-template-columns:repeat(2,minmax(0,1fr))}
  .stats div:nth-child(2){border-right:0}
  .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:46px 0}
  .hero{padding:34px 0 42px}
  .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 nowrap and margin-left:auto, so on a narrow card it is
     pushed onto a line with no room for it and overhangs the edge. */
  .ing__dose{margin-left:0;white-space:normal}
  .disc__list{columns:1}
  .figures{grid-template-columns:1fr}
  .figures div{border-right:0;border-bottom:1px solid var(--line)}
  .figures div:last-child{border-bottom:0}
  .buybar__in{flex-wrap:wrap;gap:10px;padding-block:10px}
  .buybar .btn{width:100%;margin-left:0}
  /* The menu is hidden behind the burger below 980, so the strip has nothing
     in it and collapses to zero height -- which takes the drawn diagonal, the
     one thing that makes this header this header, off every phone. A min-height
     keeps the sand wedge and its magenta rule on screen with the menu closed. */
  .nav__strip{clip-path:polygon(0 16px,100% 0,100% 100%,0 100%);min-height:26px}
  .nav__strip::before{clip-path:polygon(0 16px,100% 0,100% 3px,0 19px)}
  .nav__top{padding-block:12px 20px}
}
@media (max-width:440px){
  .badgewall{grid-template-columns:1fr}
  .meter__row{grid-template-columns:64px 1fr 42px;gap:8px}
}

/* ---- hero: sticky, centred product column ------------------------------
   The product plate holds its place, vertically centred, until the hero has
   fully scrolled past. --navh is measured and published by site.js rather
   than hardcoded: this header is two rows and its height changes between
   breakpoints.

   Requires .hero NOT to clip on the block axis. ANY non-visible overflow on
   an ancestor becomes the scrollport sticky resolves against, `clip`
   included (pitfall 65). */
@media (min-width: 981px) {
  .hero__grid { align-items: start; }
  .hero__media {
    position: sticky;
    top: calc(var(--navh, 104px) + 14px);
    align-self: start;
    min-height: calc(100vh - var(--navh, 104px) - 28px);
    min-height: calc(100svh - var(--navh, 104px) - 28px);
    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 ----------------------------
   Three cards that share their edges, their image slot and their button
   baseline. The vendor pack shots are three different shapes, so without
   these the images render at three sizes and the CTAs sit at three heights.
   The height lives here rather than on the <img> attributes because those
   must keep stating each file's true ratio (pitfall 91). */
.card--pack{display:flex;flex-direction:column}
.card--pack img{width:auto;max-width:100%;height:var(--pack-img,168px);
  object-fit:contain;margin-inline:auto;margin-bottom:14px}
.card--pack>.btn{margin-top:auto}

/* The footer column link is the thing you tap, and it was 17px tall in
   35px of row pitch -- under the 24px WCAG AA floor. The padding grows the
   hit area to ~33px and the negative margin gives the space straight back,
   so the footer renders identically. inline-block (not block) keeps the
   hover underline the width of the words. See fix_footer_tap.py. */
footer li a{display:inline-block;padding-block:4px;margin-block:-4px}

/* ==== 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 ==== */

/* brand mark: bracket construction */
.brand{position:relative;padding-inline:14px}.brand::before,.brand::after{content:'';position:absolute;top:2px;bottom:2px;width:8px;border:2px solid #e79ad0}.brand::before{left:0;border-right:0}.brand::after{right:0;border-left:0}

/* ==== 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 .copy{font-size:16px}
footer .disc li{font-size:16px}
footer .disc p{font-size:16px}
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 0 box-shadow declaration(s)
   and 0 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 (23,28,34), 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(23,28,34,.06), 0 6px 18px rgba(23,28,34,.07);
  --lift:0 2px 6px rgba(23,28,34,.09), 0 16px 34px rgba(23,28,34,.14);
}

.card,
.step,
.keypoints,
.callout,
.alert,
.toc,
.byline,
.posts article,
.shots figure,
.badgewall figure,
.tablewrap,
.faq,
.ingcard,
.final,
.split__img,
.answer{box-shadow:var(--shadow)}

/* 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. */
.step,
.keypoints,
.callout,
.alert,
.toc,
.byline,
.posts article,
.shots figure,
.badgewall figure,
.tablewrap,
.faq,
.ingcard,
.final,
.split__img{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 ==== */

/* ==== 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 ==== */
