/* GlowBerry storefront — warm cream editorial.
   Theme colours (--bg, --surface, --ink, --primary, --accent, --muted) are injected
   from Admin > Site settings in views/partials/head.ejs. Everything else derives
   from them, so changing the palette in the admin restyles the whole site. */

:root {
  /* Cream + green. Cream is the ground almost everywhere; the deep brand green is the
     type colour and the ground of the .invert bands, so green punctuates the page
     instead of filling it. Contrast comes from scale, cream tints and those bands —
     not from a third brand hue. */
  --bg: #FBF7EC;
  --surface: #F4EDDC;
  --ink: #1C3A13;
  --primary: #2E6522;
  --accent: #2E6522;
  --muted: #5D6A52;

  /* derived — tuned for a light ground: thinner rules, gentler panel tints, and
     real shadows (a dark theme gets its depth from glow, a light one from shade). */
  --line: color-mix(in srgb, var(--ink) 16%, transparent);
  --line-soft: color-mix(in srgb, var(--ink) 9%, transparent);
  --panel: color-mix(in srgb, var(--ink) 4%, var(--bg));
  --panel-2: color-mix(in srgb, var(--ink) 7%, var(--bg));
  --ink-soft: color-mix(in srgb, var(--ink) 74%, transparent);
  --accent-soft: color-mix(in srgb, var(--accent) 12%, transparent);
  --danger: #A0341F;
  --shadow-sm: 0 1px 2px color-mix(in srgb, var(--ink) 6%, transparent),
               0 6px 18px -10px color-mix(in srgb, var(--ink) 22%, transparent);
  --shadow-md: 0 2px 4px color-mix(in srgb, var(--ink) 5%, transparent),
               0 18px 44px -22px color-mix(in srgb, var(--ink) 30%, transparent);
  --shadow-lg: 0 3px 8px color-mix(in srgb, var(--ink) 5%, transparent),
               0 34px 80px -30px color-mix(in srgb, var(--ink) 34%, transparent);

  --font-body: "Inter", system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  --font-display: "Inter Tight", "Inter", system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;

  --shell-max: 1600px;
  --gutter: clamp(20px, 3.6vw, 72px);
  --radius-lg: 28px;
  --radius: 18px;
  --radius-sm: 12px;
  --header-h: 68px;

  --ease: cubic-bezier(.22, .9, .24, 1);
  --ease-out: cubic-bezier(.16, 1, .3, 1);
}

@media (min-width: 1900px) {
  :root { --shell-max: 1760px; --gutter: clamp(48px, 5vw, 120px); --header-h: 76px; }
}

/* Inverted bands (deep-green ground, cream type). head.ejs supplies the swapped
   --bg/--ink/--accent/--muted; these derived tokens recompute from them. */
.invert {
  --line: color-mix(in srgb, var(--ink) 22%, transparent);
  --line-soft: color-mix(in srgb, var(--ink) 14%, transparent);
  --panel: color-mix(in srgb, var(--ink) 6%, var(--bg));
  --panel-2: color-mix(in srgb, var(--ink) 10%, var(--bg));
  --ink-soft: color-mix(in srgb, var(--ink) 82%, transparent);
  --accent-soft: color-mix(in srgb, var(--accent) 14%, transparent);
  --danger: #FFB3A3;
  /* On a dark ground shade is invisible, so the inverted bands drop shadows. */
  --shadow-sm: none;
  --shadow-md: none;
  --shadow-lg: none;
  background: var(--bg);
  color: var(--ink);
}

/* ---------- base ---------- */
*, *::before, *::after { box-sizing: border-box; }
[hidden] { display: none !important; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  scroll-padding-top: calc(var(--header-h) + 24px);
  /* `clip` (not `hidden`) kills stray horizontal scroll without creating a
     scroll container, so position:sticky keeps working. */
  overflow-x: clip;
}
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: 16px;
  line-height: 1.6;
  overflow-x: clip;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}
html.no-scroll, html.no-scroll body { overflow: hidden; }

img, video, svg { max-width: 100%; }
img, video { display: block; }
p { margin: 0; }
a { color: inherit; }
button { font: inherit; color: inherit; }
h1, h2, h3, h4 { margin: 0; font-family: var(--font-display); font-weight: 500; line-height: 1.02; letter-spacing: -0.035em; }

:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; border-radius: 2px; }
::selection { background: var(--accent); color: var(--bg); }

.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.skip-link {
  position: absolute; left: 16px; top: -64px; z-index: 300;
  padding: 12px 20px; border-radius: 999px;
  background: var(--accent); color: var(--bg); font-weight: 600; text-decoration: none;
  transition: top .2s;
}
.skip-link:focus { top: 16px; }

/* ---------- layout ---------- */
.shell { width: min(var(--shell-max), 100% - var(--gutter) * 2); margin-inline: auto; }
.section { padding-block: clamp(80px, 9vw, 180px); position: relative; }
.section + .section { padding-top: 0; }
/* An inverted band is its own block of colour, so it keeps padding on both sides. */
.section.invert + .section, .section.invert { padding-top: clamp(80px, 9vw, 180px); }
.section-head { margin-bottom: clamp(36px, 5vw, 72px); max-width: 62ch; }
.section-head-row { display: flex; align-items: flex-end; justify-content: space-between; gap: 32px; max-width: none; }
.section-head-center { max-width: none; text-align: center; }
.section-head-center .h1, .section-head-center .h2 { margin-inline: auto; }

/* ---------- type ---------- */
.display { font-size: clamp(2.8rem, 1.2rem + 6.4vw, 8rem); letter-spacing: -0.045em; line-height: 0.94; }
.h1 { font-size: clamp(2.1rem, 1.1rem + 3.4vw, 4.6rem); letter-spacing: -0.042em; line-height: 1; max-width: 20ch; }
.h2 { font-size: clamp(1.7rem, 1rem + 2.2vw, 3.1rem); letter-spacing: -0.038em; max-width: 24ch; }
.lead { margin-top: 20px; font-size: clamp(1rem, .93rem + .35vw, 1.25rem); line-height: 1.55; color: var(--ink-soft); max-width: 58ch; }
.eyebrow {
  margin: 0 0 16px; font-size: .74rem; font-weight: 600; letter-spacing: .16em;
  text-transform: uppercase; color: var(--accent);
}
.muted { color: var(--muted); }
.footnote { margin-top: 22px; font-size: .78rem; color: var(--muted); max-width: 60ch; }

/* ---------- buttons ---------- */
.btn {
  position: relative; display: inline-flex; align-items: center; justify-content: center; gap: 10px;
  height: 52px; padding: 0 28px; border: 1px solid transparent; border-radius: 999px;
  font-family: var(--font-body); font-size: .95rem; font-weight: 600; letter-spacing: -0.01em;
  text-decoration: none; white-space: nowrap; cursor: pointer;
  background: var(--panel-2); color: var(--ink);
  transition: background .3s var(--ease), color .3s var(--ease), border-color .3s var(--ease), transform .3s var(--ease);
}
.btn:disabled { opacity: .5; cursor: not-allowed; }
.btn { box-shadow: var(--shadow-sm); }
.btn-ghost { box-shadow: none; }
.btn-accent { background: var(--accent); color: var(--bg); }
/* Mixing toward --ink darkens the green on cream; .invert (where --ink IS the cream)
   mixes toward --bg instead, so the cream button still darkens on hover. */
.btn-accent:hover:not(:disabled) { background: color-mix(in srgb, var(--accent) 86%, var(--ink)); box-shadow: var(--shadow-md); }
.invert .btn-accent:hover:not(:disabled) { background: color-mix(in srgb, var(--accent) 86%, var(--bg)); }
.btn-accent:active:not(:disabled) { transform: translateY(1px); box-shadow: var(--shadow-sm); }
.btn-primary { background: var(--accent); color: var(--bg); }
.btn-ghost { background: transparent; border-color: var(--line); color: var(--ink); }
.btn-ghost:hover { border-color: var(--accent); color: var(--accent); background: color-mix(in srgb, var(--accent) 7%, transparent); }
.btn-sm { height: 42px; padding: 0 20px; font-size: .86rem; }
.btn-lg { height: 60px; padding: 0 34px; font-size: 1rem; }
.btn-block { width: 100%; }
.btn-row { display: flex; flex-wrap: wrap; gap: 14px; margin-top: 34px; }
.btn-price { opacity: .78; font-variant-numeric: tabular-nums; }
.btn-price:not(:empty)::before { content: "·"; margin-right: 8px; opacity: .6; }

.icon-btn {
  display: inline-grid; place-items: center; width: 44px; height: 44px; flex: none;
  border: 1px solid var(--line); border-radius: 50%; background: transparent; color: var(--ink);
  cursor: pointer; transition: background .25s, border-color .25s, opacity .25s, transform .25s;
}
.icon-btn:hover:not(:disabled) { background: color-mix(in srgb, var(--ink) 8%, transparent); border-color: var(--ink); }
.icon-btn:disabled { opacity: .3; cursor: default; }
.icon { width: 22px; height: 22px; flex: none; }

.tag {
  display: inline-flex; align-items: center; height: 30px; padding: 0 14px; border-radius: 999px;
  border: 1px solid var(--line); background: color-mix(in srgb, var(--bg) 60%, transparent);
  font-size: .72rem; font-weight: 600; letter-spacing: .12em; text-transform: uppercase; color: var(--ink);
  backdrop-filter: blur(8px);
}
.tag-float { position: absolute; top: 20px; left: 20px; z-index: 3; border-color: var(--accent); color: var(--accent); }

/* ---------- media ---------- */
.cover { width: 100%; height: 100%; object-fit: cover; }

/* Transparent uploads (cut-out GIF/PNG/WebP). Two things have to change together:
   the image is fitted rather than cropped, so none of the subject is sliced off,
   and the frame behind it stops painting a panel colour so the alpha channel
   actually shows the page through. :has() carries the second part to the parent
   frame; where it is unsupported the frame simply keeps its fill, which is the
   old behaviour rather than a broken one. */
.is-contain { object-fit: contain !important; }
.is-transparent { background: transparent !important; }
.buy-visual:has(> .is-transparent),
.tech-media:has(> .is-transparent),
.kit-media:has(> .is-transparent),
.step-media:has(> .is-transparent),
.story-tile:has(> .is-transparent),
.testimonial-media:has(> .is-transparent),
.ingredient-media:has(> .is-transparent),
.gallery-stage:has(.is-transparent),
.gallery-slide:has(> .is-transparent),
.related-media:has(> .is-transparent),
.review-photo:has(> .is-transparent) {
  background: transparent;
  box-shadow: none;
}
/* Padding only where the image is deliberately letterboxed. A detected-transparent
   file still fills its frame, so an opaque false positive is indistinguishable from
   the old behaviour. */
.buy-visual:has(> .is-contain),
.tech-media:has(> .is-contain),
.kit-media:has(> .is-contain) { padding: clamp(12px, 2.4vw, 34px); }
/* Any frame JS parallaxes gets its compositor layer at parse time. Creating one
   mid-scroll costs a raster pass and shows up as a stutter on the first wheel. */
[data-parallax] > * { will-change: transform; backface-visibility: hidden; }
/* A video that has not been asked to play yet holds its poster; without this the
   element is a transparent box while the first frame decodes. */
video[data-lazy-video] { background: var(--panel); }

/* ---------- grain + scroll progress ---------- */
.grain {
  position: fixed; inset: -50%; z-index: 400; pointer-events: none;
  /* Multiply so the noise only ever darkens: on a light ground a normal-blended
     noise plate greys the whole page out. */
  mix-blend-mode: multiply; opacity: .035;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.8' numOctaves='3'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='200' height='200' filter='url(%23n)'/%3E%3C/svg%3E");
}
html.motion .grain { animation: grainShift 1.1s steps(3) infinite; }
@keyframes grainShift {
  0% { transform: translate(0, 0); }
  33% { transform: translate(-2%, 1%); }
  66% { transform: translate(1%, -2%); }
  100% { transform: translate(0, 0); }
}

.scroll-progress { position: fixed; top: 0; left: 0; right: 0; height: 2px; z-index: 250; pointer-events: none; }
.scroll-progress span {
  display: block; height: 100%; width: 100%; background: var(--accent);
  transform: scaleX(0); transform-origin: 0 50%;
}

/* ---------- custom cursor ---------- */
.cursor { position: fixed; top: 0; left: 0; z-index: 500; pointer-events: none; opacity: 0; transition: opacity .3s; }
.cursor.is-ready { opacity: 1; }
.cursor-ring,
.cursor-dot { position: absolute; top: 0; left: 0; border-radius: 50%; transform: translate(-50%, -50%); }
.cursor-ring {
  width: 40px; height: 40px; border: 1px solid color-mix(in srgb, var(--ink) 55%, transparent);
  mix-blend-mode: difference;
  transition: width .32s var(--ease), height .32s var(--ease), background .32s var(--ease), border-color .32s var(--ease), opacity .3s;
}
.cursor-dot { width: 6px; height: 6px; background: var(--ink); mix-blend-mode: difference; transition: opacity .25s, transform .25s; }
.cursor-label {
  position: absolute; top: 0; left: 0; transform: translate(-50%, -50%) scale(.6);
  padding: 7px 14px; border-radius: 999px; background: var(--accent); color: var(--bg);
  font-size: .72rem; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; white-space: nowrap;
  opacity: 0; transition: opacity .28s var(--ease), transform .28s var(--ease);
}
.cursor.has-label .cursor-ring { width: 0; height: 0; opacity: 0; }
.cursor.has-label .cursor-dot { opacity: 0; }
.cursor.has-label .cursor-label { opacity: 1; transform: translate(-50%, -50%) scale(1); }
.cursor.is-hover .cursor-ring { width: 68px; height: 68px; background: color-mix(in srgb, var(--ink) 10%, transparent); }
.cursor.is-hover .cursor-dot { opacity: 0; }
.cursor.is-down .cursor-ring { width: 30px; height: 30px; }
html.cursor-on, html.cursor-on a, html.cursor-on button, html.cursor-on label, html.cursor-on [role="button"] { cursor: none; }
html.cursor-on input, html.cursor-on textarea, html.cursor-on select { cursor: auto; }

/* ---------- motion primitives ---------- */
.mask-line { display: block; overflow: hidden; padding-bottom: .08em; margin-bottom: -.08em; }
.mask-line > span { display: block; }

html.motion .mask-line > span {
  transform: translateY(110%);
  animation: maskUp 1s var(--ease-out) both;
  animation-delay: calc(.12s + var(--d, 0) * .1s);
}
@keyframes maskUp { to { transform: none; } }

html.motion .hero-fade {
  opacity: 0; transform: translateY(20px);
  animation: fadeUp .85s var(--ease-out) both;
  animation-delay: calc(.3s + var(--d, 0) * .08s);
}
@keyframes fadeUp { to { opacity: 1; transform: none; } }

html.motion [data-reveal] {
  opacity: 0; transform: translateY(30px);
  transition: opacity .9s var(--ease-out), transform .9s var(--ease-out);
}
html.motion [data-reveal].in { opacity: 1; transform: none; }

html.motion [data-reveal-item] {
  opacity: 0; transform: translateY(28px);
  transition: opacity .8s var(--ease-out), transform .8s var(--ease-out);
  transition-delay: calc(var(--i, 0) * 85ms);
}
html.motion [data-reveal-item].in { opacity: 1; transform: none; }

/* word-by-word mask reveal (spans are built by site.js) */
.word { display: inline-block; overflow: hidden; vertical-align: bottom; padding-bottom: .1em; margin-bottom: -.1em; }
.word > span { display: inline-block; }
html.motion [data-split] .word > span {
  transform: translateY(105%);
  transition: transform .9s var(--ease-out);
  transition-delay: calc(var(--i, 0) * 38ms);
}
html.motion [data-split].in .word > span { transform: none; }
html.motion [data-split].is-split { opacity: 1; transform: none; }

/* ---------- announcement + header ---------- */
.announcement {
  position: relative; z-index: 60;
  padding: 11px var(--gutter); text-align: center;
  background: var(--accent); color: var(--bg);
  font-size: .82rem; font-weight: 600; letter-spacing: -0.01em;
}
.announcement a { font-weight: 700; text-underline-offset: 3px; }

