/* ==== font fallback metrics (fix_font_shift.py) ==== */
@font-face{font-family:"Marcellus Fallback";src:local("Georgia");font-weight:400;size-adjust:103.39%;ascent-override:94.22%;descent-override:27.06%;line-gap-override:0.00%}
@font-face{font-family:"Maven Pro Fallback";src:local("Arial");font-weight:400;size-adjust:104.06%;ascent-override:92.74%;descent-override:20.18%;line-gap-override:0.00%}
@font-face{font-family:"Maven Pro Fallback";src:local("Arial Bold");font-weight:600 900;size-adjust:101.38%;ascent-override:95.19%;descent-override:20.71%;line-gap-override:0.00%}
/* ==== end font fallback metrics ==== */
/* opticorepros.com — OptiCore Pro, U.S. authorized retailer desk.
   Design slot (batch8_assignments.py, row 303): Marcellus / Maven Pro, a cool
   porcelain ground ruled with a slate grid, the mark enclosed in a CIRCLE with
   the name beside it and everything else pushed far right, a footer whose
   destinations sit in ranks separated by drawn vertical hairlines, and the
   iris-open hero motif.

   The teal is sampled from the bottle itself: the wordmark runs #009FA4 to
   #00B3B6 and the favicon field is #44A3A6. Nothing here is borrowed from the
   LOOKS FOR reference except its component system.

   The ruled ground is the idea. An eye chart, a prescription pad and an optical
   bench are all drawn on ruled paper, and no other site on this estate carries a
   grid — the rest are flat, washed, wedged or gradient. Sections that need to
   read as paper sit on an opaque panel; the ruling shows between them.

   Everything above CRITICAL-END is inlined into every page head. */

/* ---- tokens */
:root{
  --ink:#18242a;            /* body text */
  --ink-2:#4a5a64;          /* secondary */
  --ink-3:#71838e;          /* captions, meta */
  --teal:#009fa4;           /* the wordmark */
  --teal-l:#00b3b6;         /* the wordmark's lighter end */
  --teal-d:#00767b;         /* text-safe teal */
  --slate:#33424c;          /* the rule grid, table heads, deep panels */
  --slate-d:#1e2a32;
  --slate-2:#3f515d;
  --wash:#e2f2f2;           /* teal wash */
  --paper:#f3f6f7;          /* the page: cool porcelain */
  --panel:#ffffff;
  --tint:#e8eef0;
  --line:#dae2e6;
  --line-2:#bfcbd2;
  --good:#12795c;
  --warn:#8a5a10;
  --wrap:1200px;
  --measure:760px;
  --measure-wide:980px;
  --radius:6px;
  --radius-lg:14px;
  --shadow:0 1px 2px rgba(24,36,42,.05), 0 10px 30px rgba(24,36,42,.07);
  --shadow-lg:0 22px 58px rgba(30,42,50,.20);
  --navh:104px;
  --display:"Marcellus","Marcellus Fallback",Georgia,"Times New Roman",serif;
  --text:"Maven Pro","Maven Pro Fallback",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%}
/* The slate rule grid. Two repeating gradients at very low alpha, 34px apart,
   so the ground reads as ruled paper rather than as graph paper. Sections that
   carry their own background sit on top of it; the plain .sec does not, which
   is what lets the ruling run between them. */
body{
  overflow-x:clip;color:var(--ink);
  background-color:var(--paper);
  background-image:
    repeating-linear-gradient(to bottom,rgba(51,66,76,.055) 0 1px,transparent 1px 34px),
    repeating-linear-gradient(to right,rgba(51,66,76,.035) 0 1px,transparent 1px 34px);
  font-family:var(--text);font-size:17px;line-height:1.72;font-weight:400;
  -webkit-font-smoothing:antialiased;
}
img{max-width:100%;height:auto;display:block}
a{color:var(--teal-d);text-underline-offset:3px}
a:hover{color:var(--slate)}
/* Marcellus ships ONE weight (400). Asking for 700 here would hand every
   heading on the site to the browser's synthetic bold, which smears a serif
   this fine. The hierarchy comes from size, colour and letter-spacing instead,
   and the sub-headings are set in Maven Pro where a real bold exists. */
h1,h2{font-family:var(--display);font-weight:400;color:var(--slate-d);line-height:1.18;margin:0 0 .5em}
h3,h4{font-family:var(--text);font-weight:700;color:var(--slate-d);line-height:1.28;margin:0 0 .5em}
h1{font-size:clamp(2rem,1.28rem + 2.3vw,3.15rem);letter-spacing:-.005em}
h2{font-size:clamp(1.52rem,1.2rem + 1.2vw,2.2rem);letter-spacing:-.004em}
h3{font-size:1.18rem}
h4{font-size:1.02rem}
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(--slate-d);color:#fff;padding:12px 18px;z-index:200}
.skip:focus{left:8px;top:8px}
:focus-visible{outline:3px solid var(--teal);outline-offset:2px}

/* the eyebrow names the JOB of the section beneath it */
.eyebrow{
  display:inline-flex;align-items:center;gap:10px;
  font-family:var(--text);font-size:0.8438rem;font-weight:800;
  letter-spacing:.16em;text-transform:uppercase;color:var(--teal-d);
  margin:0 0 10px;
}
/* two drawn rules, the ground's grid at its smallest scale */
.eyebrow::before{
  content:"";width:20px;height:5px;
  border-top:1px solid var(--teal);border-bottom:1px solid var(--teal);
}

