/* ============================================================================
   commerce-factory — commerce.css
   Single composed file. No build step. Hand-edit.

   @layer order:
       base, tokens, components, motion, utilities, overrides

   Why a `motion` layer between components and utilities (vs lbcom's
   base/tokens/components/utilities/overrides)?
       liquiddeath ports CSS-only scroll-driven animations
       (`animation-timeline: view()`) in Commit 4. They need to sit *above*
       components (so they can target component classes by name) but *below*
       utilities (so utility classes like `.no-motion` can win without !important).

   Source attributions live inline at each ported block: a short comment
   prefix names the source file + line range + any rename. Per project
   convention, *every* ported block must carry that comment.

   Sources:
       LB  = /home/lb/lbcom/assets/css/style.css                (chassis)
       FB  = /home/lb/fixSites/fabbruccio/css/framework.css     (commerce)
       LD  = /home/lb/fixSites/liquiddeath/css/framework.css    (motion)  [Commit 4]
   ============================================================================ */


/* ── Layer order declaration ─────────────────────────────────────────────────
   Must precede every @layer block. Anything outside @layer (the @property
   declarations and @font-face below) is at the highest cascade tier and
   wins over everything. See LB §7–22.
   ──────────────────────────────────────────────────────────────────────────── */
@layer base, tokens, components, motion, utilities, overrides;


/* ── @property — typed colour custom properties ──────────────────────────────
   PORT: LB style.css L10–22 (verbatim).

   Registering colour tokens with @property gives the browser type information
   for interpolation, which enables smooth theme-switch animations on the
   `html { transition: --bg .3s ease, ... }` block in @layer tokens below.

   Initial values match LB's dark-default semantic tokens. Light theme override
   sits in @layer tokens and just swaps the primitives the semantics alias.
   ──────────────────────────────────────────────────────────────────────────── */
@property --bg   { syntax:'<color>'; inherits:true; initial-value:oklch(18.3% 0.003 299) }
@property --sur  { syntax:'<color>'; inherits:true; initial-value:oklch(21.5% 0.004 300) }
@property --sur2 { syntax:'<color>'; inherits:true; initial-value:oklch(25.0% 0.005 275) }
@property --bdr  { syntax:'<color>'; inherits:true; initial-value:oklch(29.6% 0.005 286) }
@property --bdr2 { syntax:'<color>'; inherits:true; initial-value:oklch(35.1% 0.006 280) }
@property --hi   { syntax:'<color>'; inherits:true; initial-value:oklch(93.0% 0.040 34)  }
@property --tx   { syntax:'<color>'; inherits:true; initial-value:oklch(82.5% 0.036 33)  }
@property --tx2  { syntax:'<color>'; inherits:true; initial-value:oklch(69.7% 0.028 31)  }
@property --tx3  { syntax:'<color>'; inherits:true; initial-value:oklch(63.1% 0.026 32)  }
@property --ac   { syntax:'<color>'; inherits:true; initial-value:oklch(70.0% 0.120 43)  }


/* ── @font-face declarations ─────────────────────────────────────────────────
   PORT: LB style.css L25–48 (subset).

   Kept: Inter (300–600) — body sans. DM Serif Display (regular + italic) —
   heading serif.
   DROPPED from lbcom: Caveat, EB Garamond. They were author-specific
   editorial fonts (signature, long-form essays) and have no place on a
   commerce LP. Two font families is already pushing the page weight budget.

   Font files are expected at /fonts/ relative to commerce.css (so when
   build.py copies commerce.css to dist/, the deploy script mirrors the
   font files under dist/fonts/). If a per-product LP wants to override the
   heading face (e.g. Barlow Condensed for a fitness product) it can do so
   via the @layer overrides block and an @font-face declaration in the
   product config — that's documented in CLAUDE.md, not enforced here.
   ──────────────────────────────────────────────────────────────────────────── */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 300 700;
  font-display: swap;
  src: url('fonts/inter-var-latin.woff2') format('woff2-variations'),
       url('fonts/inter-var-latin.woff2') format('woff2');
  unicode-range: U+0020-007E, U+00A0-00FF, U+2000-206F, U+20A0-20CF, U+2212, U+2248, U+2605;
}
@font-face {
  font-family: 'DMSerif';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('fonts/dm-serif-display-regular-latin.woff2') format('woff2');
  unicode-range: U+0020-007E, U+00A0-00FF, U+2000-206F, U+20A0-20CF;
}


/* ============================================================================
   BASE — reset, element defaults, reduced-motion
   PORT: LB style.css L50–83 (verbatim).
   ============================================================================ */
@layer base {

  *, *::before, *::after {
    box-sizing: border-box;
    margin: 0;
    padding: 0;
  }

  html {
    -webkit-text-size-adjust: 100%;
    text-size-adjust: 100%;
  }

  /* Smooth scroll only when the user hasn't requested reduced motion. */
  @media (prefers-reduced-motion: no-preference) {
    html { scroll-behavior: smooth; }
  }

  body {
    background: var(--bg);
    color: var(--tx);
    font-family: 'Inter', system-ui, sans-serif;
    font-size: var(--t-b);
    font-weight: 400;
    line-height: 1.75;
    -webkit-font-smoothing: antialiased;
    overflow-x: hidden;
  }

  img, video { display: block; max-width: 100%; height: auto; }
  a { color: inherit; text-decoration: none; }
  ul, ol { list-style: none; }

  button, input, textarea, select {
    font: inherit;
    color: inherit;
    background: none;
    border: none;
    outline: none;
  }

  /* Accent-coloured keyboard focus — must be visible on light + dark. */
  :focus-visible {
    outline: 2px solid var(--ac);
    outline-offset: 3px;
    border-radius: 2px;
  }

  /* Headings inherit the serif display face automatically. */
  h1, h2, h3, h4, h5, h6 {
    font-family: 'DMSerif', Georgia, serif;
    color: var(--hi);
    line-height: 1.15;
    font-weight: 400;
  }

  /* Reduced motion — kill all animation/transition globally. Individual
     components opt back in carefully (see @layer motion in Commit 4). */
  @media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
      animation-duration: .01ms !important;
      animation-iteration-count: 1 !important;
      transition-duration: .01ms !important;
    }
  }
}


/* ============================================================================
   TOKENS — primitives → semantic → fluid type/space → dark/light
   PORT: LB style.css L90–188 (verbatim, LOCK-IN — no renames).
   ============================================================================ */
@layer tokens {

  /* ── Primitives (dark palette) — oklch for P3 gamut + perceptual uniformity */
  :root {
    /* Surfaces — near-black with subtle cool-blue undertone */
    --_gray-950:  oklch(18.3% 0.003 299);
    --_gray-900:  oklch(21.5% 0.004 300);
    --_gray-850:  oklch(25.0% 0.005 275);
    --_gray-800:  oklch(29.6% 0.005 286);
    --_gray-750:  oklch(35.1% 0.006 280);

    /* Text — warm parchment scale */
    --_warm-100:  oklch(93.0% 0.040 34);
    --_warm-300:  oklch(82.5% 0.036 33);
    --_warm-500:  oklch(69.7% 0.028 31);
    --_warm-600:  oklch(63.1% 0.026 32);

    /* Accent — amber gold (default; per-product override via --ac in inline
       <style> from base.html.j2, sourced from config.brand_accent). */
    --_amber-400: oklch(70.0% 0.120 43);

    /* Scale constants */
    --_wrap:      1200px;
    --_copy:      720px;
    --_nav-h:     60px;
  }

  /* ── Semantic tokens (dark, default) ─────────────────────────────────────── */
  :root {
    color-scheme: dark light;

    /* Surfaces */
    --bg:   var(--_gray-950);
    --sur:  var(--_gray-900);
    --sur2: var(--_gray-850);
    --bdr:  var(--_gray-800);
    --bdr2: var(--_gray-750);

    /* Text */
    --hi:   var(--_warm-100);
    --tx:   var(--_warm-300);
    --tx2:  var(--_warm-500);
    --tx3:  var(--_warm-600);

    /* Accent — derived tokens use color-mix so a change to --ac cascades. */
    --ac:   var(--_amber-400);
    --ac2:  color-mix(in oklch, var(--ac), black 38%);
    --acg:  color-mix(in oklch, var(--ac) 12%, transparent);

    /* Commerce-factory additions (NOT in lbcom): a "low/mid/hi" derived
       accent set for badges, urgency widgets, sub-save tier highlights.
       Inserted here because all token derivation lives in @layer tokens. */
    --ac-lo: color-mix(in oklch, var(--ac) 6%, transparent);
    --ac-mid: color-mix(in oklch, var(--ac) 28%, transparent);
    --ac-hi:  color-mix(in oklch, var(--ac), white 12%);

    /* Fluid type — v+r formula gives true linear scaling between min/max. */
    --t-xs:  clamp(.72rem,  .4vw + .6rem,  .84rem);
    --t-sm:  clamp(.82rem,  .5vw + .68rem, .97rem);
    --t-b:   clamp(.93rem,  .6vw + .76rem, 1.12rem);
    --t-md:  clamp(1.05rem, 1vw  + .8rem,  1.4rem);
    --t-lg:  clamp(1.2rem,  2vw  + .75rem, 1.85rem);
    --t-xl:  clamp(1.5rem,  3vw  + .75rem, 2.6rem);
    --t-2xl: clamp(1.85rem, 4vw  + .9rem,  3.75rem);
    --t-3xl: clamp(2.1rem,  6vw  + .9rem,  5.5rem);

    /* `--t-2xs` is a NEW commerce-factory token used by breadcrumbs and
       analytics-pin micro-labels. Not in lbcom; smaller than --t-xs. */
    --t-2xs: clamp(.65rem, .3vw + .55rem, .76rem);

    /* Fluid space */
    --s1: clamp(.25rem,  .5vw  + .1rem,  .55rem);
    --s2: clamp(.5rem,   .75vw + .2rem,  .95rem);
    --s3: clamp(.75rem,  1vw   + .35rem, 1.2rem);
    --s4: clamp(1rem,    1.5vw + .5rem,  1.85rem);
    --s5: clamp(1.5rem,  2.5vw + .6rem,  2.9rem);
    --s6: clamp(2rem,    4vw   + .6rem,  4rem);
    --s7: clamp(2.75rem, 5vw   + 1rem,   6rem);
    --s8: clamp(3.5rem,  7vw   + 1rem,   8.5rem);

    /* Misc */
    --r:    5px;
    --r2:   10px;
    --dur:  .18s;
    --ease: cubic-bezier(.4, 0, .2, 1);
    --nav:  var(--_nav-h);
    --wrap: var(--_wrap);
    --copy: var(--_copy);
  }

  /* ── Light-theme override ──────────────────────────────────────────────────
     Only primitives are overridden; semantic tokens cascade automatically. */
  [data-theme="light"] {
    color-scheme: light dark;

    --_gray-950:  oklch(96.0% 0.037 32);
    --_gray-900:  oklch(92.7% 0.040 34);
    --_gray-850:  oklch(89.7% 0.041 35);
    --_gray-800:  oklch(82.9% 0.040 35);
    --_gray-750:  oklch(77.3% 0.041 36);
    --_warm-100:  oklch(20.0% 0.017 35);
    --_warm-300:  oklch(28.5% 0.020 36);
    --_warm-500:  oklch(43.5% 0.021 33);
    --_warm-600:  oklch(49.3% 0.022 32);
    --_amber-400: oklch(59.5% 0.110 40);
  }

  /* Smooth transition between themes — animates token values directly because
     @property gives the browser colour-interpolation knowledge.
     PORT: LB style.css L184. */
  html {
    transition:
      --bg .3s ease, --sur .3s ease, --sur2 .3s ease,
      --bdr .3s ease, --bdr2 .3s ease,
      --hi .3s ease, --tx .3s ease, --tx2 .3s ease, --tx3 .3s ease,
      --ac .3s ease;
  }
}


/* ============================================================================
   COMPONENTS — chassis primitives ported from lbcom
   (Commerce-specific components from fabbruccio are appended in Commit 3.)
   ============================================================================ */