.site-header {
  position: sticky; top: 0; z-index: 90;
  transition: background .4s var(--ease), backdrop-filter .4s, border-color .4s;
  border-bottom: 1px solid transparent;
}
.site-header.is-scrolled {
  background: color-mix(in srgb, var(--bg) 86%, transparent);
  backdrop-filter: blur(14px) saturate(140%);
  border-bottom-color: var(--line-soft);
  box-shadow: 0 10px 30px -24px color-mix(in srgb, var(--ink) 45%, transparent);
}
.header-inner {
  display: flex; align-items: center; gap: clamp(16px, 3vw, 48px);
  height: var(--header-h); padding-inline: var(--gutter);
}
.logo {
  display: inline-flex; align-items: center; gap: 10px; text-decoration: none;
  font-family: var(--font-display); font-size: 1.3rem; font-weight: 600; letter-spacing: -0.04em;
}
.logo-mark { position: relative; width: 20px; height: 20px; border-radius: 7px; background: var(--accent); flex: none; }
.logo-mark::after { content: ""; position: absolute; inset: 5px 5px auto auto; width: 6px; height: 6px; border-radius: 50%; background: var(--bg); }

.main-nav { margin-left: auto; }
.main-nav ul { display: flex; gap: clamp(18px, 2vw, 36px); list-style: none; margin: 0; padding: 0; }
.main-nav a { position: relative; text-decoration: none; font-size: .9rem; color: var(--ink-soft); transition: color .25s; }
.main-nav a::after {
  content: ""; position: absolute; left: 0; bottom: -6px; width: 100%; height: 1px;
  background: var(--accent); transform: scaleX(0); transform-origin: 100% 50%;
  transition: transform .45s var(--ease);
}
.main-nav a:hover { color: var(--ink); }
.main-nav a:hover::after { transform: scaleX(1); transform-origin: 0 50%; }

.header-actions { display: flex; align-items: center; gap: 12px; }
.cart-btn { position: relative; }
.cart-count {
  position: absolute; top: -3px; right: -3px; min-width: 19px; height: 19px; padding: 0 5px;
  display: grid; place-items: center; border-radius: 999px;
  background: var(--accent); color: var(--bg); font-size: .74rem; font-weight: 700;
}
.menu-toggle { display: none; width: 44px; height: 44px; border: 0; background: none; cursor: pointer; }
.burger { display: grid; gap: 6px; justify-items: center; }
.burger span { display: block; width: 22px; height: 1.5px; background: var(--ink); transition: transform .35s var(--ease), opacity .25s; }
[aria-expanded="true"] .burger span:first-child { transform: translateY(3.75px) rotate(45deg); }
[aria-expanded="true"] .burger span:last-child { transform: translateY(-3.75px) rotate(-45deg); }

.mobile-menu {
  position: fixed; inset: var(--header-h) 0 0; z-index: 80;
  padding: 40px var(--gutter) 60px; background: var(--bg);
  overflow-y: auto;
}
.mobile-menu ul { list-style: none; margin: 0 0 32px; padding: 0; display: grid; gap: 4px; }
.mobile-menu a {
  display: block; padding: 14px 0; border-bottom: 1px solid var(--line-soft);
  font-family: var(--font-display); font-size: 2rem; letter-spacing: -0.04em; text-decoration: none;
}
html.motion .mobile-menu:not([hidden]) li { animation: fadeUp .5s var(--ease-out) both; animation-delay: calc(var(--i) * 60ms); }

/* ---------- hero ----------
   The media sits in an oversized frame (--bleed on each side) so the parallax
   shift can never expose an edge, and the frame is the ONLY element that gets a
   transform. The old build animated a CSS scale on the <video> while JS wrote a
   translate on its parent every frame — two competing transforms on a video layer,
   which is what made the footage judder. Now: one transform, one compositor layer,
   the drift folded into the same translate JS already writes. */
.hero {
  position: relative; min-height: 100svh; display: flex; align-items: flex-end;
  padding-block: calc(var(--header-h) + 40px) clamp(56px, 7vw, 110px);
  margin-top: calc(var(--header-h) * -1);
  overflow: clip;
  background: var(--bg);
  isolation: isolate;
}
.hero-media {
  --bleed: 14%;
  position: absolute; z-index: 0;
  inset: calc(var(--bleed) * -1) 0;
  /* Promote once, up front: a layer created mid-scroll is a visible hitch. */
  will-change: transform;
  transform: translate3d(0, 0, 0);
  backface-visibility: hidden;
}
.hero-media-el {
  width: 100%; height: 100%; object-fit: cover;
  /* Nudges the decoded frame onto whole pixels; without it a cover-scaled video
     resamples differently frame to frame and reads as a shimmer. */
  transform: translateZ(0);
  backface-visibility: hidden;
}
/* Fallback drift for no-JS / reduced-data: JS replaces it with the combined
   transform as soon as it takes over (see html.hero-js). */
html.motion .hero-media-el { animation: heroDrift 28s var(--ease) infinite alternate; }
html.motion.hero-js .hero-media-el { animation: none; }
@keyframes heroDrift { from { transform: scale(1.02) translateZ(0); } to { transform: scale(1.08) translateZ(0); } }

.hero-scrim {
  position: absolute; inset: 0; z-index: 1; pointer-events: none;
  /* Deliberately NOT a wash over the picture. Two narrow jobs only:
       1. a hairline fade at the very top, so the transparent header stays legible;
       2. a fade in the bottom strip where the headline sits, landing on solid --bg
          so the hero dissolves into the page with no seam.
     Everything between them is untouched footage. Mixed from --bg so re-theming
     from the admin still works; set Hero > Scrim strength to 0 to drop it entirely
     (the headline keeps its halo either way). */
  /* Kept so Home page > Hero > Scrim strength still works if the footage is ever
     swapped for something the headline cannot sit on. It is 0 by default, so
     nothing is drawn over the video. */
  background:
    linear-gradient(to top,
      color-mix(in srgb, var(--bg) 88%, transparent) 0%,
      color-mix(in srgb, var(--bg) 44%, transparent) 16%,
      color-mix(in srgb, var(--bg) 12%, transparent) 30%,
      transparent 42%);
  opacity: var(--overlay, 0);
}
.hero-inner { position: relative; z-index: 2; }
.hero-title {
  font-size: clamp(2.9rem, 1rem + 8.4vw, 10rem); letter-spacing: -0.05em; line-height: .9;
  font-weight: 500; color: var(--accent); text-wrap: balance;
}
/* Legibility now comes from the type, not from tinting the video. Centred rings of
   the page colour instead of an offset drop shadow, which smears at this size. */
.hero-title,
.hero-sub,
.hero .eyebrow,
.hero-badges,
.hero-cue {
  text-shadow:
    0 0 6px color-mix(in srgb, var(--bg) 92%, transparent),
    0 0 18px color-mix(in srgb, var(--bg) 82%, transparent),
    0 0 44px color-mix(in srgb, var(--bg) 66%, transparent),
    0 0 90px color-mix(in srgb, var(--bg) 46%, transparent);
}
/* The headline is the largest mark on bare footage, so it carries one more ring. */
.hero-title {
  text-shadow:
    0 0 8px color-mix(in srgb, var(--bg) 94%, transparent),
    0 0 26px color-mix(in srgb, var(--bg) 86%, transparent),
    0 0 64px color-mix(in srgb, var(--bg) 70%, transparent),
    0 0 130px color-mix(in srgb, var(--bg) 52%, transparent);
}
/* The header sits on bare footage too, and its links are only 0.9rem. */
.page-home .site-header:not(.is-scrolled) .logo,
.page-home .site-header:not(.is-scrolled) .main-nav a,
.page-home .site-header:not(.is-scrolled) .menu-toggle {
  text-shadow:
    0 0 8px color-mix(in srgb, var(--bg) 88%, transparent),
    0 0 22px color-mix(in srgb, var(--bg) 66%, transparent);
}
.hero-title .mask-line + .mask-line > span { color: color-mix(in srgb, var(--accent) 74%, var(--ink)); }
.hero-sub { margin-top: clamp(20px, 2.4vw, 32px); font-size: clamp(1.02rem, .95rem + .5vw, 1.32rem); color: var(--ink-soft); max-width: 46ch; }
.hero-ctas { display: flex; flex-wrap: wrap; gap: 14px; margin-top: clamp(28px, 3vw, 44px); }
.hero-badges {
  display: flex; flex-wrap: wrap; gap: 10px 28px; list-style: none; margin: clamp(30px, 3.4vw, 52px) 0 0; padding: 0;
  font-size: .78rem; font-weight: 600; letter-spacing: .1em; text-transform: uppercase; color: var(--muted);
}
.hero-badges li { display: flex; align-items: center; gap: 10px; }
.hero-badges li::before {
  content: ""; width: 5px; height: 5px; border-radius: 50%; background: var(--accent); flex: none;
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--bg) 46%, transparent);
}
/* --muted is tuned for the cream ground; over footage it loses too much. */
.hero-badges li { color: color-mix(in srgb, var(--ink) 88%, transparent); }

.hero-cue {
  position: absolute; z-index: 2; right: var(--gutter); bottom: clamp(56px, 7vw, 110px);
  display: grid; justify-items: center; gap: 12px;
  font-size: .7rem; font-weight: 600; letter-spacing: .18em; text-transform: uppercase; color: var(--muted);
  writing-mode: vertical-rl;
}
.hero-cue { color: var(--accent); }
.hero-cue i { display: block; width: 1px; height: 54px; background: linear-gradient(var(--accent), transparent); }
html.motion .hero-cue i { animation: cueSlide 2.2s var(--ease) infinite; transform-origin: 50% 0; }
@keyframes cueSlide { 0%, 100% { transform: scaleY(.35); opacity: .5; } 50% { transform: scaleY(1); opacity: 1; } }
@media (max-width: 860px) { .hero-cue { display: none; } }

/* ---------- marquee ---------- */
.marquee {
  position: relative; overflow: hidden; padding-block: clamp(18px, 2vw, 28px);
  border-block: 1px solid var(--line-soft); background: var(--panel);
}
.marquee-track { display: flex; width: max-content; }
html.motion .marquee-track { animation: marquee var(--speed, 42s) linear infinite; }
.marquee-group { display: flex; align-items: center; }
.marquee-item {
  padding-inline: clamp(20px, 2.4vw, 44px);
  font-family: var(--font-display); font-size: clamp(1.1rem, .9rem + 1vw, 1.9rem);
  letter-spacing: -0.03em; white-space: nowrap; color: var(--ink);
}
.marquee-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--accent); flex: none; }
@keyframes marquee { to { transform: translateX(-50%); } }

/* ---------- statement (pinned) ---------- */
.statement { position: relative; height: 200svh; }
.statement-stage {
  position: sticky; top: 0; height: 100svh; overflow: clip; display: grid; place-items: center;
  isolation: isolate; background: var(--bg);
}
.statement-media {
  position: absolute; inset: 0; z-index: 0;
  will-change: transform; transform: translate3d(0, 0, 0); backface-visibility: hidden;
}
.statement-media > img, .statement-media > video { width: 100%; height: 100%; object-fit: cover; transform: translateZ(0); }
/* A graded scrim rather than a text-shadow: shadowed type over moving footage
   smears, and the band has to work whatever frame is under it. */
.statement-stage::after {
  content: ""; position: absolute; inset: 0; z-index: 1; pointer-events: none;
  background:
    radial-gradient(120% 80% at 50% 55%, rgba(0, 0, 0, .58), rgba(0, 0, 0, .16) 62%, transparent 82%),
    linear-gradient(to top, rgba(0, 0, 0, .5), transparent 46%);
}
.statement-copy { position: relative; z-index: 2; text-align: center; display: grid; justify-items: center; }
.statement-copy .display { max-width: 18ch; }
.statement-copy .lead { margin-inline: auto; text-align: center; }

/* ---------- benefits ---------- */
.benefit-grid { display: grid; gap: 1px; background: var(--line-soft); border-block: 1px solid var(--line-soft); }
@media (min-width: 700px) { .benefit-grid { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1100px) { .benefit-grid { grid-template-columns: repeat(4, 1fr); } }
.benefit { position: relative; padding: clamp(28px, 3vw, 46px) clamp(22px, 2.4vw, 38px) clamp(36px, 4vw, 58px); background: var(--bg); }
.benefit-num { font-size: .72rem; font-weight: 600; letter-spacing: .16em; color: var(--muted); }
.benefit-icon {
  display: grid; place-items: center; width: 54px; height: 54px; margin: 26px 0 22px;
  border-radius: 50%; border: 1px solid color-mix(in srgb, var(--accent) 26%, transparent);
  background: color-mix(in srgb, var(--accent) 5%, transparent); color: var(--accent);
  transition: background .4s var(--ease), border-color .4s var(--ease), transform .4s var(--ease);
}
.benefit:hover .benefit-icon, .feature:hover .benefit-icon { background: var(--accent-soft); border-color: var(--accent); transform: translateY(-3px); }
.benefit h3, .feature h3 { font-size: 1.3rem; letter-spacing: -0.03em; margin-bottom: 10px; }
.benefit p, .feature p { color: var(--muted); font-size: .95rem; }

/* ---------- buy module ---------- */
.buy-grid { display: grid; gap: clamp(32px, 5vw, 80px); align-items: center; }
@media (min-width: 1000px) { .buy-grid { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); } }
.buy-visual { position: relative; aspect-ratio: 1; border-radius: var(--radius-lg); overflow: hidden; background: var(--panel); box-shadow: var(--shadow-lg); }
/* Only the media fills the frame — a blanket "> *" also inflated the floating
   badge into a full-size circle over the image. */
.buy-visual > img, .buy-visual > video { width: 100%; height: 100%; object-fit: cover; }
.buy-copy .lead { margin-bottom: 8px; }

.ticklist { display: grid; gap: 12px; list-style: none; margin: 30px 0 0; padding: 0; }
.ticklist li { display: flex; gap: 12px; align-items: flex-start; font-size: .98rem; color: var(--ink-soft); }
.ticklist .icon { width: 19px; height: 19px; margin-top: 3px; color: var(--accent); }

.buy { margin-top: 34px; }
.buy-options { display: grid; gap: 12px; border: 0; padding: 0; margin: 0 0 18px; }
.option { position: relative; display: block; cursor: pointer; }
.option input { position: absolute; inset: 0; width: 100%; height: 100%; margin: 0; opacity: 0; cursor: pointer; }
.option-body {
  display: flex; align-items: center; justify-content: space-between; gap: 18px;
  padding: 20px 24px; border: 1px solid var(--line); border-radius: var(--radius);
  background: var(--panel); transition: border-color .3s var(--ease), background .3s var(--ease);
}
.option-main { display: grid; gap: 4px; }
.option-label { display: flex; align-items: center; gap: 12px; font-weight: 600; }
.option-label::before {
  content: ""; width: 18px; height: 18px; border-radius: 50%; flex: none;
  border: 1px solid var(--line); transition: border-color .3s, box-shadow .3s, background .3s;
}
.option-desc { font-size: .85rem; color: var(--muted); padding-left: 30px; }
.option-price { text-align: right; white-space: nowrap; font-variant-numeric: tabular-nums; }
.option-price s { display: block; font-size: .82rem; color: var(--muted); }
.option-price strong { font-size: 1.22rem; font-weight: 600; letter-spacing: -0.02em; }
.option-price small { font-size: .78rem; color: var(--muted); font-weight: 500; }
.option-body { box-shadow: var(--shadow-sm); }
.option input:checked ~ .option-body {
  border-color: var(--accent); background: color-mix(in srgb, var(--accent) 7%, var(--panel));
  box-shadow: inset 0 0 0 1px var(--accent), var(--shadow-md);
}
.option input:checked ~ .option-body .option-label::before { border-color: var(--accent); background: var(--accent); box-shadow: inset 0 0 0 4px var(--bg); }
.option input:focus-visible ~ .option-body { outline: 2px solid var(--accent); outline-offset: 3px; }
.option:hover .option-body { border-color: color-mix(in srgb, var(--ink) 30%, transparent); }

.perks { display: grid; gap: 9px; list-style: none; margin: 22px 0 0; padding: 0; font-size: .86rem; color: var(--muted); }
.perks li { display: flex; align-items: center; gap: 10px; }
.perks li::before { content: ""; width: 5px; height: 5px; border-radius: 50%; background: var(--accent); flex: none; }

/* ---------- technology ---------- */
.tech-grid { display: grid; gap: clamp(32px, 5vw, 80px); align-items: center; }
@media (min-width: 1000px) { .tech-grid { grid-template-columns: minmax(0, 1fr) minmax(0, 1.05fr); } }
.tech-media { position: relative; aspect-ratio: 4 / 3; border-radius: var(--radius-lg); overflow: hidden; background: var(--panel); box-shadow: var(--shadow-lg); }
.tech-media > img, .tech-media > video { width: 100%; height: 100%; object-fit: cover; }