/* ---- buttons */
.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:.012em;
  border:0;border-radius:var(--radius);cursor:pointer;text-decoration:none;
  background:var(--slate-d);color:#fff;
  transition:filter .18s ease,transform .18s ease;
}
.btn:hover{filter:brightness(1.18);color:#fff}
.btn:active{transform:translateY(1px)}
.btn--teal{background:linear-gradient(100deg,var(--teal-d) 0%,var(--teal-l) 100%)}
.btn--lg{min-height:62px;padding:17px 38px;font-size:1.08rem}
.btn--ghost{background:none;color:var(--slate);box-shadow:inset 0 0 0 2px var(--line-2)}
.btn--ghost:hover{background:var(--wash);color:var(--slate-d)}
.btn--wide{width:100%}

/* ---- header: circle mark and name at the left edge, everything else far right */
.nav{position:sticky;top:0;z-index:100;background:var(--panel);box-shadow:0 1px 0 var(--line)}
/* 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.
   Invisible above the container max-width, and no overflow test can see it
   (pitfall 46). */
.nav__top{display:flex;align-items:center;gap:22px;padding-block:14px}
.brand{display:flex;align-items:center;gap:13px;text-decoration:none;color:var(--slate-d)}
.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 class="brand__glyph" onto the
   replacement, so a rule keyed only to that class stops applying the moment the
   tool runs and the glyph renders at its intrinsic size — a masthead two
   different heights on one site (pitfall 16). */
.brand>svg{width:38px;height:38px;flex:0 0 auto}
.bw{display:flex;flex-direction:column;line-height:1.1}
.bw b{font-family:var(--display);font-weight:400;font-size:1.42rem;letter-spacing:.005em;white-space:nowrap}
.bw b em{font-style:normal;color:var(--teal-d)}
.bw small{font-size:0.9062rem;font-weight:600;color:var(--ink-3)}
.nav__rail{margin-left:auto;display:flex;align-items:center;gap:20px;min-width:0}
.menu{display:flex;flex-wrap:wrap;gap:0 24px;list-style:none;margin:0;padding:0;align-items:center}
.menu a{
  display:inline-block;padding:9px 0;font-family:var(--text);
  font-size:.9375rem;font-weight:600;color:var(--ink-2);text-decoration:none;
  border-bottom:2px solid transparent;
}
.menu a:hover{color:var(--slate-d)}
.menu a[aria-current="page"]{color:var(--slate-d);border-bottom-color:var(--teal)}
.menu__more{display:none}
.nav__price{text-align:right;line-height:1.2;white-space:nowrap}
.nav__price b{display:block;font-family:var(--display);font-weight:400;font-size:1.2rem;color:var(--slate-d)}
.nav__price span{font-size:.75rem;font-weight:600;color:var(--ink-3)}
.nav__buy{min-height:46px;padding:11px 22px;font-size:.95rem}
.burger{
  display:none;width:48px;height:46px;background:transparent;border:1px solid var(--line-2);
  border-radius:var(--radius);cursor:pointer;padding:12px 11px;
}
.burger span{display:block;height:2px;background:var(--slate-d);margin:0 0 5px}
.burger span:last-child{margin:0}

/* ---- hero: copy LEFT, the bottle RIGHT on a ruled porcelain field */
.hero{position:relative;padding:52px 0 58px;overflow-x:clip}
.hero__grid{position:relative;z-index:1;display:grid;grid-template-columns:minmax(0,1.06fr) minmax(0,.94fr);gap:44px;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(--teal-d)}
.answer{
  background:var(--panel);border:1px solid var(--line);
  border-left:4px solid var(--teal);border-radius:0 var(--radius) var(--radius) 0;
  padding:20px 24px;margin:0 0 18px;box-shadow:var(--shadow);
}
.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:600;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:600;color:var(--ink-2);background:var(--panel);
  border:1px solid var(--line);padding:7px 14px;border-radius:var(--radius);
}
.factpills li b{color:var(--slate-d);font-weight:800}
.figures{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:12px;margin:0}
.figures div{background:var(--panel);border:1px solid var(--line);border-top:3px solid var(--teal);padding:13px 15px;border-radius:0 0 var(--radius) var(--radius);min-width:0}
.figures b{display:block;font-family:var(--display);font-weight:400;font-size:1.55rem;color:var(--slate-d);line-height:1.12}
.figures span{display:block;font-size:0.9062rem;font-weight:600;color:var(--ink-3);margin-top:3px}
.hero__media{position:relative;align-self:center}
.hero__card{position:relative;z-index:2;text-align:center;padding:10px}
.hero__card img{width:100%;max-width:430px;height:auto;margin-inline:auto;
  filter:drop-shadow(0 24px 40px rgba(24,36,42,.28))}