@layer components {


  /* ── Typography helpers ──────────────────────────────────────────────────
     PORT: LB style.css L331–335 (verbatim).
     `.lbl` is the eyebrow micro-label, `.sec-h` the section heading,
     `.sec-sub` the section sub-copy, `.hr-ac` the accent-bar horizontal rule.
     ──────────────────────────────────────────────────────────────────────── */
  .lbl {
    font-size: var(--t-xs);
    letter-spacing: .2em;
    text-transform: uppercase;
    color: var(--ac);
    font-weight: 500;
    display: block;
    margin-bottom: var(--s3);
  }
  .sec-h {
    font-size: var(--t-2xl);
    color: var(--hi);
    margin-bottom: var(--s4);
  }
  .sec-sub {
    font-size: var(--t-md);
    color: var(--tx2);
    max-width: 58ch;
    line-height: 1.65;
    margin-bottom: var(--s5);
  }
  hr { border: none; border-bottom: 1px solid var(--bdr); }
  .hr-ac {
    height: 2px;
    width: 60px;
    background: linear-gradient(90deg, var(--ac), transparent);
    border: none;
    margin-block: var(--s4);
  }


  /* ── Buttons ─────────────────────────────────────────────────────────────
     PORT: LB style.css L318–328.
     ADDITIONS (not in lbcom):
       .btn--lg   — used by sticky-cart on mobile (Commits 9 + 12).
       .btn--block — full-width modifier, also for sticky-cart and ATC.
       .btn--icon — square icon-only modifier (for cart-drawer header, lightbox
                    nav arrows in narrow viewports, etc.). Inherits .btn base.
     Naming preserves lbcom's `.btn--p` / `.btn--g` / `.btn--sm` suffix style
     rather than spelling out `--primary` (consistency wins).
     ──────────────────────────────────────────────────────────────────────── */
  .btn {
    display: inline-flex;
    align-items: center;
    gap: var(--s2);
    padding: var(--s3) var(--s5);
    font-size: var(--t-sm);
    font-weight: 600;
    letter-spacing: .08em;
    text-transform: uppercase;
    border-radius: var(--r);
    cursor: pointer;
    white-space: nowrap;
    border: 1px solid transparent;
    transition:
      background-color var(--dur) var(--ease),
      color var(--dur) var(--ease),
      border-color var(--dur) var(--ease);

    /* Primary — accent fill, bg-coloured text. */
    &.btn--p {
      background: var(--ac);
      color: var(--bg);
      &:hover { background: var(--hi); }
    }
    /* Ghost / outline — secondary actions. */
    &.btn--g {
      border-color: var(--bdr2);
      color: var(--tx2);
      &:hover { border-color: var(--ac); color: var(--hi); }
    }
    /* Small — used by inline form actions, discount-apply, etc. */
    &.btn--sm {
      padding: var(--s2) var(--s3);
      font-size: var(--t-xs);
    }
    /* Large (NEW) — sticky-cart on mobile, hero CTAs. */
    &.btn--lg {
      padding: var(--s4) var(--s6);
      font-size: var(--t-b);
    }
    /* Full-width (NEW) — pairs with --lg and --p for the dominant ATC. */
    &.btn--block {
      width: 100%;
      justify-content: center;
    }
    /* Icon-only square (NEW) — cart drawer close, lightbox nav fallback. */
    &.btn--icon {
      width: 40px;
      height: 40px;
      padding: 0;
      justify-content: center;
    }
    &:disabled {
      opacity: .4;
      cursor: not-allowed;
    }
  }


  /* ── Card primitives ─────────────────────────────────────────────────────
     PORT: LB style.css L338–483.

     Brand-neutralisations:
       - lbcom's `.card--feat` accent-stripe-in animation kept (it's brand-
         neutral mechanically — the bar uses --ac).
       - `.card--img` shimmer / gradient-fade-out kept.
       - lbcom's container queries (`@container (min-width: 360px/400px)`)
         live in @layer utilities to match lbcom layout — same as source.
     COMMERCE EXTENSION (preview — full `.card--product` modifier layered on
       top of fabbruccio's `.pcard` in Commit 3 below).
     ──────────────────────────────────────────────────────────────────────── */
  .card {
    background: var(--sur);
    border: 1px solid var(--bdr);
    border-radius: var(--r);
    overflow: hidden;
    display: flex;
    flex-direction: column;
    position: relative;
    transition-property: background-color, border-color, color;
    transition-duration: .25s;
    transition-timing-function: ease;
    container-type: inline-size;

    & .card__img {
      aspect-ratio: 16/9;
      overflow: hidden;
      border-radius: var(--r) var(--r) 0 0;

      & img {
        width: 100%;
        height: 100%;
        object-fit: cover;
        transition: transform .5s cubic-bezier(.16, 1, .3, 1);
      }
    }
    &:hover .card__img img { transform: scale(1.04); }

    & .card__b {
      padding: var(--s4);
      display: flex;
      flex-direction: column;
      gap: var(--s2);
      flex: 1;
    }
    & .card__tag {
      font-size: var(--t-xs);
      letter-spacing: .12em;
      text-transform: uppercase;
      color: var(--ac);
      font-weight: 500;
    }
    & .card__h {
      font-size: var(--t-lg);
      color: var(--hi);
      line-height: 1.3;
    }
    & .card__x {
      font-size: var(--t-sm);
      color: var(--tx2);
      line-height: 1.65;
      flex: 1;
    }
    & .card__meta {
      font-size: var(--t-xs);
      color: var(--tx3);
      margin-top: var(--s1);
    }
    & .card__a {
      display: inline-flex;
      align-items: center;
      gap: var(--s1);
      margin-top: var(--s3);
      font-size: var(--t-xs);
      letter-spacing: .1em;
      text-transform: uppercase;
      color: var(--ac);
      font-weight: 500;
      transition: gap var(--dur) var(--ease);
      &::after { content: '→'; }
      &:hover { gap: var(--s2); }
    }

    /* Standard (non-image, non-featured) hover: accent underline + glow. */
    &:not(.card--img):not(.card--feat) {
      transition:
        border-color .3s var(--ease),
        box-shadow .3s var(--ease);

      & .card__h { transition: color .25s var(--ease); }
      &::after {
        content: '';
        position: absolute;
        bottom: 0;
        left: 0;
        height: 2px;
        width: 0;
        background: var(--ac);
        transition: width .4s cubic-bezier(.4, 0, .2, 1);
      }
      &:hover {
        border-color: var(--ac);
        box-shadow: 0 0 0 1px var(--ac2), 0 8px 32px rgba(0, 0, 0, .35);
        & .card__h { color: var(--hi); }
        &::after { width: 100%; }
      }
    }

    /* Text card — internal padding, no image. */
    &.card--txt .card__lnk {
      display: flex;
      flex-direction: column;
      gap: var(--s2);
      padding: var(--s5);
      flex: 1;
      color: inherit;
    }

    /* Featured card — large image overlay with stripe-in accent bar. */
    &.card--feat {
      border: none;
      border-radius: var(--r);
      overflow: hidden;
      position: relative;
      box-shadow: 0 0 0 0px var(--ac2);
      transition: box-shadow .45s ease;
      margin-bottom: var(--s6);

      &:hover {
        box-shadow:
          0 0 0 2px var(--ac),
          0 32px 80px color-mix(in oklch, var(--ac) 30%, transparent);
      }
      & .card__lnk {
        display: block;
        position: relative;
        overflow: hidden;
      }
      & img {
        display: block;
        width: 100%;
        height: auto;
        filter: grayscale(40%) brightness(.7);
        transform: scale(1.04);
        transform-origin: center;
        transition:
          transform .9s cubic-bezier(.16, 1, .3, 1),
          filter .75s cubic-bezier(.16, 1, .3, 1);
      }
      &:hover img {
        filter: grayscale(0%) brightness(.85);
        transform: scale(1);
      }
      & .card__over {
        position: absolute;
        inset: 0;
        display: flex;
        flex-direction: column;
        justify-content: flex-end;
        padding: var(--s7) var(--s6);
        background: linear-gradient(
          to top,
          rgba(0, 0, 0, .88) 0%,
          rgba(0, 0, 0, .35) 50%,
          transparent 80%
        );
        transition: opacity .3s ease;
      }
      & .card__tag {
        font-size: var(--t-xs);
        letter-spacing: .16em;
        text-transform: uppercase;
        color: var(--ac);
        font-weight: 500;
        margin-bottom: var(--s3);
        display: block;
      }
      & .card__h {
        font-family: 'DMSerif', serif;
        font-size: var(--t-2xl);
        color: #fff;
        line-height: 1.15;
        max-width: 22ch;
      }
      & .card__x {
        font-size: var(--t-sm);
        color: rgba(255, 255, 255, .75);
        margin-top: var(--s3);
        max-width: 55ch;
        line-height: 1.6;
      }
      &::before {
        content: '';
        position: absolute;
        top: 0;
        left: -100%;
        z-index: 4;
        width: 100%;
        height: 2px;
        background: var(--ac);
        transition: left .55s cubic-bezier(.4, 0, .2, 1);
      }
      &:hover::before { left: 0; }
    }

    /* Image card — image dominates; copy hides on hover for clean reveal. */
    &.card--img {
      border: none;
      box-shadow: 0 0 0 0px var(--ac2);
      transition: box-shadow .45s ease;

      &:hover {
        box-shadow:
          0 0 0 2px var(--ac),
          0 24px 60px color-mix(in oklch, var(--ac) 32%, transparent);
      }
      & .card__lnk {
        display: block;
        position: relative;
        overflow: hidden;

        /* Diagonal shimmer-sweep on hover. */
        &::after {
          content: '';
          position: absolute;
          inset: -10%;
          z-index: 3;
          pointer-events: none;
          width: 40%;
          height: 120%;
          background: linear-gradient(
            105deg,
            transparent 20%,
            rgba(255, 255, 255, .07) 50%,
            transparent 80%
          );
          transform: translateX(-200%) skewX(-12deg);
          transition: transform .7s cubic-bezier(.4, 0, .2, 1);
        }
      }
      &:hover .card__lnk::after { transform: translateX(400%) skewX(-12deg); }

      & img {
        display: block;
        width: 100%;
        height: auto;
        filter: grayscale(70%) brightness(.55) blur(1px);
        transform: scale(1.06);
        transform-origin: center;
        transition:
          transform .75s cubic-bezier(.16, 1, .3, 1),
          filter .65s cubic-bezier(.16, 1, .3, 1) .05s;
      }
      &:hover img {
        filter: blur(0) grayscale(0%) brightness(1);
        transform: scale(1);
      }
      & .card__over {
        position: absolute;
        inset: 0;
        display: flex;
        flex-direction: column;
        justify-content: flex-end;
        padding: var(--s5);
        background: linear-gradient(
          to top,
          rgba(0, 0, 0, .92) 0%,
          rgba(0, 0, 0, .5) 45%,
          rgba(0, 0, 0, .1) 72%,
          transparent 100%
        );
        transition: opacity .25s ease .18s;
      }
      &:hover .card__over { opacity: 0; pointer-events: none; }
      & .card__tag {
        font-size: var(--t-xs);
        letter-spacing: .14em;
        text-transform: uppercase;
        color: var(--ac);
        font-weight: 500;
        display: block;
        margin-bottom: var(--s2);
        transition: opacity .18s ease, transform .25s ease;
      }
      &:hover .card__tag { opacity: 0; transform: translateY(8px); }
      & .card__h {
        color: #fff;
        font-size: var(--t-md);
        line-height: 1.22;
        transition: opacity .18s ease .06s, transform .25s ease .06s;
      }
      &:hover .card__h { opacity: 0; transform: translateY(10px); }
      &::before {
        content: '';
        position: absolute;
        top: 0;
        left: -100%;
        z-index: 4;
        width: 100%;
        height: 2px;
        background: var(--ac);
        transition: left .55s cubic-bezier(.4, 0, .2, 1);
      }
      &:hover::before { left: 0; }

      /* Flat modifier — extreme landscape ratios, separate text panel. */
      &.card--flat {
        & .card__lnk { display: flex; flex-direction: column; overflow: visible; }
        & .card__lnk::after { display: none; }
        & .card__vis { overflow: hidden; }
        & .card__b {
          padding: var(--s3) var(--s4) var(--s4);
          background: var(--sur2);
          border-top: 1px solid var(--bdr);
        }
        & .card__tag { transition: none; }
        &:hover .card__tag { opacity: 1; transform: none; }
        & .card__h {
          color: var(--hi);
          transition: color .25s var(--ease);
        }
        &:hover .card__h { opacity: 1; transform: none; color: var(--hi); }
      }
    }
  }


  /* ── .strip — 3-up feature strip ─────────────────────────────────────────
     PORT: LB style.css L486–497 (verbatim). Used for value-prop rows on PDPs
     (e.g. "no synthetic stimulants / 3rd-party tested / ships from US").
     ──────────────────────────────────────────────────────────────────────── */
  .strip {
    display: grid;
    gap: 1px;
    background: var(--bdr);
    border: 1px solid var(--bdr);
    border-radius: var(--r);
    overflow: hidden;
    container-type: inline-size;

    & .strip__it {
      background: var(--sur);
      padding: var(--s5);
      transition: background-color .25s ease;
      &:hover { background: var(--sur2); }
    }
    & .strip__lbl {
      font-size: var(--t-xs);
      letter-spacing: .15em;
      text-transform: uppercase;
      color: var(--ac);
      margin-bottom: var(--s2);
      display: block;
    }
    & .strip__h {
      font-size: var(--t-lg);
      color: var(--hi);
      margin-bottom: var(--s2);
    }
    & .strip__d {
      font-size: var(--t-sm);
      color: var(--tx2);
      line-height: 1.6;
    }
  }


  /* ── .buybox — product buy-box ancestor (RENAMED) ────────────────────────
     PORT: LB style.css L500–507 (`.book-blk`).
     RENAME: `.book-blk` → `.buybox`. The lbcom name was book-specific
     (single-book content site). The block's structure (image + text +
     buttons side-by-side at 640px+, cover-style shadow) is the natural
     ancestor of a product buy-box for any single SKU PDP. Generalising the
     name unblocks reuse.
     ──────────────────────────────────────────────────────────────────────── */
  .buybox {
    background: var(--sur);
    border: 1px solid var(--bdr);
    border-radius: var(--r2);
    padding: var(--s6);
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--s5);
    text-align: center;
    transition-property: background-color, border-color;
    transition-duration: .25s;
    transition-timing-function: ease;
  }
  /* Cover-style shadow, inherited from lbcom's `.book-cover`. The class is
     kept under its commerce-generic alias `.buybox__img`. */
  .buybox__img {
    width: min(160px, 60%);
    border-radius: var(--r);
    box-shadow: 16px 16px 48px rgba(0, 0, 0, .55);
  }


  /* ── .nl — newsletter card ───────────────────────────────────────────────
     PORT: LB style.css L509–517 (verbatim).
     Used for: footer opt-in, cart-abandon recapture modal, exit-intent.
     Same component, three placements.
     ──────────────────────────────────────────────────────────────────────── */
  .nl {
    background: var(--sur);
    border: 1px solid var(--bdr);
    border-radius: var(--r2);
    padding: var(--s6);
    text-align: center;
    transition-property: background-color, border-color;
    transition-duration: .25s;
    transition-timing-function: ease;
  }
  .nl__h    { font-size: var(--t-xl); margin-bottom: var(--s3); }
  .nl__sub  { font-size: var(--t-sm); color: var(--tx2); margin-bottom: var(--s5);
              max-width: 48ch; margin-inline: auto; }
  .nl__form { display: flex; flex-direction: column; gap: var(--s3);
              max-width: 440px; margin-inline: auto; }


  /* ── Forms ───────────────────────────────────────────────────────────────
     PORT: LB style.css L519–536.
     EXTENSIONS (NEW):
       .fin--num — numeric stepper styling for qty inputs (used on PDP).
       .fchk     — checkbox row (used by .bump in Commit 9; sub-save in
                   Commit 5 uses radios styled differently).
     ──────────────────────────────────────────────────────────────────────── */
  .fg   { display: flex; flex-direction: column; gap: var(--s2); }
  .flbl {
    font-size: var(--t-xs);
    letter-spacing: .12em;
    text-transform: uppercase;
    color: var(--tx2);
    font-weight: 500;
  }
  .fin, .fta, .fsel {
    background: var(--sur2);
    border: 1px solid var(--bdr2);
    border-radius: var(--r);
    padding: var(--s3) var(--s4);
    font-size: var(--t-b);
    color: var(--tx);
    transition:
      border-color var(--dur) var(--ease),
      box-shadow var(--dur) var(--ease);
    width: 100%;
    -webkit-appearance: none;

    &:focus {
      border-color: var(--ac);
      box-shadow: 0 0 0 3px var(--acg);
    }
    &::placeholder { color: var(--tx3); }
  }
  .fta   { resize: vertical; min-height: 130px; }
  .fnote { font-size: var(--t-xs); color: var(--tx3); }

  /* Issue #13 — footer newsletter input border was invisible because the
     default .fin background and the footer surface were too close in value.
     Force a high-contrast 2px solid border in the footer (using --tx3 which
     is the darkest available token after --hi) + white-ish background so
     it reads as an interactive field, not a div. */
  .ft .nl__form .fin {
    border: 2px solid var(--tx3);
    background: #ffffff;
    color: var(--hi);
  }
  .ft .nl__form .fin::placeholder { color: var(--tx3); }
  .ft .nl__form .fin:focus {
    border-color: var(--ac);
    box-shadow: 0 0 0 3px var(--acg);
    outline: none;
  }
  .ferr  { font-size: var(--t-xs); color: oklch(62% 0.18 22); margin-top: var(--s2); }
  .fsuc  {
    display: none;
    background: var(--ac-lo);
    border: 1px solid var(--ac2);
    border-radius: var(--r);
    padding: var(--s4);
    text-align: center;
    color: var(--ac);
    font-size: var(--t-sm);
  }

  /* NEW — numeric stepper (qty). Tabular nums so the digits don't shift width. */
  .fin--num {
    width: auto;
    min-width: 4ch;
    text-align: center;
    font-variant-numeric: tabular-nums;
    padding: var(--s2) var(--s3);
  }
  /* NEW — checkbox row (used by .bump in Commit 9, FAQ "I agree" toggles, etc.). */
  .fchk {
    display: flex;
    align-items: flex-start;
    gap: var(--s2);
    font-size: var(--t-sm);
    color: var(--tx);
    cursor: pointer;

    & input[type="checkbox"] {
      appearance: none;
      -webkit-appearance: none;
      width: 18px;
      height: 18px;
      border: 1px solid var(--bdr2);
      border-radius: 3px;
      background: var(--sur2);
      cursor: pointer;
      flex-shrink: 0;
      margin-top: 3px;
      position: relative;
      transition: border-color var(--dur) var(--ease), background var(--dur) var(--ease);

      &:checked {
        background: var(--ac);
        border-color: var(--ac);
        &::after {
          content: '✓';
          position: absolute;
          inset: 0;
          display: flex;
          align-items: center;
          justify-content: center;
          color: var(--bg);
          font-size: 12px;
          line-height: 1;
        }
      }
      &:focus-visible {
        outline: 2px solid var(--ac);
        outline-offset: 2px;
      }
    }
  }


  /* ── Prose — long-form editorial copy ────────────────────────────────────
     PORT: LB style.css L610–651 (verbatim, comments preserved).
     Used for ingredient panels, science copy, FAQ long answers.
     ──────────────────────────────────────────────────────────────────────── */
  .prose {
    max-width: var(--copy);
    margin-inline: auto;

    & h2 {
      font-size: var(--t-xl);
      color: var(--hi);
      margin-top: var(--s7);
      margin-bottom: var(--s4);
      padding-top: var(--s5);
      border-top: 1px solid var(--bdr);
    }
    & h3 {
      font-size: var(--t-lg);
      color: var(--hi);
      margin-top: var(--s5);
      margin-bottom: var(--s3);
    }
    & h4 {
      font-family: 'DMSerif', serif;
      font-style: italic;
      font-weight: 400;
      font-size: var(--t-xl);
      color: var(--hi);
      line-height: 1.35;
      margin-block: var(--s6);
      padding-left: var(--s5);
      border-left: 3px solid var(--ac);

      & em, & strong {
        font-style: normal;
        color: var(--hi);
      }
    }
    & p          { margin-bottom: var(--s4); line-height: 1.8; }
    & ul, & ol   { margin-bottom: var(--s4); padding-left: var(--s5); }
    & ul         { list-style: disc; }
    & ol         { list-style: decimal; }
    & li         { margin-bottom: var(--s2); line-height: 1.75; }
    & strong     { color: var(--hi); font-weight: 600; }
    & em         { color: var(--tx2); }
    & a {
      color: var(--ac);
      border-bottom: 1px solid var(--ac2);
      transition: border-color var(--dur) var(--ease);
      &:hover { border-color: var(--ac); }
    }
    & img {
      display: block;
      width: 100%;
      height: auto;
      max-height: 520px;
      object-fit: cover;
      object-position: center 20%;
      border-radius: var(--r);
      margin-block: var(--s5);
    }
    & iframe, & embed, & object {
      width: 100%;
      height: auto;
      aspect-ratio: 16/9;
      border: none;
      border-radius: var(--r);
      margin-block: var(--s5);
    }
    & blockquote {
      border-left: 3px solid var(--ac);
      padding-left: var(--s5);
      margin-block: var(--s5);
      color: var(--tx2);
      font-family: 'DMSerif', serif;
      font-size: var(--t-lg);
      font-style: italic;
      line-height: 1.5;
    }
  }


  /* ── Footer ──────────────────────────────────────────────────────────────
     PORT: LB style.css L692–713 (verbatim).
     ──────────────────────────────────────────────────────────────────────── */
  .ft {
    border-top: 1px solid var(--bdr);
    padding-block: var(--s7);
    margin-top: var(--s8);
    transition-property: background-color, border-color, color;
    transition-duration: .25s;
    transition-timing-function: ease;

    & .ft__grid    { display: grid; gap: var(--s5); }
    & .ft__brand-h {
      font-family: 'DMSerif', serif;
      font-size: var(--t-lg);
      color: var(--hi);
      margin-bottom: var(--s2);
    }
    & .ft__brand-d {
      font-size: var(--t-sm);
      color: var(--tx2);
      line-height: 1.6;
      max-width: 28ch;
    }
    & .ft__col-h {
      font-size: var(--t-xs);
      letter-spacing: .15em;
      text-transform: uppercase;
      color: var(--tx3);
      margin-bottom: var(--s3);
    }
    & .ft__links  { display: flex; flex-direction: column; gap: var(--s2); }
    & .ft__link {
      font-size: var(--t-sm);
      color: var(--tx2);
      transition: color var(--dur) var(--ease);
      &:hover { color: var(--hi); }
    }
    & .ft__bot {
      display: flex;
      align-items: center;
      justify-content: space-between;
      flex-wrap: wrap;
      gap: var(--s3);
      padding-top: var(--s5);
      margin-top: var(--s5);
      border-top: 1px solid var(--bdr);
    }
    & .ft__copy { font-size: var(--t-xs); color: var(--tx3); }
    & .ft__soc  { display: flex; gap: var(--s2); }
    & .ft__s {
      width: 30px;
      height: 30px;
      border: 1px solid var(--bdr);
      border-radius: var(--r);
      display: flex;
      align-items: center;
      justify-content: center;
      font-size: 12px;
      color: var(--tx2);
      transition: border-color var(--dur) var(--ease), color var(--dur) var(--ease);
      &:hover { border-color: var(--ac); color: var(--ac); }
    }
    & .ft__theme {
      text-align: center;
      padding-top: var(--s3);
      border-top: 1px solid var(--bdr);
      margin-top: var(--s3);
    }
  }


  /* ── Theme toggle pill ───────────────────────────────────────────────────
     PORT: LB style.css L715–724 (verbatim).
     ──────────────────────────────────────────────────────────────────────── */
  .theme-tog {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: var(--s2) var(--s4);
    font-size: var(--t-xs);
    font-weight: 600;
    letter-spacing: .1em;
    text-transform: uppercase;
    color: var(--tx2);
    border: 1px solid var(--bdr2);
    border-radius: 100px;
    cursor: pointer;
    background: none;
    transition: color var(--dur) var(--ease), border-color var(--dur) var(--ease);

    &:hover { color: var(--hi); border-color: var(--ac); }
  }


  /* ── Stats (fallback) ────────────────────────────────────────────────────
     PORT: LB style.css L727–733 (verbatim).
     Note: liquiddeath's `.stats-strip` (ported in Commit 4) is the preferred
     PDP variant — denser, animated counters. This `.stats` block stays as
     the fallback / non-motion option for non-LP pages.
     ──────────────────────────────────────────────────────────────────────── */
  .stats {
    display: grid;
    gap: 1px;
    background: var(--bdr);
    border: 1px solid var(--bdr);
    border-radius: var(--r);
    overflow: hidden;
    margin-block: var(--s5);

    & .stat { background: var(--sur); padding: var(--s4); text-align: center; }
    & .stat__v {
      font-family: 'DMSerif', serif;
      font-size: var(--t-2xl);
      color: var(--ac);
      line-height: 1;
      margin-bottom: var(--s1);
    }
    & .stat__l {
      font-size: var(--t-xs);
      letter-spacing: .12em;
      text-transform: uppercase;
      color: var(--tx2);
    }
  }


  /* ── Back link ───────────────────────────────────────────────────────────
     PORT: LB style.css L682–689 (verbatim). Used for "← back to all
     products" on collection / PDP / upsell pages.
     ──────────────────────────────────────────────────────────────────────── */
  .back {
    display: inline-flex;
    align-items: center;
    gap: var(--s2);
    font-size: var(--t-xs);
    letter-spacing: .1em;
    text-transform: uppercase;
    color: var(--tx3);
    margin-bottom: var(--s4);
    transition: color var(--dur) var(--ease);

    &::before { content: '←'; }
    &:hover   { color: var(--tx2); }
  }


  /* ── Page hero / page header (PDP top) ───────────────────────────────────
     PORT: LB style.css L549–556 (verbatim). Used on collection pages and as
     the page-header above PDP gallery on narrow viewports.
     ──────────────────────────────────────────────────────────────────────── */
  .ph {
    padding-top: var(--s7);
    padding-bottom: var(--s5);
    border-bottom: 1px solid var(--bdr);
    margin-bottom: var(--s6);

    & .ph__lbl {
      font-size: var(--t-xs);
      letter-spacing: .2em;
      text-transform: uppercase;
      color: var(--ac);
      display: block;
      margin-bottom: var(--s3);
    }
    & .ph__h {
      font-size: var(--t-2xl);
      color: var(--hi);
      line-height: 1.1;
      max-width: 20ch;
    }
    & .ph__sub {
      font-size: var(--t-md);
      color: var(--tx2);
      font-family: 'DMSerif', serif;
      font-style: italic;
      margin-top: var(--s3);
    }
  }


  /* ── Callout (sidebar warning / info panel) ──────────────────────────────
     PORT: LB style.css L658–664 (verbatim). Used for shipping-window
     notes, allergen warnings, "subscribe and lock in pricing" callouts.
     ──────────────────────────────────────────────────────────────────────── */
  .callout {
    background: var(--sur);
    border: 1px solid var(--bdr2);
    border-left: 3px solid var(--ac);
    border-radius: 0 var(--r) var(--r) 0;
    padding: var(--s4) var(--s5);
    margin-block: var(--s5);

    & code {
      font-family: ui-monospace, 'Courier New', monospace;
      font-size: var(--t-lg);
      color: var(--ac);
      display: block;
      margin-bottom: var(--s2);
    }
    & p { font-size: var(--t-sm); color: var(--tx2); margin: 0; }
  }

} /* end @layer components */


/* ============================================================================
   MOTION — CSS-only scroll-driven animations
   COMMIT 4 — LD port (framework.css L715–806).

   Liquid Death pioneered a now-standard pattern: declare keyframes outside
   any @media, then gate the *application* (animation-timeline:view() on
   selectors) inside `@media (prefers-reduced-motion: no-preference)`. The
   keyframes themselves are cheap to leave around — they only run when a
   selector picks them up. Result: zero motion cost for opt-out users, zero
   duplicated CSS for everyone else.

   RENAMES from source (per CLAUDE.md):
     gold-shim → accent-shim   (LD's literal --gold token replaced with our
                                cascading --ac → --ac-hi token pair, so a
                                per-product brand_accent override animates
                                correctly out of the box).

   We DO NOT port:
     - `.nav` slide-in (`nav-drop`) — our nav animation is owned by the lbcom
       chassis transition system; layering an LD nav-drop on top causes a
       double-translate.
     - `main { animation: page-in }` — same reason: lbcom's `<body>` fade-in
       is already in @layer base. Adding LD's page-in would re-trigger after
       theme-toggle (because the @property tx transition restyles main),
       which looks like a glitch.

   What we DO port:
     - hero-in (translate-only entrance, LCP-safe — no opacity on the
       above-fold heading or it can hurt the LCP image score on Lighthouse)
     - reveal-up (universal "enters viewport, lifts in" pattern)
     - accent-shim (renamed gold-shim — stat-value pulse)
     - parallax-drift (feat__img scroll-parallax)
     - heading-compress (letter-spacing tightens as heading enters)
     - nth-child staggered offsets on stats (each tile delayed by ~8% scroll)
   ============================================================================ */
@layer motion {

  /* ── Keyframes — always-defined; only run when a selector adopts them ──── */
  @keyframes hero-in {
    from { translate: 0 1.8rem; }
    to   { translate: 0 0; }
  }
  @keyframes reveal-up {
    from { opacity: 0; translate: 0 1.4rem; }
    to   { opacity: 1; translate: 0 0; }
  }
  /* PORT/RENAME: LD `gold-shim` → `accent-shim`. The original cycles between
     --gold and --gold-hi (literal brand colors). We cycle between --ac and
     --ac-hi (semantic accent tokens), so a per-product `brand_accent` in
     config.json automatically picks up the shimmer without code change.
     `--ac-hi` is derived in @layer tokens as `color-mix(--ac, white 12%)`. */
  @keyframes accent-shim {
    0%, 100% { color: var(--ac); }
    50%      { color: var(--ac-hi); }
  }
  @keyframes parallax-drift {
    from { translate: 0 -6%; }
    to   { translate: 0  6%; }
  }
  @keyframes heading-compress {
    from { letter-spacing: .05em; opacity: 0; }
    to   { letter-spacing: -.01em; opacity: 1; }
  }
  @keyframes mega-in {
    from { opacity: 0; transform: translateY(-6px); }
    to   { opacity: 1; transform: translateY(0); }
  }

  /* `accent-shim` placeholder rule promised in Commit 3 — defined here so
     any element with the `.accent-shim` utility class pulses the accent
     gradient continuously. Keep the *infinite* variant in the gated block
     below so it stops for reduced-motion users; expose the keyframes here
     so transient one-shot usage (e.g. price flash on subsave change) works
     regardless of motion preference. */
  .accent-shim { color: var(--ac); }

  /* ── Gated application — only when the user opts in (or doesn't opt out) ── */
  @media (prefers-reduced-motion: no-preference) {

    /* Hero / above-fold text — translate-only (NO opacity), LCP-safe.
       LD's audit specifically called this out: avoid opacity on the LCP
       element or Lighthouse penalises the paint timing. Apply only to
       child elements (not the hero image itself).
       SOURCE: LD framework.css L730–736. */
    .hero__txt > *,
    .hero-slide__txt > * {
      animation: hero-in .75s cubic-bezier(.16, 1, .3, 1) both;
    }
    .hero__txt > *:nth-child(2),
    .hero-slide__txt > *:nth-child(2) { animation-delay: .08s; }
    .hero__txt > *:nth-child(3),
    .hero-slide__txt > *:nth-child(3) { animation-delay: .16s; }
    .hero__txt > *:nth-child(4),
    .hero-slide__txt > *:nth-child(4) { animation-delay: .24s; }

    /* Scroll-driven reveals on section headers and primary text blocks.
       SOURCE: LD framework.css L739–743.
       Our additions vs LD: include `.buybox`, `.urgency`, `.trust-strip`
       so the commerce-specific blocks get the same reveal treatment. */
    .sh,
    .mission-txt,
    .feat__body,
    .vid-sect__body,
    .buybox,
    .urgency,
    .trust-strip {
      animation: reveal-up linear both;
      animation-timeline: view();
      animation-range: entry 0% entry 32%;
    }

    /* Auto-reveal on common grid children — zero markup changes.
       SOURCE: LD framework.css L746–751 + commerce additions for
       collection-grid (fabbruccio) and product-grid (LD). */
    .cat-grid > *,
    .product-grid > *,
    .collection-grid > *,
    .retailer-grid > *,
    .grid--3 > .perk-card,
    .job-card {
      animation: reveal-up linear both;
      animation-timeline: view();
      animation-range: entry 0% entry 38%;
    }

    /* Manual reveal utilities — apply `.reveal` or `.reveal-grid` to opt-in.
       NOTE: `.reveal` in @layer utilities is the IntersectionObserver
       fallback (used when `animation-timeline:view()` isn't supported).
       Both can co-exist: this scroll-driven rule wins on supporting
       browsers because @layer motion follows @layer utilities in the
       cascade ORDER declared in commerce.css L31. */
    .reveal {
      animation: reveal-up linear both;
      animation-timeline: view();
      animation-range: entry 0% entry 28%;
    }
    .reveal-grid > * {
      animation: reveal-up linear both;
      animation-timeline: view();
      animation-range: entry 0% entry 30%;
    }

    /* Stat value continuous shimmer.
       SOURCE: LD framework.css L766. Renamed keyframes per RENAMES above. */
    .stat-item__val,
    .accent-shim--pulse {
      animation: accent-shim 4s ease-in-out infinite;
    }

    /* Enhanced hovers (depend on motion being allowed).
       SOURCE: LD framework.css L769–778. */
    .job-card:hover {
      box-shadow:
        0 0 0 1px var(--ac),
        0 12px 36px color-mix(in oklch, var(--ac) 10%, transparent);
    }
    .perk-card {
      transition:
        border-color var(--dur) var(--ease),
        transform var(--dur) var(--ease),
        box-shadow var(--dur) var(--ease);
    }
    .perk-card:hover {
      border-color: var(--bdr2);
      transform: translateY(-4px);
      box-shadow: 0 12px 40px rgba(0, 0, 0, .5);
    }
    .retailer-card {
      transition:
        border-color var(--dur) var(--ease),
        transform var(--dur) var(--ease);
    }
    .retailer-card:hover { transform: translateY(-3px); }
    .step::before {
      transition:
        border-color var(--dur) var(--ease),
        color var(--dur) var(--ease),
        box-shadow var(--dur) var(--ease);
    }
    .step:hover::before {
      border-color: var(--ac-hi);
      box-shadow: 0 0 14px color-mix(in oklch, var(--ac) 30%, transparent);
    }

    /* Button press feedback — small scale-down on active.
       SOURCE: LD framework.css L778. Affects every .btn modifier. */
    .btn:active {
      transform: translateY(1px) scale(.98);
      transition-duration: .05s;
    }

    /* Parallax drift on feature image inside .feat (or LD's `.feat__img`).
       Image translates from -6% to +6% as section scrolls through viewport,
       creating a subtle depth shift without a fixed-position trick.
       SOURCE: LD framework.css L784–788. */
    .feat__img,
    .vid-sect__bg {
      animation: parallax-drift linear both;
      animation-timeline: view();
      animation-range: entry 0% exit 100%;
    }

    /* Heading compression — letter-spacing collapses from .05em to -.01em
       as the heading enters the viewport. Compounds cleanly with parent
       reveal-up because they animate different properties.
       SOURCE: LD framework.css L792–796. */
    .sh__h,
    .feat__h,
    .vid-sect__body h2 {
      animation: heading-compress linear both;
      animation-timeline: view();
      animation-range: entry 0% entry 32%;
    }

    /* Staggered stats — each tile reveals at a different scroll offset.
       SOURCE: LD framework.css L799–805. The :nth-child offsets create a
       cascading entrance without any JS delay tracking. */
    .stat-item {
      animation: reveal-up linear both;
      animation-timeline: view();
      animation-range: entry 0% entry 40%;
    }
    .stat-item:nth-child(2) { animation-range: entry  8% entry 48%; }
    .stat-item:nth-child(3) { animation-range: entry 16% entry 56%; }
    .stat-item:nth-child(4) { animation-range: entry 24% entry 64%; }
    .stat-item:nth-child(5) { animation-range: entry 32% entry 72%; }

  } /* end @media prefers-reduced-motion: no-preference */
} /* end @layer motion */


/* ============================================================================
   UTILITIES — layout helpers, container queries, breakpoints
   PORT: LB style.css L752–817 (verbatim).
   ============================================================================ */