.metric { display: flex; align-items: flex-start; gap: 22px; margin-top: clamp(34px, 4vw, 54px); padding-top: 30px; border-top: 1px solid var(--line-soft); }
.metric-value { font-family: var(--font-display); font-size: clamp(3rem, 2rem + 4vw, 6rem); line-height: .9; letter-spacing: -0.05em; color: var(--accent); }
.metric-label { font-size: .92rem; color: var(--muted); max-width: 30ch; padding-top: 8px; }

.layers { display: grid; gap: 22px; list-style: none; margin: 34px 0 0; padding: 0; }
.layers li { display: flex; gap: 20px; padding-top: 22px; border-top: 1px solid var(--line-soft); }
.layer-num { font-size: .75rem; font-weight: 600; letter-spacing: .14em; color: var(--accent); padding-top: 4px; }
.layers h3 { font-size: 1.15rem; margin-bottom: 8px; letter-spacing: -0.025em; }
.layers p { color: var(--muted); font-size: .93rem; }

/* ---------- rails ---------- */
.rail { overflow: hidden; padding-inline: max(var(--gutter), (100% - var(--shell-max)) / 2); }
.rail-track {
  display: flex; gap: clamp(14px, 1.4vw, 22px); list-style: none; margin: 0; padding: 4px 0 24px;
  overflow-x: auto; scroll-snap-type: x mandatory; scrollbar-width: none;
  overscroll-behavior-x: contain;
}
.rail-track::-webkit-scrollbar { display: none; }
.rail-track > * { scroll-snap-align: start; flex: none; }
.rail-track.is-dragging { scroll-snap-type: none; }
.rail-track.is-dragging * { pointer-events: none; }
.rail-nav { display: flex; gap: 10px; flex: none; }
.rail-nav .icon-btn:first-child .icon { transform: rotate(180deg); }

.ingredient-card {
  width: clamp(260px, 25vw, 360px);
  background: var(--panel); border: 1px solid var(--line-soft); border-radius: var(--radius-lg); overflow: hidden;
  transition: border-color .4s var(--ease), transform .5s var(--ease);
}
.ingredient-card { box-shadow: var(--shadow-sm); }
.ingredient-card:hover { border-color: color-mix(in srgb, var(--accent) 45%, transparent); transform: translateY(-4px); box-shadow: var(--shadow-md); }
.ingredient-media { aspect-ratio: 1; overflow: hidden; }
.ingredient-media > img, .ingredient-media > video { width: 100%; height: 100%; object-fit: cover; transition: transform .8s var(--ease); }
.ingredient-card:hover .ingredient-media > * { transform: scale(1.05); }
.ingredient-body { padding: 24px 26px 30px; }
.ingredient-index { font-size: .72rem; font-weight: 600; letter-spacing: .16em; color: var(--accent); }
.ingredient-body h3 { margin: 14px 0 6px; font-size: 1.35rem; letter-spacing: -0.03em; }
.ingredient-amount { font-size: .82rem; font-weight: 600; letter-spacing: .1em; text-transform: uppercase; color: var(--muted); }
.ingredient-desc { margin-top: 12px; font-size: .92rem; color: var(--muted); }

.story-tile { width: clamp(240px, 24vw, 340px); aspect-ratio: 4 / 5; border-radius: var(--radius-lg); overflow: hidden; background: var(--panel); box-shadow: var(--shadow-sm); }
.story-tile > img, .story-tile > video { width: 100%; height: 100%; object-fit: cover; }
.story-quote { display: grid; align-content: center; gap: 18px; padding: clamp(26px, 2.6vw, 40px); border: 1px solid var(--line); background: var(--panel-2); }
.story-quote blockquote { margin: 0; }
.story-quote p { font-family: var(--font-display); font-size: clamp(1.3rem, 1.1rem + .6vw, 1.7rem); line-height: 1.16; letter-spacing: -0.03em; }
.story-quote cite { display: block; margin-top: 18px; font-size: .74rem; font-style: normal; font-weight: 600; letter-spacing: .14em; text-transform: uppercase; color: var(--accent); }

/* ---------- steps (stacking) ---------- */
.steps-stack { display: grid; gap: clamp(20px, 2.4vw, 32px); }
.step-card {
  position: sticky; top: calc(var(--header-h) + clamp(16px, 3vw, 48px) + var(--i) * 14px);
  display: grid; gap: clamp(24px, 3vw, 48px); align-items: center;
  padding: clamp(26px, 3vw, 52px); border: 1px solid var(--line-soft); border-radius: var(--radius-lg);
  /* These cards stack on top of one another, so the fill has to be opaque rather
     than a blur — a translucent card over the previous one turns to mud. */
  background: var(--panel); box-shadow: var(--shadow-lg);
}
@media (min-width: 900px) { .step-card { grid-template-columns: minmax(0, 1fr) minmax(0, .95fr); } }
.step-num { font-size: .74rem; font-weight: 600; letter-spacing: .16em; color: var(--accent); }
.step-copy h3 { margin: 18px 0 14px; font-size: clamp(1.6rem, 1.2rem + 1.4vw, 2.6rem); letter-spacing: -0.035em; }
.step-copy p { color: var(--muted); max-width: 44ch; }
.step-media { aspect-ratio: 4 / 3; border-radius: var(--radius); overflow: hidden; background: var(--bg); }
.step-media > img, .step-media > video { width: 100%; height: 100%; object-fit: cover; }

/* ---------- stats ---------- */
.stats-heading { margin-bottom: clamp(36px, 4vw, 64px); }
.stat-grid { display: grid; gap: 1px; margin: 0; background: var(--line-soft); border-block: 1px solid var(--line-soft); }
@media (min-width: 640px) { .stat-grid { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1000px) { .stat-grid { grid-template-columns: repeat(4, 1fr); } }
.stat { padding: clamp(28px, 3.4vw, 52px) clamp(20px, 2vw, 32px); background: var(--bg); }
.stat-value {
  font-family: var(--font-display); font-size: clamp(3rem, 2rem + 3.4vw, 5.4rem); line-height: .92;
  letter-spacing: -0.05em; color: var(--accent); font-variant-numeric: tabular-nums;
}
.stat-label { margin: 16px 0 0; font-size: .92rem; color: var(--muted); max-width: 24ch; }

/* ---------- testimonials ---------- */
.testimonial-grid { display: grid; gap: clamp(18px, 2vw, 30px); }
@media (min-width: 760px) { .testimonial-grid { grid-template-columns: repeat(3, 1fr); } }
.testimonial { margin: 0; display: grid; gap: 22px; }
.testimonial-media { position: relative; aspect-ratio: 4 / 5; border-radius: var(--radius-lg); overflow: hidden; background: var(--panel); box-shadow: var(--shadow-md); }
.testimonial-media > img, .testimonial-media > video { width: 100%; height: 100%; object-fit: cover; transition: transform .9s var(--ease); }
.testimonial:hover .testimonial-media > * { transform: scale(1.04); }
.play-btn {
  position: absolute; inset: 0; margin: auto; width: 68px; height: 68px;
  display: grid; place-items: center; border: 0; border-radius: 50%;
  background: color-mix(in srgb, var(--bg) 55%, transparent); color: var(--ink);
  backdrop-filter: blur(6px); cursor: pointer; transition: background .3s, transform .3s var(--ease);
}
.play-btn:hover { background: var(--accent); color: var(--bg); transform: scale(1.06); }
.testimonial blockquote { margin: 0; }
.testimonial blockquote p { font-family: var(--font-display); font-size: 1.25rem; line-height: 1.24; letter-spacing: -0.025em; }
.testimonial figcaption { display: flex; flex-wrap: wrap; gap: 4px 12px; align-items: baseline; font-size: .85rem; }
.testimonial figcaption span { color: var(--muted); }

/* ---------- accordion ---------- */
.faq-grid { display: grid; gap: clamp(28px, 4vw, 64px); align-items: start; }
@media (min-width: 1000px) {
  .faq-grid { grid-template-columns: minmax(0, .8fr) minmax(0, 1.2fr); }
  .faq-grid .section-head { position: sticky; top: calc(var(--header-h) + 40px); margin-bottom: 0; }
}
.accordion { border-top: 1px solid var(--line-soft); }
.accordion-item { border-bottom: 1px solid var(--line-soft); }
.accordion-item h3 { margin: 0; font: inherit; }
.accordion-trigger {
  width: 100%; display: flex; align-items: center; justify-content: space-between; gap: 24px;
  padding: clamp(20px, 2.2vw, 30px) 0; border: 0; background: none; text-align: left; cursor: pointer;
  font-family: var(--font-display); font-size: clamp(1.1rem, 1rem + .6vw, 1.5rem); letter-spacing: -0.03em;
  transition: color .3s;
}
.accordion-trigger:hover { color: var(--accent); }
.accordion-sign { position: relative; width: 18px; height: 18px; flex: none; }
.accordion-sign::before, .accordion-sign::after {
  content: ""; position: absolute; top: 50%; left: 0; width: 100%; height: 1.5px; background: currentColor;
  transition: transform .4s var(--ease);
}
.accordion-sign::after { transform: rotate(90deg); }
[aria-expanded="true"] .accordion-sign::after { transform: rotate(0); }
.accordion-panel { overflow: hidden; }
.accordion-panel p { padding-bottom: clamp(22px, 2.4vw, 32px); color: var(--muted); max-width: 70ch; }
html.motion .accordion-panel { transition: height .45s var(--ease); }

/* ---------- final cta ---------- */
.final-cta {
  position: relative; min-height: 92svh; display: grid; place-items: center;
  overflow: clip; text-align: center; isolation: isolate; background: var(--bg);
}
.final-media {
  position: absolute; inset: -10% 0; z-index: 0;
  will-change: transform; transform: translate3d(0, 0, 0); backface-visibility: hidden;
}
.final-media > img, .final-media > video { width: 100%; height: 100%; object-fit: cover; transform: translateZ(0); }
.final-scrim {
  position: absolute; inset: 0; z-index: 1; pointer-events: none;
  background:
    radial-gradient(110% 75% at 50% 58%, rgba(0, 0, 0, .56), rgba(0, 0, 0, .18) 64%, transparent 84%),
    linear-gradient(to top, rgba(0, 0, 0, .58), rgba(0, 0, 0, .14) 52%, rgba(0, 0, 0, 0) 86%);
}
.final-inner { position: relative; z-index: 2; display: grid; justify-items: center; padding-block: clamp(80px, 10vw, 140px); }
.final-inner .display { max-width: 16ch; }
.final-inner .lead { text-align: center; margin-inline: auto; }
.final-inner > div { margin-top: 36px; }

/* ---------- footer ---------- */
.site-footer { border-top: 1px solid var(--line-soft); background: var(--panel); }
.footer-top { display: grid; gap: clamp(44px, 6vw, 90px); padding-block: clamp(60px, 7vw, 110px); }
@media (min-width: 1000px) { .footer-top { grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); } }
.footer-heading { margin-top: 28px; font-size: clamp(1.8rem, 1.3rem + 2vw, 3rem); letter-spacing: -0.04em; }
.footer-body { margin-top: 14px; color: var(--muted); max-width: 42ch; }
.newsletter { display: flex; flex-wrap: wrap; gap: 10px; max-width: 480px; margin-top: 28px; }
.newsletter input {
  flex: 1 1 220px; min-width: 0; height: 52px; padding: 0 22px; border-radius: 999px;
  border: 1px solid var(--line); background: transparent; color: var(--ink); font: inherit;
  transition: border-color .25s;
}
.newsletter input::placeholder { color: var(--muted); }
.newsletter input:focus { outline: none; border-color: var(--accent); }
.form-msg { flex-basis: 100%; min-height: 1.3em; font-size: .85rem; }
.form-msg.is-error { color: var(--danger); }
.form-msg.is-success { color: var(--accent); }