.hero__cap{margin:14px 0 0;font-size:.8125rem;font-weight:600;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;font-weight:600;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:34px 0 12px;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(--teal-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.
   Role, lot, dose and count, guarantee, order desk. It sits ABOVE the header so
   the navigation does not have to carry them, and its CSS sits ABOVE
   CRITICAL-END because it is the first thing painted; appended to the end of
   the stylesheet it would load async and flash unstyled at the very top of the
   page. Lot and dose are trimmed on phones, where five items wrap to three
   lines and eat a tenth of the screen. */
.util{background:var(--slate-d);color:#b4c4cc;font-size:.8125rem;line-height:1.5}
.util__row{display:flex;flex-wrap:wrap;align-items: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:1px;height:12px;
  background:#4d626d;flex:0 0 auto;margin-right:11px}
.util b{color:#e6eef1;font-weight:700}
.util a{color:inherit;text-decoration:none}
.util a:hover{text-decoration:underline}
@media (max-width:760px){
  .util__item--trim{display:none}
  .util__row{gap:4px 14px}
}

/* ---- hero motif -- iris-open ---------------------------------------- */
.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:radial-gradient(122% 88% at 72% 28%,#e2f1f2,#f3f6f7 44%,#eceff0)}.hero__media::before{content:'';position:absolute;left:50%;top:46%;width:150%;aspect-ratio:1;translate:-50% -50%;border-radius:50%;border:1px solid rgba(0,158,160,0.42);box-shadow:0 0 0 12px rgba(0,179,182,0.06) inset;animation:ocIris 9s cubic-bezier(.33,.06,.2,1) infinite;z-index:1;pointer-events:none}.hero__media::after{content:'';position:absolute;left:50%;top:46%;width:96%;aspect-ratio:1;translate:-50% -50%;border-radius:50%;background:radial-gradient(closest-side,rgba(0,179,182,0.30),rgba(0,179,182,0.12) 58%,transparent 74%);filter:blur(22px);animation:ocOpen 9s cubic-bezier(.33,.06,.2,1) infinite;z-index:0;pointer-events:none}@keyframes ocIris{0%{scale:.42;opacity:0}18%{opacity:.78}100%{scale:1.14;opacity:0}}@keyframes ocOpen{0%{scale:.72;opacity:.28}46%{scale:1.02;opacity:.9}100%{scale:1.14;opacity:.22}}
@media(prefers-reduced-motion:reduce){.hero__card{animation:none!important}.hero__media::before,.hero__media::after{animation:none!important;opacity:0!important}}

/* --- 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.
   REGENERATED ON EVERY BUILD from the rules below the marker. Edit
   the originals; never this copy, which is overwritten. */
@media (max-width:980px){
  .hero__grid{grid-template-columns:1fr;gap:26px}
  .hero__copy{display:contents}
  .hero .eyebrow{order:1}
  .hero h1{order:2}
  /* max-width, so the iris ring scales with the PRODUCT and not with the viewport. The ring is sized as a percentage of this column; left at full width on a tablet it becomes a 1,100px circle around a 430px bottle and spills over the headline above it. */ .hero__media{order:3;margin:6px auto 20px;max-width:460px;width:100%}
  .hero__road{order:5}
  .hero__cta{order:6}
  .hero__sub{order:8}
}
@media (max-width:760px){
  .hero{padding:32px 0 42px}
}
@media (min-width: 981px){
  .hero__media{position: sticky; top: calc(var(--navh, 88px) + 14px); align-self: start; min-height: calc(100vh - var(--navh, 88px) - 28px); min-height: calc(100svh - var(--navh, 88px) - 28px); 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;}
}
/* --- end of the copied hero responsive rules --- */

/*!SITE-HOME-CRIT-START*/
/* opticorepros.com -- home page LAYOUT. .hero is on index.html and nowhere
   else on this site, so a selector that starts ".hero " is home-only by
   construction; the pricing rules carry body:has(.hero) because #pricing also
   exists on pricing.html.

   1. Desktop reading order. Measured at 1440x900 the buy button ran 789-853
   and the secondary button was cut at 928, so the first screen ended in the
   middle of the CTA pair. Reordering the copy column to eyebrow, headline,
   quick answer, BUTTONS, payment line, then the evidence lifts the pair to
   roughly 660-800 with the payment line under it. The phone order is composed
   separately with display:contents below 980px and is left alone. */
@media (min-width:981px){
  .hero .hero__copy>.eyebrow{order:1}
  .hero .hero__copy>h1{order:2}
  .hero .hero__copy>.answer{order:3}
  .hero .hero__copy>.hero__cta{order:4;margin-bottom:14px}
  .hero .hero__copy>.hero__sub{order:5;margin-bottom:16px}
  .hero .hero__copy>.hero__road{order:6}
  .hero .hero__copy>.factpills{order:7}
  .hero .hero__copy>.figures{order:8}
}

/* 2. The pricing ribbon is a full-width bar, so every card in the row reserves
   the same 30px strip for it whether or not it carries one. The reserve is
   uniform, so the row keeps one height and the three Add To Cart buttons keep
   one baseline. The recommended tier is raised with margin-top, never
   transform -- the reveal pass sets transform:none -- and because .prices
   stretches its items the card BOTTOMS stay level, which is what the button
   baseline hangs from. Verified by measuring the three buttons afterwards. */
body:has(.hero) .prices>.card--pack{padding-top:30px}
body:has(.hero) .prices>.card--pack>.pack__flag{position:absolute;
  left:0;right:0;top:0;width:auto;height:30px;
  display:flex;align-items:center;justify-content:center;
  padding:0 14px;font-size:.75rem;line-height:1;letter-spacing:.14em}
@media (min-width:761px){
  body:has(.hero) .prices>.card--pack.featured{margin-top:-18px}
}
/*!SITE-HOME-CRIT-END*/
/*!CRITICAL-END*/
/* ---- sections. No background by default, so the ruled ground runs between
   them; the ones that need to read as paper carry their own. */
.sec{padding:60px 0;position:relative}
.sec--tint{background:var(--tint)}
.sec--panel{background:var(--panel)}
.sec--dark{background:var(--slate-d);color:#d6e0e4}
.sec--dark h2,.sec--dark h3{color:#fff}
.sec--dark p,.sec--dark li{color:#c0cdd3}
.sec--dark .eyebrow{color:#63cdd0}
.sec--dark .eyebrow::before{border-color:#63cdd0}
.sec--dark a{color:#8fdcde}
.sec--center{text-align:center}
.sec--center .sec__head{margin-inline:auto}
/* the drawn rule, repeated at section scale */
.sec--ruled{background:var(--panel);border-top:1px solid var(--line);border-bottom:1px solid var(--line)}
.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:#c0cdd3}

/* 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:#63cdd0}

/* ---- 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(--text);font-weight:700;color:#fff;background:var(--slate);font-size:.9375rem}
tbody tr:nth-child(even){background:#f8fbfb}
tbody tr:last-child td{border-bottom:0}
td b{color:var(--slate-d)}
.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}
.step{position:relative;background:var(--panel);border:1px solid var(--line);border-radius:var(--radius);padding:20px 22px 20px 70px;min-width:0}
.step::before{
  counter-increment:s;content:counter(s);
  position:absolute;left:20px;top:19px;width:36px;height:36px;
  display:grid;place-items:center;
  background:linear-gradient(140deg,var(--teal-l),var(--teal-d));color:#fff;
  font-family:var(--text);font-weight:800;font-size:1rem;border-radius:50%;
}
.step h3{margin:0 0 6px}
.step p:last-child{margin:0}

/* ---- cards: a drawn rule across the top, in the teal */
.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 belongs on the items at every width. */
.grid>*{min-width:0}
.card{position:relative;background:var(--panel);border:1px solid var(--line);border-top:3px solid var(--teal);border-radius:0 0 var(--radius) var(--radius);padding:22px 22px 20px;min-width:0}
.card h3{margin:0 0 8px}
.card p:last-child,.card ul:last-child{margin-bottom:0}
.sec--dark .card{background:#25333c;border-color:#3b4d58;border-top-color:var(--teal)}

/* ---- callout, alert, quote, keypoints */
.callout{background:var(--wash);border:1px solid #bfe2e2;border-radius:var(--radius);padding:20px 22px;margin:0 0 1.2em}
.callout b:first-child{display:block;margin-bottom:6px;color:var(--slate-d)}
.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-weight:400;font-size:1.35rem;line-height:1.5;color:var(--slate-d);border-left:3px solid var(--teal);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:400;color:var(--ink-3);margin-top:8px}
.keypoints{background:var(--panel);border:1px solid var(--line);border-top:3px solid var(--teal);border-radius:0 0 var(--radius) var(--radius);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 */
.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 .tablewrap holding a 520px-min table keeps its grid column 520px wide
   however narrow the grid is, because a grid item floors at min-content.
   Measured on the sister layout at 390: a 350px grid box whose single column
   resolved to 522px, the right-hand half 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, not only inside a media query. */
.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}

/* ---- stat band */
.stats{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:20px;text-align:center}
.stats>div{min-width:0}
.stats div b{display:block;font-family:var(--display);font-weight:400;font-size:2.3rem;color:#fff;line-height:1.12}
.stats div span{display:block;font-size:.9375rem;color:#a9bcc4;margin-top:4px}

/* ---- label versus research */
.versus{display:grid;grid-template-columns:1.05fr 1fr 1.25fr;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:#f7fafa}
.versus__h{background:var(--slate)!important;color:#fff;font-family:var(--text);font-weight:700;font-size:.92rem}

/* ---- ingredient cards */
.inglist{display:grid;gap:16px}
/* Same family as the .split fix. .ingcard is a grid ITEM and `.ing__dose` is
   white-space:nowrap, so the longest chip sets the column's min-content floor
   and the card cannot shrink below it. min-width:0 lets it; .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-radius:var(--radius);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:700;color:#fff;background:var(--slate);padding:4px 12px;border-radius:var(--radius);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;padding:0;border-top-width:2px}
/* 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 coloured head band and its flag. */
.card--pack.featured{border-color:var(--teal);box-shadow:var(--shadow-lg)}
.pack__head{background:var(--tint);border-bottom:1px solid var(--line);padding:14px 20px;display:flex;align-items:center;gap:10px}
.card--pack.featured .pack__head{background:linear-gradient(100deg,var(--slate-d),var(--slate-2));border-bottom-color:var(--slate-d)}
.card--pack.featured .pack__head b,.card--pack.featured .pack__head span{color:#fff}
.pack__head b{font-family:var(--display);font-weight:400;font-size:1.2rem}
.pack__head span{font-size:.8125rem;font-weight:700;color:var(--ink-3);margin-left:auto;white-space:nowrap}
.pack__flag{position:absolute;right:0;top:0;background:var(--teal);color:#fff;font-family:var(--text);font-size:0.8438rem;font-weight:800;letter-spacing:.08em;text-transform:uppercase;padding:5px 13px;z-index:3;border-radius:0 0 0 var(--radius)}
.pack__body{display:flex;flex-direction:column;flex:1;padding:20px 20px 22px;min-width:0}
.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-weight:400;font-size:2.5rem;color:var(--slate-d);line-height:1;text-align:center}
.pack__per sup{font-size:1rem;font-weight:700;top:-.75em}
.pack__unit{display:block;text-align:center;font-size:.875rem;font-weight:700;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:600}
.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>*{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(--slate-d)}
.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(--slate-d)}
.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 minmax(0,1fr) 52px;gap:12px;align-items:center;margin:0 0 8px;font-size:.9375rem}
.meter__bar{height:10px;background:var(--line);border-radius:999px;overflow:hidden}
.meter__bar i{display:block;height:100%;background:linear-gradient(90deg,var(--teal-l),var(--slate))}
.stars{color:#d59a1c;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(--text);font-weight:700;font-size:1.05rem;color:var(--slate-d)}
.faq summary::-webkit-details-marker{display:none}
.faq summary::after{content:"+";position:absolute;right:20px;top:50%;translate:0 -50%;font-size:1.34rem;font-weight:400;color:var(--teal-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 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 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:4px solid var(--teal);border-radius:0 var(--radius) var(--radius) 0;padding:22px 24px;margin:0 0 1.2em}
.byline>*{min-width:0}
.byline__mark{flex:0 0 auto;width:54px;height:54px;display:grid;place-items:center;background:linear-gradient(140deg,var(--slate-d),var(--slate-2));color:#fff;font-family:var(--display);font-weight:400;font-size:1.1rem;border-radius:50%}
.byline b{display:block;margin-bottom:6px;color:var(--slate-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:3px solid var(--teal);border-radius:0 0 var(--radius) var(--radius);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:210px}
.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(--teal);transform:translateY(-2px)}
.rel b{display:block;font-family:var(--display);font-weight:400;font-size:1.14rem;color:var(--slate-d);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: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:.9375rem;color:var(--ink-3);margin:0 0 20px}
.toc{background:var(--panel);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(--slate-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>*{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}

/* ---- footer: a deep CTA band, then destinations in ranks separated by drawn
   vertical hairlines, then a ruled legal rail. */
.fcta{background:linear-gradient(140deg,var(--slate-d) 0%,#101a20 100%);color:#fff;padding:52px 0}
.fcta h2,.fcta__h{color:#fff}
.fcta__box{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:34px;align-items:center}
.fcta__eye{display:inline-block;font-size:.78125rem;font-weight:800;letter-spacing:.16em;text-transform:uppercase;color:var(--teal-l);margin-bottom:8px}
.fcta__h{font-family:var(--display);font-weight:400;font-size:1.7rem;line-height:1.24;margin:0 0 10px}
.fcta p{color:#bfcdd3}
.fcta__sm{font-size:.9375rem;color:#9aacb4;margin:12px 0 0}
.fcta__sm a,.fcta p a{color:#8fdcde}
.fcta__img img{width:280px}
footer{background:var(--panel)}
.fgrid{display:grid;grid-template-columns:1.5fr repeat(4,1fr);gap:0;padding-block:44px 30px}
.fgrid>*{padding-inline:26px;min-width:0}
.fgrid>*:first-child{padding-left:0}
.fgrid>*+*{border-left:1px solid var(--line)}
.fbrand{font-family:var(--display);font-weight:400;font-size:1.72rem;color:var(--slate-d);line-height:1}
.fbrand span{color:var(--teal-d)}
.frole{font-size:.9375rem;color:var(--ink-2);margin:8px 0 14px}
.fcard p{font-size:1.062rem;color:var(--ink-2);margin:0 0 .7em}
.fcard b{color:var(--slate-d)}
.fh{font-size:.8125rem;font-weight:800;letter-spacing:.13em;text-transform:uppercase;color:var(--ink-3);margin:0 0 10px}
.fgrid ul{list-style:none;margin:0 0 20px;padding:0}
.fgrid li{margin:0}
/* 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:5px;margin-block:-5px;font-size:.9688rem;color:var(--ink-2);text-decoration:none}
footer li a:hover{color:var(--teal-d)}
.fseals{display:flex;flex-wrap:wrap;align-items:center;gap:14px;padding-block:20px;border-top:1px solid var(--line)}
.fseals img{width:44px;height:44px;object-fit:contain}
.fseals span{font-size:.9375rem;color:var(--ink-3)}
.fpay{display:flex;flex-wrap:wrap;align-items:center;gap:16px;padding-block:0 26px}
.fpay img{width:230px;height:auto}
.fpay span{font-size:.9375rem;color:var(--ink-3)}
.disc{background:var(--tint);border-top:1px solid var(--line);padding:28px 0 32px}
.disc p,.disc li{font-size:.9375rem;color:var(--ink-2)}
.disc b{color:var(--slate-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:.7em;width:8px;height:1px;background:var(--teal)}
.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:var(--slate-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:.9375rem;min-width:0}
.buybar__t b{display:block;font-size:1rem}
.buybar__t span{color:#a9bcc4}
.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 18px}
  .menu a{font-size:.9rem}
  .nav__price{display:none}
}
@media (max-width:1060px){
  :root{--navh:96px}
  .nav__rail{gap:14px}
  /* the right-hand rail keeps the CTA; the destinations drop into a panel
     beneath the header, which .nav (sticky, therefore positioned) contains */
  .menu{display:none;position:absolute;left:0;right:0;top:100%;flex-direction:column;
    align-items:stretch;gap:0;background:var(--panel);border-top:1px solid var(--line);
    box-shadow:var(--shadow);padding:6px 22px 14px}
  .menu.open{display:flex}
  .menu__more{display:block}
  .menu a{padding:12px 0;border-bottom:1px solid var(--line);border-bottom-width:1px}
  .menu a[aria-current="page"]{border-bottom-color:var(--line)}
  .burger{display:block}
  .fgrid{grid-template-columns:1fr 1fr 1fr}
  .fgrid>*{padding-inline:22px;padding-block:0 18px}
  .fgrid>*:nth-child(3n+1){padding-left:0;border-left:0}
}
@media (max-width:980px){
  .hero__grid{grid-template-columns:1fr;gap:26px}
  .hero__copy{display:contents}
  .hero .eyebrow{order:1}
  .hero h1{order:2}
  /* max-width, so the iris ring scales with the PRODUCT and not with the
     viewport. The ring is sized as a percentage of this column; left at full
     width on a tablet it becomes a 1,100px circle around a 430px bottle and
     spills over the headline above it. */
  .hero__media{order:3;margin:6px auto 20px;max-width:460px;width:100%}
  .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}
  .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:44px 0}
  .hero{padding:32px 0 42px}
  .nav__buy{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 gets pushed onto a line with no room for it and overhangs the 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}
  .figures{grid-template-columns:1fr;gap:8px}
  .fgrid{grid-template-columns:1fr 1fr}
  .fgrid>*{padding-inline:18px}
  .fgrid>*:nth-child(odd){padding-left:0;border-left:0}
  .buybar__in{flex-wrap:wrap;gap:10px;padding-block:10px}
  .buybar .btn{width:100%;margin-left:0}
}
@media (max-width:440px){
  .fgrid{grid-template-columns:1fr}
  .fgrid>*{padding-inline:0;border-left:0}
  .badgewall{grid-template-columns:1fr}
}

/* ---- hero: the product settles on the ruled field ---------------------------
   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 card is transparent by design here, so the product needs its own ground:
   an elliptical shadow beneath it, sized to the product rather than to the
   column. hero_motifs.py owns the iris ring and the bloom behind it. */
.hero__card{isolation:isolate}
.hero__card::after{
  content:"";position:absolute;left:50%;bottom:26px;translate:-50% 0;
  width:54%;height:18px;border-radius:50%;
  background:radial-gradient(closest-side,rgba(24,36,42,.34),transparent 74%);
  filter:blur(5px);z-index:0;pointer-events:none;
}
@media (prefers-reduced-motion:no-preference){
  /* The float goes on the CARD, never on the <img>. The image is the LCP
     element and is preloaded; animating it is what hero.md rules out. */
  .hero__card{animation:ocFloat 8.5s ease-in-out infinite}
  @keyframes ocFloat{0%,100%{transform:translateY(0)}50%{transform:translateY(-10px)}}
}

/* ---- 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: this header compacts between
   breakpoints, and a hardcoded offset tucks the product under the bar.

   min-height makes the sticky box a full screen tall so the shot can be CENTRED
   inside it. Without it the box is only as tall as the image and `top` merely
   pins it under the header.

   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, 88px) + 14px);
    align-self: start;
    min-height: calc(100vh - var(--navh, 88px) - 28px);
    min-height: calc(100svh - var(--navh, 88px) - 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 ---------------------------------
   A pricing row is three cards that have to share their edges, their image slot
   and their button baseline. The vendor pack shots are all 1125x1125 here, but
   the blurbs are different lengths, so without these the three CTAs 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 and CLS
   gets worse. Override per site with --pack-img. */
.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}

/* ==== directional chrome (fix_chrome_scroll.py) ==== */
.nav,#nav,header.header{transition:transform .28s ease}
@media(prefers-reduced-motion:reduce){.nav,#nav,header.header{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*/
/* opticorepros.com -- home page PAINT. radius, shadow, background, colour,
   transform, transition, animation only: nothing here moves a box, so it lives
   below the critical marker and needs a restamp rather than a rebuild.

   Everything is scoped to the home page. modern_surface.py and footer_type.py
   re-append their own blocks AFTER this one on every build, so these rules
   beat them on SPECIFICITY (body:has(.hero) .card == 0,2,1 against .card ==
   0,1,0) and never on source order.

   Assigned slot: circulate motif, 24px panels, 16px controls, a single soft
   lift with no contact stop, a full-width ribbon. The shadow is tinted with
   this site's own ink, rgb(24,36,42), never neutral black. */
:root{
  --oc-card-r:24px;                                  /* slot radius_card */
  --oc-ctl-r:16px;                                   /* slot radius_control */
  --oc-soft:0 12px 30px rgba(24,36,42,.10);          /* slot depth, one stop */
  --oc-soft-2:0 18px 42px rgba(24,36,42,.17);
  --oc-teal-lift:0 18px 44px rgba(0,118,123,.26);
}

/* ---- panels: 24px, one soft lift, no hairline contact stop --------------- */
body:has(.hero) .card,
body:has(.hero) .keypoints,
body:has(.hero) .callout,
body:has(.hero) .byline,
body:has(.hero) .final,
body:has(.hero) .split__img,
body:has(.hero) .ingcard,
body:has(.hero) .toc,
body:has(.hero) .step,
body:has(.hero) .faq,
body:has(.hero) .tablewrap,
body:has(.hero) .posts article,
body:has(.hero) .shots figure,
body:has(.hero) .badgewall figure{border-radius:var(--oc-card-r);
  box-shadow:var(--oc-soft)}

/* The quick answer and the alert are ruled down their left edge in teal and
   in amber. A 24px curve on that edge would cut the rule in half, so those two
   keep a square left and take the curve on the open side only. */
body:has(.hero) .answer{border-radius:0 var(--oc-card-r) var(--oc-card-r) 0;
  box-shadow:var(--oc-soft)}
body:has(.hero) .alert{border-radius:0 var(--oc-card-r) var(--oc-card-r) 0;
  box-shadow:var(--oc-soft)}

/* ---- controls: 16px, a gradient on the buying CTA and the secondary left
   solid, so the pair reads as two weights rather than two colours ---------- */
body:has(.hero) .btn{border-radius:var(--oc-ctl-r);
  transition:transform .22s cubic-bezier(.2,.7,.3,1),box-shadow .22s ease,
    filter .22s ease,background-color .22s ease}
body:has(.hero) .btn--teal{
  background-image:linear-gradient(118deg,#00666b 0%,var(--teal) 48%,
    var(--teal-l) 100%);
  box-shadow:var(--oc-soft)}
body:has(.hero) .btn--ghost{background-color:var(--panel);
  background-image:none;box-shadow:inset 0 0 0 2px var(--line-2)}
body:has(.hero) .btn:hover{transform:translateY(-2px)}
body:has(.hero) .btn--teal:hover{box-shadow:var(--oc-teal-lift)}
body:has(.hero) .btn--ghost:hover{background-color:var(--wash);
  box-shadow:inset 0 0 0 2px var(--teal),var(--oc-soft)}
body:has(.hero) .btn:active{transform:translateY(0)}
/* Teal on teal is not a visible ring, so the focus ring on this site's CTA is
   drawn in the slate ink instead. */
body:has(.hero) .btn:focus-visible{outline:3px solid var(--slate-d);
  outline-offset:3px}
body:has(.hero) .field input:focus-visible,
body:has(.hero) .field textarea:focus-visible,
body:has(.hero) .field select:focus-visible{outline:3px solid var(--teal-d);
  outline-offset:2px}
body:has(.hero) .field input,
body:has(.hero) .field textarea,
body:has(.hero) .field select{border-radius:var(--oc-ctl-r)}

/* ---- a surface a reader can click answers the pointer, 2px ---------------- */
body:has(.hero) .rel a,
body:has(.hero) .posts article,
body:has(.hero) .shots figure,
body:has(.hero) .badgewall figure,
body:has(.hero) .prices>.card--pack{
  transition:transform .22s cubic-bezier(.2,.7,.3,1),box-shadow .22s ease}
body:has(.hero) .rel a:hover,
body:has(.hero) .posts article:hover,
body:has(.hero) .shots figure:hover,
body:has(.hero) .badgewall figure:hover{transform:translateY(-2px);
  box-shadow:var(--oc-soft-2)}

/* ---- pricing: full-width ribbon, dashed feature separators --------------- */
/* Every card carries the reserved strip, tinted, so the row reads as one
   object; two of the three then paint a coloured bar over it. */
body:has(.hero) .prices>.card--pack{border-radius:var(--oc-card-r);
  box-shadow:var(--oc-soft),inset 0 0 0 1px var(--line)}
body:has(.hero) .prices>.card--pack::before{content:"";position:absolute;
  left:0;right:0;top:0;height:30px;background:var(--tint);
  box-shadow:inset 0 -1px 0 var(--line);z-index:2;pointer-events:none}
body:has(.hero) .prices>.card--pack>.pack__flag{border-radius:0;z-index:3;
  background-image:linear-gradient(100deg,var(--teal-d),var(--teal-l))}
body:has(.hero) .prices>.card--pack.featured{
  box-shadow:var(--oc-teal-lift),inset 0 0 0 1px rgba(0,118,123,.25)}
body:has(.hero) .prices>.card--pack.featured>.pack__flag{
  background-image:linear-gradient(100deg,var(--slate-d),var(--slate-2))}
body:has(.hero) .prices>.card--pack:hover{transform:translateY(-2px);
  box-shadow:var(--oc-soft-2),inset 0 0 0 1px var(--line)}
body:has(.hero) .prices>.card--pack.featured:hover{transform:translateY(-2px);
  box-shadow:var(--oc-teal-lift),inset 0 0 0 1px rgba(0,118,123,.25)}
/* Dashed rules between the feature rows, drawn as a background so they add no
   height: the three cards share one button baseline and nothing here may
   change a row's measurement. */
body:has(.hero) .pack__perks li{
  background-image:linear-gradient(90deg,var(--line-2) 0 5px,
    transparent 5px 10px);
  background-repeat:repeat-x;background-position:left bottom;
  background-size:10px 1px}
body:has(.hero) .pack__perks li:last-child{background-image:none}

/* ---- hero motif: CIRCULATE ----------------------------------------------- */
/* Two counter-rotating arcs, the outer wide and open, the inner tighter and
   turning the other way, so the pair reads as slow circulation around the
   bottle. Both live on the media column's pseudo-elements; the <img> is the
   LCP element, is preloaded, and is never touched. Both are sized LARGER than
   the 430px product card (620px and 470px) so they read outside it rather than
   disappearing behind an opaque panel. 54s and 38s: this is a capsule taken
   once a day for weeks, not an energy drink.

   These replace the iris rings that used to animate scale on the same two
   pseudo-elements. Only rotate and opacity move here, both compositor
   properties, and the keyframe names are new -- ocIris, ocOpen and ocFloat are
   already taken in this stylesheet. */
body:has(.hero) .hero__media::before{content:"";position:absolute;
  left:50%;top:50%;width:min(128%,620px);aspect-ratio:1;
  translate:-50% -50%;rotate:0deg;scale:1;
  border:2px solid transparent;
  border-top-color:rgba(0,159,164,.55);
  border-right-color:rgba(0,159,164,.20);
  border-radius:50%;background:none;box-shadow:none;filter:none;
  animation:opcArcOut 54s linear infinite;
  z-index:1;pointer-events:none;opacity:1}
body:has(.hero) .hero__media::after{content:"";position:absolute;
  left:50%;top:50%;width:min(98%,470px);aspect-ratio:1;
  translate:-50% -50%;rotate:0deg;scale:1;
  border:3px solid transparent;
  border-bottom-color:rgba(0,179,182,.42);
  border-left-color:rgba(0,179,182,.14);
  border-radius:50%;background:none;box-shadow:none;filter:none;
  animation:opcArcIn 38s linear infinite;
  z-index:1;pointer-events:none;opacity:1}
@keyframes opcArcOut{to{rotate:360deg}}
@keyframes opcArcIn{to{rotate:-360deg}}
/* A soft teal bloom behind the bottle, painted into the hero ground rather
   than added as a third element. Static: nothing here animates. */
body:has(.hero) .hero{
  background-image:radial-gradient(40% 44% at 78% 46%,
    rgba(0,179,182,.17),rgba(0,179,182,0) 70%),
    radial-gradient(122% 88% at 72% 28%,#e2f1f2,#f3f6f7 44%,#eceff0)}

/* Everything switches off under reduced motion. The arcs stay drawn -- they
   are the composition, not the event -- they simply stop turning. This block
   carries !important because the rule it replaces, in the critical region,
   hides both pseudo-elements with !important. */
@media (prefers-reduced-motion:reduce){
  body:has(.hero) .hero__media::before,
  body:has(.hero) .hero__media::after{animation:none!important;
    opacity:.85!important}
  body:has(.hero) .btn,
  body:has(.hero) .rel a,
  body:has(.hero) .posts article,
  body:has(.hero) .shots figure,
  body:has(.hero) .badgewall figure,
  body:has(.hero) .prices>.card--pack{transition:none}
  body:has(.hero) .btn:hover,
  body:has(.hero) .rel a:hover,
  body:has(.hero) .posts article:hover,
  body:has(.hero) .shots figure:hover,
  body:has(.hero) .badgewall figure:hover,
  body:has(.hero) .prices>.card--pack:hover{transform:none}
}
/*!SITE-HOME-PAINT-END*/
/* ==== footer type floor (footer_type.py) ==== */
/* The footer carried the smallest text on the page -- the legal pages,
   the guarantee and the contact routes, set as fine print. Running text
   and links sit at 16px, column headings at 15px (uppercase and
   letter-spaced, so they read larger than the number). Last in the file
   on purpose: it outranks the phone breakpoints that shrank them. */
footer li a{font-size:16px}
footer .copy{font-size:16px}
footer .disc li{font-size:16px}
footer .disc p{font-size:16px}
footer .fh{font-size:15px}
footer .fpay span{font-size:16px}
footer .fseals span{font-size:16px}
/* ==== end footer type floor ==== */

/* ==== modern surface (modern_surface.py) ==== */
/* House rule 11. This stylesheet had 22 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 (24,36,42), 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(24,36,42,.06), 0 6px 18px rgba(24,36,42,.07);
  --lift:0 2px 6px rgba(24,36,42,.09), 0 16px 34px rgba(24,36,42,.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. */
.card,
.keypoints,
.alert,
.byline,
.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 ==== */
.review-foot{margin:0;padding:.6rem 0;font-size:.92rem}.review-foot a{font-weight:600}