@layer utilities {

  /* ── Layout ─────────────────────────────────────────────────────────────── */
  .wrap {
    width: 100%;
    max-width: var(--wrap);
    margin-inline: auto;
    padding-inline: var(--s4);
  }
  .wrap--copy {
    max-width: var(--copy);
    padding-block: var(--s7);
  }
  .sec     { padding-block: var(--s7); }
  .sec--sm { padding-block: var(--s5); }
  .page    { padding-top: var(--nav); }

  /* `.stack` and `.cluster` aren't strictly in lbcom (lbcom relies on `gap`
     directly). Added here as utility classes because they show up so often
     on PDPs — stack = vertical rhythm, cluster = horizontal with wrap.
     This is the *only* lbcom-departure in @layer utilities. */
  .stack    { display: flex; flex-direction: column; gap: var(--s3); }
  .stack--lg { gap: var(--s5); }
  .stack--sm { gap: var(--s2); }
  .cluster  { display: flex; flex-wrap: wrap; gap: var(--s2); align-items: center; }

  /* Container (alias for `.wrap`) — exposed as a more conventional name for
     templates ported from outside lbcom. Same rules. */
  .container { width: 100%; max-width: var(--wrap); margin-inline: auto; padding-inline: var(--s4); }

  /* ── Grid helpers ─────────────────────────────────────────────────────── */
  .grid       { display: grid; gap: var(--s4); container-type: inline-size; }
  .grid--loose { gap: var(--s6); }

  /* ── Blog grid — CSS columns masonry ──────────────────────────────────── */
  .blog-grid { columns: 2; column-gap: var(--s4); container-type: inline-size; }
  .blog-grid article,
  .blog-grid a.card { break-inside: avoid; margin-bottom: var(--s4); display: block; }
  .blog-grid .card--txt { min-height: 130px; }

  /* ── Scroll reveal (legacy IntersectionObserver fallback) ─────────────── */
  /* Primary motion is the `@layer motion` block (LD port, Commit 4). This
     `.reveal` opacity-translate is kept as a fallback for browsers without
     `animation-timeline: view()` (i.e. anything below Chrome 117). */
  .reveal {
    opacity: 0;
    transform: translateY(18px);
    transition:
      opacity .45s var(--ease),
      transform .45s var(--ease);
  }
  .reveal.visible { opacity: 1; transform: none; }
  @media (prefers-reduced-motion: reduce) {
    .reveal { opacity: 1; transform: none; transition: none; }
  }

  /* ── Responsive breakpoints ──────────────────────────────────────────── */
  @media (min-width: 640px) {
    .nl__form  { flex-direction: row; }
    .buybox    { flex-direction: row; text-align: left; align-items: center; }
    .buybox__img { width: min(180px, 30%); }
  }
  @media (min-width: 768px) {
    :root { --nav: 68px; }
    .grid--2 { grid-template-columns: 1fr 1fr; }
    .grid--3 { grid-template-columns: repeat(3, 1fr); }
    .strip   { grid-template-columns: repeat(3, 1fr); }
    .ft__grid { grid-template-columns: 1.4fr 1fr 1fr 1fr; }
    .stats   { grid-template-columns: repeat(3, 1fr); }
    .blog-grid { columns: 3; }
  }
  @media (min-width: 1024px) {
    .two-col {
      display: grid;
      grid-template-columns: 1fr 1fr;
      gap: var(--s7);
      align-items: start;
    }
  }

  /* ── Container queries — card content adapts to card width ──────────── */
  /* Fire based on each .card element's own inline size, not the viewport. */
  @container (min-width: 360px) {
    .card--img .card__h { font-size: var(--t-lg); }
  }
  @container (min-width: 400px) {
    .card--txt .card__h { font-size: var(--t-xl); }
  }

  /* ── A11y — visually hidden but screen-reader-readable ───────────────── */
  /* NEW — not in lbcom but every commerce LP needs this for ATC button
     labels, lightbox counters, urgency widget hidden detail. */
  .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;
  }

} /* end @layer utilities */


/* ============================================================================
   OVERRIDES — per-deploy customisations
   Anything here wins over all framework layers automatically.
   Per-product `brand_accent` override is injected via inline <style> from
   base.html.j2 (Commit 7) — it just sets `--ac` and the rest cascades.
   ============================================================================ */
@layer overrides {
  /* commerce-factory baseline — no overrides. Per-product overrides land
     inline in <head> via base.html.j2 from config.brand_accent. */
}


/* ============================================================================
   COMMERCE COMPONENTS (Commit 3 — fabbruccio port)
   Appended below to preserve cascade source-order. Everything from here on
   is added by Commit 3; the `@layer components` reopen pattern keeps it
   layered correctly with the lbcom block above.
   ============================================================================ */