.footer-cols { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 40px 24px; }
@media (min-width: 720px) { .footer-cols { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
.footer-col h3 { margin-bottom: 20px; font-family: var(--font-body); font-size: .72rem; font-weight: 600; letter-spacing: .16em; text-transform: uppercase; color: var(--muted); }
.footer-col ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 12px; }
.footer-col a { font-size: .93rem; text-decoration: none; color: var(--ink-soft); transition: color .25s; }
.footer-col a:hover { color: var(--accent); }
.footer-bottom { display: grid; gap: 14px; padding-block: 30px 46px; border-top: 1px solid var(--line-soft); font-size: .78rem; color: var(--muted); }
.disclaimer { max-width: 90ch; }
.page-product .footer-bottom, .page-home .footer-bottom { padding-bottom: 120px; }

/* ---------- cart drawer ---------- */
/* Dim toward --ink: on a cream page a --bg-tinted veil dims nothing at all. */
.drawer-backdrop { position: fixed; inset: 0; z-index: 190; background: color-mix(in srgb, var(--ink) 38%, transparent); backdrop-filter: blur(5px); opacity: 0; transition: opacity .4s var(--ease); }
.drawer-backdrop.is-open { opacity: 1; }
.cart-drawer {
  position: fixed; top: 0; right: 0; bottom: 0; z-index: 200; width: min(460px, 100%);
  display: flex; flex-direction: column; background: var(--bg); border-left: 1px solid var(--line-soft);
  box-shadow: -30px 0 70px -40px color-mix(in srgb, var(--ink) 50%, transparent);
  transform: translateX(100%); visibility: hidden;
  transition: transform .5s var(--ease), visibility 0s linear .5s;
}
.cart-drawer.is-open { transform: none; visibility: visible; transition: transform .5s var(--ease), visibility 0s; }
.cart-drawer:focus { outline: none; }
.cart-head { display: flex; align-items: center; justify-content: space-between; padding: 22px 20px 22px 28px; border-bottom: 1px solid var(--line-soft); }
.cart-head h2 { font-size: 1.4rem; }
.cart-perk { padding: 11px 28px; background: var(--accent); color: var(--bg); font-size: .78rem; font-weight: 600; text-align: center; }
.cart-body { flex: 1; overflow-y: auto; padding: 6px 28px; }
.cart-body:empty { display: none; }
.cart-line { display: grid; grid-template-columns: 82px minmax(0, 1fr) auto; gap: 16px; padding: 22px 0; border-bottom: 1px solid var(--line-soft); }
.cart-line-media { width: 82px; height: 82px; border-radius: var(--radius-sm); object-fit: cover; background: var(--bg); }
.cart-line-name { font-weight: 600; text-decoration: none; }
.cart-line-name:hover { color: var(--accent); }
.cart-line-opt { margin-top: 3px; font-size: .82rem; color: var(--muted); }
.cart-line-right { display: flex; flex-direction: column; align-items: flex-end; justify-content: space-between; font-variant-numeric: tabular-nums; }
.cart-remove { border: 0; background: none; padding: 0; color: var(--muted); font-size: .78rem; text-decoration: underline; cursor: pointer; }
.cart-remove:hover { color: var(--danger); }
.qty { display: inline-flex; align-items: center; height: 38px; margin-top: 14px; border: 1px solid var(--line); border-radius: 999px; }
.qty button { width: 36px; height: 36px; border: 0; border-radius: 50%; background: none; font-size: 1.05rem; cursor: pointer; }
.qty button:hover { color: var(--accent); }
.qty span { min-width: 26px; text-align: center; font-size: .9rem; font-weight: 600; }
.cart-empty { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 20px; padding: 24px; color: var(--muted); }
.cart-foot { display: grid; gap: 12px; padding: 24px 28px 32px; border-top: 1px solid var(--line-soft); }
.cart-subtotal { display: flex; justify-content: space-between; font-size: 1.05rem; font-variant-numeric: tabular-nums; }
.cart-note { font-size: .78rem; color: var(--muted); }

/* ---------- video modal ---------- */
.modal { position: fixed; inset: 0; z-index: 220; display: grid; place-items: center; padding: 72px 20px 20px; }
/* Video wants a genuinely dark surround whichever way the theme runs. */
.modal-backdrop { position: absolute; inset: 0; background: color-mix(in srgb, var(--ink) 88%, #000); backdrop-filter: blur(6px); }
.modal-dialog { position: relative; width: min(1100px, 100%); }
.modal-close { position: absolute; right: 0; top: -58px; }
.modal-video video, .modal-video iframe { display: block; width: 100%; aspect-ratio: 16 / 9; max-height: 78vh; border: 0; border-radius: var(--radius); background: #000; }

/* ---------- sticky add to cart ---------- */
.sticky-atc {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 85;
  padding: 14px 0 max(14px, env(safe-area-inset-bottom));
  background: color-mix(in srgb, var(--bg) 88%, transparent); backdrop-filter: blur(16px);
  border-top: 1px solid var(--line-soft);
  transform: translateY(110%); transition: transform .5s var(--ease);
}
.sticky-atc.is-visible { transform: none; }
.sticky-atc-inner { display: flex; align-items: center; justify-content: space-between; gap: 20px; }
.sticky-atc-info { display: grid; gap: 2px; min-width: 0; }
.sticky-atc-name { font-weight: 600; letter-spacing: -0.02em; }
.sticky-atc-opt { font-size: .82rem; color: var(--muted); }
@media (max-width: 560px) { .sticky-atc-info { display: none; } .sticky-atc .btn { width: 100%; } }

/* ---------- product page ---------- */
.product-hero { padding-top: clamp(24px, 4vw, 48px); padding-bottom: clamp(60px, 7vw, 120px); }
.breadcrumb { padding-block: 10px 28px; font-size: .82rem; color: var(--muted); }
.breadcrumb ol { display: flex; flex-wrap: wrap; gap: 8px; list-style: none; margin: 0; padding: 0; }
.breadcrumb li + li::before { content: "/"; margin-right: 8px; opacity: .5; }
.breadcrumb a { text-decoration: none; }
.breadcrumb a:hover { color: var(--accent); }
.breadcrumb [aria-current] { color: var(--ink); }

.product-grid { display: grid; gap: clamp(28px, 4vw, 72px); align-items: start; }
@media (min-width: 1000px) {
  .product-grid { grid-template-columns: minmax(0, 1.1fr) minmax(0, .9fr); }
  .product-info { position: sticky; top: calc(var(--header-h) + 32px); }
}

.gallery-stage { position: relative; border-radius: var(--radius-lg); overflow: hidden; background: var(--panel); box-shadow: var(--shadow-lg); }
.gallery-track { display: flex; overflow-x: auto; scroll-snap-type: x mandatory; scrollbar-width: none; }
.gallery-track::-webkit-scrollbar { display: none; }
.gallery-slide { flex: none; width: 100%; aspect-ratio: 1; scroll-snap-align: start; }
.gallery-slide > img, .gallery-slide > video { width: 100%; height: 100%; object-fit: cover; }
.gallery-nav { position: absolute; inset: auto 20px 20px auto; display: flex; gap: 10px; z-index: 3; }
.gallery-nav .icon-btn { background: color-mix(in srgb, var(--bg) 62%, transparent); backdrop-filter: blur(8px); }
.gallery-nav .icon-btn:first-child .icon { transform: rotate(180deg); }
.gallery-thumbs { display: flex; gap: 12px; margin-top: 14px; overflow-x: auto; scrollbar-width: none; }
.gallery-thumbs::-webkit-scrollbar { display: none; }
.gallery-thumb {
  flex: none; width: 88px; aspect-ratio: 1; padding: 0; overflow: hidden; cursor: pointer;
  border: 1px solid var(--line-soft); border-radius: var(--radius-sm); background: var(--panel);
  transition: border-color .3s, opacity .3s; opacity: .55;
}
.gallery-thumb > img, .gallery-thumb > video { width: 100%; height: 100%; object-fit: cover; }
.gallery-thumb[aria-current="true"] { border-color: var(--accent); opacity: 1; }

.product-meta { display: flex; align-items: center; gap: 14px; font-size: .8rem; letter-spacing: .1em; text-transform: uppercase; }
.product-title { margin: 20px 0 16px; font-size: clamp(2.4rem, 1.6rem + 2.6vw, 4.2rem); letter-spacing: -0.045em; }
.rating { display: flex; align-items: center; gap: 12px; font-size: .88rem; }
.rating a { color: var(--muted); text-underline-offset: 3px; }
.rating a:hover { color: var(--accent); }
.stars { position: relative; display: inline-block; font-size: 1rem; letter-spacing: 2px; line-height: 1; color: var(--line); }
.stars-fill { position: absolute; inset: 0; overflow: hidden; color: var(--accent); white-space: nowrap; }

.feature-grid { display: grid; gap: 1px; background: var(--line-soft); border-block: 1px solid var(--line-soft); }
@media (min-width: 700px) { .feature-grid { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1100px) { .feature-grid { grid-template-columns: repeat(4, 1fr); } }
.feature { padding: clamp(28px, 3vw, 46px) clamp(22px, 2.4vw, 38px) clamp(36px, 4vw, 58px); background: var(--bg); }
.feature .benefit-icon { margin-top: 0; }

.split-grid { display: grid; gap: clamp(28px, 4vw, 72px); align-items: start; }
@media (min-width: 1000px) {
  .split-grid { grid-template-columns: minmax(0, .8fr) minmax(0, 1.2fr); }
  .split-grid .section-head { position: sticky; top: calc(var(--header-h) + 40px); margin-bottom: 0; }
}
.spec-list { margin: 0; border-top: 1px solid var(--line-soft); }
.spec { padding: clamp(20px, 2.2vw, 28px) 0; border-bottom: 1px solid var(--line-soft); }
.spec dt { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: 12px; font-family: var(--font-display); font-size: 1.25rem; letter-spacing: -0.03em; }
.spec-amount { font-family: var(--font-body); font-size: .8rem; font-weight: 600; letter-spacing: .1em; text-transform: uppercase; color: var(--accent); }
.spec dd { margin: 10px 0 0; color: var(--muted); font-size: .95rem; max-width: 62ch; }

.compare-wrap { overflow-x: auto; border: 1px solid var(--line-soft); border-radius: var(--radius-lg); box-shadow: var(--shadow-sm); }
.compare { width: 100%; border-collapse: collapse; min-width: 560px; }
.compare th, .compare td { padding: clamp(16px, 1.8vw, 24px) clamp(16px, 2vw, 28px); text-align: left; border-bottom: 1px solid var(--line-soft); }
.compare thead th { font-family: var(--font-body); font-size: .74rem; font-weight: 600; letter-spacing: .14em; text-transform: uppercase; color: var(--muted); }
.compare tbody th { font-weight: 500; font-family: var(--font-body); font-size: .96rem; }
.compare td { text-align: center; color: var(--muted); font-size: .92rem; }
.compare tr:last-child th, .compare tr:last-child td { border-bottom: 0; }
.compare-ours { text-align: center; background: color-mix(in srgb, var(--accent) 6%, transparent); color: var(--ink); }
thead .compare-ours { color: var(--accent); }
.mark { display: inline-grid; place-items: center; width: 30px; height: 30px; border-radius: 50%; }
.mark .icon { width: 18px; height: 18px; }
.mark-yes { background: var(--accent-soft); color: var(--accent); }
.mark-no { background: color-mix(in srgb, var(--ink) 8%, transparent); color: var(--muted); }

.kit-grid { display: grid; gap: clamp(32px, 5vw, 80px); align-items: center; }
@media (min-width: 1000px) { .kit-grid { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); } }
.kit-media { aspect-ratio: 4 / 3; border-radius: var(--radius-lg); overflow: hidden; background: var(--panel); box-shadow: var(--shadow-lg); }
.kit-media > img, .kit-media > video { width: 100%; height: 100%; object-fit: cover; }

.badge-grid { display: flex; flex-wrap: wrap; justify-content: center; gap: 12px; list-style: none; margin: 0; padding: 0; }
.badge-grid li {
  padding: 12px 22px; border: 1px solid var(--line); border-radius: 999px;
  font-size: .86rem; color: var(--ink-soft); transition: border-color .3s, color .3s;
}
.badge-grid li:hover { border-color: var(--accent); color: var(--accent); }

.reviews-grid { display: grid; gap: clamp(30px, 4vw, 64px); align-items: start; }
@media (min-width: 1000px) {
  .reviews-grid { grid-template-columns: minmax(0, .75fr) minmax(0, 1.25fr); }
  .reviews-summary { position: sticky; top: calc(var(--header-h) + 40px); }
}
.reviews-score { display: grid; gap: 10px; margin-top: 30px; }
.reviews-score strong { font-family: var(--font-display); font-size: 3.4rem; line-height: 1; letter-spacing: -0.04em; color: var(--accent); }
.review-list { display: grid; gap: 1px; background: var(--line-soft); border-block: 1px solid var(--line-soft); }
.review { padding: clamp(24px, 2.6vw, 38px) 0 clamp(28px, 3vw, 42px); background: var(--bg); }
.review h3 { margin: 14px 0 10px; font-size: 1.2rem; letter-spacing: -0.025em; }
.review p { color: var(--ink-soft); max-width: 70ch; }
.review footer { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 18px; margin-top: 18px; font-size: .84rem; color: var(--muted); }
.verified { display: inline-flex; align-items: center; gap: 6px; color: var(--accent); }
.verified .icon { width: 15px; height: 15px; }

.related-grid { display: grid; gap: clamp(16px, 2vw, 26px); }
@media (min-width: 760px) { .related-grid { grid-template-columns: repeat(3, 1fr); } }
.related-card { text-decoration: none; border: 1px solid var(--line-soft); border-radius: var(--radius-lg); overflow: hidden; background: var(--panel); transition: border-color .35s, transform .45s var(--ease); }
.related-card { box-shadow: var(--shadow-sm); }
.related-card:hover { border-color: var(--accent); transform: translateY(-4px); box-shadow: var(--shadow-md); }
.related-media { aspect-ratio: 1; overflow: hidden; }
.related-media > img, .related-media > video { width: 100%; height: 100%; object-fit: cover; }
.related-body { padding: 22px 24px 28px; }
.related-body h3 { font-size: 1.2rem; margin-bottom: 8px; }
.related-body p { font-size: .9rem; color: var(--muted); }

/* ---------- 404 ---------- */
.notfound { display: grid; place-items: center; min-height: 72svh; padding-block: clamp(60px, 10vw, 140px); text-align: center; }
.notfound-inner { display: grid; justify-items: center; }
.notfound .lead { margin-inline: auto; }

/* ---------- checkout ---------- */
.checkout-header { border-bottom: 1px solid var(--line-soft); background: var(--bg); }
.checkout-header-inner { display: flex; align-items: center; justify-content: space-between; gap: 16px; height: var(--header-h); }
.checkout-secure { display: inline-flex; align-items: center; gap: 8px; font-size: .82rem; font-weight: 600; color: var(--muted); }
.checkout-back { font-size: .86rem; color: var(--muted); text-decoration: none; }
.checkout-back:hover { color: var(--accent); }
@media (max-width: 640px) { .checkout-secure { display: none; } }

.checkout-main { min-height: calc(100svh - var(--header-h) - 80px); padding-block: clamp(32px, 4vw, 64px) clamp(60px, 7vw, 100px); }
.checkout-container { width: min(1160px, 100% - var(--gutter) * 2); margin-inline: auto; }
.checkout-test-banner {
  margin-bottom: 26px; padding: 12px 18px; border-radius: var(--radius-sm);
  border: 1px solid color-mix(in srgb, var(--accent) 40%, transparent);
  background: color-mix(in srgb, var(--accent) 10%, transparent);
  font-size: .86rem; color: var(--ink);
}
.checkout-step-head { margin-bottom: clamp(22px, 3vw, 34px); }
.checkout-step-head-row { display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: space-between; gap: 16px; }
.checkout-title { font-size: clamp(1.9rem, 1.4rem + 2vw, 3rem); letter-spacing: -0.04em; }
.checkout-title:focus { outline: none; }
.checkout-grid { display: grid; gap: 22px; align-items: start; }
@media (min-width: 900px) { .checkout-grid { grid-template-columns: minmax(0, 1fr) 390px; } .checkout-summary { position: sticky; top: 24px; } }
.checkout-card { background: var(--panel); border: 1px solid var(--line-soft); border-radius: var(--radius-lg); padding: clamp(20px, 2.4vw, 30px); box-shadow: var(--shadow-sm); }
.checkout-lines .cart-line:first-child { padding-top: 0; }
.checkout-lines .cart-line:last-child { padding-bottom: 0; border-bottom: 0; }
.checkout-empty { display: grid; justify-items: start; gap: 18px; color: var(--muted); }
.checkout-summary { display: grid; gap: 16px; }
.checkout-summary-title { font-size: 1.3rem; }
.checkout-totals { display: grid; gap: 10px; margin: 0; }
.checkout-totals div { display: flex; justify-content: space-between; gap: 16px; font-size: .94rem; }
.checkout-totals dt { color: var(--muted); }
.checkout-totals dd { margin: 0; font-weight: 500; text-align: right; font-variant-numeric: tabular-nums; }
.checkout-totals .is-total { padding-top: 14px; border-top: 1px solid var(--line-soft); font-size: 1.1rem; }
.checkout-totals .is-total dt { color: var(--ink); }
.checkout-totals .is-total dd { font-weight: 600; }
.checkout-recurring { padding: 12px 16px; border-radius: var(--radius-sm); background: var(--accent-soft); color: var(--accent); font-size: .84rem; font-weight: 500; }
.checkout-summary .form-msg { min-height: 0; text-align: center; }
.checkout-summary .form-msg:empty { display: none; }
.checkout-perks { display: grid; gap: 9px; margin: 0; padding: 0; list-style: none; font-size: .84rem; color: var(--muted); }
.checkout-perks li { display: flex; align-items: flex-start; gap: 10px; }
.checkout-perks li::before { content: ""; flex: none; width: 6px; height: 6px; margin-top: .55em; border-radius: 50%; background: var(--accent); }
.checkout-note { font-size: .8rem; color: var(--muted); }
.checkout-mini { display: flex; align-items: center; gap: 14px; font-size: .9rem; }
.link-btn { padding: 0; border: 0; background: none; color: var(--ink); font-weight: 600; text-decoration: underline; cursor: pointer; }
.link-btn:hover { color: var(--accent); }
.checkout-stripe { position: relative; min-height: 460px; padding: clamp(10px, 1.5vw, 18px); background: var(--surface); }
.checkout-loading { position: absolute; inset: 0; display: grid; place-items: center; color: var(--muted); font-size: .92rem; }
.checkout-footer { padding-block: 26px; border-top: 1px solid var(--line-soft); font-size: .8rem; color: var(--muted); }
.checkout-confirm { max-width: 760px; }
.confirm-icon { display: grid; place-items: center; width: 60px; height: 60px; margin-bottom: 26px; border-radius: 50%; background: var(--accent); color: var(--bg); }
.checkout-confirm .lead { max-width: 52ch; }
.confirm-card { display: grid; gap: 22px; margin-top: 34px; }
.confirm-line { display: flex; justify-content: space-between; gap: 16px; padding-block: 14px; border-bottom: 1px solid var(--line-soft); }
.confirm-line:first-child { padding-top: 0; }
.confirm-line span { display: block; font-size: .85rem; color: var(--muted); }
.confirm-address { font-size: .92rem; color: var(--ink-soft); }
.confirm-address h2 { margin-bottom: 10px; font-family: var(--font-body); font-size: .72rem; font-weight: 600; letter-spacing: .16em; text-transform: uppercase; color: var(--muted); }

/* the checkout views still use the older .container name */
.container { width: min(var(--shell-max), 100% - var(--gutter) * 2); margin-inline: auto; }

/* ---------- responsive ---------- */
@media (max-width: 1023px) {
  .main-nav { display: none; }
  .menu-toggle { display: grid; place-items: center; }
  .header-inner > .logo { margin-right: auto; }
}
@media (min-width: 1024px) { .mobile-menu { display: none !important; } }
@media (max-width: 860px) {
  /* The hero holds eyebrow + headline + sub + two buttons + badges. At phone
     widths that stack is taller than the viewport, so trim the vertical rhythm
     rather than letting the section grow past 100svh and swallow the page. */
  .hero { padding-bottom: clamp(36px, 8vw, 56px); }
  .hero-sub { margin-top: 16px; max-width: 34ch; }
  .hero-ctas { margin-top: 24px; gap: 10px; }
  .hero-badges { margin-top: 24px; gap: 8px 20px; font-size: .72rem; }
  /* Full-width buttons beat two half-width ones that wrap unevenly. */
  .hero-ctas .btn { flex: 1 1 100%; }
}
@media (max-width: 620px) {
  .header-cta { display: none; }
  .btn-lg { height: 54px; padding: 0 26px; }
  .option-body { padding: 16px 18px; }
  .statement { height: 170svh; }
  /* A 220svh pinned band on a phone is three screens of the same frame. */
  .final-cta { min-height: 86svh; }
  .hero-badges li { font-size: .76rem; }
}
@media (max-width: 400px) {
  /* Long badge strings ("Third-party tested") wrap into the buttons below. */
  .hero-badges { display: grid; gap: 7px; }
}

/* Save-Data / reduced-data: site.js refuses to start any video, so the poster is
   what the visitor actually sees — make sure it fills the frame the same way. */
@media (prefers-reduced-data: reduce) {
  html.motion .hero-media-el { animation: none; }
  .hero-media { transform: none !important; }
}

/* ---------- reduced motion ---------- */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
    scroll-behavior: auto !important;
  }
  .hero-media-el, .grain { animation: none !important; }
  .statement { height: auto; }
  .statement-stage { position: relative; height: auto; min-height: 80svh; padding-block: 80px; }
  .step-card { position: relative; top: auto; }
}

/* ==================================================================
   MOTION LAYER
   Reactive hovers, the horizontal testimonial strip and the particle brand
   wordmark. Every rule is token-driven (so the admin palette still controls
   it) and every animation is gated on html.motion, so reduced-motion and
   no-JS visitors get a plain, fully readable page. Appended last so it wins
   the cascade without editing the rules above.

   Note: the velocity-driven "elastic" scroll response that used to live here
   (skewing media frames and squashing the grids as you scrolled) was removed
   on request. Entrance reveals are unaffected — those fire once when an
   element arrives rather than tracking the scroll.
   ================================================================== */

/* ---------- GPU hints, kept deliberately narrow ---------- */
html.motion [data-hscroll-track] { will-change: transform; }


/* ---------- eyebrows draw their own rule ---------- */
.eyebrow { display: flex; align-items: center; gap: 14px; }
.eyebrow::after {
  content: ""; flex: 0 1 92px; height: 1px; background: currentColor; opacity: .38;
  transform-origin: 0 50%;
}
.section-head-center .eyebrow, .final-inner .eyebrow { justify-content: center; }
html.motion .eyebrow[data-reveal]::after { transform: scaleX(0); transition: transform .9s var(--ease-out) .2s; }
html.motion .eyebrow[data-reveal].in::after { transform: scaleX(1); }

/* ---------- buttons: a fill that sweeps up, and a real press ---------- */
.btn { overflow: hidden; isolation: isolate; }
.btn::before {
  content: ""; position: absolute; inset: -1px; z-index: -1; border-radius: inherit;
  transform: translateY(101%); transition: transform .55s var(--ease);
}
.btn-accent::before, .btn-primary::before, .btn-ghost::before { background: var(--ink); }
.btn-accent:hover:not(:disabled), .btn-primary:hover:not(:disabled) { background: var(--accent); color: var(--bg); }
.btn-ghost:hover:not(:disabled) { color: var(--bg); border-color: var(--ink); background: transparent; }
.btn:hover:not(:disabled)::before { transform: translateY(0); }
.btn:active:not(:disabled) { transform: scale(.975); }
/* Label and price ride above the sweeping fill. */
.btn > * { position: relative; }

.icon-btn .icon { transition: transform .45s var(--ease); }
.icon-btn:hover:not(:disabled) .icon { transform: scale(1.12); }
.rail-nav .icon-btn:first-child:hover:not(:disabled) .icon,
.gallery-nav .icon-btn:first-child:hover:not(:disabled) .icon { transform: rotate(180deg) scale(1.12); }

/* ---------- link sweep, reusing the main-nav idiom everywhere ---------- */
.footer-col a, .breadcrumb a, .rating a, .cart-line-name, .checkout-back {
  position: relative; text-decoration: none;
}
.footer-col a::after, .breadcrumb a::after, .rating a::after,
.cart-line-name::after, .checkout-back::after {
  content: ""; position: absolute; left: 0; bottom: -3px; width: 100%; height: 1px;
  background: currentColor; transform: scaleX(0); transform-origin: 100% 50%;
  transition: transform .45s var(--ease);
}
.footer-col a:hover::after, .breadcrumb a:hover::after, .rating a:hover::after,
.cart-line-name:hover::after, .checkout-back:hover::after { transform: scaleX(1); transform-origin: 0 50%; }

/* ---------- accordion rows light up and the sign spins ---------- */
.accordion-item { position: relative; }
.accordion-item::before {
  content: ""; position: absolute; inset: 0 -18px; z-index: 0; pointer-events: none;
  background: var(--panel-2); opacity: 0; transition: opacity .4s var(--ease);
}
.accordion-item:hover::before { opacity: 1; }
.accordion-trigger, .accordion-panel { position: relative; z-index: 1; }
.accordion-sign { transition: transform .5s var(--ease); }
.accordion-trigger[aria-expanded="false"]:hover .accordion-sign { transform: rotate(90deg); }

/* ---------- cards react to the cursor: tilt + a soft spotlight ---------- */
[data-tilt] { position: relative; }
[data-tilt]::after {
  content: ""; position: absolute; inset: 0; z-index: 4; pointer-events: none; border-radius: inherit;
  background: radial-gradient(260px circle at var(--mx, 50%) var(--my, 50%),
    color-mix(in srgb, var(--accent) 20%, transparent), transparent 68%);
  opacity: 0; transition: opacity .45s var(--ease);
}
[data-tilt].is-live::after { opacity: 1; }
html.motion [data-tilt] { transition: transform .6s var(--ease), border-color .4s var(--ease); }
html.motion [data-tilt].is-live { transition-duration: .18s; }

/* ---------- grid cells draw a rule on hover ---------- */
.stat, .benefit, .feature { position: relative; overflow: hidden; }
.stat::before, .benefit::before, .feature::before {
  content: ""; position: absolute; left: 0; top: 0; width: 100%; height: 2px;
  background: var(--accent); transform: scaleX(0); transform-origin: 0 50%;
  transition: transform .7s var(--ease);
}
.stat:hover::before, .benefit:hover::before, .feature:hover::before { transform: scaleX(1); }

/* ---------- horizontal testimonial strip ---------- */
.testimonials-h .section-head-row { align-items: flex-end; }
.hscroll-hint {
  display: none; align-items: center; gap: 12px; flex: none; margin: 0;
  font-size: .7rem; font-weight: 600; letter-spacing: .18em; text-transform: uppercase; color: var(--muted);
}
.testimonials-h.is-hscroll .hscroll-hint { display: inline-flex; }
.hscroll-hint i { display: block; width: 48px; height: 1px; background: currentColor; transform-origin: 0 50%; }
html.motion .hscroll-hint i { animation: hintSlide 2.4s var(--ease) infinite; }
@keyframes hintSlide { 0%, 100% { transform: scaleX(.28); opacity: .45; } 50% { transform: scaleX(1); opacity: 1; } }

.hscroll-outer { position: relative; }
/* Fallback, small screens and no-JS: an ordinary swipeable rail. */
.hscroll-stage { overflow-x: auto; overflow-y: hidden; scrollbar-width: none; -webkit-overflow-scrolling: touch; }
.hscroll-stage::-webkit-scrollbar { display: none; }
.hscroll-track {
  display: flex; width: max-content; gap: clamp(16px, 1.8vw, 30px); list-style: none; margin: 0;
  padding: 6px var(--gutter) 10px;
}
/* Sized off the viewport so four panels always overrun the stage — that is what
   gives the pinned strip something to travel. Below 760px JS leaves it as a
   swipe rail and the width just reads as a comfortable card. */
.testimonial-card { flex: none; width: clamp(290px, 33vw, 680px); }
.hscroll-rail { display: none; }

/* Closing panel: same footprint as a review, styled as an invitation. */
.cta-panel {
  height: 100%; display: grid; align-content: center; justify-items: start; gap: 18px;
  padding: clamp(26px, 2.6vw, 42px);
  border: 1px solid var(--line); border-radius: var(--radius-lg); background: var(--panel-2);
}
.cta-panel h3 { font-size: clamp(1.7rem, 1.3rem + 1.4vw, 2.6rem); letter-spacing: -0.035em; }
.testimonial-cta { display: flex; }

/* Pinned mode — JS adds .is-hscroll only once it has measured a real run. */
.testimonials-h.is-hscroll .hscroll-stage {
  position: sticky; top: 0; height: 100svh; overflow: hidden;
  display: flex; flex-direction: column; justify-content: center; gap: clamp(26px, 3vw, 44px);
}
.testimonials-h.is-hscroll .hscroll-track { padding-block: 0; }
.testimonials-h.is-hscroll .hscroll-rail {
  display: block; align-self: center; position: relative; height: 2px;
  width: min(var(--shell-max), 100% - var(--gutter) * 2); background: var(--line-soft);
}
.hscroll-rail span {
  display: block; height: 100%; background: var(--accent);
  transform: scaleX(0); transform-origin: 0 50%;
}
/* Cards drift in as the strip is entered. */
html.motion .is-hscroll .testimonial-card { opacity: 0; transform: translateY(26px); }
html.motion .is-hscroll .hscroll-stage.in .testimonial-card {
  opacity: 1; transform: none;
  transition: opacity .8s var(--ease-out), transform .8s var(--ease-out);
  transition-delay: calc(var(--i, 0) * 90ms);
}

/* ---------- brand outro: the wordmark that comes apart ---------- */
.brand-outro {
  position: relative; overflow: hidden; z-index: 1;
  padding: clamp(40px, 5vw, 78px) 0 clamp(26px, 3vw, 44px);
  display: grid; place-items: center;
}
.page-home .brand-outro, .page-product .brand-outro { padding-bottom: clamp(96px, 9vw, 132px); }
.brand-outro::after {
  content: ""; position: absolute; inset: auto 0 0; height: 46%; pointer-events: none;
  background: radial-gradient(64% 120% at 50% 118%, color-mix(in srgb, var(--accent) 24%, transparent), transparent 72%);
}
.brand-outro-word {
  position: relative; z-index: 2;
  width: min(var(--shell-max), 100% - var(--gutter) * 2);
  font-family: var(--font-display); font-weight: 600;
  font-size: clamp(3rem, 15.2vw, 16rem); line-height: .84; letter-spacing: -0.055em;
  color: var(--ink); user-select: none;
}
/* The canvas samples this element's own box, so the box has to have a real height of
   its own before any particle exists — hence an explicit aspect-driven height rather
   than letting the text size it. */
.brand-outro-word.is-canvas {
  display: block; height: clamp(84px, 17vw, 260px);
  cursor: crosshair; touch-action: manipulation;
}
.brand-outro-canvas { display: block; width: 100%; height: 100%; }

/* Fallback: reduced motion, no JS, or a browser that refuses getImageData. Renders
   as ordinary centred type — the band still reads as a sign-off. */
.brand-outro-word.is-plain,
html:not(.js) .brand-outro-word {
  display: flex; align-items: baseline; justify-content: center; flex-wrap: nowrap;
}
.brand-outro-note {
  position: relative; z-index: 2; margin-top: clamp(10px, 1.4vw, 20px);
  font-size: .68rem; font-weight: 600; letter-spacing: .2em; text-transform: uppercase; color: var(--muted);
  transition: opacity .4s var(--ease), transform .4s var(--ease);
}
/* The hint retires once the visitor has found the interaction. */
.brand-outro-word.is-canvas:hover ~ .brand-outro-note { opacity: 0; transform: translateY(4px); }
.brand-outro-word.is-plain ~ .brand-outro-note { display: none; }

/* ---------- reduced motion: keep the layout, drop the movement ---------- */
@media (prefers-reduced-motion: reduce) {
  [data-hscroll-track], [data-tilt] { transform: none !important; }
  .eyebrow::after { transform: none !important; }
  .hscroll-hint i { animation: none !important; }
  .testimonials-h.is-hscroll .hscroll-stage {
    position: static; height: auto; overflow-x: auto; display: block;
  }
  .testimonials-h.is-hscroll .hscroll-rail { display: none; }
  .testimonial-card { opacity: 1 !important; }
}

/* ---------- motion layer: fit-and-finish ---------- */

/* Cards in the pinned strip are sized off the viewport, not an aspect ratio,
   so a full card (media + quote + caption) always clears a 100svh stage. */
.testimonial-card .testimonial-media { aspect-ratio: auto; height: clamp(220px, 44svh, 420px); }
.testimonial-card .testimonial { gap: 18px; }
.testimonial-card blockquote p { font-size: clamp(1.05rem, .98rem + .3vw, 1.25rem); }

/* The skew on a rail needs a little headroom or it clips inside .rail. */
.rail-track { padding-top: 10px; }

/* Keep the hint from squeezing the heading on mid-size screens. */
@media (max-width: 900px) { .hscroll-hint { display: none !important; } }

/* A pinned strip owns the viewport, so drop the section's own bottom padding. */
.testimonials-h.is-hscroll { padding-bottom: clamp(40px, 4vw, 80px); }

/* ==================================================================
   CONTENT PAGES + CONTACT FORM
   Standalone pages served at /<slug> from Admin > Pages: policies, shipping,
   contact. Long-form reading, so the measure is tight and the rhythm is looser
   than the marketing sections above.
   ================================================================== */

.page-doc { padding-block: clamp(28px, 4vw, 56px) clamp(80px, 9vw, 150px); }
.doc-head { max-width: 62ch; margin-bottom: clamp(40px, 5vw, 72px); }
.doc-title {
  font-family: var(--font-display); font-weight: 500;
  font-size: clamp(2.2rem, 1.3rem + 2.8vw, 4.2rem); letter-spacing: -0.042em; line-height: 1;
  margin: 8px 0 0; text-wrap: balance;
}
.doc-updated {
  margin-top: 18px; font-size: .78rem; font-weight: 600; letter-spacing: .12em;
  text-transform: uppercase; color: var(--muted);
}

.doc-grid { display: grid; gap: clamp(32px, 4vw, 68px); align-items: start; }
@media (min-width: 1000px) {
  /* Contents rail first in the source order would read before the prose for a
     screen reader, so it is placed second and moved left visually instead. */
  .doc-grid { grid-template-columns: minmax(0, 1fr) 232px; }
  .doc-toc { grid-column: 2; grid-row: 1; position: sticky; top: calc(var(--header-h) + 32px); }
  .doc-body { grid-column: 1; grid-row: 1; }
}
.doc-toc-label {
  font-size: .7rem; font-weight: 600; letter-spacing: .16em; text-transform: uppercase;
  color: var(--muted); margin-bottom: 16px;
}
.doc-toc ol {
  list-style: none; margin: 0; padding: 0; display: grid; gap: 10px;
  border-left: 1px solid var(--line-soft); counter-reset: toc;
}
.doc-toc li { counter-increment: toc; }
.doc-toc a {
  display: block; padding: 2px 0 2px 16px; margin-left: -1px;
  border-left: 1px solid transparent;
  font-size: .88rem; color: var(--muted); text-decoration: none;
  transition: color .25s var(--ease), border-color .25s var(--ease);
}
.doc-toc a:hover { color: var(--accent); border-left-color: var(--accent); }

.doc-body { max-width: 68ch; }
.doc-section + .doc-section { margin-top: clamp(30px, 3.4vw, 52px); }
.doc-section h2 {
  font-size: clamp(1.25rem, 1.05rem + .7vw, 1.7rem); letter-spacing: -0.03em;
  margin-bottom: 14px;
  /* Anchored from the contents rail, so keep the heading clear of the sticky header. */
  scroll-margin-top: calc(var(--header-h) + 28px);
}
.doc-section p { color: var(--ink-soft); font-size: 1rem; line-height: 1.7; }
.doc-section p + p { margin-top: 14px; }

/* ---------- contact form ---------- */
.contact-block {
  margin-top: clamp(44px, 5vw, 78px); padding-top: clamp(36px, 4vw, 56px);
  border-top: 1px solid var(--line-soft);
}
.contact-form { margin-top: 26px; display: grid; gap: 18px; }
.contact-row { display: grid; gap: 18px; }
@media (min-width: 620px) { .contact-row { grid-template-columns: 1fr 1fr; } }
.contact-form .field { display: grid; gap: 8px; }
.contact-form label {
  font-size: .8rem; font-weight: 600; letter-spacing: .04em; color: var(--ink);
}
.contact-form input,
.contact-form textarea {
  width: 100%; padding: 14px 18px; font: inherit; font-size: .96rem;
  color: var(--ink); background: var(--panel);
  border: 1px solid var(--line); border-radius: var(--radius-sm);
  transition: border-color .25s var(--ease), background .25s var(--ease), box-shadow .25s var(--ease);
}
.contact-form textarea { resize: vertical; min-height: 140px; line-height: 1.6; border-radius: var(--radius); }
.contact-form input::placeholder, .contact-form textarea::placeholder { color: var(--muted); }
.contact-form input:focus,
.contact-form textarea:focus {
  outline: none; border-color: var(--accent); background: var(--bg);
  box-shadow: 0 0 0 3px var(--accent-soft);
}
/* Only flag a field the visitor has actually left in a bad state — :invalid alone
   paints every required field red before anyone has typed a character. */
.contact-form input:user-invalid,
.contact-form textarea:user-invalid { border-color: var(--danger); }

/* Honeypot. Off-screen rather than display:none, because some bots skip hidden
   inputs; aria-hidden + tabindex="-1" in the markup keep it away from real users. */
.contact-trap {
  position: absolute; left: -9999px; width: 1px; height: 1px;
  overflow: hidden; opacity: 0; pointer-events: none;
}

.contact-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 18px; margin-top: 6px; }
.contact-actions .form-msg { flex-basis: auto; margin: 0; }
.contact-form.is-sent { opacity: .6; pointer-events: none; }

/* ---------- footer policy row ---------- */
.footer-legal { margin-bottom: 4px; }
.footer-legal ul {
  display: flex; flex-wrap: wrap; gap: 8px 22px; list-style: none; margin: 0; padding: 0;
}
.footer-legal a {
  font-size: .78rem; color: var(--muted); text-decoration: none;
  transition: color .25s var(--ease);
}
.footer-legal a:hover { color: var(--accent); }

/* ==================================================================
   ACCOUNTS + CUSTOMER REVIEWS
   Written mobile-first: the base rules are the phone layout and the
   media queries only ever add columns, so a narrow screen never has to
   undo a desktop rule.
   ================================================================== */

/* ---------- shared form furniture ---------- */
.field { display: grid; gap: 7px; }
.field-label { font-size: .78rem; font-weight: 600; letter-spacing: .08em; text-transform: uppercase; color: var(--muted); }
.field-hint { font-size: .82rem; color: var(--muted); line-height: 1.45; }
.field input[type="text"], .field input[type="email"], .field input[type="password"],
.field input[type="tel"], .field input:not([type]), .field textarea {
  width: 100%; padding: 13px 16px; border-radius: var(--radius-sm);
  border: 1px solid var(--line); background: var(--bg); color: var(--ink);
  font: inherit; line-height: 1.4;
  /* 16px minimum stops iOS Safari zooming the viewport when a field is focused,
     which on a phone reads as the page jumping sideways. */
  font-size: max(16px, 1rem);
  transition: border-color .2s, box-shadow .2s;
}
.field textarea { resize: vertical; min-height: 120px; }
.field input:focus, .field textarea:focus {
  outline: none; border-color: var(--accent);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 16%, transparent);
}
.field input[type="file"] { font-size: .9rem; color: var(--muted); padding: 10px 0; }
.field-row { display: grid; gap: 14px; }
@media (min-width: 620px) { .field-row { grid-template-columns: 1fr 1fr; } }
.field-check { display: flex; align-items: center; gap: 10px; font-size: .92rem; }
.field-check input { width: 18px; height: 18px; accent-color: var(--accent); flex: none; }

