/* ═══════════════════════════════════════════════════════════
   MENU OF CARE — CREAM-CANVAS · SOLID-MATERIAL ARCHITECTURE
   YogNeeti · Somatic Wellness

   MOBILE-FIRST (min-width breakpoints)

   Variable Harmony:
     --cream       → #F9F8F2  (defined on all pages)
     --charcoal    → #2C2C2C  (matched to existing pages)
     --sage        → #8A9A90  (matched to existing pages)
     --dark-rust   → #5C4033  (MOC-only, with fallback)
     --f-serif     → Cormorant Garamond (matched to existing pages)
     --f-sans      → Lato (matched to existing pages)

   Laws:
     ✓ Background is --cream, NOT dark
     ✓ ZERO hover movement (no scale, no translateY)
     ✓ Inverted typography: Titles massive, prices secondary
     ✓ Massive internal padding (2rem mobile → 3rem desktop)
     ✓ Flex column + margin-top:auto for CTAs
     ✓ GPU acceleration on interactive elements
     ✓ Somatic easing: 0.8s cubic-bezier(0.2, 0.8, 0.2, 1)
   ═══════════════════════════════════════════════════════════ */

:root {
  --moc-ease: cubic-bezier(0.2, 0.8, 0.2, 1);
  --moc-dur: 0.8s;
}


/* ─── SR-ONLY ─── */
.moc-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;
}


/* ─── SCROLL REVEAL ─── */
[data-moc-reveal] {
  opacity: 0;
  transform: translateY(24px);
  transition: opacity var(--moc-dur) var(--moc-ease),
              transform var(--moc-dur) var(--moc-ease);
}
[data-moc-reveal].moc-revealed {
  opacity: 1;
  transform: translateY(0);
}
[data-moc-delay="1"] { transition-delay: 0.1s; }
[data-moc-delay="2"] { transition-delay: 0.25s; }
[data-moc-delay="3"] { transition-delay: 0.4s; }


/* ─── PRICE BLOCK: CSS GRID STACK (zero layout thrash) ─── */
.moc-card__price-block {
  display: grid;
  grid-template-rows: 1fr;
  margin-bottom: 0.75rem;
}
.price-full,
.price-monthly {
  grid-area: 1 / 1;
  transition: opacity 0.4s var(--moc-ease);
}
.price-monthly {
  display: flex;
  align-items: baseline;
  gap: 0.3em;
  opacity: 0;
  pointer-events: none;
  user-select: none;
}


/* ═══════════════════════════════════════════════
   SECTION — Seamless cream canvas
   ═══════════════════════════════════════════════ */