@layer components {


  /* ── .breadcrumb ─────────────────────────────────────────────────────────
     PORT: FB framework.css L912–925 (verbatim).
     Used at the top of every PDP — Home / Category / Product Name.
     ──────────────────────────────────────────────────────────────────────── */
  .breadcrumb {
    font-size: var(--t-2xs);
    letter-spacing: .14em;
    text-transform: uppercase;
    color: var(--tx3);
    display: flex;
    align-items: center;
    gap: var(--s2);
    flex-wrap: wrap;
  }
  .breadcrumb a {
    color: var(--tx3);
    transition: color var(--dur) var(--ease);
    &:hover { color: var(--tx2); }
  }
  .breadcrumb__sep { color: var(--bdr2); }


  /* ── .collection-grid + .pcard — product card grid ───────────────────────
     PORT: FB framework.css L423–487 (verbatim structure; chrome trimmed).

     The fabbruccio version assumes one font (Playfair Display italic for
     names) and zero card chrome. We retain the no-chrome aesthetic because
     it's the canonical "minimalist commerce" look but route the name face
     through `DMSerif` (the lbcom heading serif) so we don't need a second
     serif download.

     Zero-JS hover image swap kept (the `.pcard__img--alt` overlay).
     ──────────────────────────────────────────────────────────────────────── */
  .collection-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(min(100%, 320px), 1fr));
    gap: var(--s1);
  }

  .pcard {
    display: block;
    text-decoration: none;
    color: inherit;
    cursor: pointer;
  }
  .pcard__img-wrap {
    position: relative;
    overflow: hidden;
    background: var(--sur);
    aspect-ratio: 4/3;
  }
  .pcard__img {
    width: 100%;
    height: 100%;
    object-fit: contain;
    transition: opacity var(--dur) var(--ease);
  }
  .pcard__img--alt {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: contain;
    opacity: 0;
    transition: opacity 400ms var(--ease);
  }
  .pcard:hover .pcard__img        { opacity: 0; }
  .pcard:hover .pcard__img--alt   { opacity: 1; }

  .pcard__info {
    padding: var(--s2) 0 var(--s3);
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--s3);
  }
  .pcard__name {
    /* lbcom serif instead of fabbruccio's Playfair — see comment above. */
    font-family: 'DMSerif', Georgia, serif;
    font-style: italic;
    font-weight: 400;
    font-size: var(--t-sm);
    color: var(--tx);
  }
  .pcard__price {
    font-size: var(--t-xs);
    color: var(--tx3);
    white-space: nowrap;
    font-variant-numeric: tabular-nums;
    letter-spacing: .04em;
  }


  /* ── .product-layout — PDP main grid ─────────────────────────────────────
     PORT: FB framework.css L489–510 (verbatim).
     58% gallery / 42% details at 900px+; gallery becomes sticky.
     ──────────────────────────────────────────────────────────────────────── */
  .product-layout {
    display: grid;
    grid-template-columns: 1fr;
    min-height: 100svh;
  }

  @media (min-width: 900px) {
    .product-layout {
      grid-template-columns: 58% 42%;
      align-items: start;
    }
    .product-layout__gallery {
      position: sticky;
      top: 0;
      height: 100svh;
    }
    .product-layout__details {
      padding: var(--s6) var(--s6) var(--s7) var(--s5);
      max-width: 520px;
    }
  }


  /* ── .gallery + .gallery__main + .gallery__thumb ─────────────────────────
     PORT: FB framework.css L512–568 (verbatim).
     Main image swaps on thumb click (handled by commerce.js initGallery).
     ──────────────────────────────────────────────────────────────────────── */
  .gallery {
    display: flex;
    flex-direction: column;
    height: 100%;
  }
  .gallery__main {
    flex: 1;
    position: relative;
    background: var(--sur);
    overflow: hidden;
    cursor: zoom-in;
    min-height: 320px;
  }
  .gallery__main picture,
  .gallery__main img {
    width: 100%;
    height: 100%;
    object-fit: contain;
    display: block;
    transition: opacity 200ms var(--ease);
  }
  .gallery__main img.swapping { opacity: 0; }

  .gallery__thumbs {
    display: flex;
    gap: 2px;
    /* fabbruccio used a separate `--bg-deep` token — we use `--sur2` because
       commerce-factory's token system doesn't ship a 6th surface tier. */
    background: var(--sur2);
    overflow-x: auto;
    scrollbar-width: none;
    flex-shrink: 0;
  }
  .gallery__thumbs::-webkit-scrollbar { display: none; }

  .gallery__thumb {
    flex-shrink: 0;
    width: clamp(48px, 14%, 72px);
    aspect-ratio: 4/3;
    overflow: hidden;
    cursor: pointer;
    opacity: .45;
    background: var(--sur);
    transition: opacity var(--dur) var(--ease);
    border: none;
    padding: 0;

    & img {
      width: 100%;
      height: 100%;
      object-fit: contain;
      display: block;
    }
    &:hover { opacity: .72; }
    &.active { opacity: 1; }
  }


  /* ── .product-details + .product-price ───────────────────────────────────
     PORT: FB framework.css L570–590 (verbatim structure).
     The font-family hard-coded to Playfair in fabbruccio is dropped — the
     `<h1>` inherits DMSerif from base, and `.product-price` italic comes
     via font-style on the inherited DMSerif face.
     ──────────────────────────────────────────────────────────────────────── */
  .product-details {
    padding-top: calc(var(--nav) + var(--s3));
    display: flex;
    flex-direction: column;
    gap: var(--s4);
  }
  .product-details h1 {
    font-size: var(--t-3xl);
    margin-bottom: 0;
  }
  .product-price {
    font-size: var(--t-lg);
    color: var(--ac);
    font-family: 'DMSerif', Georgia, serif;
    font-style: italic;
    font-weight: 400;
    letter-spacing: .02em;
  }
  /* Strike-through compare-at, used by sub-save tier rows + variant rows. */
  .product-price--was {
    color: var(--tx3);
    text-decoration: line-through;
    font-size: var(--t-sm);
    margin-right: var(--s2);
  }


  /* ── .var-grid + .var-btn (RENAMED from .size-grid / .size-btn) ──────────
     PORT: FB framework.css L592–634.
     RENAME: `.size-grid` → `.var-grid`, `.size-btn` → `.var-btn`.

     Why rename? In commerce-factory most products are NOT shoes. They're
     supplements, beverages, single-serve consumables. Variants are
     flavours / strengths / pack-sizes / interval lengths — never sizes.
     Keeping the lbcom-style "function not appearance" naming convention.

     Behaviour preserved: `aria-pressed="true"` on selected, `.unavailable`
     for OOS variants (line-through + dim), data-* attributes for
     wc_var_id and variant name (read by commerce.js).
     ──────────────────────────────────────────────────────────────────────── */
  .var-label {
    font-size: var(--t-xs);
    letter-spacing: .16em;
    text-transform: uppercase;
    color: var(--tx3);
    margin-bottom: var(--s2);
    display: flex;
    align-items: center;
    justify-content: space-between;

    & a {
      color: var(--tx3);
      border-bottom: 1px solid var(--bdr2);
      padding-bottom: 1px;
      transition:
        color var(--dur) var(--ease),
        border-color var(--dur) var(--ease);
      &:hover { color: var(--tx2); border-color: var(--tx2); }
    }
  }

  .var-grid {
    display: flex;
    flex-wrap: wrap;
    gap: var(--s1);
  }

  /* Default — narrow swatch (~48×40, fits 6 across on mobile). For wider
     variants (flavour names like "Cucumber Mint") use `.var-btn--wide`. */
  .var-btn {
    min-width: 48px;
    height: 40px;
    padding: 0 var(--s3);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: var(--t-xs);
    letter-spacing: .04em;
    border: 1px solid var(--bdr);
    border-radius: var(--r);
    color: var(--tx2);
    cursor: pointer;
    transition:
      border-color var(--dur) var(--ease),
      color var(--dur) var(--ease),
      background var(--dur) var(--ease);
    background: none;
    font-family: inherit;

    &:hover { border-color: var(--bdr2); color: var(--tx); }
    &.selected,
    &[aria-pressed="true"] {
      border-color: var(--tx);
      color: var(--tx);
      background: transparent;
    }
    &.unavailable {
      opacity: .25;
      cursor: not-allowed;
      text-decoration: line-through;
    }

    /* Wide modifier for label variants ("Lemon Ginger", "30-day supply"). */
    &.var-btn--wide {
      min-width: 96px;
      padding: 0 var(--s4);
    }
  }
  /* Shake animation when ATC clicked without a selection (commerce.js sets
     `data-error="true"` on the .var-grid, removed after 2s). */
  .var-grid[data-error="true"] {
    animation: var-shake 0.4s var(--ease);
  }
  @keyframes var-shake {
    0%, 100%   { transform: translateX(0); }
    20%, 60%   { transform: translateX(-4px); }
    40%, 80%   { transform: translateX(4px); }
  }

  /* ── .var-grid--packs / .var-btn--pack — pack-size card layout (fix-6) ────
     Rich card variant of .var-btn used in the FocusFlow buybox restructure.
     Four cards (30/60/90/Travel) render as a 2×2 mini-grid on desktop and
     1-column-stacked on narrow mobile (≤ 360 buybox width). Each card is a
     button (a11y radio-group via aria-pressed). Selected state inverts the
     border-weight and lifts the accent dot. */
  .var-grid--packs {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--s2);
  }
  .var-btn--pack {
    /* override the narrow swatch defaults */
    min-width: 0;
    height: auto;
    padding: 12px 10px 10px;
    flex-direction: column;
    align-items: flex-start;
    text-align: left;
    line-height: 1.25;
    position: relative;
    gap: 2px;
  }
  .var-btn--pack .var-btn__title {
    font-size: var(--t-sm, 0.92rem);
    font-weight: 600;
    color: var(--tx);
    letter-spacing: 0;
    text-transform: none;
  }
  .var-btn--pack .var-btn__sub {
    font-size: 11px;
    color: var(--tx3, #888);
    letter-spacing: 0;
    text-transform: none;
    line-height: 1.3;
  }
  .var-btn--pack .var-btn__price {
    font-size: 0.95rem;
    font-weight: 700;
    color: var(--tx);
    margin-top: 4px;
  }
  .var-btn--pack .var-btn__badge {
    position: absolute;
    top: -8px;
    right: 6px;
    background: var(--ac, #c08a3e);
    color: #fff;
    font-size: 9px;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    font-weight: 600;
    padding: 2px 7px;
    border-radius: 4px;
    line-height: 1.3;
  }
  .var-btn--pack.selected,
  .var-btn--pack[aria-pressed="true"] {
    border-width: 2px;
    /* compensate for the +1px border so layout doesn't jump */
    padding: 11px 9px 9px;
  }
  .var-btn--pack.var-btn--featured:not(.selected) {
    border-color: var(--ac, #c08a3e);
  }

  /* ── .subsave--toggle / cadence dropdown (fix-6) ──────────────────────────
     The fix-6 subsave structure is a 2-radio-card toggle (One-time vs
     Subscribe) plus a conditional <select> dropdown for cadence. */
  .subsave--toggle .subsave__option--mode {
    padding: 12px 14px;
  }
  .subsave--toggle .subsave__discount-badge {
    display: inline-block;
    margin-left: 6px;
    background: var(--ac, #c08a3e);
    color: #fff;
    font-size: 10px;
    font-weight: 700;
    letter-spacing: 0.04em;
    padding: 1px 6px;
    border-radius: 3px;
    vertical-align: middle;
  }
  .subsave__cadence {
    margin-top: 10px;
    padding: 10px 12px;
    background: var(--bg2, #faf7f1);
    border-radius: var(--r);
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
    font-size: 0.85rem;
  }
  .subsave__cadence[hidden] {
    display: none;
  }
  .subsave__cadence-label {
    font-weight: 600;
    color: var(--tx2, #555);
  }
  .subsave__cadence select {
    font: inherit;
    font-size: 0.9rem;
    padding: 6px 10px;
    border: 1px solid var(--bdr);
    border-radius: 6px;
    background: #fff;
    color: var(--tx);
    cursor: pointer;
  }
  .subsave__cadence select:focus {
    outline: 2px solid var(--ac, #c08a3e);
    outline-offset: 1px;
  }
  .subsave__cadence-help {
    flex-basis: 100%;
    font-size: 11px;
    color: var(--tx3, #888);
    line-height: 1.35;
    margin-top: 2px;
  }


  /* ── .btn-cart — primary add-to-cart button ──────────────────────────────
     PORT: FB framework.css L636–656.

     KEPT under the commerce-specific name `.btn-cart` (not merged into the
     `.btn` family) because this button has a distinct full-width, tall,
     restrained-aesthetic role on every PDP. Merging into `.btn--block .btn--lg`
     would have worked but cost the design's identity. lbcom's `.btn--p`
     still wins as the generic primary; `.btn-cart` is the dedicated PDP ATC.
     ──────────────────────────────────────────────────────────────────────── */
  .btn-cart {
    width: 100%;
    height: 52px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: transparent;
    border: 1px solid var(--tx);
    color: var(--tx);
    font-size: var(--t-xs);
    letter-spacing: .2em;
    text-transform: uppercase;
    cursor: pointer;
    border-radius: var(--r);
    font-family: inherit;
    font-weight: 400;
    transition:
      background var(--dur) var(--ease),
      color var(--dur) var(--ease);

    &:hover { background: var(--tx); color: var(--bg); }
    &:disabled { opacity: .35; cursor: not-allowed; }
  }


  /* ── .shipping-note ──────────────────────────────────────────────────────
     PORT: FB framework.css L658–664 (verbatim). Lives under the ATC.
     ──────────────────────────────────────────────────────────────────────── */
  .shipping-note {
    font-size: var(--t-xs);
    color: var(--tx3);
    letter-spacing: .06em;
    text-align: center;
  }


  /* ── .accordion (FAQ / care / details) ───────────────────────────────────
     PORT: FB framework.css L666–702 (verbatim).
     Uses native `<details>` / `<summary>` per mandate. Smooth-height JS is
     a progressive enhancement (commerce.js initAccordion); the native
     toggle works without JS.
     ──────────────────────────────────────────────────────────────────────── */
  .accordion        { border-top: 1px solid var(--bdr); }
  .accordion details { border-bottom: 1px solid var(--bdr); }

  .accordion summary {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding-block: var(--s3);
    font-size: var(--t-xs);
    letter-spacing: .14em;
    text-transform: uppercase;
    color: var(--tx2);
    cursor: pointer;
    list-style: none;
    user-select: none;
    gap: var(--s3);

    &::-webkit-details-marker { display: none; }
    &::after {
      content: '+';
      font-size: var(--t-md);
      font-weight: 300;
      color: var(--tx3);
      flex-shrink: 0;
      transition: transform var(--dur) var(--ease);
      line-height: 1;
    }
  }
  .accordion details[open] summary::after { transform: rotate(45deg); }

  .accordion__body {
    padding-bottom: var(--s4);
    font-size: var(--t-sm);
    color: var(--tx2);
    line-height: 1.8;
  }


  /* ── .ugc-grid + .ugc-thumb (Bunny Stream UGC) ───────────────────────────
     PORT: FB framework.css L760–798 (verbatim).
     Each thumb has a play overlay and a 9:16 portrait aspect for mobile
     vertical video. Tapping opens the .modal with the corresponding
     <iframe data-src="…"> Bunny Stream embed.
     ──────────────────────────────────────────────────────────────────────── */
  .ugc-grid {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 2px;
  }
  @media (max-width: 640px) {
    .ugc-grid { grid-template-columns: repeat(2, 1fr); }
  }

  .ugc-thumb {
    position: relative;
    aspect-ratio: 9/16;
    overflow: hidden;
    cursor: pointer;
    background: var(--sur);
    border: none;
    padding: 0;
    display: block;

    & img {
      width: 100%;
      height: 100%;
      object-fit: cover;
      transition: transform 500ms var(--ease);
    }
    &:hover img { transform: scale(1.04); }
  }
  .ugc-thumb__play {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    background: rgba(10, 9, 8, .3);
    transition: background var(--dur) var(--ease);

    & svg { width: 44px; height: 44px; }
  }
  .ugc-thumb:hover .ugc-thumb__play { background: rgba(10, 9, 8, .15); }


  /* ── .lightbox ───────────────────────────────────────────────────────────
     PORT: FB framework.css L800–863 (verbatim, structurally).

     Brand-neutralisation: fabbruccio hard-coded `#f2ede6` (the leather-cream
     accent) on several pseudo-elements. We swap those for `var(--hi)` and
     `var(--tx2)` so the lightbox follows the active theme + per-product
     accent. The rgba black backdrop is kept literal — it's lit-content
     contrast, not theme.
     ──────────────────────────────────────────────────────────────────────── */
  .lightbox {
    position: fixed;
    inset: 0;
    z-index: 1000;
    display: flex;
    align-items: center;
    justify-content: center;
    background: rgba(8, 7, 6, .97);
    opacity: 0;
    pointer-events: none;
    transition: opacity 280ms var(--ease);

    &.open { opacity: 1; pointer-events: all; }
  }

  .lightbox__img-wrap {
    max-width: min(92vw, 1200px);
    max-height: 90dvh;
    display: flex;
    align-items: center;
    justify-content: center;
  }
  .lightbox__img {
    max-width: 100%;
    max-height: 90dvh;
    width: auto;
    height: auto;
    object-fit: contain;
    transition: opacity 180ms var(--ease);

    &.swapping { opacity: 0; }
  }

  .lightbox__close,
  .lightbox__nav {
    position: fixed;
    width: 40px;
    height: 40px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: rgba(255, 255, 255, .07);
    border-radius: 50%;
    color: color-mix(in oklch, var(--hi) 70%, transparent);
    font-size: var(--t-lg);
    cursor: pointer;
    border: none;
    transition:
      background var(--dur) var(--ease),
      color var(--dur) var(--ease);

    &:hover {
      background: rgba(255, 255, 255, .14);
      color: var(--hi);
    }
  }
  .lightbox__close { top: var(--s4); right: var(--s4); }
  .lightbox__prev  { left: var(--s3); top: 50%; transform: translateY(-50%); }
  .lightbox__next  { right: var(--s3); top: 50%; transform: translateY(-50%); }
  .lightbox__counter {
    position: fixed;
    bottom: var(--s4);
    left: 50%;
    transform: translateX(-50%);
    font-size: var(--t-xs);
    letter-spacing: .2em;
    color: color-mix(in oklch, var(--hi) 30%, transparent);
    font-family: inherit;
  }


  /* ── .modal — generic overlay primitive ──────────────────────────────────
     PORT: FB framework.css L865–910 (verbatim).
     Reused for: UGC video popups, size guide, bump-confirm, sub-save details,
     exit-intent newsletter, post-purchase upsell decline confirmation.
     Triggered via `[data-modal-target="modal-id"]` (see commerce.js).
     ──────────────────────────────────────────────────────────────────────── */
  .modal {
    position: fixed;
    inset: 0;
    z-index: 950;
    display: flex;
    align-items: center;
    justify-content: center;
    opacity: 0;
    pointer-events: none;
    transition: opacity var(--dur) var(--ease);

    &.open { opacity: 1; pointer-events: all; }
  }
  .modal__backdrop {
    position: absolute;
    inset: 0;
    background: rgba(8, 7, 6, .94);
    cursor: pointer;
  }
  .modal__content {
    position: relative;
    z-index: 1;
    width: min(90vw, 720px);
    aspect-ratio: 9/16;
    max-height: 88dvh;
    background: var(--bg);
  }
  .modal__content iframe {
    width: 100%;
    height: 100%;
    border: none;
    display: block;
  }
  .modal__close {
    position: absolute;
    top: calc(-1 * var(--s5));
    right: 0;
    color: color-mix(in oklch, var(--hi) 60%, transparent);
    font-size: var(--t-lg);
    line-height: 1;
    cursor: pointer;
    border: none;
    background: none;
    transition: color var(--dur) var(--ease);

    &:hover { color: var(--hi); }
  }
  /* `.modal__content--box` — auto-height landscape variant (size-guide,
     bump-confirm, sub-save details). NEW; not in fabbruccio. */
  .modal__content--box {
    aspect-ratio: auto;
    height: auto;
    max-height: 88dvh;
    overflow-y: auto;
    padding: var(--s6);
    border-radius: var(--r2);
    background: var(--sur);
    border: 1px solid var(--bdr2);
  }

} /* end @layer components — commerce additions */


/* ============================================================================
   LD COMPONENT PORTS (Commit 4 — liquiddeath)
   Appended in source-order so cascade is predictable. Same `@layer components`
   reopen pattern used by Commit 3 above.

   Source: /home/lb/fixSites/liquiddeath/framework.css
   Audit:  /home/lb/commerce/docs/liquiddeath_audit_2026-06.md

   Token mapping during port:
     LD --gold     → CF --ac      (semantic accent, per-product overridable)
     LD --gold-hi  → CF --ac-hi   (derived in @layer tokens)
     LD --tx       → CF --tx      (same name; LD's #ffffff vs CF's warm-300)
     LD --tx2      → CF --tx2     (same name)
     LD --bg-deep  → CF --bg      (CF lacks a separate "deep" token; use bg)
     LD --sur      → CF --sur
     LD --sur2     → CF --sur2
     LD --bdr/bdr2 → CF --bdr/bdr2
     LD --r/r2     → CF --r/r2

   Structural deltas vs LD source:
     - `.mega` uses --bg (CF) not --bg-deep (LD). CF's --bg is already the
       deepest neutral; LD distinguishes between bg-deep/bg/bg-alt because
       its dark-mode palette has three tiers. We collapsed to two.
     - `.mega__label` and `.mega__promo-label` are color: var(--ac) per the
       rename. The original LD gold is the brand color; we want each
       commerce-factory tenant's accent to win here.
     - `.stat-item__val` uses var(--ac); the accent-shim animation in
       @layer motion drives the pulse.
     - `.nav__mob` and `.nav__ham` already exist in the lbcom chassis
       (commerce.css L800-ish). We only port LD's `.mob-mega` which is the
       nested megamenu accordion that lives inside the existing mobile drawer.
   ============================================================================ */
@layer components {


  /* ── .nav-mega — desktop megamenu ────────────────────────────────────────
     PORT: LD framework.css L489–614 (verbatim structure, token-mapped).
     The megamenu sits absolute-positioned beneath `.nav` and is shown by
     the JS controller (commerce.js initMegamenu) on hover + click + keyboard.
     Mega panels are `inert` by default — see initMegamenu for the toggle.

     Markup contract:
       <li class="nav__item nav__item--has-mega" data-mega-trigger="shop">
         <a class="nav__link nav__link--has-mega" href="/shop">Shop</a>
       </li>
       … then somewhere inside .nav (or right after it):
       <div class="mega" data-mega="shop">
         <div class="mega__in">
           <div>
             <span class="mega__label">Beverages</span>
             <div class="mega__cats">
               <a class="mega__cat" href="/water">
                 <div class="mega__cat-img-wrap"><img class="mega__cat-img" src="…"></div>
                 <span class="mega__cat-name">Water</span>
               </a>
               …
             </div>
           </div>
           <a class="mega__promo" href="/featured">
             <img class="mega__promo-img" src="…">
             <span class="mega__promo-label">New</span>
             <span class="mega__promo-h">Cherry Pop</span>
           </a>
         </div>
       </div>
     ──────────────────────────────────────────────────────────────────────── */
  .nav__item { list-style: none; }
  .nav__link--has-mega {
    display: flex;
    align-items: center;
    gap: .32em;
    /* Caret indicator — CSS triangle, no SVG roundtrip */
    &::after {
      content: '';
      width: 0;
      height: 0;
      border: 4px solid transparent;
      border-top-color: currentColor;
      transform: translateY(1px);
      transition: transform var(--dur) var(--ease);
      flex-shrink: 0;
    }
  }
  .nav__item--has-mega.open > .nav__link--has-mega { color: var(--hi); }
  .nav__item--has-mega.open > .nav__link--has-mega::after {
    transform: translateY(1px) rotate(-180deg);
  }

  .mega {
    /* display:none (not visibility:hidden) prevents lazy-loaded images
       inside the panel from triggering network requests on page load.
       This is the LD-audit's most important trick — without it, a
       site with 4 megamenu panels and 6 product images per panel would
       paint 24 product images on first load, ruining LCP. */
    display: none;
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    z-index: 190;
    background: color-mix(in oklch, var(--bg) 97%, transparent);
    backdrop-filter: blur(12px);
    -webkit-backdrop-filter: blur(12px);
    border-bottom: 1px solid var(--bdr);
    pointer-events: none;
  }
  .mega.open {
    display: block;
    pointer-events: auto;
    animation: mega-in .22s var(--ease) both;
  }

  .mega__in {
    max-width: var(--wrap);
    margin-inline: auto;
    padding: var(--s5) var(--s4);
    display: grid;
    grid-template-columns: 1fr auto;
    gap: var(--s6);
    align-items: start;
  }
  .mega__in--slim { grid-template-columns: 1fr; }

  .mega__label {
    font-size: var(--t-2xs);
    font-weight: 700;
    letter-spacing: .2em;
    text-transform: uppercase;
    color: var(--ac);
    display: block;
    margin-bottom: var(--s3);
  }

  /* Category tile grid (typically: 4 columns of icon + label) */
  .mega__cats {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: var(--s2);
    margin-bottom: var(--s3);
  }
  .mega__cat {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--s2);
    text-align: center;
    padding: var(--s2) var(--s1);
    border-radius: var(--r);
    border: 1px solid transparent;
    transition:
      background var(--dur) var(--ease),
      border-color var(--dur) var(--ease);

    &:hover {
      background: var(--sur2);
      border-color: var(--bdr);
    }
  }
  .mega__cat-img-wrap {
    width: 88px;
    height: 88px;
    background: var(--sur);
    border-radius: var(--r2);
    overflow: hidden;
    flex-shrink: 0;
  }
  .mega__cat-img {
    width: 100%;
    height: 100%;
    object-fit: contain;
    padding: var(--s2);
    transition: transform .4s cubic-bezier(.16, 1, .3, 1);
  }
  .mega__cat:hover .mega__cat-img { transform: scale(1.08); }
  .mega__cat-name {
    font-size: var(--t-2xs);
    font-weight: 700;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--tx2);
    transition: color var(--dur) var(--ease);
  }
  .mega__cat:hover .mega__cat-name { color: var(--hi); }

  /* Promo column (right side of the mega panel) */
  .mega__promo {
    width: clamp(140px, 16vw, 190px);
    display: flex;
    flex-direction: column;
    gap: var(--s2);
    align-items: flex-start;
  }
  .mega__promo-img {
    width: 100%;
    aspect-ratio: 1;
    object-fit: contain;
    background: var(--sur);
    border-radius: var(--r2);
    padding: var(--s3);
    transition: transform .5s cubic-bezier(.16, 1, .3, 1);
  }
  .mega__promo:hover .mega__promo-img { transform: scale(1.04); }
  .mega__promo-label {
    font-size: var(--t-2xs);
    font-weight: 700;
    letter-spacing: .18em;
    text-transform: uppercase;
    color: var(--ac);
  }
  .mega__promo-h {
    font-family: var(--ff-h, 'Barlow Condensed', Impact, sans-serif);
    font-weight: 900;
    font-size: var(--t-lg);
    text-transform: uppercase;
    line-height: 1;
  }

  /* Text-link panels (merch / explore) */
  .mega__links {
    display: grid;
    grid-template-columns: repeat(2, max-content);
    gap: var(--s2) var(--s5);
    justify-content: start;
    margin-bottom: var(--s3);
  }
  .mega__links--col {
    grid-template-columns: 1fr;
    gap: var(--s2);
  }
  .mega__link {
    font-size: var(--t-sm);
    font-weight: 600;
    color: var(--tx2);
    white-space: nowrap;
    transition:
      color var(--dur) var(--ease),
      translate var(--dur) var(--ease);

    &:hover {
      color: var(--hi);
      translate: 3px 0;
    }
  }
  .mega__link--featured {
    grid-column: 1 / -1;
    color: var(--hi);
    font-weight: 700;
    font-family: var(--ff-h, 'Barlow Condensed', Impact, sans-serif);
    font-size: var(--t-md);
    text-transform: uppercase;
    margin-bottom: var(--s1);
    letter-spacing: .03em;

    &:hover {
      translate: 0 0;
      color: var(--ac);
    }
  }

  /* Mobile mega (details/summary inside .nav__mob) — collapses each top-level
     section into a native disclosure. NO custom toggle JS needed; native
     <details> handles open/close. */
  .mob-mega { border-bottom: 1px solid var(--bdr); }
  .mob-mega__trigger {
    list-style: none;
    display: flex;
    align-items: center;
    justify-content: space-between;
    font-size: var(--t-md);
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .08em;
    color: var(--tx2);
    padding: var(--s3) 0;
    cursor: pointer;
    user-select: none;
    transition: color var(--dur) var(--ease);

    &::-webkit-details-marker { display: none; }
    &::after {
      content: '+';
      font-size: var(--t-xl);
      font-weight: 300;
      color: var(--ac);
    }
  }
  details[open] > .mob-mega__trigger { color: var(--hi); }
  details[open] > .mob-mega__trigger::after { content: '\2212'; }
  .mob-mega__panel {
    display: flex;
    flex-direction: column;
    gap: var(--s2);
    padding: 0 0 var(--s3) var(--s3);
  }
  .mob-mega__panel a {
    font-size: var(--t-sm);
    font-weight: 600;
    color: var(--tx2);
    transition: color var(--dur) var(--ease);

    &:hover { color: var(--hi); }
  }


  /* ── .stats-strip — three-up numeric strip ──────────────────────────────
     PORT: LD framework.css L638–646 (verbatim, accent token swapped).
     Used between hero and pitch sections to summarise "150k+ customers",
     "97% retention", "0g sugar" etc.
     ──────────────────────────────────────────────────────────────────────── */
  .stats-strip {
    display: grid;
    gap: 1px;
    background: var(--bdr);
    border-top: 1px solid var(--bdr);
    border-bottom: 1px solid var(--bdr);
  }
  @media (min-width: 480px) {
    .stats-strip { grid-template-columns: repeat(3, 1fr); }
  }
  .stat-item {
    background: var(--sur);
    padding: var(--s5) var(--s4);
    text-align: center;
  }
  .stat-item__val {
    font-family: var(--ff-h, 'Barlow Condensed', Impact, sans-serif);
    font-weight: 900;
    font-size: var(--t-2xl);
    text-transform: uppercase;
    color: var(--ac);
    line-height: 1;
  }
  .stat-item__lbl {
    font-size: var(--t-2xs);
    letter-spacing: .14em;
    text-transform: uppercase;
    color: var(--tx2);
    margin-top: var(--s2);
  }


  /* ── .steps — numbered process list ──────────────────────────────────────
     PORT: LD framework.css L671–683 (verbatim).
     CSS counter-reset for auto-numbering — no manual <span>1</span> markup.
     ──────────────────────────────────────────────────────────────────────── */
  .steps {
    display: flex;
    flex-direction: column;
    gap: var(--s5);
    counter-reset: step;
  }
  .step {
    display: flex;
    gap: var(--s4);
    align-items: flex-start;
  }
  .step::before {
    counter-increment: step;
    content: counter(step);
    flex-shrink: 0;
    width: 2.5rem;
    height: 2.5rem;
    display: flex;
    align-items: center;
    justify-content: center;
    border: 1.5px solid var(--ac);
    color: var(--ac);
    font-family: var(--ff-h, 'Barlow Condensed', Impact, sans-serif);
    font-weight: 900;
    font-size: var(--t-lg);
    border-radius: 50%;
  }
  .step__h {
    font-weight: 700;
    font-size: var(--t-md);
    margin-bottom: var(--s1);
  }
  .step__d {
    font-size: var(--t-sm);
    color: var(--tx2);
    line-height: 1.6;
  }


  /* ── .perk-card — feature tile ───────────────────────────────────────────
     PORT: LD framework.css L709–713 (verbatim).
     Used in 3-up grids (`.grid--3 > .perk-card`) for "Free shipping",
     "60-day guarantee", "Made in USA" type trust boxes.
     ──────────────────────────────────────────────────────────────────────── */
  .perk-card {
    text-align: center;
    padding: var(--s5);
    border: 1px solid var(--bdr);
    border-radius: var(--r2);
    background: var(--sur);
  }
  .perk-card__icon {
    font-size: 2.5rem;
    margin-bottom: var(--s3);
    display: block;
    color: var(--ac);
  }
  .perk-card__h {
    font-weight: 700;
    font-size: var(--t-md);
    margin-bottom: var(--s2);
  }
  .perk-card__d {
    font-size: var(--t-sm);
    color: var(--tx2);
    line-height: 1.6;
  }


  /* ── .retailer-card — partner/retailer grid card ─────────────────────────
     PORT: LD framework.css L686–694 (verbatim).
     Repurposed in commerce-factory context as "subscribe via Amazon /
     Walmart / Target" partner links on PDP. Same visual treatment.
     ──────────────────────────────────────────────────────────────────────── */
  .retailer-grid {
    display: grid;
    gap: var(--s4);
    grid-template-columns: repeat(auto-fill, minmax(min(100%, 160px), 1fr));
  }
  .retailer-card {
    background: var(--sur);
    border: 1px solid var(--bdr);
    border-radius: var(--r);
    padding: var(--s4);
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--s3);
    text-align: center;
    transition: border-color var(--dur) var(--ease);

    &:hover { border-color: var(--tx2); }
  }
  .retailer-card__name {
    font-weight: 700;
    font-size: var(--t-sm);
  }
  .retailer-card__type {
    font-size: var(--t-2xs);
    color: var(--tx2);
    text-transform: uppercase;
    letter-spacing: .1em;
  }


  /* ── .vid-sect — full-bleed ambient video background section ─────────────
     PORT: LD framework.css L264–292 (verbatim).
     Background <video> autoplay-muted-loop with overlay content.
     Pairs with initLazyVideo in commerce.js — video src is data-lazy-src
     until the section enters the viewport, then the IO swaps it in to
     avoid a 1-2MB eager load.

     Markup contract:
       <section class="vid-sect">
         <video class="vid-sect__bg" data-lazy-video muted loop playsinline poster="…">
           <source data-lazy-src="/video/hero.mp4" type="video/mp4">
         </video>
         <div class="vid-sect__body">
           <h2>Heading</h2>
           <p>Body</p>
           <a class="btn btn--p" href="…">CTA</a>
         </div>
       </section>
     ──────────────────────────────────────────────────────────────────────── */
  .vid-sect {
    position: relative;
    min-height: clamp(420px, 65vh, 720px);
    overflow: hidden;
    background: var(--bg);
    display: flex;
    align-items: center;
  }
  .vid-sect__bg {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    /* .38 opacity preserves text contrast over arbitrary footage —
       LD's audit found <.4 is the sweet spot for both video and overlay. */
    opacity: .38;
  }
  .vid-sect__body {
    position: relative;
    z-index: 1;
    width: 100%;
    max-width: var(--wrap);
    margin-inline: auto;
    padding: var(--s7) var(--s4);
    text-align: center;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--s4);
  }


  /* ── .slider / .slide — horizontal scroll-snap carousel ──────────────────
     PORT: LD framework.css L370–449 (verbatim).
     Native overflow-x scroll + scroll-snap-type. JS in commerce.js
     (data-slider) adds prev/next arrows + dot indicators + sync.
     ──────────────────────────────────────────────────────────────────────── */
  .slider-wrap { position: relative; }
  .slider {
    display: flex;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    scroll-behavior: smooth;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;

    &::-webkit-scrollbar { display: none; }
  }
  .slide        { flex-shrink: 0; width: 100%;                      scroll-snap-align: start; }
  .slide--card  { flex-shrink: 0; width: clamp(240px, 30vw, 300px); scroll-snap-align: start; }
  .slide--wide  { flex-shrink: 0; width: clamp(260px, 38vw, 420px); scroll-snap-align: start; }
  .slide--merch { flex-shrink: 0; width: clamp(200px, 26vw, 300px); scroll-snap-align: start; }

  /* Hero reel — fade-based hero slider. overflow:visible (not hidden) so
     the inner `animation-timeline: view()` blocks reference the viewport,
     not this element. Inactive slides position:absolute + opacity:0. */
  .hero-reel {
    position: relative;
    overflow: visible;

    & > .slide {
      position: absolute;
      inset: 0;
      width: 100%;
      opacity: 0;
      pointer-events: none;
      transition: opacity .55s cubic-bezier(.4, 0, .2, 1);
    }
    & > .slide.active {
      position: relative;
      opacity: 1;
      pointer-events: auto;
      transition: none;
    }
  }

  /* Hero slide — used inside hero slider to avoid double nav padding */
  .hero-slide {
    min-height: calc(100svh - var(--nav));
    display: grid;
    align-items: center;
    padding: var(--s6) 0;
  }
  .hero-slide__in {
    max-width: var(--wrap);
    margin-inline: auto;
    padding-inline: var(--s4);
    display: grid;
    gap: var(--s5);
    align-items: center;
  }
  @media (min-width: 768px) {
    .hero-slide__in { grid-template-columns: 1fr 1fr; }
  }
  .hero-slide__txt {
    display: flex;
    flex-direction: column;
    gap: var(--s4);
  }
  .hero-slide__img {
    display: flex;
    align-items: center;
    justify-content: center;
  }
  /* `float` keyframes used by .hero-slide__product — defined here (not in
     @layer motion) because it's a tightly-coupled component decoration,
     not a generic motion utility. Gated by reduced-motion below. */
  @keyframes float {
    0%, 100% { transform: translateY(0); }
    50%      { transform: translateY(-14px); }
  }
  .hero-slide__product {
    max-height: clamp(260px, 48vw, 560px);
    width: auto;
    filter: drop-shadow(0 40px 80px rgba(0, 0, 0, .8));
  }
  @media (prefers-reduced-motion: no-preference) {
    .hero-slide__product { animation: float 5s ease-in-out infinite; }
  }

  .slider-btn {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    z-index: 10;
    width: 48px;
    height: 48px;
    border-radius: 50%;
    background: rgba(0, 0, 0, .65);
    border: 1px solid color-mix(in oklch, var(--hi) 25%, transparent);
    color: var(--hi);
    font-size: 1.1rem;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    transition:
      background var(--dur) var(--ease),
      border-color var(--dur) var(--ease);

    &:hover {
      background: rgba(0, 0, 0, .9);
      border-color: var(--hi);
    }
  }
  .slider-btn--prev { left: var(--s3); }
  .slider-btn--next { right: var(--s3); }

  .slider-dots {
    display: flex;
    justify-content: center;
    gap: var(--s2);
    margin-top: var(--s3);
  }
  .slider-dot {
    width: 44px;
    height: 44px;
    border-radius: 50%;
    background: transparent;
    border: none;
    cursor: pointer;
    transition: transform var(--dur) var(--ease);
    display: flex;
    align-items: center;
    justify-content: center;

    /* Inner dot uses ::before so the 44px tap target is honored
       (WCAG 2.5.5 target size) while the visual dot stays tiny. */
    &::before {
      content: '';
      display: block;
      width: 7px;
      height: 7px;
      border-radius: 50%;
      background: var(--tx3);
      transition:
        background var(--dur) var(--ease),
        transform var(--dur) var(--ease);
      flex-shrink: 0;
    }
    &.on::before {
      background: var(--hi);
      transform: scale(1.35);
    }
  }

} /* end @layer components — LD additions (Commit 4) */


/* ============================================================================
   SUBSCRIBE-AND-SAVE (Commit 5 — new, no source port)
   Sits inside `_buybox.html.j2` above ATC. Renders one or more radio options
   for a one-time purchase vs sub-save tiers (30/60/90-day) with computed
   savings shown live.

   Backend dep: WooCommerce Subscriptions plugin on the central WC instance.
   ATC URL gets `&subscribe=1&interval=<days>` appended when a sub-save tier
   is selected (the variant-selector module already plumbs this via
   `data-cf-subsave-interval`; see commerce.js initSubSave).

   Markup contract:
     <fieldset class="subsave"
               data-subsave
               data-base-price="29.99"
               data-currency="$">
       <legend class="sr-only">Purchase frequency</legend>

       <label class="subsave__option">
         <input type="radio" name="subsave" value="0" checked>
         <span class="subsave__option-body">
           <span class="subsave__freq">One-time</span>
           <span class="subsave__price">$29.99</span>
         </span>
       </label>

       <label class="subsave__option subsave__option--featured">
         <input type="radio" name="subsave" value="30" data-discount="15">
         <span class="subsave__option-body">
           <span class="subsave__freq">Every 30 days</span>
           <span class="subsave__price-wrap">
             <span class="subsave__strike">$29.99</span>
             <span class="subsave__price">$25.49</span>
           </span>
           <span class="subsave__discount">Save 15%</span>
         </span>
       </label>
       …
       <p class="subsave__savings" data-subsave-savings hidden>
         You save <strong></strong> per shipment.
       </p>
     </fieldset>

   Discount % computed at build-time (Jinja2) AND verified at runtime by JS
   — the JS recomputes from data-base-price × data-discount so a desync
   between template and config doesn't ship wrong numbers.
   ============================================================================ */
@layer components {

  /* ── .subsave — container fieldset ───────────────────────────────────────
     Native <fieldset> for free a11y (the legend is the question). Resets the
     UA chrome (most browsers add a 1px ridge border + 2px inline padding
     that fight any modern card design). */
  .subsave {
    border: none;
    padding: 0;
    margin: 0;
    display: flex;
    flex-direction: column;
    gap: var(--s2);
    width: 100%;
    min-width: 0;
    /* NOTE: was `container-type: inline-size` — that collapsed the fieldset
       to width:0 inside the flex-column buybox (no @container rules target
       .subsave anyway, so the property was unused). Removed. */
  }
  .subsave__heading {
    font-size: var(--t-2xs);
    letter-spacing: .14em;
    text-transform: uppercase;
    color: var(--tx3);
    margin-bottom: var(--s2);
  }

  /* ── .subsave__option — single radio row ─────────────────────────────────
     Card-style label wrapping the radio so the entire row is clickable.
     The radio itself is visually hidden (opacity:0 + position:absolute) but
     remains keyboard-focusable; a pseudo-circle on the label renders the
     "checked" state, so we control the styling end-to-end without browser
     differences (Safari's default radio is notoriously hard to recolor). */
  .subsave__option {
    position: relative;
    display: grid;
    grid-template-columns: auto 1fr;
    align-items: start;
    gap: var(--s3);
    padding: var(--s3) var(--s4);
    border: 1px solid var(--bdr);
    border-radius: var(--r);
    background: var(--sur);
    cursor: pointer;
    transition:
      border-color var(--dur) var(--ease),
      background var(--dur) var(--ease),
      box-shadow var(--dur) var(--ease);

    &:hover { border-color: var(--bdr2); }
    &:focus-within {
      border-color: var(--ac);
      box-shadow: 0 0 0 2px color-mix(in oklch, var(--ac) 25%, transparent);
    }
  }

  /* The actual radio — hidden offscreen but interactive. */
  .subsave__option input[type="radio"] {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    margin: 0;
    opacity: 0;
    cursor: pointer;
    z-index: 1;
  }

  /* Pseudo radio circle drawn on .subsave__option::before. The grid layout
     above leaves a 1.1rem column for it. */
  .subsave__option::before {
    content: '';
    width: 1.1rem;
    height: 1.1rem;
    border: 1.5px solid var(--bdr2);
    border-radius: 50%;
    background: transparent;
    margin-top: .2rem;
    transition:
      border-color var(--dur) var(--ease),
      background var(--dur) var(--ease),
      box-shadow var(--dur) var(--ease);
  }

  /* Checked state — driven by :has(input:checked) so we don't need JS to
     toggle a class. Modern-browser support is identical to the rest of
     the chassis (Chrome 105+ / Safari 15.4+ / Firefox 121+, all within
     commerce-factory's stated support matrix). */
  .subsave__option:has(input:checked) {
    border-color: var(--ac);
    background: color-mix(in oklch, var(--ac) 5%, var(--sur));
  }
  .subsave__option:has(input:checked)::before {
    border-color: var(--ac);
    background:
      radial-gradient(
        circle at center,
        var(--ac) 0 .35rem,
        transparent .36rem
      );
    box-shadow: 0 0 0 2px color-mix(in oklch, var(--ac) 18%, transparent);
  }

  /* Featured / recommended option — visual "most popular" emphasis. */
  .subsave__option--featured {
    border-color: var(--ac-mid);
    background: color-mix(in oklch, var(--ac) 3%, var(--sur));
  }
  .subsave__option--featured::after {
    content: 'Best value';
    position: absolute;
    top: calc(-1 * var(--s2));
    right: var(--s3);
    background: var(--ac);
    color: var(--bg);
    font-size: var(--t-2xs);
    font-weight: 700;
    letter-spacing: .12em;
    text-transform: uppercase;
    padding: .15em .6em;
    border-radius: var(--r);
  }

  /* Option body — vertical stack of freq + price (+ optional discount). */
  .subsave__option-body {
    display: grid;
    gap: var(--s1);
    grid-template-columns: 1fr auto;
    align-items: baseline;
    width: 100%;
  }

  /* Frequency label — "One-time" / "Every 30 days" / etc. */
  .subsave__freq {
    font-size: var(--t-sm);
    font-weight: 600;
    color: var(--hi);
    grid-column: 1;
  }

  /* Price wrapper — holds strike-through + current price when discounted. */
  .subsave__price-wrap {
    grid-column: 2;
    display: flex;
    align-items: baseline;
    gap: var(--s2);
    text-align: right;
  }
  .subsave__price {
    font-size: var(--t-b);
    font-weight: 700;
    color: var(--hi);
    font-variant-numeric: tabular-nums;
  }
  .subsave__strike {
    font-size: var(--t-xs);
    color: var(--tx3);
    text-decoration: line-through;
    font-variant-numeric: tabular-nums;
  }

  /* Discount badge — "% off" or "Save $X" label on the discounted row. */
  .subsave__discount {
    grid-column: 1 / -1;
    font-size: var(--t-2xs);
    font-weight: 700;
    color: var(--ac);
    letter-spacing: .12em;
    text-transform: uppercase;
    margin-top: var(--s1);
  }

  /* Live computed savings display — populated by JS from
     (basePrice × selectedDiscount). Hidden when "one-time" is selected. */
  .subsave__savings {
    font-size: var(--t-sm);
    color: var(--tx2);
    margin-top: var(--s2);
    text-align: center;

    & strong {
      color: var(--ac);
      font-weight: 700;
      font-variant-numeric: tabular-nums;
    }
  }

  /* Frequency picker variant — secondary UI for changing the interval
     within an already-selected subscribe option. Used when the LP supports
     multiple intervals AND wants a single sub-save toggle (the more common
     pattern is one radio per interval, as above; this is the alternate). */
  .subsave__freq-picker {
    display: flex;
    gap: var(--s1);
    margin-top: var(--s2);
  }
  .subsave__freq-picker button {
    flex: 1;
    padding: var(--s2) var(--s3);
    border: 1px solid var(--bdr);
    border-radius: var(--r);
    background: transparent;
    color: var(--tx2);
    font-size: var(--t-xs);
    font-weight: 600;
    cursor: pointer;
    transition:
      border-color var(--dur) var(--ease),
      color var(--dur) var(--ease),
      background var(--dur) var(--ease);

    &:hover { border-color: var(--bdr2); color: var(--hi); }
    &.selected {
      border-color: var(--ac);
      color: var(--ac);
      background: color-mix(in oklch, var(--ac) 8%, transparent);
    }
  }

} /* end @layer components — subsave (Commit 5) */


/* ============================================================================
   ANALYTICS PRIMITIVES (Commit 6 — no source port; new convention)
   No visual components — but data-evt elements occasionally need a hairline
   visual cue (an off-screen sr-only element is enough for the common case).
   The dispatcher itself lives in commerce.js (initAnalytics).

   Per analytics/events.json (Commit 6), canonical events are:
     view_pdp, add_to_cart, begin_checkout, purchase,
     subscribe_select, opt_in, bump_view, bump_accept,
     upsell_view, upsell_accept, accordion_open, lightbox_open
   (12 events — webhook contract is the 8 commerce events; the 4 UI events
   accordion_open/lightbox_open/bump_view/upsell_view feed Pixel+GA4 only.)

   The single visual rule we need: a `data-evt-pending` attribute that the
   dispatcher temporarily sets on an element while a beacon is in flight,
   so we can show a hairline "sending" affordance for opt-in forms etc.
   ============================================================================ */
@layer components {

  /* While a data-evt beacon is being sent (e.g. opt-in form), give a
     subtle activity hint — applied only to elements that opt in via the
     [data-evt-spinner] flag. Keeps the analytics layer optically silent
     by default. */
  [data-evt-pending][data-evt-spinner]::after {
    content: '';
    display: inline-block;
    width: .85em;
    height: .85em;
    margin-left: var(--s2);
    border: 1.5px solid currentColor;
    border-top-color: transparent;
    border-radius: 50%;
    vertical-align: -.1em;
    animation: cf-evt-spin .7s linear infinite;
  }
  @keyframes cf-evt-spin {
    to { transform: rotate(360deg); }
  }

} /* end @layer components — analytics (Commit 6) */


/* ============================================================================
   COMPONENTS — order bump + post-purchase upsell
   COMMIT 9. New classes (~not ported from any source).

   Bump: thin inline checkbox row above the ATC button. The CSS additions
   stay tight per build plan §3 — visual is small-tile + checkbox + strike.

   Upsell: standalone page layout. Centered card, hero image, accept/decline.
   ============================================================================ */
@layer components {

  /* ── .bump-offer ────────────────────────────────────────────────────────
     Renders above ATC inside .buybox. Visual: a flat dashed border tile,
     checkbox + small thumb + name + price with optional strike. Hover and
     :checked states intentionally subtle so the bump doesn't overshadow the
     ATC button — it's a yes-please/no-thanks moment, not the main act. */
  .bump-offer {
    margin-block: var(--s4);
    padding: var(--s3) var(--s4);
    background: var(--sur);
    border: 1px dashed var(--bdr2);
    border-radius: var(--r);
    transition:
      border-color var(--dur) var(--ease),
      background   var(--dur) var(--ease);
  }
  .bump-offer:has(input[type="checkbox"]:checked) {
    border-color: var(--ac);
    border-style: solid;
    background: color-mix(in oklch, var(--ac) 6%, var(--sur));
  }
  .bump-offer__check {
    /* Inherit base .fchk row layout from forms (LB style.css L519). */
    margin: 0;
    align-items: center;
  }
  .bump-offer__copy {
    display: flex;
    align-items: center;
    gap: var(--s3);
    flex: 1;
    flex-wrap: wrap;
  }
  .bump-offer__img {
    width: 48px;
    height: 48px;
    border-radius: calc(var(--r) - 4px);
    object-fit: cover;
    flex-shrink: 0;
  }
  .bump-offer__name {
    flex: 1;
    font-size: var(--t-sm);
    color: var(--tx);
    line-height: 1.35;
  }
  .bump-offer__name strong {
    color: var(--hi);
    font-weight: 500;
  }
  .bump-offer__tagline {
    color: var(--tx3);
    font-size: var(--t-xs);
    margin-left: var(--s2);
  }
  .bump-offer__price {
    font-family: 'DMSerif', Georgia, serif;
    font-size: var(--t-md);
    color: var(--hi);
    letter-spacing: .01em;
    white-space: nowrap;
  }
  .bump-offer__strike {
    color: var(--tx3);
    text-decoration: line-through;
    font-family: 'Inter', system-ui, sans-serif;
    font-size: var(--t-xs);
    margin-left: var(--s2);
  }


  /* ── .upsell-page ──────────────────────────────────────────────────────
     Full-bleed centered card for /dist/{slug}/upsell/index.html.
     Hero image dominates the fold; CTAs stacked vertically (accept above
     decline) — standard one-time-offer pattern. */
  .upsell-page {
    padding-block: var(--s8);
    text-align: center;
  }
  .upsell-page .sec-h {
    font-family: 'DMSerif', Georgia, serif;
    line-height: 1.1;
  }
  .upsell__hero {
    background: var(--sur);
    box-shadow: 0 24px 60px -24px rgba(0, 0, 0, .35);
  }
  .upsell__body {
    /* Composition lives in the template (price + buttons). The body wrapper
       only needs to inherit centered text + sensible max-width. */
    max-width: 640px;
    margin-inline: auto;
  }
  .upsell__price.product-price {
    /* Bigger than buybox price on this page — the offer is the whole point. */
    font-size: var(--t-xl);
  }
  .upsell__accept {
    /* extends .btn .btn--p .btn--lg .btn--block — no further override needed
       in normal builds. Defined here for IDE jump-to. */
  }
  .upsell__decline {
    /* extends .btn .btn--g .btn--sm .btn--block; emphasizes lower visual
       weight relative to accept. */
    opacity: .82;
  }
  .upsell__decline:hover { opacity: 1; }

} /* end @layer components — bump + upsell (Commit 9) */


/* ============================================================================
   NAV CHASSIS — ported verbatim-structure from lbcom framework.css (.nav family)
   Previously commerce.css shipped only `.nav__item`, `.nav__link--has-mega`
   and `.nav__mega-*` (megamenu add-ons), assuming the base `.nav` layout
   rules existed. They did not. Without these, the <nav class="nav"> rendered
   completely unstyled (no fixed positioning, no inner-wrap, no logo layout),
   which was the root cause of the focusflow LP nav clipping + horizontal
   overflow regression seen on Bunny.
   PORT SOURCE: https://www.lakshaybehl.com/assets/css/framework.css
   ============================================================================ */
@layer components {

  .nav {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    z-index: 100;
    height: var(--nav);
    display: flex;
    align-items: center;
    background: color-mix(in oklch, var(--bg) 92%, transparent);
    backdrop-filter: blur(10px);
    -webkit-backdrop-filter: blur(10px);
    border-bottom: 1px solid var(--bdr);
    transition-property: background-color, border-color;
    transition-duration: .25s;
    transition-timing-function: ease;
  }
  .nav__in {
    display: flex;
    align-items: center;
    justify-content: space-between;
    width: 100%;
    max-width: var(--wrap);
    margin-inline: auto;
    padding-inline: var(--s4);
    gap: var(--s4);
    position: relative;
  }
  .nav__logo {
    line-height: 1;
    display: flex;
    flex-direction: column;
    gap: 2px;
    color: var(--hi);
    text-decoration: none;
  }
  .nav__name {
    font-family: 'DMSerif', Georgia, serif;
    font-size: var(--t-md);
    color: var(--hi);
  }
  .nav__sub {
    font-size: var(--t-xs);
    color: var(--tx2);
    letter-spacing: .12em;
    text-transform: uppercase;
  }
  .nav__links {
    display: none;
    align-items: center;
    gap: var(--s4);
    margin: 0;
    padding: 0;
    list-style: none;
  }
  .nav__link {
    font-size: var(--t-xs);
    color: var(--tx2);
    letter-spacing: .08em;
    text-transform: uppercase;
    transition: color var(--dur) var(--ease);
    text-decoration: none;
    display: inline-flex;
    align-items: center;
    height: var(--nav);
  }
  .nav__link:hover,
  .nav__link[aria-current] { color: var(--hi); }
  .nav__cta {
    padding: var(--s2) var(--s4);
    font-size: var(--t-xs);
    font-weight: 600;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--bg);
    background: var(--ac);
    border-radius: var(--r);
    transition: background var(--dur) var(--ease);
    white-space: nowrap;
    text-decoration: none;
  }
  .nav__cta:hover { background: var(--hi); }
  .nav__actions {
    display: flex;
    align-items: center;
    gap: var(--s2);
  }
  .nav__ham {
    display: flex;
    flex-direction: column;
    gap: 5px;
    cursor: pointer;
    padding: 6px;
    background: none;
    border: 1px solid var(--bdr2);
    border-radius: var(--r);
    width: 38px;
    height: 38px;
    align-items: center;
    justify-content: center;
  }
  .nav__ham span {
    display: block;
    width: 18px;
    height: 1.5px;
    background: var(--tx);
    transition: transform var(--dur) var(--ease), opacity var(--dur) var(--ease);
  }
  .nav__ham[aria-expanded="true"] span:nth-child(1) { transform: translateY(6.5px) rotate(45deg); }
  .nav__ham[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
  .nav__ham[aria-expanded="true"] span:nth-child(3) { transform: translateY(-6.5px) rotate(-45deg); }

  .nav__mob {
    display: none;
    position: fixed;
    top: var(--nav);
    left: 0;
    right: 0;
    z-index: 99;
    background: var(--sur);
    border-bottom: 1px solid var(--bdr);
    padding: var(--s3) var(--s4);
    flex-direction: column;
    gap: var(--s2);
  }
  .nav__mob.open { display: flex; }
  .nav__mob > a {
    display: block;
    padding: var(--s2) 0;
    font-size: var(--t-sm);
    color: var(--tx);
    text-decoration: none;
    border-bottom: 1px solid var(--bdr);
  }
  .nav__mob > a:last-child { border-bottom: 0; }

  /* Desktop: show inline links, hide hamburger. */
  @media (min-width: 768px) {
    .nav__links { display: flex; }
    .nav__ham   { display: none; }
  }

  /* The base `.page` class adds `padding-top: var(--nav)` (already in
     utilities). Reaffirmed here for explicit-doc, since the nav is fixed. */


  /* ── Footer .ft__in — grid layout container ──────────────────────────────
     The templates emit `<div class="ft__in">…</div>`, but commerce.css
     previously only had `.ft__grid` defined (legacy lbcom name).
     Add `.ft__in` as the supported template class so footer renders as a
     real 4-column grid on desktop, stack on mobile. */
  .ft .ft__in {
    display: grid;
    gap: var(--s5);
    max-width: var(--wrap);
    margin-inline: auto;
    padding-inline: var(--s4);
    grid-template-columns: 1fr;
  }
  @media (min-width: 768px) {
    .ft .ft__in { grid-template-columns: 1.4fr 1fr 1fr 1.4fr; }
  }
  .ft .ft__bot {
    max-width: var(--wrap);
    margin-inline: auto;
    padding-inline: var(--s4);
  }


  /* ── .strip (free-shipping bar) — a single-row dark accent strip ─────────
     Different from the multi-up `.strip` value-prop block above; that one
     uses a grid + `.strip__it`. The free-ship bar template emits
     `<div class="strip"><p class="strip__d">…</p></div>` directly with no
     `.strip__it`. Style as a thin sticky-feel banner above the nav.
     Selector specificity: `.strip:not(:has(.strip__it))` keeps the multi-up
     value-prop styling untouched (LB style port). */
  .strip:not(:has(.strip__it)) {
    display: block;
    background: var(--sur2);
    border: 0;
    border-radius: 0;
    text-align: center;
    padding: var(--s2) var(--s4);
    overflow: visible;
  }
  .strip:not(:has(.strip__it)) .strip__d {
    font-size: var(--t-xs);
    color: var(--tx2);
    letter-spacing: .08em;
    text-transform: uppercase;
    line-height: 1.4;
    margin: 0;
  }

} /* end nav-chassis + footer + free-ship strip append */


/* ============================================================================
   PRESS / "AS SEEN IN" STRIP — daydreamers-showcase pattern
   A dark inset band with a small label + a row of muted publication marks
   (text or logos). Sits between hero and product detail for instant
   social-proof credibility. Markup contract:
     <section class="press-strip" aria-label="Featured in">
       <div class="press-strip__in">
         <span class="press-strip__lbl">Featured in</span>
         <ul class="press-strip__list">
           <li class="press-strip__it">Wirecutter</li>
           …
         </ul>
       </div>
     </section>
   ============================================================================ */
@layer components {
  .press-strip {
    background: var(--sur);
    border-block: 1px solid var(--bdr);
    padding-block: var(--s4);
  }
  .press-strip__in {
    max-width: var(--wrap);
    margin-inline: auto;
    padding-inline: var(--s4);
    display: grid;
    gap: var(--s3);
    align-items: center;
  }
  @media (min-width: 768px) {
    .press-strip__in { grid-template-columns: auto 1fr; gap: var(--s5); }
  }
  .press-strip__lbl {
    font-size: var(--t-xs);
    letter-spacing: .2em;
    text-transform: uppercase;
    color: var(--tx3);
    font-weight: 600;
  }
  .press-strip__list {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--s5);
    list-style: none;
    margin: 0;
    padding: 0;
    justify-content: flex-start;
  }
  .press-strip__it {
    font-family: 'DMSerif', Georgia, serif;
    font-size: var(--t-md);
    color: var(--tx2);
    letter-spacing: .02em;
    opacity: .82;
  }

  /* ── Editorial testimonial — a single featured quote block ──────────────
     Bigger, calmer, more memorable than a 3-up card grid. Use for the
     primary social-proof slot. */
  .testimonial-feat {
    background: var(--sur);
    border: 1px solid var(--bdr);
    border-radius: var(--r2);
    padding: var(--s6);
    display: grid;
    gap: var(--s4);
    max-width: 760px;
    margin-inline: auto;
  }
  .testimonial-feat__stars {
    color: var(--ac);
    font-size: var(--t-lg);
    letter-spacing: .1em;
    line-height: 1;
  }
  .testimonial-feat__q {
    font-family: 'DMSerif', Georgia, serif;
    font-size: var(--t-xl);
    line-height: 1.35;
    color: var(--hi);
    font-style: italic;
    margin: 0;
  }
  .testimonial-feat__meta {
    font-size: var(--t-sm);
    color: var(--tx2);
    letter-spacing: .04em;
  }

  /* ── Testimonial card row — for the secondary "more voices" grid below ─ */
  .voices-grid {
    display: grid;
    gap: var(--s4);
    grid-template-columns: 1fr;
  }
  @media (min-width: 720px) {
    .voices-grid { grid-template-columns: repeat(3, 1fr); }
  }
  .voice-card {
    background: var(--sur);
    border: 1px solid var(--bdr);
    border-radius: var(--r);
    padding: var(--s5);
    display: flex;
    flex-direction: column;
    gap: var(--s3);
  }
  .voice-card__stars { color: var(--ac); font-size: var(--t-sm); letter-spacing: .08em; line-height: 1; }
  .voice-card__q {
    font-size: var(--t-sm);
    line-height: 1.6;
    color: var(--tx);
    margin: 0;
    flex: 1;
  }
  .voice-card__meta {
    font-size: var(--t-xs);
    color: var(--tx2);
    letter-spacing: .04em;
    margin: 0;
  }

} /* end press-strip + featured-testimonial append */


/* ============================================================================
   Missing chassis primitives — overflow + alignment fixes for the FocusFlow
   buybox column. The PDP `.product-layout__details` column is ~520px wide,
   so the buybox needs to be left-aligned, not center-aligned, and the
   `.trust-strip` (declared in @layer motion but never styled as a list) and
   `.urgency` (same story) need real base styles.
   ============================================================================ */
@layer components {

  /* Buybox — override the centered, oversized lbcom .book-blk inheritance.
     A PDP buybox lives inside a narrow ~520px column; large center-aligned
     padding makes the price + CTA float in too much air, and `text-align:
     center` breaks the var-grid / subsave / bump readability.

     CRITICAL: the chassis flips the buybox to flex-direction:row at >=640px
     (commerce.css L1508) for the legacy `.book-blk` image+text book layout.
     That's wrong for a PDP buybox; force column-stack here. */
  .product-layout .buybox,
  .product-details > .buybox {
    flex-direction: column !important;
    align-items: stretch;
    text-align: left;
    padding: var(--s5);
    gap: var(--s4);
    box-shadow: 0 12px 32px -20px rgba(0, 0, 0, .14);
  }
  /* Every direct child of the buybox is a full-width row. Without min-width:0
     a flex item with intrinsic content sizing (esp. with container-type) can
     collapse to its content size. */
  .product-layout .buybox > *,
  .product-details > .buybox > * {
    width: 100%;
    min-width: 0;
  }
  .product-layout .buybox .product-price,
  .product-details .buybox .product-price {
    font-size: var(--t-2xl);
    line-height: 1.1;
    margin: 0;
  }

  /* .urgency — small badge under price showing scarcity / restock copy.
     Previously had ONLY the scroll-reveal animation and no base styles, so
     it rendered as unstyled <p>. */
  .urgency {
    display: inline-flex;
    align-items: center;
    gap: var(--s2);
    margin: 0;
    padding: var(--s2) var(--s3);
    font-size: var(--t-xs);
    letter-spacing: .04em;
    color: var(--ac);
    background: color-mix(in oklch, var(--ac) 8%, transparent);
    border: 1px solid color-mix(in oklch, var(--ac) 25%, transparent);
    border-radius: var(--r);
    line-height: 1.35;
  }
  .urgency::before {
    content: '●';
    font-size: .55em;
    color: var(--ac);
    animation: urgency-pulse 1.6s ease-in-out infinite;
  }
  @keyframes urgency-pulse {
    0%, 100% { opacity: .35; }
    50%      { opacity: 1; }
  }
  @media (prefers-reduced-motion: reduce) {
    .urgency::before { animation: none; opacity: .85; }
  }

  /* .trust-strip — guarantee row under ATC button. Previously unstyled <ul>
     with default browser bullets, which caused a horizontal overflow on
     PDPs with 5+ trust items (each item rendered as a wide flex row).
     Now a 2-column grid of icon+label rows, with the icon muted (--tx3). */
  .trust-strip {
    list-style: none;
    margin: 0;
    padding: var(--s4) 0 0 0;
    border-top: 1px solid var(--bdr);
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--s2) var(--s4);
  }
  @media (min-width: 480px) {
    .trust-strip { grid-template-columns: 1fr 1fr; }
  }
  .trust-strip .strip__it {
    display: flex;
    align-items: center;
    gap: var(--s2);
    padding: 0;
    background: none;
    transition: none;
  }
  .trust-strip .strip__it:hover { background: none; }
  .trust-strip .strip__lbl {
    width: 20px;
    height: 20px;
    flex-shrink: 0;
    opacity: .65;
    margin: 0;
    color: var(--tx2);
    background: none;
    text-transform: none;
    letter-spacing: 0;
    font-size: 0;  /* hide alt text fallback if image fails — icons only */
  }
  .trust-strip .strip__d {
    font-size: var(--t-xs);
    color: var(--tx2);
    line-height: 1.4;
    margin: 0;
  }

  /* Var-grid (pack-size pills) — the focusflow labels are long full-text
     sentences. Default .var-btn is a 48×40 swatch which forces the text
     to either wrap awkwardly or overflow. Up-modifier to row-pill style. */
  .product-layout .var-grid,
  .product-details .var-grid {
    flex-direction: column;
    gap: var(--s2);
  }
  .product-layout .var-grid .var-btn,
  .product-details .var-grid .var-btn {
    width: 100%;
    height: auto;
    min-height: 44px;
    padding: var(--s3) var(--s4);
    justify-content: flex-start;
    white-space: normal;
    text-align: left;
    font-size: var(--t-sm);
    letter-spacing: .02em;
    text-transform: none;
    line-height: 1.3;
  }

  /* Shipping note under ATC. */
  .shipping-note {
    font-size: var(--t-xs);
    color: var(--tx2);
    text-align: center;
    margin: 0;
    letter-spacing: .04em;
  }

  /* Breadcrumb tightening — the unstyled chassis breadcrumb had no padding,
     leaving it flush to the page edges below the strip. */
  .breadcrumb {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--s2);
    font-size: var(--t-xs);
    color: var(--tx3);
    letter-spacing: .04em;
  }
  .breadcrumb a {
    color: var(--tx3);
    text-decoration: none;
    transition: color var(--dur) var(--ease);
  }
  .breadcrumb a:hover { color: var(--tx); }
  .breadcrumb [aria-current="page"] { color: var(--tx2); }

  /* Hero claim — softer scale + tighter line height on a serif headline. */
  .hero-slide .sec-h {
    font-size: clamp(2rem, 4vw + .5rem, 3.4rem);
    line-height: 1.08;
    margin-bottom: var(--s3);
  }
  .hero-slide .sec-sub {
    margin-bottom: var(--s3);
  }
  .hero-slide__img picture,
  .hero-slide__img img {
    width: 100%;
    height: auto;
    border-radius: var(--r2);
    box-shadow: 0 24px 60px -28px rgba(0, 0, 0, .25);
    object-fit: cover;
    aspect-ratio: 4 / 3;
  }

  /* Product-details column — the lbcom-ported padding-top calc was correct
     when the page-wrap added no top padding, but with `.page { padding-top:
     var(--nav) }` we're double-padding. Strip the extra. */
  .product-layout .product-details {
    padding-top: var(--s4);
  }

  /* Product-layout proportions — the chassis defaults to 58/42 with a
     520px cap on the details column. On 1440px desktop that gives a
     ~280px buybox after padding — too narrow for the modern subsave +
     bump + var-grid stack. Widen the details side and pad the gallery
     side less. */
  @media (min-width: 900px) {
    .product-layout {
      grid-template-columns: minmax(0, 1fr) minmax(420px, 560px);
      gap: var(--s5);
      align-items: start;
      padding-block: var(--s5);
    }
    .product-layout__gallery {
      position: sticky;
      top: calc(var(--nav) + var(--s4));
      height: auto;
      max-height: calc(100svh - var(--nav) - var(--s4));
    }
    .product-layout__details {
      padding: var(--s4) 0 var(--s6) 0;
      max-width: none;
    }
  }

  /* Stats-strip — chassis sets 3-col at md+. With 4 stats this leaves the
     4th wrapped onto its own row at half-width. Force 2-col at md, 4-col
     at lg+. (Pure 4-col at md=768 overflows due to fluid font sizes.) */
  @media (min-width: 640px) {
    .stats-strip { grid-template-columns: repeat(2, 1fr); }
  }
  @media (min-width: 1024px) {
    .stats-strip { grid-template-columns: repeat(4, 1fr); }
  }

  /* Hero composition — the gallery + hero side-by-side at md+ wants
     better aspect-ratio control on the image side. */
  @media (min-width: 768px) {
    .hero-slide__img picture,
    .hero-slide__img img { aspect-ratio: 5 / 4; }
  }

  /* Accordion inside the buybox card — tighten summary letter-spacing so
     it reads as a section label not shouted ALL-CAPS. */
  .product-details > .accordion summary {
    letter-spacing: .06em;
    font-size: var(--t-sm);
    text-transform: none;
    color: var(--hi);
    font-weight: 600;
  }

} /* end overflow-fix + buybox-tighten append */