/* ---------- account pages ---------- */
.account-main { padding-block: clamp(28px, 5vw, 72px) clamp(60px, 8vw, 120px); }
.account-shell { display: grid; gap: clamp(18px, 2.4vw, 28px); }
.account-card {
  background: var(--panel); border: 1px solid var(--line-soft); border-radius: var(--radius-lg);
  padding: clamp(20px, 3.4vw, 36px); box-shadow: var(--shadow-sm);
}
.account-card-narrow { width: min(460px, 100%); margin-inline: auto; }
.account-title { font-size: clamp(1.8rem, 1.2rem + 2.4vw, 2.8rem); letter-spacing: -0.035em; }
.account-h2 { font-size: 1.2rem; letter-spacing: -0.02em; margin-bottom: 18px; }
.account-lede { margin-top: 10px; color: var(--muted); }
.account-form { display: grid; gap: 16px; margin-top: 22px; }
.account-switch { margin-top: 22px; font-size: .92rem; color: var(--muted); text-align: center; }
.account-switch a { font-weight: 600; color: var(--accent); }

.account-head { display: grid; gap: 16px; align-items: start; }
@media (min-width: 640px) { .account-head { grid-template-columns: 1fr auto; align-items: center; } }

.account-tabs { display: flex; gap: 6px; flex-wrap: wrap; border-bottom: 1px solid var(--line-soft); }
.account-tabs a {
  padding: 12px 16px; text-decoration: none; font-size: .92rem; font-weight: 600;
  color: var(--muted); border-bottom: 2px solid transparent; margin-bottom: -1px;
}
.account-tabs a[aria-current] { color: var(--accent); border-bottom-color: var(--accent); }