.moc-section {
  background: var(--cream, #F9F8F2);
  padding: clamp(4rem, 8vw, 8rem) clamp(1.25rem, 5vw, 4rem);
  position: relative;
}

.moc-section__inner {
  max-width: 1200px;
  margin: 0 auto;
}


/* ═══════════════════════════════════════════════
   HEADER
   ═══════════════════════════════════════════════ */
/* == TRUST ELEMENTS ========================================================
   Added 2026-08-27. Markup currently lives on nsr-protocol.html only, but the
   styles sit in the shared stylesheet so rolling them out to soft-cycle and
   surya-namaskar later is a markup-only change.

   All three are quiet by design: this audience reads a loud trust badge as a
   reason to distrust. No icons, no boxes, no colour beyond the palette. */

/* The credentials strip that used to live here moved to style.css on
   2026-08-27. It is now used under every pricing section on the site --
   including library.html and foundation-session.html, which do not load this
   stylesheet -- so it had to become global. The .moc- prefix is kept only
   because renaming it would touch five pages for no functional gain; it is no
   longer a Menu-of-Care-only component. */

/* 5C -- the renewal question, answered at the point of purchase.
   Sits under the cards rather than inside them so it reads as a term of the
   whole menu, not a feature of one tier. */
.moc-terms {
  margin: clamp(1.5rem, 3vw, 2rem) auto 0;
  max-width: 62ch;
  text-align: center;
  font-family: var(--f-sans, 'Lato', sans-serif);
  font-size: clamp(0.8rem, 0.8vw, 0.86rem);
  font-weight: 400;
  line-height: 1.7;
  letter-spacing: 0.02em;
  opacity: 0.78;
}

/* The two gaps below (heading->toggle, toggle->cards) were 64px and 72px at
   desktop. 3A/3B/3D took the section from 1168px to 981px measured heading-
   top to CTA-bottom, but 1080p minus browser chrome is ~965px on Windows
   Chrome, so it still cut the buttons there. These two trims give back 36px
   and land it at 945px, inside the usable height on both platforms.
   Card padding is deliberately untouched -- the brief was right that the
   internal padding is not the problem. */
.moc-header {
  text-align: center;
  margin-bottom: clamp(1.5rem, 3vw, 2rem);
}

.moc-eyebrow {
  display: block;
  font-family: var(--f-sans, 'Lato', sans-serif);
  font-size: clamp(0.75rem, 0.7vw, 0.75rem);
  font-weight: 700;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--sage-deep, #5A6457);
  margin-bottom: 0.75rem;
}

.moc-title {
  font-family: var(--f-serif, 'Cormorant Garamond', serif);
  font-size: clamp(2rem, 5vw + 0.5rem, 3.5rem);
  font-weight: 400;
  color: var(--charcoal, #2C2C2C);
  line-height: 1.15;
}
.moc-title em {
  font-style: italic;
  color: var(--sage-green);
}


/* ═══════════════════════════════════════════════
   TOGGLE — Carved into the cream page
   ═══════════════════════════════════════════════ */
.moc-toggle-wrap {
  display: flex;
  justify-content: center;
  /* Raised slightly when the badge moved up 11px: the badge now reaches
     further above the cards, and removing the guarantee preamble above freed
     more than enough room to keep it off the toggle. */
  margin-bottom: clamp(2.6rem, 3.6vw, 2.8rem);
}

.moc-toggle {
  display: inline-flex;
  position: relative;
  padding: 4px;
  border-radius: 50px;
  background: rgba(0, 0, 0, 0.05);
  box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.1);
  transform: translateZ(0);
  will-change: opacity, transform;
}

/* The sliding white frosted pill */
.moc-toggle__slider {
  position: absolute;
  top: 4px; bottom: 4px;
  left: 4px;
  width: 80px;
  border-radius: 50px;
  background: #FFFFFF;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
  pointer-events: none;
  transition: left var(--moc-dur) var(--moc-ease),
              width var(--moc-dur) var(--moc-ease);
  will-change: left, width;
  transform: translateZ(0);
}

.moc-toggle__btn {
  font-family: var(--f-sans, 'Lato', sans-serif);
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  border: none;
  background: transparent;
  padding: 0.65rem 1.4rem;
  border-radius: 50px;
  color: rgba(42, 42, 42, 0.4);
  cursor: pointer;
  transition: color 0.4s var(--moc-ease);
  white-space: nowrap;
  position: relative;
  z-index: 1;
  min-height: 48px;
  display: flex;
  align-items: center;
}
/* Both labels are `white-space: nowrap`, so at 375px the pair measures ~370px
   inside a 335px column and the toggle spills past its container. Tightening
   the horizontal padding and tracking buys back ~30px, which is enough — and
   keeps the 48px min-height that makes it a comfortable touch target. */
@media (max-width: 480px) {
  .moc-toggle__btn {
    padding-left: 0.9rem;
    padding-right: 0.9rem;
    letter-spacing: 0.06em;
  }
}

.moc-toggle__btn.is-active {
  color: var(--charcoal, #2C2C2C);
}


/* ═══════════════════════════════════════════════
   CARDS — Mobile stack (default), desktop grid
   ═══════════════════════════════════════════════ */
.moc-cards {
  display: flex;
  flex-direction: column;
  gap: 4rem;
}


/* ─── CARD WRAPPER ─── */
.moc-card-wrap {
  position: relative;
}


/* ─── THE BADGE ─── */
.moc-card__badge {
  position: absolute;

  /* Was -14px. The badge is ~34px tall, so at -14px it reached ~20px down
     into the card — which was fine when .moc-card__media was 16/5.4 and its
     centred label sat ~64px down. Halving the band to 16/2.7 brought the
     label up to ~26px and the two collided (measured -5px of overlap at
     1440px, i.e. the pill sat on the "REGULATION BUNDLE" text).

     It still straddles the card's top edge — that is the intended look — it
     just sits high enough to clear the label underneath it. */
  top: -25px;
  left: 50%;
  transform: translateX(-50%);
  font-family: var(--f-sans, 'Lato', sans-serif);
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  white-space: nowrap;
  z-index: 5;
  padding: 0.45rem 1.5rem;
  border-radius: 999px;
  background: var(--charcoal, #2C2C2C);
  color: var(--cream, #F9F8F2);
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);
}


/* ═══════════════════════════════════════════════
   THE CARD — Solid material, flexbox column
   ═══════════════════════════════════════════════ */
.moc-card {
  display: flex;
  flex-direction: column;
  height: 100%;
  border-radius: 20px;
  overflow: hidden;
  /* NO layer promotion (translateZ(0) + will-change removed 2026-08-31).
     The hero card is scaled a fractional 1.025; keeping it composited made
     the hover shadow's animation re-snap the layer's bounds every frame, so
     its text drifted by sub-pixels while the shadow bloomed — visible as a
     subtle shimmer on hover. In the normal paint path the scale rasterizes
     crisply and nothing moves. Do not "optimise" these back in. */
  /* ONLY hover: soft shadow bloom. ZERO movement. */
  transition: box-shadow var(--moc-dur) var(--moc-ease),
              opacity 0.4s var(--moc-ease);
}


/* ─── CARD VARIANT: LIGHT (T1) ─── */
.moc-card--light {
  background: #FFFFFF;
  box-shadow: 0 4px 24px rgba(0, 0, 0, 0.06);
}
.moc-card--light:hover {
  box-shadow: 0 8px 40px rgba(0, 0, 0, 0.1);
}
.moc-card--light .moc-card__tier,
.moc-card--light .moc-card__name,
.moc-card--light .price-full,
.moc-card--light .price-monthly {
  color: var(--charcoal, #2C2C2C);
}
.moc-card--light .moc-card__desc,
.moc-card--light .moc-card__features li {
  color: rgba(42, 42, 42, 0.7);
}
.moc-card--light .feat-icon {
  color: var(--sage-green);
}


/* ─── CARD VARIANT: SAGE (T2 HERO) ─── */
.moc-card--sage {
  /* Deepened from #8A9A90. Cream on that sage measured 2.78 — the whole
     card failed AA, including the price. Same on-cream/on-dark sage split
     as foundation-session.css; this value matches it. */
  background-color: var(--sage-deep, #5A6457) !important;
  color: #F9F8F2 !important;
  box-shadow: 0 20px 40px rgba(90, 100, 87, 0.25) !important;
}
.moc-card--sage:hover {
  box-shadow: 0 24px 56px rgba(90, 100, 87, 0.35) !important;
}
.moc-card--sage .moc-card__tier,
.moc-card--sage .moc-card__name,
.moc-card--sage .price-full,
.moc-card--sage .price-monthly {
  color: var(--cream, #F9F8F2);
}
.moc-card--sage .moc-card__desc,
.moc-card--sage .moc-card__features li {
  color: rgba(249, 248, 242, 0.9);
}
.moc-card--sage .moc-card__desc em {
  color: var(--cream, #F9F8F2);
  font-style: italic;
}
.moc-card--sage .feat-icon {
  color: rgba(249, 248, 242, 0.5);
}


/* ─── CARD VARIANT: DARK (T3 VIP) ─── */
.moc-card--dark {
  background: var(--charcoal, #2C2C2C);
  border: 1px solid rgba(255, 255, 255, 0.08);
  box-shadow: 0 4px 24px rgba(0, 0, 0, 0.1);
}
.moc-card--dark:hover {
  box-shadow: 0 8px 40px rgba(0, 0, 0, 0.18);
}
.moc-card--dark .moc-card__tier,
.moc-card--dark .moc-card__name,
.moc-card--dark .price-full,
.moc-card--dark .price-monthly {
  color: var(--cream, #F9F8F2);
}
.moc-card--dark .moc-card__desc,
.moc-card--dark .moc-card__features li {
  color: rgba(249, 248, 242, 0.6);
}
.moc-card--dark .feat-icon {
  color: rgba(249, 248, 242, 0.35);
}


/* ─── MEDIA WINDOW (top of card — 60% height) ─── */
.moc-card__media {
  width: 100%;
  /* Halved from 16/5.4 (128px at desktop) to 16/2.7 (64px). The band
     carries one small-caps label and nothing else, so the extra height was
     paid for entirely out of the visitor's screen. */
  aspect-ratio: 16 / 2.7;

  /* Floor, because aspect-ratio alone makes the band a function of card
     width: at 1024px the three columns are at their narrowest (~300px) and
     the band bottomed out near 50px, which pulled the centred label up under
     the badge again. 60px is where the label clears the badge at every width
     from 1024 up; above ~1180px the aspect ratio already exceeds it and this
     does nothing. */
  min-height: 60px;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 16px 16px 0 0;
  /* Default: soft sage wash — aesthetic glass pane */
  background: rgba(138, 154, 144, 0.15);
}
.moc-card__media--sage {
  background: rgba(249, 248, 242, 0.12);
}
.moc-card__media--dark {
  background: rgba(255, 255, 255, 0.04);
}

.moc-card__media-label {
  font-family: var(--f-sans, 'Lato', sans-serif);
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  text-align: center;
  color: rgba(42, 42, 42, 0.25);
}
.moc-card--sage .moc-card__media-label,
.moc-card--dark .moc-card__media-label {
  color: rgba(249, 248, 242, 0.25);
}


/* ─── CARD BODY ─── */
.moc-card__body {
  padding: 2rem;
  display: flex;
  flex-direction: column;
  flex: 1;
}

.moc-card__tier {
  display: block;
  font-family: var(--f-sans, 'Lato', sans-serif);
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  opacity: 0.5;
  margin-bottom: 0.45rem;
}

/* INVERTED HIERARCHY: Title is massive — the focal point */
.moc-card__name {
  font-family: var(--f-serif, 'Cormorant Garamond', serif);
  /* Was clamp(2.5rem, 4vw, 3.5rem) -- 56px, which is --fs-h2, a full-page
     heading size used inside a 340px column. It wrapped two of the three
     tier names onto three lines. --fs-card-title is the step added for
     exactly this: display serif at column scale, 38px ceiling. */
  font-size: var(--fs-card-title) !important;
  font-weight: 400;
  line-height: 1.05;
  letter-spacing: -0.02em;
  margin-bottom: 0.56rem;
  color: inherit;
}

/* Price is SECONDARY — clean, smaller */
.price-full,
.price-monthly {
  font-family: var(--f-sans, 'Lato', sans-serif);
  font-size: clamp(1.25rem, 2vw, 1.5rem);
  font-weight: 300;
  line-height: 1;
  letter-spacing: -0.01em;
}

.mo-text {
  font-size: 0.8rem;
  opacity: 0.7;
  font-weight: 400;
  margin-left: 0.15em;
}

.moc-card__desc {
  max-width: var(--measure, 68ch);
  font-family: var(--f-sans, 'Lato', sans-serif);
  font-size: clamp(0.88rem, 1vw, 0.95rem);
  line-height: 1.65;
  margin-bottom: 0.94rem;
}


/* ─── MODAL TRIGGER ──────────────────────────────────────────────────────
   Secondary control: it opens the "what's also included" dialog, so it must
   read as tappable at rest without competing with .moc-card__cta below it.

   It used to be dim italic underlined text at 0.55 alpha — on a phone, where
   there is no hover to reveal it, that read as a caption rather than a
   control and went unnoticed. It is now a bordered chip: the same 14px-radius
   family and sans face as the primary CTA, but sentence case, lighter weight,
   a hairline border and a barely-there ground — subordinate by contrast and
   size, not by hiding. Resting state carries the whole affordance; hover only
   deepens what is already visible. */
/* The label used to end in a literal "↗" (U+2197). That codepoint has emoji
   presentation by default, so iOS rendered it as a colour emoji sitting inside
   an otherwise monochrome control — reported from an iPhone 2026-08-05. Every
   other arrow on the site is "→" (U+2192), which has no emoji form, which is
   why this was the only one that broke. Replaced with an inline SVG so the
   glyph can never be substituted by a platform font again. */
.modal-trigger__arrow {
  flex-shrink: 0;
  transition: transform 0.4s var(--moc-ease);
}

.modal-trigger:hover .modal-trigger__arrow {
  transform: translate3d(2px, -2px, 0);
}

@media (prefers-reduced-motion: reduce) {
  .modal-trigger:hover .modal-trigger__arrow { transform: none; }
}

.modal-trigger {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  width: fit-content;
  max-width: 100%;
  cursor: pointer;
  font-family: var(--f-sans, 'Lato', sans-serif);
  font-size: 0.8rem;
  font-weight: 500;
  letter-spacing: 0.01em;
  line-height: 1.4;
  padding: 0.7rem 1.1rem;
  min-height: 44px;
  margin: 0 0 0.94rem;
  text-align: left;
  text-wrap: balance; /* keeps the ↗ from orphaning onto its own line */
  text-decoration: none;
  border-radius: 14px;
  background: rgba(42, 42, 42, 0.045);
  border: 1px solid rgba(42, 42, 42, 0.28);
  color: rgba(42, 42, 42, 0.9);
  transition: background 0.4s var(--moc-ease),
              border-color 0.4s var(--moc-ease),
              color 0.4s var(--moc-ease),
              box-shadow var(--moc-dur) var(--moc-ease);
}
.modal-trigger:hover {
  background: rgba(42, 42, 42, 0.075);
  border-color: rgba(42, 42, 42, 0.5);
  color: var(--charcoal, #2C2C2C);
  box-shadow: 0 4px 18px rgba(42, 42, 42, 0.07);
}
.modal-trigger:focus-visible {
  outline: 2px solid var(--charcoal, #2C2C2C);
  outline-offset: 3px;
}

/* Light variant (on sage/dark cards) */
.modal-trigger--light,
.moc-card--sage .modal-trigger,
.moc-card--dark .modal-trigger {
  background: rgba(249, 248, 242, 0.09);
  border-color: rgba(249, 248, 242, 0.42);
  color: rgba(249, 248, 242, 0.95);
}
.modal-trigger--light:hover,
.moc-card--sage .modal-trigger:hover,
.moc-card--dark .modal-trigger:hover {
  background: rgba(249, 248, 242, 0.16);
  border-color: rgba(249, 248, 242, 0.68);
  color: var(--cream, #F9F8F2);
  box-shadow: 0 4px 18px rgba(249, 248, 242, 0.08);
}
.modal-trigger--light:focus-visible,
.moc-card--sage .modal-trigger:focus-visible,
.moc-card--dark .modal-trigger:focus-visible {
  outline: 2px solid var(--cream, #F9F8F2);
  outline-offset: 3px;
}


/* ─── FEATURES LIST ─── */
.moc-card__features {
  list-style: none;
  padding: 0;
  margin: 0 0 1.13rem;
  display: flex;
  flex-direction: column;
  gap: 0.56rem;
}
.moc-card__features li {
  display: flex;
  align-items: flex-start;
  gap: 0.6rem;
  font-family: var(--f-sans, 'Lato', sans-serif);
  font-size: clamp(0.82rem, 0.9vw, 0.88rem);
  line-height: 1.5;
}
.feat-icon {
  width: 18px;
  height: 18px;
  flex-shrink: 0;
  margin-top: 2px;
}

/* ─── HIGHLIGHTED FEATURE ───────────────────────────────────────────────
   The live 1-to-1 sessions are what actually separate this tier from the
   self-paced ones, so the line naming them gets full-strength ink and a
   tinted ground instead of sitting at the same recessed alpha as the rest
   of the list. Negative inline margin equal to the padding keeps the icon
   on the same optical line as its neighbours while the tint bleeds wider. */
.moc-card__features li.is-highlighted {
  padding: 0.6rem 0.7rem;
  margin-inline: -0.7rem;
  background: rgba(143, 163, 150, 0.16);
  border-radius: 12px;
  font-weight: 600;
}

/* Specificity has to beat `.moc-card--dark .moc-card__features li`, which
   otherwise recesses this to 0.6 alpha like every other row. */
.moc-card--dark .moc-card__features li.is-highlighted,
.moc-card--sage .moc-card__features li.is-highlighted,
.moc-card--light .moc-card__features li.is-highlighted {
  color: var(--cream, #F9F8F2);
}

.moc-card--light .moc-card__features li.is-highlighted {
  color: var(--charcoal, #2C2C2C);
  background: rgba(90, 100, 87, 0.14);
}

.moc-card--dark .moc-card__features li.is-highlighted .feat-icon,
.moc-card--sage .moc-card__features li.is-highlighted .feat-icon {
  color: var(--sage-lifted, #A9BAB0);
}


/* ─── CTA BUTTONS ─── */
.moc-card__cta {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  min-height: 52px;
  padding: 0.9rem 1.5rem;
  font-family: var(--f-sans, 'Lato', sans-serif);
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  text-decoration: none;
  border-radius: 14px;
  cursor: pointer;
  margin-top: auto;
  transition: box-shadow var(--moc-dur) var(--moc-ease),
              background 0.4s var(--moc-ease),
              border-color 0.4s var(--moc-ease);
  transform: translateZ(0);
  will-change: opacity, transform;
}

/* Ghost dark — on white card */
.moc-cta--ghost-dark {
  background: transparent;
  border: 1.5px solid var(--charcoal, #2C2C2C);
  color: var(--charcoal, #2C2C2C);
}
.moc-cta--ghost-dark:hover {
  background: rgba(42, 42, 42, 0.04);
  box-shadow: 0 4px 20px rgba(42, 42, 42, 0.08);
}

/* Solid dark — on sage card */
.moc-cta--solid-dark {
  background: var(--charcoal, #2C2C2C);
  border: 1.5px solid var(--charcoal, #2C2C2C);
  color: var(--cream, #F9F8F2);
}
.moc-cta--solid-dark:hover {
  box-shadow: 0 4px 20px rgba(42, 42, 42, 0.2);
}

/* Ghost light — on dark card */
.moc-cta--ghost-light {
  background: transparent;
  border: 1.5px solid rgba(249, 248, 242, 0.3);
  color: var(--cream, #F9F8F2);
}
.moc-cta--ghost-light:hover {
  border-color: rgba(249, 248, 242, 0.5);
  box-shadow: 0 4px 20px rgba(249, 248, 242, 0.06);
}


/* ═══════════════════════════════════════════════
   INCLUDED WITH EVERY PLAN
   Sits directly under the pricing cards — the Community Circle
   applies to all three tiers, so it gets its own beat instead of
   living inside the guarantee footer, where it read as a footnote
   to the refund policy and got missed.
   ═══════════════════════════════════════════════ */
.moc-included {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.65rem;
  width: fit-content;
  max-width: calc(100% - 2rem);
  margin: 3.5rem auto 0;
  padding: 0.9rem 1.75rem;
  border-radius: 999px;
  background: rgba(138, 154, 144, 0.14);
  border: 1px solid rgba(138, 154, 144, 0.32);
  font-family: var(--f-sans, 'Lato', sans-serif);
  font-size: clamp(0.85rem, 1vw, 0.95rem);
  font-weight: 500;
  color: var(--sage-deep, #5A6457);
  line-height: 1.4;
  text-align: center;
}
.moc-included__icon {
  width: 18px;
  height: 18px;
  flex-shrink: 0;
  opacity: 0.9;
}


/* ═══════════════════════════════════════════════
   GUARANTEE FOOTER
   ═══════════════════════════════════════════════ */
.moc-guarantee {
  text-align: center;
  max-width: 700px;
  margin: 8svh auto 0;
  padding: 0 1rem;
}

.moc-guarantee__icon {
  width: 44px;
  height: 44px;
  color: var(--charcoal, #2C2C2C);
  opacity: 0.35;
  margin: 0 auto 1.5rem;
  display: block;
}

.moc-guarantee__headline {
  font-family: var(--f-serif, 'Cormorant Garamond', serif);
  font-size: clamp(1.25rem, 2.5vw, 1.75rem);
  font-weight: 400;
  color: var(--charcoal, #2C2C2C);
  line-height: 1.3;
  margin-bottom: 1.5rem;
}

.moc-guarantee__body {
  margin-inline: auto;
  max-width: var(--measure, 68ch);
  font-family: var(--f-sans, 'Lato', sans-serif);
  font-size: clamp(0.88rem, 1vw, 0.95rem);
  color: var(--charcoal, #2C2C2C);
  opacity: 0.8;
  line-height: 1.8;
  margin-bottom: 1.25rem;
}

/* ═══════════════════════════════════════════════
   DESKTOP GRID — min-width: 1024px (Mobile-First)
   ═══════════════════════════════════════════════ */
@media (min-width: 1024px) {
  .moc-cards {
    display: grid;
    grid-template-columns: 1fr 1fr 1fr;
    gap: 2rem;
    align-items: stretch;
  }

  .moc-card__body {
    padding: 3rem;
  }

  /* Hero Pop — Card 2 scales up to break the flat plane.
     Applied to the CARD, not the wrap, to avoid transform
     collision with the scroll-reveal translateY on the wrap. */
  .moc-card-wrap--hero {
    z-index: 2;
    position: relative;
  }
  /* Halved from scale(1.05) to scale(1.025). This is what reads as the
     vertical stagger between cards -- there is no offset in the grid; the
     middle card simply overhangs top and bottom. At 1.05 that overhang
     cost ~45px of section height for the effect. The effect survives at
     half the price. */
  .moc-card-wrap--hero .moc-card {
    transform: scale(1.025);
    transform-origin: center center;
  }

  /* The badge lives on the WRAP, which is not scaled; the card inside it is.
     scale(1.025) from a centred origin lifts the card's top edge ~8px above
     the wrap, so the badge effectively sits 8px lower relative to the card it
     labels — and it only ever appears on the hero card, the one card that is
     scaled. This cancels that lift so the clearance matches every other
     breakpoint. */
  .moc-card-wrap--hero .moc-card__badge {
    top: -33px;
  }
}


/* ═══════════════════════════════════════════════
   MODAL — iOS BOTTOM SHEET (Mobile-First)
   ═══════════════════════════════════════════════ */

/* Overlay */
/* The close used to flash a dark band across the lower half of the screen.
   Measured frame by frame: the overlay's opacity transition ended at 524ms and
   cleanup un-fixed <body> at 527ms — but the panel's transform ran to 624ms,
   so the page was relaid out and the scroll position restored while this
   element still owned a live backdrop-filter layer. A backdrop sampler being
   torn down mid-relayout is exactly when iOS paints an unsampled (black)
   frame.

   Three changes, all here rather than in JS:
     · durations matched to the panel's 0.6s, so nothing outlives anything else
     · backdrop-filter and will-change scoped to .is-open — they were permanent,
       which pinned six composited layers per page (three overlays, three
       panels) with a live backdrop sampler on each, for the whole page life
     · content-visibility while closed so the subtree costs nothing at rest */
.moc-modal-overlay {
  position: fixed;
  inset: 0;
  z-index: 9999;
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  background: rgba(42, 42, 42, 0.4);
  transition: opacity 0.6s var(--moc-ease), visibility 0.6s;
  /* Stays on the base rule DELIBERATELY. It was briefly scoped to .is-open on
     2026-08-05 and that caused a worse artefact than the one it was chasing:
     removing the class drops the blur in a single frame while this element is
     still at full opacity, so for the rest of the 0.6s fade the page shows
     sharply through a 40% dark wash. Reported as "just black on NSR, half
     green half black on soft cycle" — that is the dark tier-3 card, and the
     sage tier-2 card beside it, seen unblurred through the scrim.
     backdrop-filter cannot be transitioned away cleanly either, since blur(24px)
     does not interpolate to `none`. Leave it on. */
  backdrop-filter: var(--glass-blur-lg);
  -webkit-backdrop-filter: var(--glass-blur-lg);
}
.moc-modal-overlay.is-open {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
  /* will-change STAYS scoped — unlike backdrop-filter it has no visual effect,
     so promoting only while open is a pure win. Unconditionally it pinned six
     composited layers per page for the whole page life. */
  will-change: opacity;
}

/* Body lock */
body.moc-modal-open {
  overflow: hidden;
}
/* The position-fixed half of the lock moved into scroll.js (2026-08-05) so
   there is one implementation instead of four. Left as overflow:hidden only —
   harmless alongside it, and still correct if this stylesheet is ever used
   without the controller. */

/* Panel — MOBILE: bottom sheet */
.moc-modal-panel {
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  transform: translateY(100%);
  height: 90svh;
  background: var(--cream, #F9F8F2);
  border-radius: 24px 24px 0 0;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  transition: transform 0.6s var(--moc-ease);
  box-shadow: 0 -8px 40px rgba(0, 0, 0, 0.15);
}

/* Promoted only while the sheet is actually moving — see the overlay note. */
.moc-modal-overlay.is-open .moc-modal-panel {
  will-change: transform;
}
.moc-modal-overlay.is-open .moc-modal-panel {
  transform: translateY(0);
}

/* Close button — 44×44 min */
.moc-modal-close {
  position: sticky;
  top: 0;
  align-self: flex-end;
  z-index: 10;
  width: 44px;
  height: 44px;
  min-width: 44px;
  min-height: 44px;
  border-radius: 50%;
  border: none;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(42, 42, 42, 0.06);
  margin: 0.75rem 0.75rem 0 0;
  flex-shrink: 0;
  transition: background 0.3s var(--moc-ease);
}
.moc-modal-close svg {
  width: 18px; height: 18px;
  color: var(--charcoal, #2C2C2C);
}
.moc-modal-close:hover {
  background: rgba(42, 42, 42, 0.12);
}

/* Scroll area */
.moc-modal-scroll {
  flex: 1;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior: contain;
}

/* Lenis/Locomotive scroll-lock shield — prevents global smooth-scroller
   from consuming wheel events that originate inside the modal panel */
.moc-modal-overlay,
.moc-modal-panel,
.moc-modal-scroll {
  overscroll-behavior: contain;
}

/* Hero placeholder inside modal */
.moc-modal__hero {
  width: 100%;
  aspect-ratio: 16 / 9;
  background: rgba(138, 154, 144, 0.15);
  display: flex;
  align-items: center;
  justify-content: center;
  /* Anchors the absolutely-positioned iframe vsl-embed.js injects here.
     Without it the video would position against the nearest positioned
     ancestor — the modal panel — and overflow the 16:9 box. */
  position: relative;
}
.moc-modal__hero .moc-card__media-label {
  color: rgba(42, 42, 42, 0.2);
}

/* Modal content */
.moc-modal__content {
  padding: 2rem;
}

.moc-modal__eyebrow {
  display: block;
  font-family: var(--f-sans, 'Lato', sans-serif);
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--sage-deep, #5A6457);
  margin-bottom: 0.6rem;
}

.moc-modal__headline {
  font-family: var(--f-serif, 'Cormorant Garamond', serif);
  font-size: clamp(1.35rem, 3vw, 1.75rem);
  font-weight: 400;
  color: var(--charcoal, #2C2C2C);
  line-height: 1.25;
  margin-bottom: 0.6rem;
}

.moc-modal__subhead {
  max-width: var(--measure, 68ch);
  font-family: var(--f-sans, 'Lato', sans-serif);
  font-size: clamp(0.85rem, 1vw, 0.92rem);
  color: rgba(42, 42, 42, 0.7);
  line-height: 1.6;
  margin-bottom: 2rem;
}

/* Feature grid — 1 col mobile */
.moc-modal__features {
  display: grid;
  grid-template-columns: 1fr;
  gap: 1.25rem;
}

.moc-modal__feat {
  padding: 1.25rem;
  border-radius: 16px;
  background: rgba(138, 154, 144, 0.06);
  border: 1px solid rgba(42, 42, 42, 0.05);
}

.moc-modal__feat-icon {
  width: 26px; height: 26px;
  color: var(--sage-green);
  margin-bottom: 0.6rem;
  margin-top: 4px;
  flex-shrink: 0;
}

.moc-modal__feat-title {
  font-family: var(--f-sans, 'Lato', sans-serif);
  font-size: 0.85rem;
  font-weight: 700;
  color: var(--charcoal, #2C2C2C);
  margin-bottom: 0.3rem;
}

.moc-modal__feat-body {
  max-width: var(--measure, 68ch);
  font-family: var(--f-sans, 'Lato', sans-serif);
  font-size: 0.82rem;
  color: rgba(42, 42, 42, 0.7);
  line-height: 1.55;
}

/* Modal CTA bars removed — modals are pure "Quick Look" informational sheets.
   Checkout happens on the card CTAs which respect the active toggle state. */


/* ═══════════════════════════════════════════════
   DESKTOP MODAL — Centered float (min-width)
   ═══════════════════════════════════════════════ */
@media (min-width: 768px) {
  .moc-modal-panel {
    position: absolute;
    bottom: auto;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%) translateY(40px);
    width: 92%;
    max-width: 800px;
    height: auto;
    max-height: 85svh;
    border-radius: 24px;
    box-shadow: 0 24px 64px rgba(0, 0, 0, 0.15);
  }
  .moc-modal-overlay.is-open .moc-modal-panel {
    transform: translate(-50%, -50%) translateY(0);
  }

  .moc-modal__content {
    padding: 2.5rem;
  }

  .moc-modal__features {
    grid-template-columns: 1fr 1fr;
    gap: 1.5rem;
  }


}


/* ═══════════════════════════════════════════════
   ALSO HERE — THE PRACTICE LIBRARY
   Quiet downsell. Loaded only on the three protocol pages.

   Placement law: this block sits AFTER the pricing chooser and
   AFTER the FAQ, so the protocol has already been read, priced,
   and defended before the Library is named at all.

   Weight laws — this must stay quieter than the protocol's own offer:
     ✓ No filled button. A text link only. Filled rust CTAs stay
       reserved for the protocol, and that hierarchy is what protects it.
     ✓ $49 is never set beside the protocol price.
     ✓ Framed as a different door, not a cheaper one.

   The photograph is ATMOSPHERE, not a hero image: blurred to texture
   and veiled with cream so it reads as warmth behind glass rather than
   as a picture competing for attention. If it ever starts reading as a
   second hero, raise --moc-lib-veil before touching anything else.
   ═══════════════════════════════════════════════ */

.moc-lib {
  --moc-lib-veil: 0.62;
  position: relative;
  isolation: isolate;
  background: var(--cream, #F9F8F2);
  border-top: 1px solid rgba(44, 44, 44, 0.08);
  padding: clamp(5rem, 12svh, 9rem) clamp(1.25rem, 5vw, 4rem);
  overflow: hidden;
}

/* Mobile-first: portrait crop. Inset bleed + scale keeps the blur from
   showing a soft edge where the image ends. */
.moc-lib::before {
  content: '';
  position: absolute;
  inset: -60px;
  z-index: -2;
  background-image: url('PageWiseAssets_rs/LibrarySectionBackground-portrait.jpg');
  background-size: cover;
  background-position: center;
  filter: blur(16px) saturate(0.9) brightness(1.28);
  transform: scale(1.05);
}

/* Warm veil, not a flat one. A single cream wash over this photograph
   lands cool grey — the source is dark and blue-toned, and cool grey is
   the one neutral the palette rules out. The gradient carries a warm
   sand mid-stop so the field stays on the cream/taupe axis. */
.moc-lib::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  background: linear-gradient(
    160deg,
    rgba(249, 248, 242, calc(var(--moc-lib-veil) + 0.14)) 0%,
    rgba(238, 229, 213, calc(var(--moc-lib-veil) - 0.04)) 52%,
    rgba(249, 248, 242, calc(var(--moc-lib-veil) + 0.10)) 100%
  );
}

@media (min-width: 768px) {
  .moc-lib::before {
    background-image: url('PageWiseAssets_rs/LibrarySectionBackground-wide.jpg');
  }
}

/* The glass panel — o-p-e-n.com spec from SKILL_01 §4. */
.moc-lib__inner {
  max-width: 640px;
  margin: 0 auto;
  padding: clamp(1.75rem, 5vw, 3.25rem);
  background: rgba(249, 248, 242, 0.72);
  backdrop-filter: var(--glass-blur-lg) saturate(1.1);
  -webkit-backdrop-filter: var(--glass-blur-lg) saturate(1.1);
  border: 1px solid rgba(44, 44, 44, 0.10);
  border-radius: 16px;
  box-shadow: 0 24px 60px rgba(44, 44, 44, 0.10);
}

/* Opacity-only arrival. The inherited reveal translates 24px, and
   translating an element that owns a backdrop-filter re-rasterises the
   blur every frame — visibly cheap on a mid-range phone. */
.moc-lib__inner[data-moc-reveal] {
  transform: none;
}

/* 12px floor — the sitewide eyebrows render 9.3–11.5px and are
   unreadable on a phone. Do not shrink this one to match them. */
.moc-lib__eyebrow {
  font-family: var(--f-sans, 'Lato', sans-serif);
  font-size: 0.75rem;
  font-weight: 400;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: rgba(44, 44, 44, 0.78);
  margin: 0 0 1.5rem;
}

.moc-lib__title {
  font-family: var(--f-serif, 'Cormorant Garamond', serif);
  font-size: clamp(1.9rem, 4.5vw, 3rem);
  font-weight: 300;
  line-height: 1.15;
  letter-spacing: -0.01em;
  color: var(--charcoal, #2C2C2C);
  margin: 0 0 1.5rem;
}

.moc-lib__body {
  font-family: var(--f-sans, 'Lato', sans-serif);
  font-size: 1rem;
  line-height: 1.6;
  color: rgba(44, 44, 44, 0.85);
  max-width: 46ch;
  margin: 0 0 2.5rem;
}

/* Text link, hairline rule — never a filled button.
   inline-flex + min-height keeps the tap target at 44px (WCAG 2.5.8),
   but the rule belongs on the label, not on the 44px box — otherwise it
   floats ~20px under the type and reads as an unrelated divider. */
/* .moc-lib__link / __label / __arrow removed 2026-08-05. This block's CTA now
   uses the shared .lib-cta in style.css, so the same control renders on all
   five pages that offer the Library instead of a text link here and a filled
   terracotta pill on index and offerings. */

.moc-lib__terms {
  font-family: var(--f-sans, 'Lato', sans-serif);
  font-size: 0.8125rem;
  line-height: 1.6;
  color: rgba(44, 44, 44, 0.78);
  max-width: 44ch;
  margin: 2rem 0 0;
}

/* Content must still arrive when motion is off — the reveal starts
   at opacity 0, so this has to override, not just shorten. */
@media (prefers-reduced-motion: reduce) {
  .moc-lib__inner[data-moc-reveal] {
    opacity: 1;
    transform: none;
    transition: none;
  }
  .moc-lib__label,
  .moc-lib__arrow {
    transition: none;
  }
}