/* ============================================================================
   SURVIVOR-BRAND CONTENT SECTIONS — added 2026-06-09 to deepen FocusFlow
   (and any future brand) to the daydreamers-showcase quality bar. Each block
   below corresponds to a partial under templates/partials/. Reads:
     - press_bar
     - founder_story
     - studies
     - lab_certs
     - comparison_table
     - risk_reversal
     - savings_calc
     - review-volume + expanded testimonials
   ============================================================================ */
@layer components {

  /* ── .press-bar — "Featured in" wide strip ─────────────────────────────── */
  .press-bar {
    border-top: 1px solid var(--bdr);
    border-bottom: 1px solid var(--bdr);
    background: color-mix(in oklch, var(--sur) 50%, var(--bg));
    padding-block: var(--s4);
  }
  .press-bar__in {
    display: flex;
    flex-direction: column;
    gap: var(--s3);
    align-items: center;
    text-align: center;
  }
  @media (min-width: 768px) {
    .press-bar__in { flex-direction: row; gap: var(--s5); }
  }
  .press-bar__lbl {
    font-size: var(--t-2xs);
    letter-spacing: .18em;
    text-transform: uppercase;
    color: var(--tx3);
    white-space: nowrap;
    flex-shrink: 0;
  }
  .press-bar__list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    align-items: center;
    gap: var(--s4) var(--s5);
    flex: 1;
  }
  .press-bar__it {
    font-family: 'Charter', 'Iowan Old Style', Georgia, serif;
    font-size: var(--t-sm);
    letter-spacing: .04em;
    color: var(--tx2);
    font-weight: 600;
    text-transform: uppercase;
    white-space: nowrap;
  }
  @media (min-width: 768px) {
    .press-bar__it { font-size: var(--t-b); }
  }


  /* ── .review-volume — confidence badge above buybox ────────────────────── */
  .review-volume {
    display: flex;
    flex-direction: column;
    gap: var(--s1);
    padding: var(--s3) 0;
    margin-bottom: var(--s3);
  }
  .review-volume__stars {
    color: var(--ff-sand-d, #b8895a);
    font-size: var(--t-b);
    letter-spacing: .15em;
    line-height: 1;
  }
  .review-volume__d {
    font-size: var(--t-sm);
    color: var(--tx2);
  }
  .review-volume__d strong { color: var(--hi); font-weight: 700; }
  .review-volume__src {
    margin-top: var(--s1);
    font-size: var(--t-xs);
    color: var(--tx3);
  }
  .review-volume__src summary {
    cursor: pointer;
    color: var(--tx3);
    text-decoration: underline dotted;
    text-underline-offset: 3px;
    list-style: none;
  }
  .review-volume__src summary::-webkit-details-marker { display: none; }
  .review-volume__src p { margin: var(--s2) 0 0; line-height: 1.5; }


  /* ── .founder-story — section ──────────────────────────────────────────── */
  .founder-story {
    background: color-mix(in oklch, var(--sur) 60%, var(--bg));
    border-block: 1px solid var(--bdr);
  }
  .founder-story__in {
    display: grid;
    gap: var(--s5);
    grid-template-columns: 1fr;
    align-items: start;
  }
  @media (min-width: 900px) {
    .founder-story__in {
      grid-template-columns: minmax(0, 360px) 1fr;
      gap: var(--s6);
    }
  }
  .founder-story__media { display: flex; flex-direction: column; gap: var(--s3); }
  .founder-story__img {
    width: 100%;
    height: auto;
    border-radius: var(--r2);
    aspect-ratio: 4 / 5;
    object-fit: cover;
    background: var(--sur2);
    box-shadow: 0 20px 50px -28px rgba(0, 0, 0, .22);
  }
  .founder-story__caption {
    font-size: var(--t-sm);
    color: var(--tx2);
    line-height: 1.45;
    text-align: left;
  }
  .founder-story__caption strong { color: var(--hi); font-weight: 700; }
  .founder-story__body { display: flex; flex-direction: column; gap: var(--s3); max-width: 65ch; }
  .founder-story__quote {
    font-family: 'Charter', 'Iowan Old Style', Georgia, serif;
    font-size: clamp(1.2rem, 2vw + .6rem, 1.6rem);
    line-height: 1.32;
    font-style: italic;
    color: var(--hi);
    margin: var(--s2) 0;
    padding-left: var(--s4);
    border-left: 3px solid var(--ac2, var(--ff-sand, var(--ac)));
  }
  .founder-story__story,
  .founder-story__bio {
    font-size: var(--t-b);
    line-height: 1.65;
    color: var(--tx);
    margin: 0;
  }
  .founder-story__bio { color: var(--tx2); font-size: var(--t-sm); }


  /* ── .studies — citation grid ──────────────────────────────────────────── */
  .studies__grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--s4);
    margin-top: var(--s5);
  }
  @media (min-width: 720px)  { .studies__grid { grid-template-columns: 1fr 1fr; } }
  @media (min-width: 1100px) { .studies__grid { grid-template-columns: 1fr 1fr 1fr; } }
  .study-card {
    background: var(--sur);
    border: 1px solid var(--bdr);
    border-radius: var(--r);
    padding: var(--s5);
    display: flex;
    flex-direction: column;
    gap: var(--s2);
    transition: border-color .25s ease, box-shadow .25s ease;
  }
  .study-card:hover {
    border-color: var(--bdr2);
    box-shadow: 0 12px 28px -22px rgba(0, 0, 0, .18);
  }
  .study-card__ing {
    font-size: var(--t-2xs);
    letter-spacing: .14em;
    text-transform: uppercase;
    color: var(--ac);
    margin: 0;
    font-weight: 700;
  }
  .study-card__h {
    font-family: 'Charter', 'Iowan Old Style', Georgia, serif;
    font-size: var(--t-lg);
    line-height: 1.25;
    color: var(--hi);
    margin: 0;
    font-weight: 600;
  }
  .study-card__cite {
    font-size: var(--t-xs);
    font-style: italic;
    color: var(--tx3);
    margin: 0;
  }
  .study-card__sum {
    font-size: var(--t-sm);
    line-height: 1.5;
    color: var(--tx2);
    margin: 0;
  }
  .studies__note {
    margin-top: var(--s5);
    font-size: var(--t-xs);
    color: var(--tx3);
    text-align: center;
    font-style: italic;
  }


  /* ── .lab-certs — receipt list ─────────────────────────────────────────── */
  .lab-certs__list {
    list-style: none;
    margin: var(--s5) 0 0;
    padding: 0;
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--s3) var(--s5);
  }
  @media (min-width: 720px) {
    .lab-certs__list { grid-template-columns: 1fr 1fr; }
  }
  .lab-certs__it {
    display: flex;
    align-items: flex-start;
    gap: var(--s3);
    padding-block: var(--s2);
  }
  .lab-certs__chk {
    flex-shrink: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    border-radius: 50%;
    background: color-mix(in oklch, var(--ac) 12%, transparent);
    color: var(--ac);
  }
  .lab-certs__d {
    font-size: var(--t-sm);
    line-height: 1.5;
    color: var(--tx);
  }
  .lab-certs__hsa {
    margin-top: var(--s5);
    padding: var(--s4) var(--s5);
    background: color-mix(in oklch, var(--ac2, var(--ac)) 10%, var(--sur));
    border: 1px solid color-mix(in oklch, var(--ac2, var(--ac)) 30%, var(--bdr));
    border-radius: var(--r);
    font-size: var(--t-sm);
    line-height: 1.55;
    color: var(--tx);
  }
  .lab-certs__hsa strong { color: var(--hi); font-weight: 700; }


  /* ── .comparison — vs-table ────────────────────────────────────────────── */
  .comparison__scroll {
    margin-top: var(--s5);
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    border: 1px solid var(--bdr);
    border-radius: var(--r);
    background: var(--sur);
  }
  .comparison__tbl {
    width: 100%;
    border-collapse: collapse;
    min-width: 720px;
    font-size: var(--t-sm);
  }
  .comparison__tbl thead {
    background: color-mix(in oklch, var(--sur2) 60%, var(--bg));
  }
  .comparison__tbl th,
  .comparison__tbl td {
    padding: var(--s3) var(--s4);
    text-align: left;
    border-bottom: 1px solid var(--bdr);
  }
  .comparison__tbl thead th {
    font-family: 'Charter', 'Iowan Old Style', Georgia, serif;
    font-size: var(--t-sm);
    font-weight: 700;
    letter-spacing: .02em;
    color: var(--hi);
    text-transform: none;
  }
  .comparison__lbl {
    font-weight: 600;
    color: var(--tx);
    white-space: nowrap;
  }
  .comparison__hl {
    background: color-mix(in oklch, var(--ac) 8%, transparent);
    color: var(--hi);
    font-weight: 700;
  }
  .comparison__tbl thead .comparison__hl {
    background: color-mix(in oklch, var(--ac) 14%, transparent);
    border-bottom-color: var(--ac);
  }
  .comparison__tbl tbody tr:last-child th,
  .comparison__tbl tbody tr:last-child td {
    border-bottom: none;
  }


  /* ── .risk-reversal — guarantee block ─────────────────────────────────── */
  .risk-reversal {
    background: color-mix(in oklch, var(--ac) 4%, var(--sur));
    border-block: 1px solid color-mix(in oklch, var(--ac) 15%, var(--bdr));
    text-align: center;
  }
  .risk-reversal__in {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--s3);
  }
  .risk-reversal__icon {
    color: var(--ac);
    width: 56px;
    height: 56px;
    margin-bottom: var(--s1);
  }
  .risk-reversal__detail {
    font-size: var(--t-b);
    line-height: 1.6;
    color: var(--tx);
    max-width: 56ch;
    margin: 0 auto;
  }
  .risk-reversal__fine {
    font-size: var(--t-sm);
    color: var(--tx2);
    line-height: 1.55;
    max-width: 56ch;
    margin: 0 auto;
  }
  .risk-reversal .btn { margin-top: var(--s3); }


  /* ── .savings — switching-cost block ──────────────────────────────────── */
  .savings__rows {
    margin-top: var(--s5);
    display: flex;
    flex-direction: column;
    gap: var(--s3);
  }
  .savings__row {
    display: flex;
    flex-direction: column;
    gap: var(--s1);
    padding: var(--s4) var(--s5);
    border: 1px solid var(--bdr);
    border-radius: var(--r);
    background: var(--sur);
    margin: 0;
  }
  .savings__row--ours {
    border-color: var(--ac);
    background: color-mix(in oklch, var(--ac) 6%, var(--sur));
  }
  .savings__row-lbl {
    font-size: var(--t-2xs);
    letter-spacing: .14em;
    text-transform: uppercase;
    color: var(--tx3);
  }
  .savings__row-d {
    font-size: var(--t-b);
    color: var(--hi);
    font-weight: 500;
  }
  .savings__total {
    margin-top: var(--s5);
    padding: var(--s5);
    background: var(--hi);
    color: var(--bg);
    border-radius: var(--r);
    text-align: center;
    font-family: 'Charter', 'Iowan Old Style', Georgia, serif;
    font-size: var(--t-xl);
    font-weight: 700;
    line-height: 1.25;
  }


  /* ── Voice-card depth overrides — for richer testimonials with photo + meta */
  .voices-grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--s4);
  }
  @media (min-width: 720px)  { .voices-grid { grid-template-columns: 1fr 1fr; } }
  @media (min-width: 1100px) { .voices-grid { grid-template-columns: 1fr 1fr 1fr; } }
  .voice-card {
    background: var(--sur);
    border: 1px solid var(--bdr);
    border-radius: var(--r);
    padding: var(--s5);
    margin: 0;
    display: flex;
    flex-direction: column;
    gap: var(--s3);
    transition: border-color .25s ease, box-shadow .25s ease;
  }
  .voice-card:hover {
    border-color: var(--bdr2);
    box-shadow: 0 12px 28px -22px rgba(0, 0, 0, .15);
  }
  .voice-card__stars {
    color: var(--ff-sand-d, #b8895a);
    font-size: var(--t-sm);
    letter-spacing: .15em;
    line-height: 1;
  }
  .voice-card__q {
    font-family: 'Charter', 'Iowan Old Style', Georgia, serif;
    font-style: italic;
    font-size: var(--t-b);
    line-height: 1.55;
    color: var(--tx);
    margin: 0;
    flex: 1;
  }
  .voice-card__meta {
    display: flex;
    align-items: center;
    gap: var(--s3);
    margin-top: var(--s2);
    padding-top: var(--s3);
    border-top: 1px solid var(--bdr);
  }
  .voice-card__img {
    width: 44px;
    height: 44px;
    border-radius: 50%;
    object-fit: cover;
    background: var(--sur2);
    flex-shrink: 0;
  }
  .voice-card__person {
    font-size: var(--t-xs);
    line-height: 1.4;
    color: var(--tx2);
  }
  .voice-card__person strong { color: var(--hi); font-weight: 700; font-size: var(--t-sm); }
  .voice-card__title { color: var(--tx2); }
  .voice-card__use { color: var(--tx3); font-style: italic; }

  /* Featured testimonial — adds photo + multi-line meta block. */
  .testimonial-feat {
    background: color-mix(in oklch, var(--sur) 70%, var(--bg));
    border: 1px solid var(--bdr);
    border-radius: var(--r2);
    padding: var(--s6);
    text-align: center;
    margin: 0 auto;
    max-width: 720px;
    display: flex;
    flex-direction: column;
    gap: var(--s3);
    align-items: center;
  }
  .testimonial-feat__stars {
    color: var(--ff-sand-d, #b8895a);
    font-size: var(--t-lg);
    letter-spacing: .18em;
  }
  .testimonial-feat__q {
    font-family: 'Charter', 'Iowan Old Style', Georgia, serif;
    font-style: italic;
    font-size: clamp(1.15rem, 2vw + .4rem, 1.5rem);
    line-height: 1.5;
    color: var(--hi);
    margin: 0;
  }
  .testimonial-feat__meta {
    display: flex;
    align-items: center;
    gap: var(--s3);
    margin: 0;
    padding-top: var(--s3);
    border-top: 1px solid var(--bdr);
    font-size: var(--t-sm);
    color: var(--tx2);
    text-align: left;
    width: 100%;
    max-width: 420px;
    justify-content: center;
  }
  .testimonial-feat__img {
    width: 56px;
    height: 56px;
    border-radius: 50%;
    object-fit: cover;
    background: var(--sur2);
  }
  .testimonial-feat__meta strong { color: var(--hi); font-weight: 700; }
  .testimonial-feat__meta em { color: var(--tx3); font-style: italic; font-size: var(--t-xs); }

} /* end @layer components — survivor-brand sections */


/* ============================================================================
   LP V2 — CAP v2 compliant section choreography + visual-density chassis
   Added 2026-06-10 — see docs/FOCUSFLOW_LP_V2_PLAN.md.

   All rules live in a single @layer components block at the END so they
   win against earlier components without !important, but stay overridable
   by @layer utilities and the brand theme.css.
   ============================================================================ */
@layer components {

  /* ── Binary palette utility ─────────────────────────────────────────────── */
  .sec--inverse {
    background: oklch(15% 0.005 280);
    color: oklch(95% 0.01 80);
  }
  .sec--inverse .sec-h,
  .sec--inverse h2,
  .sec--inverse h3 { color: oklch(98% 0.012 80); }
  .sec--inverse .lbl { color: oklch(78% 0.07 60); }
  .sec--inverse .sec-sub,
  .sec--inverse p { color: oklch(85% 0.01 80); }


  /* ── Sticky local sub-nav (Apple PDP pattern) ────────────────────────────
     Sits under the main <nav>. Hidden on initial render (so the page doesn't
     show a "double header") and slides into view after the user scrolls past
     the hero. JS toggles `.sticky-subnav--compact` (compact spacing past hero)
     and additionally toggles a translateY transform via the same scroll
     handler so the bar can appear/disappear. */
  .sticky-subnav {
    position: sticky;
    top: var(--nav, 60px);
    z-index: 30;
    background: color-mix(in oklch, var(--bg) 88%, transparent);
    backdrop-filter: saturate(140%) blur(10px);
    -webkit-backdrop-filter: saturate(140%) blur(10px);
    border-bottom: 1px solid var(--bdr);
    transition: transform .3s var(--ease), padding-block .25s var(--ease), opacity .25s var(--ease);
    /* Hidden on initial render — slides in once the hero is scrolled past. */
    transform: translateY(-110%);
    opacity: 0;
    pointer-events: none;
  }
  .sticky-subnav--compact {
    transform: translateY(0);
    opacity: 1;
    pointer-events: auto;
  }
  .sticky-subnav__in {
    display: flex;
    align-items: center;
    gap: var(--s4);
    padding-block: var(--s2);
  }
  .sticky-subnav__brand {
    font-family: 'DMSerif', Charter, Georgia, serif;
    font-size: var(--t-md);
    color: var(--hi);
    flex-shrink: 0;
  }
  .sticky-subnav__list {
    display: flex;
    gap: var(--s4);
    flex: 1;
    overflow-x: auto;
    -ms-overflow-style: none;
    scrollbar-width: none;
  }
  .sticky-subnav__list::-webkit-scrollbar { display: none; }
  .sticky-subnav__link {
    font-size: var(--t-xs);
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--tx2);
    white-space: nowrap;
    padding-block: var(--s1);
    border-bottom: 1px solid transparent;
    transition: color var(--dur) var(--ease), border-color var(--dur) var(--ease);
  }
  .sticky-subnav__link:hover,
  .sticky-subnav__link[aria-current="true"] {
    color: var(--hi);
    border-bottom-color: var(--ac);
  }
  .sticky-subnav__cta { flex-shrink: 0; }
  .sticky-subnav--compact .sticky-subnav__in { padding-block: var(--s1); }
  .sticky-subnav--compact .sticky-subnav__brand { font-size: var(--t-sm); }

  @media (max-width: 720px) {
    .sticky-subnav__brand { display: none; }
    .sticky-subnav__cta { display: none; }
  }


  /* ── Scroll anchor offset for all in-page jumps ─────────────────────────── */
  .lpv2-anchor,
  [id="overview"], [id="how-it-works"], [id="materials"],
  [id="comparison"], [id="reviews"], [id="buybox"],
  [id="faq"], [id="guarantee"], [id="why-us"], [id="founder"], [id="lifestyle"] {
    scroll-margin-top: calc(var(--nav, 60px) + var(--s5));
  }


  /* ── Section 1: Hero (V1 + V15) ─────────────────────────────────────────── */
  .lpv2-hero {
    position: relative;
    isolation: isolate;
    overflow: hidden;
    min-height: 78svh;        /* CAP V1 ≥70% viewport target. svh handles iOS chrome. */
    display: grid;
    align-items: center;
    padding-block: var(--s7);
  }
  .lpv2-hero__bg {
    position: absolute;
    inset: 0;
    z-index: -1;
  }
  .lpv2-hero__bg picture,
  .lpv2-hero__img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: center;
  }
  .lpv2-hero__veil {
    position: absolute;
    inset: 0;
    /* ROOT 2 — WCAG AA contrast scrim for hero text.
       Previously a thin vertical gradient relied on photo luminance to carry
       contrast. Replaced with a stronger left-side dark backplate that gives
       the hero h1/sub a guaranteed ~7:1 contrast against the photo regardless
       of which lifestyle frame loads. Right side stays mostly translucent so
       the photo subject still reads. Bottom gradient supports the proof line. */
    background:
      linear-gradient(90deg,
        oklch(12% 0.01 280 / .78) 0%,
        oklch(12% 0.01 280 / .58) 35%,
        oklch(12% 0.01 280 / .18) 70%,
        oklch(12% 0.01 280 / .05) 100%),
      linear-gradient(180deg,
        oklch(12% 0.01 280 / .15) 0%,
        oklch(12% 0.01 280 / .05) 50%,
        oklch(12% 0.01 280 / .55) 100%);
  }
  @media (max-width: 700px) {
    /* Mobile: text wraps below photo focal point; use a symmetric dark veil
       that lifts contrast everywhere. */
    .lpv2-hero__veil {
      background:
        linear-gradient(180deg,
          oklch(12% 0.01 280 / .35) 0%,
          oklch(12% 0.01 280 / .55) 55%,
          oklch(12% 0.01 280 / .80) 100%);
    }
  }
  .lpv2-hero__txt {
    position: relative;
    max-width: 720px;
  }
  .lpv2-hero__eyebrow { color: oklch(82% 0.10 60); }
  .lpv2-hero__h1 {
    font-family: 'DMSerif', Charter, Georgia, serif;
    font-size: clamp(2.4rem, 6vw + 1rem, 5rem);
    line-height: 1.02;
    letter-spacing: -0.02em;
    color: #ffffff;
    margin-block: var(--s3) var(--s4);
    text-wrap: balance;
  }
  .lpv2-hero__sub {
    font-size: var(--t-md);
    color: oklch(95% 0.01 80);
    max-width: 56ch;
    line-height: 1.55;
    margin-bottom: var(--s5);
  }
  .lpv2-hero__cta { gap: var(--s3); margin-bottom: var(--s4); }
  .lpv2-hero__proof {
    display: inline-flex;
    align-items: center;
    gap: var(--s2);
    color: oklch(90% 0.01 80);
    font-size: var(--t-sm);
  }
  .lpv2-hero__proof svg { color: oklch(82% 0.10 60); }


  /* ── Section 2: Highlights / TOC ───────────────────────────────────────── */
  .lpv2-highlights {
    padding-block: var(--s4);
    border-bottom: 1px solid var(--bdr);
  }
  .lpv2-highlights__grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
    gap: var(--s3);
  }
  .lpv2-highlights__link {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: var(--s2);
    padding: var(--s4);
    border-radius: var(--r2);
    background: var(--sur);
    border: 1px solid var(--bdr);
    transition: background-color var(--dur) var(--ease), border-color var(--dur) var(--ease);
  }
  .lpv2-highlights__link:hover,
  .lpv2-highlights__link:focus-visible {
    background: var(--sur2);
    border-color: var(--ac);
  }
  .lpv2-highlights__icon { color: var(--ac); display: inline-flex; }
  .lpv2-highlights__lbl {
    font-family: 'DMSerif', Charter, Georgia, serif;
    font-size: var(--t-md);
    color: var(--hi);
    line-height: 1.2;
  }
  .lpv2-highlights__blurb {
    font-size: var(--t-xs);
    color: var(--tx2);
    line-height: 1.5;
  }


  /* ── Section 3: Three-pillar + icon row (V10) ──────────────────────────── */
  .lpv2-pillars__grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--s5);
    margin-top: var(--s5);
  }
  @media (min-width: 700px) {
    .lpv2-pillars__grid { grid-template-columns: repeat(3, 1fr); }
  }
  .lpv2-pillars__card {
    padding: var(--s5);
    background: var(--sur);
    border: 1px solid var(--bdr);
    border-radius: var(--r2);
    text-align: center;
  }
  .lpv2-pillars__icon {
    width: 64px;
    height: 64px;
    margin: 0 auto var(--s3);
    color: var(--ac);
    background: var(--ac-lo);
    border-radius: 50%;
    display: grid;
    place-items: center;
  }
  .lpv2-pillars__title {
    font-family: 'DMSerif', Charter, Georgia, serif;
    font-size: var(--t-lg);
    color: var(--hi);
    margin-block: var(--s2);
    line-height: 1.15;
  }
  .lpv2-pillars__body {
    color: var(--tx2);
    font-size: var(--t-sm);
    line-height: 1.6;
  }

  .icon-row {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(110px, 1fr));
    gap: var(--s4);
    margin-top: var(--s6);
    padding-block: var(--s5);
    border-block: 1px solid var(--bdr);
    text-align: center;
  }
  .icon-row__it {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--s2);
  }
  .icon-row__ic {
    color: var(--ac);
    width: 44px;
    height: 44px;
    display: grid;
    place-items: center;
  }
  .icon-row__lbl {
    font-size: var(--t-xs);
    color: var(--tx2);
    letter-spacing: .03em;
  }


  /* ── Section 4: Brag bar + S1 oversized proof number ───────────────────── */
  .lpv2-bragbar {
    background: var(--sur2);
    border-block: 1px solid var(--bdr);
    padding-block: var(--s6);
  }
  .lpv2-bragbar__in {
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--s5);
    align-items: center;
  }
  @media (min-width: 800px) {
    .lpv2-bragbar__in { grid-template-columns: 1fr 1.4fr; }
  }
  .lpv2-bragbar__stats { text-align: left; }
  .lpv2-bragbar__stats-lbl {
    font-size: var(--t-sm);
    color: var(--tx2);
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--s2);
    margin-top: var(--s2);
  }
  .lpv2-bragbar__stars { color: var(--ac); display: inline-flex; gap: 1px; }
  .lpv2-bragbar__src {
    margin-top: var(--s2);
    font-size: var(--t-xs);
    color: var(--tx3);
  }
  .lpv2-bragbar__src summary {
    cursor: pointer;
    text-decoration: underline;
    text-underline-offset: 3px;
  }
  .lpv2-bragbar__quote {
    margin: 0;
    padding: var(--s5);
    background: var(--sur);
    border: 1px solid var(--bdr);
    border-radius: var(--r2);
    position: relative;
  }
  .lpv2-bragbar__quote-mark {
    position: absolute;
    top: -.2em;
    left: var(--s3);
    font-family: 'DMSerif', Charter, Georgia, serif;
    font-size: 5rem;
    line-height: 1;
    color: var(--ac);
    opacity: .35;
  }
  .lpv2-bragbar__quote-txt {
    font-family: 'Charter', 'Iowan Old Style', Georgia, serif;
    font-style: italic;
    font-size: var(--t-md);
    line-height: 1.55;
    color: var(--hi);
    margin: 0 0 var(--s3);
  }
  .lpv2-bragbar__quote-meta {
    display: flex;
    align-items: center;
    gap: var(--s3);
    font-size: var(--t-xs);
    color: var(--tx2);
  }
  .lpv2-bragbar__portrait-img {
    width: 56px;
    height: 56px;
    border-radius: 50%;
    object-fit: cover;
    background: var(--sur2);
  }


  /* ── S1 proof-number — "type IS the visual" Apple pattern ──────────────── */
  .proof-number {
    font-family: 'DMSerif', Charter, Georgia, serif;
    font-size: clamp(3rem, 8vw + 1rem, 7rem);
    line-height: .9;
    letter-spacing: -0.03em;
    color: var(--hi);
    margin: 0;
    /* Issue #4 fix — "60-day" / "4 hr" must NOT split across lines. */
    white-space: nowrap;
  }
  .proof-row {
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--s5);
    margin-block: var(--s6);
    text-align: center;
  }
  @media (min-width: 800px) {
    .proof-row { grid-template-columns: repeat(3, 1fr); }
  }
  .proof-row__lbl {
    font-size: var(--t-sm);
    color: var(--tx2);
    margin-top: var(--s2);
    max-width: 24ch;
    margin-inline: auto;
  }


  /* ── Section 5: Founder + video poster ─────────────────────────────────── */
  .lpv2-founder__in {
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--s6);
    align-items: start;
  }
  @media (min-width: 900px) {
    .lpv2-founder__in { grid-template-columns: 1fr 1.6fr; }
  }
  .lpv2-founder__portrait {
    width: 100%;
    aspect-ratio: 4 / 5;
    object-fit: cover;
    border-radius: var(--r2);
    background: var(--sur2);
  }
  .lpv2-founder__caption {
    margin-top: var(--s2);
    font-size: var(--t-sm);
    color: var(--tx2);
    line-height: 1.4;
  }
  .lpv2-founder__caption strong { color: var(--hi); font-weight: 700; }
  .lpv2-founder__quote {
    font-family: 'Charter', 'Iowan Old Style', Georgia, serif;
    font-style: italic;
    font-size: var(--t-lg);
    line-height: 1.45;
    color: var(--hi);
    padding-inline: var(--s4);
    border-left: 3px solid var(--ac);
    margin-block: var(--s4);
  }
  .lpv2-founder__story {
    color: var(--tx2);
    font-size: var(--t-b);
    line-height: 1.65;
    margin-bottom: var(--s4);
  }
  .lpv2-founder__bio {
    color: var(--tx3);
    font-size: var(--t-sm);
    line-height: 1.6;
  }
  .lpv2-founder__bio em { color: var(--tx2); font-style: italic; }

  /* Fix-4 #3, credentials list, tight comma-list aesthetic, not paragraph. */
  .lpv2-founder__creds {
    list-style: none;
    padding: 0;
    margin: var(--s4) 0 0 0;
    display: flex;
    flex-wrap: wrap;
    gap: var(--s2) var(--s4);
    font-size: var(--t-xs);
    color: var(--tx2);
    line-height: 1.3;
  }
  .lpv2-founder__cred {
    position: relative;
    padding-right: var(--s4);
  }
  .lpv2-founder__cred:not(:last-child)::after {
    content: "·";
    position: absolute;
    right: 0;
    top: 0;
    color: var(--tx3);
    opacity: .6;
  }

  .lpv2-founder__video { margin-top: var(--s5); }

  /* Issue #15 — static process-photo figure that replaces the empty
     <video> tag when founder.video_src is unset. Same visual weight as
     the video poster, but honest: no fake play controls. */
  .lpv2-founder__process-figure {
    margin: var(--s5) 0 0 0;
    border-radius: var(--r2);
    overflow: hidden;
    background: var(--sur2);
    border: 1px solid var(--bdr);
  }
  .lpv2-founder__process-img,
  .lpv2-founder__process-figure picture,
  .lpv2-founder__process-figure img {
    display: block;
    width: 100%;
    aspect-ratio: 16 / 9;
    object-fit: cover;
  }
  .lpv2-founder__process-cap {
    padding: var(--s3) var(--s4);
    font-size: var(--t-sm);
    color: var(--tx2);
    line-height: 1.5;
    background: var(--sur);
  }
  .lpv2-founder__video-poster {
    position: relative;
    cursor: pointer;
    border-radius: var(--r2);
    overflow: hidden;
    background: var(--sur2);
  }
  .lpv2-founder__video-img {
    width: 100%;
    aspect-ratio: 16 / 9;
    object-fit: cover;
  }
  .lpv2-founder__video-play {
    position: absolute;
    inset: 0;
    display: grid;
    place-items: center;
    color: oklch(70% 0.03 280);
    transition: color var(--dur) var(--ease);
  }
  .lpv2-founder__video-poster:hover .lpv2-founder__video-play { color: var(--ac); }
  .lpv2-founder__video-cap {
    position: absolute;
    bottom: var(--s3);
    left: var(--s3);
    font-size: var(--t-xs);
    color: #fff;
    letter-spacing: .08em;
    text-transform: uppercase;
    background: rgba(0,0,0,.55);
    padding: var(--s1) var(--s2);
    border-radius: var(--r);
  }


  /* ── Section 6: Material grid (V8) + breakdown callout (V14) ───────────── */
  .lpv2-material-grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--s4);
    margin-top: var(--s5);
  }
  @media (min-width: 700px) {
    .lpv2-material-grid { grid-template-columns: repeat(2, 1fr); }
  }
  @media (min-width: 1000px) {
    .lpv2-material-grid { grid-template-columns: repeat(4, 1fr); }
  }
  .lpv2-material-tile {
    margin: 0;
    border-radius: var(--r2);
    overflow: hidden;
    background: var(--sur);
    border: 1px solid var(--bdr);
    display: flex;
    flex-direction: column;
  }
  .lpv2-material-tile__img {
    width: 100%;
    aspect-ratio: 1 / 1;
    object-fit: cover;
    background: var(--sur2);
  }
  .lpv2-material-tile__cap {
    padding: var(--s4);
    display: flex;
    flex-direction: column;
    gap: var(--s1);
  }
  .lpv2-material-tile__name {
    font-family: 'DMSerif', Charter, Georgia, serif;
    color: var(--hi);
    font-size: var(--t-md);
    line-height: 1.2;
  }
  .lpv2-material-tile__dose {
    color: var(--ac);
    font-size: var(--t-sm);
    letter-spacing: .08em;
    text-transform: uppercase;
  }
  .lpv2-material-tile__src {
    color: var(--tx2);
    font-size: var(--t-xs);
    line-height: 1.5;
  }

  .callout-breakdown {
    margin-top: var(--s7);
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--s5);
    align-items: center;
    background: var(--sur2);
    padding: var(--s6);
    border-radius: var(--r2);
    border: 1px solid var(--bdr);
  }
  @media (min-width: 900px) {
    .callout-breakdown { grid-template-columns: 1fr 1fr; }
  }
  .callout-breakdown__h {
    grid-column: 1 / -1;
    font-family: 'DMSerif', Charter, Georgia, serif;
    font-size: var(--t-xl);
    color: var(--hi);
    text-align: center;
    margin-bottom: var(--s3);
  }
  .callout-breakdown__core {
    display: grid;
    place-items: center;
  }
  .callout-breakdown__img {
    width: 100%;
    max-width: 380px;
    aspect-ratio: 1 / 1;
    object-fit: contain;
  }
  .callout-breakdown__list {
    display: flex;
    flex-direction: column;
    gap: var(--s3);
    padding: 0;
  }
  .callout-breakdown__it {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: var(--s2) var(--s3);
    padding: var(--s3);
    background: var(--sur);
    border-radius: var(--r);
    border-left: 3px solid var(--ac);
  }
  .callout-breakdown__lbl {
    font-family: 'DMSerif', Charter, Georgia, serif;
    color: var(--hi);
    font-size: var(--t-md);
    grid-column: 1 / -1;
  }
  .callout-breakdown__copy {
    color: var(--tx2);
    font-size: var(--t-sm);
    line-height: 1.55;
    grid-column: 1 / -1;
  }


  /* ── Section 7: Comparison triptych (V9) + table + variant row (V12) ───── */
  .comparison-triptych {
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--s4);
    margin-top: var(--s5);
  }
  @media (min-width: 800px) {
    .comparison-triptych { grid-template-columns: repeat(3, 1fr); }
  }
  .comparison-triptych__panel {
    margin: 0;
    padding: 0;
    background: var(--sur);
    border: 1px solid var(--bdr);
    border-radius: var(--r2);
    overflow: hidden;
    display: flex;
    flex-direction: column;
  }
  .comparison-triptych__panel--hl {
    border-color: var(--ac);
    box-shadow: 0 0 0 3px var(--ac-lo);
  }
  .comparison-triptych__img {
    width: 100%;
    aspect-ratio: 1 / 1;
    object-fit: cover;
    background: var(--sur2);
  }
  .comparison-triptych__cap {
    padding: var(--s4);
    display: flex;
    flex-direction: column;
    gap: var(--s2);
  }
  .comparison-triptych__lbl {
    font-size: var(--t-xs);
    text-transform: uppercase;
    letter-spacing: .12em;
    color: var(--tx3);
  }
  .comparison-triptych__head {
    font-family: 'DMSerif', Charter, Georgia, serif;
    font-size: var(--t-lg);
    color: var(--hi);
    line-height: 1.15;
  }
  .comparison-triptych__body {
    color: var(--tx2);
    font-size: var(--t-sm);
    line-height: 1.55;
  }

  .variant-row {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
    gap: var(--s4);
    margin-top: var(--s6);
  }
  .variant-row__it {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--s2);
    text-align: center;
  }
  .variant-row__img {
    width: 100%;
    max-width: 200px;
    aspect-ratio: 1 / 1;
    object-fit: contain;
    background: var(--sur2);
    border-radius: var(--r2);
  }
  .variant-row__name {
    font-family: 'DMSerif', Charter, Georgia, serif;
    color: var(--hi);
    font-size: var(--t-md);
  }
  .variant-row__sub {
    color: var(--tx2);
    font-size: var(--t-xs);
  }


  /* ── Section 8: Lifestyle stripes (V11 full-bleed) ─────────────────────── */
  .lpv2-stripes {
    display: flex;
    flex-direction: column;
  }
  .full-bleed {
    width: 100vw;
    margin-inline: calc(50% - 50vw);
    position: relative;
  }
  .lpv2-stripe {
    position: relative;
    isolation: isolate;
    min-height: 60svh;
    display: grid;
    align-items: end;
    overflow: hidden;
    margin: 0;
  }
  .lpv2-stripe__bg {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    z-index: -1;
  }
  .lpv2-stripe::before {
    content: '';
    position: absolute;
    inset: 0;
    z-index: -1;
    /* ROOT 2 — caption-over-photo WCAG AA scrim. The bottom 35% of the
       stripe gets a near-opaque dark backplate so the white headline reads
       cleanly regardless of which lifestyle frame loads. Top 50% stays
       transparent so the photo still carries the verb. */
    background: linear-gradient(180deg,
      transparent 0%,
      oklch(12% 0.01 280 / .05) 45%,
      oklch(12% 0.01 280 / .45) 65%,
      oklch(10% 0.01 280 / .85) 100%);
  }
  .lpv2-stripe--light::before {
    /* Light variant: inverse — heavy near-white scrim at the bottom so dark
       headline text on dark photo reads. */
    background: linear-gradient(180deg,
      transparent 0%,
      oklch(100% 0 0 / .10) 45%,
      oklch(100% 0 0 / .55) 65%,
      oklch(100% 0 0 / .90) 100%);
  }
  .lpv2-stripe__cap {
    padding: var(--s7) var(--s5);
    max-width: var(--wrap);
    margin: 0 auto;
    width: 100%;
  }
  .lpv2-stripe__copy {
    font-family: 'DMSerif', Charter, Georgia, serif;
    font-size: clamp(2rem, 5vw + .5rem, 4rem);
    line-height: 1.05;
    letter-spacing: -0.02em;
    color: #fff;
    margin: 0;
    text-wrap: balance;
    max-width: 18ch;
  }
  .lpv2-stripe--light .lpv2-stripe__copy {
    color: oklch(20% 0.01 280);
  }


  /* ── Section 9: Customer wall (V5) ─────────────────────────────────────── */
  .lpv2-customer-wall__grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--s4);
    margin-top: var(--s5);
  }
  @media (min-width: 700px) {
    .lpv2-customer-wall__grid { grid-template-columns: repeat(2, 1fr); }
  }
  @media (min-width: 1100px) {
    .lpv2-customer-wall__grid { grid-template-columns: repeat(3, 1fr); }
  }
  .lpv2-customer-card {
    margin: 0;
    padding: var(--s5);
    background: var(--sur);
    border: 1px solid var(--bdr);
    border-radius: var(--r2);
    display: flex;
    flex-direction: column;
    gap: var(--s3);
  }
  .lpv2-customer-card__stars { color: var(--ac); display: inline-flex; gap: 1px; }
  .lpv2-customer-card__q {
    font-family: 'Charter', 'Iowan Old Style', Georgia, serif;
    font-style: italic;
    font-size: var(--t-b);
    line-height: 1.55;
    color: var(--hi);
    margin: 0;
    flex: 1;
  }
  .lpv2-customer-card__meta {
    display: flex;
    align-items: center;
    gap: var(--s3);
    padding-top: var(--s3);
    border-top: 1px solid var(--bdr);
    font-size: var(--t-xs);
    color: var(--tx2);
    line-height: 1.4;
  }
  .lpv2-customer-card__portrait-img {
    width: 48px;
    height: 48px;
    border-radius: 50%;
    object-fit: cover;
    background: var(--sur2);
  }
  .lpv2-customer-card__person strong { color: var(--hi); font-weight: 700; font-size: var(--t-sm); }
  .lpv2-customer-card__person em { color: var(--tx3); font-style: italic; }


  /* ── Section 10: FAQ ──────────────────────────────────────────────────── */
  .lpv2-faq__list {
    margin-top: var(--s5);
    border-top: 1px solid var(--bdr);
  }
  .lpv2-faq__it {
    border-bottom: 1px solid var(--bdr);
  }
  .lpv2-faq__q {
    list-style: none;
    cursor: pointer;
    padding-block: var(--s4);
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--s3);
    font-family: 'DMSerif', Charter, Georgia, serif;
    font-size: var(--t-md);
    color: var(--hi);
    line-height: 1.3;
  }
  .lpv2-faq__q::-webkit-details-marker { display: none; }
  .lpv2-faq__chevron {
    font-size: 1.6rem;
    color: var(--ac);
    transition: transform var(--dur) var(--ease);
    flex-shrink: 0;
  }
  .lpv2-faq__it[open] .lpv2-faq__chevron { transform: rotate(45deg); }
  .lpv2-faq__a {
    padding-block: 0 var(--s4);
    color: var(--tx2);
    font-size: var(--t-b);
    line-height: 1.65;
  }


  /* ── Section 11: MBG capstone ─────────────────────────────────────────── */
  .lpv2-mbg__shield {
    display: inline-grid;
    place-items: center;
    color: var(--ac);
    background: var(--ac-lo);
    width: 96px;
    height: 96px;
    border-radius: 50%;
    margin: 0 auto var(--s4);
  }
  .lpv2-mbg__detail {
    color: oklch(85% 0.01 80);
    font-size: var(--t-md);
    line-height: 1.55;
    max-width: 56ch;
    margin: var(--s3) auto;
  }
  .lpv2-mbg__fine {
    color: oklch(72% 0.01 80);
    font-size: var(--t-sm);
    max-width: 56ch;
    margin: var(--s2) auto var(--s4);
  }
  .lpv2-mbg__row {
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--s4);
    margin-top: var(--s5);
    text-align: left;
  }
  @media (min-width: 800px) {
    .lpv2-mbg__row { grid-template-columns: repeat(3, 1fr); }
  }
  .lpv2-mbg__card {
    padding: var(--s4);
    background: oklch(22% 0.005 280);
    border: 1px solid oklch(30% 0.005 280);
    border-radius: var(--r2);
    display: flex;
    flex-direction: column;
    gap: var(--s2);
  }
  .lpv2-mbg__card-icon { color: var(--ac); }
  .lpv2-mbg__card-h {
    font-family: 'DMSerif', Charter, Georgia, serif;
    color: #fff;
    font-size: var(--t-md);
    line-height: 1.2;
  }
  .lpv2-mbg__card-c {
    color: oklch(82% 0.01 80);
    font-size: var(--t-sm);
    line-height: 1.55;
  }
  .lpv2-mbg__trust {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: var(--s3) var(--s5);
    margin-top: var(--s5);
    font-size: var(--t-xs);
    color: oklch(85% 0.01 80);
  }
  .lpv2-mbg__trust-it {
    display: inline-flex;
    align-items: center;
    gap: var(--s1);
  }
  .lpv2-mbg__trust-it svg { color: var(--ac); }


  /* ── Section 12: Why-us capstone ──────────────────────────────────────── */
  .lpv2-why__grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--s4);
    margin-top: var(--s5);
  }
  @media (min-width: 700px) {
    .lpv2-why__grid { grid-template-columns: repeat(2, 1fr); }
  }
  @media (min-width: 1100px) {
    .lpv2-why__grid { grid-template-columns: repeat(5, 1fr); }
  }
  .lpv2-why__card {
    padding: var(--s4);
    background: var(--sur);
    border: 1px solid var(--bdr);
    border-radius: var(--r2);
    display: flex;
    flex-direction: column;
    gap: var(--s2);
  }
  .lpv2-why__icon { color: var(--ac); }
  .lpv2-why__h {
    font-family: 'DMSerif', Charter, Georgia, serif;
    color: var(--hi);
    font-size: var(--t-md);
    line-height: 1.2;
  }
  .lpv2-why__c {
    color: var(--tx2);
    font-size: var(--t-sm);
    line-height: 1.55;
  }


  /* ── V13 sticky right-rail buy box + 2-col main grid ───────────────────── */
  /* On lpv2 pages, widen the page wrap so a 16" MacBook Pro (1728px effective
     viewport) gets adequate breathing room for the 2-col grid. The previous
     1200px wrap left ~264px gutters and a cramped left column. */
  .page--lpv2 .lpv2-grid,
  .page--lpv2 .wrap,
  .page--lpv2 .sticky-subnav__in {
    max-width: 1400px;
  }
  .lpv2-grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--s5);
    max-width: var(--wrap);
    margin-inline: auto;
    padding-inline: var(--s4);
  }
  @media (min-width: 1000px) {
    .lpv2-grid {
      grid-template-columns: minmax(0, 1fr) 320px;
      gap: var(--s6);
      align-items: start;
    }
  }
  .lpv2-grid__main { min-width: 0; }
  .lpv2-grid__rail {
    position: relative;
  }
  @media (min-width: 1000px) {
    .lpv2-grid__rail {
      position: sticky;
      top: calc(var(--nav, 60px) + var(--s4));
      align-self: start;
      /* Cap rail height so a tall buybox fits the viewport on a 16" MBP
         (≈1117px effective). Account for the top nav + sticky-subnav (~50px)
         + s4 top offset + a small bottom margin. Content scrolls internally
         when it exceeds available height. */
      max-height: calc(100vh - var(--nav, 60px) - 50px - var(--s4) - var(--s3));
      overflow-y: auto;
      overscroll-behavior: contain;
      /* Hide scrollbar visually but keep it functional. */
      scrollbar-width: thin;
    }
    .lpv2-grid__rail::-webkit-scrollbar { width: 6px; }
    .lpv2-grid__rail::-webkit-scrollbar-thumb {
      background: color-mix(in oklch, var(--bdr) 70%, transparent);
      border-radius: 3px;
    }
  }

  .sticky-buybox {
    background: var(--sur);
    border: 1px solid var(--bdr);
    border-radius: var(--r2);
    padding: var(--s4);
    display: flex;
    flex-direction: column;
    gap: var(--s3);
    box-shadow: 0 8px 24px -12px oklch(15% 0.01 280 / .18);
  }
  .sticky-buybox__top { padding-bottom: var(--s3); border-bottom: 1px solid var(--bdr); }
  .sticky-buybox__name {
    font-family: 'DMSerif', Charter, Georgia, serif;
    font-size: var(--t-md);
    color: var(--hi);
    line-height: 1.2;
    margin-bottom: var(--s2);
  }
  .sticky-buybox__price {
    display: flex;
    align-items: baseline;
    gap: var(--s2);
    margin-bottom: var(--s2);
  }
  .sticky-buybox__price-val {
    font-family: 'DMSerif', Charter, Georgia, serif;
    font-size: var(--t-xl);
    color: var(--hi);
    line-height: 1;
  }
  .sticky-buybox__price-strike {
    text-decoration: line-through;
    color: var(--tx3);
    font-size: var(--t-sm);
  }
  .sticky-buybox__rating {
    font-size: var(--t-xs);
    color: var(--tx2);
    display: flex;
    flex-wrap: wrap;
    gap: var(--s1);
    align-items: center;
  }
  .sticky-buybox__rating span:first-child { color: var(--ac); letter-spacing: 1px; }
  .sticky-buybox__trust {
    display: flex;
    flex-direction: column;
    gap: var(--s2);
    padding-top: var(--s3);
    border-top: 1px solid var(--bdr);
  }
  .sticky-buybox__trust-it {
    display: flex;
    align-items: center;
    gap: var(--s2);
    font-size: var(--t-xs);
    color: var(--tx2);
    line-height: 1.4;
  }
  .sticky-buybox__trust-it svg { color: var(--ac); flex-shrink: 0; }
  .sticky-buybox__trust-it strong { color: var(--hi); font-weight: 600; }
  .sticky-buybox__authority {
    font-size: var(--t-xs);
    color: var(--tx3);
    padding-top: var(--s2);
    border-top: 1px dashed var(--bdr);
    line-height: 1.5;
  }
  .sticky-buybox__authority strong { color: var(--hi); }


  /* ── Mobile sticky bottom CTA (V13 mobile + thumb zone) ────────────────── */
  .sticky-buybox-bottom {
    display: none;
    position: fixed;
    left: var(--s3);
    right: var(--s3);
    bottom: var(--s3);
    z-index: 50;
    background: var(--ac);
    color: #fff;
    padding: var(--s3) var(--s4);
    border-radius: var(--r2);
    box-shadow: 0 12px 32px -8px oklch(15% 0.01 280 / .35);
    align-items: center;
    justify-content: space-between;
    gap: var(--s3);
    font-weight: 600;
    text-decoration: none;
    min-height: 56px;     /* CAP §11: ≥48px tap target; we use 56px for comfort. */
  }
  @media (max-width: 999px) {
    .sticky-buybox-bottom { display: flex; }
    body { padding-bottom: 84px; }   /* leave clearance for the floating CTA */
  }
  .sticky-buybox-bottom__price {
    font-family: 'DMSerif', Charter, Georgia, serif;
    font-size: var(--t-md);
  }
  .sticky-buybox-bottom__price small {
    font-size: .65em;
    margin-left: 2px;
    opacity: .85;
  }
  .sticky-buybox-bottom__cta {
    font-size: var(--t-sm);
    letter-spacing: .05em;
    text-transform: uppercase;
  }


  /* ── CAP §11: thumb-zone CTA helper ────────────────────────────────────── */
  .cta-thumb {
    min-height: 48px;
    padding-block: var(--s3);
  }


  /* ── Performance helpers — explicit aspect + size hints ────────────────── */
  .lpv2-hero picture,
  .lpv2-stripe picture,
  .comparison-triptych__panel picture {
    display: block;
    width: 100%;
    height: 100%;
  }

} /* end @layer components — LP v2 */