.account-grid { display: grid; gap: clamp(18px, 2.4vw, 28px); }
@media (min-width: 900px) { .account-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.account-address { font-style: normal; line-height: 1.7; margin-bottom: 18px; }

.address-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 14px; }
.address-item {
  position: relative; padding: 18px 20px; border: 1px solid var(--line-soft);
  border-radius: var(--radius); background: var(--bg); display: grid; gap: 12px;
}
.address-item.is-default { border-color: color-mix(in srgb, var(--accent) 40%, transparent); }
.address-item address { font-style: normal; line-height: 1.6; font-size: .94rem; }
.address-item .tag { position: static; justify-self: start; height: 26px; }
.address-actions { display: flex; flex-wrap: wrap; gap: 8px 18px; align-items: center; }
.address-actions form { display: contents; }
.link-btn-danger { color: var(--danger); }

.account-reviews { list-style: none; margin: 0; padding: 0; display: grid; gap: 22px; }
.account-reviews > li { padding-bottom: 22px; border-bottom: 1px solid var(--line-soft); }
.account-reviews > li:last-child { border-bottom: 0; padding-bottom: 0; }
.account-reviews h3 { margin: 10px 0 8px; font-size: 1.05rem; }
.account-review-head { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 14px; font-size: .84rem; }
.review-status {
  padding: 3px 10px; border-radius: 999px; font-size: .72rem; font-weight: 600;
  letter-spacing: .06em; text-transform: uppercase;
}
.review-status-approved { background: var(--accent-soft); color: var(--accent); }
.review-status-pending { background: color-mix(in srgb, var(--muted) 18%, transparent); color: var(--muted); }
.review-status-rejected { background: color-mix(in srgb, var(--danger) 14%, transparent); color: var(--danger); }

.account-btn { position: relative; }
.account-dot {
  position: absolute; top: 6px; right: 6px; width: 7px; height: 7px; border-radius: 50%;
  background: var(--accent); box-shadow: 0 0 0 2px var(--bg);
}
@media (min-width: 1024px) { .mobile-account { display: none; } }

/* ---------- review writing + photos ---------- */
.review-cta { margin-top: 26px; display: grid; gap: 12px; justify-items: start; }
.review-side { margin-bottom: clamp(20px, 3vw, 34px); }
.review-form {
  display: grid; gap: 18px; padding: clamp(18px, 3vw, 28px);
  border: 1px solid var(--line-soft); border-radius: var(--radius-lg);
  background: var(--panel); box-shadow: var(--shadow-sm);
}
.review-form[hidden] { display: none; }

/* Radios painted as stars. They stay real radios underneath, so they are keyboard
   operable and submit without JavaScript; row-reverse plus the sibling selector is
   what lets hovering a star light every star below it. */
.rating-picker { display: flex; flex-direction: row-reverse; justify-content: flex-end; gap: 4px; border: 0; padding: 0; margin: 0; }
.rating-picker legend { float: left; width: 100%; margin-bottom: 8px; }
.rating-option input { position: absolute; opacity: 0; width: 1px; height: 1px; }
.rating-option span {
  display: block; cursor: pointer; font-size: 0; line-height: 1;
  color: color-mix(in srgb, var(--ink) 22%, transparent); transition: color .18s;
}
/* Only the first glyph of each label is shown, so the five labels read as 1..5. */
.rating-option span::first-letter { font-size: 1.9rem; }
.rating-option input:checked ~ span,
.rating-option:hover span,
.rating-option:hover ~ .rating-option span,
.rating-picker:not(:hover) .rating-option input:checked ~ span,
.rating-option input:checked ~ span { color: var(--accent); }
.rating-picker:hover .rating-option input:checked ~ span { color: color-mix(in srgb, var(--accent) 45%, transparent); }
.rating-option input:focus-visible ~ span { outline: 2px solid var(--accent); outline-offset: 3px; border-radius: 3px; }

.review-photos, .review-photo-preview { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 14px; }
.review-photo-preview[hidden] { display: none; }
.review-photo {
  display: block; width: clamp(72px, 20vw, 104px); aspect-ratio: 1; overflow: hidden;
  border-radius: var(--radius-sm); border: 1px solid var(--line-soft); background: var(--panel-2);
}
.review-photo img { width: 100%; height: 100%; object-fit: cover; display: block; }
a.review-photo { transition: transform .3s var(--ease), border-color .3s; }
a.review-photo:hover { transform: translateY(-2px); border-color: var(--accent); }

/* The reviews grid gains its sidebar only when there is room for one. */
@media (min-width: 1000px) {
  .reviews-grid { grid-template-columns: minmax(0, .8fr) minmax(0, 1.2fr); }
  .review-side { grid-column: 1; }
  .review-list { grid-column: 2; grid-row: 1 / span 2; }
}

/* ==================================================================
   MOBILE PASS
   Fixes found by measuring every page at 360 / 414 / 768 rather than by
   eye: one real overflow, tap targets under the 24px minimum, and a few
   labels below a comfortable reading size.
   ================================================================== */

/* ---------- 1. the product gallery overflowed its column ----------
   A grid item's default min-width is auto, which means it refuses to shrink below
   the intrinsic width of its contents. The thumbnail strip is 88px per thumb, so on
   a 360px screen the gallery insisted on ~400px and pushed its own next/previous
   buttons off the side of the screen, where they could not be tapped at all.
   min-width: 0 lets the column shrink; the strip then scrolls, as it was always
   meant to. */
.product-grid > * { min-width: 0; }
.gallery, .gallery-stage, .gallery-track { min-width: 0; max-width: 100%; }
.gallery-thumbs { min-width: 0; }

@media (max-width: 720px) {
  /* Smaller thumbs so a phone shows three or four rather than two and a half. */
  .gallery-thumb { width: 64px; }
  /* Corner controls move in from the edge and grow, so they clear the rounded
     corner and are comfortably tappable. */
  .gallery-nav { inset: auto 12px 12px auto; gap: 8px; }
  .gallery-nav .icon-btn { width: 40px; height: 40px; }
}

/* ---------- 2. tap targets ----------
   WCAG 2.2 asks for 24x24 CSS px. The footer, breadcrumb and legal links were
   16-18px tall. Padding is used rather than font-size so the type keeps its
   proportions; the negative margin keeps the visual rhythm unchanged.
   Scoped to coarse pointers so a mouse-driven layout is untouched. */
@media (max-width: 860px), (pointer: coarse) {
  .footer-col a,
  .footer-col li > a,
  /* The policy links and the announcement bar sit outside .footer-col and were the
     shortest targets on the page at 15-16px. */
  .footer-legal a,
  .announcement a,
  .breadcrumb a,
  .doc-toc a,
  .account-switch a,
  .checkout-back,
  .rating a {
    display: inline-block;
    padding-block: 6px;
    min-height: 24px;
  }
  .footer-col ul { gap: 4px; }
  .main-nav a { padding-block: 8px; }
  /* Icon buttons are 44px already; the cart badge just needs to not shrink them. */
  .icon-btn { min-width: 44px; min-height: 44px; }
}

/* ---------- 3. small label text ----------
   These are uppercase, widely-tracked labels, so they read smaller than their
   nominal size. Nudged up on phones where they are closest to the eye. */
/* Tablets get the same treatment: these labels are uppercase and widely tracked,
   so they read a size smaller than their nominal value at any hand-held distance. */
@media (max-width: 900px) {
  .brand-outro-note { font-size: .74rem; }
  .doc-toc-label { font-size: .76rem; }
  .gb-loader-word { font-size: .76rem; }
  .hscroll-hint { font-size: .76rem; }
  .hero-badges { font-size: .76rem; }
}

/* ---------- 4. account + review pages on a phone ---------- */
@media (max-width: 620px) {
  .account-main { padding-block: 20px 56px; }
  .account-card { padding: 20px 18px; border-radius: var(--radius); }
  .account-head { gap: 14px; }
  /* Sign-out sits under the name rather than squeezing beside it. */
  .account-head form { justify-self: start; }
  .account-tabs { gap: 0; }
  .account-tabs a { flex: 1; text-align: center; padding: 12px 8px; }
  .address-actions { gap: 6px 14px; }
  .review-form { padding: 18px 16px; }
  /* Stars large enough to hit accurately with a thumb. */
  .rating-option span::first-letter { font-size: 2.2rem; }
  .rating-picker { gap: 6px; }
  .review-photo { width: calc(50% - 5px); }
  .review-photo-preview .review-photo { width: calc(33.333% - 7px); }
}

/* ---------- 5. checkout on a phone ---------- */
@media (max-width: 620px) {
  .checkout-container { width: min(1160px, 100% - 32px); }
  .checkout-card { padding: 18px 16px; }
  .cart-line { grid-template-columns: 64px minmax(0, 1fr); row-gap: 10px; }
  .cart-line-media { width: 64px; height: 64px; }
  /* The price column drops below the name instead of squeezing it to two words. */
  .cart-line-right { grid-column: 1 / -1; flex-direction: row; align-items: center; justify-content: space-between; }
  .qty { margin-top: 0; }
}

/* ---------- 6. tables and long words ----------
   A postcode, an email or a long product name should wrap rather than push the
   layout sideways. */
.account-address, .address-item address, .msg-body, .review p, .account-reviews p {
  overflow-wrap: anywhere;
}
@media (max-width: 620px) {
  .compare { min-width: 460px; } /* still scrolls, but less far */
}

@media (max-width: 860px), (pointer: coarse) {
  /* Keep the strip its designed height while still offering a 24px target. */
  .announcement { padding-block: 8px; }
  .announcement a { padding-block: 5px; }
  .footer-legal ul { gap: 2px 18px; }
}

/* ==================================================================
   DIRECTION: CLEAN COMMERCIAL DTC
   Replaces the editorial/cinematic treatment with the plain, confident
   supplement-shop look: white page, light-grey alternating bands,
   Poppins at heavy weights, centred section headings, white cards with
   a soft lift, and one deep green doing all the accent work.

   Appended last so it wins the cascade without unpicking the rules
   above, every one of which still supplies the structure.
   ================================================================== */

:root {
  --font-body: "Poppins", system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  --font-display: "Poppins", system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;

  /* Softer, rounder geometry than the editorial direction's near-square frames. */
  --radius-lg: 16px;
  --radius: 12px;
  --radius-sm: 8px;
  --header-h: 72px;
  --shell-max: 1240px;

  /* Light-theme shade: shallow and diffuse, the way a product card lifts off
     white rather than the deep drama a dark theme needs. */
  --shadow-sm: 0 1px 2px rgba(17, 17, 17, .04), 0 2px 10px -4px rgba(17, 17, 17, .08);
  --shadow-md: 0 2px 4px rgba(17, 17, 17, .04), 0 10px 26px -12px rgba(17, 17, 17, .14);
  --shadow-lg: 0 4px 10px rgba(17, 17, 17, .04), 0 22px 50px -22px rgba(17, 17, 17, .18);

  --line: rgba(17, 17, 17, .10);
  --line-soft: rgba(17, 17, 17, .07);
  --panel: #FFFFFF;
  --panel-2: #F3F3F3;
  --ink-soft: rgba(17, 17, 17, .72);
  --accent-soft: rgba(8, 89, 70, .08);
  --danger: #B3261E;
}
.invert {
  --line: rgba(255, 255, 255, .22);
  --line-soft: rgba(255, 255, 255, .14);
  --panel: rgba(255, 255, 255, .08);
  --panel-2: rgba(255, 255, 255, .12);
  --ink-soft: rgba(255, 255, 255, .80);
  --accent-soft: rgba(255, 255, 255, .14);
  --shadow-sm: none; --shadow-md: none; --shadow-lg: none;
}

/* ---------- 1. the cinematic layer comes off ----------
   The reference has no grain, no custom cursor, no pinned full-screen statement
   and no per-word heading animation. Those read as "editorial magazine"; this
   direction wants the page to simply be there. Reveals stay, but as one quiet
   fade rather than a staged performance. */
.grain, .cursor { display: none !important; }
html.cursor-on, html.cursor-on a, html.cursor-on button,
html.cursor-on label, html.cursor-on [role="button"] { cursor: auto; }

/* Headings wipe up behind a mask, word by word. The spans and the .in class
   both come from site.js, which also force-reveals them if the observer never
   fires, so a stalled script cannot leave a heading blank. */