@layer components {
  /* ── LP v2 micro-additions for gen-agent content shape ─────────────────── */
  .comparison-triptych__stats {
    display: flex;
    flex-direction: column;
    gap: var(--s2);
    margin: 0;
  }
  .comparison-triptych__stat-row {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: var(--s2);
    padding-block: var(--s1);
    border-bottom: 1px dashed var(--bdr);
    font-size: var(--t-sm);
  }
  .comparison-triptych__stat-row dt {
    color: var(--tx2);
    letter-spacing: .05em;
    text-transform: uppercase;
    font-size: var(--t-xs);
  }
  .comparison-triptych__stat-row dd {
    color: var(--hi);
    font-family: 'DMSerif', Charter, Georgia, serif;
    font-weight: 400;
    margin: 0;
  }

  .icon-row__sub {
    font-size: var(--t-2xs, .68rem);
    color: var(--tx3);
    margin-top: -2px;
  }

  .variant-row__badge {
    display: inline-block;
    margin-left: var(--s1);
    padding: 2px var(--s2);
    background: var(--ac);
    color: var(--bg);
    border-radius: var(--r);
    font-style: normal;
    font-size: var(--t-2xs, .68rem);
    letter-spacing: .05em;
    text-transform: uppercase;
  }
}


/* ============================================================================
   LP v2 — FIX ROUND 3 (Issue list 2026-06-10)
   ----------------------------------------------------------------------------
   This block addresses the 14 desktop polish issues the user reported after
   walking the live LP at 1728×1117 (16" MBP). Loaded after the main lpv2
   @layer so each rule wins via source-order specificity.

   Critical constraint: do NOT regress mobile — the user said mobile reads
   well. Every fix here is gated by `@media (min-width: ...)` where relevant.
   ============================================================================ */
@layer components {

  /* Fix-4 #1, ATF hero whitespace compression (desktop) v3.
     Target, on a 1728x1117 MBP viewport (1117px usable below the chrome),
     the 16" user should see, ABOVE the fold,
       (a) nav + free-ship strip + hero photo + headline + sub + CTAs + proof line, AND
       (b) the START of the next section (lpv2-highlights).
     Hero must therefore be roughly 55svh on desktop, NOT 70.
     Padding-block dropped to s3. h1/sub/cta margins also tightened.
     We do NOT regress mobile, only ratchet desktop. */
  @media (min-width: 1000px) {
    .lpv2-hero {
      min-height: 55svh;        /* was 70 then 78 */
      padding-block: var(--s3); /* was s5 then s7 */
    }
    .lpv2-hero__h1 { margin-block: var(--s2) var(--s3); }
    .lpv2-hero__sub { margin-bottom: var(--s3); }
    .lpv2-hero__cta { margin-bottom: var(--s2); }
    /* Remove the top margin after the nav on lpv2 pages, the hero is
       full-bleed inverse and should butt right up against the nav. */
    .page--lpv2 main { padding-top: 0; }
    /* Tighten the free-shipping strip too so it does not eat ATF height. */
    .page--lpv2 .strip { padding-block: var(--s2); }
  }

  /* ── #11 — CTA hierarchy: demote main-nav SHOP NOW + hide subnav CTA when
     the buybox is in view. The main-nav "Shop now" button competes with
     the buybox CTA at all scroll positions; convert it to a ghost (less
     visual weight) so the buybox stays the dominant primary action. The
     sticky-subnav cta gets a class toggle by JS (.sticky-subnav--cta-off)
     when the buybox is intersecting. */
  .page--lpv2 .nav__cta {
    background: transparent !important;
    color: var(--tx2) !important;
    border: 1px solid var(--bdr2) !important;
  }
  .page--lpv2 .nav__cta:hover {
    color: var(--hi) !important;
    border-color: var(--ac) !important;
  }
  .sticky-subnav--cta-off .sticky-subnav__cta {
    visibility: hidden;
    pointer-events: none;
    opacity: 0;
    transition: opacity .2s var(--ease);
  }

  /* ── #6 — Button horizontal padding pass.
     Existing .btn--lg padding was --s4 --s6; bump to --s4 --s7 and base .btn
     padding from --s3 --s5 to --s3 --s6 so labels have proper breathing room.
     Only on lpv2 pages so we don't disturb v1 PDPs. */
  .page--lpv2 .btn,
  .page--lpv2 .nav__cta,
  .page--lpv2 .sticky-subnav__cta { padding-inline: var(--s6); }
  .page--lpv2 .btn.btn--lg { padding-inline: var(--s7); }
  .page--lpv2 .btn.btn--sm { padding-inline: var(--s4); }

  /* ── #2a — "How it works" hero secondary CTA contrast.
     btn--g on a dark scrim was unreadable. On the hero (inverse section)
     swap to a white-bordered translucent-fill ghost so the label has a
     guaranteed 4.5:1 contrast against the scrim. */
  .lpv2-hero .btn--g {
    background: oklch(100% 0 0 / .08);
    border-color: oklch(100% 0 0 / .70);
    color: #ffffff;
    backdrop-filter: blur(2px);
    -webkit-backdrop-filter: blur(2px);
  }
  .lpv2-hero .btn--g:hover {
    background: oklch(100% 0 0 / .18);
    border-color: #ffffff;
    color: #ffffff;
  }

  /* Fix-5 — Mobile ATF whitespace under free-shipping strip.
     The `.sticky-subnav` lives in normal flow but is initially hidden
     (translateY(-110%) + opacity:0). Despite being visually off-screen, it
     reserves ~43px of layout height between the free-ship strip and the hero
     section on mobile — visible as a blank cream band. Collapse its initial
     height to 0; the JS that adds `--compact` past the hero will restore the
     natural height with the existing transition. Applies at all viewports
     because the same waste exists on desktop, and fix-4 expected the strip
     to butt against the hero on desktop too. */
  .sticky-subnav:not(.sticky-subnav--compact) {
    height: 0;
    padding-block: 0;
    overflow: hidden;
    border-bottom-width: 0;
  }

  /* ── #2b — Highlights strip: add section header context + equal-height cards.
     The strip currently floats with no header above; reads as content-of-
     nowhere. The header is rendered in the template; here we style it +
     enforce equal-height cards via grid stretch. */
  .lpv2-highlights__header {
    text-align: center;
    margin-bottom: var(--s4);
  }
  .lpv2-highlights__header .lbl { margin-bottom: var(--s2); }
  .lpv2-highlights__header .sec-h {
    font-family: 'DMSerif', Charter, Georgia, serif;
    font-size: var(--t-lg);
    margin-bottom: 0;
    max-width: 36ch;
    margin-inline: auto;
    line-height: 1.2;
  }
  /* Make the highlights grid stretch all cards to equal height. */
  .lpv2-highlights__grid {
    align-items: stretch;
  }
  .lpv2-highlights__grid > li,
  .lpv2-highlights__card {
    display: flex;
    height: 100%;
  }
  .lpv2-highlights__link {
    width: 100%;
    min-height: 148px;       /* equal floor so cards line up */
    flex: 1;
    justify-content: flex-start;
  }
  .lpv2-highlights__lbl {
    /* Issue #2 — cards were missing strong header weight. Make the label
       feel like a card title rather than a footnote label. */
    font-size: var(--t-md);
    font-weight: 500;
    margin-block: var(--s1) 0;
  }


  /* ── #3 — Buybox: widen on desktop, push to right viewport edge, fit in 100vh.
     We override .lpv2-grid for the page--lpv2 case so the rail can extend
     past the 1400px wrap into the right edge. Strategy:
       · Bring back the wrap on .lpv2-grid--wide (we use the existing one)
       · Bump the rail column from 320px → 380px (more room for selectors)
       · Reduce the rail max-height by lowering internal padding so the
         buybox fits in 100vh on a 16" MBP.
     We pad the LEFT side with a max-width on the main column so the article
     stays readable while the rail gets the right slack. */
  @media (min-width: 1200px) {
    .page--lpv2 .lpv2-grid {
      grid-template-columns: minmax(0, 1fr) 400px;
      gap: var(--s5);
      max-width: 1500px;       /* a touch wider than 1400 to give buybox slack */
    }
  }
  @media (min-width: 1500px) {
    .page--lpv2 .lpv2-grid {
      /* On wider desktops let the rail fan to the right by enlarging the
         right column. The wrap is bumped to 1600. */
      grid-template-columns: minmax(0, 1fr) 440px;
      max-width: 1600px;
    }
  }

  /* Compact buybox content density so the entire rail fits in 100vh on a
     16" MBP (1117px effective). The previous internal scroll-on-overflow
     was an admission of defeat — squeeze the chrome instead. */
  @media (min-width: 1000px) {
    .sticky-buybox {
      padding: var(--s3) var(--s4);
      gap: var(--s2);
    }
    .sticky-buybox__top { padding-bottom: var(--s2); }
    .sticky-buybox__name { margin-bottom: var(--s1); font-size: var(--t-sm); }
    .sticky-buybox__price { margin-bottom: var(--s1); }
    .sticky-buybox__rating { font-size: var(--t-2xs); }
    .sticky-buybox__trust { padding-top: var(--s2); gap: var(--s1); }
    .sticky-buybox__trust-it { font-size: var(--t-2xs); line-height: 1.3; }
    .sticky-buybox__authority {
      font-size: var(--t-2xs);
      padding-top: var(--s2);
      line-height: 1.4;
    }
    /* Fix-4 #2 restore, allow the rail to scroll internally if its content
       exceeds the visible viewport. fix-3 removed this and the user lost
       the ability to interact with rail elements that fell outside the
       viewport. We cap height at calc(100vh - nav offset) and scroll inside. */
    .lpv2-grid__rail {
      max-height: calc(100vh - var(--nav, 64px) - var(--s4));
      overflow-y: auto;
      overscroll-behavior: contain;
      scrollbar-width: thin;
    }
    .lpv2-grid__rail::-webkit-scrollbar { width: 6px; }
    .lpv2-grid__rail::-webkit-scrollbar-thumb { background: var(--bdr); border-radius: 3px; }
  }

  /* Tighter still on shorter desktop viewports (16" MBP territory). */
  @media (min-width: 1000px) and (max-height: 1150px) {
    .sticky-buybox { padding: var(--s2) var(--s3); }
    .sticky-buybox__top { padding-bottom: var(--s2); margin-bottom: var(--s1); }
    .sticky-buybox__name { font-size: var(--t-sm); margin-bottom: 0; }
    .sticky-buybox__price-val { font-size: var(--t-lg); }
    .sticky-buybox__rating { font-size: var(--t-2xs); }
    /* Suppress the authority line on shorter viewports — it's repeated in the
       founder section anyway. */
    .sticky-buybox__authority { display: none; }
  }


  /* ── #5 — Buybox selectors: more prominent variant + cadence boxes.
     The variant + subsave/cadence boxes were cramped. Give them larger
     touch targets, more padding, clearer selected/unselected separation. */
  .sticky-buybox .var-grid {
    gap: var(--s2);
    margin-top: var(--s2);
  }
  .sticky-buybox .var-btn {
    padding: var(--s3) var(--s4);
    font-size: var(--t-sm);
    min-height: 52px;
    text-align: left;
    line-height: 1.3;
    white-space: normal;
  }
  .sticky-buybox .var-btn.selected {
    border-color: var(--ac);
    box-shadow: 0 0 0 2px color-mix(in oklch, var(--ac) 25%, transparent);
    background: color-mix(in oklch, var(--ac) 5%, var(--sur));
  }

  /* ── #8 — Subsave/cadence cards: compact, no spillout.
     Cards were oversized vertically and the discount badge was spilling
     past the card edge. Rebuild the layout: keep horizontal density,
     tighten vertical padding. */
  .sticky-buybox .subsave {
    gap: var(--s2);
    margin-top: var(--s2);
  }
  .sticky-buybox .subsave__heading {
    font-size: var(--t-2xs);
    margin-bottom: var(--s1);
  }
  .sticky-buybox .subsave__option {
    padding: var(--s2) var(--s3);
    grid-template-columns: auto 1fr auto;
    align-items: center;
    gap: var(--s2);
    min-height: 56px;
  }
  /* Restructure option body to fit on one row for compactness. */
  .sticky-buybox .subsave__option-body {
    display: grid;
    grid-template-columns: 1fr auto;
    grid-template-rows: auto auto;
    column-gap: var(--s2);
    row-gap: 2px;
    align-items: center;
  }
  .sticky-buybox .subsave__freq {
    font-size: var(--t-sm);
    line-height: 1.2;
    grid-column: 1;
    grid-row: 1;
  }
  .sticky-buybox .subsave__price-wrap {
    grid-column: 2;
    grid-row: 1;
    flex-wrap: wrap;
    justify-content: flex-end;
    gap: var(--s1);
  }
  .sticky-buybox .subsave__price { font-size: var(--t-md); }
  .sticky-buybox .subsave__strike { font-size: var(--t-2xs); }
  /* The discount badge previously wrapped onto its own row and spilled —
     move it inline next to the price, fixed-width, contained. */
  .sticky-buybox .subsave__discount {
    grid-column: 2;
    grid-row: 2;
    margin-top: 0;
    font-size: var(--t-2xs);
    letter-spacing: .04em;
    text-align: right;
    white-space: nowrap;
  }
  .sticky-buybox .subsave__savings {
    grid-column: 1 / -1;
    grid-row: 2;
    margin-top: 0;
    text-align: left;
    font-size: var(--t-2xs);
    color: var(--tx3);
  }
  /* The "Best value" pseudo badge was floating above the option card; reposition
     it inside the top edge so it doesn't add vertical height. */
  .sticky-buybox .subsave__option--featured::after {
    top: -8px;
    right: 8px;
    font-size: 9px;
    padding: 2px 6px;
  }

  /* ── #7 — Order bump alignment.
     Current .bump-offer__copy is flex with flex-wrap, which collapses to a
     poorly-aligned multi-line stack inside the narrow buybox rail. Restructure
     as a 3-column grid: thumb | name/copy | price — that aligns everything
     to a single baseline. */
  .sticky-buybox .bump-offer {
    margin-block: var(--s2);
    padding: var(--s3);
  }
  .sticky-buybox .bump-offer__check {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: var(--s2);
    align-items: start;
  }
  .sticky-buybox .bump-offer__copy {
    display: grid;
    grid-template-columns: 48px 1fr auto;
    gap: var(--s2) var(--s3);
    align-items: center;
    flex: none;
  }
  .sticky-buybox .bump-offer__img {
    grid-column: 1;
    grid-row: 1 / span 2;
    width: 48px;
    height: 48px;
  }
  .sticky-buybox .bump-offer__name {
    grid-column: 2;
    grid-row: 1 / span 2;
    align-self: center;
    font-size: var(--t-xs);
    line-height: 1.35;
  }
  .sticky-buybox .bump-offer__name strong {
    display: inline;
    font-weight: 700;
    color: var(--hi);
  }
  .sticky-buybox .bump-offer__tagline {
    display: block;
    margin-left: 0;
    margin-top: 2px;
    line-height: 1.35;
  }
  .sticky-buybox .bump-offer__price {
    grid-column: 3;
    grid-row: 1 / span 2;
    align-self: center;
    font-size: var(--t-md);
    text-align: right;
  }


  /* Fix-4 #6, "What's in the jar" breakdown image, enlarge much more.
     fix-3 went 380 -> 600, user still says it is unreadable. The labels
     inside the SVG are 14px, so even at 600px they render too small.
     Strategy: (a) blow the SVG up to ~960px on desktop so the labels
     enlarge proportionally, (b) give the image the full row by stacking
     it above the list on the breakdown layout, and (c) re-rank
     callout-breakdown__h so the title doesn't dominate. */
  @media (min-width: 900px) {
    .callout-breakdown {
      grid-template-columns: 1fr;
      gap: var(--s5);
      max-width: 1100px;
      margin-inline: auto;
    }
    .callout-breakdown__core {
      order: 1;
      text-align: center;
    }
    .callout-breakdown__img {
      max-width: 960px;
      margin-inline: auto;
      display: block;
      width: 100%;
    }
    .callout-breakdown__list {
      order: 2;
      max-width: 880px;
      margin-inline: auto;
    }
  }
  .callout-breakdown__h {
    font-size: var(--t-2xl);
    margin-bottom: var(--s4);
  }


  /* Fix-4 #7, Lifestyle stripes, switch to TRUE 2-column split layout.
     Prior rounds put the caption over the photo with a scrim. The user
     called this unreadable on all four stripes across multiple rounds.
     New approach (Apple PDP pattern): solid-color text panel on one side,
     unobstructed photo on the other. Alternates left/right by index.
     The kill-the-scrim is also a kill-the-overlay, so the image gets to
     breathe and the type sits on a flat WCAG-AA panel. */
  .lpv2-stripe {
    min-height: 56svh;
    display: grid;
    grid-template-columns: 1fr;     /* mobile, stacked */
    align-items: stretch;
    position: relative;
    overflow: hidden;
  }
  /* Kill the prior gradient-scrim overlay completely. */
  .lpv2-stripe::before { content: none; background: none; }
  .lpv2-stripe::after  { content: none; background: none; }

  /* Override .full-bleed for lpv2-stripe so it doesn't overflow the body
     (which has its own padding). Stripes container itself is full-bleed. */
  .lpv2-stripes.full-bleed,
  .lpv2-stripe.full-bleed {
    width: 100%;
    max-width: 100vw;
    margin-inline: 0;
    overflow: hidden;
  }
  .lpv2-grid__main > .lpv2-stripes {
    margin-inline: calc(-50vw + 50%);
    width: 100vw;
    max-width: 100vw;
  }

  /* Fix-4 #7, photo column.
     The picture macro renders <picture><img class="lpv2-stripe__bg"></picture>,
     so the class is on the inner img not the outer picture. We treat the
     outer <picture> wrapper as the grid cell, and override the inner img's
     base "position:absolute" rule to relative so it occupies its grid cell. */
  .lpv2-stripe > picture {
    position: relative;
    width: 100%;
    height: 100%;
    min-height: 56svh;
    display: block;
    z-index: 1;
    overflow: hidden;
  }
  .lpv2-stripe > picture > img,
  .lpv2-stripe > picture .lpv2-stripe__bg {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
    z-index: auto;            /* override base z-index: -1 */
  }

  /* Caption panel is a flat color block, NOT an over-image scrim. */
  .lpv2-stripe__cap {
    display: flex;
    flex-direction: column;
    justify-content: center;
    padding: var(--s6) var(--s5);
    background: oklch(14% 0.01 280);            /* deep ink default */
    color: oklch(96% 0.01 80);
  }
  .lpv2-stripe--light .lpv2-stripe__cap {
    background: oklch(96% 0.012 80);
    color: oklch(20% 0.01 280);
  }
  .lpv2-stripe__copy {
    font-family: 'DMSerif', Charter, Georgia, serif;
    font-size: clamp(2.4rem, 4vw + .8rem, 4.8rem);
    line-height: 1.02;
    letter-spacing: -0.02em;
    max-width: 14ch;
    text-wrap: balance;
    /* Drop the text-shadow, the flat panel gives 7:1 contrast already. */
    text-shadow: none;
  }

  /* Desktop, true split. Photo right (60%), text left (40%), alternating
     by index so the layout has rhythm. */
  @media (min-width: 900px) {
    .lpv2-stripe {
      grid-template-columns: 2fr 3fr;   /* 40% text, 60% photo */
      min-height: 60svh;
    }
    .lpv2-stripe__cap { order: 1; padding: var(--s7) var(--s6); }
    .lpv2-stripe__bg  { order: 2; }
    /* Alternate, even-index stripes flip so the photo is on the left. */
    .lpv2-stripe:nth-child(even) {
      grid-template-columns: 3fr 2fr;   /* photo first */
    }
    .lpv2-stripe:nth-child(even) .lpv2-stripe__cap { order: 2; }
    .lpv2-stripe:nth-child(even) .lpv2-stripe__bg  { order: 1; }
  }


  /* Fix-4 #8, customer wall avatars, force PERFECT circle.
     Prior rounds set border-radius:50% on the <img> but the parent <span>
     and <picture> wrappers had no constraints, letting the picture stretch
     horizontally in the flex meta row and produce an oval. We now size
     and shape ALL THREE levels (span > picture > img) so no parent can
     stretch the avatar regardless of intrinsic image size. */
  .lpv2-customer-card__portrait {
    display: inline-block;
    width: 72px;
    height: 72px;
    flex-shrink: 0;
    overflow: hidden;
    border-radius: 50%;
    background: var(--sur2);
    /* Use line-height: 0 to prevent inline baseline gaps inside the span. */
    line-height: 0;
  }
  .lpv2-customer-card__portrait > picture {
    display: block;
    width: 72px;
    height: 72px;
  }
  .lpv2-customer-card__portrait-img,
  .lpv2-customer-card__portrait img {
    display: block;
    width: 72px !important;
    height: 72px !important;
    aspect-ratio: 1 / 1;
    border-radius: 50%;
    object-fit: cover;
    object-position: center top;     /* face up if the source is full-body */
    flex-shrink: 0;
  }
  /* The meta row gets a bigger gap to absorb the bigger avatar. */
  .lpv2-customer-card__meta {
    gap: var(--s4);
    align-items: center;
  }


  /* ── #13 — Footer subhead line-height.
     "FocusFlow Vanilla Mocha — 30-Pack" with the "— 30-Pack" wrapping on
     a separate line with the wrong line-height felt broken. Tighten the
     line-height + set a sensible max-width so it wraps gracefully. */
  .ft__brand-h {
    line-height: 1.25 !important;
  }
  .ft__brand-h span {
    line-height: 1.15 !important;
    display: block;
  }
  .ft__brand-d {
    line-height: 1.55 !important;
    margin-top: var(--s2);
  }


  /* ── #14 — Footer "Stay in the loop" email field width + form layout.
     The .nl__form grid was column on mobile, row on desktop, but the email
     input collapsed to too narrow when the desktop layout activated. Force
     a sensible flex-distribution: input takes 2/3, button takes 1/3, note
     wraps below. */
  @media (min-width: 768px) {
    .nl__form {
      display: grid;
      grid-template-columns: 1fr auto;
      grid-template-areas:
        "field button"
        "note  note";
      gap: var(--s3);
      max-width: 480px;
    }
    .nl__form .fg { grid-area: field; width: 100%; }
    .nl__form .btn { grid-area: button; align-self: end; min-height: 48px; }
    .nl__form .fnote {
      grid-area: note;
      margin: 0;
      font-size: var(--t-xs);
      color: var(--tx3);
    }
    .nl__form .fin { width: 100%; min-width: 0; }
  }

} /* end @layer components — LP v2 FIX ROUND 3 */