html.motion .mask-line > span { animation: none !important; transform: none !important; }
html.motion [data-split] .word > span {
  transform: translateY(102%);
  transition: transform .8s cubic-bezier(.22,.9,.24,1);
  transition-delay: calc(var(--i, 0) * 34ms);
}
html.motion [data-split].in .word > span { transform: none !important; }

html.motion [data-reveal],
html.motion [data-reveal-item] {
  opacity: 0; transform: translateY(14px);
  transition: opacity .55s ease, transform .55s ease;
  transition-delay: 0s;
}
html.motion [data-reveal].in,
html.motion [data-reveal-item].in { opacity: 1; transform: none; }
html.motion [data-reveal-item] { transition-delay: calc(var(--i, 0) * 50ms); }

/* ---------- 2. type ---------- */
body { font-size: 16px; line-height: 1.6; color: var(--ink); }
h1, h2, h3, h4 { font-weight: 700; letter-spacing: -0.02em; line-height: 1.12; }

.display { font-size: clamp(2rem, 1.2rem + 3.2vw, 3.4rem); font-weight: 700; letter-spacing: -0.025em; line-height: 1.12; }
.h1 { font-size: clamp(1.85rem, 1.1rem + 2.6vw, 3rem); font-weight: 700; letter-spacing: -0.025em; line-height: 1.14; max-width: none; }
.h2 { font-size: clamp(1.45rem, 1rem + 1.6vw, 2.05rem); font-weight: 700; letter-spacing: -0.02em; max-width: none; }
.lead { font-size: clamp(.98rem, .95rem + .2vw, 1.08rem); line-height: 1.68; color: var(--muted); max-width: 64ch; }

/* The reference centres almost every section heading and its intro paragraph,
   which is what gives the page its symmetrical, catalogue rhythm. */
.section-head { text-align: center; margin-inline: auto; max-width: 760px; margin-bottom: clamp(28px, 4vw, 52px); }
.section-head .lead { margin-inline: auto; text-align: center; }
.section-head-row { text-align: left; max-width: none; }
.section-head-row .lead { margin-inline: 0; text-align: left; }

/* Eyebrows become small green labels rather than rules with a line through them. */
.eyebrow {
  display: inline-flex; align-items: center; gap: 0;
  font-size: .76rem; font-weight: 600; letter-spacing: .1em; text-transform: uppercase;
  color: var(--accent); margin-bottom: 12px;
}
.eyebrow::after { display: none; }
.section-head .eyebrow { justify-content: center; }

/* ---------- 3. bands ----------
   White and #F3F3F3 alternating, with real padding between them. */
.section { padding-block: clamp(56px, 6.5vw, 96px); background: var(--bg); }
.section + .section { padding-top: clamp(56px, 6.5vw, 96px); }
.section.band { background: var(--surface); }
.section.invert { background: var(--bg); }

/* ---------- 4. buttons ----------
   Solid green, modest radius, no sweeping fill. */