/* ============================================================================
   LP v2 — FIX ROUND 3 PATCH B (post-screenshot review 2026-06-10 ~11:35)
   ----------------------------------------------------------------------------
   Patch fixes spotted in fix-3 verification screenshots:
     · Buybox still 1242px (vs 1117px viewport) — needs ~125px more compression
     · Footer newsletter: input still narrow, button hyper-tall, headline wrapping
     · Lifestyle scrim dialed back so photos still read behind captions
     · Customer wall portrait images sized correctly via CSS but appear empty due
       to lazy-load (no fix needed — real user view loads them in)
   ============================================================================ */
@layer components {

  /* ── Further buybox compression (#3 follow-up) ─────────────────────────
     Need ~125px more vertical savings. Sources of waste:
       · subsave option min-height 56px × 4 = 224px → drop to 44px = 176px (-48px)
       · variant-btn min-height 52px × 2 = 104px → drop to 44px = 88px (-16px)
       · bump-offer margin + padding cuts another -16px
       · ATC button btn--lg → btn (medium) on this rail saves -20px
       · trust strip gap further compressed -10px
       · Hide rating row on very short viewports saves -25px
     Target ≤1100px buybox height at 1117 viewport. */
  @media (min-width: 1000px) {
    .sticky-buybox .subsave__option {
      padding: var(--s2) var(--s3);
      min-height: 44px;
    }
    .sticky-buybox .var-btn {
      padding: var(--s2) var(--s3);
      min-height: 44px;
      font-size: var(--t-xs);
    }
    .sticky-buybox .bump-offer {
      margin-block: var(--s1);
      padding: var(--s2) var(--s3);
    }
    .sticky-buybox .bump-offer__img {
      width: 40px;
      height: 40px;
    }
    .sticky-buybox .bump-offer__copy {
      grid-template-columns: 40px 1fr auto;
    }
    /* Shrink the ATC button on desktop only — mobile still uses btn--lg via
       the sticky-buybox-bottom path. */
    .sticky-buybox .btn-cart.btn--lg {
      padding: var(--s3) var(--s4);
      font-size: var(--t-sm);
      min-height: 48px;
    }
    /* Tighten subsave heading + var-label */
    .sticky-buybox .var-label,
    .sticky-buybox .subsave__heading {
      font-size: 10px;
      letter-spacing: .14em;
      margin-bottom: var(--s1);
    }
    /* The "Most popular" line in the featured subsave row was adding
       another row — tuck it into the existing 2nd row column. */
    .sticky-buybox .subsave__option--featured .subsave__savings {
      display: none;
    }
  }

  /* On the actual 1117-or-shorter MBP viewport hide the bump entirely.
     User can still see it on mobile (where the buybox stacks in flow). */
  @media (min-width: 1000px) and (max-height: 1150px) {
    .sticky-buybox .sticky-buybox__rating { display: none; }
    .sticky-buybox .bump-offer__tagline { display: none; }
  }


  /* ── Footer newsletter form fix-3 PATCH B (#14 follow-up) ─────────────
     Earlier grid attempted `grid-template-columns: 1fr auto` but the field
     `<div class="fg">` containing the input wasn't filling. The fg child has
     `display: flex; flex-direction: column` so the .fin inside is at natural
     width. Force everything to fill properly. */
  @media (min-width: 768px) {
    .ft .nl__form {
      display: grid;
      grid-template-columns: minmax(220px, 1fr) auto;
      grid-template-areas:
        "field button"
        "note  note";
      column-gap: var(--s3);
      row-gap: var(--s2);
      max-width: 480px;
      align-items: end;
    }
    .ft .nl__form .fg {
      grid-area: field;
      width: 100%;
      min-width: 0;
    }
    .ft .nl__form .fin {
      width: 100%;
      min-width: 0;
      height: 48px;
      box-sizing: border-box;
    }
    .ft .nl__form .btn {
      grid-area: button;
      height: 48px;
      min-height: 48px;
      align-self: end;
      padding-block: 0;
      display: inline-flex;
      align-items: center;
    }
    .ft .nl__form .fnote {
      grid-area: note;
      margin: 0;
    }
    .ft .nl__form .fsuc {
      grid-area: note;
    }
    /* Stay-in-the-loop headline — keep on one line. */
    .ft .nl__h {
      font-size: var(--t-lg);
      white-space: nowrap;
      margin-bottom: var(--s2);
      line-height: 1.15;
    }
    .ft .nl__sub {
      font-size: var(--t-sm);
      margin-bottom: var(--s3);
    }
  }


  /* Fix-4 #7, stripe scrim NUKED. The 2-column split layout (see fix-4
     above at #7) makes the gradient overlays unnecessary. We explicitly
     null them here so the prior fix-3b rules can't reappear. */
  .lpv2-stripe::before,
  .lpv2-stripe--light::before,
  .lpv2-stripe::after,
  .lpv2-stripe--light::after {
    content: none !important;
    background: none !important;
    display: none !important;
  }

} /* end @layer components — LP v2 FIX ROUND 4 */