.btn {
  height: 48px; padding: 0 26px; border-radius: 8px; font-weight: 600; font-size: .95rem;
  letter-spacing: 0; box-shadow: none; overflow: visible; isolation: auto;
  transition: background .2s ease, color .2s ease, border-color .2s ease, transform .1s ease;
}
.btn::before { display: none; }
.btn-lg { height: 54px; padding: 0 30px; font-size: 1rem; }
.btn-sm { height: 40px; padding: 0 18px; font-size: .88rem; }
.btn-accent, .btn-primary { background: var(--accent); color: #fff; border-color: var(--accent); }
.btn-accent:hover:not(:disabled), .btn-primary:hover:not(:disabled) { background: #064334; color: #fff; }
.btn-accent:active:not(:disabled) { transform: translateY(1px); }
.btn-ghost { background: transparent; border: 1.5px solid var(--ink); color: var(--ink); }
.btn-ghost:hover { background: var(--ink); color: var(--bg); border-color: var(--ink); }
.invert .btn-accent { background: #fff; color: var(--accent); border-color: #fff; }
.invert .btn-accent:hover:not(:disabled) { background: rgba(255,255,255,.88); color: var(--accent); }
.invert .btn-ghost { border-color: #fff; color: #fff; }
.invert .btn-ghost:hover { background: #fff; color: var(--accent); }

/* ---------- 5. announcement + header ----------
   Thin green strip, then a solid white header that does not go transparent. */
.announcement {
  background: var(--accent); color: #fff; font-weight: 600; font-size: .82rem;
  letter-spacing: .01em; padding: 10px var(--gutter);
}
.announcement a { color: #fff; text-decoration: underline; }

.site-header { background: var(--bg); border-bottom: 1px solid var(--line-soft); }
.site-header.is-scrolled { background: var(--bg); backdrop-filter: none; box-shadow: var(--shadow-sm); }
.header-inner { height: var(--header-h); gap: clamp(14px, 2.4vw, 36px); }
.logo { font-weight: 700; font-size: 1.15rem; letter-spacing: -0.02em; }
.logo-mark { width: 24px; height: 24px; border-radius: 50%; background: var(--accent); }
.logo-mark::after { inset: 7px 7px auto auto; width: 7px; height: 7px; background: #fff; }
.main-nav { margin-left: 0; }
.main-nav ul { gap: clamp(14px, 1.8vw, 28px); }
.main-nav a { font-size: .92rem; font-weight: 500; color: var(--ink); }
.main-nav a::after { background: var(--accent); bottom: -4px; }
.header-actions { margin-left: auto; }
.icon-btn { border: 0; width: 40px; height: 40px; }
.icon-btn:hover:not(:disabled) { background: var(--surface); border: 0; }

/* ---------- 6. hero ----------
   Copy on the left over a full-bleed product photograph, which is the shape the
   reference uses. No parallax, no zoom drift — the image simply sits there. */
.hero {
  min-height: clamp(460px, 56vw, 660px);
  align-items: center;
  padding-block: clamp(40px, 5vw, 72px);
  margin-top: 0;
  background: var(--surface);
}
.hero-media { position: absolute; inset: 0; transform: none !important; will-change: auto; }
.hero-media-el { width: 100%; height: 100%; object-fit: cover; animation: none !important; }
.hero-scrim {
  /* A readable plate under the left-hand copy only, fading out across the middle
     so the product photograph is untouched on the right. */
  background: linear-gradient(to right,
    rgba(255, 255, 255, .92) 0%,
    rgba(255, 255, 255, .80) 26%,
    rgba(255, 255, 255, .30) 46%,
    rgba(255, 255, 255, 0) 62%);
  opacity: 1;
}
.hero-inner { max-width: 1240px; }
.hero-title {
  font-size: clamp(1.65rem, 1rem + 2.1vw, 2.65rem);
  font-weight: 700; letter-spacing: -0.01em; line-height: 1.22;
  text-transform: uppercase; color: var(--ink); text-shadow: none; max-width: 17ch;
}
.hero-title .mask-line + .mask-line > span { color: var(--ink); }
.hero-sub {
  margin-top: 14px; font-size: clamp(.95rem, .92rem + .2vw, 1.05rem);
  color: var(--ink); font-weight: 500; text-shadow: none; max-width: 40ch;
}
.hero-ctas { margin-top: 22px; }
.hero-badges {
  margin-top: 18px; gap: 8px 18px; font-size: .82rem; font-weight: 500;
  letter-spacing: 0; text-transform: none; color: var(--ink); text-shadow: none;
}
.hero-badges li::before { background: var(--accent); box-shadow: none; }
.hero-cue { display: none; }

/* ---------- 7. cards ----------
   White, rounded, a hairline border and a shallow lift. */
.benefit, .feature, .stat, .review {
  background: var(--bg); border-radius: var(--radius-lg); border: 1px solid var(--line-soft);
  box-shadow: var(--shadow-sm); padding: clamp(22px, 2.4vw, 30px);
}
.benefit-grid, .feature-grid, .stat-grid {
  gap: clamp(14px, 1.6vw, 20px); background: none; border: 0;
}
.benefit::before, .feature::before, .stat::before { display: none; }
.benefit-num { color: var(--accent); font-weight: 600; }
.benefit-icon {
  width: 46px; height: 46px; margin: 14px 0 16px; border-radius: 12px;
  background: var(--accent-soft); border: 0; color: var(--accent);
}
.benefit h3, .feature h3 { font-size: 1.08rem; font-weight: 600; margin-bottom: 8px; }
.benefit p, .feature p { font-size: .93rem; color: var(--muted); }

.ingredient-card {
  background: var(--bg); border: 1px solid var(--line-soft); border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
}
.ingredient-card:hover { transform: translateY(-2px); box-shadow: var(--shadow-md); border-color: var(--line); }
.ingredient-index { color: var(--accent); font-weight: 600; }
.ingredient-body h3 { font-size: 1.12rem; font-weight: 600; }
.ingredient-amount { color: var(--accent); font-weight: 600; letter-spacing: .04em; }

.step-card { background: var(--bg); border: 1px solid var(--line-soft); box-shadow: var(--shadow-md); border-radius: var(--radius-lg); }
.step-num { color: var(--accent); font-weight: 600; }
.step-copy h3 { font-size: clamp(1.3rem, 1.1rem + .8vw, 1.9rem); font-weight: 700; }

.stat-value, .metric-value, .reviews-score strong { color: var(--accent); font-weight: 700; letter-spacing: -0.02em; }
.stat-label { color: var(--muted); }

/* ---------- 8. the statement band ----------
   Was a pinned, full-screen, scroll-scrubbed moment. Here it is an ordinary
   image band with the copy on it — no pinning, no scrubbing. */
.statement { height: auto; }
.statement-stage { position: relative; height: auto; min-height: clamp(320px, 40vw, 460px); padding-block: clamp(48px, 6vw, 86px); }
.statement-media { transform: none !important; }
.statement-media > img, .statement-media > video { transform: none !important; }
.statement-copy { transform: none !important; opacity: 1 !important; max-width: 820px; }
.statement-copy .display { max-width: 22ch; }

/* ---------- 9. trust strip (was the marquee) ---------- */
.marquee { background: var(--bg); border-block: 1px solid var(--line-soft); padding-block: 16px; }
.marquee-item { font-size: .9rem; font-weight: 500; color: var(--ink); letter-spacing: 0; }
.marquee-dot { background: var(--accent); width: 5px; height: 5px; }

/* ---------- 10. buy box ---------- */
.buy-visual { border-radius: var(--radius-lg); background: var(--surface); box-shadow: none; border: 1px solid var(--line-soft); }
.option-body { border-radius: var(--radius); border: 1.5px solid var(--line); background: var(--bg); box-shadow: none; }
.option input:checked ~ .option-body {
  border-color: var(--accent); background: var(--accent-soft);
  box-shadow: none;
}
.option-price strong { font-weight: 700; }
.ticklist .icon, .perks li::before { color: var(--accent); background: var(--accent); }
.ticklist .icon { background: none; }

/* ---------- 11. reviews ---------- */
.review-list { gap: clamp(14px, 1.6vw, 20px); background: none; border: 0; }
.review h3 { font-size: 1.05rem; font-weight: 600; }
.stars, .stars-fill { color: var(--accent); }
.verified { color: var(--accent); font-weight: 500; }
.testimonial blockquote p { font-size: 1.05rem; font-weight: 500; line-height: 1.5; letter-spacing: -0.01em; }
.testimonial-card { background: var(--bg); border: 1px solid var(--line-soft); border-radius: var(--radius-lg); padding: 20px; box-shadow: var(--shadow-sm); }
.testimonial-card .testimonial-media { margin: -20px -20px 16px; border-radius: var(--radius-lg) var(--radius-lg) 0 0; box-shadow: none; }

/* ---------- 12. accordion ---------- */
.accordion { border-top: 0; }
.accordion-item {
  border: 1px solid var(--line-soft); border-radius: var(--radius); margin-bottom: 10px;
  background: var(--bg); overflow: hidden;
}
.accordion-item::before { display: none; }
.accordion-trigger { padding: 18px 20px; font-size: 1rem; font-weight: 600; letter-spacing: -0.01em; }
.accordion-trigger:hover { color: var(--accent); }
.accordion-panel p { padding: 0 20px 18px; color: var(--muted); }

/* ---------- 13. final call to action ---------- */
.final-cta { min-height: auto; padding-block: clamp(56px, 7vw, 96px); background: var(--bg); }
.final-media { display: none; }
.final-scrim { display: none; }
.final-inner { padding-block: 0; }
.final-inner .display { max-width: 20ch; }

/* ---------- 14. footer ---------- */
.site-footer { background: var(--surface); border-top: 1px solid var(--line-soft); }
.footer-heading { font-size: clamp(1.3rem, 1.1rem + 1vw, 1.8rem); font-weight: 700; }
.footer-col h3 { color: var(--ink); font-weight: 600; font-size: .8rem; }
.footer-col a { color: var(--muted); }
.footer-col a:hover { color: var(--accent); }
.newsletter input { border-radius: 8px; background: var(--bg); }

/* The particle wordmark belongs to the editorial direction. */
.brand-outro { display: none; }

/* ---------- 15. forms ---------- */
.field input, .field textarea { border-radius: 8px; border: 1.5px solid var(--line); }
.field input:focus, .field textarea:focus { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
.account-card { background: var(--bg); border: 1px solid var(--line-soft); border-radius: var(--radius-lg); }
.account-tabs a[aria-current] { color: var(--accent); border-bottom-color: var(--accent); }

/* ---------- 16. small screens ---------- */
@media (max-width: 860px) {
  .hero { min-height: auto; padding-block: 32px 36px; align-items: flex-end; }
  /* On a phone the photograph cannot share the row, so the plate covers the lower
     half and the copy sits on it. */
  .hero-scrim {
    background: linear-gradient(to top,
      #fff 0%, rgba(255,255,255,.95) 34%, rgba(255,255,255,.72) 50%, rgba(255,255,255,0) 72%);
  }
  .hero-title { max-width: none; font-size: clamp(1.5rem, 1.1rem + 2.6vw, 2rem); }
  .hero-sub { max-width: none; }
  .section-head { margin-bottom: 26px; }
}
@media (max-width: 620px) {
  .section { padding-block: 44px; }
  .hero-ctas .btn { flex: 1 1 100%; }
}

/* The dark brand band. It no longer pins or scrubs, so it needs a flat, even
   scrim rather than one tuned for a moving crop — the copy has to be legible on
   whatever frame the video happens to be showing. */
.statement-stage::after {
  background: linear-gradient(to bottom, rgba(0,0,0,.55), rgba(0,0,0,.62));
}
.statement-copy { padding-inline: var(--gutter); }
.statement-copy .display { font-size: clamp(1.6rem, 1.1rem + 2vw, 2.6rem); max-width: 20ch; }
.statement-copy .lead { color: rgba(255,255,255,.86); max-width: 56ch; }

/* ---------- steps: a plain row, not a stack ----------
   The sticky, stacking cards were part of the cinematic direction. They also made
   each card as tall as the viewport, so a single short step read as a mostly empty
   panel. Here the steps are three ordinary cards side by side, media on top. */
.steps-stack { display: grid; gap: clamp(14px, 1.6vw, 20px); }
@media (min-width: 860px) { .steps-stack { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
.step-card {
  position: static; top: auto;
  display: flex; flex-direction: column; gap: 0;
  padding: 0; overflow: hidden; backdrop-filter: none;
}
.step-media {
  order: -1;                     /* picture first, copy under it */
  aspect-ratio: 4 / 3; width: 100%; border-radius: 0; background: var(--surface);
}
.step-copy { padding: clamp(18px, 2vw, 26px); }
.step-copy h3 { margin: 10px 0 8px; font-size: 1.15rem; font-weight: 600; }
.step-copy p { font-size: .93rem; color: var(--muted); max-width: none; }

/* ---------- reviews: a grid, not a sliding strip ----------
   The horizontal run is gone, so the track becomes a plain responsive grid and
   the stage stops trying to be a sticky viewport-height stage. */
.testimonials-h .hscroll-outer { position: static; }
.testimonials-h .hscroll-stage {
  position: static; height: auto; overflow: visible; display: block;
}
.testimonials-h .hscroll-track {
  display: grid; width: auto; padding: 0;
  gap: clamp(14px, 1.6vw, 20px);
  grid-template-columns: 1fr;
}
@media (min-width: 700px) { .testimonials-h .hscroll-track { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 1040px) { .testimonials-h .hscroll-track { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
.testimonials-h .testimonial-card { width: auto; }
.testimonials-h .hscroll-rail, .testimonials-h .hscroll-hint { display: none; }
/* The cards were faded out ready to drift in with the strip; show them. */
html.motion .is-hscroll .testimonial-card,
html.motion .testimonials-h .testimonial-card { opacity: 1; transform: none; }

/* The closing panel in that row reads as a card, not a cut-off slide. */
.testimonial-cta {
  display: grid; align-content: center; justify-items: start; gap: 14px;
  background: var(--accent); color: #fff; padding: clamp(22px, 2.4vw, 30px);
}
.testimonial-cta .eyebrow, .testimonial-cta h3, .testimonial-cta p { color: #fff; }
.testimonial-cta .btn { background: #fff; color: var(--accent); border-color: #fff; }

/* ---------- the hero simply is ----------
   .hero-fade keyframes from opacity 0 with fill both, so anything that stops the
   animation running — a paused state that is never released, a browser that
   skips it — leaves the subhead, the buttons and the badges invisible. This
   direction has no staged entrance anyway: the reference hero is just there when
   the page is. Removing the animation removes the whole failure mode.

   This is the third time in this build that a decorative effect could permanently
   hide content (the clip-path wipe and the stat counters were the others), so the
   rule here is: nothing that hides content may depend on an effect completing. */
html.motion .hero-fade {
  opacity: 1; transform: none; animation: none;
}
html.gb-loading .hero-fade { animation: none !important; }

/* ==================================================================
   ROUND 2: more green, comet cards, rise-in media, modern cursor
   ================================================================== */

/* ---------- 1. more green ----------
   The page was almost entirely white. Green now does more work: a tinted band
   instead of neutral grey, green rules and numerals, a green-washed hero plate
   and a green footer. The brand colour is one hue, so this reads as more of the
   same rather than as a second palette. */
:root {
  /* Grey bands pick up a trace of the brand hue instead of being neutral. */
  --accent-soft: color-mix(in srgb, var(--accent) 10%, transparent);
  --accent-line: color-mix(in srgb, var(--accent) 22%, transparent);
}
.section.band { background: var(--surface); }
/* A deeper tint for alternate bands, so three greens step down the page. */
.section.band-2 { background: var(--surface-2); }

/* Section headings get a short green rule above them. */
.section-head .eyebrow::before {
  content: ""; width: 26px; height: 2px; background: var(--accent);
  border-radius: 2px; margin-right: 10px; flex: none;
}

/* Hairlines and small marks take the brand hue rather than neutral grey. */
.accordion-item { border-color: var(--accent-line); }
.option-body { border-color: var(--accent-line); }
.marquee { border-color: var(--accent-line); background: var(--surface); }
.site-header { border-bottom-color: var(--accent-line); }
.ticklist li, .perks li { color: var(--ink); }

/* The footer becomes the closing green band. */
.site-footer {
  background: var(--brand); color: #fff; border-top: 0;
  --ink: #FFFFFF; --muted: rgba(255,255,255,.76); --line-soft: rgba(255,255,255,.16);
  --line: rgba(255,255,255,.24); --accent: #FFFFFF;
}
.site-footer .logo, .site-footer .footer-heading, .site-footer .footer-col h3 { color: #fff; }
.site-footer .logo-mark { background: #fff; }
.site-footer .logo-mark::after { background: var(--primary); }
.site-footer .newsletter input { background: rgba(255,255,255,.10); border-color: rgba(255,255,255,.28); color: #fff; }
.site-footer .newsletter input::placeholder { color: rgba(255,255,255,.6); }
.site-footer .btn-accent { background: #fff; color: var(--primary); border-color: #fff; }
.site-footer .footer-legal a, .site-footer .footer-col a { color: rgba(255,255,255,.78); }
.site-footer .footer-legal a:hover, .site-footer .footer-col a:hover { color: #fff; }

/* A green wash over the hero photograph, so the top of the page is not white. */
.hero { background: var(--surface-2); }
.hero-scrim {
  background:
    linear-gradient(to right,
      color-mix(in srgb, var(--accent) 10%, rgba(255,255,255,.93)) 0%,
      color-mix(in srgb, var(--accent) 7%, rgba(255,255,255,.82)) 26%,
      rgba(255,255,255,.32) 46%,
      rgba(255,255,255,0) 64%);
}

/* ---------- 2. the logo ---------- */
.logo.has-logo { gap: 0; }
.logo-img { height: var(--logo-h, 30px); width: auto; max-width: 220px; display: block; object-fit: contain; }
@media (max-width: 620px) { .logo-img { height: calc(var(--logo-h, 30px) * .86); max-width: 160px; } }

/* ---------- 3. comet cards ----------
   The Aceternity "comet card" is a React/Tailwind component and this project is
   EJS with plain CSS, so the behaviour is rebuilt natively: the card tilts toward
   the cursor in 3D and a soft highlight tracks the pointer across it. site.js
   writes --rx/--ry/--mx/--my; everything else is here.

   perspective lives on the outer element so each card tilts in its own space. */
[data-comet] { perspective: 1000px; background: none; border: 0; box-shadow: none; padding: 0; }
.benefit-inner {
  position: relative; height: 100%; display: flex; flex-direction: column;
  background: var(--bg); border: 1px solid var(--accent-line); border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm); overflow: hidden;
  transform-style: preserve-3d;
  transition: transform .5s cubic-bezier(.22,.9,.24,1), box-shadow .4s ease, border-color .4s ease;
}
html.motion [data-comet].is-live .benefit-inner {
  /* Short transition while the pointer is on it, so the tilt tracks rather than lags. */
  transition: transform .12s linear, box-shadow .4s ease, border-color .4s ease;
  transform: rotateX(var(--rx, 0deg)) rotateY(var(--ry, 0deg)) scale(1.02);
  box-shadow: var(--shadow-lg);
  border-color: color-mix(in srgb, var(--accent) 45%, transparent);
}
/* The comet: a soft light that follows the pointer across the card face. */
.comet-glare {
  position: absolute; inset: 0; z-index: 3; pointer-events: none; opacity: 0;
  transition: opacity .35s ease;
  background:
    radial-gradient(240px circle at var(--mx, 50%) var(--my, 50%),
      color-mix(in srgb, var(--accent) 26%, transparent), transparent 62%),
    radial-gradient(500px circle at var(--mx, 50%) var(--my, 50%),
      rgba(255,255,255,.55), transparent 55%);
  mix-blend-mode: soft-light;
}
html.motion [data-comet].is-live .comet-glare { opacity: 1; }

.benefit-media { position: relative; aspect-ratio: 16 / 11; overflow: hidden; background: var(--surface); }
.benefit-media > img, .benefit-media > video { width: 100%; height: 100%; object-fit: cover; display: block; transition: transform .7s cubic-bezier(.22,.9,.24,1); }
html.motion [data-comet].is-live .benefit-media > img,
html.motion [data-comet].is-live .benefit-media > video { transform: scale(1.05); }
.benefit-badge {
  position: absolute; left: 14px; bottom: 14px; z-index: 2;
  display: grid; place-items: center; width: 38px; height: 38px; border-radius: 11px;
  background: rgba(255,255,255,.92); color: var(--accent);
  box-shadow: 0 2px 10px rgba(17,17,17,.14); backdrop-filter: blur(6px);
}
.benefit-badge .icon { width: 19px; height: 19px; }
.benefit-body { padding: clamp(18px, 2vw, 24px); display: flex; flex-direction: column; gap: 6px; flex: 1; }
.benefit.has-media .benefit-num { color: var(--accent); }

/* ---------- 4. media that rises into place ----------
   Used by the science image and the showcase band. Visible by DEFAULT and only
   lowered once JS confirms it will manage the reveal (html.rise-on). Three
   effects in this build could permanently hide content when an observer never
   fired; this one cannot, because without the script nothing is hidden at all. */
html.motion.rise-on [data-rise] {
  opacity: 0;
  transform: translateY(44px) scale(.985);
  transition: opacity .9s cubic-bezier(.22,.9,.24,1), transform .9s cubic-bezier(.22,.9,.24,1);
  will-change: transform, opacity;
}
html.motion.rise-on [data-rise].in { opacity: 1; transform: none; }

/* ---------- 5. the science image, shown whole ---------- */
.tech-media.is-whole {
  aspect-ratio: auto; min-height: clamp(240px, 32vw, 460px);
  display: grid; place-items: center;
  padding: clamp(14px, 2vw, 28px);
  background: var(--surface); border: 1px solid var(--accent-line); box-shadow: var(--shadow-md);
}
.tech-media.is-whole > img, .tech-media.is-whole > video {
  width: 100%; height: auto; max-height: clamp(280px, 42vw, 560px);
  object-fit: contain; border-radius: var(--radius);
}

/* ---------- 6. the showcase band ---------- */
.showcase { background: var(--bg); }
.showcase-frame {
  position: relative; margin: 0; overflow: hidden;
  border-radius: var(--radius-lg); background: var(--surface);
  border: 1px solid var(--accent-line); box-shadow: var(--shadow-lg);
}
.showcase-frame > img, .showcase-frame > video {
  display: block; width: 100%; height: clamp(240px, 42vw, 560px); object-fit: cover;
}
/* "Show the whole image": the frame takes the picture's own shape. */
.showcase-frame.is-whole { padding: clamp(12px, 2vw, 26px); }
.showcase-frame.is-whole > img, .showcase-frame.is-whole > video {
  height: auto; max-height: clamp(300px, 54vw, 720px); object-fit: contain; border-radius: var(--radius);
}
.showcase-frame figcaption {
  padding: 14px 18px 2px; font-size: .86rem; color: var(--muted); text-align: center;
}
.showcase-frame.is-whole figcaption { padding-bottom: 6px; }

/* ---------- 7. a quiet modern cursor ----------
   A small ring that trails the pointer and swells over anything interactive. The
   real cursor is never hidden — the previous build removed the native cursor and
   that is a usability cost with no upside. Fine pointers only.
   It also never covers content: pointer-events are off and it is purely additive. */
.cursor-ring {
  position: fixed; top: 0; left: 0; z-index: 500; pointer-events: none;
  width: 30px; height: 30px; margin: -15px 0 0 -15px; border-radius: 50%;
  border: 1.5px solid color-mix(in srgb, var(--accent) 55%, transparent);
  opacity: 0; transform: translate3d(-100px, -100px, 0);
  transition: opacity .3s ease, width .25s ease, height .25s ease, margin .25s ease,
              background .25s ease, border-color .25s ease;
}
html.has-ring .cursor-ring { opacity: 1; }
.cursor-ring.is-hot {
  width: 54px; height: 54px; margin: -27px 0 0 -27px;
  background: color-mix(in srgb, var(--accent) 12%, transparent);
  border-color: color-mix(in srgb, var(--accent) 70%, transparent);
}
@media (hover: none), (prefers-reduced-motion: reduce) { .cursor-ring { display: none; } }

/* ---------- 9. the stats band reads greener ---------- */
.stats.invert .stat {
  background: rgba(255,255,255,.07); border: 1px solid rgba(255,255,255,.16);
  border-radius: var(--radius-lg);
}
.stats.invert .stat-value { color: #fff; }

/* ---------- 10. small screens ---------- */
@media (max-width: 860px) {
  .tech-media.is-whole { min-height: 200px; }
  .showcase-frame > img, .showcase-frame > video { height: clamp(200px, 56vw, 340px); }
  /* A tilt needs a pointer; on touch the card is simply a card. */
  [data-comet] { perspective: none; }
  .benefit-inner { transform: none !important; }
  .comet-glare { display: none; }
}

/* ---------- more green still ----------
   The first pass was too timid: at 5% the tint read as grey. These are the
   values that actually make the page feel green without turning the product
   photography murky. Three steps so consecutive bands are distinguishable. */
:root {
  /* --surface is supplied by the theme (Admin > Site settings) because head.ejs
     writes it inline and would override anything set here. Only the deeper step
     is defined locally. */
  --surface-2: color-mix(in srgb, var(--accent) 17%, #FFFFFF);
}
/* Alternate the two tints down the page rather than repeating one. */
.section.band { background: var(--surface); }
.section.band-2 { background: var(--surface-2); }

/* The trust strip under the hero is a solid green rule, not a grey one. */
.marquee {
  background: var(--accent); border-block: 0;
  --ink: #FFFFFF; color: #fff;
}
.marquee-item { color: #fff; font-weight: 600; }
.marquee-dot { background: rgba(255,255,255,.55); }

/* Buy module sits on a tint so the white option cards read as cards. */
.buy-section { background: var(--surface); }
.buy-visual { background: #fff; border-color: var(--accent-line); }

/* The closing call to action becomes a solid green band rather than white. */
.final-cta.invert { background: var(--brand); }
.final-cta.invert .display, .final-cta.invert .lead, .final-cta.invert .footnote { color: #fff; }

/* Green numerals and rules wherever a figure or a divider appears. */
.layers li, .metric { border-top-color: var(--accent-line); }
.layer-num, .ingredient-index, .step-num, .benefit-num, .review-status-approved { color: var(--accent); }
.spec-list, .spec { border-color: var(--accent-line); }

/* ---------- an ingredient card with no image yet ----------
   The media panel is dropped from the markup rather than left empty, so the
   card becomes a text card instead of a tall white rectangle. */
/* Top-aligned, so the names line up across cards whose text runs to different
   lengths; bottom-aligning them staggered the headings down a staircase. */
.ingredient-card.no-media { display: flex; flex-direction: column; justify-content: flex-start; min-height: 0; }
.ingredient-card.no-media .ingredient-body { padding-top: clamp(22px, 3vw, 34px); }
.ingredient-card.no-media .ingredient-desc { color: var(--muted); }

/* A stat value typed as "60-day" should not break at its hyphen. */
.stat-value { hyphens: none; overflow-wrap: normal; word-break: keep-all; }

/* ==================================================================
   The community strip, and the science band
   ================================================================== */

/* ---------- community: a marquee the width of the page ----------
   .section carries no horizontal padding, so a direct child already spans the
   full page; only the overflow needs clipping.

   The spacing between cards is a margin on each card rather than a gap on the
   track. With `gap`, 2N cards carry 2N-1 gaps, so half the track width is half a
   gap short of one full period and the loop jumps every pass. A right margin
   makes every card occupy exactly width+gap, which makes -50% exactly one
   period and the seam invisible. */
.tmarquee { overflow: hidden; --tm-gap: clamp(16px, 2vw, 28px); --tm-dur: 48s; }
.tmarquee-track { display: flex; width: max-content; list-style: none; margin: 0; padding: 4px 0; }
.tmarquee .testimonial-card { width: clamp(250px, 25vw, 360px); margin-right: var(--tm-gap); }
html.motion .tmarquee-track {
  animation: tmarquee var(--tm-dur, 70s) linear infinite;
  will-change: transform;
}
@keyframes tmarquee { from { transform: translate3d(0, 0, 0); } to { transform: translate3d(-50%, 0, 0); } }
/* Stop it so a visitor can actually read a review, or tab through one. */
.tmarquee:hover .tmarquee-track,
.tmarquee:focus-within .tmarquee-track { animation-play-state: paused; }
/* Without motion it becomes an ordinary swipe strip rather than freezing. */
@media (prefers-reduced-motion: reduce) {
  .tmarquee { overflow-x: auto; scrollbar-width: none; }
  .tmarquee::-webkit-scrollbar { display: none; }
  .tmarquee-track { animation: none; }
}
@media (max-width: 620px) { .tmarquee .testimonial-card { width: 76vw; } }

/* ---------- science: one image, the full width of the page ----------
   No copy and no frame — the image is the section. It keeps its own aspect
   ratio at full width, so nothing is cropped. */
.tech.tech-full { padding-block: 0; background: var(--bg); }
.section + .section.tech-full { padding-top: 0; }
.tech-full-media { margin: 0; display: block; line-height: 0; }
.tech-full-media > img, .tech-full-media > video {
  /* Full page width, edge to edge, with the height following the image's own
     ratio. An earlier max-height cap kept the band to a screenful, but with
     contain that letterboxed the picture and left white bars down both sides —
     the opposite of the full-width band this is meant to be. A wide banner
     lands short; a tall source image makes a tall band, which is a reason to
     upload a wide one, not a reason to crop or inset it here. */
  display: block; width: 100%; height: auto;
}

/* ---------- a review card with no photo ----------
   Most reviews are words, not pictures. Without a photo the card drops the 4:5
   media panel rather than reserving it, so it sizes to its quote instead of
   standing as a tall white rectangle with a name at the bottom. */
.testimonial-card.no-media .testimonial { gap: 14px; align-content: start; }
.testimonial-card.no-media { align-self: start; }
/* The <li> is the card; the figure inside it just lays the content out. */
.tmarquee .testimonial-card.no-media .testimonial { background: none; border: 0; box-shadow: none; padding: 0; }
.testimonial-rating { line-height: 1; }
.testimonial-rating .stars { font-size: .95rem; }
